Interpreters¶
This module contains all the different Interpreters. Interpreters interprete all or a subset of operations of a DiffLog. That way interpreters encapsulate behavior for checks and actions of operations, that can be turned on and off freely.
Interpreters work by implementing callbacks that can review a single operation. When an interpreter gets executed on a DiffLog all operations of the DiffLog will be fed one by one into the interpreter. Most of the interpreters will just raise an exception when they detect an issue in one operation, some just print the operations and others can rewrite the entire DiffLog.
CheckDynamicFilesInterpreter |
Checks if there are changes to a dynamic file and gives the user the opportunity to interact with them. |
CheckLinkBlacklistInterpreter |
Checks if a operation touches a link that is on the blacklist. |
CheckLinkDirsInterpreter |
Checks if directories need to be created. |
CheckLinkExistsInterpreter |
Checks if links of installed-file really exist in the filesystem. |
CheckLinksInterpreter |
Checks for conflicts between all links. |
CheckProfilesInterpreter |
Checks if profiles can be installed together. |
DUIStrategyInterpreter |
Reorders DiffLog so linking won't be in the order of profiles but instead in the order Delete-Update-Insert. |
DetectRootInterpreter |
Detects if root permission is needed to perform operations. |
EventExecInterpreter |
This interpreter is used to execute the event scripts of a profile. |
EventInterpreter |
This interpreter is the abstract base class for interpreters that work with profile events. |
EventPrintInterpreter |
This interpreter is used to print out what an event will do. |
ExecuteInterpreter |
This interpreter actually executes the operations from the DiffLog. |
GainRootInterpreter |
If root permission is needed to perform the operations, this interpreter restarts the process with "sudo". |
Interpreter |
Base-class for interpreters. |
PlainPrintInterpreter |
Prints add/remove/update-operation without any formating. |
PrintInterpreter |
Pretty-prints log messages and what a operation is going to do. |
RootNeededInterpreter |
Checks if root permission are required to perform all operations. |
SkipRootInterpreter |
Skips all operations that would require root permission. |
-
class
interpreters.
Interpreter
¶ Bases:
object
Base-class for interpreters.
-
data
¶ The raw DiffLog that is interpreted. Only needed by Interpreters that alter the DiffLog.
Type: list
-
__init__
()¶ Constructor
-
call_operation
(operation)¶ Call the implemented behavior for this operation.
This calls a function named like
operation["operation"]
with the prefix '_op_', if the function was implemented by the interpreter.Parameters: operation (dict) -- A operation from DiffLog
-
set_difflog_data
(data)¶ Sets the raw DiffLog content.
Needed by Interpreters that alter the DiffLog.
Parameters: data (list) -- The raw DiffLog that will be set
-
-
class
interpreters.
CheckDynamicFilesInterpreter
(dryrun)¶ Bases:
interpreters.Interpreter
Checks if there are changes to a dynamic file and gives the user the opportunity to interact with them.
-
dryrun
¶ Stores, if
--dryrun
was setType: bool
-
__init__
(dryrun)¶ Constructor.
Parameters: dryrun (bool) -- Sets, if this is a dryrun
-
_op_remove_l
(dop)¶ Inspects the target file of the to be removed link.
Parameters: dop (dict) -- The remove-operation of the to be removed link
-
_op_update_l
(dop)¶ Inspects the target file of the to be updated link.
Parameters: dop (dict) -- The update-operation of the to be updated link
-
inspect_file
(target)¶ Checks if a file is dynamic and was changed. If so, it calls a small UI to store/undo changes.
Parameters: target (str) -- The full path to the file that will be checked
-
user_interaction
(target)¶ Provides a small UI for the user to interact with a changed dynamic file.
The user can choose one of the following options to handle the changes:
- A: Abort and exit uberdot
- I: Ignore the changes and do nothing
- D: Show a diff and ask again
- P: Create a patch file and ask again
- U: Undo the changes and restore the original file
Parameters: target (str) -- The full path to the file that the user will interact with
Raises: UserAbortion
-- The user decided to abort the whole processPreconditionError
-- The patch file could not be written
-
-
class
interpreters.
CheckLinkBlacklistInterpreter
(superforce)¶ Bases:
interpreters.Interpreter
Checks if a operation touches a link that is on the blacklist.
-
superforce
¶ Stores, if
--superforce
was setType: bool
-
blacklist
¶ A list of file name patterns that are forbidden to touch without superforce flag
Type: list
-
__init__
(superforce)¶ Constructor.
Loads the blacklist.
Parameters: superforce (bool) -- Sets, if superforce was turned on
-
_op_add_l
(dop)¶ Checks the to be added symlink for blacklist violations.
Parameters: dop (dict) -- The add-operation whose symlink will be checked
-
_op_remove_l
(dop)¶ Checks the to be removed symlink for blacklist violations.
Parameters: dop (dict) -- The remove-operation whose symlink will be checked
-
_op_update_l
(dop)¶ Checks the old and the new symlink for blacklist violations.
Parameters: dop (dict) -- The update-operation whose symlinks will be checked
-
check_blacklist
(file_name, action)¶ Checks if a file matches a pattern in the blacklist.
Parameters: - file_name (str) -- Name of the file
- action (str) -- The action that is causing the touch of the file
Raises: UserAbortion
-- The user decided to not touch the fileIntegrityError
-- The file was blacklisted andsuperforce
wasn't set
-
-
class
interpreters.
CheckLinkDirsInterpreter
(makedirs)¶ Bases:
interpreters.Interpreter
Checks if directories need to be created.
-
makedirs
¶ Stores, if
--makedirs
was setType: bool
-
__init__
(makedirs)¶ Constructor
Parameters: makedirs (bool) -- Sets, if directories shall be created
-
_op_add_l
(dop)¶ Checks if the directory of the to be added link already exists.
Parameters: dop (dict) -- The add-operation whose symlink will be checked
-
_op_update_l
(dop)¶ Checks if the directory of the to be updated link already exists.
Parameters: dop (dict) -- The update-operation whose symlink will be checked
-
check_dirname
(dirname)¶ Checks if a directory exists.
Parameters: dirname (str) -- The path to a directory Raises: PreconditionError
-- The directory doesn't exist andmakedirs
isn't set
-
-
class
interpreters.
CheckLinkExistsInterpreter
(force)¶ Bases:
interpreters.Interpreter
Checks if links of installed-file really exist in the filesystem.
-
force
¶ Stores, if
--force
was setType: bool
-
removed_links
¶ A collection of all links that are going to be removed
Type: list
-
__init__
(force)¶ Constructor
-
_op_add_l
(dop)¶ Checks if the new link already exists.
Parameters: dop (dict) -- The add-operation that will be checked - Raise:
- PreconditionError: The new link already exists or its target does
- not exist
-
_op_remove_l
(dop)¶ Checks if the to be removed link really exists.
Furthermore adds the link to
removed_links
, because removed links need to be stored for_op_add_l()
.Parameters: dop (dict) -- The remove-operation that will be checked Raises: PreconditionError
-- The to be removed link does not exist
-
_op_update_l
(dop)¶ Checks if the old and the new link already exist.
Furthermore adds the old link to
removed_links
if old and new link have different names, because removed links need to be stored for_op_add_l()
.Parameters: dop (dict) -- The update-operation that will be checked Raises: PreconditionError
-- The old link does not exist, the new link already exists or the new link points to a non-existent file
-
-
class
interpreters.
CheckLinksInterpreter
(installed)¶ Bases:
interpreters.Interpreter
Checks for conflicts between all links.
Conflicts are things like duplicates, multiple targets / overwrites, etc.
Parameters: linklist (list) -- list that stores all links, their corresponding profiles and if they are already installed. Links that are already installed and won't be removed, will end up twice in this list. -
__init__
(installed)¶ Constructor.
Initializes
linklist
with all links from the installed-file.Parameters: installed (dict) -- The installed-file, that was used to create the current DiffLog
-
_op_add_l
(dop)¶ Checks if the to be added link already occurs in
linklist
.This would be forbidden, because a link that is already installed can't be added again (only updated). Similary it would be forbidden to add a link that was already added by another profile in the same run. If everything is valid, the link will be added to the list.
Parameters: dop (dict) -- The add-operation that will be checked Raises: IntegrityError
-- The check failed
-
_op_remove_l
(dop)¶ Removes link from linklist because links could be removed and added in one run by different profiles.
In that case it would look like the link is added even though it is already installed if we don't remove it here.
Parameters: dop (dict) -- The remove-operation that will be used to remove the link
-
-
class
interpreters.
CheckProfilesInterpreter
(installed, parent_arg=None)¶ Bases:
interpreters.Interpreter
Checks if profiles can be installed together. Protects against duplicates and overwrites.
-
parent_arg
¶ Stores the value of
--parent
Type: str
-
profile_list
¶ A list that stores all profiles, their parents and if they are already installed. Profiles that are still installed in the end, will end up twice in this list.
Type: list
-
__init__
(installed, parent_arg=None)¶ Constructor.
Initializes
profile_list
with all profiles from the installed-file.Parameters: - installed (dict) -- The installed-file, that was used to create the DiffLog
- parent_arg (str) -- The value of
--parent
-
_op_add_p
(dop)¶ Checks if a profile is added twice.
Adds the profile to
profile_list
if the operation is valid.Parameters: dop (dict) -- The add-operation that will be checked Raises: IntegrityError
-- A profile is added twice or is already installed
-
_op_update_p
(dop)¶ Checks if profiles will be overwritten.
Parameters: dop (dict) -- The update-operation that will be checked Raises: IntegrityError
-- A profile is already installed as a subprofile of another root profile
-
get_known
(name, is_installed)¶ Returns the entry of a profile from
profile_list
. Either for already installed profiles or for to be installed profiles.Parameters: - name (str) -- Name of the profile
- is_installed (bool) -- True, for lookups of already installed profiles
Returns: Tuple -- The entry that was found in
profile_list
.None
if no entry was found.
-
-
class
interpreters.
DUIStrategyInterpreter
¶ Bases:
interpreters.Interpreter
Reorders DiffLog so linking won't be in the order of profiles but instead in the order Delete-Update-Insert. It also removes log messages because without the old order they are not useful anymore.
-
profile_deletes
¶ A collection of profile-remove-operations
Type: list
-
profile_updates
¶ A collection of profile-update-operations
Type: list
-
profile_adds
¶ A collection of profile-add-operations
Type: list
-
link_deletes
¶ A collection of link-remove-operations
Type: list
-
link_updates
¶ A collection of link-update-operations
Type: list
-
link_adds
¶ A collection of link-add-operations
Type: list
-
__init__
()¶ Constructor
-
_op_add_l
(dop)¶ Adds the link-add-operation to
link_adds
.Parameters: dop (dict) -- The operation that will be added
-
_op_add_p
(dop)¶ Adds the profile-add-operation to
profile_adds
.Parameters: dop (dict) -- The operation that will be added
-
_op_fin
(dop)¶ Merges the collections of operations in the correct order and overwrites
self.data
to alter the DiffLogParameters: dop (dict) -- Unused in this implementation
-
_op_remove_l
(dop)¶ Adds the link-remove-operation to
link_removes
.Parameters: dop (dict) -- The operation that will be added
-
_op_remove_p
(dop)¶ Adds the profile-remove-operation to
profile_removes
.Parameters: dop (dict) -- The operation that will be added
-
_op_update_l
(dop)¶ Adds the link-update-operation to
link_updates
.Parameters: dop (dict) -- The operation that will be added
-
_op_update_p
(dop)¶ Adds the profile-update-operation to
profile_updates
.Parameters: dop (dict) -- The operation that will be added
-
-
class
interpreters.
DetectRootInterpreter
¶ Bases:
interpreters.Interpreter
Detects if root permission is needed to perform operations.
-
_access
(path)¶ Checks if we have write access for a given path.
Because the path might not be existent at this point, this function goes the full directory tree upwards until it finds a directory that we have write accesss to. If it finds one, it assumes that we have access to all subdirectories as well.
Parameters: path (str) -- The path that will be checked Returns: bool -- True, if we have access to the path
-
_op_add_l
(dop)¶ Checks if new links are either created in inaccessible directories or will be owned by other users than the current.
Parameters: dop (dict) -- The add-operation that will be checked
-
_op_remove_l
(dop)¶ Checks if to be removed links are owned by other users than the current.
Parameters: dop (dict) -- The remove-operation that will be checked
-
_op_update_l
(dop)¶ Checks if to be updated links are owned by other users than the current or will be moved to inaccessible directories.
Parameters: dop (dict) -- The update-operation that will be checked
-
_root_detected
(dop, description, affected_file)¶ This method is called when requirement of root permission is detected.
Parameters: - dop (dict) -- The operation that requires root permission
- description (str) -- A description of what the operation does that will require root permission
- affected_file (str) -- The file that the description refers to
-
-
class
interpreters.
EventExecInterpreter
(profiles, installed, event_type)¶ Bases:
interpreters.EventInterpreter
This interpreter is used to execute the event scripts of a profile.
-
shell
¶ The shell process used to execute all event callbacks
Type: Process
-
queue_out
¶ Used to push the output of the shell back in realtime
Type: Queue
-
queue_err
¶ Used to push exceptions during execution back to the main process
Type: Queue
-
ticks_without_feedback
¶ Counter that stores the time in milliseconds that the main thread is already waiting for the shell script without capturing any output.
Type: int
-
failures
¶ Counter that stores how many scripts executed with errors.
Type: int
-
__init__
(profiles, installed, event_type)¶ Constructor.
Creates a thread and queues for listening on the shells stdout and stderr.
-
_op_fin
(dop)¶ Logs a summary of the executed scripts. If one or more scripts failed, it aborts the program
-
listen_for_script_output
()¶ Runnable of
thread_out
. Waits for the shell to push something to stdout or stderr and prints it. All catched exceptions will be stored inqueue_err
to handle on the main thread. Also resetsticks_without_feedback
.
-
run_script
(script_path, profilename)¶ Execute script for the given profile.
Parameters: - script_name (str) -- The name of the script that was generated for an event
- profilename (str) -- The name of the profile that triggered the event
-
-
class
interpreters.
EventInterpreter
(profiles, installed, event_type)¶ Bases:
interpreters.Interpreter
This interpreter is the abstract base class for interpreters that work with profile events. Implements _op_* depending on self.event_type.
-
profiles
¶ A list of profiles after their execution.
Type: list
-
installed
¶ A copy of the old installed-file that is used to lookup if a profile had Uninstall-events set
Type: dict
-
event_type
¶ A specific type ("after" or "before") that determines which events this interpreter shall look for
Type: str
-
__init__
(profiles, installed, event_type)¶ Constructor.
Sets _op_add_p and _op_update_p depending on event_type.
Parameters: - profiles (list) -- A list of profiles after their execution.
- installed (dict) -- A copy of the old installed-file that is used to lookup if a profile had Uninstall-events set
- event_type (str) -- A specific type ("after" or "before") that determines which events this interpreter shall look for
-
_op_remove_p
(dop)¶ Checks if a profile has an uninstall-event set, that matches event_type. If so, it calls start_event().
Parameters: dop (dict) -- The remove-operation that triggers the event
-
event_handler
(event_name)¶ Returns a function that can be used to interprete add_p- and update_p-operations.
The returned function checks for a given operation, if the profile has an event set that matches event_type and event_name. If so, it calls start_event().
Parameters: event_name (str) -- Name of the event that shall be interpreted by the returned function
-
get_profile
(profilename)¶ Gets a profile from
self.profiles
by it's name.Parameters: profilename (str) -- Name of the profile that will be searched for. Returns: Profile -- The corresponding profile
-
run_script
(script_path, profilename)¶ Used to handle script execution of an event. Depending on the subclass this might execute or just print out the script.
Parameters: - script_path (str) -- The path of the script that was generated for an event
- profilename (str) -- The name of the profile whose event is executed
-
start_event
(profile_name, event_name)¶ Finds the generated script for a specific profile and event. Calls run_script() for the found script.
Parameters: - profile_name (str) -- The name of the profile for which the generated script is searched
- event_name (str) -- The name of the event for which the generated script is searched
-
-
class
interpreters.
EventPrintInterpreter
(profiles, installed, event_type)¶ Bases:
interpreters.EventInterpreter
This interpreter is used to print out what an event will do.
More precisly this prints out the generated shell script that would be executed by an event line by line.
-
run_script
(script_path, profilename)¶ Print the script line by line for an event of a given profile.
-
-
class
interpreters.
ExecuteInterpreter
(installed, force)¶ Bases:
interpreters.Interpreter
This interpreter actually executes the operations from the DiffLog.
It can create/delete links in the filesystem and modify the installed-file.
-
installed
¶ The installed-file that will be updated
Type: dict
-
force
¶ Stores, if
--force
was setType: bool
-
_ExecuteInterpreter__create_symlink
(name, target, uid, gid, permission, secure)¶ Create a symlink in the filesystem.
Parameters: - name (str) -- The full path of the link that will be created
- target (str) -- The full path of the file that the link will point to
- uid (int) -- The UID of the owner of the link
- gid (int) -- The GID of the owner of the link
- permission (int) -- The permissions of the target
- secure (bool) -- Wether target should have same owner as name
Raises: UnkownError
-- The link could not be created
-
_ExecuteInterpreter__remove_symlink
(path)¶ Remove a symlink. If the directory is empty, it removes the directory as well. Does this recursively for all parent directories.
Parameters: path (str) -- The path to the symlink, that will be removed
-
__init__
(installed, force)¶ Constructor.
Updates the version number of the installed-file.
Parameters: - installed (dict) -- The installed-file that will be updated
- force (bool) -- The value of
--force
-
static
_makedirs
(filename)¶ Custom
os.makedirs()
that keeps the owner of the directory.This means that it will create the directory with the same owner as of the deepest parent directory that already exists instead of using current user as owner. This is needed, because otherwise directories won't be accessible by the user, if some links would be created with root permissions.
Parameters: filename (str) -- The full path of the file that needs its directories created
-
_op_add_l
(dop)¶ Adds a link to the filesystem and adds a link entry of the corresponding profile in the installed-file.
Parameters: dop (dict) -- The add-operation that will be executed
-
_op_add_p
(dop)¶ Adds a profile entry of the installed-file.
Parameters: dop (dict) -- The add-operation that will be executed
-
_op_remove_l
(dop)¶ Removes a link from the filesystem and removes the links entry of the corresponding profile in the installed-file.
Parameters: dop (dict) -- The remove-operation that will be executed
-
_op_remove_p
(dop)¶ Removes a profile entry of the installed-file.
Parameters: dop (dict) -- The remove-operation that will be executed
-
_op_update_l
(dop)¶ Updates a link in the filesystem and updates the links entry of the corresponding profile in the installed-file.
Parameters: dop (dict) -- The update-operation that will be executed
-
_op_update_p
(dop)¶ Updates a profile entry of the installed-file.
Parameters: dop (dict) -- The update-operation that will be executed
-
_op_update_s
(dop)¶ Updates the script_path of the onUninstall-script for a profile.
Parameters: dop (dict) -- The update-operation that will be executed
-
-
class
interpreters.
GainRootInterpreter
¶ Bases:
interpreters.RootNeededInterpreter
If root permission is needed to perform the operations, this interpreter restarts the process with "sudo".
-
_op_fin
(dop)¶ Replace the process if root permission is needed with the same call of uberdot, but prepend it with "sudo".
Parameters: dop (dict) -- Unused in this implementation
-
-
class
interpreters.
PlainPrintInterpreter
¶ Bases:
interpreters.Interpreter
Prints add/remove/update-operation without any formating.
-
__init__
()¶ Constructor.
Maps
_op_*
functions toprint()
.
-
_op_fin
(dop)¶ Print "]" to show the end of an array.
Parameters: dop (dict) -- Unused in this implementation
-
_op_start
(dop)¶ Print "[" to show the start of an array.
Parameters: dop (dict) -- Unused in this implementation
-
-
class
interpreters.
PrintInterpreter
¶ Bases:
interpreters.Interpreter
Pretty-prints log messages and what a operation is going to do.
-
_op_add_l
(dop)¶ Logs/Prints out that a link was added.
Parameters: dop (dict) -- The add-operation that will be logged
-
_op_add_p
(dop)¶ Logs/Prints out that a profile was added.
Parameters: dop (dict) -- The add-operation that will be logged
-
_op_info
(dop)¶ Logs/Prints out an info-operation.
Parameters: dop (dict) -- The info-operation that will be logged
-
_op_remove_l
(dop)¶ Logs/Prints out that a link was removed.
Parameters: dop (dict) -- The remove-operation that will be logged
-
_op_remove_p
(dop)¶ Logs/Prints out that a profile was removed.
Parameters: dop (dict) -- The remove-operation that will be logged
-
_op_start
(dop)¶ Logs/Prints out the start of the linking process.
Parameters: dop (dict) -- Unused in this implementation
-
_op_update_l
(dop)¶ Logs/Prints out that a link was updated.
The message is generated according to what changed in the updated link.
Parameters: dop (dict) -- The update-operation that will be logged
-
_op_update_p
(dop)¶ Logs/Prints out that a profile was updated.
Parameters: dop (dict) -- The update-operation that will be logged
-
-
class
interpreters.
RootNeededInterpreter
¶ Bases:
interpreters.DetectRootInterpreter
Checks if root permission are required to perform all operations. Prints out all such operations.
-
content
¶ A list of tuples with (dop, description, affected_file) that stores which operations require root permission, which file or directory they affect and a description of what the operation would exactly require root permission for
Type: list
-
__init__
()¶ Constructor
-
_root_detected
(dop, description, affected_file)¶ Logs and prints out the operation that needs root permission.
Parameters: - dop (dict) -- Unused in this implementation
- description (str) -- A description of what the operation does that will require root permission
- affected_file (str) -- The file that the description refers to
-
-
class
interpreters.
SkipRootInterpreter
¶ Bases:
interpreters.DetectRootInterpreter
Skips all operations that would require root permission.
-
skipped
¶ A list of all operations that will be skipped
Type: list
-
skipped_reasons
¶ A list of tuples that counts how often a description occured
Type: list
-
__init__
()¶ Constructor
-
_op_fin
(dop)¶ Remove all operations from difflog that are collected in
self.skip
.Parameters: dop (dict) -- Unused in this implementation
-
_root_detected
(dop, description, affected_file)¶ Stores which operations needs to be skipped.
Parameters: - dop (dict) -- The operation that will be skipped
- description (str) -- A description of what the operation does that will require root permission
- affected_file (str) -- Used to determine if description refers to a file or a directory
-