Ejemplo n.º 1
0
def install_cloud_sdk(g: guestfs.GuestFS, ubuntu_release: str) -> None:
    """ Installs Google Cloud SDK, supporting apt and snap.

  Args:
    g: A mounted GuestFS instance.
    ubuntu_release: The release nickname (eg: trusty).
  """
    try:
        run(g, 'gcloud --version')
        logging.info(
            'Found gcloud. Skipping installation of Google Cloud SDK.')
        return
    except RuntimeError:
        logging.info('Did not find previous install of gcloud.')

    if g.gcp_image_major < '18':
        g.write('/etc/apt/sources.list.d/partner.list',
                apt_cloud_sdk.format(ubuntu_release=ubuntu_release))
        utils.update_apt(g)
        utils.install_apt_packages(g, 'google-cloud-sdk')
        logging.info('Installed Google Cloud SDK with apt.')
        return

    # Starting at 18.04, Canonical installs the sdk using snap.
    # Running `snap install` directly is not an option here since it
    # requires the snapd daemon to be running on the guest.
    g.write('/etc/cloud/cloud.cfg.d/91-google-cloud-sdk.cfg',
            cloud_init_cloud_sdk)
    logging.info(
        'Google Cloud SDK will be installed using snap with cloud-init.')

    # Include /snap/bin in the PATH for startup and shutdown scripts.
    # This was present in the old guest agent, but lost in the new guest
    # agent.
    for p in [
            '/lib/systemd/system/google-shutdown-scripts.service',
            '/lib/systemd/system/google-startup-scripts.service'
    ]:
        logging.debug('[%s] Checking whether /bin/snap is on PATH.', p)
        if not g.exists(p):
            logging.debug('[%s] Skipping: Unit not found.', p)
            continue
        original_unit = g.cat(p)
        # Check whether the PATH is already set; if so, skip patching to avoid
        # overwriting existing directive.
        match = re.search('Environment=[\'"]?PATH.*',
                          original_unit,
                          flags=re.IGNORECASE)
        if match:
            logging.debug(
                '[%s] Skipping: PATH already defined in unit file: %s.', p,
                match.group())
            continue
        # Add Environment directive to unit file, and show diff in debug log.
        patched_unit = original_unit.replace('[Service]', snap_env_directive)
        g.write(p, patched_unit)
        diff = '\n'.join(Differ().compare(original_unit.splitlines(),
                                          patched_unit.splitlines()))
        logging.debug('[%s] PATH not defined. Added:\n%s', p, diff)
Ejemplo n.º 2
0
def remove_azure_agents(g):
  try:
    run(g, ['apt-get', 'remove', '-y', '-f', 'walinuxagent'])
  except Exception as e:
    logging.debug(str(e))

  try:
    run(g, ['apt-get', 'remove', '-y', '-f', 'waagent'])
  except Exception as e:
    logging.debug(str(e))
Ejemplo n.º 3
0
def reset_network_for_dhcp(spec: TranslateSpec):
    logging.info('Resetting network to DHCP for eth0.')
    spec.g.write('/etc/sysconfig/network-scripts/ifcfg-eth0', ifcfg_eth0)
    # Remove NetworkManager-config-server if it's present. The package configures
    # NetworkManager to *not* use DHCP.
    #  https://access.redhat.com/solutions/894763
    pkg = 'NetworkManager-config-server'
    if package_is_installed(spec, pkg):
        if yum_is_on_path(spec):
            run(spec.g, ['yum', 'remove', '-y', pkg])
        else:
            run(spec.g, ['rpm', '--erase', pkg])
Ejemplo n.º 4
0
def check_repos(spec: TranslateSpec) -> str:
    """Check for unreachable repos.

  YUM fails if any of its repos are unreachable. Running `yum updateinfo`
  will have a non-zero return code when it fail to update any of its repos.
  """
    if run(spec.g, 'yum --help | grep updateinfo').code != 0:
        logging.debug('command `yum updateinfo` not available. skipping test.')
        return ''
    v = 'yum updateinfo -v'
    p = run(spec.g, v)
    logging.debug('yum updateinfo -v: {}'.format(p))
    if p.code != 0:
        return 'Ensure all configured repos are reachable.'
Ejemplo n.º 5
0
def yum_install(g, *packages):
    """Install one or more packages using YUM.

  Args:
    g (guestfs.GuestFS): A mounted GuestFS instance.
    *packages (list of str): The YUM packages to be installed.

  Raises:
      RuntimeError: If there is a failure during installation.
  """
    p = None
    for i in range(6):
        # There's no sleep on the first iteration since `i` is zero.
        time.sleep(i**2)
        # Bypass HTTP proxies configured in the guest image to allow
        # import to continue when the proxy is unreachable.
        #   no_proxy="*": Disables proxies set by using the `http_proxy`
        #                 environment variable.
        #   proxy=_none_: Disables proxies set in /etc/yum.conf.
        cmd = 'no_proxy="*" yum install --setopt=proxy=_none_ -y ' + ' '.join(
            '"{0}"'.format(p) for p in packages)
        p = run(g, cmd, raiseOnError=False)
        if p.code == 0:
            return
        logging.debug('Yum install failed: {}'.format(p))
    raise RuntimeError('Failed to install {}. Details: {}.'.format(
        ', '.join(packages), p))
Ejemplo n.º 6
0
def check_yum_on_path(spec: TranslateSpec) -> str:
    """Check whether the `yum` command is available.

  If `yum` isn't found, errs is updated.
  """
    p = run(spec.g, 'yum --version', raiseOnError=False)
    logging.debug('yum --version: {}'.format(p))
    if p.code != 0:
        return 'Verify the disk\'s OS: `yum` not found.'
def check_repos(spec: TranslateSpec) -> str:
    """Check for unreachable repos.

  YUM fails if any of its repos are unreachable. Running `yum updateinfo`
  will have a non-zero return code when it fail to update any of its repos.
  """
    v = 'yum updateinfo -v'
    p = run(spec.g, v)
    logging.debug('yum updateinfo -v: {}'.format(p))
    if p.code != 0:
        return 'Ensure all configured repos are reachable.'
Ejemplo n.º 8
0
def setup_cloud_init(g: guestfs.GuestFS):
    """ Install cloud-init if not present, and configure to the cloud provider.

  Args:
    g: A mounted GuestFS instance.
  """
    a = Apt(run)
    curr_version = a.get_package_version(g, 'cloud-init')
    available_versions = a.list_available_versions(g, 'cloud-init')
    # Try to avoid installing 21.3-1, which conflicts which the guest agent.
    # On first boot, systemd reaches a deadlock deadlock and doest start
    # its unit. If a version other than 21.3-1 isn't explicitly found, *and*
    # cloud-init isn't currently installed, then this allows apt to pick the
    # version to install.
    version_to_install = Apt.determine_version_to_install(
        curr_version, available_versions, {'21.3-1'})
    pkg_to_install = ''
    if version_to_install:
        pkg_to_install = 'cloud-init=' + version_to_install
    elif curr_version == '':
        pkg_to_install = 'cloud-init'
    # If this block doesn't execute, it means that cloud-init was found
    # on the system, but there wasn't an upgrade candidate. Therefore
    # leave the version that's currently installed.
    if pkg_to_install:
        logging.info(pkg_to_install)
        utils.install_apt_packages(g, pkg_to_install)
    # Ubuntu 14.04's version of cloud-init doesn't have `clean`.
    if g.gcp_image_major > '14':
        run(g, 'cloud-init clean')
    # Remove cloud-init configs that may conflict with GCE's.
    #
    # - subiquity disables automatic network configuration
    #     https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1871975
    for cfg in [
            'azure', 'curtin', 'waagent', 'walinuxagent', 'aws', 'amazon',
            'subiquity'
    ]:
        run(g, 'rm -f /etc/cloud/cloud.cfg.d/*%s*' % cfg)
    g.write('/etc/cloud/cloud.cfg.d/91-gce-system.cfg', cloud_init_config)
Ejemplo n.º 9
0
def check_rhel_license(spec: TranslateSpec) -> str:
    """Check for an active RHEL license.

  If a license isn't found, errs is updated.
  """
    if spec.distro != Distro.RHEL or spec.use_rhel_gce_license:
        return ''

    p = run(spec.g, 'subscription-manager status', raiseOnError=False)
    logging.debug('subscription-manager: {}'.format(p))
    if p.code != 0:
        return 'subscription-manager did not find an active subscription. ' \
               'Omit `-byol` to register with on-demand licensing.'
Ejemplo n.º 10
0
def DistroSpecific(g):
    ubuntu_release = utils.GetMetadataAttribute('ubuntu_release')
    install_gce = utils.GetMetadataAttribute('install_gce_packages')

    # If present, remove any hard coded DNS settings in resolvconf.
    # This is a common workaround to include permanent changes:
    # https://askubuntu.com/questions/157154
    if g.exists('/etc/resolvconf/resolv.conf.d/base'):
        logging.info('Resetting resolvconf base.')
        run(g, 'echo "" > /etc/resolvconf/resolv.conf.d/base')

    # Reset the network to DHCP.
    if ubuntu_release == 'trusty':
        g.write('/etc/network/interfaces', network_trusty)
    elif ubuntu_release == 'xenial':
        g.write('/etc/network/interfaces', network_xenial)
    elif g.is_dir('/etc/netplan'):
        run(g, 'rm -f /etc/netplan/*.yaml')
        g.write('/etc/netplan/config.yaml', network_netplan)
        run(g, 'netplan apply')

    if install_gce == 'true':
        utils.update_apt(g)
        setup_cloud_init(g)
        remove_azure_agents(g)

        if g.gcp_image_major > '14':
            install_osconfig_agent(g)
        utils.install_apt_packages(g, 'gce-compute-image-packages')
        install_cloud_sdk(g, ubuntu_release)

    # Update grub config to log to console.
    run(g, [
        'sed', '-i',
        r's#^\(GRUB_CMDLINE_LINUX=".*\)"$#\1 console=ttyS0,38400n8"#',
        '/etc/default/grub'
    ])
    run(g, ['update-grub2'])
Ejemplo n.º 11
0
def translate():
  """Mounts the disk, runs translation steps, then unmounts the disk."""
  include_gce_packages = utils.GetMetadataAttribute(
      'install_gce_packages', 'true').lower() == 'true'
  subscription_model = utils.GetMetadataAttribute(
      'subscription_model', 'byol').lower()

  g = diskutils.MountDisk('/dev/sdb')
  release = _get_release(g)

  pkgs = release.gce_packages if include_gce_packages else []

  if subscription_model == 'gce':
    logging.info('Converting to on-demand')
    migrate.migrate(
        g=g, tar_url=release.on_demand_rpms.url,
        tar_sha256=release.on_demand_rpms.sha256,
        cloud_product=release.cloud_product,
        post_convert_packages=pkgs
    )
  else:
    _install_product(g, release)
    _refresh_zypper(g)
    _install_packages(g, pkgs)
  _install_virtio_drivers(g)
  if include_gce_packages:
    logging.info('Enabling google services.')
    for unit in g.ls('/usr/lib/systemd/system/'):
      if unit.startswith('google-'):
        run(g, ['systemctl', 'enable', '/usr/lib/systemd/system/' + unit],
            raiseOnError=True)

  _reset_network(g)
  _update_grub(g)
  utils.CommonRoutines(g)
  diskutils.UnmountDisk(g)
 def test_capture_stdout(self):
     cmd = 'echo abc123'
     result = run(_make_local_guestfs(), cmd, raiseOnError=False)
     assert result == CompletedProcess('abc123\n', '', 0, cmd)
Ejemplo n.º 13
0
def test_support_array_args():
    result = run(_make_local_guestfs(), ['echo', 'hi'])
    assert result == CompletedProcess('hi\n', '', 0, 'echo hi')
Ejemplo n.º 14
0
def test_capture_runtime_errors():
    result = run(_make_local_guestfs(), 'not-a-command')
    assert result.code != 0
    assert 'not-a-command' in result.stderr
 def test_raise_error_when_failure(self):
     cmd = '>&2 echo stderr msg; exit 1'
     with pytest.raises(RuntimeError, match='stderr msg'):
         run(_make_local_guestfs(), cmd)
 def test_return_completed_process_when_success(self):
     cmd = 'echo abc123'
     result = run(_make_local_guestfs(), cmd)
     assert result == CompletedProcess('abc123\n', '', 0, cmd)
 def test_capture_output_when_non_zero_return(self):
     cmd = 'printf content; printf err > /dev/stderr; exit 1'
     result = run(_make_local_guestfs(), cmd, raiseOnError=False)
     assert result == CompletedProcess('content', 'err', 1, cmd)
 def test_capture_runtime_errors(self):
     result = run(_make_local_guestfs(),
                  'not-a-command',
                  raiseOnError=False)
     assert result.code != 0
     assert 'not-a-command' in result.stderr
 def test_escape_array_members(self):
     result = run(_make_local_guestfs(), ['echo', 'hello', '; ls *'],
                  raiseOnError=False)
     assert result == CompletedProcess('hello ; ls *\n', '', 0,
                                       "echo hello '; ls *'")
 def test_support_array_args(self):
     result = run(_make_local_guestfs(), ['echo', 'hi'], raiseOnError=False)
     assert result == CompletedProcess('hi\n', '', 0, 'echo hi')
 def test_support_positive_code(self):
     cmd = 'exit 100'
     result = run(_make_local_guestfs(), cmd, raiseOnError=False)
     assert result == CompletedProcess('', '', 100, cmd)
Ejemplo n.º 22
0
def test_support_positive_code():
    cmd = 'exit 100'
    result = run(_make_local_guestfs(), cmd)
    assert result == CompletedProcess('', '', 100, cmd)
Ejemplo n.º 23
0
def yum_is_on_path(spec: TranslateSpec) -> bool:
    """Check whether the `yum` command is available."""
    p = run(spec.g, 'yum --version', raiseOnError=False)
    logging.debug('yum --version: {}'.format(p))
    return p.code == 0
Ejemplo n.º 24
0
def DistroSpecific(spec: TranslateSpec):
    g = spec.g
    el_release = spec.el_release
    # This must be performed prior to making network calls from the guest.
    # Otherwise, if /etc/resolv.conf is present, and has an immutable attribute,
    # guestfs will fail with:
    #
    #   rename: /sysroot/etc/resolv.conf to
    #     /sysroot/etc/i9r7obu6: Operation not permitted
    utils.common.ClearEtcResolv(g)

    # Some imported images haven't contained `/etc/yum.repos.d`.
    if not g.exists('/etc/yum.repos.d'):
        g.mkdir('/etc/yum.repos.d')

    if spec.distro == Distro.RHEL:
        if spec.use_rhel_gce_license:
            run(g, ['yum', 'remove', '-y', '*rhui*'])
            logging.info('Adding in GCE RHUI package.')
            g.write('/etc/yum.repos.d/google-cloud.repo',
                    repo_compute % el_release)
            yum_install(g, 'google-rhui-client-rhel' + el_release)

    # Historically, translations have failed for corrupt dbcache and rpmdb.
    run(g, 'yum clean -y all')

    if spec.install_gce:
        logging.info('Installing GCE packages.')
        g.write('/etc/yum.repos.d/google-cloud.repo',
                repo_compute % el_release)
        if el_release == '6':
            # yum operations fail when the epel repo is used with stale
            # ca-certificates, causing translation to fail. To avoid that,
            # update ca-certificates when the epel repo is found.
            #
            # The `--disablerepo` flag does the following:
            #  1. Skip the epel repo for *this* operation only.
            #  2. Block update if the epel repo isn't found.
            p = run(g,
                    'yum update -y ca-certificates --disablerepo=epel',
                    raiseOnError=False)
            logging.debug('Attempted conditional update of '
                          'ca-certificates. Success expected only '
                          'if epel repo is installed. Result={}'.format(p))

            # Install Google Cloud SDK from the upstream tar and create links for the
            # python27 SCL environment.
            logging.info('Installing python27 from SCL.')
            yum_install(g, 'python27')
            logging.info('Installing Google Cloud SDK from tar.')
            sdk_base_url = 'https://dl.google.com/dl/cloudsdk/channels/rapid'
            sdk_base_tar = '%s/google-cloud-sdk.tar.gz' % sdk_base_url
            tar = utils.HttpGet(sdk_base_tar)
            g.write('/tmp/google-cloud-sdk.tar.gz', tar)
            run(g,
                ['tar', 'xzf', '/tmp/google-cloud-sdk.tar.gz', '-C', '/tmp'])
            sdk_version = g.cat('/tmp/google-cloud-sdk/VERSION').strip()

            logging.info('Getting Cloud SDK Version %s', sdk_version)
            sdk_version_tar = 'google-cloud-sdk-%s-linux-x86_64.tar.gz' % sdk_version
            sdk_version_tar_url = '%s/downloads/%s' % (sdk_base_url,
                                                       sdk_version_tar)
            logging.info('Getting versioned Cloud SDK tar file from %s',
                         sdk_version_tar_url)
            tar = utils.HttpGet(sdk_version_tar_url)
            sdk_version_tar_file = os.path.join('/tmp', sdk_version_tar)
            g.write(sdk_version_tar_file, tar)
            g.mkdir_p('/usr/local/share/google')
            run(g, [
                'tar', 'xzf', sdk_version_tar_file, '-C',
                '/usr/local/share/google', '--no-same-owner'
            ])

            logging.info('Creating CloudSDK SCL symlinks.')
            sdk_bin_path = '/usr/local/share/google/google-cloud-sdk/bin'
            g.ln_s(os.path.join(sdk_bin_path, 'git-credential-gcloud.sh'),
                   os.path.join('/usr/bin', 'git-credential-gcloud.sh'))
            for binary in ['bq', 'gcloud', 'gsutil']:
                binary_path = os.path.join(sdk_bin_path, binary)
                new_bin_path = os.path.join('/usr/bin', binary)
                bin_str = '#!/bin/bash\nsource /opt/rh/python27/enable\n%s $@' % \
                    binary_path
                g.write(new_bin_path, bin_str)
                g.chmod(0o755, new_bin_path)
        else:
            g.write_append('/etc/yum.repos.d/google-cloud.repo',
                           repo_sdk % el_release)
            yum_install(g, 'google-cloud-sdk')
        yum_install(g, 'google-compute-engine', 'google-osconfig-agent')

    logging.info('Updating initramfs')
    for kver in g.ls('/lib/modules'):
        # Although each directory in /lib/modules typically corresponds to a
        # kernel version  [1], that may not always be true.
        # kernel-abi-whitelists, for example, creates extra directories in
        # /lib/modules.
        #
        # Skip building initramfs if the directory doesn't look like a
        # kernel version. Emulates the version matching from depmod [2].
        #
        # 1. https://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/lib.html
        # 2. https://kernel.googlesource.com/pub/scm/linux/kernel/git/mmarek/kmod
        # /+/tip/tools/depmod.c#2537
        if not re.match(r'^\d+.\d+', kver):
            logging.debug(
                '/lib/modules/{} doesn\'t look like a kernel directory. '
                'Skipping creation of initramfs for it'.format(kver))
            continue
        if not g.exists(os.path.join('/lib/modules', kver, 'modules.dep')):
            try:
                run(g, ['depmod', kver])
            except RuntimeError as e:
                logging.info(
                    'Failed to write initramfs for {kver}. If image fails to '
                    'boot, verify that depmod /lib/modules/{kver} runs on '
                    'the original machine'.format(kver=kver))
                logging.debug('depmod error: {}'.format(e))
                continue
        if el_release == '6':
            # Version 6 doesn't have option --kver
            run(g, ['dracut', '-v', '-f', kver])
        else:
            run(g, ['dracut', '--stdlog=1', '-f', '--kver', kver])

    logging.info('Update grub configuration')
    if el_release == '6':
        # Version 6 doesn't have grub2, file grub.conf needs to be updated by hand
        g.write('/tmp/grub_gce_generated', grub_cfg)
        run(
            g,
            r'grep -P "^[\t ]*initrd|^[\t ]*root|^[\t ]*kernel|^[\t ]*title" '
            r'/boot/grub/grub.conf >> /tmp/grub_gce_generated;'
            r'sed -i "s/console=ttyS0[^ ]*//g" /tmp/grub_gce_generated;'
            r'sed -i "/^[\t ]*kernel/s/$/ console=ttyS0,38400n8/" '
            r'/tmp/grub_gce_generated;'
            r'mv /tmp/grub_gce_generated /boot/grub/grub.conf')
    else:
        g.write('/etc/default/grub', grub2_cfg)
        run(g, ['grub2-mkconfig', '-o', '/boot/grub2/grub.cfg'])

    # Reset network for DHCP.
    logging.info('Resetting network to DHCP for eth0.')
    # Remove NetworkManager-config-server if it's present. The package configures
    # NetworkManager to *not* use DHCP.
    #  https://access.redhat.com/solutions/894763
    run(g, ['yum', 'remove', '-y', 'NetworkManager-config-server'])
    g.write('/etc/sysconfig/network-scripts/ifcfg-eth0', ifcfg_eth0)
Ejemplo n.º 25
0
def package_is_installed(spec: TranslateSpec, package: str) -> bool:
    """Check whether package is installed."""
    p = run(spec.g, ['rpm', '-q', package], raiseOnError=False)
    logging.debug('rpm -q: {}'.format(p))
    return p.code == 0
Ejemplo n.º 26
0
def DistroSpecific(g):
  ubuntu_release = utils.GetMetadataAttribute('ubuntu_release')
  install_gce = utils.GetMetadataAttribute('install_gce_packages')

  # If present, remove any hard coded DNS settings in resolvconf.
  # This is a common workaround to include permanent changes:
  # https://askubuntu.com/questions/157154
  if g.exists('/etc/resolvconf/resolv.conf.d/base'):
    logging.info('Resetting resolvconf base.')
    run(g, 'echo "" > /etc/resolvconf/resolv.conf.d/base')

  # Reset the network to DHCP.
  if ubuntu_release == 'trusty':
    g.write('/etc/network/interfaces', network_trusty)
  elif ubuntu_release == 'xenial':
    g.write('/etc/network/interfaces', network_xenial)
  elif g.is_dir('/etc/netplan'):
    run(g, 'rm -f /etc/netplan/*.yaml')
    g.write('/etc/netplan/config.yaml', network_netplan)
    run(g, 'netplan apply')

  if install_gce == 'true':
    utils.update_apt(g)
    logging.info('Installing cloud-init.')
    utils.install_apt_packages(g, 'cloud-init')
    # Ubuntu 14.04's version of cloud-init doesn't have `clean`.
    if g.gcp_image_major > '14':
      run(g, 'cloud-init clean')

    # Remove cloud-init configs that may conflict with GCE's.
    #
    # - subiquity disables automatic network configuration
    #     https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1871975
    for cfg in [
        'azure', 'curtin', 'waagent', 'walinuxagent', 'aws', 'amazon',
        'subiquity'
    ]:
      run(g, 'rm -f /etc/cloud/cloud.cfg.d/*%s*' % cfg)

    remove_azure_agents(g)

    g.write('/etc/cloud/cloud.cfg.d/91-gce-system.cfg', cloud_init_repos)

    if g.gcp_image_major > '14':
      install_osconfig_agent(g)
    utils.install_apt_packages(g, 'gce-compute-image-packages')
    install_cloud_sdk(g, ubuntu_release)

  # Update grub config to log to console.
  run(g, [
      'sed', '-i',
      r's#^\(GRUB_CMDLINE_LINUX=".*\)"$#\1 console=ttyS0,38400n8"#',
      '/etc/default/grub'
  ])
  run(g, ['update-grub2'])
 def test_capture_stderr(self):
     cmd = 'echo error msg > /dev/stderr'
     result = run(_make_local_guestfs(), cmd, raiseOnError=False)
     assert result == CompletedProcess('', 'error msg\n', 0, cmd)
Ejemplo n.º 28
0
def DistroSpecific(g):
    install_gce = utils.GetMetadataAttribute('install_gce_packages')
    deb_release = utils.GetMetadataAttribute('debian_release')

    if install_gce == 'true':
        logging.info('Installing GCE packages.')

        utils.update_apt(g)
        utils.install_apt_packages(g, 'gnupg')

        run(g, [
            'wget', 'https://packages.cloud.google.com/apt/doc/apt-key.gpg',
            '-O', '/tmp/gce_key'
        ])
        run(g, ['apt-key', 'add', '/tmp/gce_key'])
        g.rm('/tmp/gce_key')
        g.write('/etc/apt/sources.list.d/google-cloud.list',
                google_cloud.format(deb_release=deb_release))
        # Remove Azure agent.
        try:
            run(g,
                ['apt-get', 'remove', '-y', '-f', 'waagent', 'walinuxagent'])
        except Exception as e:
            logging.debug(str(e))
            logging.warn('Could not uninstall Azure agent. Continuing anyway.')

        utils.update_apt(g)
        pkgs = [
            'google-cloud-packages-archive-keyring', 'google-compute-engine'
        ]
        # Debian 8 differences:
        #   1. No NGE
        #   2. No Cloud SDK, since it requires Python 3.5+.
        #   3. No OS config agent.
        if deb_release == 'jessie':
            # Debian 8 doesn't support the new guest agent, so we need to install
            # the legacy Python version.
            pkgs += [
                'python-google-compute-engine', 'python3-google-compute-engine'
            ]
            logging.info('Skipping installation of OS Config agent. '
                         'Requires Debian 9 or newer.')
        else:
            pkgs += ['google-cloud-sdk', 'google-osconfig-agent']
        utils.install_apt_packages(g, *pkgs)

    # Update grub config to log to console.
    run(g, [
        'sed', '-i""', r'/GRUB_CMDLINE_LINUX/s#"$# console=ttyS0,38400n8"#',
        '/etc/default/grub'
    ])

    # Disable predictive network interface naming in 9+.
    if deb_release != 'jessie':
        run(g, [
            'sed', '-i',
            r's#^\(GRUB_CMDLINE_LINUX=".*\)"$#\1 net.ifnames=0 biosdevname=0"#',
            '/etc/default/grub'
        ])

    run(g, ['update-grub2'])

    # Reset network for DHCP.
    logging.info('Resetting network to DHCP for eth0.')
    g.write('/etc/network/interfaces', interfaces)
Ejemplo n.º 29
0
def test_capture_stdout():
    cmd = 'echo abc123'
    result = run(_make_local_guestfs(), cmd)
    assert result == CompletedProcess('abc123\n', '', 0, cmd)