def GetLatestBootstrapUrl(): base_url = 'http://mirrors.kernel.org/archlinux/iso/latest/' sha1sums = utils.HttpGet(base_url + 'sha1sums.txt') items = sha1sums.splitlines() for item in items: if TARGET_ARCH in item and 'bootstrap' in item: entries = item.split() return base_url + entries[1], entries[0] raise RuntimeError('Cannot find Arch bootstrap url')
def DistroSpecific(g: guestfs.GuestFS): el_release = utils.GetMetadataAttribute('el_release') install_gce = utils.GetMetadataAttribute('install_gce_packages') rhel_license = utils.GetMetadataAttribute('use_rhel_gce_license') # 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 rhel_license == 'true': if 'Red Hat' in g.cat('/etc/redhat-release'): g.command(['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) if install_gce == 'true': logging.info('Installing GCE packages.') g.write('/etc/yum.repos.d/google-cloud.repo', repo_compute % el_release) if el_release == '6': if 'CentOS' in g.cat('/etc/redhat-release'): logging.info('Installing CentOS SCL.') g.command(['rm', '-f', '/etc/yum.repos.d/CentOS-SCL.repo']) yum_install(g, 'centos-release-scl') # 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) g.command( ['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') g.command([ '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: g.command(['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 g.command(['dracut', '-v', '-f', kver]) else: g.command(['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) g.sh(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) g.command(['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 g.command(['yum', 'remove', '-y', 'NetworkManager-config-server']) g.write('/etc/sysconfig/network-scripts/ifcfg-eth0', ifcfg_eth0)
def DistroSpecific(g): el_release = utils.GetMetadataParam('el_release') install_gce = utils.GetMetadataParam('install_gce_packages') rhel_license = utils.GetMetadataParam('use_rhel_gce_license') if rhel_license == 'true': if 'Red Hat' in g.cat('/etc/redhat-release'): g.command(['yum', 'remove', '-y', '*rhui*']) logging.info('Adding in GCE RHUI package.') g.write('/etc/yum.repos.d/google-cloud.repo', repo_compute % el_release) g.command([ 'yum', 'install', '-y', 'google-rhui-client-rhel%s' % el_release ]) if install_gce == 'true': logging.info('Installing GCE packages.') g.write('/etc/yum.repos.d/google-cloud.repo', repo_compute % el_release) if el_release == '7': g.write_append('/etc/yum.repos.d/google-cloud.repo', repo_sdk % el_release) g.command(['yum', '-y', 'install', 'google-cloud-sdk']) if el_release == '6': if 'CentOS' in g.cat('/etc/redhat-release'): logging.info('Installing CentOS SCL.') g.command(['rm', '-f', '/etc/yum.repos.d/CentOS-SCL.repo']) g.command(['yum', '-y', 'install', 'centos-release-scl']) # Install Google Cloud SDK from the upstream tar and create links for the # python27 SCL environment. logging.info('Installing python27 from SCL.') g.command(['yum', '-y', 'install', 'python27']) g.command([ 'scl', 'enable', 'python27', 'pip2.7 install --upgrade google_compute_engine' ]) 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) g.command( ['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') g.command([ '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(0755, new_bin_path) g.command([ 'yum', '-y', 'install', 'google-compute-engine', 'python-google-compute-engine' ]) logging.info('Updating initramfs') for kver in g.ls('/lib/modules'): if el_release == '6': # Version 6 doesn't have option --kver g.command(['dracut', '-v', '-f', kver]) else: g.command(['dracut', '-v', '-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) g.sh(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) g.command(['grub2-mkconfig', '-o', '/boot/grub2/grub.cfg']) # Reset network for DHCP. logging.info('Resetting network to DHCP for eth0.') g.write('/etc/sysconfig/network-scripts/ifcfg-eth0', ifcfg_eth0)
def DistroSpecific(g): el_release = utils.GetMetadataAttribute('el_release') install_gce = utils.GetMetadataAttribute('install_gce_packages') rhel_license = utils.GetMetadataAttribute('use_rhel_gce_license') # 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) if rhel_license == 'true': if 'Red Hat' in g.cat('/etc/redhat-release'): g.command(['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) if install_gce == 'true': logging.info('Installing GCE packages.') g.write('/etc/yum.repos.d/google-cloud.repo', repo_compute % el_release) if el_release == '6': if 'CentOS' in g.cat('/etc/redhat-release'): logging.info('Installing CentOS SCL.') g.command(['rm', '-f', '/etc/yum.repos.d/CentOS-SCL.repo']) yum_install(g, 'centos-release-scl') # 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') g.command( ['scl', 'enable', 'python27', 'pip2.7 install --upgrade pip']) g.command([ 'scl', 'enable', 'python27', 'pip2.7 install --upgrade google_compute_engine' ]) 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) g.command( ['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') g.command([ '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') if el_release == '8': yum_install(g, 'google-compute-engine', 'python3-google-compute-engine') else: yum_install(g, 'google-compute-engine', 'python-google-compute-engine') logging.info('Updating initramfs') for kver in g.ls('/lib/modules'): if not g.exists(os.path.join('/lib/modules', kver, 'modules.dep')): g.command(['depmod', kver]) if el_release == '6': # Version 6 doesn't have option --kver g.command(['dracut', '-v', '-f', kver]) else: g.command(['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) g.sh(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) g.command(['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 g.command(['yum', 'remove', '-y', 'NetworkManager-config-server']) g.write('/etc/sysconfig/network-scripts/ifcfg-eth0', ifcfg_eth0)
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. if yum_is_on_path(spec): 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) logging.info('Enabling rsyslog') run(g, 'chkconfig rsyslog on') 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'): logging.debug('Updating initramfs for ' + kver) # 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 # We perform a best-effort attempt to rebuild initramfs; if there's a # failure, continue while giving the user some debug tips. This is # sensible since the existing initramfs may work for booting. Or the # failure may be associated with an older kernel that will never be used. cmds = [] if not g.exists(os.path.join('/lib/modules', kver, 'modules.dep')): cmds.append(['depmod', kver]) if el_release == '6': # Version 6 doesn't have option --kver cmds.append(['dracut', '-v', '-f', kver]) else: cmds.append(['dracut', '--stdlog=1', '-f', '--kver', kver]) for cmd in cmds: try: run(g, cmd) except RuntimeError as e: cmd_string = ' '.join(cmd) logging.debug('`{cmd}` error: {err}'.format(cmd=cmd_string, err=e)) msg = ( 'Failed to write initramfs for {kver}. If the image ' 'fails to boot: Boot the original machine, remove unused ' 'kernel versions, verify that `{cmd}` runs, re-export ' 'the disks, and re-import.').format(kver=kver, cmd=cmd_string) logging.info(msg) break 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(spec)