{"id":21748694,"url":"https://github.com/bryanl/sheaf","last_synced_at":"2025-04-13T07:15:45.231Z","repository":{"id":57518160,"uuid":"238946485","full_name":"bryanl/sheaf","owner":"bryanl","description":"Inspired by https://cnab.io/, sheaf manages bundles of Kubernetes components.","archived":false,"fork":false,"pushed_at":"2020-07-17T14:43:40.000Z","size":465,"stargazers_count":30,"open_issues_count":12,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-13T07:15:37.686Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bryanl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-07T14:39:00.000Z","updated_at":"2024-11-28T11:19:55.000Z","dependencies_parsed_at":"2022-09-26T18:01:38.098Z","dependency_job_id":null,"html_url":"https://github.com/bryanl/sheaf","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryanl%2Fsheaf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryanl%2Fsheaf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryanl%2Fsheaf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bryanl%2Fsheaf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bryanl","download_url":"https://codeload.github.com/bryanl/sheaf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248675397,"owners_count":21143768,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-26T08:14:49.473Z","updated_at":"2025-04-13T07:15:45.180Z","avatar_url":"https://github.com/bryanl.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sheaf\n\nManages bundles of Kubernetes components.\n\n`sheaf` is a tool that can create a `bundle` of Kubernetes components. It can generate an archive from the bundle\nthat can be distributed for use in Kubernetes clusters. The initial idea was inspired by\n[CNAB](https://cnab.io/). It answers the question: _how can I distribute Kubernetes manifests with their \nassociated images_?\n\n## Why sheaf?\n\n* You want to create a distributable archive of Kubernetes manifests and their images\n* The Kubernetes clusters you are working with are potentially air-gapped and don't have access to the Internet.\n\nFeatures:\n\n* Manages a `bundle` of Kubernetes manifests\n* Package a bundle into an archive\n* Relocate images referenced in a bundle archive to another registry\n* Generate manifests contained in a bundle archive with optionally relocated images\n\n\n## Getting started\n\n`sheaf` is currently in an alpha state. We are releasing the tool early as a preview.\n\n### Install/Upgrade\n\n`go get -u github.com/bryanl/sheaf/cmd/sheaf`\n\n### Initialize Bundle\n\n```sh\nsheaf init --bundle-path \u003cbundle directory\u003e --bundle-name \u003cyour project name\u003e\n```\n\nInitialize a sheaf project:\n\n* Creates the directory bundle directory.\n* Creates a bundle configuration in _project_/`bundle.json`\n* Creates a manifests directory in _project_/`app/manifests`\n\n### Add Manifests to Bundle\n\nRepeat the following for each manifest (or pass multiple `-f` switches):\n\n`sheaf manifest add --bundle-path \u003cbundle directory\u003e -f \u003cmanifest path or URL\u003e`\n\n### Package Bundle\n\n`sheaf archive pack --bundle-path \u003cbundle directory\u003e --dest \u003carchive output directory\u003e`\n\nCreate an archive of `\u003cbundle directory\u003e` with any images found by scanning the manifests together with any listed in `bundle.json` and output it in the _\u003carchive output directory\u003e_ directory.\nNote that the directory _\u003carchive output directory\u003e_ must exist.\n\nFor an example of what appears in the archive, see below.\n\n### Stage Bundle\n\n`sheaf archive relocate --archive \u003carchive path\u003e --prefix \u003cprefix\u003e`\n\nRelocate the images located in the archive to a registry repository with `\u003cprefix\u003e`. Images will be renamed and pushed to the new registry.\n\n### Generate Manifest\n\n`sheaf manifest show --bundle-path \u003cbundle directory\u003e [--prefix=\u003cprefix\u003e]`\n\nGenerate manifests stored in the archive to stdout. If `\u003cprefix\u003e` is specified, the images in the manifests will be\nrewritten to the prefixed location. \n\n### Create user defined images\n\nWith Custom Resource Definitions, it is possible to define locations that `sheaf` cannot detect automatically. `sheaf`\nallows the user to create user defined images. For example, if you have a custom resource with API version\n`x.bryanl.dev/v1` and kind `Config` with a container image specified at `.spec.image`, you can use the following \ncommand to update the `sheaf` configuration.\n\n```sh\nsheaf config set-udi --bundle-path project-path --api-version x.bryanl.dev/v1 --kind Config --json-path '{.spec.image}'\n```\n\nThere is also support for arrays of images as well.\n\n```sh\nsheaf config set-udi --bundle-path project-path \\\n  --api-version x.bryanl.dev/v1 \\\n  --kind SecondaryConfig \\\n  --json-path '{.spec.images}'\n  --type multiple\n```\n\nWhen `sheaf` is building a bundle archive or generating manifests, it will use the user defined mappings.\n\n\n## Finding images\n\nThere are myriad ways to specify an image in a manifest. `sheaf` can detect images defined in pod specs that are in\nPods themselves or in a pod Spec template (e.g., in a Deployment). This heuristic works in a large number of cases. \nWith Kubernetes and Custom Resource Definitions it is possible to define images in other locations as well. `sheaf`\nhas a method called \"user defined images\", that allows custom locations to be created. \n\nExample:\n\n```sh\nsheaf config set-udi --bundle-path project-path --api-version caching.internal.knative.dev/v1alpha1 --kind Image --json-path '.spec.image'\n```\n \nIn this case, when `sheaf` is parsing the `Image` kind API version `caching.internal.knative.dev/v1alpha1` it will\nuse the JSON path `.spec.image` to locate an image. In this case:\n\n```yaml\n---\napiVersion: caching.internal.knative.dev/v1alpha1\nkind: Image\nmetadata:\n  labels:\n    serving.knative.dev/release: \"v0.12.0\"\n  name: queue-proxy\n  namespace: knative-serving\nspec:\n  image: gcr.io/knative-releases/knative.dev/serving/cmd/queue@sha256:3932262d4a44284f142f4c49f707526e70dd86317163a88a8cbb6de035a401a9\n```\n\nsheaf will identify `gcr.io/knative-releases/...` as an image.\n\nExamples of JSON path queries:\n* `.spec.images[*]`: Looks for an array of images in `.spec.images`\n* `..spec.containers[*].image`: This is the method that `sheaf` uses to find images in a Pod spec template\n\n## So what's in an archive?\n\nThe following detailed example shows the contents of an archive. This may change over time as `sheaf` evolves, but it should give some insight.\n```\n$ ./sheaf init --bundle-path scratch/example --bundle-name example\n$ ./sheaf manifest add --bundle-path scratch/example -f scratch/deployment.yaml\nAdding manifest from scratch/deployment.yaml\n$ cat scratch/deployment.yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: sample-deployment\nspec:\n  template:\n     spec:\n      containers:\n      - name: nginx\n        image: nginx\n        ports:\n        - containerPort: 80\n$ ./sheaf archive pack --bundle-path scratch/example --dest scratch\nStaging bundle configuration\nStaging manifests\nStaging images\n  deployment.yaml\n  └─ docker.io/library/nginx\n  adding docker.io/library/nginx to layout\nCreating archive: scratch/example-0.1.0.tgz\n$ tar xvzf scratch/example-0.1.0.tgz --directory scratch/example-expanded\n$ tree scratch/example-expanded\nscratch/example-expanded\n├── app\n│   └── manifests\n│       └── deployment.yaml\n├── artifacts\n│   └── layout\n│       ├── blobs\n│       │   └── sha256\n│       │       ├── 00dbf0056e4065d3e66bbfbd42551123cabfd4b75859f586bfaea443e279d07a\n│       │       ├── 015f0cb643493d580fe878b28ba8b33f17752aa349f417f80c022514e2b50a8c\n│       │       ├── 02997b777612b24efedac3f1f219afcd6bcf769108563209573e3471bd534478\n│       │       ├── 0598bd3a8f718f1b030930aa692ca6f9095d743c57b3b4aa3a200c362dc0de02\n│       │       ├── 06085c693a49adbc2f75ef87074579df1412d39da48d1c4203b0a8370c67125b\n│       │       ├── 0901fa9da894a8e9de5cb26d6749eaffb67b373dc1ff8a26c46b23b1175c913a\n│       │       ├── 092368e66229d2df31f2f6980d4abe630bc4576cc830485ce9aec1ad6ee39a7b\n│       │       ├── 0fc13119a4a310bba2bfeab8e68068dfce512f8871050555a254988397aafa1e\n│       │       ├── 18a64c9928215257ea8bcbbc2aee0e41b022bed61791291d141aaa2edcb5aad7\n│       │       ├── 1cf27aa8120baed22838ca29cdacc71bb16278cd846d91c62479ed72eeb23463\n│       │       ├── 230cf2b89e1f15b73a321a8b7637583cc0c6bbf0f948ef291d1ed844126c4635\n│       │       ├── 2b94f09d2d25fffb610349b7e7d26c0b1bc6a7d55795906a34e346c52c464fd1\n│       │       ├── 2db5eb6422bd5ac7462c19ab7b1f8d89a41873216bc583a9a6821c1a478337c8\n│       │       ├── 2dd003996c9ab82cac8112be0a4c04068e666e7a5d0cce3c65fb8f064de284e7\n│       │       ├── 33cc09c9b190539635d7c971301f623d94fda5b4b5647966c6c240902119009f\n│       │       ├── 36a1077091ada6e640493ea6da4c304d7b32f7341dcb5be2bbb27c45dd20b77b\n│       │       ├── 3d3726baabd4a64466564b8068c1af39ca69f003bd0662f0c30e6253666290ab\n│       │       ├── 405e75bf6bb0104d67fcebf58e07cd21bf344589df9c1a41c00354a60ea3a604\n│       │       ├── 40969e979bd83d4599eb92444aefa1abeaaf64186a636f4e4c50a181e680d360\n│       │       ├── 43362c1f9f7a7afc4e76b3906fb9dd7e605432ce6f00137d5aeb7420fede16ee\n│       │       ├── 4584011f2cd184c8af36b3111f56cd7830a7bfda446d2112d28ec0dfff91082a\n│       │       ├── 4ae502311710257cf63b1020256729f1f474f320b6e768284be83182877f3244\n│       │       ├── 4ce8bb5bca50e30a1b523de188d7538f5f0e17693dda87462c434aa7174d5b57\n│       │       ├── 565c5b948bc1162b1b8bb1699830e79345a5fe06ce7a6e97a137b9837e9422e9\n│       │       ├── 57a619d34e5582111a25d6e29783e7cef7858c05d82e446c9654698a51d86457\n│       │       ├── 57d8e76b728c535237497f00d57f2e5a000eed287fdf975ffcf090cd2a094061\n│       │       ├── 5b11fc09c1a26b11a7df7d593adf43baff53c5cdba71cf8a87ae4a6dd17eb52c\n│       │       ├── 5e38a7a36675286bba77c3b1a48fe3f994195a672f8f92c4f01635c3f05b0ecf\n│       │       ├── 63dbb66c5119bb5086d9e6fb6b154211afc20b44ed136ab7df808f6044cfc6f1\n│       │       ├── 644cef618ceea1cc2a7c5aa22d188fcdedeffc2ac89896fffdec74506615a0fc\n│       │       ├── 66979ef6cabd7bb5aa8a418f1d1a8127ebd5ac02f910a14def8f33738041c4a7\n│       │       ├── 67d252a8c1e1e940e1b2c52e05046403d00e84a33f6ddc94dc9c8870110338d3\n│       │       ├── 67ddcee0b1be2b67823856a6aa49c601ca5783d693f4724b6a8f7e413d44a73a\n│       │       ├── 68c6bf98048c7f913ee5e59b4f913be0b363d4ca0644ead4287202d56cbdf4d9\n│       │       ├── 68ec9ddfb393aee91093cbf859cde906459cbf7218fc988f2990f21b22f8e521\n│       │       ├── 6a03ff813dcd7a821ea0d229b54798547a6062c7f26f54dc8c1e2981c01f5e58\n│       │       ├── 6a4ba5c72a8ea85ea434c8b2039f9b4a776fb2463fff084b0cff53c07bcc58e6\n│       │       ├── 71719749d285a416f8253bf524980b4a96250add89b03e9af3cb8d5ffe293ca9\n│       │       ├── 71d2ad811a3bf658598b1f8d635024971b15b673e50891446f6ac97ad9ecfae9\n│       │       ├── 76f2a0c8ea98ebd699a77ced9c677e97cd54b038a8c5e89670af78f38b047b33\n│       │       ├── 8559a31e96f442f2c7b6da49d6c84705f98a39d8be10b3f5f14821d0ee8417df\n│       │       ├── 860f8957d8be856e2235a28e49fc4dca17254951e0eb67d760769755656f5cad\n│       │       ├── 8a8b84398062afd8652193b566914890f836f8a9303eeb278a4dce93e2223a65\n│       │       ├── 8ff4598873f588ca9d2bf1be51bdb117ec8f56cdfd5a81b5bb0224a61565aa49\n│       │       ├── 9a2ce85454764788d4e69016d9a7b74808619a56a00c4a1685d685655d0eb78c\n│       │       ├── 9c2b660fcff6200198b5a6dd0f4acb51d27813a959f6a38a2ab089b5d058e1d7\n│       │       ├── a52fbcfc43b142e3f86683bf1b2b8da0f58f0f52cf1584d236f47a2a4cadbf6f\n│       │       ├── a93c8a0b0974c967aebe868a186e5c205f4d3bcb5423a56559f2f9599074bbcd\n│       │       ├── b38125636144fda2e96c14893240ff2a307f3743ea83d297905289e49523a088\n│       │       ├── c2cb1aebb3e93bed04cee202f88e8c1932169beae7a164cd2b5a5d8b356b1c35\n│       │       ├── c2e53b84630c36ddf2ee1993636b89d678a43f75d27c3e2298f77ccd06b6594e\n│       │       ├── cc0e3936130331cb326019018d2761610ae2e018a07fba42d65ce63b1ad3e657\n│       │       ├── ccdad9502600ef5f2a2b04a4c5a9d94ae9e0b7bd6f9a1588090193964819916b\n│       │       ├── ce8699553d8b3417193659018fb5fb4ada22ed879ec1650f47f5b769e97a9800\n│       │       ├── efe6d8b8ae3a94bd3b6e7e68a7ab7749e099231ad9d7b13cbccf8af538fb04dd\n│       │       ├── f3e35b5be24177bc7f2c19401e9b45e8e834795815a982187c680643037064ed\n│       │       └── f58da03af52f1386c795c25912f0835a91884c5cbe62963d7c1438b2259095a3\n│       ├── index.json\n│       └── oci-layout\n└── bundle.json\n$ cat scratch/example-expanded/bundle.json\n{\n  \"schemaVersion\": \"v1alpha1\",\n  \"name\": \"example\",\n  \"version\": \"0.1.0\"\n}\n$ cat scratch/example-expanded/app/manifests/deployment.yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: sample-deployment\nspec:\n  template:\n     spec:\n      containers:\n      - name: nginx\n        image: nginx\n        ports:\n        - containerPort: 80\n```\nThe contents of scratch/example-expanded/artifacts/layout is a [standard OCI image layout](https://github.com/opencontainers/image-spec/blob/master/image-layout.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbryanl%2Fsheaf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbryanl%2Fsheaf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbryanl%2Fsheaf/lists"}