├── .github └── workflows │ ├── codeql-analysis.yml │ └── imagesync-ci.yaml ├── .gitignore ├── .goreleaser.yaml ├── Dockerfile ├── README.md ├── cmd └── imagesync │ └── main.go ├── go.mod ├── go.sum ├── imagesync.go ├── release.sh └── testdata ├── alpine-oci.tar ├── alpine-oci ├── blobs │ └── sha256 │ │ ├── 0c673ee68853a04014c0c623ba5ee21ee700e1d71f7ac1160ddb2e31c6fdbb18 │ │ ├── 1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870 │ │ ├── 13749bbca9f97be00999dbeb8bf38b3c185f20b8472bb73249ab867de4e4d6fd │ │ ├── 1d96e60e5270815238e999aed0ae61d22ac6f5e5f976054b24796d0e0158b39c │ │ ├── 213ec9aee27d8be045c6a92b7eac22c9a64b44558193775a1a7f626352392b49 │ │ ├── 4d0c95c8f9f7c6363ffe08596a1c6a624f3bf59d61a663083a816b59cb2e47f1 │ │ ├── 520cf2ab7c1a1ba979e7d20c8ad2b433d119288ba0b88660a0afdca28f41afb3 │ │ ├── 5da989a9a3a08357bc7c00bd46c3ed782e1aeefc833e0049e6834ec1dcad8a42 │ │ ├── 6c0d3b419d848ea31ca748254611d5d5ce3b76e3d7bba520fd87400fbb75f3b9 │ │ ├── 790c84f1f3409eab952345157df7fa804ba6b5f06d4ceb6f2dfa3c6de2064397 │ │ ├── 9506b835437abb4d8ba1683e00c500b8f77e1975e930b356fbb72f2dbdc274d9 │ │ ├── 9a88b8895602862ed151c64204a1fa465366d6fa4bb7797f09e7d32d9e6763c0 │ │ ├── 9b18e9b68314027565b90ff6189d65942c0f7986da80df008b8431276885218e │ │ ├── 9c6f0724472873bb50a2ae67a9e7adcb57673a183cea8b06eb778dca859181b5 │ │ ├── a6215f271958c760a2975a6765016044115dbae4b90f414eba3a448a6a26b4f6 │ │ ├── b2cce0f0dbe61be2d8aa8228e6cfc757064cde399198b877e50fdf57beda2c12 │ │ ├── bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad │ │ ├── c2046a6c3d2db4f75bfb8062607cc8ff47896f2d683b7f18fe6b6cf368af3c60 │ │ ├── c6556b3b6858c6fa1e328377cc2c4becdc9cd1bc3e7302aa7299936522cf93ba │ │ ├── c79e5d1a8c89b87020a754c8a5c8370faaa37bfb5bca1d8af66770d522ef1caf │ │ ├── ed73e2bee79b3428995b16fce4221fc715a849152f364929cdccdc83db5f3d5c │ │ └── fa30af02cc8c339dd7ffecb0703cd4a3db175e56875c413464c5ba46821253a8 ├── index.json └── oci-layout └── alpine.tar /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: [ master ] 9 | schedule: 10 | - cron: '20 23 * * 1' 11 | 12 | jobs: 13 | analyze: 14 | name: Analyze 15 | runs-on: ubuntu-latest 16 | permissions: 17 | actions: read 18 | contents: read 19 | security-events: write 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | language: [ 'go' ] 25 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 26 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 27 | 28 | steps: 29 | - name: Checkout repository 30 | uses: actions/checkout@v2 31 | 32 | # Initializes the CodeQL tools for scanning. 33 | - name: Initialize CodeQL 34 | uses: github/codeql-action/init@v1 35 | with: 36 | languages: ${{ matrix.language }} 37 | # If you wish to specify custom queries, you can do so here or in a config file. 38 | # By default, queries listed here will override any specified in a config file. 39 | # Prefix the list here with "+" to use these queries and those in the config file. 40 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 41 | 42 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 43 | # If this step fails, then you should remove it and run the build manually (see below) 44 | - name: Autobuild 45 | uses: github/codeql-action/autobuild@v1 46 | 47 | # ℹ️ Command-line programs to run using the OS shell. 48 | # 📚 https://git.io/JvXDl 49 | 50 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 51 | # and modify them (or add more) to build your code if your project 52 | # uses a compiled language 53 | 54 | #- run: | 55 | # make bootstrap 56 | # make release 57 | 58 | - name: Perform CodeQL Analysis 59 | uses: github/codeql-action/analyze@v1 60 | -------------------------------------------------------------------------------- /.github/workflows/imagesync-ci.yaml: -------------------------------------------------------------------------------- 1 | name: "Imagesync CI" 2 | on: 3 | push: 4 | branches: [ master ] 5 | tags: [ v* ] 6 | 7 | permissions: read-all 8 | 9 | jobs: 10 | build-push-image: 11 | name: Build/Push imagesync image 12 | runs-on: ubuntu-latest 13 | permissions: 14 | packages: write 15 | contents: read 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v2 20 | 21 | - name: Set up QEMU 22 | uses: docker/setup-qemu-action@v2 23 | 24 | - name: Set up Docker Buildx 25 | uses: docker/setup-buildx-action@v2 26 | 27 | - name: Login to Container Registry 28 | uses: docker/login-action@v2 29 | with: 30 | registry: "ghcr.io" 31 | username: ${{ github.actor }} 32 | password: ${{ secrets.GITHUB_TOKEN }} 33 | 34 | - name: Login to Docker Hub 35 | uses: docker/login-action@v2 36 | with: 37 | username: ${{ secrets.DOCKERHUB_USERNAME }} 38 | password: ${{ secrets.DOCKERHUB_PASSWORD }} 39 | 40 | - name: Determine tag for container image 41 | id: image-tag 42 | run: | 43 | if [[ "${{ github.ref_name }}" == "master" ]]; then 44 | echo "::set-output name=value::latest" 45 | else 46 | echo "::set-output name=value::${{ github.ref_name }}" 47 | fi 48 | 49 | - name: Build and Push 50 | uses: docker/build-push-action@v3 51 | with: 52 | push: true 53 | tags: | 54 | ghcr.io/mqasimsarfraz/imagesync:${{ steps.image-tag.outputs.value }} 55 | smqasims/imagesync:${{ steps.image-tag.outputs.value }} 56 | build-args: | 57 | IMAGESYNC_VERSION=${{ github.ref_name }} 58 | 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | dist 3 | imagesync# Added by goreleaser init: 4 | dist/ 5 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | before: 4 | hooks: 5 | - apt update 6 | - apt install libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev pkg-config -y 7 | - go mod download 8 | builds: 9 | - main: ./cmd/imagesync/main.go 10 | binary: imagesync 11 | env: 12 | - CGO_ENABLED=1 13 | goos: 14 | - linux 15 | goarch: 16 | - amd64 17 | ignore: 18 | - goos: darwin 19 | goarch: 386 20 | archives: 21 | - name_template: >- 22 | {{ .ProjectName }}_ 23 | {{- title .Os }}_ 24 | {{- if eq .Arch "amd64" }}x86_64 25 | {{- else if eq .Arch "386" }}i386 26 | {{- else }}{{ .Arch }}{{ end }} 27 | {{- if .Arm }}v{{ .Arm }}{{ end }} 28 | checksum: 29 | name_template: 'checksums.txt' 30 | changelog: 31 | sort: asc 32 | filters: 33 | exclude: 34 | - '^*.sh:' 35 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.22-bullseye AS go-builder 2 | 3 | ARG IMAGESYNC_VERSION 4 | ENV IMAGESYNC_VERSION ${IMAGESYNC_VERSION} 5 | 6 | ENV PACKAGE github.com/mqasimsarfraz/image-sync 7 | ENV CGO_ENABLED 1 8 | 9 | WORKDIR $GOPATH/src/$PACKAGE 10 | 11 | # create directories for binary and install dependencies 12 | RUN mkdir -p /out && \ 13 | apt -qq update && \ 14 | apt install -y git libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev pkg-config 15 | 16 | # copy sources, test and build the application 17 | COPY . ./ 18 | RUN go vet ./... 19 | RUN go test --parallel=1 ./... 20 | RUN go build -v \ 21 | -ldflags="-s -w \ 22 | -X 'github.com/mqasimsarfraz/imagesync.Version=${IMAGESYNC_VERSION}'"\ 23 | -o /out/imagesync ./cmd/imagesync 24 | 25 | 26 | # build the final container image 27 | FROM bitnami/minideb:bullseye 28 | 29 | RUN apt -qq update && \ 30 | apt install -y libgpgme-dev --no-install-recommends && \ 31 | rm -rf /var/lib/apt/lists/* 32 | 33 | COPY --from=go-builder /out/imagesync / 34 | 35 | ENTRYPOINT ["/imagesync"] 36 | 37 | CMD ["-h"] 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
11 | 12 | # imagesync 13 | 14 | A tool to copy/sync images in registries without a demon. 15 | 16 | ```bash 17 | imagesync -h 18 | 19 | NAME: 20 | imagesync - Sync images in registries. 21 | 22 | USAGE: 23 | imagesync [global options] command [command options] [arguments...] 24 | 25 | COMMANDS: 26 | help, h Shows a list of commands or help for one command 27 | 28 | GLOBAL OPTIONS: 29 | --src value, -s value Reference for the source container image/repository. 30 | --src-strict-tls Enable strict TLS for connections to source container registry. 31 | --dest value, -d value Reference for the destination container repository. 32 | --dest-strict-tls Enable strict TLS for connections to destination container registry. 33 | --tags-pattern value Regex pattern to select for tag to-be synced. 34 | --skip-tags-pattern value Regex pattern to exclude tags. 35 | --skip-tags value Comma separated list of tags to be skipped. 36 | --overwrite Use this to copy/override all the tags. 37 | --max-concurrent-tags value Maximum number of tags to be synced/copied in parallel. (default: 1) 38 | --help, -h show help 39 | ``` 40 | 41 | ## Installation 42 | 43 | ### Binary 44 | 45 | You can download the binary from [releases](https://github.com/mqasimsarfraz/imagesync/releases) page and use it directly: 46 | 47 | ```bash 48 | VERSION=$(curl -s https://api.github.com/repos/mqasimsarfraz/imagesync/releases/latest | jq -r .tag_name) 49 | curl -sL https://github.com/mqasimsarfraz/imagesync/releases/download/${VERSION}/imagesync_Linux_x86_64.tar.gz | sudo tar -C /usr/local/bin -xzf - imagesync 50 | imagesync -h 51 | ``` 52 | 53 | ### Docker 54 | 55 | You can use the docker image to run `imagesync`: 56 | 57 | ```bash 58 | VERSION=$(curl -s https://api.github.com/repos/mqasimsarfraz/imagesync/releases/latest | jq -r .tag_name) 59 | docker run --rm -it ghcr.io/mqasimsarfraz/imagesync:$VERSION -h 60 | ``` 61 | 62 | ## Examples 63 | Following is a list of examples with different sources. In order to try out examples with [testdata](testdata) you need to start a local [registry](https://docs.docker.com/registry/deploying/#run-a-local-registry) using: 64 | 65 | ``` 66 | docker run -d -p 5000:5000 --restart=always --name registry registry:2 67 | ``` 68 | 69 | ### Docker Archive 70 | 71 | ``` 72 | imagesync -s testdata/alpine.tar -d localhost:5000/library/alpine:3 73 | ``` 74 | 75 | ### OCI Archive 76 | 77 | ``` 78 | imagesync -s testdata/alpine-oci.tar -d localhost:5000/library/alpine:3 79 | ``` 80 | 81 | ### OCI layout 82 | 83 | ``` 84 | imagesync -s testdata/alpine-oci -d localhost:5000/library/alpine:3 85 | ``` 86 | 87 | ### Image Tag 88 | 89 | #### container image 90 | ``` 91 | imagesync -s library/alpine:3 -d localhost:5000/library/alpine:3 92 | ``` 93 | 94 | #### helm chart 95 | ``` 96 | imagesync -s ghcr.io/nginxinc/charts/nginx-ingress:1.3.1 -d localhost:5000/nginxinc/charts/nginx-ingress:1.3.1 97 | ``` 98 | 99 | ### Entire Repository 100 | 101 | ``` 102 | imagesync -s library/alpine -d localhost:5000/library/alpine 103 | ``` 104 | 105 | ### Entire Repository (helm) 106 | 107 | ``` 108 | imagesync -s ghcr.io/nginxinc/charts/nginx-ingress -d localhost:5000/nginxinc/charts/nginx-ingress 109 | ``` 110 | 111 | ## Private Registries 112 | 113 | `imagesync` will respect the credentials stored in `~/.docker/config.json` via `docker login` etc. So in case you are 114 | running it in a container you need to mount the path with credentials as: 115 | 116 | ``` 117 | docker run --rm -it -v ${HOME}/.docker/config.json:/root/.docker/config.json ghcr.io/mqasimsarfraz/imagesync:v1.2.0 -h 118 | ``` 119 | 120 | ## Multi-arch images 121 | 122 | `imagesync` supports copying multi-arch images. So in case you are copying a multi-arch image it will copy all the platforms unlike `docker pull`/`docker push` approach which only copies the platform of the host. 123 | 124 | ## Contributing/Dependencies 125 | 126 | Following needs to be installed in order to compile the project locally: 127 | 128 | ### fedora/centos 129 | 130 | ``` 131 | dnf --enablerepo=powertools install gpgme-devel 132 | dnf install libassuan libassuan-devel 133 | ``` 134 | 135 | ### debian/ubuntu 136 | 137 | ``` 138 | sudo apt install libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev pkg-config 139 | ``` 140 | -------------------------------------------------------------------------------- /cmd/imagesync/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/mqasimsarfraz/imagesync" 8 | ) 9 | 10 | func main() { 11 | if err := imagesync.Execute(); err != nil { 12 | log.Fatal(err) 13 | os.Exit(1) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mqasimsarfraz/imagesync 2 | 3 | go 1.22.6 4 | toolchain go1.24.1 5 | 6 | require ( 7 | github.com/containers/image/v5 v5.33.1 8 | github.com/samber/lo v1.38.1 9 | github.com/sirupsen/logrus v1.9.3 10 | github.com/urfave/cli v1.22.15 11 | ) 12 | 13 | require ( 14 | github.com/BurntSushi/toml v1.4.0 // indirect 15 | github.com/VividCortex/ewma v1.2.0 // indirect 16 | github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect 17 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect 18 | github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect 19 | github.com/containers/ocicrypt v1.2.0 // indirect 20 | github.com/containers/storage v1.56.1 // indirect 21 | github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect 22 | github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect 23 | github.com/distribution/reference v0.6.0 // indirect 24 | github.com/docker/distribution v2.8.3+incompatible // indirect 25 | github.com/docker/docker v27.3.1+incompatible // indirect 26 | github.com/docker/docker-credential-helpers v0.8.2 // indirect 27 | github.com/docker/go-connections v0.5.0 // indirect 28 | github.com/docker/go-units v0.5.0 // indirect 29 | github.com/go-jose/go-jose/v4 v4.0.5 // indirect 30 | github.com/go-openapi/analysis v0.23.0 // indirect 31 | github.com/go-openapi/errors v0.22.0 // indirect 32 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 33 | github.com/go-openapi/jsonreference v0.21.0 // indirect 34 | github.com/go-openapi/loads v0.22.0 // indirect 35 | github.com/go-openapi/runtime v0.28.0 // indirect 36 | github.com/go-openapi/spec v0.21.0 // indirect 37 | github.com/go-openapi/strfmt v0.23.0 // indirect 38 | github.com/go-openapi/swag v0.23.0 // indirect 39 | github.com/go-openapi/validate v0.24.0 // indirect 40 | github.com/golang/protobuf v1.5.4 // indirect 41 | github.com/google/go-containerregistry v0.20.2 // indirect 42 | github.com/google/uuid v1.6.0 // indirect 43 | github.com/gorilla/mux v1.8.1 // indirect 44 | github.com/josharian/intern v1.0.0 // indirect 45 | github.com/json-iterator/go v1.1.12 // indirect 46 | github.com/klauspost/compress v1.17.11 // indirect 47 | github.com/klauspost/pgzip v1.2.6 // indirect 48 | github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect 49 | github.com/mailru/easyjson v0.7.7 // indirect 50 | github.com/mattn/go-runewidth v0.0.16 // indirect 51 | github.com/mattn/go-sqlite3 v1.14.24 // indirect 52 | github.com/miekg/pkcs11 v1.1.1 // indirect 53 | github.com/mitchellh/mapstructure v1.5.0 // indirect 54 | github.com/moby/sys/capability v0.3.0 // indirect 55 | github.com/moby/sys/mountinfo v0.7.2 // indirect 56 | github.com/moby/sys/user v0.3.0 // indirect 57 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 58 | github.com/modern-go/reflect2 v1.0.2 // indirect 59 | github.com/oklog/ulid v1.3.1 // indirect 60 | github.com/opencontainers/go-digest v1.0.0 // indirect 61 | github.com/opencontainers/image-spec v1.1.0 // indirect 62 | github.com/opencontainers/runtime-spec v1.2.0 // indirect 63 | github.com/proglottis/gpgme v0.1.3 // indirect 64 | github.com/rivo/uniseg v0.4.7 // indirect 65 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 66 | github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect 67 | github.com/sigstore/fulcio v1.6.4 // indirect 68 | github.com/sigstore/rekor v1.3.6 // indirect 69 | github.com/sigstore/sigstore v1.8.9 // indirect 70 | github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect 71 | github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect 72 | github.com/ulikunitz/xz v0.5.12 // indirect 73 | github.com/vbatts/tar-split v0.11.6 // indirect 74 | github.com/vbauerster/mpb/v8 v8.8.3 // indirect 75 | go.mongodb.org/mongo-driver v1.14.0 // indirect 76 | go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect 77 | golang.org/x/crypto v0.35.0 // indirect 78 | golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect 79 | golang.org/x/net v0.36.0 // indirect 80 | golang.org/x/sync v0.11.0 // indirect 81 | golang.org/x/sys v0.30.0 // indirect 82 | golang.org/x/term v0.29.0 // indirect 83 | golang.org/x/text v0.22.0 // indirect 84 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect 85 | google.golang.org/grpc v1.67.0 // indirect 86 | google.golang.org/protobuf v1.34.2 // indirect 87 | gopkg.in/yaml.v3 v3.0.1 // indirect 88 | ) 89 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= 2 | dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= 3 | github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 4 | github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= 5 | github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= 6 | github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= 7 | github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= 8 | github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= 9 | github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= 10 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= 11 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 12 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 13 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 14 | github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 15 | github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 16 | github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= 17 | github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= 18 | github.com/containers/image/v5 v5.33.1 h1:nTWKwxAlY0aJrilvvhssqssJVnley6VqxkLiLzTEYIs= 19 | github.com/containers/image/v5 v5.33.1/go.mod h1:/FJiLlvVbeBxWNMPVPPIWJxHTAzwBoFvyN0a51zo1CE= 20 | github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= 21 | github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= 22 | github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM= 23 | github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U= 24 | github.com/containers/storage v1.56.1 h1:gDZj/S6Zxus4Xx42X6iNB3ODXuh0qoOdH/BABfrvcKo= 25 | github.com/containers/storage v1.56.1/go.mod h1:c6WKowcAlED/DkWGNuL9bvGYqIWCVy7isRMdCSKWNjk= 26 | github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 27 | github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= 28 | github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 29 | github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f h1:eHnXnuK47UlSTOQexbzxAZfekVz6i+LKRdj1CU5DPaM= 30 | github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= 31 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 32 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 33 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 34 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 35 | github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= 36 | github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= 37 | github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= 38 | github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= 39 | github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= 40 | github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= 41 | github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= 42 | github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= 43 | github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= 44 | github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= 45 | github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= 46 | github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= 47 | github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= 48 | github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= 49 | github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= 50 | github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= 51 | github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= 52 | github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= 53 | github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= 54 | github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= 55 | github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= 56 | github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= 57 | github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= 58 | github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= 59 | github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= 60 | github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= 61 | github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= 62 | github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= 63 | github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= 64 | github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc= 65 | github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= 66 | github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= 67 | github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= 68 | github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= 69 | github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= 70 | github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= 71 | github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= 72 | github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= 73 | github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= 74 | github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= 75 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 76 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 77 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 78 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 79 | github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo= 80 | github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= 81 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 82 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 83 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 84 | github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= 85 | github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= 86 | github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs= 87 | github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI= 88 | github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= 89 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 90 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 91 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 92 | github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= 93 | github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= 94 | github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= 95 | github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 96 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 97 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 98 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 99 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 100 | github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ= 101 | github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk= 102 | github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= 103 | github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 104 | github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= 105 | github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 106 | github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= 107 | github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= 108 | github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= 109 | github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= 110 | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= 111 | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 112 | github.com/moby/sys/capability v0.3.0 h1:kEP+y6te0gEXIaeQhIi0s7vKs/w0RPoH1qPa6jROcVg= 113 | github.com/moby/sys/capability v0.3.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= 114 | github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= 115 | github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= 116 | github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= 117 | github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= 118 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 119 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 120 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 121 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 122 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 123 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= 124 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 125 | github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= 126 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= 127 | github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= 128 | github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= 129 | github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= 130 | github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= 131 | github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= 132 | github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= 133 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 134 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 135 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 136 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 137 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 138 | github.com/proglottis/gpgme v0.1.3 h1:Crxx0oz4LKB3QXc5Ea0J19K/3ICfy3ftr5exgUK1AU0= 139 | github.com/proglottis/gpgme v0.1.3/go.mod h1:fPbW/EZ0LvwQtH8Hy7eixhp1eF3G39dtx7GUN+0Gmy0= 140 | github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= 141 | github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= 142 | github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= 143 | github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= 144 | github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= 145 | github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= 146 | github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= 147 | github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= 148 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 149 | github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= 150 | github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 151 | github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= 152 | github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= 153 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 154 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 155 | github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= 156 | github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= 157 | github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= 158 | github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= 159 | github.com/sigstore/fulcio v1.6.4 h1:d86obfxUAG3Y6CYwOx1pdwCZwKmROB6w6927pKOVIRY= 160 | github.com/sigstore/fulcio v1.6.4/go.mod h1:Y6bn3i3KGhXpaHsAtYP3Z4Np0+VzCo1fLv8Ci6mbPDs= 161 | github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8= 162 | github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc= 163 | github.com/sigstore/sigstore v1.8.9 h1:NiUZIVWywgYuVTxXmRoTT4O4QAGiTEKup4N1wdxFadk= 164 | github.com/sigstore/sigstore v1.8.9/go.mod h1:d9ZAbNDs8JJfxJrYmulaTazU3Pwr8uLL9+mii4BNR3w= 165 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 166 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 167 | github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw= 168 | github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M= 169 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 170 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 171 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 172 | github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 173 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 174 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 175 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 176 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 177 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 178 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 179 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 180 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 181 | github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= 182 | github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= 183 | github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= 184 | github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 185 | github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= 186 | github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= 187 | github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs= 188 | github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI= 189 | github.com/vbauerster/mpb/v8 v8.8.3 h1:dTOByGoqwaTJYPubhVz3lO5O6MK553XVgUo33LdnNsQ= 190 | github.com/vbauerster/mpb/v8 v8.8.3/go.mod h1:JfCCrtcMsJwP6ZwMn9e5LMnNyp3TVNpUWWkN+nd4EWk= 191 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= 192 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 193 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= 194 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= 195 | github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= 196 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 197 | go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= 198 | go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= 199 | go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak= 200 | go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= 201 | golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= 202 | golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= 203 | golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= 204 | golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= 205 | golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= 206 | golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= 207 | golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= 208 | golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 209 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 210 | golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= 211 | golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 212 | golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= 213 | golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= 214 | golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= 215 | golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= 216 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= 217 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= 218 | google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= 219 | google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= 220 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 221 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 222 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 223 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 224 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 225 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 226 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 227 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 228 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 229 | -------------------------------------------------------------------------------- /imagesync.go: -------------------------------------------------------------------------------- 1 | package imagesync 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "os" 8 | "regexp" 9 | "strings" 10 | "sync" 11 | 12 | "github.com/containers/image/v5/copy" 13 | "github.com/containers/image/v5/docker" 14 | dockerarchive "github.com/containers/image/v5/docker/archive" 15 | ociarchive "github.com/containers/image/v5/oci/archive" 16 | ocilayout "github.com/containers/image/v5/oci/layout" 17 | "github.com/containers/image/v5/signature" 18 | "github.com/containers/image/v5/types" 19 | "github.com/samber/lo" 20 | "github.com/sirupsen/logrus" 21 | "github.com/urfave/cli" 22 | ) 23 | 24 | var Version string 25 | 26 | var ErrInvalidTag = errors.New("invalid tag") 27 | 28 | func Execute() error { 29 | app := cli.NewApp() 30 | app.Name = "imagesync" 31 | app.Usage = "Sync images in registries." 32 | app.Version = Version 33 | 34 | app.Flags = []cli.Flag{ 35 | cli.StringFlag{ 36 | Name: "src, s", 37 | Usage: "Reference for the source image/repository.", 38 | Required: true, 39 | }, 40 | cli.BoolFlag{ 41 | Name: "src-strict-tls", 42 | Usage: "Enable strict TLS for connections to source registry.", 43 | }, 44 | cli.StringFlag{ 45 | Name: "dest, d", 46 | Usage: "Reference for the destination repository.", 47 | Required: true, 48 | }, 49 | cli.BoolFlag{ 50 | Name: "dest-strict-tls", 51 | Usage: "Enable strict TLS for connections to destination registry.", 52 | }, 53 | cli.StringFlag{ 54 | Name: "tags-pattern", 55 | Usage: "Regex pattern to select tags for syncing.", 56 | }, 57 | cli.StringFlag{ 58 | Name: "skip-tags-pattern", 59 | Usage: "Regex pattern to exclude tags.", 60 | }, 61 | cli.StringFlag{ 62 | Name: "skip-tags", 63 | Usage: "Comma separated list of tags to be skipped.", 64 | }, 65 | cli.BoolFlag{ 66 | Name: "overwrite", 67 | Usage: "Use this to copy/override all the tags.", 68 | }, 69 | cli.IntFlag{ 70 | Name: "max-concurrent-tags", 71 | Usage: "Maximum number of tags to be synced/copied in parallel.", 72 | Value: 1, 73 | }, 74 | } 75 | 76 | app.Action = cli.ActionFunc(DetectAndCopyImage) 77 | 78 | if err := app.Run(os.Args); err != nil { 79 | return err 80 | } 81 | return nil 82 | } 83 | 84 | // DetectAndCopyImage will try to detect the source type and will 85 | // copy the image. Detection is based on following rules if: 86 | // 87 | // - src is a directory assume it is an OCI layout. 88 | // - src is file detect for oci-archive or docker-archive. 89 | // - src is an image with a tag copy single image to dest. 90 | // - none of the above then it is an entire repository sync 91 | // to sync the repositories. 92 | func DetectAndCopyImage(c *cli.Context) error { 93 | dest := c.String("dest") 94 | destRef, err := docker.ParseReference(fmt.Sprintf("//%s", dest)) 95 | if err != nil { 96 | return fmt.Errorf("parsing destination ref: %w", err) 97 | } 98 | 99 | // setup copy options 100 | opts := copy.Options{ 101 | ReportWriter: os.Stdout, 102 | ImageListSelection: copy.CopyAllImages, 103 | } 104 | if !c.Bool("dest-strict-tls") { 105 | opts.DestinationCtx = &types.SystemContext{DockerInsecureSkipTLSVerify: types.NewOptionalBool(true)} 106 | } 107 | if !c.Bool("src-strict-tls") { 108 | opts.SourceCtx = &types.SystemContext{DockerInsecureSkipTLSVerify: types.NewOptionalBool(true)} 109 | } 110 | 111 | ctx := context.Background() 112 | src := c.String("src") 113 | if info, err := os.Stat(src); err == nil { 114 | // copy oci layout 115 | if info.IsDir() { 116 | srcRef, err := ocilayout.ParseReference(src) 117 | if err != nil { 118 | return fmt.Errorf("parsing source oci ref: %w", err) 119 | } 120 | if err = copyImage(ctx, destRef, srcRef, &opts); err != nil { 121 | return fmt.Errorf("copy oci layout: %w", err) 122 | } 123 | logrus.Info("Image(s) sync completed.") 124 | return nil 125 | } 126 | 127 | // try copying oci archive with docker archive as fallback 128 | srcRef, _ := ociarchive.ParseReference(src) 129 | if err = copyImage(ctx, destRef, srcRef, &opts); err != nil { 130 | srcRef, err = dockerarchive.ParseReference(src) 131 | if err != nil { 132 | return fmt.Errorf("parsing source docker-archive ref: %w", err) 133 | } 134 | if err = copyImage(ctx, destRef, srcRef, &opts); err != nil { 135 | return fmt.Errorf("copy docker-archive layout: %w", err) 136 | } 137 | } 138 | } else { 139 | // copy single tag sync entire repository 140 | srcRef, err := docker.ParseReference(fmt.Sprintf("//%s", src)) 141 | if err != nil { 142 | return fmt.Errorf("parsing source docker ref: %w", err) 143 | } 144 | if hasTag(src, srcRef) { 145 | if err = copyImage(ctx, destRef, srcRef, &opts); err != nil { 146 | return fmt.Errorf("copy tag: %w", err) 147 | } 148 | } else { 149 | if hasTag(dest, destRef) { 150 | return fmt.Errorf("tag shouldn't be provided in dest: %w", ErrInvalidTag) 151 | } 152 | if err = copyRepository(ctx, c, destRef, srcRef, opts); err != nil { 153 | return fmt.Errorf("copy repository: %w", err) 154 | } 155 | } 156 | } 157 | 158 | logrus.Info("Image(s) sync completed.") 159 | return nil 160 | } 161 | 162 | func copyRepository(ctx context.Context, cliCtx *cli.Context, destRepository, srcRepository types.ImageReference, opts copy.Options) error { 163 | srcTags, err := docker.GetRepositoryTags(ctx, opts.SourceCtx, srcRepository) 164 | if err != nil { 165 | return fmt.Errorf("getting source tags: %w", err) 166 | } 167 | 168 | // skip tags 169 | shouldSkip := cliCtx.String("skip-tags") 170 | if shouldSkip != "" { 171 | srcTags = subtract(srcTags, strings.Split(shouldSkip, ",")) 172 | } 173 | 174 | // match tags 175 | if pattern := cliCtx.String("tags-pattern"); pattern != "" { 176 | re, err := regexp.Compile(pattern) 177 | if err != nil { 178 | return fmt.Errorf("%q is not valid regexp", pattern) 179 | } 180 | 181 | srcTags = lo.Filter(srcTags, func(item string, index int) bool { return re.MatchString(item) }) 182 | } 183 | 184 | // exclude tags 185 | if pattern := cliCtx.String("skip-tags-pattern"); pattern != "" { 186 | re, err := regexp.Compile(pattern) 187 | if err != nil { 188 | return fmt.Errorf("%q is not valid regexp", pattern) 189 | } 190 | srcTags = lo.Filter(srcTags, func(item string, index int) bool { return !re.MatchString(item) }) 191 | } 192 | 193 | var tags []string 194 | destTags, err := docker.GetRepositoryTags(ctx, opts.DestinationCtx, destRepository) 195 | if cliCtx.Bool("overwrite") || err != nil { 196 | tags = srcTags 197 | } else { 198 | tags = subtract(srcTags, destTags) 199 | } 200 | 201 | if len(tags) == 0 { 202 | logrus.Info("Image in repositories are already synced") 203 | os.Exit(0) 204 | } 205 | 206 | logrus.Infof("Starting image sync with total-tags=%d tags=%v source=%s destination=%s", len(tags), tags, srcRepository.DockerReference().Name(), destRepository.DockerReference().Name()) 207 | 208 | // limit the go routines to avoid 429 on registries 209 | maxConcurrentTags := cliCtx.Int("max-concurrent-tags") 210 | numberOfConcurrentTags := maxConcurrentTags 211 | if len(tags) < maxConcurrentTags { 212 | numberOfConcurrentTags = len(tags) 213 | } 214 | 215 | // sync repository by copying each tag. Errors are ignored on purpose 216 | // and only warning are shown via ReportWriter for failing tags. 217 | var wg sync.WaitGroup 218 | ch := make(chan string, len(tags)) 219 | wg.Add(numberOfConcurrentTags) 220 | for i := 0; i < numberOfConcurrentTags; i++ { 221 | go func() { 222 | for { 223 | tag, ok := <-ch 224 | if !ok { 225 | wg.Done() 226 | return 227 | } 228 | destTagRef, err := docker.ParseReference(fmt.Sprintf("//%s:%s", cliCtx.String("dest"), tag)) 229 | if err != nil { 230 | logrus.Warnf("failed parsing dest ref: %s", err) 231 | } 232 | srcTagRef, err := docker.ParseReference(fmt.Sprintf("//%s:%s", cliCtx.String("src"), tag)) 233 | if err != nil { 234 | logrus.Warnf("failed parsing src ref: %s", err) 235 | } 236 | if err = copyImage(ctx, destTagRef, srcTagRef, &opts); err != nil { 237 | logrus.Warnf("failed copying image: %s", err) 238 | } 239 | } 240 | }() 241 | } 242 | for _, tag := range tags { 243 | ch <- tag 244 | } 245 | close(ch) 246 | wg.Wait() 247 | return nil 248 | } 249 | 250 | func copyImage(ctx context.Context, destRef, srcRef types.ImageReference, opts *copy.Options) error { 251 | policyContext, err := signature.NewPolicyContext(&signature.Policy{ 252 | Default: []signature.PolicyRequirement{signature.NewPRInsecureAcceptAnything()}, 253 | }) 254 | if err != nil { 255 | return fmt.Errorf("creating policy context: %w", err) 256 | } 257 | if _, err = copy.Image(ctx, policyContext, destRef, srcRef, opts); err != nil { 258 | return fmt.Errorf("copying image: %w", err) 259 | } 260 | 261 | return nil 262 | } 263 | 264 | func hasTag(ref string, imageRef types.ImageReference) bool { 265 | return strings.HasSuffix(imageRef.DockerReference().String(), ref) 266 | } 267 | 268 | func subtract(ts1 []string, ts2 []string) []string { 269 | var diff []string 270 | for _, term := range ts1 { 271 | if lo.Contains(ts2, term) { 272 | continue 273 | } 274 | diff = append(diff, term) 275 | } 276 | return diff 277 | } 278 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION=$(git describe --tags --abbrev=0) 4 | VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" 5 | GITHUB_TOKEN=$(cat "${HOME}"/.githubtoken ) 6 | 7 | if [[ ! ${VERSION} =~ $VERSION_REGEX ]]; then 8 | echo "Latest tag $VERSION must be a SemVer, exiting ..." 9 | exit 1 10 | fi 11 | 12 | if [[ -z ${GITHUB_TOKEN} ]]; then 13 | echo "Please set the \$GITHUB_TOKEN, exiting ..." 14 | exit 1 15 | fi 16 | 17 | docker run -it --rm \ 18 | -v "$PWD":/src \ 19 | -w /src \ 20 | -e GITHUB_TOKEN="${GITHUB_TOKEN}" \ 21 | ghcr.io/goreleaser/goreleaser-cross:v1.23.5 release 22 | -------------------------------------------------------------------------------- /testdata/alpine-oci.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine-oci.tar -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/0c673ee68853a04014c0c623ba5ee21ee700e1d71f7ac1160ddb2e31c6fdbb18: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 4 | "config": { 5 | "mediaType": "application/vnd.docker.container.image.v1+json", 6 | "size": 1485, 7 | "digest": "sha256:b2cce0f0dbe61be2d8aa8228e6cfc757064cde399198b877e50fdf57beda2c12" 8 | }, 9 | "layers": [ 10 | { 11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", 12 | "size": 2417065, 13 | "digest": "sha256:c6556b3b6858c6fa1e328377cc2c4becdc9cd1bc3e7302aa7299936522cf93ba" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 4 | "config": { 5 | "mediaType": "application/vnd.docker.container.image.v1+json", 6 | "size": 1470, 7 | "digest": "sha256:9c6f0724472873bb50a2ae67a9e7adcb57673a183cea8b06eb778dca859181b5" 8 | }, 9 | "layers": [ 10 | { 11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", 12 | "size": 2806054, 13 | "digest": "sha256:213ec9aee27d8be045c6a92b7eac22c9a64b44558193775a1a7f626352392b49" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/13749bbca9f97be00999dbeb8bf38b3c185f20b8472bb73249ab867de4e4d6fd: -------------------------------------------------------------------------------- 1 | {"architecture":"arm","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Image":"sha256:319d1c683890c5b0a5778fcfba31e5d533eb2973e54e8fad4342410e50b53486","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"0fab3f57d92717ee2e4a3ba8e056e9007478a90ec19d53fe398d5c3fcaece453","container_config":{"Hostname":"0fab3f57d927","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"Image":"sha256:319d1c683890c5b0a5778fcfba31e5d533eb2973e54e8fad4342410e50b53486","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2022-08-09T17:49:22.44746317Z","docker_version":"20.10.12","history":[{"created":"2022-08-09T17:49:22.223933084Z","created_by":"/bin/sh -c #(nop) ADD file:e8733e8cc0a81e15ca4041760b6e27392c34171512d34405a9b262b1fff5c687 in / "},{"created":"2022-08-09T17:49:22.44746317Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:847cef20dd8bcc24d2313e7afea7501c2776b1f0ffe77c954974f9184897fa0d"]},"variant":"v6"} -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/1d96e60e5270815238e999aed0ae61d22ac6f5e5f976054b24796d0e0158b39c: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 4 | "config": { 5 | "mediaType": "application/vnd.docker.container.image.v1+json", 6 | "size": 1470, 7 | "digest": "sha256:9a88b8895602862ed151c64204a1fa465366d6fa4bb7797f09e7d32d9e6763c0" 8 | }, 9 | "layers": [ 10 | { 11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", 12 | "size": 2807121, 13 | "digest": "sha256:6c0d3b419d848ea31ca748254611d5d5ce3b76e3d7bba520fd87400fbb75f3b9" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/213ec9aee27d8be045c6a92b7eac22c9a64b44558193775a1a7f626352392b49: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine-oci/blobs/sha256/213ec9aee27d8be045c6a92b7eac22c9a64b44558193775a1a7f626352392b49 -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/4d0c95c8f9f7c6363ffe08596a1c6a624f3bf59d61a663083a816b59cb2e47f1: -------------------------------------------------------------------------------- 1 | {"architecture":"s390x","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Image":"sha256:b245d1a82d21dae5e0fb64b8108565a97274f9c74c688538d5a05d5885042272","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"72ca892280d3601a6b196834d473758431b6678f1ad405b25db6d2b66426e92e","container_config":{"Hostname":"72ca892280d3","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"Image":"sha256:b245d1a82d21dae5e0fb64b8108565a97274f9c74c688538d5a05d5885042272","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2022-08-09T17:41:46.365492087Z","docker_version":"20.10.12","history":[{"created":"2022-08-09T17:41:46.115340634Z","created_by":"/bin/sh -c #(nop) ADD file:b43a065471bc4711415d3c67cd5b6559b0c48ee7ffe9761530477cf457a6dc34 in / "},{"created":"2022-08-09T17:41:46.365492087Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:52e9a0c02513030e2dc642e29f9b8245c570e6af691c60a2e6b3b5f55da3c77d"]}} -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/520cf2ab7c1a1ba979e7d20c8ad2b433d119288ba0b88660a0afdca28f41afb3: -------------------------------------------------------------------------------- 1 | {"architecture":"ppc64le","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Image":"sha256:d97b74b9417797ca012489ecad0095b91b19a17d32aeced08c192388d09cc7ad","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"4b975e853d3e006f7c7dceb68f60489c60ae90798a584de362dc63634c4a382f","container_config":{"Hostname":"4b975e853d3e","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"Image":"sha256:d97b74b9417797ca012489ecad0095b91b19a17d32aeced08c192388d09cc7ad","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2022-08-09T17:17:10.038905647Z","docker_version":"20.10.12","history":[{"created":"2022-08-09T17:17:09.642954049Z","created_by":"/bin/sh -c #(nop) ADD file:66b351666e41834033d334aeb3dc6998dea77aa22e8e254028c923fee67a41a8 in / "},{"created":"2022-08-09T17:17:10.038905647Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:c5c7928ad132a6df2252946007bb0575fa17ac952d42df28867211dd330d26ac"]}} -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/5da989a9a3a08357bc7c00bd46c3ed782e1aeefc833e0049e6834ec1dcad8a42: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 4 | "config": { 5 | "mediaType": "application/vnd.docker.container.image.v1+json", 6 | "size": 1483, 7 | "digest": "sha256:13749bbca9f97be00999dbeb8bf38b3c185f20b8472bb73249ab867de4e4d6fd" 8 | }, 9 | "layers": [ 10 | { 11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", 12 | "size": 2613965, 13 | "digest": "sha256:9506b835437abb4d8ba1683e00c500b8f77e1975e930b356fbb72f2dbdc274d9" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/6c0d3b419d848ea31ca748254611d5d5ce3b76e3d7bba520fd87400fbb75f3b9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine-oci/blobs/sha256/6c0d3b419d848ea31ca748254611d5d5ce3b76e3d7bba520fd87400fbb75f3b9 -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/790c84f1f3409eab952345157df7fa804ba6b5f06d4ceb6f2dfa3c6de2064397: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine-oci/blobs/sha256/790c84f1f3409eab952345157df7fa804ba6b5f06d4ceb6f2dfa3c6de2064397 -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/9506b835437abb4d8ba1683e00c500b8f77e1975e930b356fbb72f2dbdc274d9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine-oci/blobs/sha256/9506b835437abb4d8ba1683e00c500b8f77e1975e930b356fbb72f2dbdc274d9 -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/9a88b8895602862ed151c64204a1fa465366d6fa4bb7797f09e7d32d9e6763c0: -------------------------------------------------------------------------------- 1 | {"architecture":"386","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Image":"sha256:1652ab5b10eabffcc8f26f7f76300c4ffef7d5400a49b265c53cdbc37b13ea32","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"69a1b5368e65b7b4cc441d99d49e5bc05c12cd6be255d7eec368e504c82a6d7b","container_config":{"Hostname":"69a1b5368e65","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"Image":"sha256:1652ab5b10eabffcc8f26f7f76300c4ffef7d5400a49b265c53cdbc37b13ea32","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2022-08-09T17:38:39.316717562Z","docker_version":"20.10.12","history":[{"created":"2022-08-09T17:38:39.056216551Z","created_by":"/bin/sh -c #(nop) ADD file:b828bc14bc5ff03c8f7310fe0aed6ac5df19a393622d5d1d779a523234d07c0a in / "},{"created":"2022-08-09T17:38:39.316717562Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:ee679b2966f2656afd0eb6ec6db00c70679575bfff8d5fd2e0795dc2b7f2d741"]}} -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/9b18e9b68314027565b90ff6189d65942c0f7986da80df008b8431276885218e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine-oci/blobs/sha256/9b18e9b68314027565b90ff6189d65942c0f7986da80df008b8431276885218e -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/9c6f0724472873bb50a2ae67a9e7adcb57673a183cea8b06eb778dca859181b5: -------------------------------------------------------------------------------- 1 | {"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Image":"sha256:c0261ca8a4a79627f3e658c0c2b1e3166f56713a58e1411b1e3ab1e378962e75","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"0c4b20968eb1d804460f8612bc52be4f5a8e65eb14190b5ae30fec94d2fb4f50","container_config":{"Hostname":"0c4b20968eb1","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"Image":"sha256:c0261ca8a4a79627f3e658c0c2b1e3166f56713a58e1411b1e3ab1e378962e75","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2022-08-09T17:19:53.47374331Z","docker_version":"20.10.12","history":[{"created":"2022-08-09T17:19:53.274069586Z","created_by":"/bin/sh -c #(nop) ADD file:2a949686d9886ac7c10582a6c29116fd29d3077d02755e87e111870d63607725 in / "},{"created":"2022-08-09T17:19:53.47374331Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:994393dc58e7931862558d06e46aa2bb17487044f670f310dffe1d24e4d1eec7"]}} -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/a6215f271958c760a2975a6765016044115dbae4b90f414eba3a448a6a26b4f6: -------------------------------------------------------------------------------- 1 | {"architecture":"arm64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Image":"sha256:3677e158eeff3032a22f0c59d48a6d11815fc3a8a1db257a5492be5f66e27e4d","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"0b62327de505ff9d53d437341a21096bb9ef764c684fd778dc94490c39df7800","container_config":{"Hostname":"0b62327de505","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"Image":"sha256:3677e158eeff3032a22f0c59d48a6d11815fc3a8a1db257a5492be5f66e27e4d","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2022-08-09T17:39:42.400443113Z","docker_version":"20.10.12","history":[{"created":"2022-08-09T17:39:41.840607995Z","created_by":"/bin/sh -c #(nop) ADD file:960fd469d48cf79ba14bbda71f3192074ed860c112e30e0bc92bff3440cb45ab in / "},{"created":"2022-08-09T17:39:42.400443113Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:5d3e392a13a0fdfbf8806cb4a5e4b0a92b5021103a146249d8a2c999f06a9772"]},"variant":"v8"} -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/b2cce0f0dbe61be2d8aa8228e6cfc757064cde399198b877e50fdf57beda2c12: -------------------------------------------------------------------------------- 1 | {"architecture":"arm","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Image":"sha256:b70d079436c3be8fe71d6b2aa0596aaa136e991f79007273ecb1396e69a65d30","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"8c666aeca787f4cf22fd3365495c0d68d567eac005c1724c72d1622e5fecf84f","container_config":{"Hostname":"8c666aeca787","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"Image":"sha256:b70d079436c3be8fe71d6b2aa0596aaa136e991f79007273ecb1396e69a65d30","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2022-08-09T16:57:44.380297658Z","docker_version":"20.10.12","history":[{"created":"2022-08-09T16:57:44.277705433Z","created_by":"/bin/sh -c #(nop) ADD file:75521fe16320b193092588f6f31052c85e736965ceb11673de18bd14965a45e6 in / "},{"created":"2022-08-09T16:57:44.380297658Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:9f4c631c29019ad979563c1915df489896095eee1321ff085e182fcf99c0a954"]},"variant":"v7"} -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad: -------------------------------------------------------------------------------- 1 | {"manifests":[{"digest":"sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"amd64","os":"linux"},"size":528},{"digest":"sha256:5da989a9a3a08357bc7c00bd46c3ed782e1aeefc833e0049e6834ec1dcad8a42","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm","os":"linux","variant":"v6"},"size":528},{"digest":"sha256:0c673ee68853a04014c0c623ba5ee21ee700e1d71f7ac1160ddb2e31c6fdbb18","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm","os":"linux","variant":"v7"},"size":528},{"digest":"sha256:ed73e2bee79b3428995b16fce4221fc715a849152f364929cdccdc83db5f3d5c","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm64","os":"linux","variant":"v8"},"size":528},{"digest":"sha256:1d96e60e5270815238e999aed0ae61d22ac6f5e5f976054b24796d0e0158b39c","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"386","os":"linux"},"size":528},{"digest":"sha256:fa30af02cc8c339dd7ffecb0703cd4a3db175e56875c413464c5ba46821253a8","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"ppc64le","os":"linux"},"size":528},{"digest":"sha256:c2046a6c3d2db4f75bfb8062607cc8ff47896f2d683b7f18fe6b6cf368af3c60","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"s390x","os":"linux"},"size":528}],"mediaType":"application\/vnd.docker.distribution.manifest.list.v2+json","schemaVersion":2} -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/c2046a6c3d2db4f75bfb8062607cc8ff47896f2d683b7f18fe6b6cf368af3c60: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 4 | "config": { 5 | "mediaType": "application/vnd.docker.container.image.v1+json", 6 | "size": 1472, 7 | "digest": "sha256:4d0c95c8f9f7c6363ffe08596a1c6a624f3bf59d61a663083a816b59cb2e47f1" 8 | }, 9 | "layers": [ 10 | { 11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", 12 | "size": 2590597, 13 | "digest": "sha256:790c84f1f3409eab952345157df7fa804ba6b5f06d4ceb6f2dfa3c6de2064397" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/c6556b3b6858c6fa1e328377cc2c4becdc9cd1bc3e7302aa7299936522cf93ba: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine-oci/blobs/sha256/c6556b3b6858c6fa1e328377cc2c4becdc9cd1bc3e7302aa7299936522cf93ba -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/c79e5d1a8c89b87020a754c8a5c8370faaa37bfb5bca1d8af66770d522ef1caf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine-oci/blobs/sha256/c79e5d1a8c89b87020a754c8a5c8370faaa37bfb5bca1d8af66770d522ef1caf -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/ed73e2bee79b3428995b16fce4221fc715a849152f364929cdccdc83db5f3d5c: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 4 | "config": { 5 | "mediaType": "application/vnd.docker.container.image.v1+json", 6 | "size": 1487, 7 | "digest": "sha256:a6215f271958c760a2975a6765016044115dbae4b90f414eba3a448a6a26b4f6" 8 | }, 9 | "layers": [ 10 | { 11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", 12 | "size": 2707663, 13 | "digest": "sha256:9b18e9b68314027565b90ff6189d65942c0f7986da80df008b8431276885218e" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /testdata/alpine-oci/blobs/sha256/fa30af02cc8c339dd7ffecb0703cd4a3db175e56875c413464c5ba46821253a8: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 4 | "config": { 5 | "mediaType": "application/vnd.docker.container.image.v1+json", 6 | "size": 1474, 7 | "digest": "sha256:520cf2ab7c1a1ba979e7d20c8ad2b433d119288ba0b88660a0afdca28f41afb3" 8 | }, 9 | "layers": [ 10 | { 11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", 12 | "size": 2803320, 13 | "digest": "sha256:c79e5d1a8c89b87020a754c8a5c8370faaa37bfb5bca1d8af66770d522ef1caf" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /testdata/alpine-oci/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "manifests": [ 4 | { 5 | "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", 6 | "size": 1638, 7 | "digest": "sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad" 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /testdata/alpine-oci/oci-layout: -------------------------------------------------------------------------------- 1 | { 2 | "imageLayoutVersion": "1.0.0" 3 | } -------------------------------------------------------------------------------- /testdata/alpine.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqasimsarfraz/imagesync/86e9ed1e29b4dfc097c9302610786ce80f32e85d/testdata/alpine.tar --------------------------------------------------------------------------------