diff --git a/build_library/oem_aci_util.sh b/build_library/oem_aci_util.sh new file mode 100644 index 0000000000..80100818eb --- /dev/null +++ b/build_library/oem_aci_util.sh @@ -0,0 +1,124 @@ +# Copyright (c) 2016 The CoreOS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Expects BOARD, BUILD_DIR, BUILD_LIBRARY_DIR, and COREOS_VERSION in env. + +# There must be a manifest template included with the ebuild at +# files/manifest.in, which will have some variable values substituted before +# being written into place for the ACI. Optionally, a shell script can also be +# included at files/manglefs.sh to be run after all packages are installed. It +# is intended to be used to make modifications to the file system layout and +# program paths that some included agent software might expect. + +# Copied from create_prod_image() +create_oem_aci_image() { + local image_name="$1" + local disk_layout="$2" + local update_group="$3" + local base_pkg="${4?No base package was specified}" + + info "Building OEM ACI staging image ${image_name}" + local root_fs_dir="${BUILD_DIR}/rootfs" + local image_contents="${image_name%.bin}_contents.txt" + local image_packages="${image_name%.bin}_packages.txt" + local image_licenses="${image_name%.bin}_licenses.txt" + + start_image \ + "${image_name}" "${disk_layout}" "${root_fs_dir}" "${update_group}" + + # Install minimal GCC (libs only) and then everything else + set_image_profile oem-aci + extract_prod_gcc "${root_fs_dir}" + emerge_to_image "${root_fs_dir}" "${base_pkg}" + run_ldconfig "${root_fs_dir}" + write_packages "${root_fs_dir}" "${BUILD_DIR}/${image_packages}" + write_licenses "${root_fs_dir}" "${BUILD_DIR}/${image_licenses}" + extract_docs "${root_fs_dir}" || : # This is allowed to fail. + + # clean-ups of things we do not need + sudo rm ${root_fs_dir}/etc/csh.env + sudo rm -rf ${root_fs_dir}/etc/env.d + sudo rm -rf ${root_fs_dir}/var/db/pkg + + sudo mv ${root_fs_dir}/etc/profile.env \ + ${root_fs_dir}/usr/share/baselayout/profile.env + + # Move the ld.so configs into /usr so they can be symlinked from / + sudo mv ${root_fs_dir}/etc/ld.so.conf ${root_fs_dir}/usr/lib + sudo mv ${root_fs_dir}/etc/ld.so.conf.d ${root_fs_dir}/usr/lib + + sudo ln --symbolic ../usr/lib/ld.so.conf ${root_fs_dir}/etc/ld.so.conf + + # Add a tmpfiles rule that symlink ld.so.conf from /usr into / + sudo tee "${root_fs_dir}/usr/lib/tmpfiles.d/baselayout-ldso.conf" \ + > /dev/null </dev/null) + local staging_image="coreos_oem_${oem}_aci_stage.bin" + + [ -n "${ebuild}" ] || die_notrace "No ebuild exists for OEM \"${oem}\"" + grep -Fqs '(meta package)' "${ebuild}" || + die_notrace "The \"${base_pkg}\" ebuild is not a meta package" + + # Build a staging image for this OEM. + create_oem_aci_image "${staging_image}" container stable "${base_pkg}" + + # Remount the staging image to brutalize the rootfs for broken services. + "${BUILD_LIBRARY_DIR}/disk_util" --disk_layout=container \ + mount "${BUILD_DIR}/${staging_image}" "${aciroot}/rootfs" + trap "cleanup_mounts '${aciroot}/rootfs' && delete_prompt" EXIT + [ -r "${ebuild%/*}/files/manglefs.sh" ] && + sudo sh -c "cd '${aciroot}/rootfs' && . '${ebuild%/*}/files/manglefs.sh'" + + # Substitute variables into the OEM manifest to produce the final version. + oem_aci_write_manifest \ + "${ebuild%/*}/files/manifest.in" \ + "${aciroot}/manifest" \ + "coreos.com/oem-${oem}" + + # Write a tar ACI file containing the manifest and mounted rootfs contents. + sudo tar -C "${aciroot}" -czf "${BUILD_DIR}/coreos-oem-${oem}.aci" \ + manifest rootfs + + # Unmount the staging image, and delete it to save space. + cleanup_mounts "${aciroot}/rootfs" + trap - EXIT + rm -f "${BUILD_DIR}/${staging_image}" +} diff --git a/build_library/vm_image_util.sh b/build_library/vm_image_util.sh index 770176758b..e6678a927b 100644 --- a/build_library/vm_image_util.sh +++ b/build_library/vm_image_util.sh @@ -216,6 +216,7 @@ IMG_iso_CONF_FORMAT=iso IMG_gce_DISK_LAYOUT=vm IMG_gce_CONF_FORMAT=gce IMG_gce_OEM_PACKAGE=oem-gce +IMG_gce_OEM_ACI=gce ## rackspace IMG_rackspace_OEM_PACKAGE=oem-rackspace @@ -444,6 +445,34 @@ install_oem_package() { sudo rm -rf "${oem_tmp}" } +# Write the OEM ACI file into the OEM partition. +install_oem_aci() { + local oem_aci=$(_get_vm_opt OEM_ACI) + local aci_dir="${FLAGS_to}/oem-${oem_aci}-aci" + local aci_path="${aci_dir}/coreos-oem-${oem_aci}.aci" + local binpkgflags=(--nogetbinpkg) + + [ -n "${oem_aci}" ] || return 0 + + [ "${FLAGS_getbinpkg}" = "${FLAGS_TRUE}" ] && + binpkgflags=(--getbinpkg --getbinpkgver="${FLAGS_getbinpkgver}") + + # Build an OEM ACI if necessary, supplying build environment flags. + [ -e "${aci_path}" ] && + info "ACI ${aci_path} exists; reusing it" || + "${SCRIPT_ROOT}/build_oem_aci" \ + --board="${BOARD}" \ + --build_dir="${aci_dir}" \ + "${binpkgflags[@]}" \ + "${oem_aci}" + + info "Installing ${oem_aci} OEM ACI" + sudo install -Dpm 0644 \ + "${aci_path}" \ + "${VM_TMP_ROOT}/usr/share/oem/coreos-oem-${oem_aci}.aci" || + die "Could not install ${oem_aci} OEM ACI" +} + # Any other tweaks required? run_fs_hook() { local fs_hook=$(_get_vm_opt FS_HOOK) diff --git a/build_oem_aci b/build_oem_aci new file mode 100755 index 0000000000..dd6325d48f --- /dev/null +++ b/build_oem_aci @@ -0,0 +1,78 @@ +#!/bin/bash + +# Copyright (c) 2016 The CoreOS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This is a wrapper around the oem_aci_util.sh functions to set up the +# necessary environment, similar to the build_image script. + +SCRIPT_ROOT=$(dirname $(readlink -f "$0")) +. "${SCRIPT_ROOT}/common.sh" || exit 1 + +# Script must run inside the chroot +restart_in_chroot_if_needed "$@" + +assert_not_root_user + +# Developer-visible flags. +DEFINE_string board "${DEFAULT_BOARD}" \ + "The board to build an image for." +DEFINE_string build_dir "" \ + "Directory in which to place image result directories (named by version)" +DEFINE_boolean getbinpkg "${FLAGS_FALSE}" \ + "Download binary packages from remote repository." +DEFINE_string getbinpkgver "" \ + "Use binary packages from a specific version." + +FLAGS_HELP="USAGE: build_oem_aci [flags] [oem name]. +This script is used to build a CoreOS OEM ACI. + +Examples: + +build_oem_aci --board=amd64-usr --build_dir= gce +... +" +show_help_if_requested "$@" + +# The following options are advanced options, only available to those willing +# to read the source code. They are not shown in help output, since they are +# not needed for the typical developer workflow. +DEFINE_integer build_attempt 1 \ + "The build attempt for this image build." +DEFINE_string group "oem-aci" \ + "The update group (not used for actual updates here)" +DEFINE_string output_root "${DEFAULT_BUILD_ROOT}/images" \ + "Directory in which to place image result directories (named by version)" +DEFINE_string version "" \ + "Overrides version number in name to this version." + +# Parse command line. +FLAGS "$@" || exit 1 +[ -z "${FLAGS_ARGV}" ] && echo 'No OEM given' && exit 0 +eval set -- "${FLAGS_ARGV}" + +# Only now can we die on error. shflags functions leak non-zero error codes, +# so will die prematurely if 'switch_to_strict_mode' is specified before now. +switch_to_strict_mode + +# If downloading packages is enabled ensure the board is configured properly. +if [[ ${FLAGS_getbinpkg} -eq ${FLAGS_TRUE} ]]; then + "${SRC_ROOT}/scripts/setup_board" --board="${FLAGS_board}" \ + --getbinpkgver="${FLAGS_getbinpkgver}" --regen_configs_only +fi + +# N.B. Ordering matters for some of the libraries below, because +# some of the files contain initialization used by later files. +. "${BUILD_LIBRARY_DIR}/toolchain_util.sh" || exit 1 +. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1 +. "${BUILD_LIBRARY_DIR}/build_image_util.sh" || exit 1 +. "${BUILD_LIBRARY_DIR}/prod_image_util.sh" || exit 1 +. "${BUILD_LIBRARY_DIR}/test_image_content.sh" || exit 1 +. "${BUILD_LIBRARY_DIR}/oem_aci_util.sh" || exit 1 + +BUILD_DIR=${FLAGS_build_dir:-$BUILD_DIR} + +for oem +do oem_aci_create "${oem}" +done diff --git a/image_to_vm.sh b/image_to_vm.sh index 21bed2dd14..8526606a2d 100755 --- a/image_to_vm.sh +++ b/image_to_vm.sh @@ -124,6 +124,7 @@ setup_disk_image "${FLAGS_disk_layout}" # Optionally install any OEM packages install_oem_package +install_oem_aci run_fs_hook # Changes done, glue it together