redhat-buildpacks / poc

Project to be used to perform go build of images using Buildah, ...
3 stars 6 forks source link

Table of Contents

Poc development

This project has been designed in order to validate if we can parse a Dockerfile to build an image locally using different go modules such as: kaniko, buildah, containers/image, containers/storage, ... and next to extract the content of the new layer(s) created under the container root FS.

Kaniko application

Go application using mainly kaniko as lib to parse the Dockerfile - see readme.md

Buildah application

Go application using mainly buildah and containers/image modules as lib to parse the Dockerfile - see readme.md

Using tools

This section contains the instructions to perform different operations using tools (buildah, skopeo, docker client, ...) on a container's image, layers such as:

1. Buildah and Skopeo

With the hlp of buildah bud and skopeo tools, we can perform such an operations:

REMARK: An interesting project which has not been fully investigated but which could be helpful is [umoci](https://github.com/opencontainers/umoci). It allows to unpack too, the layers of an image sudo umoci unpack --image $IMAGE_ID:$TAG bundle

sudo rm -rf _temp && mkdir -p _temp
REPO="buildpack-poc"
sudo podman rmi localhost/$REPO
pushd _temp  

cat <<'EOF' > Dockerfile
FROM registry.access.redhat.com/ubi8:8.4-211

RUN yum install -y --setopt=tsflags=nodocs nodejs && \
    rpm -V nodejs && \
    yum -y clean all
EOF

sudo buildah bud -q -f Dockerfile -t $REPO . > /dev/null 2>&1

GRAPH_DRIVER="overlay"
TAG=$(sudo buildah --storage-driver $GRAPH_DRIVER images | awk -v r="$REPO" '$0 ~ r {print $2;}')
IMAGE_ID=$(sudo buildah --storage-driver $GRAPH_DRIVER images | awk -v r="$REPO" '$0 ~ r {print $3;}')
# This syntax is not correct "sudo skopeo copy -q containers-storage:$IMAGE_ID oci:$(pwd)/$IMAGE_ID:$TAG > /dev/null 2>&1"
STORAGE="[vfs@/var/lib/containers/storage+/run/containers/storage]"
sudo skopeo copy -q containers-storage:$STORAGE$IMAGE_ID oci:$(pwd)/$IMAGE_ID:$TAG

cat $IMAGE_ID/index.json
MANIFEST_SHA=$(cat $IMAGE_ID/index.json | jq '.manifests[0].digest' | cut -d: -f2 | sed 's/.$//')
echo "MANIFEST SHA: $MANIFEST_SHA"
cat $IMAGE_ID/blobs/sha256/$MANIFEST_SHA | python -m json.tool

DIGEST_SHA=$(cat $IMAGE_ID/blobs/sha256/$MANIFEST_SHA | jq '.config.digest' | cut -d: -f2 | sed 's/.$//')
echo "DIGEST SHA: $DIGEST_SHA"
cat $IMAGE_ID/blobs/sha256/$DIGEST_SHA | python -m json.tool

LAST_LAYER_ID=$(cat $IMAGE_ID/blobs/sha256/$MANIFEST_SHA | jq '.layers[-1].digest' | cut -d: -f2 | sed 's/.$//')
echo "LAST LAYER SHA: $LAST_LAYER_ID"
echo "## Display the content of the layer containing the package added ..."
tar -tvf $IMAGE_ID/blobs/sha256/$LAST_LAYER_ID

popd

2. Docker and Python tool

Using Docker and the undocker.py python tool, we can:

To validate such a scenario, execute the following instructions

RUN apk add wget EOF


- Do a docker build. Next tag the image. Save the image content locally and find the last layer id to extract it
```bash
docker build -f Dockerfile my-alpine .
IMAGE_ID=$(docker images --format="{{.Repository}} {{.ID}}" | awk '/none/ { print $2; }')
docker tag $IMAGE_ID my-alpine
LAST_LAYER_ID=$(docker save localhost/my-alpine | ./undocker.py --layers | head -n 1)
docker save my-alpine | ./undocker.py -i -o my-alpine-wget -l $LAST_LAYER_ID

docker save my-alpine | ./undocker.py -vi -o my-alpine-wget -l f35d9c7ad180a77b0969ca4e87e6f9655098d577cc29f64cae5c300d9c33d753


- Check the tree of the folder created locally
```bash
tree my-alpine-wget   

Deprecated

Mount root FS

See the following links where it is discussed How to mount a root FS:

The problem that we will have, if we want to mount the root FS, within the pod is that currently we cannot mount it under / but using a different path as otherwise that will clash

spec:
  volumes:
    - name: host
      hostPath:
        path: /
volumeMounts:
  - name: cache-dir
    mountPath: /workspace
  - name: host
    mountPath: /host

The consequence is that we need to find a way to copy the content of the subpath /host to the / using a different initContainer which is only used to copy the files coming from the layers !

MacOS

It is not possible for the moment to develop on a Mac as it is not a real Linux platform !

The following package is needed otherwise the compilation of the application will fail

# github.com/mtrmac/gpgme
../../golang/pkg/mod/github.com/mtrmac/gpgme@v0.1.2/data.go:4:11: fatal error: 'gpgme.h' file not found
 #include <gpgme.h>
          ^~~~~~~~~

It can be installed using brew

brew install gpgme