def __init__(self, use_ee_cart = True): switch_controller_serv_name = 'pr2_controller_manager/switch_controller' list_controllers_serv_name = 'pr2_controller_manager/list_controllers' wait_for_service(switch_controller_serv_name) wait_for_service(list_controllers_serv_name) self.switch_controller_service = \ rospy.ServiceProxy(switch_controller_serv_name, SwitchController) self.list_controllers_service = \ rospy.ServiceProxy(list_controllers_serv_name, ListControllers) self.controllers = { 'joint': "_arm_controller", 'cartesian': "_cart" } if use_ee_cart: self.controllers['cartesian']= "_arm_cart_imped_controller"
def perform_backup(full_backup): env = load_environment() # Create an global exclusive lock so that the backup script # cannot be run more than one. Lock(die=True).forever() config = get_backup_config(env) backup_root = os.path.join(env["STORAGE_ROOT"], 'backup') backup_cache_dir = os.path.join(backup_root, 'cache') backup_dir = os.path.join(backup_root, 'encrypted') # Are backups disabled? if config["target"] == "off": return # On the first run, always do a full backup. Incremental # will fail. Otherwise do a full backup when the size of # the increments since the most recent full backup are # large. try: full_backup = full_backup or should_force_full(config, env) except Exception as e: # This was the first call to duplicity, and there might # be an error already. print(e) sys.exit(1) # Stop services. def service_command(service, command, quit=None): # Execute silently, but if there is an error then display the output & exit. code, ret = shell('check_output', ["/usr/sbin/service", service, command], capture_stderr=True, trap=True) if code != 0: print(ret) if quit: sys.exit(code) service_command("php7.2-fpm", "stop", quit=True) service_command("postfix", "stop", quit=True) service_command("dovecot", "stop", quit=True) # Execute a pre-backup script that copies files outside the homedir. # Run as the STORAGE_USER user, not as root. Pass our settings in # environment variables so the script has access to STORAGE_ROOT. pre_script = os.path.join(backup_root, 'before-backup') if os.path.exists(pre_script): shell('check_call', ['su', env['STORAGE_USER'], '-c', pre_script, config["target"]], env=env) # Run a backup of STORAGE_ROOT (but excluding the backups themselves!). # --allow-source-mismatch is needed in case the box's hostname is changed # after the first backup. See #396. try: shell('check_call', [ "/usr/bin/duplicity", "full" if full_backup else "incr", "--verbosity", "warning", "--no-print-statistics", "--archive-dir", backup_cache_dir, "--exclude", backup_root, "--volsize", "250", "--gpg-options", "--cipher-algo=AES256", env["STORAGE_ROOT"], config["target"], "--allow-source-mismatch" ] + rsync_ssh_options, get_env(env)) finally: # Start services again. service_command("dovecot", "start", quit=False) service_command("postfix", "start", quit=False) service_command("php7.2-fpm", "start", quit=False) # Remove old backups. This deletes all backup data no longer needed # from more than 3 days ago. shell('check_call', [ "/usr/bin/duplicity", "remove-older-than", "%dD" % config["min_age_in_days"], "--verbosity", "error", "--archive-dir", backup_cache_dir, "--force", config["target"] ] + rsync_ssh_options, get_env(env)) # From duplicity's manual: # "This should only be necessary after a duplicity session fails or is # aborted prematurely." # That may be unlikely here but we may as well ensure we tidy up if # that does happen - it might just have been a poorly timed reboot. shell('check_call', [ "/usr/bin/duplicity", "cleanup", "--verbosity", "error", "--archive-dir", backup_cache_dir, "--force", config["target"] ] + rsync_ssh_options, get_env(env)) # Change ownership of backups to the user-data user, so that the after-bcakup # script can access them. if get_target_type(config) == 'file': shell('check_call', ["/bin/chown", "-R", env["STORAGE_USER"], backup_dir]) # Execute a post-backup script that does the copying to a remote server. # Run as the STORAGE_USER user, not as root. Pass our settings in # environment variables so the script has access to STORAGE_ROOT. post_script = os.path.join(backup_root, 'after-backup') if os.path.exists(post_script): shell('check_call', ['su', env['STORAGE_USER'], '-c', post_script, config["target"]], env=env) # Our nightly cron job executes system status checks immediately after this # backup. Since it checks that dovecot and postfix are running, block for a # bit (maximum of 10 seconds each) to give each a chance to finish restarting # before the status checks might catch them down. See #381. wait_for_service(25, True, env, 10) wait_for_service(993, True, env, 10)
def perform_backup(full_backup): env = load_environment() exclusive_process("backup") config = get_backup_config(env) backup_root = os.path.join(env["STORAGE_ROOT"], "backup") backup_cache_dir = os.path.join(backup_root, "cache") backup_dir = os.path.join(backup_root, "encrypted") # Are backups dissbled? if config["target"] == "off": return # In an older version of this script, duplicity was called # such that it did not encrypt the backups it created (in # backup/duplicity), and instead openssl was called separately # after each backup run, creating AES256 encrypted copies of # each file created by duplicity in backup/encrypted. # # We detect the transition by the presence of backup/duplicity # and handle it by 'dupliception': we move all the old *un*encrypted # duplicity files up out of the backup/duplicity directory (as # backup/ is excluded from duplicity runs) in order that it is # included in the next run, and we delete backup/encrypted (which # duplicity will output files directly to, post-transition). old_backup_dir = os.path.join(backup_root, "duplicity") migrated_unencrypted_backup_dir = os.path.join(env["STORAGE_ROOT"], "migrated_unencrypted_backup") if os.path.isdir(old_backup_dir): # Move the old unencrypted files to a new location outside of # the backup root so they get included in the next (new) backup. # Then we'll delete them. Also so that they do not get in the # way of duplicity doing a full backup on the first run after # we take care of this. shutil.move(old_backup_dir, migrated_unencrypted_backup_dir) # The backup_dir (backup/encrypted) now has a new purpose. # Clear it out. shutil.rmtree(backup_dir) # On the first run, always do a full backup. Incremental # will fail. Otherwise do a full backup when the size of # the increments since the most recent full backup are # large. try: full_backup = full_backup or should_force_full(config, env) except Exception as e: # This was the first call to duplicity, and there might # be an error already. print(e) sys.exit(1) # Stop services. def service_command(service, command, quit=None): # Execute silently, but if there is an error then display the output & exit. code, ret = shell("check_output", ["/usr/sbin/service", service, command], capture_stderr=True, trap=True) if code != 0: print(ret) if quit: sys.exit(code) service_command("php5-fpm", "stop", quit=True) service_command("postfix", "stop", quit=True) service_command("dovecot", "stop", quit=True) # Execute a pre-backup script that copies files outside the homedir. # Run as the STORAGE_USER user, not as root. Pass our settings in # environment variables so the script has access to STORAGE_ROOT. pre_script = os.path.join(backup_root, "before-backup") if os.path.exists(pre_script): shell("check_call", ["su", env["STORAGE_USER"], "-c", pre_script, config["target"]], env=env) # Run a backup of STORAGE_ROOT (but excluding the backups themselves!). # --allow-source-mismatch is needed in case the box's hostname is changed # after the first backup. See #396. try: shell( "check_call", [ "/usr/bin/duplicity", "full" if full_backup else "incr", "--verbosity", "warning", "--no-print-statistics", "--archive-dir", backup_cache_dir, "--exclude", backup_root, "--volsize", "250", "--gpg-options", "--cipher-algo=AES256", env["STORAGE_ROOT"], config["target"], "--allow-source-mismatch", ], get_env(env), ) finally: # Start services again. service_command("dovecot", "start", quit=False) service_command("postfix", "start", quit=False) service_command("php5-fpm", "start", quit=False) # Once the migrated backup is included in a new backup, it can be deleted. if os.path.isdir(migrated_unencrypted_backup_dir): shutil.rmtree(migrated_unencrypted_backup_dir) # Remove old backups. This deletes all backup data no longer needed # from more than 3 days ago. shell( "check_call", [ "/usr/bin/duplicity", "remove-older-than", "%dD" % config["min_age_in_days"], "--verbosity", "error", "--archive-dir", backup_cache_dir, "--force", config["target"], ], get_env(env), ) # From duplicity's manual: # "This should only be necessary after a duplicity session fails or is # aborted prematurely." # That may be unlikely here but we may as well ensure we tidy up if # that does happen - it might just have been a poorly timed reboot. shell( "check_call", [ "/usr/bin/duplicity", "cleanup", "--verbosity", "error", "--archive-dir", backup_cache_dir, "--force", config["target"], ], get_env(env), ) # Change ownership of backups to the user-data user, so that the after-bcakup # script can access them. if get_target_type(config) == "file": shell("check_call", ["/bin/chown", "-R", env["STORAGE_USER"], backup_dir]) # Execute a post-backup script that does the copying to a remote server. # Run as the STORAGE_USER user, not as root. Pass our settings in # environment variables so the script has access to STORAGE_ROOT. post_script = os.path.join(backup_root, "after-backup") if os.path.exists(post_script): shell("check_call", ["su", env["STORAGE_USER"], "-c", post_script, config["target"]], env=env) # Our nightly cron job executes system status checks immediately after this # backup. Since it checks that dovecot and postfix are running, block for a # bit (maximum of 10 seconds each) to give each a chance to finish restarting # before the status checks might catch them down. See #381. wait_for_service(25, True, env, 10) wait_for_service(993, True, env, 10)
def perform_backup(full_backup): env = load_environment() exclusive_process("backup") config = get_backup_config(env) backup_root = os.path.join(env["STORAGE_ROOT"], 'backup') backup_cache_dir = os.path.join(backup_root, 'cache') backup_dir = os.path.join(backup_root, 'encrypted') # Are backups dissbled? if config["target"] == "off": return # In an older version of this script, duplicity was called # such that it did not encrypt the backups it created (in # backup/duplicity), and instead openssl was called separately # after each backup run, creating AES256 encrypted copies of # each file created by duplicity in backup/encrypted. # # We detect the transition by the presence of backup/duplicity # and handle it by 'dupliception': we move all the old *un*encrypted # duplicity files up out of the backup/duplicity directory (as # backup/ is excluded from duplicity runs) in order that it is # included in the next run, and we delete backup/encrypted (which # duplicity will output files directly to, post-transition). old_backup_dir = os.path.join(backup_root, 'duplicity') migrated_unencrypted_backup_dir = os.path.join(env["STORAGE_ROOT"], "migrated_unencrypted_backup") if os.path.isdir(old_backup_dir): # Move the old unencrypted files to a new location outside of # the backup root so they get included in the next (new) backup. # Then we'll delete them. Also so that they do not get in the # way of duplicity doing a full backup on the first run after # we take care of this. shutil.move(old_backup_dir, migrated_unencrypted_backup_dir) # The backup_dir (backup/encrypted) now has a new purpose. # Clear it out. shutil.rmtree(backup_dir) # On the first run, always do a full backup. Incremental # will fail. Otherwise do a full backup when the size of # the increments since the most recent full backup are # large. try: full_backup = full_backup or should_force_full(config, env) except Exception as e: # This was the first call to duplicity, and there might # be an error already. print(e) sys.exit(1) # Stop services. def service_command(service, command, quit=None): # Execute silently, but if there is an error then display the output & exit. code, ret = shell('check_output', ["/usr/sbin/service", service, command], capture_stderr=True, trap=True) if code != 0: print(ret) if quit: sys.exit(code) service_command("postfix", "stop", quit=True) service_command("dovecot", "stop", quit=True) # Execute a pre-backup script that copies files outside the homedir. # Run as the STORAGE_USER user, not as root. Pass our settings in # environment variables so the script has access to STORAGE_ROOT. pre_script = os.path.join(backup_root, 'before-backup') if os.path.exists(pre_script): shell('check_call', ['su', env['STORAGE_USER'], '-c', pre_script, config["target"]], env=env) # Run a backup of STORAGE_ROOT (but excluding the backups themselves!). # --allow-source-mismatch is needed in case the box's hostname is changed # after the first backup. See #396. try: shell('check_call', [ "/usr/bin/duplicity", "full" if full_backup else "incr", "--verbosity", "warning", "--no-print-statistics", "--archive-dir", backup_cache_dir, "--exclude", backup_root, "--volsize", "250", "--gpg-options", "--cipher-algo=AES256", env["STORAGE_ROOT"], config["target"], "--allow-source-mismatch" ], get_env(env)) finally: # Start services again. service_command("dovecot", "start", quit=False) service_command("postfix", "start", quit=False) # Once the migrated backup is included in a new backup, it can be deleted. if os.path.isdir(migrated_unencrypted_backup_dir): shutil.rmtree(migrated_unencrypted_backup_dir) # Remove old backups. This deletes all backup data no longer needed # from more than 3 days ago. shell('check_call', [ "/usr/bin/duplicity", "remove-older-than", "%dD" % config["min_age_in_days"], "--verbosity", "error", "--archive-dir", backup_cache_dir, "--force", config["target"] ], get_env(env)) # From duplicity's manual: # "This should only be necessary after a duplicity session fails or is # aborted prematurely." # That may be unlikely here but we may as well ensure we tidy up if # that does happen - it might just have been a poorly timed reboot. shell('check_call', [ "/usr/bin/duplicity", "cleanup", "--verbosity", "error", "--archive-dir", backup_cache_dir, "--force", config["target"] ], get_env(env)) # Change ownership of backups to the user-data user, so that the after-bcakup # script can access them. if get_target_type(config) == 'file': shell('check_call', ["/bin/chown", "-R", env["STORAGE_USER"], backup_dir]) # Execute a post-backup script that does the copying to a remote server. # Run as the STORAGE_USER user, not as root. Pass our settings in # environment variables so the script has access to STORAGE_ROOT. post_script = os.path.join(backup_root, 'after-backup') if os.path.exists(post_script): shell('check_call', ['su', env['STORAGE_USER'], '-c', post_script, config["target"]], env=env) # Our nightly cron job executes system status checks immediately after this # backup. Since it checks that dovecot and postfix are running, block for a # bit (maximum of 10 seconds each) to give each a chance to finish restarting # before the status checks might catch them down. See #381. wait_for_service(25, True, env, 10) wait_for_service(993, True, env, 10)
def perform_backup(full_backup): env = load_environment() exclusive_process("backup") backup_root = os.path.join(env["STORAGE_ROOT"], 'backup') backup_cache_dir = os.path.join(backup_root, 'cache') backup_dir = os.path.join(backup_root, 'encrypted') # In an older version of this script, duplicity was called # such that it did not encrypt the backups it created (in # backup/duplicity), and instead openssl was called separately # after each backup run, creating AES256 encrypted copies of # each file created by duplicity in backup/encrypted. # # We detect the transition by the presence of backup/duplicity # and handle it by 'dupliception': we move all the old *un*encrypted # duplicity files up out of the backup/duplicity directory (as # backup/ is excluded from duplicity runs) in order that it is # included in the next run, and we delete backup/encrypted (which # duplicity will output files directly to, post-transition). old_backup_dir = os.path.join(backup_root, 'duplicity') migrated_unencrypted_backup_dir = os.path.join(env["STORAGE_ROOT"], "migrated_unencrypted_backup") if os.path.isdir(old_backup_dir): # Move the old unencrypted files to a new location outside of # the backup root so they get included in the next (new) backup. # Then we'll delete them. Also so that they do not get in the # way of duplicity doing a full backup on the first run after # we take care of this. shutil.move(old_backup_dir, migrated_unencrypted_backup_dir) # The backup_dir (backup/encrypted) now has a new purpose. # Clear it out. shutil.rmtree(backup_dir) # On the first run, always do a full backup. Incremental # will fail. Otherwise do a full backup when the size of # the increments since the most recent full backup are # large. full_backup = full_backup or should_force_full(env) # Stop services. shell('check_call', ["/usr/sbin/service", "dovecot", "stop"]) shell('check_call', ["/usr/sbin/service", "postfix", "stop"]) # Get the encryption passphrase. secret_key.txt is 2048 random # bits base64-encoded and with line breaks every 65 characters. # gpg will only take the first line of text, so sanity check that # that line is long enough to be a reasonable passphrase. It # only needs to be 43 base64-characters to match AES256's key # length of 32 bytes. with open(os.path.join(backup_root, 'secret_key.txt')) as f: passphrase = f.readline().strip() if len(passphrase) < 43: raise Exception("secret_key.txt's first line is too short!") env_with_passphrase = { "PASSPHRASE" : passphrase } # Run a backup of STORAGE_ROOT (but excluding the backups themselves!). # --allow-source-mismatch is needed in case the box's hostname is changed # after the first backup. See #396. try: shell('check_call', [ "/usr/bin/duplicity", "full" if full_backup else "incr", "--archive-dir", backup_cache_dir, "--exclude", backup_root, "--volsize", "250", "--gpg-options", "--cipher-algo=AES256", env["STORAGE_ROOT"], "file://" + backup_dir, "--allow-source-mismatch" ], env_with_passphrase) finally: # Start services again. shell('check_call', ["/usr/sbin/service", "dovecot", "start"]) shell('check_call', ["/usr/sbin/service", "postfix", "start"]) # Once the migrated backup is included in a new backup, it can be deleted. if os.path.isdir(migrated_unencrypted_backup_dir): shutil.rmtree(migrated_unencrypted_backup_dir) # Remove old backups. This deletes all backup data no longer needed # from more than 3 days ago. shell('check_call', [ "/usr/bin/duplicity", "remove-older-than", "%dD" % keep_backups_for_days, "--archive-dir", backup_cache_dir, "--force", "file://" + backup_dir ], env_with_passphrase) # From duplicity's manual: # "This should only be necessary after a duplicity session fails or is # aborted prematurely." # That may be unlikely here but we may as well ensure we tidy up if # that does happen - it might just have been a poorly timed reboot. shell('check_call', [ "/usr/bin/duplicity", "cleanup", "--archive-dir", backup_cache_dir, "--force", "file://" + backup_dir ], env_with_passphrase) # Change ownership of backups to the user-data user, so that the after-bcakup # script can access them. shell('check_call', ["/bin/chown", "-R", env["STORAGE_USER"], backup_dir]) # Execute a post-backup script that does the copying to a remote server. # Run as the STORAGE_USER user, not as root. Pass our settings in # environment variables so the script has access to STORAGE_ROOT. post_script = os.path.join(backup_root, 'after-backup') if os.path.exists(post_script): shell('check_call', ['su', env['STORAGE_USER'], '-c', post_script], env=env) # Our nightly cron job executes system status checks immediately after this # backup. Since it checks that dovecot and postfix are running, block for a # bit (maximum of 10 seconds each) to give each a chance to finish restarting # before the status checks might catch them down. See #381. wait_for_service(25, True, env, 10) wait_for_service(993, True, env, 10)
def perform_backup(full_backup): env = load_environment() exclusive_process("backup") backup_root = os.path.join(env["STORAGE_ROOT"], 'backup') backup_cache_dir = os.path.join(backup_root, 'cache') backup_dir = os.path.join(backup_root, 'encrypted') # In an older version of this script, duplicity was called # such that it did not encrypt the backups it created (in # backup/duplicity), and instead openssl was called separately # after each backup run, creating AES256 encrypted copies of # each file created by duplicity in backup/encrypted. # # We detect the transition by the presence of backup/duplicity # and handle it by 'dupliception': we move all the old *un*encrypted # duplicity files up out of the backup/duplicity directory (as # backup/ is excluded from duplicity runs) in order that it is # included in the next run, and we delete backup/encrypted (which # duplicity will output files directly to, post-transition). old_backup_dir = os.path.join(backup_root, 'duplicity') migrated_unencrypted_backup_dir = os.path.join( env["STORAGE_ROOT"], "migrated_unencrypted_backup") if os.path.isdir(old_backup_dir): # Move the old unencrypted files to a new location outside of # the backup root so they get included in the next (new) backup. # Then we'll delete them. Also so that they do not get in the # way of duplicity doing a full backup on the first run after # we take care of this. shutil.move(old_backup_dir, migrated_unencrypted_backup_dir) # The backup_dir (backup/encrypted) now has a new purpose. # Clear it out. shutil.rmtree(backup_dir) # On the first run, always do a full backup. Incremental # will fail. Otherwise do a full backup when the size of # the increments since the most recent full backup are # large. full_backup = full_backup or should_force_full(env) # Stop services. shell('check_call', ["/usr/sbin/service", "dovecot", "stop"]) shell('check_call', ["/usr/sbin/service", "postfix", "stop"]) # Get the encryption passphrase. secret_key.txt is 2048 random # bits base64-encoded and with line breaks every 65 characters. # gpg will only take the first line of text, so sanity check that # that line is long enough to be a reasonable passphrase. It # only needs to be 43 base64-characters to match AES256's key # length of 32 bytes. with open(os.path.join(backup_root, 'secret_key.txt')) as f: passphrase = f.readline().strip() if len(passphrase) < 43: raise Exception("secret_key.txt's first line is too short!") env_with_passphrase = {"PASSPHRASE": passphrase} # Update the backup mirror directory which mirrors the current # STORAGE_ROOT (but excluding the backups themselves!). try: shell('check_call', [ "/usr/bin/duplicity", "full" if full_backup else "incr", "--archive-dir", backup_cache_dir, "--exclude", backup_root, "--volsize", "250", "--gpg-options", "--cipher-algo=AES256", env["STORAGE_ROOT"], "file://" + backup_dir ], env_with_passphrase) finally: # Start services again. shell('check_call', ["/usr/sbin/service", "dovecot", "start"]) shell('check_call', ["/usr/sbin/service", "postfix", "start"]) # Once the migrated backup is included in a new backup, it can be deleted. if os.path.isdir(migrated_unencrypted_backup_dir): shutil.rmtree(migrated_unencrypted_backup_dir) # Remove old backups. This deletes all backup data no longer needed # from more than 3 days ago. shell('check_call', [ "/usr/bin/duplicity", "remove-older-than", "%dD" % keep_backups_for_days, "--archive-dir", backup_cache_dir, "--force", "file://" + backup_dir ], env_with_passphrase) # From duplicity's manual: # "This should only be necessary after a duplicity session fails or is # aborted prematurely." # That may be unlikely here but we may as well ensure we tidy up if # that does happen - it might just have been a poorly timed reboot. shell('check_call', [ "/usr/bin/duplicity", "cleanup", "--archive-dir", backup_cache_dir, "--force", "file://" + backup_dir ], env_with_passphrase) # Change ownership of backups to the user-data user, so that the after-bcakup # script can access them. shell('check_call', ["/bin/chown", "-R", env["STORAGE_USER"], backup_dir]) # Execute a post-backup script that does the copying to a remote server. # Run as the STORAGE_USER user, not as root. Pass our settings in # environment variables so the script has access to STORAGE_ROOT. post_script = os.path.join(backup_root, 'after-backup') if os.path.exists(post_script): shell('check_call', ['su', env['STORAGE_USER'], '-c', post_script], env=env) # Our nightly cron job executes system status checks immediately after this # backup. Since it checks that dovecot and postfix are running, block for a # bit (maximum of 10 seconds each) to give each a chance to finish restarting # before the status checks might catch them down. See #381. wait_for_service(25, True, env, 10) wait_for_service(993, True, env, 10)