Exemple #1
0
    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')
Exemple #2
0
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()