diff --git a/tests/layering/build_helper_test.go b/tests/layering/build_helper_test.go index e96571c13..c4d2d0f56 100644 --- a/tests/layering/build_helper_test.go +++ b/tests/layering/build_helper_test.go @@ -12,6 +12,7 @@ import ( buildv1 "github.com/openshift/api/build/v1" imagev1 "github.com/openshift/api/image/v1" "github.com/openshift/machine-config-operator/test/framework" + "github.com/openshift/os/tests/layering/fixtures" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" @@ -61,6 +62,10 @@ func (b *builder) build(ctx context.Context) error { return nil } + if err := b.createConfigMap(ctx); err != nil { + return err + } + return b.buildDerivedOSImage(ctx) } @@ -101,17 +106,32 @@ func (b *builder) createImageStream(ctx context.Context) (*imagev1.ImageStream, return imageStream, err } +// Creates a configmap which contains the hello-world.go and +// hello-world.service files for injection into the image build context. +func (b *builder) createConfigMap(ctx context.Context) error { + configMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: buildConfigMapName, + }, + Data: map[string]string{ + "hello-world.go": fixtures.HelloWorldSrc, + "hello-world.service": fixtures.HelloWorldService, + }, + } + + _, err := b.clientSet.CoreV1Interface.ConfigMaps(mcoNamespace).Create(ctx, configMap, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("could not create build configmap: %w", err) + } + + return nil +} + // Actually perform the OS derivation build and waits for it to complete. func (b *builder) buildDerivedOSImage(ctx context.Context) error { baseImagePullSpec := getEnvVarOrDefault("BASE_IMAGE_PULLSPEC", "registry.ci.openshift.org/rhcos-devel/rhel-coreos:latest") - derivationRepoURL := getEnvVarOrDefault("DERIVATION_REPO_URL", "https://github.com/coreos/fcos-derivation-example") - derivationRepoRef := getEnvVarOrDefault("DERIVATION_REPO_REF", "rhcos") - dockerfilePath := getEnvVarOrDefault("DERIVATION_DOCKERFILE_PATH", "Dockerfile") b.t.Log("base image pullspec:", baseImagePullSpec) - b.t.Log("derivation repo URL:", derivationRepoURL) - b.t.Log("derivation repo ref:", derivationRepoRef) - b.t.Log("dockerfile path:", dockerfilePath) // Create a new build buildConfig := &buildv1.Build{ @@ -121,18 +141,21 @@ func (b *builder) buildDerivedOSImage(ctx context.Context) error { Spec: buildv1.BuildSpec{ CommonSpec: buildv1.CommonSpec{ Source: buildv1.BuildSource{ - Type: "Git", - Git: &buildv1.GitBuildSource{ - URI: derivationRepoURL, - Ref: derivationRepoRef, + ConfigMaps: []buildv1.ConfigMapBuildSource{ + { + ConfigMap: corev1.LocalObjectReference{ + Name: buildConfigMapName, + }, + DestinationDir: ".", + }, }, + Dockerfile: &fixtures.Dockerfile, }, Strategy: buildv1.BuildStrategy{ DockerStrategy: &buildv1.DockerBuildStrategy{ - DockerfilePath: dockerfilePath, BuildArgs: []corev1.EnvVar{ { - Name: "RHEL_COREOS_IMAGE", + Name: "BASE_OS_IMAGE", Value: baseImagePullSpec, }, }, diff --git a/tests/layering/fixtures/Dockerfile b/tests/layering/fixtures/Dockerfile new file mode 100644 index 000000000..9f65531a4 --- /dev/null +++ b/tests/layering/fixtures/Dockerfile @@ -0,0 +1,16 @@ +# This file is consumed by the layering test. It is embedded into +# the layering test binary via an embed directive in the +# fixtures.go file. +ARG BASE_OS_IMAGE="registry.ci.openshift.org/rhcos-devel/rhel-coreos:latest" +FROM registry.access.redhat.com/ubi8/ubi:latest as builder +WORKDIR /build +COPY . . +RUN yum -y install go-toolset +RUN go build hello-world.go + +FROM $BASE_OS_IMAGE +# Inject our Golang binary into our OS base image +COPY --from=builder /build/hello-world /usr/bin +# And add our unit file +ADD hello-world.service /etc/systemd/system/hello-world.service +RUN ostree container commit diff --git a/tests/layering/fixtures/fixtures.go b/tests/layering/fixtures/fixtures.go new file mode 100644 index 000000000..e576ed135 --- /dev/null +++ b/tests/layering/fixtures/fixtures.go @@ -0,0 +1,12 @@ +package fixtures + +import _ "embed" + +//go:embed Dockerfile +var Dockerfile string + +//go:embed hello-world.go.fixture +var HelloWorldSrc string + +//go:embed hello-world.service +var HelloWorldService string diff --git a/tests/layering/fixtures/hello-world.go.fixture b/tests/layering/fixtures/hello-world.go.fixture new file mode 100644 index 000000000..0bf42cd26 --- /dev/null +++ b/tests/layering/fixtures/hello-world.go.fixture @@ -0,0 +1,12 @@ +// This file is consumed by the layering test. It is embedded into +// the layering test binary via an embed directive in the +// fixtures.go file. +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("Hello, world!") +} diff --git a/tests/layering/fixtures/hello-world.service b/tests/layering/fixtures/hello-world.service new file mode 100644 index 000000000..367b7e425 --- /dev/null +++ b/tests/layering/fixtures/hello-world.service @@ -0,0 +1,11 @@ +# This file is consumed by the layering test. It is embedded into +# the layering test binary via an embed directive in the +# fixtures.go file. +[Unit] +Description=A hello world unit! +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/hello-world +[Install] +WantedBy=multi-user.target diff --git a/tests/layering/helpers_test.go b/tests/layering/helpers_test.go index 9f52994d8..e537c1ee5 100644 --- a/tests/layering/helpers_test.go +++ b/tests/layering/helpers_test.go @@ -125,7 +125,6 @@ func assertNotInDerivedImage(t *testing.T, cs *framework.ClientSet, node *corev1 func checkUsingImage(t *testing.T, cs *framework.ClientSet, node *corev1.Node, usingImage bool, status *Status) { // These files are placed on the node by the derived container build process. expectedFiles := []string{ - "/usr/lib64/libpixman-1.so.0", "/etc/systemd/system/hello-world.service", helloWorldPath, } diff --git a/tests/layering/layering_test.go b/tests/layering/layering_test.go index 3eff1a727..2ea1e16b3 100644 --- a/tests/layering/layering_test.go +++ b/tests/layering/layering_test.go @@ -22,12 +22,13 @@ const ( // If this moves from /run, make sure files get cleaned up authfilePath = "/run/ostree/auth.json" - buildName = imageStreamName - helloWorldPath = "/usr/bin/hello-world" - imageRegistry = "image-registry.openshift-image-registry.svc:5000" - imageStreamName = "test-boot-in-cluster-image" - imageURL = ostreeUnverifiedRegistry + ":" + imageRegistry + "/" + mcoNamespace + "/" + imageStreamName - mcoNamespace = "openshift-machine-config-operator" + buildName = imageStreamName + buildConfigMapName = buildName + "-config-map" + helloWorldPath = "/usr/bin/hello-world" + imageRegistry = "image-registry.openshift-image-registry.svc:5000" + imageStreamName = "test-boot-in-cluster-image" + imageURL = ostreeUnverifiedRegistry + ":" + imageRegistry + "/" + mcoNamespace + "/" + imageStreamName + mcoNamespace = "openshift-machine-config-operator" // ostreeUnverifiedRegistry means no GPG or container signatures are used. // Right now we're usually relying on digested pulls. See @@ -60,9 +61,11 @@ func TestBootInClusterImage(t *testing.T) { if deleteBuild != nil && *deleteBuild == true { defer func() { t.Log("Deleting the ImageStream") - require.Nil(t, cs.ImageStreams(mcoNamespace).Delete(context.TODO(), imageStreamName, metav1.DeleteOptions{})) + require.Nil(t, cs.ImageStreams(mcoNamespace).Delete(ctx, imageStreamName, metav1.DeleteOptions{})) t.Log("Deleting the Image Build") - require.Nil(t, cs.BuildV1Interface.Builds(mcoNamespace).Delete(context.TODO(), buildName, metav1.DeleteOptions{})) + require.Nil(t, cs.BuildV1Interface.Builds(mcoNamespace).Delete(ctx, buildName, metav1.DeleteOptions{})) + t.Log("Deleting the Image Build ConfigMap") + require.Nil(t, cs.CoreV1Interface.ConfigMaps(mcoNamespace).Delete(ctx, buildConfigMapName, metav1.DeleteOptions{})) }() }