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.

Revisions

  1. r2r-dev created this gist Feb 20, 2024.
    158 changes: 158 additions & 0 deletions yocto2oci.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,158 @@
    #!/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 .