Skip to content

Commit

Permalink
Add cosa buildextend-layered
Browse files Browse the repository at this point in the history
As part of openshift/os#799, we'll want to
build the "OCP node" image as a layered image on top of the RHCOS base
image.

Eventually, this image should be built outside our pipelines and more
like the rest of OpenShift container images. But for now, let's build
it ourselves. This allows us to prove out the idea without yet requiring
changes in the rest of OpenShift.

The script added here looks wordy, but it's really trivial. It's
basically a glorified wrapper around `podman build` and `skopeo copy` so
that the built OCI image ends up in our `meta.json`.
  • Loading branch information
jlebon committed Apr 16, 2024
1 parent 583522a commit 71dc812
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 3 deletions.
2 changes: 1 addition & 1 deletion cmd/coreos-assembler.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
// commands we'd expect to use in the local dev path
var buildCommands = []string{"init", "fetch", "build", "run", "prune", "clean", "list"}
var advancedBuildCommands = []string{"buildfetch", "buildupload", "oc-adm-release", "push-container"}
var buildextendCommands = []string{"aliyun", "applehv", "aws", "azure", "digitalocean", "exoscale", "extensions-container", "gcp", "hashlist-experimental", "hyperv", "ibmcloud", "kubevirt", "live", "metal", "metal4k", "nutanix", "openstack", "qemu", "secex", "virtualbox", "vmware", "vultr"}
var buildextendCommands = []string{"aliyun", "applehv", "aws", "azure", "digitalocean", "exoscale", "extensions-container", "gcp", "hashlist-experimental", "hyperv", "ibmcloud", "kubevirt", "layered", "live", "metal", "metal4k", "nutanix", "openstack", "qemu", "secex", "virtualbox", "vmware", "vultr"}

var utilityCommands = []string{"aws-replicate", "compress", "copy-container", "koji-upload", "kola", "push-container-manifest", "remote-build-container", "remote-prune", "remote-session", "sign", "tag", "update-variant"}
var otherCommands = []string{"shell", "meta"}
Expand Down
3 changes: 2 additions & 1 deletion pkg/builds/cosa_v1.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package builds

// generated by 'make schema'
// source hash: 4c19aed3b3d84af278780bff63728510bb3e70613e4c4eef8cabd7939eb31bd8
// source hash: 6fb3ed460736f7d07147e5aecf581b1a417206ed30423d642620a2a0577b7952

type AdvisoryDiff []AdvisoryDiffItems

Expand Down Expand Up @@ -60,6 +60,7 @@ type Build struct {
InputHashOfTheRpmOstree string `json:"rpm-ostree-inputhash"`
Koji *Koji `json:"koji,omitempty"`
KubevirtContainer *Image `json:"kubevirt,omitempty"`
LayeredImages map[string]Artifact `json:"layered-images,omitempty"`
MetaStamp float64 `json:"coreos-assembler.meta-stamp,omitempty"`
Name string `json:"name"`
Oscontainer *Image `json:"oscontainer,omitempty"`
Expand Down
15 changes: 14 additions & 1 deletion pkg/builds/schema_doc.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Generated by ./generate-schema.sh
// Source hash: 4c19aed3b3d84af278780bff63728510bb3e70613e4c4eef8cabd7939eb31bd8
// Source hash: 6fb3ed460736f7d07147e5aecf581b1a417206ed30423d642620a2a0577b7952
// DO NOT EDIT

package builds
Expand Down Expand Up @@ -230,6 +230,7 @@ var generatedSchemaJSON = `{
"ibmcloud",
"powervs",
"images",
"layered-images",
"koji",
"oscontainer",
"extensions",
Expand Down Expand Up @@ -741,6 +742,18 @@ var generatedSchemaJSON = `{
}
}
},
"layered-images": {
"$id": "#/properties/layered-images",
"type": "object",
"title": "Layered Images",
"propertyNames": {
"pattern": "^[a-z][-a-z0-9]*$"
},
"additionalProperties": {
"type": "object",
"$ref": "#/definitions/artifact"
}
},
"ostree-commit": {
"$id": "#/properties/ostree-commit",
"type": "string",
Expand Down
155 changes: 155 additions & 0 deletions src/cmd-buildextend-layered
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#!/usr/bin/env bash
set -euo pipefail

dn=$(dirname "$0")
# shellcheck source=src/cmdlib.sh
. "${dn}"/cmdlib.sh

print_help() {
cat 1>&2 <<EOF
Usage: coreos-assembler buildextend-layered --help
coreos-assembler buildextend-layered [--force] [--build ID] <NAME>
Build a layered image on top of base oscontainer.
EOF
}

if [ ! -f /etc/cosa-supermin ] && [ -z "${COSA_BUILDEXTEND_LAYERED_FORCE_INNER:-}" ]; then

# This runs outside of supermin

# Parse options
build=
force=
rc=0
options=$(getopt --options h --longoptions help,force,build: -- "$@") || rc=$?
[ $rc -eq 0 ] || {
print_help
exit 1
}
eval set -- "$options"
while true; do
case "$1" in
-h | --help)
print_help
exit 0
;;
--force)
force=1
;;
--build)
build=$2
shift
;;
--)
shift
break
;;
-*)
fatal "$0: unrecognized option: $1"
;;
*)
break
;;
esac
shift
done

if [ $# = 0 ]; then
print_help
exit 1
fi

name=$1; shift

containerfile="src/config/Containerfile.${name}"
if [ ! -f "${containerfile}" ]; then
fatal "Containerfile does not exist: ${containerfile}"
fi

if [ -z "${build}" ]; then
build=$(get_latest_build)
if [ -z "${build}" ]; then
fatal "No build found."
fi
fi

osname=$(cosa meta --build="${build}" --get-value name)
imgname=${osname}-${build}-layered-${name}.${basearch}.ociarchive

# check if the image already exists in the meta.json
if [ -z "${force}" ]; then
path=$(cosa meta --build="${build}" --get-value "layered-images.${name}.path")
if [ "${path}" != "None" ]; then
echo "layered-${name} image already exists:"
echo "$imgname"
exit 0
fi
unset path
fi

builddir=$(get_build_dir "$build")
if [ ! -d "${builddir}" ]; then
fatal "Build dir ${builddir} does not exist."
fi

oscontainer_meta_path=$(cosa meta --build="${build}" --get-value images.ostree.path)
oscontainer="builds/${build}/${basearch}/${oscontainer_meta_path}"
tmp_builddir="tmp/buildextend-layered-${name}"
rm -rf "${tmp_builddir}" && mkdir -p "${tmp_builddir}"
outfile="${tmp_builddir}/${imgname}"

# A common pattern in the local developer path is to wrap `podman` so that
# it actually runs on the host. If privileged (proxy for "developer setup")
# and `podman info` works, use podman directly.
if has_privileges && podman info &>/dev/null; then
COSA_BUILDEXTEND_LAYERED_FORCE_INNER=1 cosa buildextend-layered "${name}" "${containerfile}" "${oscontainer}" "${outfile}"
else
cosa supermin-run /usr/lib/coreos-assembler/cmd-buildextend-layered "${name}" "${containerfile}" "${oscontainer}" "${outfile}"
fi

# everything below is standard "add to meta.json and mv artifact to builddir"

sha256=$(sha256sum_str < "${outfile}")
cosa meta --build "${build}" --dump | python3 -c "
import sys, json
j = json.load(sys.stdin)
if 'layered-images' not in j:
j['layered-images'] = {}
j['layered-images']['${name}'] = {
'path': '${imgname}',
'sha256': '${sha256}',
'size': $(stat -c '%s' "${outfile}")
}
json.dump(j, sys.stdout, indent=4)" | jq -s add > "${tmp_builddir}/meta.json.new"

cosa meta --build "${build}" --artifact "layered-${name}" --artifact-json "$(readlink -f "${tmp_builddir}/meta.json.new")"
/usr/lib/coreos-assembler/finalize-artifact "${outfile}" "${builddir}/${imgname}"

rm -rf "${tmp_builddir}"
else
# This runs inside supermin (or still outside if
# COSA_BUILDEXTEND_LAYERED_FORCE_INNER is set)

name=$1; shift
containerfile=$1; shift
oscontainer=$1; shift
outfile=$1; shift

set --
# we'll mount in the config and yumrepos dir
set -- "$@" --volume "$(pwd)/src/config":/run/src/config:ro
if [ -e src/yumrepos ]; then
set -- "$@" --volume "$(pwd)/src/yumrepos":/run/src/yumrepos:ro
fi

# mount ca-trust if some repos need a custom root CA.
set -- "$@" --volume /etc/pki/ca-trust:/etc/pki/ca-trust:ro

# we disable labeling to not require the mounts above to be container_file_t
set -- "$@" --security-opt label=disable

podman build -t "localhost/cosa-layered-${name}" -f "${containerfile}" \
--from oci-archive:"${oscontainer}" "$@"
skopeo copy containers-storage:"localhost/cosa-layered-${name}" oci-archive:"${outfile}"
fi
13 changes: 13 additions & 0 deletions src/v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@
"ibmcloud",
"powervs",
"images",
"layered-images",
"koji",
"oscontainer",
"extensions",
Expand Down Expand Up @@ -735,6 +736,18 @@
}
}
},
"layered-images": {
"$id": "#/properties/layered-images",
"type": "object",
"title": "Layered Images",
"propertyNames": {
"pattern": "^[a-z][-a-z0-9]*$"
},
"additionalProperties": {
"type": "object",
"$ref": "#/definitions/artifact"
}
},
"ostree-commit": {
"$id": "#/properties/ostree-commit",
"type": "string",
Expand Down

0 comments on commit 71dc812

Please sign in to comment.