Skip to content

Instantly share code, notes, and snippets.

@r2r-dev
Created February 20, 2024 12:03
Show Gist options
  • Save r2r-dev/adbcbc1b3baf60c68bd22f3af81b64db to your computer and use it in GitHub Desktop.
Save r2r-dev/adbcbc1b3baf60c68bd22f3af81b64db to your computer and use it in GitHub Desktop.
yocto2oci
#!/usr/bin/env bash
# USAGE: ./yocto2oci.sh <sdk>
# where sdk is a yocto-generated installer
# example sdk: https://downloads.yoctoproject.org/releases/yocto/yocto-4.0.16/toolchain/x86_64/poky-glibc-x86_64-core-image-sato-ppc7400-qemuppc-toolchain-ext-4.0.16.sh
set -e
ALGORITHM="sha256"
BUILD_DIR="build"
BLOBS_DIR="$BUILD_DIR/blobs/$ALGORITHM"
mkdir -p $BLOBS_DIR
# GET AUTH TOKEN
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/busybox:pull" | jq -r .token)
# PULL LATEST MANIFEST (DOCKER V2) OF BUSYBOX FROM THE REGISTRY
curl https://registry.hub.docker.com/v2/library/busybox/manifests/sha256:538721340ded10875f4710cad688c70e5d0ecb4dcd5e7d0c161f301f36f79414 \
-H "Accept: application/vnd.oci.image.manifest.v1+json" \
-H "Authorization: Bearer $TOKEN" \
-L \
-o manifest.json
# PARSE LAYERS REFs FROM THE MANIFEST
CONFIG_LAYER=$(cat manifest.json | jq -r '.config.digest')
ROOTFS_LAYER_DIGEST=$(cat manifest.json | jq -r '.layers[0].digest')
ROOTFS_LAYER_SIZE=$(cat manifest.json | jq -r '.layers[0].size')
# PULL CONFIG LAYER OF BUSYBOX FROM THE REGISTRY
curl https://registry.hub.docker.com/v2/library/busybox/blobs/$CONFIG_LAYER \
-H "Authorization: Bearer $TOKEN" \
-L \
-o config.json
ROOTFS_LAYER_DIFF=$(cat config.json | jq -r '.rootfs.diff_ids[0]')
# PULL ROOT FILE SYTEM LAYER OF BUSYBOX FROM THE REGISTRY
curl https://registry.hub.docker.com/v2/library/busybox/blobs/$ROOTFS_LAYER_DIGEST \
-H "Authorization: Bearer $TOKEN" \
-L \
-o $BLOBS_DIR/${ROOTFS_LAYER_DIGEST//$ALGORITHM:/}
DEFAULT_PREFIX="$(grep -na -m1 DEFAULT $1 | cut -d= -f2 | cut -d\" -f2)/"
tail -n +$(($(grep -na -m1 "^MARKER:$" $1 | cut -d':' -f1) + 1)) $1 > app-layer.tar.xz
xz -d app-layer.tar.xz
mv app-layer.tar app-layer-old.tar
mkdir tempdir && tar -xf app-layer-old.tar -C tempdir
tar -C tempdir -cf app-layer.tar --transform "s,^./,$DEFAULT_PREFIX/," .
rm -fr app-layer-old.tar tempdir
# CREATE APPLICATION LAYER LOCALLY
APP_LAYER="app-layer.tar"
GZIP_APP_LAYER="$APP_LAYER.gz"
gzip < $APP_LAYER > $GZIP_APP_LAYER
# CALCULATE LAYER'S DIGEST, DIFFID AND SIZE
APP_LAYER_DIFF="$(sha256sum < $APP_LAYER | sed 's/\s*-//g')"
APP_LAYER_DIGEST="$(sha256sum < $GZIP_APP_LAYER | sed 's/\s*-//g')"
APP_LAYER_SIZE="$(stat -c%s $GZIP_APP_LAYER)"
# MOVE APPLICATION LAYER TO BLOBS FOLDER
cp $GZIP_APP_LAYER "$BLOBS_DIR/$APP_LAYER_DIGEST"
# OCI container image layout
# ├── blobs
# │ └── sha256
# │ ├── DIFFID (image.manifest)
# │ └── DIFFID (image.config)
# │ └── DIFFID (image.rootfs)
# │ └── DIFFID (image.application)
# ├── index.json
# └── oci-layout
# CREATE OCI-LAYOUT FILE
cat > "$BUILD_DIR/oci-layout" << EOF
{
"imageLayoutVersion": "1.0.0"
}
EOF
##
## CREATE OCI-CONFIG LAYER
CONFIG_LAYER="image-config.json"
cat > $CONFIG_LAYER << EOF
{
"created": "2020-04-07T01:29:27.650294696Z",
"architecture": "amd64",
"os": "linux",
"config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/ash"
]
},
"rootfs": {
"type": "layers",
"diff_ids": [
"$ROOTFS_LAYER_DIFF",
"sha256:$APP_LAYER_DIFF"
]
},
"history": []
}
EOF
CONFIG_LAYER_DIGEST="$(sha256sum < $CONFIG_LAYER | sed 's/\s*-//g')"
CONFIG_LAYER_SIZE="$(stat -c%s $CONFIG_LAYER)"
cp $CONFIG_LAYER "$BLOBS_DIR/$CONFIG_LAYER_DIGEST"
# CREATE OCI-CONFIG LAYER
MANIFEST_LAYER="image-manifest.json"
cat > $MANIFEST_LAYER << EOF
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:$CONFIG_LAYER_DIGEST",
"size": $CONFIG_LAYER_SIZE
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "$ROOTFS_LAYER_DIGEST",
"size": $ROOTFS_LAYER_SIZE
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:$APP_LAYER_DIGEST",
"size": $APP_LAYER_SIZE
}
]
}
EOF
MANIFEST_LAYER_DIGEST="$(sha256sum < $MANIFEST_LAYER | sed 's/\s*-//g')"
MANIFEST_LAYER_SIZE="$(stat -c%s $MANIFEST_LAYER)"
cp $MANIFEST_LAYER "$BLOBS_DIR/$MANIFEST_LAYER_DIGEST"
# CREATE INDEX FILE
MANIFESTS_INDEX="index.json"
cat > "$BUILD_DIR/$MANIFESTS_INDEX" << EOF
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:$MANIFEST_LAYER_DIGEST",
"size": $MANIFEST_LAYER_SIZE,
"annotations": {
"org.opencontainers.image.ref.name": "latest"
}
}
]
}
EOF
tar -C build -cf image.tar .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment