shipwright-io / build

Shipwright - a framework for building container images on Kubernetes
https://shipwright.io
Apache License 2.0
672 stars 113 forks source link

S2I Chained builds #1216

Open tommaso-borgato opened 1 year ago

tommaso-borgato commented 1 year ago

Enhancing the s2i build strategy, e.g. with a new parameter, in order to manage s2i chained builds;

This enhancement would allow us to handle WildFly s2i builds (see https://github.com/wildfly/wildfly-s2i/) which use a builder and a runtime image; in WildFly s2i builds two images are defined, one for the actual build and one for the runtime:

  s2i:
    builderImage: wildfly-s2i:latest-jdk17
    runtimeImage: wildfly-runtime:latest-jdk17
SaschaSchwarze0 commented 1 year ago

Related slack thread: https://kubernetes.slack.com/archives/C019ZRGUEJC/p1672908372054139

SaschaSchwarze0 commented 1 year ago

@tommaso-borgato thanks for the issue.

We were just looking at that project and at this example, https://github.com/wildfly/wildfly-s2i/tree/main/examples/docker-build. But, we don't get the full picture.

Do you have a full e2e example by chance which includes the source code repository, and the commands that one must run that produce the container image. Then we can better assess if and how this is doable with Shipwright Build ?

tommaso-borgato commented 1 year ago

You can do it with HELM (https://github.com/wildfly/wildfly-charts) and this is actually the scenario we would like to cover:

oc new-project shipwright

helm repo add wildfly https://docs.wildfly.org/wildfly-charts/

cat > values.yaml << EOF
build:
  uri: https://github.com/wildfly/quickstart.git
  ref: main
  contextDir: helloworld
deploy:
  replicas: 1
EOF

helm install my-release -f ./values.yaml wildfly/wildfly --namespace shipwright

You'll notice two builds will be started (my-release-build-artifacts-1-build --> my-release-2-build):

image

tommaso-borgato commented 1 year ago

@SaschaSchwarze0 ^^^

SaschaSchwarze0 commented 1 year ago

Thanks for the details @tommaso-borgato. So basically a build strategy would need to contain two steps:

  1. A build step.
  2. An image build (and push) step.

What I wonder is how generic that is. It would be no issue to set this up, like step (1) using a Java+Maven image and running a Maven build. And then a second step which uses maybe crane append to add a layer with the output of step (1) to a runtime image. That would be no magic, but very specific to your source code that must be Java+Maven and produce a WAR file.

Assuming it is simple, then so far, our sample build strategies are more generic (maybe with the exception of ko which is specific for Go code). Does not mean that one should not build this, I am also having local build strategies that do similar things in the NodeJS world. And it maybe makes sense to have one or two samples that show this pattern.

What could also be the case as you mention builder image: one could build a generic build strategy where the image of step (1) is a parameter. For your Java app, you use image a, for my node app, I use image b. When those images run, they will run the build and put the output somewhere. And then step (2) would take that output and append it to the parameterized run image as a layer, and somehow define the image's entrypoint.

tommaso-borgato commented 1 year ago

@SaschaSchwarze0 the process is described here https://github.com/openshift/source-to-image/blob/master/docs/runtime_image.md

I suppose that, if s2i cli is used internally, we just need to pass two more parameters --runtime-image <runtime-image> --runtime-artifact </path/to/artifact>, e.g.:

s2i build <repo> <builder-image> <my-app> --runtime-image <runtime-image> --runtime-artifact </path/to/artifact>
SaschaSchwarze0 commented 1 year ago

Okay, so, are you then just asking for the addition of --runtime-image into https://github.com/shipwright-io/build/blob/main/samples/buildstrategy/source-to-image/buildstrategy_source-to-image_cr.yaml ?

tommaso-borgato commented 1 year ago

and --runtime-artifact

SaschaSchwarze0 commented 1 year ago

Okay, do you have a full example for me then. And sorry to ask so stupid questions, but I never used s2i.

s2i build <WHICH SOURCE CODE, the wildfly hello world?> <WHICH_BUILDER> --runtime-image <WHICH_RUNTIME> --runtime-artifact <WHICH_ARTIFACT>

And is --runtime-artifact a single value or can this appear more than once ?

tommaso-borgato commented 1 year ago

give me some time to put one together ....

tommaso-borgato commented 1 year ago

e.g.

s2i build https://github.com/tommaso-borgato/helloworld.git quay.io/wildfly/wildfly-s2i-jdk11 my-release --ref=main --runtime-image=quay.io/wildfly/wildfly-runtime-jdk11 --runtime-artifact=/opt/server --assemble-user=root --assemble-runtime-user=root 

the resulting image doesn't start correctly yet (need to fix something) but the chained s2i build is successful