def __init__(self, args): # Where to the backup files will be by default self.backup_directory = args.directory.rstrip('/') # Action to perform self.action = args.action.lower() if self.action == 'backup': self.archive = args.archive if self.action == 'restore': # Allow user to chose tar archive to restore from self.restore_file = args.restore_file # Backup file names self.var_lib_gravity_backup_name = "var_lib_gravity_backup.tar.gz" self.postgres_backup_name = "full_postgres_backup.sql" self.storage_backup_name = "storage_backup.tar.gz" self.repository_db_name = "all_repositories.tar" # AE5 default locations for data - DO NOT CHANGE self.postgres_container_backup = "/var/lib/postgresql/data" self.postgres_system_backup = "/opt/anaconda/storage/pgdata" # Generate some paths to make things easier in the code self.postgres_system_backup_path = "{0}/{1}".format( self.postgres_system_backup, self.postgres_backup_name) self.postgres_container_backup_path = "{0}/{1}".format( self.postgres_container_backup, self.postgres_backup_name) self.postgres_system_repo_backup_path = "{0}/{1}".format( self.postgres_system_backup, self.repository_db_name) self.postgres_container_repo_backup_path = "{0}/{1}".format( self.postgres_container_backup, self.repository_db_name) # Repository location self.repository = ("/opt/anaconda/storage/object/anaconda-repository") # Signal file for restore if self.backup_directory != '': self.signal_file = f'{self.backup_directory}/restore' else: self.signal_file = 'restore' # Sync settings self.repos_only = args.repos_only if self.repos_only: # If only doing the repos then assume sync self.sync_files = True if self.action == 'restore': self.sync_files = False self.override = args.override else: self.sync_files = args.sync if self.action == 'backup' and self.sync_files: # Set the sync user and node self.sync_user = args.sync_user self.sync_node = args.sync_node if not self.sync_node: log.error('Node to sync files to not provided') raise exceptions.MissingSyncNode( 'Node to rsync files to was not provided. Please provide ' 'the --sync-node switch with the node name') # Secret files with namespaces self.secret_files = { 'kube-system': [ 'cluster-tls', ], 'default': ['anaconda-enterprise-certs', 'anaconda-config-files'] } # Config maps self.config_maps = { 'default': [ 'anaconda-enterprise-anaconda-platform.yml', ], } # Running some checks to ensure that things are successful if (self.action == 'restore' and not self.override and self.restore_file is None): if not self.check_for_restore(): log.error('Restore signal not found') raise exceptions.RestoreSignal( 'Restore signal file not found, closing application') if self.sync_files: self.test_sync_to_backup() if self.action == 'backup': self.setup_backup_directory() self.remove_signal_restore_file() self.start_deployments = args.start_deployments self.start_username = None self.start_password = None self.to_start = [] self.no_config = args.no_config self.namespace = 'default' self.postgres_pod = None self.docker_cont_id = None self.kubectl = sh.Command('kubectl')
def main(): arguments = handle_arguments() try: process = Accord(arguments) except exceptions.RestoreSignal: log.error('Signal file for restore not found so not performing ' 'restore of AE5') sys.exit(1) if process.action == 'backup': if process.repos_only: # Backup the repository database only log.info('Backing up repository database') backup_repository_db(process) else: # Backup the full database log.info('Backing up postgres database') backup_postgres_database(process) # Backup gravity log.info('Running gravity backup') process.gravity_backup_restore('backup') # tar up all of the files log.info('Packaging all of the files with tar') file_backup_restore(process, process.action) # Backup the secrets log.info('Backing up all secrets') backup_secrets_config_maps(process) # Backup the ingress definiton log.info('Backing up all ingress definitions') backup_ingress_definitions(process) # Clean all of the secrets log.info('Sanitizing yaml files') sanitize_secrets_config_maps(process) # Drop in signal file to indicate good to restore log.info('Adding signal for restore') process.add_signal_for_restore() if process.archive: log.info('Creating tar archive for backup') process.create_tar_archive() # Sync the files if requested if process.sync_files: # Sync the anaconda repositories log.info('Syncing up repositories to restore cluster') sync_repositories(process) # Sync the backup files log.info('Syncing all backup files to restore cluster') sync_files(process) elif process.action == 'restore': if process.restore_file is not None: process.extract_tar_archive() # After extract check for the restore signle file log.info('Checking for restore signal file') if not process.check_for_restore(): raise exceptions.RestoreSignal( 'Restore signal file not found, closing application') if process.repos_only: # Restore the repository database only log.info('Restoring repositories only') restore_repo_db(process) else: # Cleanup any existing deployments or sessions running log.info('Cleaning up sessions and deployments') cleanup_sessions_deployments(process) # Scale the postgres pod down to 0 so we can do some work log.info('Scaling down postgres pod for restore') scale_postgres_pod(process, 0) # Cleanup the existing files and restore the backup log.info('Cleanup and setup directories for restore') cleanup_and_restore_files(process) # Scale the postgres pod up to 1 log.info('Scaling up postgres pod after restore') scale_postgres_pod(process, 1) # Restore the postgres database log.info('Restoring postgres database') restore_postgres_database(process) # Cleanup sessions and deployments log.info('Cleaning up postgres database') cleanup_postgres_database(process) # Restore secrets/configmaps for cluster log.info('Restoring files') restoring_files(process) restoring_ingress(process) # Restart the pods log.info('Restarting all pods') restart_pods(process) if process.start_deployments: # Restore deployments log.info('Starting up deployments that should be running') restore_deployments(process) log.info('Cleaning up restore file') process.remove_signal_restore_file()