Kotlin implementation of the OCI Distribution client specification.
// 0. Create a file store
val store = runBlocking { Layout.create("/tmp/koci-store") }.getOrThrow()
// 1. Connect to a remote repository
val repo = Registry("https://public.ecr.aws").repo("ubuntu/redis")
// 2. Copy from the remote repository to the file store
val tag = "latest"
repo.pull(tag, store).collect{ prog ->
println("$prog% done")
}
- Request scopes relevant code
- Basic/Bearer auth w/ Distribution auth flow
- Docker's
~/.docker/config.json
support
- GET
/v2/
Ping registry - GET
/v2/_catalog
Catalog- Support pagination
- HEAD|GET
/v2/<name>/manifests/<reference>
Check for existence / fetch manifest by tag/digest- Resolve/fetch tag into manifest/index
- Support custom index -> manifest resolution logic
- Reference support and validation
- Resolve/fetch tag into manifest/index
- DELETE
/v2/<name>/manifests/<digest>
- GET
/v2/<name>/tags/list
List image tags- Support pagination
- Pull image (3 layer concurrency) with %/100 progress
- By tag
- By descriptor
- Into OCI layout
- Fetch blob
-
Accept-Ranges: bytes
detection +Range
support - Resumable downloads
- Content verification using size + digest
-
- Referrers API
- Push blobs
- Resumable uploads
- Single PUT request if content <
OCI-Chunk-Min-Length
or 5MB if unset. Chunked upload otherwise
- Push + tag manifests/indexes
- Referrers API
Support for SHA-256 and SHA-512 hashing algorithms.
-
index.json
- Resolve by image reference via
org.opencontainers.image.ref.name
- Resolve by digest
- Resolve through custom logic
- Resolve by image reference via
-
oci-layout
-
blobs
directory- Remove blob by descriptor
- Remove image/artifact by digest/reference
- Garbage collection
Changes to the concurrency API of
koci
are currently subject to change at any time.For now, it is best to run operations that could interfere (images sharing layers) sequentially.
See CONTRIBUTING.md.
See CODE_OF_CONDUCT.md.