def dracut_bind_mounts(root_path,):
    """Function to do bind mounts needed before running dracut"""

    log = logging.getLogger(Defaults.get_migration_log_name())

    BIND_DIRS = ['/dev', '/proc', '/sys']

    for bind_dir in BIND_DIRS:
        try:
            log.info(
                'Running mount --bind {0} {1}'.format(bind_dir, root_path + bind_dir)
            )
            Command.run(
                [
                    'mount',
                    '--bind',
                    bind_dir,
                    root_path + bind_dir
                ]
            )
        except Exception as issue:
            log.error(
                'Unable to mount: {0}'.format(issue)
            )
            raise DistMigrationCommandException(
                'Unable to mount: {0}'.format(
                    issue
                )
            ) from issue
def run_dracut(root_path):
    """Function run dracut"""

    log = logging.getLogger(Defaults.get_migration_log_name())

    try:
        log.info(
            'Running chroot {0} dracut --no-kernel --no-host-only --no-hostonly-cmdline'
            '--regenerate-all --logfile /tmp/host_independent_initrd.log -f'.format(root_path)
        )
        Command.run(
            [
                'chroot',
                root_path,
                'dracut',
                '--no-kernel',
                '--no-host-only',
                '--no-hostonly-cmdline',
                '--regenerate-all',
                '--logfile',
                '/tmp/host_independent_initrd.log',
                '-f'
            ]
        )
        Command.run(
            [
                'chroot',
                root_path,
                'cat',
                '/tmp/host_independent_initrd.log',
                '>> /var/log/distro_migration.log'
            ]
        )
        Command.run(
            [
                'chroot',
                root_path,
                'rm',
                '/tmp/host_independent_initrd.log'
            ]
        )
    except Exception as issue:
        log.error(
            'Unable to create new initrd with dracut: {0}'.format(issue)
        )
        raise DistMigrationCommandException(
            'Failed to create new initrd: {0}'.format(
                issue
            )
        ) from issue
Пример #3
0
def main():
    """
    DistMigration run zypper based migration

    Call zypper migration plugin and migrate the system.
    The output of the call is logged on the system to migrate
    """
    root_path = Defaults.get_system_root_path()

    try:
        log.info('Running migrate service')
        migration_config = MigrationConfig()
        if migration_config.is_zypper_migration_plugin_requested():
            bash_command = ' '.join([
                'zypper', 'migration', '--non-interactive',
                '--gpg-auto-import-keys', '--no-selfupdate',
                '--auto-agree-with-licenses', '--allow-vendor-change',
                '--strict-errors-dist-migration', '--replacefiles',
                '--product',
                migration_config.get_migration_product(), '--root', root_path,
                '&>>',
                Defaults.get_migration_log_file()
            ])
            Command.run(['bash', '-c', bash_command])
        else:
            bash_command = ' '.join([
                'zypper', '--non-interactive', '--gpg-auto-import-keys',
                '--root', root_path, 'dup', '--auto-agree-with-licenses',
                '--allow-vendor-change', '--replacefiles', '&>>',
                Defaults.get_migration_log_file()
            ])
            zypper_call = Command.run(['bash', '-c', bash_command],
                                      raise_on_error=False)
            if zypper_has_failed(zypper_call.returncode):
                raise DistMigrationCommandException(
                    '{0} failed with: {1}: {2}'.format(bash_command,
                                                       zypper_call.output,
                                                       zypper_call.error))
    except Exception as issue:
        etc_issue_path = os.sep.join([root_path, 'etc/issue'])
        log_path_migrated_system = os.sep + os.path.relpath(
            Defaults.get_migration_log_file(), root_path)
        with open(etc_issue_path, 'w') as issue_file:
            issue_file.write(
                'Migration has failed, for further details see {0}'.format(
                    log_path_migrated_system))
        log.error('migrate service failed with {0}'.format(issue))
        raise DistMigrationZypperException(
            'Migration failed with {0}'.format(issue))
Пример #4
0
 def test_run_failure(self, mock_popen, mock_which):
     mock_which.return_value = 'command'
     mock_popen.side_effect = DistMigrationCommandException('Run failure')
     with raises(DistMigrationCommandException):
         Command.run(['command', 'args'])
Пример #5
0
    def run(command, custom_env=None, raise_on_error=True):
        """
        Execute a program and block the caller. The return value
        is a hash containing the stdout, stderr and return code
        information. Unless raise_on_error is set to false an
        exception is thrown if the command exits with an error
        code not equal to zero

        Example:

        .. code:: python

            result = Command.run(['ls', '-l'])

        :param list command: command and arguments
        :param list custom_env: custom os.environ
        :param bool raise_on_error: control error behaviour

        :return:
            Contains call results in command type

            .. code:: python

                command(output='string', error='string', returncode=int)

        :rtype: namedtuple
        """
        from .path import Path
        command_type = namedtuple('command', ['output', 'error', 'returncode'])
        environment = os.environ
        if custom_env:
            environment = custom_env
        if not Path.which(
                command[0], custom_env=environment, access_mode=os.X_OK):
            message = 'Command "%s" not found in the environment' % command[0]
            if not raise_on_error:
                return command_type(output=None, error=None, returncode=-1)
            else:
                log.error(message)
                raise DistMigrationCommandNotFoundException(message)
        try:
            log.info('Calling: {0}'.format(command))
            process = subprocess.Popen(command,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       env=environment)
        except Exception as issue:
            raise DistMigrationCommandException('{0}: {1}: {2}'.format(
                command[0],
                type(issue).__name__, issue))
        output, error = process.communicate()
        if process.returncode != 0 and not error:
            error = bytes(b'(no output on stderr)')
        if process.returncode != 0 and not output:
            output = bytes(b'(no output on stdout)')
        if process.returncode != 0 and raise_on_error:
            log.error('EXEC: Failed with stderr: {0}, stdout: {1}'.format(
                error.decode(), output.decode()))
            raise DistMigrationCommandException(
                '{0}: stderr: {1}, stdout: {2}'.format(command[0],
                                                       error.decode(),
                                                       output.decode()))
        return command_type(output=output.decode(),
                            error=error.decode(),
                            returncode=process.returncode)