mirror of
https://github.com/containers/skopeo.git
synced 2026-01-31 14:29:03 +00:00
Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2c1eecd40 | ||
|
|
5650a2cd4d | ||
|
|
33d3ae416a | ||
|
|
bec43c5784 | ||
|
|
36176ac499 | ||
|
|
92ee8a550d | ||
|
|
d1bbcb4626 | ||
|
|
5973d144f2 | ||
|
|
cf76c899c7 | ||
|
|
a4f3fb313a | ||
|
|
b59c8598cd | ||
|
|
203a4cf741 | ||
|
|
319d18c0f9 | ||
|
|
94e949984f | ||
|
|
5d2cb67fb1 | ||
|
|
4dafc99bd6 | ||
|
|
d64b59917d | ||
|
|
5a1e5749c8 | ||
|
|
0aab0745e9 | ||
|
|
7b68a033bc | ||
|
|
a3b8e175c5 | ||
|
|
729a053464 | ||
|
|
f17b4c9672 | ||
|
|
cb17dedf54 | ||
|
|
f87d569628 | ||
|
|
b395b2b923 | ||
|
|
f9bdc2d8fc | ||
|
|
1f18641d34 | ||
|
|
8651716fa7 | ||
|
|
4ac60afc85 | ||
|
|
73f3b44cdb | ||
|
|
862c2331b7 | ||
|
|
872ab48154 | ||
|
|
ef2375bc80 | ||
|
|
a4ab531365 | ||
|
|
3de83e9f73 | ||
|
|
e5104ad291 | ||
|
|
3c93577be1 | ||
|
|
b6c726f854 | ||
|
|
ac8b652729 | ||
|
|
c49bbbe2ee | ||
|
|
99c6fb09e9 | ||
|
|
634c0d99f3 | ||
|
|
40353ad7eb | ||
|
|
855cfb2f23 | ||
|
|
bdc6d70f0e | ||
|
|
654c3fcc9c | ||
|
|
54077f5238 | ||
|
|
3ddcdee045 | ||
|
|
25d4df6ee8 | ||
|
|
abf7bbbab3 | ||
|
|
0f7515e099 | ||
|
|
889225db22 | ||
|
|
eb0e5cf578 | ||
|
|
f87cd5ec62 | ||
|
|
a50b2d910b | ||
|
|
753f8be5c6 | ||
|
|
763606cdde | ||
|
|
f825fdcb15 | ||
|
|
ea37e10d4b | ||
|
|
69af7bfe4c | ||
|
|
3618a76e92 | ||
|
|
8abee34d4b | ||
|
|
08dc3c94de | ||
|
|
65cee5abeb | ||
|
|
c9d5569a84 | ||
|
|
cfae4fd800 | ||
|
|
3ad4bfcfee | ||
|
|
5c119083fe | ||
|
|
50f414a7cf | ||
|
|
dc88f3211b | ||
|
|
a5cbf05259 | ||
|
|
c3e66b5876 | ||
|
|
aaba5370de |
@@ -21,7 +21,7 @@ env:
|
||||
SCRIPT_BASE: "./contrib/cirrus"
|
||||
|
||||
# Google-cloud VM Images
|
||||
IMAGE_SUFFIX: "c20250422t130822z-f42f41d13"
|
||||
IMAGE_SUFFIX: "c20250721t181111z-f42f41d13"
|
||||
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
|
||||
|
||||
# Container FQIN's
|
||||
|
||||
@@ -54,6 +54,9 @@ jobs:
|
||||
- fedora-all-x86_64
|
||||
- fedora-all-aarch64
|
||||
enable_net: true
|
||||
# Re-enable these scans if OpenScanHub starts scanning go packages
|
||||
# https://packit.dev/posts/openscanhub-prototype
|
||||
osh_diff_scan_after_copr_build: false
|
||||
|
||||
# Ignore until golang is updated in distro buildroot to go 1.23.3+
|
||||
- job: copr_build
|
||||
@@ -129,8 +132,10 @@ jobs:
|
||||
- fedora-all
|
||||
|
||||
# Sync to CentOS Stream
|
||||
# FIXME: Switch trigger whenever we're ready to update CentOS Stream via
|
||||
# Packit
|
||||
- job: propose_downstream
|
||||
trigger: release
|
||||
trigger: ignore
|
||||
packages: [skopeo-centos]
|
||||
update_release: false
|
||||
dist_git_branches:
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
## The Skopeo Project Community Governance
|
||||
|
||||
The Skopeo project, as part of Podman Container Tools, follows the [Podman Project Governance](https://github.com/containers/podman/blob/main/GOVERNANCE.md).
|
||||
The Skopeo project, as part of Podman Container Tools, follows the [Podman Project Governance](https://github.com/containers/podman/blob/main/GOVERNANCE.md)
|
||||
except sections found in this document, which override those found in Podman's Governance.
|
||||
|
||||
---
|
||||
|
||||
# Maintainers File
|
||||
|
||||
The definitive source of truth for maintainers of this repository is the local [MAINTAINERS.md](./MAINTAINERS.md) file. The [MAINTAINERS.md](https://github.com/containers/podman/blob/main/MAINTAINERS.md) file in the main Podman repository is used for project-spanning roles, including Core Maintainer and Community Manager. Some repositories in the project will also have a local [OWNERS](./OWNERS) file, which the CI system uses to map users to roles. Any changes to the [OWNERS](./OWNERS) file must make a corresponding change to the [MAINTAINERS.md](./MAINTAINERS.md) file to ensure that the file remains up to date. Most changes to [MAINTAINERS.md](./MAINTAINERS.md) will require a change to the repository’s [OWNERS](.OWNERS) file (e.g., adding a Reviewer), but some will not (e.g., promoting a Maintainer to a Core Maintainer, which comes with no additional CI-related privileges).
|
||||
|
||||
Any Core Maintainers listed in Podman’s [MAINTAINERS.md](https://github.com/containers/podman/blob/main/MAINTAINERS.md) file should also be added to the list of “approvers” in the local [OWNERS](./OWNERS) file and as a Core Maintainer in the list of “Maintainers” in the local [MAINTAINERS.md](./MAINTAINERS.md) file.
|
||||
|
||||
@@ -13,12 +13,13 @@ describes the project's governance and the Project Roles used below.
|
||||
| Paul Holzinger | [Luap99](https://github.com/Luap99) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Giuseppe Scrivano | [giuseppe](https://github.com/giuseppe) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Miloslav Trmač | [mtrmac](https://github.com/mtrmac) | Core Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Neil Smith | [Neil-Smith](https://github.com/Neil-Smith) | Community Manager | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Neil Smith | [actionmancan](https://github.com/actionmancan) | Community Manager | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Tom Sweeney | [TomSweeneyRedHat](https://github.com/TomSweeneyRedHat/) | Maintainer and Community Manager | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Lokesh Mandvekar | [lsm5](https://github.com/lsm5) | Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Dan Walsh | [rhatdan](https://github.com/rhatdan) | Maintainer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Ashley Cui | [ashley-cui](https://github.com/ashley-cui) | Reviewer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Valentin Rothberg | [vrothberg](https://github.com/vrothberg) | Reviewer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
| Colin Walters | [cgwalters](https://github.com/cgwalters) | Reviewer | [Red Hat](https://github.com/RedHatOfficial) |
|
||||
|
||||
## Alumni
|
||||
|
||||
@@ -27,3 +28,7 @@ None at present
|
||||
## Credits
|
||||
|
||||
The structure of this document was based off of the equivalent one in the [CRI-O Project](https://github.com/cri-o/cri-o/blob/main/MAINTAINERS.md).
|
||||
|
||||
## Note
|
||||
|
||||
If there is a discrepancy between the [MAINTAINERS.md](https://github.com/containers/podman/blob/main/MAINTAINERS.md) file in the main Podman repository and this file regarding Core Maintainers or Community Managers, the file in the Podman Repository is considered the source of truth.
|
||||
|
||||
12
Makefile
12
Makefile
@@ -27,7 +27,7 @@ GOARCH ?= $(shell go env GOARCH)
|
||||
# N/B: This value is managed by Renovate, manual changes are
|
||||
# possible, as long as they don't disturb the formatting
|
||||
# (i.e. DO NOT ADD A 'v' prefix!)
|
||||
GOLANGCI_LINT_VERSION := 2.1.6
|
||||
GOLANGCI_LINT_VERSION := 2.3.0
|
||||
|
||||
ifeq ($(GOBIN),)
|
||||
GOBIN := $(GOPATH)/bin
|
||||
@@ -53,10 +53,9 @@ ifeq ($(GOOS), linux)
|
||||
endif
|
||||
endif
|
||||
|
||||
# If $TESTFLAGS is set, it is passed as extra arguments to 'go test'.
|
||||
# If $TESTFLAGS is set, it is passed as extra arguments to 'go test' on integration tests.
|
||||
# You can select certain tests to run, with `-run <regex>` for example:
|
||||
#
|
||||
# make test-unit TESTFLAGS='-run ^TestManifestDigest$'
|
||||
# make test-integration TESTFLAGS='-run copySuite.TestCopy.*'
|
||||
export TESTFLAGS ?= -timeout=15m
|
||||
|
||||
@@ -92,7 +91,8 @@ MANPAGES ?= $(MANPAGES_MD:%.md=%)
|
||||
|
||||
BTRFS_BUILD_TAG = $(shell hack/btrfs_installed_tag.sh)
|
||||
LIBSUBID_BUILD_TAG = $(shell hack/libsubid_tag.sh)
|
||||
LOCAL_BUILD_TAGS = $(BTRFS_BUILD_TAG) $(LIBSUBID_BUILD_TAG)
|
||||
SQLITE_BUILD_TAG = $(shell hack/sqlite_tag.sh)
|
||||
LOCAL_BUILD_TAGS = $(BTRFS_BUILD_TAG) $(LIBSUBID_BUILD_TAG) $(SQLITE_BUILD_TAG)
|
||||
BUILDTAGS += $(LOCAL_BUILD_TAGS)
|
||||
|
||||
ifeq ($(DISABLE_CGO), 1)
|
||||
@@ -204,7 +204,7 @@ test-integration:
|
||||
# Intended for CI, assumed to be running in quay.io/libpod/skopeo_cidev container.
|
||||
test-integration-local: bin/skopeo
|
||||
hack/warn-destructive-tests.sh
|
||||
hack/test-integration.sh
|
||||
hack/test-integration.sh $(SKOPEO_LDFLAGS) $(TESTFLAGS)
|
||||
|
||||
# complicated set of options needed to run podman-in-podman
|
||||
test-system:
|
||||
@@ -221,7 +221,7 @@ test-system:
|
||||
# Intended for CI, assumed to already be running in quay.io/libpod/skopeo_cidev container.
|
||||
test-system-local: bin/skopeo
|
||||
hack/warn-destructive-tests.sh
|
||||
hack/test-system.sh
|
||||
hack/test-system.sh SKOPEO_LDFLAGS="$(SKOPEO_LDFLAGS)" BUILDTAGS="$(BUILDTAGS)"
|
||||
|
||||
test-unit:
|
||||
# Just call (make test unit-local) here instead of worrying about environment differences
|
||||
|
||||
1
OWNERS
1
OWNERS
@@ -11,6 +11,7 @@ approvers:
|
||||
reviewers:
|
||||
- ashley-cui
|
||||
- baude
|
||||
- cgwalters
|
||||
- giuseppe
|
||||
- lsm5
|
||||
- Luap99
|
||||
|
||||
@@ -12,9 +12,6 @@ import (
|
||||
"github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/pkg/cli"
|
||||
"github.com/containers/image/v5/pkg/cli/sigstore"
|
||||
"github.com/containers/image/v5/signature/signer"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
encconfig "github.com/containers/ocicrypt/config"
|
||||
@@ -23,28 +20,22 @@ import (
|
||||
)
|
||||
|
||||
type copyOptions struct {
|
||||
global *globalOptions
|
||||
deprecatedTLSVerify *deprecatedTLSVerifyOption
|
||||
srcImage *imageOptions
|
||||
destImage *imageDestOptions
|
||||
retryOpts *retry.Options
|
||||
additionalTags []string // For docker-archive: destinations, in addition to the name:tag specified as destination, also add these
|
||||
removeSignatures bool // Do not copy signatures from the source image
|
||||
signByFingerprint string // Sign the image using a GPG key with the specified fingerprint
|
||||
signBySigstoreParamFile string // Sign the image using a sigstore signature per configuration in a param file
|
||||
signBySigstorePrivateKey string // Sign the image using a sigstore private key
|
||||
signPassphraseFile string // Path pointing to a passphrase file when signing (for either signature format, but only one of them)
|
||||
signIdentity string // Identity of the signed image, must be a fully specified docker reference
|
||||
digestFile string // Write digest to this file
|
||||
format commonFlag.OptionalString // Force conversion of the image to a specified format
|
||||
quiet bool // Suppress output information when copying images
|
||||
all bool // Copy all of the images if the source is a list
|
||||
multiArch commonFlag.OptionalString // How to handle multi architecture images
|
||||
preserveDigests bool // Preserve digests during copy
|
||||
encryptLayer []int // The list of layers to encrypt
|
||||
encryptionKeys []string // Keys needed to encrypt the image
|
||||
decryptionKeys []string // Keys needed to decrypt the image
|
||||
imageParallelCopies uint // Maximum number of parallel requests when copying images
|
||||
global *globalOptions
|
||||
deprecatedTLSVerify *deprecatedTLSVerifyOption
|
||||
srcImage *imageOptions
|
||||
destImage *imageDestOptions
|
||||
retryOpts *retry.Options
|
||||
copy *sharedCopyOptions
|
||||
additionalTags []string // For docker-archive: destinations, in addition to the name:tag specified as destination, also add these
|
||||
signIdentity string // Identity of the signed image, must be a fully specified docker reference
|
||||
digestFile string // Write digest to this file
|
||||
quiet bool // Suppress output information when copying images
|
||||
all bool // Copy all of the images if the source is a list
|
||||
multiArch commonFlag.OptionalString // How to handle multi architecture images
|
||||
encryptLayer []int // The list of layers to encrypt
|
||||
encryptionKeys []string // Keys needed to encrypt the image
|
||||
decryptionKeys []string // Keys needed to decrypt the image
|
||||
imageParallelCopies uint // Maximum number of parallel requests when copying images
|
||||
}
|
||||
|
||||
func copyCmd(global *globalOptions) *cobra.Command {
|
||||
@@ -53,11 +44,13 @@ func copyCmd(global *globalOptions) *cobra.Command {
|
||||
srcFlags, srcOpts := imageFlags(global, sharedOpts, deprecatedTLSVerifyOpt, "src-", "screds")
|
||||
destFlags, destOpts := imageDestFlags(global, sharedOpts, deprecatedTLSVerifyOpt, "dest-", "dcreds")
|
||||
retryFlags, retryOpts := retryFlags()
|
||||
copyFlags, copyOpts := sharedCopyFlags()
|
||||
opts := copyOptions{global: global,
|
||||
deprecatedTLSVerify: deprecatedTLSVerifyOpt,
|
||||
srcImage: srcOpts,
|
||||
destImage: destOpts,
|
||||
retryOpts: retryOpts,
|
||||
copy: copyOpts,
|
||||
}
|
||||
cmd := &cobra.Command{
|
||||
Use: "copy [command options] SOURCE-IMAGE DESTINATION-IMAGE",
|
||||
@@ -80,19 +73,13 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
|
||||
flags.AddFlagSet(&srcFlags)
|
||||
flags.AddFlagSet(&destFlags)
|
||||
flags.AddFlagSet(&retryFlags)
|
||||
flags.AddFlagSet(©Flags)
|
||||
flags.StringSliceVar(&opts.additionalTags, "additional-tag", []string{}, "additional tags (supports docker-archive)")
|
||||
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress output information when copying images")
|
||||
flags.BoolVarP(&opts.all, "all", "a", false, "Copy all images if SOURCE-IMAGE is a list")
|
||||
flags.Var(commonFlag.NewOptionalStringValue(&opts.multiArch), "multi-arch", `How to handle multi-architecture images (system, all, or index-only)`)
|
||||
flags.BoolVar(&opts.preserveDigests, "preserve-digests", false, "Preserve digests of images and lists")
|
||||
flags.BoolVar(&opts.removeSignatures, "remove-signatures", false, "Do not copy signatures from SOURCE-IMAGE")
|
||||
flags.StringVar(&opts.signByFingerprint, "sign-by", "", "Sign the image using a GPG key with the specified `FINGERPRINT`")
|
||||
flags.StringVar(&opts.signBySigstoreParamFile, "sign-by-sigstore", "", "Sign the image using a sigstore parameter file at `PATH`")
|
||||
flags.StringVar(&opts.signBySigstorePrivateKey, "sign-by-sigstore-private-key", "", "Sign the image using a sigstore private key at `PATH`")
|
||||
flags.StringVar(&opts.signPassphraseFile, "sign-passphrase-file", "", "Read a passphrase for signing an image from `PATH`")
|
||||
flags.StringVar(&opts.signIdentity, "sign-identity", "", "Identity of signed image, must be a fully specified docker reference. Defaults to the target docker reference.")
|
||||
flags.StringVar(&opts.digestFile, "digestfile", "", "Write the digest of the pushed image to the specified file")
|
||||
flags.VarP(commonFlag.NewOptionalStringValue(&opts.format), "format", "f", `MANIFEST TYPE (oci, v2s1, or v2s2) to use in the destination (default is manifest type of source, with fallbacks)`)
|
||||
flags.StringSliceVar(&opts.encryptionKeys, "encryption-key", []string{}, "*Experimental* key with the encryption protocol to use needed to encrypt the image (e.g. jwe:/path/to/key.pem)")
|
||||
flags.IntSliceVar(&opts.encryptLayer, "encrypt-layer", []int{}, "*Experimental* the 0-indexed layer indices, with support for negative indexing (e.g. 0 is the first layer, -1 is the last layer)")
|
||||
flags.StringSliceVar(&opts.decryptionKeys, "decryption-key", []string{}, "*Experimental* key needed to decrypt the image")
|
||||
@@ -160,14 +147,6 @@ func (opts *copyOptions) run(args []string, stdout io.Writer) (retErr error) {
|
||||
return err
|
||||
}
|
||||
|
||||
var manifestType string
|
||||
if opts.format.Present() {
|
||||
manifestType, err = parseManifestFormat(opts.format.Value())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, image := range opts.additionalTags {
|
||||
ref, err := reference.ParseNormalizedNamed(image)
|
||||
if err != nil {
|
||||
@@ -237,43 +216,6 @@ func (opts *copyOptions) run(args []string, stdout io.Writer) (retErr error) {
|
||||
decConfig = cc.DecryptConfig
|
||||
}
|
||||
|
||||
// c/image/copy.Image does allow creating both simple signing and sigstore signatures simultaneously,
|
||||
// with independent passphrases, but that would make the CLI probably too confusing.
|
||||
// For now, use the passphrase with either, but only one of them.
|
||||
if opts.signPassphraseFile != "" && opts.signByFingerprint != "" && opts.signBySigstorePrivateKey != "" {
|
||||
return fmt.Errorf("Only one of --sign-by and sign-by-sigstore-private-key can be used with sign-passphrase-file")
|
||||
}
|
||||
var passphrase string
|
||||
if opts.signPassphraseFile != "" {
|
||||
p, err := cli.ReadPassphraseFile(opts.signPassphraseFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
passphrase = p
|
||||
} else if opts.signBySigstorePrivateKey != "" {
|
||||
p, err := promptForPassphrase(opts.signBySigstorePrivateKey, os.Stdin, os.Stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
passphrase = p
|
||||
} // opts.signByFingerprint triggers a GPG-agent passphrase prompt, possibly using a more secure channel, so we usually shouldn’t prompt ourselves if no passphrase was explicitly provided.
|
||||
|
||||
var signers []*signer.Signer
|
||||
if opts.signBySigstoreParamFile != "" {
|
||||
signer, err := sigstore.NewSignerFromParameterFile(opts.signBySigstoreParamFile, &sigstore.Options{
|
||||
PrivateKeyPassphrasePrompt: func(keyFile string) (string, error) {
|
||||
return promptForPassphrase(keyFile, os.Stdin, os.Stdout)
|
||||
},
|
||||
Stdin: os.Stdin,
|
||||
Stdout: stdout,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error using --sign-by-sigstore: %w", err)
|
||||
}
|
||||
defer signer.Close()
|
||||
signers = append(signers, signer)
|
||||
}
|
||||
|
||||
var signIdentity reference.Named = nil
|
||||
if opts.signIdentity != "" {
|
||||
signIdentity, err = reference.ParseNamed(opts.signIdentity)
|
||||
@@ -284,26 +226,22 @@ func (opts *copyOptions) run(args []string, stdout io.Writer) (retErr error) {
|
||||
|
||||
opts.destImage.warnAboutIneffectiveOptions(destRef.Transport())
|
||||
|
||||
copyOpts, cleanupOptions, err := opts.copy.copyOptions(stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cleanupOptions()
|
||||
copyOpts.SignIdentity = signIdentity
|
||||
copyOpts.SourceCtx = sourceCtx
|
||||
copyOpts.DestinationCtx = destinationCtx
|
||||
copyOpts.ImageListSelection = imageListSelection
|
||||
copyOpts.OciDecryptConfig = decConfig
|
||||
copyOpts.OciEncryptLayers = encLayers
|
||||
copyOpts.OciEncryptConfig = encConfig
|
||||
copyOpts.MaxParallelDownloads = opts.imageParallelCopies
|
||||
|
||||
return retry.IfNecessary(ctx, func() error {
|
||||
manifestBytes, err := copy.Image(ctx, policyContext, destRef, srcRef, ©.Options{
|
||||
RemoveSignatures: opts.removeSignatures,
|
||||
Signers: signers,
|
||||
SignBy: opts.signByFingerprint,
|
||||
SignPassphrase: passphrase,
|
||||
SignBySigstorePrivateKeyFile: opts.signBySigstorePrivateKey,
|
||||
SignSigstorePrivateKeyPassphrase: []byte(passphrase),
|
||||
SignIdentity: signIdentity,
|
||||
ReportWriter: stdout,
|
||||
SourceCtx: sourceCtx,
|
||||
DestinationCtx: destinationCtx,
|
||||
ForceManifestMIMEType: manifestType,
|
||||
ImageListSelection: imageListSelection,
|
||||
PreserveDigests: opts.preserveDigests,
|
||||
OciDecryptConfig: decConfig,
|
||||
OciEncryptLayers: encLayers,
|
||||
OciEncryptConfig: encConfig,
|
||||
MaxParallelDownloads: opts.imageParallelCopies,
|
||||
})
|
||||
manifestBytes, err := copy.Image(ctx, policyContext, destRef, srcRef, copyOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -57,13 +57,13 @@ skopeo inspect --format "Name: {{.Name}} Digest: {{.Digest}}" docker://registry.
|
||||
}
|
||||
adjustUsage(cmd)
|
||||
flags := cmd.Flags()
|
||||
flags.AddFlagSet(&sharedFlags)
|
||||
flags.AddFlagSet(&imageFlags)
|
||||
flags.AddFlagSet(&retryFlags)
|
||||
flags.BoolVar(&opts.raw, "raw", false, "output raw manifest or configuration")
|
||||
flags.BoolVar(&opts.config, "config", false, "output configuration")
|
||||
flags.StringVarP(&opts.format, "format", "f", "", "Format the output to a Go template")
|
||||
flags.BoolVarP(&opts.doNotListTags, "no-tags", "n", false, "Do not list the available tags from the repository in the output")
|
||||
flags.AddFlagSet(&sharedFlags)
|
||||
flags.AddFlagSet(&imageFlags)
|
||||
flags.AddFlagSet(&retryFlags)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ func loginCmd(global *globalOptions) *cobra.Command {
|
||||
}
|
||||
adjustUsage(cmd)
|
||||
flags := cmd.Flags()
|
||||
commonFlag.OptionalBoolFlag(flags, &opts.tlsVerify, "tls-verify", "require HTTPS and verify certificates when accessing the registry")
|
||||
flags.AddFlagSet(auth.GetLoginFlags(&opts.loginOpts))
|
||||
commonFlag.OptionalBoolFlag(flags, &opts.tlsVerify, "tls-verify", "require HTTPS and verify certificates when accessing the registry")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ func logoutCmd(global *globalOptions) *cobra.Command {
|
||||
}
|
||||
adjustUsage(cmd)
|
||||
flags := cmd.Flags()
|
||||
commonFlag.OptionalBoolFlag(flags, &opts.tlsVerify, "tls-verify", "require HTTPS and verify certificates when accessing the registry")
|
||||
flags.AddFlagSet(auth.GetLogoutFlags(&opts.logoutOpts))
|
||||
commonFlag.OptionalBoolFlag(flags, &opts.tlsVerify, "tls-verify", "require HTTPS and verify certificates when accessing the registry")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -3,59 +3,9 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
This code is currently only intended to be used by ostree
|
||||
to fetch content via containers. The API is subject
|
||||
to change. A goal however is to stabilize the API
|
||||
eventually as a full out-of-process interface to the
|
||||
core containers/image library functionality.
|
||||
|
||||
To use this command, in a parent process create a
|
||||
`socketpair()` of type `SOCK_SEQPACKET`. Fork
|
||||
off this command, and pass one half of the socket
|
||||
pair to the child. Providing it on stdin (fd 0)
|
||||
is the expected default.
|
||||
|
||||
The protocol is JSON for the control layer,
|
||||
and a read side of a `pipe()` passed for large data.
|
||||
|
||||
Base JSON protocol:
|
||||
|
||||
request: { method: "MethodName": args: [arguments] }
|
||||
reply: { success: bool, value: JSVAL, pipeid: number, error: string }
|
||||
|
||||
For any non-metadata i.e. payload data from `GetManifest`
|
||||
and `GetBlob` the server will pass back the read half of a `pipe(2)` via FD passing,
|
||||
along with a `pipeid` integer.
|
||||
|
||||
The expected flow looks like this:
|
||||
|
||||
- Initialize
|
||||
And validate the returned protocol version versus
|
||||
what your client supports.
|
||||
- OpenImage docker://quay.io/someorg/example:latest
|
||||
(returns an imageid)
|
||||
- GetManifest imageid (and associated <pipeid>)
|
||||
(Streaming read data from pipe)
|
||||
- FinishPipe <pipeid>
|
||||
- GetBlob imageid sha256:...
|
||||
(Streaming read data from pipe)
|
||||
- FinishPipe <pipeid>
|
||||
- GetBlob imageid sha256:...
|
||||
(Streaming read data from pipe)
|
||||
- FinishPipe <pipeid>
|
||||
- CloseImage imageid
|
||||
|
||||
You may interleave invocations of these methods, e.g. one
|
||||
can also invoke `OpenImage` multiple times, as well as
|
||||
starting multiple GetBlob requests before calling `FinishPipe`
|
||||
on them. The server will stream data into the pipefd
|
||||
until `FinishPipe` is invoked.
|
||||
|
||||
Note that the pipe will not be closed by the server until
|
||||
the client has invoked `FinishPipe`. This is to ensure
|
||||
that the client checks for errors. For example, `GetBlob`
|
||||
performs digest (e.g. sha256) verification and this must
|
||||
be checked after all data has been written.
|
||||
This command is still experimental. Documentation
|
||||
is available in
|
||||
docs-experimental/skopeo-experimental-image-proxy.1.md
|
||||
*/
|
||||
|
||||
import (
|
||||
@@ -87,14 +37,7 @@ import (
|
||||
// The first version of the protocol has major version 0.2 to signify a
|
||||
// departure from the original code which used HTTP.
|
||||
//
|
||||
// 0.2.1: Initial version
|
||||
// 0.2.2: Added support for fetching image configuration as OCI
|
||||
// 0.2.3: Added GetFullConfig
|
||||
// 0.2.4: Added OpenImageOptional
|
||||
// 0.2.5: Added LayerInfoJSON
|
||||
// 0.2.6: Policy Verification before pulling OCI
|
||||
// 0.2.7: Added GetLayerInfoPiped
|
||||
// 0.2.8: Added GetRawBlob and reply.error_code
|
||||
// When bumping this, please also update the man page.
|
||||
const protocolVersion = "0.2.8"
|
||||
|
||||
// maxMsgSize is the current limit on a packet size.
|
||||
|
||||
@@ -16,9 +16,9 @@ const (
|
||||
// fixturesTestImageManifestDigest is the Docker manifest digest of "image.manifest.json"
|
||||
fixturesTestImageManifestDigest = digest.Digest("sha256:20bf21ed457b390829cdbeec8795a7bea1626991fda603e0d01b4e7f60427e55")
|
||||
// fixturesTestKeyFingerprint is the fingerprint of the private key.
|
||||
fixturesTestKeyFingerprint = "1D8230F6CDB6A06716E414C1DB72F2188BB46CC8"
|
||||
fixturesTestKeyFingerprint = "08CD26E446E2E95249B7A405E932F44B23E8DD43"
|
||||
// fixturesTestKeyFingerprint is the key ID of the private key.
|
||||
fixturesTestKeyShortID = "DB72F2188BB46CC8"
|
||||
fixturesTestKeyShortID = "E932F44B23E8DD43"
|
||||
)
|
||||
|
||||
// Test that results of runSkopeo failed with nothing on stdout, and substring
|
||||
|
||||
@@ -14,16 +14,12 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
commonFlag "github.com/containers/common/pkg/flag"
|
||||
"github.com/containers/common/pkg/retry"
|
||||
"github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/directory"
|
||||
"github.com/containers/image/v5/docker"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/pkg/cli"
|
||||
"github.com/containers/image/v5/pkg/cli/sigstore"
|
||||
"github.com/containers/image/v5/signature/signer"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/opencontainers/go-digest"
|
||||
@@ -34,26 +30,20 @@ import (
|
||||
|
||||
// syncOptions contains information retrieved from the skopeo sync command line.
|
||||
type syncOptions struct {
|
||||
global *globalOptions // Global (not command dependent) skopeo options
|
||||
deprecatedTLSVerify *deprecatedTLSVerifyOption
|
||||
srcImage *imageOptions // Source image options
|
||||
destImage *imageDestOptions // Destination image options
|
||||
retryOpts *retry.Options
|
||||
removeSignatures bool // Do not copy signatures from the source image
|
||||
signByFingerprint string // Sign the image using a GPG key with the specified fingerprint
|
||||
signBySigstoreParamFile string // Sign the image using a sigstore signature per configuration in a param file
|
||||
signBySigstorePrivateKey string // Sign the image using a sigstore private key
|
||||
signPassphraseFile string // Path pointing to a passphrase file when signing
|
||||
format commonFlag.OptionalString // Force conversion of the image to a specified format
|
||||
source string // Source repository name
|
||||
destination string // Destination registry name
|
||||
digestFile string // Write digest to this file
|
||||
scoped bool // When true, namespace copied images at destination using the source repository name
|
||||
all bool // Copy all of the images if an image in the source is a list
|
||||
dryRun bool // Don't actually copy anything, just output what it would have done
|
||||
preserveDigests bool // Preserve digests during sync
|
||||
keepGoing bool // Whether or not to abort the sync if there are any errors during syncing the images
|
||||
appendSuffix string // Suffix to append to destination image tag
|
||||
global *globalOptions // Global (not command dependent) skopeo options
|
||||
deprecatedTLSVerify *deprecatedTLSVerifyOption
|
||||
srcImage *imageOptions // Source image options
|
||||
destImage *imageDestOptions // Destination image options
|
||||
retryOpts *retry.Options
|
||||
copy *sharedCopyOptions
|
||||
source string // Source repository name
|
||||
destination string // Destination registry name
|
||||
digestFile string // Write digest to this file
|
||||
scoped bool // When true, namespace copied images at destination using the source repository name
|
||||
all bool // Copy all of the images if an image in the source is a list
|
||||
dryRun bool // Don't actually copy anything, just output what it would have done
|
||||
keepGoing bool // Whether or not to abort the sync if there are any errors during syncing the images
|
||||
appendSuffix string // Suffix to append to destination image tag
|
||||
}
|
||||
|
||||
// repoDescriptor contains information of a single repository used as a sync source.
|
||||
@@ -89,6 +79,7 @@ func syncCmd(global *globalOptions) *cobra.Command {
|
||||
srcFlags, srcOpts := dockerImageFlags(global, sharedOpts, deprecatedTLSVerifyOpt, "src-", "screds")
|
||||
destFlags, destOpts := dockerImageFlags(global, sharedOpts, deprecatedTLSVerifyOpt, "dest-", "dcreds")
|
||||
retryFlags, retryOpts := retryFlags()
|
||||
copyFlags, copyOpts := sharedCopyFlags()
|
||||
|
||||
opts := syncOptions{
|
||||
global: global,
|
||||
@@ -96,6 +87,7 @@ func syncCmd(global *globalOptions) *cobra.Command {
|
||||
srcImage: srcOpts,
|
||||
destImage: &imageDestOptions{imageOptions: destOpts},
|
||||
retryOpts: retryOpts,
|
||||
copy: copyOpts,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
@@ -113,12 +105,12 @@ See skopeo-sync(1) for details.
|
||||
}
|
||||
adjustUsage(cmd)
|
||||
flags := cmd.Flags()
|
||||
flags.BoolVar(&opts.removeSignatures, "remove-signatures", false, "Do not copy signatures from SOURCE images")
|
||||
flags.StringVar(&opts.signByFingerprint, "sign-by", "", "Sign the image using a GPG key with the specified `FINGERPRINT`")
|
||||
flags.StringVar(&opts.signBySigstoreParamFile, "sign-by-sigstore", "", "Sign the image using a sigstore parameter file at `PATH`")
|
||||
flags.StringVar(&opts.signBySigstorePrivateKey, "sign-by-sigstore-private-key", "", "Sign the image using a sigstore private key at `PATH`")
|
||||
flags.StringVar(&opts.signPassphraseFile, "sign-passphrase-file", "", "File that contains a passphrase for the --sign-by key")
|
||||
flags.VarP(commonFlag.NewOptionalStringValue(&opts.format), "format", "f", `MANIFEST TYPE (oci, v2s1, or v2s2) to use when syncing image(s) to a destination (default is manifest type of source, with fallbacks)`)
|
||||
flags.AddFlagSet(&sharedFlags)
|
||||
flags.AddFlagSet(&deprecatedTLSVerifyFlags)
|
||||
flags.AddFlagSet(&srcFlags)
|
||||
flags.AddFlagSet(&destFlags)
|
||||
flags.AddFlagSet(&retryFlags)
|
||||
flags.AddFlagSet(©Flags)
|
||||
flags.StringVarP(&opts.source, "src", "s", "", "SOURCE transport type")
|
||||
flags.StringVarP(&opts.destination, "dest", "d", "", "DESTINATION transport type")
|
||||
flags.BoolVar(&opts.scoped, "scoped", false, "Images at DESTINATION are prefix using the full source image path as scope")
|
||||
@@ -126,13 +118,7 @@ See skopeo-sync(1) for details.
|
||||
flags.StringVar(&opts.digestFile, "digestfile", "", "Write the digests and Image References of the resulting images to the specified file, separated by newlines")
|
||||
flags.BoolVarP(&opts.all, "all", "a", false, "Copy all images if SOURCE-IMAGE is a list")
|
||||
flags.BoolVar(&opts.dryRun, "dry-run", false, "Run without actually copying data")
|
||||
flags.BoolVar(&opts.preserveDigests, "preserve-digests", false, "Preserve digests of images and lists")
|
||||
flags.BoolVarP(&opts.keepGoing, "keep-going", "", false, "Do not abort the sync if any image copy fails")
|
||||
flags.AddFlagSet(&sharedFlags)
|
||||
flags.AddFlagSet(&deprecatedTLSVerifyFlags)
|
||||
flags.AddFlagSet(&srcFlags)
|
||||
flags.AddFlagSet(&destFlags)
|
||||
flags.AddFlagSet(&retryFlags)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -643,14 +629,6 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
|
||||
return err
|
||||
}
|
||||
|
||||
var manifestType string
|
||||
if opts.format.Present() {
|
||||
manifestType, err = parseManifestFormat(opts.format.Value())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancel := opts.global.commandTimeoutContext()
|
||||
defer cancel()
|
||||
|
||||
@@ -669,57 +647,15 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
|
||||
return err
|
||||
}
|
||||
|
||||
// c/image/copy.Image does allow creating both simple signing and sigstore signatures simultaneously,
|
||||
// with independent passphrases, but that would make the CLI probably too confusing.
|
||||
// For now, use the passphrase with either, but only one of them.
|
||||
if opts.signPassphraseFile != "" && opts.signByFingerprint != "" && opts.signBySigstorePrivateKey != "" {
|
||||
return fmt.Errorf("Only one of --sign-by and sign-by-sigstore-private-key can be used with sign-passphrase-file")
|
||||
}
|
||||
var passphrase string
|
||||
if opts.signPassphraseFile != "" {
|
||||
p, err := cli.ReadPassphraseFile(opts.signPassphraseFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
passphrase = p
|
||||
} else if opts.signBySigstorePrivateKey != "" {
|
||||
p, err := promptForPassphrase(opts.signBySigstorePrivateKey, os.Stdin, os.Stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
passphrase = p
|
||||
options, cleanupOptions, err := opts.copy.copyOptions(stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cleanupOptions()
|
||||
options.DestinationCtx = destinationCtx
|
||||
options.ImageListSelection = imageListSelection
|
||||
options.OptimizeDestinationImageAlreadyExists = true
|
||||
|
||||
var signers []*signer.Signer
|
||||
if opts.signBySigstoreParamFile != "" {
|
||||
signer, err := sigstore.NewSignerFromParameterFile(opts.signBySigstoreParamFile, &sigstore.Options{
|
||||
PrivateKeyPassphrasePrompt: func(keyFile string) (string, error) {
|
||||
return promptForPassphrase(keyFile, os.Stdin, os.Stdout)
|
||||
},
|
||||
Stdin: os.Stdin,
|
||||
Stdout: stdout,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error using --sign-by-sigstore: %w", err)
|
||||
}
|
||||
defer signer.Close()
|
||||
signers = append(signers, signer)
|
||||
}
|
||||
|
||||
options := copy.Options{
|
||||
RemoveSignatures: opts.removeSignatures,
|
||||
Signers: signers,
|
||||
SignBy: opts.signByFingerprint,
|
||||
SignPassphrase: passphrase,
|
||||
SignBySigstorePrivateKeyFile: opts.signBySigstorePrivateKey,
|
||||
SignSigstorePrivateKeyPassphrase: []byte(passphrase),
|
||||
ReportWriter: stdout,
|
||||
DestinationCtx: destinationCtx,
|
||||
ImageListSelection: imageListSelection,
|
||||
PreserveDigests: opts.preserveDigests,
|
||||
OptimizeDestinationImageAlreadyExists: true,
|
||||
ForceManifestMIMEType: manifestType,
|
||||
}
|
||||
errorsPresent := false
|
||||
imagesNumber := 0
|
||||
if opts.dryRun {
|
||||
@@ -775,7 +711,7 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
|
||||
} else {
|
||||
logrus.WithFields(fromToFields).Infof("Copying image ref %d/%d", counter+1, len(srcRepo.ImageRefs))
|
||||
if err = retry.IfNecessary(ctx, func() error {
|
||||
manifestBytes, err = copy.Image(ctx, policyContext, destRef, ref, &options)
|
||||
manifestBytes, err = copy.Image(ctx, policyContext, destRef, ref, options)
|
||||
return err
|
||||
}, opts.retryOpts); err != nil {
|
||||
if !opts.keepGoing {
|
||||
|
||||
@@ -16,6 +16,7 @@ var neededCapabilities = []capability.Cap{
|
||||
capability.CAP_FSETID,
|
||||
capability.CAP_MKNOD,
|
||||
capability.CAP_SETFCAP,
|
||||
capability.CAP_SYS_ADMIN,
|
||||
}
|
||||
|
||||
func maybeReexec() error {
|
||||
|
||||
@@ -11,10 +11,15 @@ import (
|
||||
|
||||
commonFlag "github.com/containers/common/pkg/flag"
|
||||
"github.com/containers/common/pkg/retry"
|
||||
"github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/directory"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
ociarchive "github.com/containers/image/v5/oci/archive"
|
||||
ocilayout "github.com/containers/image/v5/oci/layout"
|
||||
"github.com/containers/image/v5/pkg/cli"
|
||||
"github.com/containers/image/v5/pkg/cli/sigstore"
|
||||
"github.com/containers/image/v5/pkg/compression"
|
||||
"github.com/containers/image/v5/signature/signer"
|
||||
"github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
@@ -109,7 +114,7 @@ type sharedImageOptions struct {
|
||||
func sharedImageFlags() (pflag.FlagSet, *sharedImageOptions) {
|
||||
opts := sharedImageOptions{}
|
||||
fs := pflag.FlagSet{}
|
||||
fs.StringVar(&opts.authFilePath, "authfile", os.Getenv("REGISTRY_AUTH_FILE"), "path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json")
|
||||
fs.StringVar(&opts.authFilePath, "authfile", os.Getenv("REGISTRY_AUTH_FILE"), "path of the registry credentials file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json")
|
||||
return fs, &opts
|
||||
}
|
||||
|
||||
@@ -152,7 +157,7 @@ func dockerImageFlags(global *globalOptions, shared *sharedImageOptions, depreca
|
||||
fs := pflag.FlagSet{}
|
||||
if flagPrefix != "" {
|
||||
// the non-prefixed flag is handled by a shared flag.
|
||||
fs.Var(commonFlag.NewOptionalStringValue(&flags.authFilePath), flagPrefix+"authfile", "path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json")
|
||||
fs.Var(commonFlag.NewOptionalStringValue(&flags.authFilePath), flagPrefix+"authfile", "path of the registry credentials file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json")
|
||||
}
|
||||
fs.Var(commonFlag.NewOptionalStringValue(&flags.credsOption), flagPrefix+"creds", "Use `USERNAME[:PASSWORD]` for accessing the registry")
|
||||
fs.Var(commonFlag.NewOptionalStringValue(&flags.userName), flagPrefix+"username", "Username for accessing the registry")
|
||||
@@ -175,9 +180,9 @@ func imageFlags(global *globalOptions, shared *sharedImageOptions, deprecatedTLS
|
||||
dockerFlags, opts := dockerImageFlags(global, shared, deprecatedTLSVerify, flagPrefix, credsOptionAlias)
|
||||
|
||||
fs := pflag.FlagSet{}
|
||||
fs.AddFlagSet(&dockerFlags)
|
||||
fs.StringVar(&opts.sharedBlobDir, flagPrefix+"shared-blob-dir", "", "`DIRECTORY` to use to share blobs across OCI repositories")
|
||||
fs.StringVar(&opts.dockerDaemonHost, flagPrefix+"daemon-host", "", "use docker daemon host at `HOST` (docker-daemon: only)")
|
||||
fs.AddFlagSet(&dockerFlags)
|
||||
return fs, opts
|
||||
}
|
||||
|
||||
@@ -318,6 +323,110 @@ func (opts *imageDestOptions) warnAboutIneffectiveOptions(destTransport types.Im
|
||||
}
|
||||
}
|
||||
|
||||
// sharedCopyOptions collects CLI flags that affect copying images, currently shared between the copy and sync commands.
|
||||
type sharedCopyOptions struct {
|
||||
removeSignatures bool // Do not copy signatures from the source image
|
||||
signByFingerprint string // Sign the image using a GPG key with the specified fingerprint
|
||||
signBySigstoreParamFile string // Sign the image using a sigstore signature per configuration in a param file
|
||||
signBySigstorePrivateKey string // Sign the image using a sigstore private key
|
||||
signPassphraseFile string // Path pointing to a passphrase file when signing
|
||||
preserveDigests bool // Preserve digests during copy
|
||||
format commonFlag.OptionalString // Force conversion of the image to a specified format
|
||||
}
|
||||
|
||||
// sharedCopyFlags prepares a collection of CLI flags writing into sharedCopyoptions.
|
||||
func sharedCopyFlags() (pflag.FlagSet, *sharedCopyOptions) {
|
||||
opts := sharedCopyOptions{}
|
||||
fs := pflag.FlagSet{}
|
||||
fs.BoolVar(&opts.removeSignatures, "remove-signatures", false, "Do not copy signatures from source")
|
||||
fs.StringVar(&opts.signByFingerprint, "sign-by", "", "Sign the image using a GPG key with the specified `FINGERPRINT`")
|
||||
fs.StringVar(&opts.signBySigstoreParamFile, "sign-by-sigstore", "", "Sign the image using a sigstore parameter file at `PATH`")
|
||||
fs.StringVar(&opts.signBySigstorePrivateKey, "sign-by-sigstore-private-key", "", "Sign the image using a sigstore private key at `PATH`")
|
||||
fs.StringVar(&opts.signPassphraseFile, "sign-passphrase-file", "", "Read a passphrase for signing an image from `PATH`")
|
||||
fs.VarP(commonFlag.NewOptionalStringValue(&opts.format), "format", "f", `MANIFEST TYPE (oci, v2s1, or v2s2) to use in the destination (default is manifest type of source, with fallbacks)`)
|
||||
fs.BoolVar(&opts.preserveDigests, "preserve-digests", false, "Preserve digests of images and lists")
|
||||
return fs, &opts
|
||||
}
|
||||
|
||||
// copyOptions interprets opts, returns a partially-filled *copy.Options,
|
||||
// and a function that should be called to clean up.
|
||||
func (opts *sharedCopyOptions) copyOptions(stdout io.Writer) (*copy.Options, func(), error) {
|
||||
var manifestType string
|
||||
if opts.format.Present() {
|
||||
mt, err := parseManifestFormat(opts.format.Value())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
manifestType = mt
|
||||
}
|
||||
|
||||
// c/image/copy.Image does allow creating both simple signing and sigstore signatures simultaneously,
|
||||
// with independent passphrases, but that would make the CLI probably too confusing.
|
||||
// For now, use the passphrase with either, but only one of them.
|
||||
if opts.signPassphraseFile != "" && opts.signByFingerprint != "" && opts.signBySigstorePrivateKey != "" {
|
||||
return nil, nil, fmt.Errorf("Only one of --sign-by and sign-by-sigstore-private-key can be used with sign-passphrase-file")
|
||||
}
|
||||
var passphrase string
|
||||
if opts.signPassphraseFile != "" {
|
||||
p, err := cli.ReadPassphraseFile(opts.signPassphraseFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
passphrase = p
|
||||
} else if opts.signBySigstorePrivateKey != "" {
|
||||
p, err := promptForPassphrase(opts.signBySigstorePrivateKey, os.Stdin, os.Stdout)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
passphrase = p
|
||||
} // opts.signByFingerprint triggers a GPG-agent passphrase prompt, possibly using a more secure channel, so we usually shouldn’t prompt ourselves if no passphrase was explicitly provided.
|
||||
var passphraseBytes []byte
|
||||
if passphrase != "" {
|
||||
passphraseBytes = []byte(passphrase)
|
||||
}
|
||||
|
||||
var signers []*signer.Signer
|
||||
closeSigners := func() {
|
||||
for _, signer := range signers {
|
||||
signer.Close()
|
||||
}
|
||||
}
|
||||
succeeded := false
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
closeSigners()
|
||||
}
|
||||
}()
|
||||
if opts.signBySigstoreParamFile != "" {
|
||||
signer, err := sigstore.NewSignerFromParameterFile(opts.signBySigstoreParamFile, &sigstore.Options{
|
||||
PrivateKeyPassphrasePrompt: func(keyFile string) (string, error) {
|
||||
return promptForPassphrase(keyFile, os.Stdin, os.Stdout)
|
||||
},
|
||||
Stdin: os.Stdin,
|
||||
Stdout: stdout,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Error using --sign-by-sigstore: %w", err)
|
||||
}
|
||||
signers = append(signers, signer)
|
||||
}
|
||||
|
||||
succeeded = true
|
||||
return ©.Options{
|
||||
RemoveSignatures: opts.removeSignatures,
|
||||
Signers: signers,
|
||||
SignBy: opts.signByFingerprint,
|
||||
SignPassphrase: passphrase,
|
||||
SignBySigstorePrivateKeyFile: opts.signBySigstorePrivateKey,
|
||||
SignSigstorePrivateKeyPassphrase: passphraseBytes,
|
||||
|
||||
ReportWriter: stdout,
|
||||
|
||||
PreserveDigests: opts.preserveDigests,
|
||||
ForceManifestMIMEType: manifestType,
|
||||
}, closeSigners, nil
|
||||
}
|
||||
|
||||
func parseCreds(creds string) (string, string, error) {
|
||||
if creds == "" {
|
||||
return "", "", errors.New("credentials can't be empty")
|
||||
@@ -419,9 +528,12 @@ func promptForPassphrase(privateKeyFile string, stdin, stdout *os.File) (string,
|
||||
// authentication error, an I/O error etc.)
|
||||
// TODO drive this into containers/image properly
|
||||
func isNotFoundImageError(err error) bool {
|
||||
var layoutImageNotFoundError ocilayout.ImageNotFoundError
|
||||
var archiveImageNotFoundError ociarchive.ImageNotFoundError
|
||||
return isDockerManifestUnknownError(err) ||
|
||||
errors.Is(err, storage.ErrNoSuchImage) ||
|
||||
errors.Is(err, ocilayout.ImageNotFoundError{})
|
||||
errors.As(err, &layoutImageNotFoundError) ||
|
||||
errors.As(err, &archiveImageNotFoundError)
|
||||
}
|
||||
|
||||
// isDockerManifestUnknownError is a copy of code from containers/image,
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/types"
|
||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
@@ -350,6 +353,92 @@ func TestTLSVerifyFlags(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// fakeSharedCopyOptions creates sharedCopyOptions and sets it according to cmdFlags.
|
||||
func fakeSharedCopyOptions(t *testing.T, cmdFlags []string) *sharedCopyOptions {
|
||||
_, cmd := fakeGlobalOptions(t, []string{})
|
||||
sharedCopyFlags, sharedCopyOpts := sharedCopyFlags()
|
||||
cmd.Flags().AddFlagSet(&sharedCopyFlags)
|
||||
err := cmd.ParseFlags(cmdFlags)
|
||||
require.NoError(t, err)
|
||||
return sharedCopyOpts
|
||||
}
|
||||
|
||||
func TestSharedCopyOptionsCopyOptions(t *testing.T) {
|
||||
someStdout := bytes.Buffer{}
|
||||
|
||||
// Default state
|
||||
opts := fakeSharedCopyOptions(t, []string{})
|
||||
res, cleanup, err := opts.copyOptions(&someStdout)
|
||||
require.NoError(t, err)
|
||||
defer cleanup()
|
||||
assert.Equal(t, ©.Options{
|
||||
ReportWriter: &someStdout,
|
||||
}, res)
|
||||
|
||||
// Set most flags to non-default values
|
||||
// This should also test --sign-by-sigstore and --sign-by-sigstore-private-key; we would have
|
||||
// to create test keys for that.
|
||||
opts = fakeSharedCopyOptions(t, []string{
|
||||
"--remove-signatures",
|
||||
"--sign-by", "gpgFingerprint",
|
||||
"--format", "oci",
|
||||
"--preserve-digests",
|
||||
})
|
||||
res, cleanup, err = opts.copyOptions(&someStdout)
|
||||
require.NoError(t, err)
|
||||
defer cleanup()
|
||||
assert.Equal(t, ©.Options{
|
||||
RemoveSignatures: true,
|
||||
SignBy: "gpgFingerprint",
|
||||
ReportWriter: &someStdout,
|
||||
PreserveDigests: true,
|
||||
ForceManifestMIMEType: imgspecv1.MediaTypeImageManifest,
|
||||
}, res)
|
||||
|
||||
// --sign-passphrase-file + --sign-by work
|
||||
passphraseFile, err := os.CreateTemp("", "passphrase") // Eventually we could refer to a passphrase fixture instead
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(passphraseFile.Name())
|
||||
_, err = passphraseFile.WriteString("test-passphrase")
|
||||
require.NoError(t, err)
|
||||
opts = fakeSharedCopyOptions(t, []string{
|
||||
"--sign-by", "gpgFingerprint",
|
||||
"--sign-passphrase-file", passphraseFile.Name(),
|
||||
})
|
||||
res, cleanup, err = opts.copyOptions(&someStdout)
|
||||
require.NoError(t, err)
|
||||
defer cleanup()
|
||||
assert.Equal(t, ©.Options{
|
||||
SignBy: "gpgFingerprint",
|
||||
SignPassphrase: "test-passphrase",
|
||||
SignSigstorePrivateKeyPassphrase: []byte("test-passphrase"),
|
||||
ReportWriter: &someStdout,
|
||||
}, res)
|
||||
// --sign-passphrase-file + --sign-by-sigstore-private-key should be tested here.
|
||||
|
||||
// Invalid --format
|
||||
opts = fakeSharedCopyOptions(t, []string{"--format", "invalid"})
|
||||
_, _, err = opts.copyOptions(&someStdout)
|
||||
assert.Error(t, err)
|
||||
|
||||
// More --sign-passphrase-file, --sign-by-sigstore-private-key, --sign-by-sigstore failure cases should be tested here.
|
||||
|
||||
// --sign-passphrase-file not found
|
||||
opts = fakeSharedCopyOptions(t, []string{
|
||||
"--sign-by", "gpgFingerprint",
|
||||
"--sign-passphrase-file", "/dev/null/this/does/not/exist",
|
||||
})
|
||||
_, _, err = opts.copyOptions(&someStdout)
|
||||
assert.Error(t, err)
|
||||
|
||||
// --sign-by-sigstore file not found
|
||||
opts = fakeSharedCopyOptions(t, []string{
|
||||
"--sign-by-sigstore", "/dev/null/this/does/not/exist",
|
||||
})
|
||||
_, _, err = opts.copyOptions(&someStdout)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestParseManifestFormat(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
formatParam string
|
||||
|
||||
@@ -64,7 +64,7 @@ _run_setup() {
|
||||
# things directly on the host VM. Fortunately they're all
|
||||
# located in the container under /usr/local/bin
|
||||
msg "Accessing contents of $SKOPEO_CIDEV_CONTAINER_FQIN"
|
||||
podman pull --quiet $SKOPEO_CIDEV_CONTAINER_FQIN
|
||||
podman pull --retry 3 --quiet $SKOPEO_CIDEV_CONTAINER_FQIN
|
||||
mnt=$(podman mount $(podman create $SKOPEO_CIDEV_CONTAINER_FQIN))
|
||||
|
||||
# The container and VM images are built in tandem in the same repo.
|
||||
|
||||
162
docs-experimental/skopeo-experimental-image-proxy.1.md
Normal file
162
docs-experimental/skopeo-experimental-image-proxy.1.md
Normal file
@@ -0,0 +1,162 @@
|
||||
% skopeo-experimental-image-proxy(1)
|
||||
|
||||
# NAME
|
||||
skopeo-experimental-image-proxy - API server for fetching container images (EXPERIMENTAL)
|
||||
|
||||
# SYNOPSIS
|
||||
**skopeo experimental-image-proxy** [*options*]
|
||||
|
||||
# DESCRIPTION
|
||||
**EXPERIMENTAL COMMAND**: This command is experimental, and its API is subject to change. It is currently hidden from the main help output and not supported on Windows.
|
||||
|
||||
`skopeo experimental-image-proxy` exposes core container image fetching APIs via custom JSON+fd-passing protocol. This provides a lightweight way to fetch container image content (manifests and blobs). This command is primarily intended for programs that want to operate on a storage type that skopeo doesn't natively handle. For example, the bootc project currently has a custom ostree-based container storage backend.
|
||||
|
||||
The client process that invokes `skopeo experimental-image-proxy` is responsible for creating a socket pair and passing one of the file descriptors to the proxy. By default, the proxy expects this file descriptor to be its standard input (fd 0), but a different fd can be specified using the **--sockfd** option.
|
||||
|
||||
**Protocol Overview**
|
||||
|
||||
The protocol requires a `socketpair(2)` of type `SOCK_SEQPACKET`, over which a single JSON message is sent per packet. Large data payloads, such as image manifests and blobs, are transferred over separate pipes (`pipe(2)`), with the read-ends of these pipes passed to the client via file descriptor (FD) passing.
|
||||
|
||||
* **Request Format**: A JSON object: `{ "method": "MethodName", "args": [arguments] }`
|
||||
* **Reply Format**: A JSON object: `{ "success": boolean, "value": JSONValue, "pipeid": number, "error_code": string, "error": string }`
|
||||
* `success`: `true` if the call succeeded, `false` otherwise.
|
||||
* `value`: The return value of the method, if any.
|
||||
* `pipeid`: An integer identifying a pipe for data transfer. This ID is used with the `FinishPipe` method.
|
||||
* `error_code`: A string indicating the type of error if `success` is `false` (e.g., "EPIPE", "retryable", "other"). (Introduced in protocol version 0.2.8)
|
||||
* `error`: A string describing the error if `success` is `false`.
|
||||
|
||||
The current protocol version is `0.2.8`.
|
||||
|
||||
**Supported Protocol Methods**
|
||||
|
||||
The server supports the following methods:
|
||||
|
||||
* **Initialize**: Initializes the proxy. This method must be called before any other method.
|
||||
* Args: `[]` (empty array)
|
||||
* Returns: `string` (the protocol version, e.g., "0.2.8")
|
||||
* **OpenImage**: Opens an image reference (e.g., `docker://quay.io/example/image:latest`).
|
||||
* Args: `[string imageName]`
|
||||
* Returns: `uint64` (an opaque image ID to be used in subsequent calls)
|
||||
* **OpenImageOptional**: Similar to `OpenImage`, but if the image is not found, it returns `0` (a sentinel image ID) instead of an error.
|
||||
* Args: `[string imageName]`
|
||||
* Returns: `uint64` (opaque image ID, or `0` if the image is not found)
|
||||
* **CloseImage**: Closes a previously opened image, releasing associated resources.
|
||||
* Args: `[uint64 imageID]`
|
||||
* Returns: `null`
|
||||
* **GetManifest**: Retrieves the image manifest. If the image is a manifest list, it is resolved to an image matching the proxy's current OS and architecture. The manifest is converted to OCI format if it isn't already. The `value` field in the reply contains the original digest of the manifest (if the image is a manifest list, this is the digest of the list, not the per-platform instance). The manifest content is streamed over a pipe.
|
||||
* Args: `[uint64 imageID]`
|
||||
* Returns: `string` (manifest digest in `value`), manifest data via pipe.
|
||||
* **GetFullConfig**: Retrieves the full image configuration, conforming to the OCI Image Format Specification. Configuration data is streamed over a pipe.
|
||||
* Args: `[uint64 imageID]`
|
||||
* Returns: `null`, configuration data via pipe.
|
||||
* **GetBlob**: Fetches an image blob (e.g., a layer) by its digest and expected size. The proxy performs digest verification on the blob data. The `value` field in the reply contains the blob size. Blob data is streamed over a pipe.
|
||||
* Args: `[uint64 imageID, string digest, uint64 size]`
|
||||
* Returns: `int64` (blob size in `value`, `-1` if unknown), blob data via pipe.
|
||||
* **GetRawBlob**: Fetches an image blob by its digest. Unlike `GetBlob`, this method does not perform server-side digest verification. It returns two file descriptors to the client: one for the blob data and another for reporting errors that occur during the streaming. This method does not use the `FinishPipe` mechanism. The `value` field in the reply contains the blob size. (Introduced in protocol version 0.2.8)
|
||||
* Args: `[uint64 imageID, string digest]`
|
||||
* Returns: `int64` (blob size in `value`, `-1` if unknown), and *two* file descriptors: one for the blob data, one for errors. The error is a `ProxyError` type, see below.
|
||||
* **GetLayerInfoPiped**: Retrieves information about image layers. This replaces `GetLayerInfo`. Layer information data is streamed over a pipe, which makes it more reliable for images with many layers that would exceed message size limits with `GetLayerInfo`. The returned data is a JSON array of `{digest: string, size: int64, media_type: string}`. (Introduced in protocol version 0.2.7)
|
||||
* Args: `[uint64 imageID]`
|
||||
* Returns: `null`, layer information data via pipe.
|
||||
* **FinishPipe**: Signals that the client has finished reading all data from a pipe associated with a `pipeid` (obtained from methods like `GetManifest` or `GetBlob`). This allows the server to close its end of the pipe and report any pending errors (e.g., digest verification failure for `GetBlob`). This method **must** be called by the client after consuming data from a pipe, except for pipes from `GetRawBlob`.
|
||||
* Args: `[uint32 pipeID]`
|
||||
* Returns: `null`
|
||||
* **Shutdown**: Instructs the proxy server to terminate gracefully.
|
||||
* Args: `[]` (empty array)
|
||||
* Returns: `null`
|
||||
|
||||
The following methods are deprecated:
|
||||
|
||||
* **GetConfig**: (deprecated) Retrieves the container runtime configuration part of the image (the OCI `config` field). **Note**: This method returns only a part of the full image configuration due to a historical oversight. Use `GetFullConfig` for the complete image configuration. Configuration data is streamed over a pipe.
|
||||
* Args: `[uint64 imageID]`
|
||||
* Returns: `null`, configuration data via pipe.
|
||||
* **GetLayerInfo**: (deprecated) Retrieves an array of objects, each describing an image layer (digest, size, mediaType). **Note**: This method returns data inline and may fail for images with many layers due to message size limits. Use `GetLayerInfoPiped` for a more robust solution.
|
||||
* Args: `[uint64 imageID]`
|
||||
* Returns: `array` of `{digest: string, size: int64, media_type: string}`.
|
||||
|
||||
**Data Transfer for Pipes**
|
||||
|
||||
When a method returns a `pipeid`, the server also passes the read-end of a pipe via file descriptor (FD) passing. The client reads the data (e.g., manifest content, blob content) from this FD. After successfully reading all data, the client **must** call `FinishPipe` with the corresponding `pipeid`. This signals to the server that the transfer is complete, allows the server to clean up resources, and enables the client to check for any errors that might have occurred during the data streaming process (e.g., a digest mismatch during `GetBlob`). The `GetRawBlob` method is an exception; it uses a dedicated error pipe instead of the `FinishPipe` mechanism.
|
||||
|
||||
**ProxyError**
|
||||
|
||||
`GetBlobRaw` returns a JSON object of the following form in the error pipe where:
|
||||
```
|
||||
{
|
||||
"code": "EPIPE" | "retryable" | "other",
|
||||
"message": "error message"
|
||||
}
|
||||
```
|
||||
|
||||
- EPIPE: The client closed the pipe before reading all data.
|
||||
- retryable: The operation failed but might succeed if retried.
|
||||
- other: A generic error occurred.
|
||||
|
||||
# OPTIONS
|
||||
**--sockfd**=*fd*
|
||||
Serve on the opened socket passed as file descriptor *fd*. Defaults to 0 (standard input).
|
||||
|
||||
The command also supports common skopeo options for interacting with image registries and local storage. These include:
|
||||
|
||||
**--authfile**=*path*
|
||||
|
||||
Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
|
||||
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.
|
||||
|
||||
Use `skopeo login` to manage the credentials.
|
||||
|
||||
The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.
|
||||
|
||||
**--cert-dir**=*path*
|
||||
|
||||
Use certificates at *path* (\*.crt, \*.cert, \*.key) to connect to the registry.
|
||||
|
||||
**--creds** _username[:password]_
|
||||
|
||||
Username and password for accessing the registry.
|
||||
|
||||
**--daemon-host** _host_
|
||||
|
||||
Use docker daemon host at _host_ (`docker-daemon:` transport only)
|
||||
|
||||
**--no-creds**
|
||||
|
||||
Access the registry anonymously.
|
||||
|
||||
**--password**=*password*
|
||||
|
||||
Password for accessing the registry. Use with **--username**.
|
||||
|
||||
**--registry-token**=*token*
|
||||
|
||||
Provide a Bearer *token* for accessing the registry.
|
||||
|
||||
**--shared-blob-dir** _directory_
|
||||
|
||||
Directory to use to share blobs across OCI repositories.
|
||||
|
||||
**--tls-verify**=_bool_
|
||||
|
||||
Require HTTPS and verify certificates when talking to the container registry or daemon. Default to registry.conf setting.
|
||||
|
||||
**--username**=*username*
|
||||
Username for accessing the registry. Use with **--password**.
|
||||
|
||||
# REFERENCE CLIENT LIBRARIES
|
||||
|
||||
- Rust: The [containers-image-proxy-rs project](https://github.com/containers/containers-image-proxy-rs) serves
|
||||
as the reference Rust client.
|
||||
|
||||
# PROTOCOL HISTORY
|
||||
|
||||
- 0.2.1: Initial version
|
||||
- 0.2.2: Added support for fetching image configuration as OCI
|
||||
- 0.2.3: Added GetFullConfig
|
||||
- 0.2.4: Added OpenImageOptional
|
||||
- 0.2.5: Added LayerInfoJSON
|
||||
- 0.2.6: Policy Verification before pulling OCI
|
||||
- 0.2.7: Added GetLayerInfoPiped
|
||||
- 0.2.8: Added GetRawBlob and error_code to replies
|
||||
|
||||
## SEE ALSO
|
||||
skopeo(1), containers-auth.json(5)
|
||||
@@ -34,19 +34,20 @@ the images in the list, and the list itself.
|
||||
|
||||
**--authfile** _path_
|
||||
|
||||
Path of the authentication file. Default is ${XDG_RUNTIME\_DIR}/containers/auth.json, which is set using `skopeo login`.
|
||||
If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`.
|
||||
Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
|
||||
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.
|
||||
|
||||
Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE
|
||||
environment variable. `export REGISTRY_AUTH_FILE=path`
|
||||
Use `skopeo login` to manage the credentials.
|
||||
|
||||
The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.
|
||||
|
||||
**--src-authfile** _path_
|
||||
|
||||
Path of the authentication file for the source registry. Uses path given by `--authfile`, if not provided.
|
||||
Path of the primary registry credentials file for the source registry. Uses path given by `--authfile`, if not provided.
|
||||
|
||||
**--dest-authfile** _path_
|
||||
|
||||
Path of the authentication file for the destination registry. Uses path given by `--authfile`, if not provided.
|
||||
Path of the primary registry credentials file for the destination registry. Uses path given by `--authfile`, if not provided.
|
||||
|
||||
**--dest-shared-blob-dir** _directory_
|
||||
|
||||
|
||||
@@ -35,8 +35,12 @@ See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.
|
||||
|
||||
**--authfile** _path_
|
||||
|
||||
Path of the authentication file. Default is ${XDG_RUNTIME\_DIR}/containers/auth.json, which is set using `skopeo login`.
|
||||
If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`.
|
||||
Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
|
||||
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.
|
||||
|
||||
Use `skopeo login` to manage the credentials.
|
||||
|
||||
The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.
|
||||
|
||||
**--creds** _username[:password]_
|
||||
|
||||
|
||||
@@ -21,8 +21,12 @@ See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.
|
||||
|
||||
**--authfile** _path_
|
||||
|
||||
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `skopeo login`.
|
||||
If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`.
|
||||
Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
|
||||
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.
|
||||
|
||||
Use `skopeo login` to manage the credentials.
|
||||
|
||||
The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.
|
||||
|
||||
**--cert-dir** _path_
|
||||
|
||||
|
||||
@@ -16,8 +16,12 @@ See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.
|
||||
|
||||
**--authfile** _path_
|
||||
|
||||
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `skopeo login`.
|
||||
If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`.
|
||||
Path of the updated registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
|
||||
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.
|
||||
|
||||
Use `skopeo login` to manage the credentials.
|
||||
|
||||
The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.
|
||||
|
||||
**--creds** _username[:password]_ for accessing the registry.
|
||||
|
||||
@@ -64,7 +68,7 @@ Repository names are transport-specific references as each transport may have it
|
||||
This commands refers to repositories using a _transport_`:`_details_ format. The following formats are supported:
|
||||
|
||||
**docker://**_docker-repository-reference_
|
||||
A repository in a registry implementing the "Docker Registry HTTP API V2". By default, uses the authorization state in either `$XDG_RUNTIME_DIR/containers/auth.json`, which is set using `(skopeo login)`. If the authorization state is not found there, `$HOME/.docker/config.json` is checked, which is set using `(docker login)`.
|
||||
A repository in a registry implementing the "Docker Registry HTTP API V2".
|
||||
A _docker-repository-reference_ is of the form: **registryhost:port/repositoryname** which is similar to an _image-reference_ but with no tag or digest allowed as the last component (e.g no `:latest` or `@sha256:xyz`)
|
||||
|
||||
Examples of valid docker-repository-references:
|
||||
|
||||
@@ -10,8 +10,8 @@ skopeo\-login - Login to a container registry.
|
||||
**skopeo login** logs into a specified registry server with the correct username
|
||||
and password. **skopeo login** reads in the username and password from STDIN.
|
||||
The username and password can also be set using the **username** and **password** flags.
|
||||
The path of the authentication file can be specified by the user by setting the **authfile**
|
||||
flag. The default path used is **${XDG\_RUNTIME\_DIR}/containers/auth.json**.
|
||||
The path of the credentials file can be specified by the user by setting the **authfile**
|
||||
flag.
|
||||
|
||||
## OPTIONS
|
||||
|
||||
@@ -31,10 +31,10 @@ Username for registry
|
||||
|
||||
**--authfile**=*path*
|
||||
|
||||
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json
|
||||
Path of the managed registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
|
||||
See **containers-auth.json**(5) for more details about the default on other platforms.
|
||||
|
||||
Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE
|
||||
environment variable. `export REGISTRY_AUTH_FILE=path`
|
||||
The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.
|
||||
|
||||
**--compat-auth-file**=*path*
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ skopeo\-logout - Logout of a container registry.
|
||||
|
||||
## DESCRIPTION
|
||||
**skopeo logout** logs out of a specified registry server by deleting the cached credentials
|
||||
stored in the **auth.json** file. The path of the authentication file can be overridden by the user by setting the **authfile** flag.
|
||||
The default path used is **${XDG\_RUNTIME\_DIR}/containers/auth.json**.
|
||||
stored in the **auth.json** file. The path of the credentials file can be overridden by the user by setting the **authfile** flag.
|
||||
All the cached credentials can be removed by setting the **all** flag.
|
||||
|
||||
## OPTIONS
|
||||
@@ -18,10 +17,10 @@ See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.
|
||||
|
||||
**--authfile**=*path*
|
||||
|
||||
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json
|
||||
Path of the managed registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
|
||||
See **containers-auth.json**(5) for more details about the default on other platforms.
|
||||
|
||||
Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE
|
||||
environment variable. `export REGISTRY_AUTH_FILE=path`
|
||||
The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.
|
||||
|
||||
**--compat-auth-file**=*path*
|
||||
|
||||
|
||||
@@ -39,16 +39,20 @@ the images in the list, and the list itself.
|
||||
|
||||
**--authfile** _path_
|
||||
|
||||
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `skopeo login`.
|
||||
If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`.
|
||||
Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
|
||||
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.
|
||||
|
||||
Use `skopeo login` to manage the credentials.
|
||||
|
||||
The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.
|
||||
|
||||
**--src-authfile** _path_
|
||||
|
||||
Path of the authentication file for the source registry. Uses path given by `--authfile`, if not provided.
|
||||
Path of the primary registry credentials file for the source registry. Uses path given by `--authfile`, if not provided.
|
||||
|
||||
**--dest-authfile** _path_
|
||||
|
||||
Path of the authentication file for the destination registry. Uses path given by `--authfile`, if not provided.
|
||||
Path of the primary registry credentials file for the destination registry. Uses path given by `--authfile`, if not provided.
|
||||
|
||||
**--dry-run**
|
||||
|
||||
|
||||
@@ -33,7 +33,9 @@ Most commands refer to container images, using a _transport_`:`_details_ format.
|
||||
An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
|
||||
|
||||
**docker://**_docker-reference_
|
||||
An image in a registry implementing the "Docker Registry HTTP API V2". By default, uses the authorization state in either `$XDG_RUNTIME_DIR/containers/auth.json`, which is set using `(skopeo login)`. If the authorization state is not found there, `$HOME/.docker/config.json` is checked, which is set using `(docker login)`.
|
||||
An image in a registry implementing the "Docker Registry HTTP API V2".
|
||||
Credentials are typically managed using `(skopeo login)`;
|
||||
see **containers-auth.json**(5) for more details about the credential search mechanism.
|
||||
|
||||
**docker-archive:**_path_[**:**_docker-reference_]
|
||||
An image is stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a file, and it must not contain a digest.
|
||||
|
||||
81
go.mod
81
go.mod
@@ -6,62 +6,51 @@ go 1.23.3
|
||||
// Warning: Ensure the "go" and "toolchain" versions match exactly to prevent unwanted auto-updates
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.3.1
|
||||
github.com/containers/common v0.63.0
|
||||
github.com/containers/image/v5 v5.35.0
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
github.com/containers/common v0.64.0
|
||||
github.com/containers/image/v5 v5.36.0
|
||||
github.com/containers/ocicrypt v1.2.1
|
||||
github.com/containers/storage v1.58.0
|
||||
github.com/containers/storage v1.59.0
|
||||
github.com/docker/distribution v2.8.3+incompatible
|
||||
github.com/moby/sys/capability v0.4.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.1
|
||||
github.com/opencontainers/image-spec v1.1.2-0.20250724175814-2daaaaf0e7c1
|
||||
github.com/opencontainers/image-tools v1.0.0-rc3
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/spf13/pflag v1.0.7
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/term v0.32.0
|
||||
golang.org/x/term v0.33.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.12.9 // indirect
|
||||
github.com/Microsoft/hcsshim v0.13.0 // indirect
|
||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.5 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.13.0 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.14.1 // indirect
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/docker v28.0.4+incompatible // indirect
|
||||
github.com/docker/docker v28.3.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
github.com/go-openapi/errors v0.22.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/loads v0.22.0 // indirect
|
||||
github.com/go-openapi/runtime v0.28.0 // indirect
|
||||
github.com/go-openapi/spec v0.21.0 // indirect
|
||||
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
@@ -71,67 +60,57 @@ require (
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.2-0.20250313123807-1ee6e1a1957a // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.27 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.28 // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/sys/mountinfo v0.7.2 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/opencontainers/image-spec/schema v0.0.0-20250717171153-ab80ff15c2dd // indirect
|
||||
github.com/opencontainers/runtime-spec v1.2.1 // indirect
|
||||
github.com/opencontainers/selinux v1.12.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/proglottis/gpgme v0.1.4 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/russross/blackfriday v2.0.0+incompatible // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
|
||||
github.com/segmentio/ksuid v1.0.4 // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/sigstore/fulcio v1.6.6 // indirect
|
||||
github.com/sigstore/protobuf-specs v0.4.1 // indirect
|
||||
github.com/sigstore/rekor v1.3.10 // indirect
|
||||
github.com/sigstore/sigstore v1.9.3 // indirect
|
||||
github.com/sigstore/sigstore v1.9.5 // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
||||
github.com/smallstep/pkcs7 v0.1.1 // indirect
|
||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect
|
||||
github.com/sylabs/sif/v2 v2.21.1 // indirect
|
||||
github.com/tchap/go-patricia/v2 v2.3.2 // indirect
|
||||
github.com/tchap/go-patricia/v2 v2.3.3 // indirect
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
||||
github.com/ulikunitz/xz v0.5.12 // indirect
|
||||
github.com/vbatts/tar-split v0.12.1 // indirect
|
||||
github.com/vbauerster/mpb/v8 v8.9.3 // indirect
|
||||
go.mongodb.org/mongo-driver v1.14.0 // indirect
|
||||
github.com/vbauerster/mpb/v8 v8.10.2 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
golang.org/x/crypto v0.37.0 // indirect
|
||||
golang.org/x/mod v0.23.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/oauth2 v0.29.0 // indirect
|
||||
golang.org/x/sync v0.13.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
golang.org/x/crypto v0.40.0 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
||||
google.golang.org/grpc v1.71.0 // indirect
|
||||
google.golang.org/grpc v1.72.2 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
)
|
||||
|
||||
214
go.sum
214
go.sum
@@ -1,25 +1,21 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg=
|
||||
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
|
||||
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
|
||||
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
|
||||
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
|
||||
github.com/Microsoft/hcsshim v0.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA=
|
||||
github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH6HAaclpEok=
|
||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
@@ -41,18 +37,18 @@ github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRcc
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
|
||||
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
|
||||
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
|
||||
github.com/containers/common v0.63.0 h1:ox6vgUYX5TSvt4W+bE36sYBVz/aXMAfRGVAgvknSjBg=
|
||||
github.com/containers/common v0.63.0/go.mod h1:+3GCotSqNdIqM3sPs152VvW7m5+Mg8Kk+PExT3G9hZw=
|
||||
github.com/containers/image/v5 v5.35.0 h1:T1OeyWp3GjObt47bchwD9cqiaAm/u4O4R9hIWdrdrP8=
|
||||
github.com/containers/image/v5 v5.35.0/go.mod h1:8vTsgb+1gKcBL7cnjyNOInhJQfTUQjJoO2WWkKDoebM=
|
||||
github.com/containers/common v0.64.0 h1:Jdjq1e5tqrLov9tcAVc/AfvQCgX4krhcfDBgOXwrSfw=
|
||||
github.com/containers/common v0.64.0/go.mod h1:bq2UIiFP8vUJdgM+WN8E8jkD7wF69SpDRGzU7epJljg=
|
||||
github.com/containers/image/v5 v5.36.0 h1:Zh+xFcLjRmicnOT5AFPHH/xj+e3s9ojDN/9X2Kx1+Jo=
|
||||
github.com/containers/image/v5 v5.36.0/go.mod h1:VZ6cyDHbxZoOt4dklUJ+WNEH9FrgSgfH3qUBYKFlcT0=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
|
||||
github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM=
|
||||
github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ=
|
||||
github.com/containers/storage v1.58.0 h1:Q7SyyCCjqgT3wYNgRNIL8o/wUS92heIj2/cc8Sewvcc=
|
||||
github.com/containers/storage v1.58.0/go.mod h1:w7Jl6oG+OpeLGLzlLyOZPkmUso40kjpzgrHUk5tyBlo=
|
||||
github.com/coreos/go-oidc/v3 v3.13.0 h1:M66zd0pcc5VxvBNM4pB331Wrsanby+QomQYjN8HamW8=
|
||||
github.com/coreos/go-oidc/v3 v3.13.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
|
||||
github.com/containers/storage v1.59.0 h1:r2pYSTzQpJTROZbjJQ54Z0GT+rUC6+wHzlSY8yPjsXk=
|
||||
github.com/containers/storage v1.59.0/go.mod h1:KoAYHnAjP3/cTsRS+mmWZGkufSY2GACiKQ4V3ZLQnR0=
|
||||
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
|
||||
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
|
||||
@@ -64,12 +60,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/cli v28.0.4+incompatible h1:pBJSJeNd9QeIWPjRcV91RVJihd/TXB77q1ef64XEu4A=
|
||||
github.com/docker/cli v28.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
|
||||
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/docker/cli v28.3.2+incompatible h1:mOt9fcLE7zaACbxW1GeS65RI67wIJrTnqS3hP2huFsY=
|
||||
github.com/docker/cli v28.3.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v28.0.4+incompatible h1:JNNkBctYKurkw6FrHfKqY0nKIDf5nrbxjVBtS+cdcok=
|
||||
github.com/docker/docker v28.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
|
||||
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
@@ -92,30 +90,10 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
|
||||
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
|
||||
github.com/go-openapi/errors v0.22.1 h1:kslMRRnK7NCb/CvR1q1VWuEQCEIsBGn5GgKD9e+HYhU=
|
||||
github.com/go-openapi/errors v0.22.1/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||
github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=
|
||||
github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=
|
||||
github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ=
|
||||
github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc=
|
||||
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
|
||||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||
github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
|
||||
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
|
||||
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
|
||||
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
|
||||
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
|
||||
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
|
||||
github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA=
|
||||
github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
@@ -171,14 +149,12 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-multierror v1.1.2-0.20250313123807-1ee6e1a1957a h1:zTI4FFCOXw14aUC78fxMh4tS7jJI7Fm51sH4smjl+Fc=
|
||||
github.com/hashicorp/go-multierror v1.1.2-0.20250313123807-1ee6e1a1957a/go.mod h1:RYOtqYU2MvOrqUMooJlQoFFuqR6sazGdm1ubZTL++r8=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs=
|
||||
github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
@@ -195,28 +171,28 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ=
|
||||
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU=
|
||||
github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
|
||||
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
|
||||
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
||||
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
|
||||
github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
|
||||
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
|
||||
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
|
||||
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
|
||||
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
|
||||
@@ -230,26 +206,22 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
|
||||
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
|
||||
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/opencontainers/image-spec v1.1.2-0.20250724175814-2daaaaf0e7c1 h1:4Fo/qGEjjR6Ugeqb0Ldokiy/VYG4669QIlD0+ZN3jQg=
|
||||
github.com/opencontainers/image-spec v1.1.2-0.20250724175814-2daaaaf0e7c1/go.mod h1:GRy5q9c6/vsqXmQ1I6TL1PkhA64F6eXG9fUOQ9tFvm8=
|
||||
github.com/opencontainers/image-spec/schema v0.0.0-20250717171153-ab80ff15c2dd h1:demTtfPH+DsqagnumQZv8nQrFoUqCJDNVrw+6LsGpm4=
|
||||
github.com/opencontainers/image-spec/schema v0.0.0-20250717171153-ab80ff15c2dd/go.mod h1:vPOv9cXqxB6ycHY5iVwqL4rkYbwRh46GZj13CfkZ6As=
|
||||
github.com/opencontainers/image-tools v1.0.0-rc3 h1:ZR837lBIxq6mmwEqfYrbLMuf75eBSHhccVHy6lsBeM4=
|
||||
github.com/opencontainers/image-tools v1.0.0-rc3/go.mod h1:A9btVpZLzttF4iFaKNychhPyrhfOjJ1OF5KrA8GcLj4=
|
||||
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
|
||||
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
|
||||
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqwnHagNDPGOlts35QkhAZ8by3DR7nMih7M=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -257,11 +229,11 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/proglottis/gpgme v0.1.4 h1:3nE7YNA70o2aLjcg63tXMOhPD7bplfE5CBdV+hLAm2M=
|
||||
github.com/proglottis/gpgme v0.1.4/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM=
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
@@ -271,13 +243,10 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk=
|
||||
github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
|
||||
github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3mcNEL9NBPB0iuVjyxvq3LZc=
|
||||
@@ -286,16 +255,12 @@ github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c
|
||||
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sigstore/fulcio v1.6.6 h1:XaMYX6TNT+8n7Npe8D94nyZ7/ERjEsNGFC+REdi/wzw=
|
||||
github.com/sigstore/fulcio v1.6.6/go.mod h1:BhQ22lwaebDgIxVBEYOOqLRcN5+xOV+C9bh/GUXRhOk=
|
||||
github.com/sigstore/protobuf-specs v0.4.1 h1:5SsMqZbdkcO/DNHudaxuCUEjj6x29tS2Xby1BxGU7Zc=
|
||||
github.com/sigstore/protobuf-specs v0.4.1/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc=
|
||||
github.com/sigstore/rekor v1.3.10 h1:/mSvRo4MZ/59ECIlARhyykAlQlkmeAQpvBPlmJtZOCU=
|
||||
github.com/sigstore/rekor v1.3.10/go.mod h1:JvryKJ40O0XA48MdzYUPu0y4fyvqt0C4iSY7ri9iu3A=
|
||||
github.com/sigstore/sigstore v1.9.3 h1:y2qlTj+vh+Or3ictKuR3JUFawZPdDxAjrWkeFhon0OQ=
|
||||
github.com/sigstore/sigstore v1.9.3/go.mod h1:VwYkiw0G0dRtwL25KSs04hCyVFF6CYMd/qvNeYrl7EQ=
|
||||
github.com/sigstore/sigstore v1.9.5 h1:Wm1LT9yF4LhQdEMy5A2JeGRHTrAWGjT3ubE5JUSrGVU=
|
||||
github.com/sigstore/sigstore v1.9.5/go.mod h1:VtxgvGqCmEZN9X2zhFSOkfXxvKUjpy8RpUW39oCtoII=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
|
||||
@@ -304,8 +269,9 @@ github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU
|
||||
github.com/smallstep/pkcs7 v0.1.1/go.mod h1:dL6j5AIz9GHjVEBTXtW+QliALcgM19RtXaTeyxI+AfA=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw=
|
||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -320,8 +286,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/sylabs/sif/v2 v2.21.1 h1:GZ0b5//AFAqJEChd8wHV/uSKx/l1iuGYwjR8nx+4wPI=
|
||||
github.com/sylabs/sif/v2 v2.21.1/go.mod h1:YoqEGQnb5x/ItV653bawXHZJOXQaEWpGwHsSD3YePJI=
|
||||
github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/Yc7nM=
|
||||
github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||
github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhgwZDDc=
|
||||
github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
@@ -329,8 +295,8 @@ github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=
|
||||
github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
|
||||
github.com/vbauerster/mpb/v8 v8.9.3 h1:PnMeF+sMvYv9u23l6DO6Q3+Mdj408mjLRXIzmUmU2Z8=
|
||||
github.com/vbauerster/mpb/v8 v8.9.3/go.mod h1:hxS8Hz4C6ijnppDSIX6LjG8FYJSoPo9iIOcE53Zik0c=
|
||||
github.com/vbauerster/mpb/v8 v8.10.2 h1:2uBykSHAYHekE11YvJhKxYmLATKHAGorZwFlyNw4hHM=
|
||||
github.com/vbauerster/mpb/v8 v8.10.2/go.mod h1:+Ja4P92E3/CorSZgfDtK46D7AVbDqmBQRTmyTqPElo0=
|
||||
github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=
|
||||
github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns=
|
||||
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
|
||||
@@ -344,34 +310,30 @@ github.com/ysmood/leakless v0.9.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
|
||||
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@@ -380,8 +342,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -393,8 +355,6 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -411,11 +371,11 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
|
||||
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -427,8 +387,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -444,8 +404,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -455,8 +415,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
||||
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
|
||||
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
@@ -466,8 +426,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -482,8 +442,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -502,8 +462,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
|
||||
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
||||
7
hack/sqlite_tag.sh
Executable file
7
hack/sqlite_tag.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
${CPP:-${CC:-cc} -E} ${CPPFLAGS} - &> /dev/null << EOF
|
||||
#include <sqlite3.h>
|
||||
EOF
|
||||
if test $? -eq 0 ; then
|
||||
echo libsqlite3
|
||||
fi
|
||||
@@ -3,6 +3,6 @@ set -e
|
||||
|
||||
make PREFIX=/usr install
|
||||
|
||||
echo "cd ./integration;" go test $TESTFLAGS ${BUILDTAGS:+-tags "$BUILDTAGS"}
|
||||
echo "cd ./integration;" go test "$@" ${BUILDTAGS:+-tags "$BUILDTAGS"}
|
||||
cd ./integration
|
||||
go test $TESTFLAGS ${BUILDTAGS:+-tags "$BUILDTAGS"}
|
||||
go test "$@" ${BUILDTAGS:+-tags "$BUILDTAGS"}
|
||||
|
||||
@@ -38,7 +38,7 @@ EOF
|
||||
fi
|
||||
|
||||
# Build skopeo, install into /usr/bin
|
||||
make PREFIX=/usr install
|
||||
make PREFIX=/usr install "$@"
|
||||
|
||||
# Run tests
|
||||
SKOPEO_BINARY=/usr/bin/skopeo bats --tap systemtest
|
||||
|
||||
@@ -107,7 +107,8 @@ func (s *skopeoSuite) TestCopyWithLocalAuth() {
|
||||
"login", "--tls-verify=false", "--username="+s.regV2WithAuth.username, "--password="+s.regV2WithAuth.password, s.regV2WithAuth.url)
|
||||
// copy to private registry using local authentication
|
||||
imageName := fmt.Sprintf("docker://%s/busybox:mine", s.regV2WithAuth.url)
|
||||
assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", testFQIN+":latest", imageName)
|
||||
assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", "--retry-times", "3",
|
||||
testFQIN+":latest", imageName)
|
||||
// inspect from private registry
|
||||
assertSkopeoSucceeds(t, "", "inspect", "--tls-verify=false", imageName)
|
||||
// logout from the registry
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"maps"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
@@ -101,6 +102,16 @@ func (s *copySuite) TearDownSuite() {
|
||||
}
|
||||
}
|
||||
|
||||
// policyFixture applies the general edits, as well as extraSubstitutions, to the policy.json fixture,
|
||||
// and returns a path to a policy, which will be automatically removed when the test completes.
|
||||
func (s *copySuite) policyFixture(extraSubstitutions map[string]string) string {
|
||||
t := s.T()
|
||||
edits := map[string]string{"@keydir@": s.gpgHome}
|
||||
maps.Copy(edits, extraSubstitutions)
|
||||
policyPath := fileFromFixture(t, "fixtures/policy.json", edits)
|
||||
return policyPath
|
||||
}
|
||||
|
||||
func (s *copySuite) TestCopyWithManifestList() {
|
||||
t := s.T()
|
||||
dir := t.TempDir()
|
||||
@@ -451,7 +462,8 @@ func (s *copySuite) TestCopySucceedsWhenImageDoesNotMatchRuntimeButWeOverride()
|
||||
t := s.T()
|
||||
storage := t.TempDir()
|
||||
storage = fmt.Sprintf("[vfs@%s/root+%s/runroot]", storage, storage)
|
||||
assertSkopeoSucceeds(t, "", "--override-os=windows", "--override-arch=amd64", "copy", knownWindowsOnlyImage, "containers-storage:"+storage+"test")
|
||||
assertSkopeoSucceeds(t, "", "--override-os=windows", "--override-arch=amd64", "copy", knownWindowsOnlyImage, "--retry-times", "3",
|
||||
"containers-storage:"+storage+"test")
|
||||
}
|
||||
|
||||
func (s *copySuite) TestCopySimpleAtomicRegistry() {
|
||||
@@ -461,7 +473,7 @@ func (s *copySuite) TestCopySimpleAtomicRegistry() {
|
||||
|
||||
// FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection.
|
||||
// "pull": docker: → dir:
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQIN64, "dir:"+dir1)
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQIN64, "--retry-times", "3", "dir:"+dir1)
|
||||
// "push": dir: → atomic:
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "dir:"+dir1, "atomic:localhost:5000/myns/unsigned:unsigned")
|
||||
// The result of pushing and pulling is an equivalent image, except for schema1 embedded names.
|
||||
@@ -496,6 +508,8 @@ func (s *copySuite) TestCopySimple() {
|
||||
assertSkopeoSucceeds(t, "", "copy", "docker://registry.k8s.io/pause:latest", "oci:"+ociDest+":"+ociImgName)
|
||||
_, err := os.Stat(ociDest)
|
||||
require.NoError(t, err)
|
||||
// copy exits with status 2 if the image is not found within the container, in some transports.
|
||||
assertSkopeoFailsWithStatus(t, 2, "copy", "oci:"+ociDest+":thisdoesnotexist", "dir:"+t.TempDir())
|
||||
|
||||
// docker v2s2 -> OCI image layout without image name
|
||||
ociDest = "pause-latest-noimage"
|
||||
@@ -539,7 +553,8 @@ func (s *copySuite) TestCopyEncryption() {
|
||||
"oci:"+encryptedImgDir+":encrypted", "oci:"+decryptedImgDir+":decrypted")
|
||||
|
||||
// Copy a standard busybox image locally
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQIN+":1.30.1", "oci:"+originalImageDir+":latest")
|
||||
assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3",
|
||||
testFQIN+":1.30.1", "oci:"+originalImageDir+":latest")
|
||||
|
||||
// Encrypt the image
|
||||
assertSkopeoSucceeds(t, "", "copy", "--encryption-key",
|
||||
@@ -570,7 +585,7 @@ func (s *copySuite) TestCopyEncryption() {
|
||||
matchLayerBlobBinaryType(t, decryptedImgDir+"/blobs/sha256", "application/x-gzip", 1)
|
||||
|
||||
// Copy a standard multi layer nginx image locally
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQINMultiLayer, "oci:"+multiLayerImageDir+":latest")
|
||||
assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQINMultiLayer, "oci:"+multiLayerImageDir+":latest")
|
||||
|
||||
// Partially encrypt the image
|
||||
assertSkopeoSucceeds(t, "", "copy", "--encryption-key", "jwe:"+keysDir+"/public.key",
|
||||
@@ -671,9 +686,10 @@ func (s *copySuite) TestCopyStreaming() {
|
||||
|
||||
// FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection.
|
||||
// streaming: docker: → atomic:
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", testFQIN64, "atomic:localhost:5000/myns/unsigned:streaming")
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "--retry-times", "3",
|
||||
testFQIN64, "atomic:localhost:5000/myns/unsigned:streaming")
|
||||
// Compare (copies of) the original and the copy:
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQIN64, "dir:"+dir1)
|
||||
assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN64, "dir:"+dir1)
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "atomic:localhost:5000/myns/unsigned:streaming", "dir:"+dir2)
|
||||
assertSchema1DirImagesAreEqualExceptNames(t, dir1, "libpod/busybox:amd64", dir2, "myns/unsigned:streaming")
|
||||
// FIXME: Also check pushing to docker://
|
||||
@@ -692,7 +708,8 @@ func (s *copySuite) TestCopyOCIRoundTrip() {
|
||||
oci2 := t.TempDir()
|
||||
|
||||
// Docker -> OCI
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", testFQIN, "oci:"+oci1+":latest")
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "--retry-times", "3",
|
||||
testFQIN, "oci:"+oci1+":latest")
|
||||
// OCI -> Docker
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--debug", "copy", "oci:"+oci1+":latest", ourRegistry+"original/busybox:oci_copy")
|
||||
// Docker -> OCI
|
||||
@@ -738,8 +755,7 @@ func (s *copySuite) TestCopySignatures() {
|
||||
dir := t.TempDir()
|
||||
dirDest := "dir:" + dir
|
||||
|
||||
policy := fileFromFixture(t, "fixtures/policy.json", map[string]string{"@keydir@": s.gpgHome})
|
||||
defer os.Remove(policy)
|
||||
policy := s.policyFixture(nil)
|
||||
|
||||
// type: reject
|
||||
assertSkopeoFails(t, fmt.Sprintf(".*Source image rejected: Running image %s:latest is rejected by policy.*", testFQIN),
|
||||
@@ -750,8 +766,10 @@ func (s *copySuite) TestCopySignatures() {
|
||||
|
||||
// type: signedBy
|
||||
// Sign the images
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--sign-by", "personal@example.com", testFQIN+":1.26", "atomic:localhost:5006/myns/personal:personal")
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--sign-by", "official@example.com", testFQIN+":1.26.1", "atomic:localhost:5006/myns/official:official")
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--sign-by", "personal@example.com",
|
||||
testFQIN+":1.26", "atomic:localhost:5006/myns/personal:personal")
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--sign-by", "official@example.com",
|
||||
testFQIN+":1.26.1", "atomic:localhost:5006/myns/official:official")
|
||||
// Verify that we can pull them
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--policy", policy, "copy", "atomic:localhost:5006/myns/personal:personal", dirDest)
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--policy", policy, "copy", "atomic:localhost:5006/myns/official:official", dirDest)
|
||||
@@ -800,12 +818,11 @@ func (s *copySuite) TestCopyDirSignatures() {
|
||||
|
||||
// Note the "/@dirpath@": The value starts with a slash so that it is not rejected in other tests which do not replace it,
|
||||
// but we must ensure that the result is a canonical path, not something starting with a "//".
|
||||
policy := fileFromFixture(t, "fixtures/policy.json", map[string]string{"@keydir@": s.gpgHome, "/@dirpath@": topDir + "/restricted"})
|
||||
defer os.Remove(policy)
|
||||
policy := s.policyFixture(map[string]string{"/@dirpath@": topDir + "/restricted"})
|
||||
|
||||
// Get some images.
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQIN+":armfh", topDirDest+"/dir1")
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQIN+":s390x", topDirDest+"/dir2")
|
||||
assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN+":armfh", topDirDest+"/dir1")
|
||||
assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN+":s390x", topDirDest+"/dir2")
|
||||
|
||||
// Sign the images. By coping from a topDirDest/dirN, also test that non-/restricted paths
|
||||
// use the dir:"" default of insecureAcceptAnything.
|
||||
@@ -908,8 +925,7 @@ func (s *copySuite) TestCopyDockerLookaside() {
|
||||
}))
|
||||
defer splitLookasideReadServer.Close()
|
||||
|
||||
policy := fileFromFixture(t, "fixtures/policy.json", map[string]string{"@keydir@": s.gpgHome})
|
||||
defer os.Remove(policy)
|
||||
policy := s.policyFixture(nil)
|
||||
registriesDir := filepath.Join(tmpDir, "registries.d")
|
||||
err = os.Mkdir(registriesDir, 0755)
|
||||
require.NoError(t, err)
|
||||
@@ -919,7 +935,8 @@ func (s *copySuite) TestCopyDockerLookaside() {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Get an image to work with. Also verifies that we can use Docker repositories with no lookaside configured.
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, "copy", testFQIN, ourRegistry+"original/busybox")
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, "copy", "--retry-times", "3",
|
||||
testFQIN, ourRegistry+"original/busybox")
|
||||
// Pulling an unsigned image fails.
|
||||
assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*",
|
||||
"--tls-verify=false", "--policy", policy, "--registries.d", registriesDir, "copy", ourRegistry+"original/busybox", dirDest)
|
||||
@@ -968,11 +985,11 @@ func (s *copySuite) TestCopyAtomicExtension() {
|
||||
}
|
||||
registriesDir := filepath.Join(topDir, "registries.d")
|
||||
dirDest := "dir:" + topDir
|
||||
policy := fileFromFixture(t, "fixtures/policy.json", map[string]string{"@keydir@": s.gpgHome})
|
||||
defer os.Remove(policy)
|
||||
policy := s.policyFixture(nil)
|
||||
|
||||
// Get an image to work with to an atomic: destination. Also verifies that we can use Docker repositories without X-Registry-Supports-Signatures
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, "copy", testFQIN, "atomic:localhost:5000/myns/extension:unsigned")
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir, "copy", "--retry-times", "3",
|
||||
testFQIN, "atomic:localhost:5000/myns/extension:unsigned")
|
||||
// Pulling an unsigned image using atomic: fails.
|
||||
assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*",
|
||||
"--tls-verify=false", "--policy", policy,
|
||||
@@ -996,7 +1013,8 @@ func (s *copySuite) TestCopyAtomicExtension() {
|
||||
|
||||
// Get another image (different so that they don't share signatures, and sign it using docker://)
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "--registries.d", registriesDir,
|
||||
"copy", "--sign-by", "personal@example.com", testFQIN+":ppc64le", "docker://localhost:5000/myns/extension:extension")
|
||||
"copy", "--retry-times", "3", "--sign-by", "personal@example.com",
|
||||
testFQIN+":ppc64le", "docker://localhost:5000/myns/extension:extension")
|
||||
t.Logf("%s", combinedOutputOfCommand(t, "oc", "get", "istag", "extension:extension", "-o", "json"))
|
||||
// Pulling the image using atomic: succeeds.
|
||||
assertSkopeoSucceeds(t, "", "--debug", "--tls-verify=false", "--policy", policy,
|
||||
@@ -1024,8 +1042,7 @@ func (s *copySuite) TestCopyVerifyingMirroredSignatures() {
|
||||
registriesDir := filepath.Join(topDir, "registries.d") // An empty directory to disable lookaside use
|
||||
dirDest := "dir:" + filepath.Join(topDir, "unused-dest")
|
||||
|
||||
policy := fileFromFixture(t, "fixtures/policy.json", map[string]string{"@keydir@": s.gpgHome})
|
||||
defer os.Remove(policy)
|
||||
policy := s.policyFixture(nil)
|
||||
|
||||
// We use X-R-S-S for this testing to avoid having to deal with the lookasides.
|
||||
// A downside is that OpenShift records signatures per image, so the error messages below
|
||||
@@ -1033,7 +1050,8 @@ func (s *copySuite) TestCopyVerifyingMirroredSignatures() {
|
||||
// So, make sure to never create a signature that could be considered valid in a different part of the test (i.e. don't reuse tags).
|
||||
|
||||
// Get an image to work with.
|
||||
assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", testFQIN, regPrefix+"primary:unsigned")
|
||||
assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", "--dest-tls-verify=false",
|
||||
testFQIN, regPrefix+"primary:unsigned")
|
||||
// Verify that unsigned images are rejected
|
||||
assertSkopeoFails(t, ".*Source image rejected: A signature was required, but no signature exists.*",
|
||||
"--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:unsigned", dirDest)
|
||||
@@ -1082,19 +1100,22 @@ func (s *copySuite) TestCopyVerifyingMirroredSignatures() {
|
||||
|
||||
func (s *skopeoSuite) TestCopySrcWithAuth() {
|
||||
t := s.T()
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--dest-creds=testuser:testpassword", testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--dest-creds=testuser:testpassword",
|
||||
testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
|
||||
dir1 := t.TempDir()
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--src-creds=testuser:testpassword", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url), "dir:"+dir1)
|
||||
}
|
||||
|
||||
func (s *skopeoSuite) TestCopyDestWithAuth() {
|
||||
t := s.T()
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--dest-creds=testuser:testpassword", testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--dest-creds=testuser:testpassword",
|
||||
testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
|
||||
}
|
||||
|
||||
func (s *skopeoSuite) TestCopySrcAndDestWithAuth() {
|
||||
t := s.T()
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--dest-creds=testuser:testpassword", testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--retry-times", "3", "--dest-creds=testuser:testpassword",
|
||||
testFQIN, fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
|
||||
assertSkopeoSucceeds(t, "", "--tls-verify=false", "copy", "--src-creds=testuser:testpassword", "--dest-creds=testuser:testpassword", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url), fmt.Sprintf("docker://%s/test:auth", s.regV2WithAuth.url))
|
||||
}
|
||||
|
||||
@@ -1125,7 +1146,7 @@ func (s *copySuite) TestCopyManifestConversion() {
|
||||
|
||||
// oci to v2s1 and vice-versa not supported yet
|
||||
// get v2s2 manifest type
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQIN, "dir:"+srcDir)
|
||||
assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN, "dir:"+srcDir)
|
||||
verifyManifestMIMEType(t, srcDir, manifest.DockerV2Schema2MediaType)
|
||||
// convert from v2s2 to oci
|
||||
assertSkopeoSucceeds(t, "", "copy", "--format=oci", "dir:"+srcDir, "dir:"+destDir1)
|
||||
@@ -1161,7 +1182,7 @@ func (s *copySuite) testCopySchemaConversionRegistries(t *testing.T, schema1Regi
|
||||
|
||||
// Ensure we are working with a schema2 image.
|
||||
// dir: accepts any manifest format, i.e. this makes …/input2 a schema2 source which cannot be asked to produce schema1 like ordinary docker: registries can.
|
||||
assertSkopeoSucceeds(t, "", "copy", testFQIN, "dir:"+input2Dir)
|
||||
assertSkopeoSucceeds(t, "", "copy", "--retry-times", "3", testFQIN, "dir:"+input2Dir)
|
||||
verifyManifestMIMEType(t, input2Dir, manifest.DockerV2Schema2MediaType)
|
||||
// 2→2 (the "f2t2" in tag means "from 2 to 2")
|
||||
assertSkopeoSucceeds(t, "", "copy", "--dest-tls-verify=false", "dir:"+input2Dir, schema2Registry+":f2t2")
|
||||
|
||||
@@ -223,7 +223,7 @@ func (cluster *openshiftCluster) ocLoginToProject(t *testing.T) {
|
||||
// We do not run (docker login) directly, because that requires a running daemon and a docker package.
|
||||
func (cluster *openshiftCluster) dockerLogin(t *testing.T) {
|
||||
cluster.dockerDir = filepath.Join(homedir.Get(), ".docker")
|
||||
err := os.Mkdir(cluster.dockerDir, 0700)
|
||||
err := os.MkdirAll(cluster.dockerDir, 0700)
|
||||
require.NoError(t, err)
|
||||
|
||||
out := combinedOutputOfCommand(t, "oc", "config", "view", "-o", "json", "-o", "jsonpath={.users[*].user.token}")
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
binaryV2 = "registry-v2"
|
||||
binaryV2 = "registry"
|
||||
binaryV2Schema1 = "registry-v2-schema1"
|
||||
)
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ func consumeAndLogOutputs(t *testing.T, id string, cmd *exec.Cmd) {
|
||||
}
|
||||
|
||||
// combinedOutputOfCommand runs a command as if exec.Command().CombinedOutput(), verifies that the exit status is 0, and returns the output,
|
||||
// or terminates c on failure.
|
||||
// or terminates t on failure.
|
||||
func combinedOutputOfCommand(t *testing.T, name string, args ...string) string {
|
||||
t.Logf("Running %s %s", name, strings.Join(args, " "))
|
||||
out, err := exec.Command(name, args...).CombinedOutput()
|
||||
@@ -64,8 +64,7 @@ func combinedOutputOfCommand(t *testing.T, name string, args ...string) string {
|
||||
}
|
||||
|
||||
// assertSkopeoSucceeds runs a skopeo command as if exec.Command().CombinedOutput, verifies that the exit status is 0,
|
||||
// and optionally that the output matches a multi-line regexp if it is nonempty;
|
||||
// or terminates c on failure
|
||||
// and optionally that the output matches a multi-line regexp if it is nonempty
|
||||
func assertSkopeoSucceeds(t *testing.T, regexp string, args ...string) {
|
||||
t.Logf("Running %s %s", skopeoBinary, strings.Join(args, " "))
|
||||
out, err := exec.Command(skopeoBinary, args...).CombinedOutput()
|
||||
@@ -75,9 +74,8 @@ func assertSkopeoSucceeds(t *testing.T, regexp string, args ...string) {
|
||||
}
|
||||
}
|
||||
|
||||
// assertSkopeoFails runs a skopeo command as if exec.Command().CombinedOutput, verifies that the exit status is 0,
|
||||
// and that the output matches a multi-line regexp;
|
||||
// or terminates c on failure
|
||||
// assertSkopeoFails runs a skopeo command as if exec.Command().CombinedOutput, verifies that the exit status is not 0,
|
||||
// and that the output matches a multi-line regexp
|
||||
func assertSkopeoFails(t *testing.T, regexp string, args ...string) {
|
||||
t.Logf("Running %s %s", skopeoBinary, strings.Join(args, " "))
|
||||
out, err := exec.Command(skopeoBinary, args...).CombinedOutput()
|
||||
@@ -85,15 +83,25 @@ func assertSkopeoFails(t *testing.T, regexp string, args ...string) {
|
||||
assert.Regexp(t, "(?s)"+regexp, string(out)) // (?s) : '.' will also match newlines
|
||||
}
|
||||
|
||||
// assertSkopeoFailsWithStatus runs a skopeo command as if exec.Command().CombinedOutput,
|
||||
// and verifies that it fails with a specific exit status.
|
||||
func assertSkopeoFailsWithStatus(t *testing.T, status int, args ...string) {
|
||||
t.Logf("Running %s %s", skopeoBinary, strings.Join(args, " "))
|
||||
_, err := exec.Command(skopeoBinary, args...).CombinedOutput()
|
||||
var exitErr *exec.ExitError
|
||||
require.ErrorAs(t, err, &exitErr)
|
||||
assert.Equal(t, status, exitErr.ExitCode())
|
||||
}
|
||||
|
||||
// runCommandWithInput runs a command as if exec.Command(), sending it the input to stdin,
|
||||
// and verifies that the exit status is 0, or terminates c on failure.
|
||||
// and verifies that the exit status is 0, or terminates t on failure.
|
||||
func runCommandWithInput(t *testing.T, input string, name string, args ...string) {
|
||||
cmd := exec.Command(name, args...)
|
||||
runExecCmdWithInput(t, cmd, input)
|
||||
}
|
||||
|
||||
// runExecCmdWithInput runs an exec.Cmd, sending it the input to stdin,
|
||||
// and verifies that the exit status is 0, or terminates c on failure.
|
||||
// and verifies that the exit status is 0, or terminates t on failure.
|
||||
func runExecCmdWithInput(t *testing.T, cmd *exec.Cmd, input string) {
|
||||
t.Logf("Running %s %s", cmd.Path, strings.Join(cmd.Args, " "))
|
||||
consumeAndLogOutputs(t, cmd.Path+" "+strings.Join(cmd.Args, " "), cmd)
|
||||
@@ -166,8 +174,8 @@ func modifyEnviron(env []string, name, value string) []string {
|
||||
return append(res, prefix+value)
|
||||
}
|
||||
|
||||
// fileFromFixture applies edits to inputPath and returns a path to the temporary file.
|
||||
// Callers should defer os.Remove(the_returned_path)
|
||||
// fileFromFixture applies edits to inputPath and returns a path to the temporary file with the edits,
|
||||
// which will be automatically removed when the test completes.
|
||||
func fileFromFixture(t *testing.T, inputPath string, edits map[string]string) string {
|
||||
contents, err := os.ReadFile(inputPath)
|
||||
require.NoError(t, err)
|
||||
@@ -180,6 +188,7 @@ func fileFromFixture(t *testing.T, inputPath string, edits map[string]string) st
|
||||
file, err := os.CreateTemp("", "policy.json")
|
||||
require.NoError(t, err)
|
||||
path := file.Name()
|
||||
t.Cleanup(func() { os.Remove(path) })
|
||||
|
||||
_, err = file.Write(contents)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -6,8 +6,14 @@ prepare:
|
||||
- when: distro == centos-stream or distro == rhel
|
||||
how: shell
|
||||
script: |
|
||||
dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm --eval '%{?rhel}').noarch.rpm
|
||||
dnf -y config-manager --set-enabled epel
|
||||
# Install bats
|
||||
# https://bats-core.readthedocs.io/en/stable/installation.html
|
||||
BATS_VERSION=1.12.0
|
||||
curl -L https://github.com/bats-core/bats-core/archive/refs/tags/v"$BATS_VERSION".tar.gz | tar -xz
|
||||
pushd bats-core-"$BATS_VERSION"
|
||||
./install.sh /usr
|
||||
popd
|
||||
rm -rf bats-core-"$BATS_VERSION"
|
||||
order: 10
|
||||
- when: initiator == packit
|
||||
how: shell
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- fedora-*
|
||||
decision_context:
|
||||
decision_contexts:
|
||||
- bodhi_update_push_stable
|
||||
- bodhi_update_push_testing
|
||||
subject_type: koji_build
|
||||
|
||||
@@ -63,10 +63,10 @@ BuildRequires: go-rpm-macros
|
||||
%endif
|
||||
BuildRequires: gpgme-devel
|
||||
BuildRequires: libassuan-devel
|
||||
BuildRequires: ostree-devel
|
||||
BuildRequires: glib2-devel
|
||||
BuildRequires: make
|
||||
BuildRequires: shadow-utils-subid-devel
|
||||
BuildRequires: sqlite-devel
|
||||
Requires: containers-common >= 4:1-21
|
||||
|
||||
%description
|
||||
@@ -79,7 +79,6 @@ registries without the need to pull them
|
||||
Summary: Tests for %{name}
|
||||
|
||||
Requires: %{name} = %{epoch}:%{version}-%{release}
|
||||
Requires: bats
|
||||
%if %{defined fakeroot}
|
||||
Requires: fakeroot
|
||||
%endif
|
||||
@@ -91,6 +90,8 @@ Requires: crun
|
||||
Requires: httpd-tools
|
||||
Requires: openssl
|
||||
Requires: squashfs-tools
|
||||
# bats is not present on RHEL and ELN so it shouldn't be a strong dep
|
||||
Recommends: bats
|
||||
|
||||
%description tests
|
||||
%{summary}
|
||||
@@ -118,7 +119,7 @@ CGO_CFLAGS=$(echo $CGO_CFLAGS | sed 's/-specs=\/usr\/lib\/rpm\/redhat\/redhat-an
|
||||
export CGO_CFLAGS="$CGO_CFLAGS -m64 -mtune=generic -fcf-protection=full"
|
||||
%endif
|
||||
|
||||
BASEBUILDTAGS="$(hack/libsubid_tag.sh)"
|
||||
BASEBUILDTAGS="$(hack/libsubid_tag.sh) libsqlite3"
|
||||
%if %{defined build_with_btrfs}
|
||||
export BUILDTAGS="$BASEBUILDTAGS $(hack/btrfs_installed_tag.sh)"
|
||||
%else
|
||||
|
||||
@@ -16,4 +16,30 @@ function setup() {
|
||||
expect_output --substring "skopeo version [0-9.]+"
|
||||
}
|
||||
|
||||
@test "skopeo release isn't a development version" {
|
||||
[[ "${RELEASE_TESTING:-false}" == "true" ]] || \
|
||||
skip "Release testing may be enabled by setting \$RELEASE_TESTING = 'true'."
|
||||
|
||||
run_skopeo --version
|
||||
|
||||
# expect_output() doesn't support negative matching
|
||||
if [[ "$output" =~ "dev" ]]; then
|
||||
# This is a multi-line message, which may in turn contain multi-line
|
||||
# output, so let's format it ourselves, readably
|
||||
local -a output_split
|
||||
readarray -t output_split <<<"$output"
|
||||
printf "#/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n" >&2
|
||||
printf "#| FAIL: $BATS_TEST_NAME\n" >&2
|
||||
printf "#| unexpected: 'dev'\n" >&2
|
||||
printf "#| actual: '%s'\n" "${output_split[0]}" >&2
|
||||
local line
|
||||
for line in "${output_split[@]:1}"; do
|
||||
printf "#| > '%s'\n" "$line" >&2
|
||||
done
|
||||
printf "#\\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" >&2
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# vim: filetype=sh
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
require:
|
||||
- bats
|
||||
- skopeo-tests
|
||||
|
||||
environment:
|
||||
SKOPEO_BINARY: /usr/bin/skopeo
|
||||
|
||||
adjust:
|
||||
- when: initiator != "packit"
|
||||
environment+:
|
||||
RELEASE_TESTING: true
|
||||
|
||||
summary: System test
|
||||
test: bash ./test.sh
|
||||
duration: 60m
|
||||
|
||||
7
vendor/dario.cat/mergo/FUNDING.json
vendored
Normal file
7
vendor/dario.cat/mergo/FUNDING.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"drips": {
|
||||
"ethereum": {
|
||||
"ownedBy": "0x6160020e7102237aC41bdb156e94401692D76930"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
vendor/dario.cat/mergo/README.md
vendored
5
vendor/dario.cat/mergo/README.md
vendored
@@ -85,7 +85,6 @@ Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/depend
|
||||
* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
|
||||
* [go-micro/go-micro](https://github.com/go-micro/go-micro)
|
||||
* [grafana/loki](https://github.com/grafana/loki)
|
||||
* [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
|
||||
* [masterminds/sprig](github.com/Masterminds/sprig)
|
||||
* [moby/moby](https://github.com/moby/moby)
|
||||
* [slackhq/nebula](https://github.com/slackhq/nebula)
|
||||
@@ -191,10 +190,6 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
Note: if test are failing due missing package, please execute:
|
||||
|
||||
go get gopkg.in/yaml.v3
|
||||
|
||||
### Transformers
|
||||
|
||||
Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
|
||||
|
||||
4
vendor/dario.cat/mergo/SECURITY.md
vendored
4
vendor/dario.cat/mergo/SECURITY.md
vendored
@@ -4,8 +4,8 @@
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.3.x | :white_check_mark: |
|
||||
| < 0.3 | :x: |
|
||||
| 1.x.x | :white_check_mark: |
|
||||
| < 1.0 | :x: |
|
||||
|
||||
## Security contact information
|
||||
|
||||
|
||||
28
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
28
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
@@ -1,5 +1,31 @@
|
||||
# Changelog
|
||||
|
||||
## 3.4.0 (2025-06-27)
|
||||
|
||||
### Added
|
||||
|
||||
- #268: Added property to Constraints to include prereleases for Check and Validate
|
||||
|
||||
### Changed
|
||||
|
||||
- #263: Updated Go testing for 1.24, 1.23, and 1.22
|
||||
- #269: Updated the error message handling for message case and wrapping errors
|
||||
- #266: Restore the ability to have leading 0's when parsing with NewVersion.
|
||||
Opt-out of this by setting CoerceNewVersion to false.
|
||||
|
||||
### Fixed
|
||||
|
||||
- #257: Fixed the CodeQL link (thanks @dmitris)
|
||||
- #262: Restored detailed errors when failed to parse with NewVersion. Opt-out
|
||||
of this by setting DetailedNewVersionErrors to false for faster performance.
|
||||
- #267: Handle pre-releases for an "and" group if one constraint includes them
|
||||
|
||||
## 3.3.1 (2024-11-19)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #253: Fix for allowing some version that were invalid
|
||||
|
||||
## 3.3.0 (2024-08-27)
|
||||
|
||||
### Added
|
||||
@@ -137,7 +163,7 @@ functions. These are described in the added and changed sections below.
|
||||
- #78: Fix unchecked error in example code (thanks @ravron)
|
||||
- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
|
||||
- #97: Fixed copyright file for proper display on GitHub
|
||||
- #107: Fix handling prerelease when sorting alphanum and num
|
||||
- #107: Fix handling prerelease when sorting alphanum and num
|
||||
- #109: Fixed where Validate sometimes returns wrong message on error
|
||||
|
||||
## 1.4.2 (2018-04-10)
|
||||
|
||||
18
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
18
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
@@ -50,6 +50,18 @@ other versions, convert the version back into a string, and get the original
|
||||
string. Getting the original string is useful if the semantic version was coerced
|
||||
into a valid form.
|
||||
|
||||
There are package level variables that affect how `NewVersion` handles parsing.
|
||||
|
||||
- `CoerceNewVersion` is `true` by default. When set to `true` it coerces non-compliant
|
||||
versions into SemVer. For example, allowing a leading 0 in a major, minor, or patch
|
||||
part. This enables the use of CalVer in versions even when not compliant with SemVer.
|
||||
When set to `false` less coercion work is done.
|
||||
- `DetailedNewVersionErrors` provides more detailed errors. It only has an affect when
|
||||
`CoerceNewVersion` is set to `false`. When `DetailedNewVersionErrors` is set to `true`
|
||||
it can provide some more insight into why a version is invalid. Setting
|
||||
`DetailedNewVersionErrors` to `false` is faster on performance but provides less
|
||||
detailed error messages if a version fails to parse.
|
||||
|
||||
## Sorting Semantic Versions
|
||||
|
||||
A set of versions can be sorted using the `sort` package from the standard library.
|
||||
@@ -160,6 +172,10 @@ means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
|
||||
sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
|
||||
the spec specifies.
|
||||
|
||||
The `Constraints` instance returned from `semver.NewConstraint()` has a property
|
||||
`IncludePrerelease` that, when set to true, will return prerelease versions when calls
|
||||
to `Check()` and `Validate()` are made.
|
||||
|
||||
### Hyphen Range Comparisons
|
||||
|
||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||
@@ -250,7 +266,7 @@ or [create a pull request](https://github.com/Masterminds/semver/pulls).
|
||||
Security is an important consideration for this project. The project currently
|
||||
uses the following tools to help discover security issues:
|
||||
|
||||
* [CodeQL](https://github.com/Masterminds/semver)
|
||||
* [CodeQL](https://codeql.github.com)
|
||||
* [gosec](https://github.com/securego/gosec)
|
||||
* Daily Fuzz testing
|
||||
|
||||
|
||||
127
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
127
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
@@ -12,6 +12,13 @@ import (
|
||||
// checked against.
|
||||
type Constraints struct {
|
||||
constraints [][]*constraint
|
||||
containsPre []bool
|
||||
|
||||
// IncludePrerelease specifies if pre-releases should be included in
|
||||
// the results. Note, if a constraint range has a prerelease than
|
||||
// prereleases will be included for that AND group even if this is
|
||||
// set to false.
|
||||
IncludePrerelease bool
|
||||
}
|
||||
|
||||
// NewConstraint returns a Constraints instance that a Version instance can
|
||||
@@ -22,11 +29,10 @@ func NewConstraint(c string) (*Constraints, error) {
|
||||
c = rewriteRange(c)
|
||||
|
||||
ors := strings.Split(c, "||")
|
||||
or := make([][]*constraint, len(ors))
|
||||
lenors := len(ors)
|
||||
or := make([][]*constraint, lenors)
|
||||
hasPre := make([]bool, lenors)
|
||||
for k, v := range ors {
|
||||
|
||||
// TODO: Find a way to validate and fetch all the constraints in a simpler form
|
||||
|
||||
// Validate the segment
|
||||
if !validConstraintRegex.MatchString(v) {
|
||||
return nil, fmt.Errorf("improper constraint: %s", v)
|
||||
@@ -43,12 +49,22 @@ func NewConstraint(c string) (*Constraints, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If one of the constraints has a prerelease record this.
|
||||
// This information is used when checking all in an "and"
|
||||
// group to ensure they all check for prereleases.
|
||||
if pc.con.pre != "" {
|
||||
hasPre[k] = true
|
||||
}
|
||||
|
||||
result[i] = pc
|
||||
}
|
||||
or[k] = result
|
||||
}
|
||||
|
||||
o := &Constraints{constraints: or}
|
||||
o := &Constraints{
|
||||
constraints: or,
|
||||
containsPre: hasPre,
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
@@ -57,10 +73,10 @@ func (cs Constraints) Check(v *Version) bool {
|
||||
// TODO(mattfarina): For v4 of this library consolidate the Check and Validate
|
||||
// functions as the underlying functions make that possible now.
|
||||
// loop over the ORs and check the inner ANDs
|
||||
for _, o := range cs.constraints {
|
||||
for i, o := range cs.constraints {
|
||||
joy := true
|
||||
for _, c := range o {
|
||||
if check, _ := c.check(v); !check {
|
||||
if check, _ := c.check(v, (cs.IncludePrerelease || cs.containsPre[i])); !check {
|
||||
joy = false
|
||||
break
|
||||
}
|
||||
@@ -83,12 +99,12 @@ func (cs Constraints) Validate(v *Version) (bool, []error) {
|
||||
// Capture the prerelease message only once. When it happens the first time
|
||||
// this var is marked
|
||||
var prerelesase bool
|
||||
for _, o := range cs.constraints {
|
||||
for i, o := range cs.constraints {
|
||||
joy := true
|
||||
for _, c := range o {
|
||||
// Before running the check handle the case there the version is
|
||||
// a prerelease and the check is not searching for prereleases.
|
||||
if c.con.pre == "" && v.pre != "" {
|
||||
if !(cs.IncludePrerelease || cs.containsPre[i]) && v.pre != "" {
|
||||
if !prerelesase {
|
||||
em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
e = append(e, em)
|
||||
@@ -98,7 +114,7 @@ func (cs Constraints) Validate(v *Version) (bool, []error) {
|
||||
|
||||
} else {
|
||||
|
||||
if _, err := c.check(v); err != nil {
|
||||
if _, err := c.check(v, (cs.IncludePrerelease || cs.containsPre[i])); err != nil {
|
||||
e = append(e, err)
|
||||
joy = false
|
||||
}
|
||||
@@ -227,8 +243,8 @@ type constraint struct {
|
||||
}
|
||||
|
||||
// Check if a version meets the constraint
|
||||
func (c *constraint) check(v *Version) (bool, error) {
|
||||
return constraintOps[c.origfunc](v, c)
|
||||
func (c *constraint) check(v *Version, includePre bool) (bool, error) {
|
||||
return constraintOps[c.origfunc](v, c, includePre)
|
||||
}
|
||||
|
||||
// String prints an individual constraint into a string
|
||||
@@ -236,7 +252,7 @@ func (c *constraint) string() string {
|
||||
return c.origfunc + c.orig
|
||||
}
|
||||
|
||||
type cfunc func(v *Version, c *constraint) (bool, error)
|
||||
type cfunc func(v *Version, c *constraint, includePre bool) (bool, error)
|
||||
|
||||
func parseConstraint(c string) (*constraint, error) {
|
||||
if len(c) > 0 {
|
||||
@@ -272,7 +288,7 @@ func parseConstraint(c string) (*constraint, error) {
|
||||
|
||||
// The constraintRegex should catch any regex parsing errors. So,
|
||||
// we should never get here.
|
||||
return nil, errors.New("constraint Parser Error")
|
||||
return nil, errors.New("constraint parser error")
|
||||
}
|
||||
|
||||
cs.con = con
|
||||
@@ -290,7 +306,7 @@ func parseConstraint(c string) (*constraint, error) {
|
||||
|
||||
// The constraintRegex should catch any regex parsing errors. So,
|
||||
// we should never get here.
|
||||
return nil, errors.New("constraint Parser Error")
|
||||
return nil, errors.New("constraint parser error")
|
||||
}
|
||||
|
||||
cs := &constraint{
|
||||
@@ -305,16 +321,14 @@ func parseConstraint(c string) (*constraint, error) {
|
||||
}
|
||||
|
||||
// Constraint functions
|
||||
func constraintNotEqual(v *Version, c *constraint) (bool, error) {
|
||||
func constraintNotEqual(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.dirty {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.con.Major() != v.Major() {
|
||||
return true, nil
|
||||
}
|
||||
@@ -345,12 +359,11 @@ func constraintNotEqual(v *Version, c *constraint) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func constraintGreaterThan(v *Version, c *constraint) (bool, error) {
|
||||
func constraintGreaterThan(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@@ -391,11 +404,10 @@ func constraintGreaterThan(v *Version, c *constraint) (bool, error) {
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintLessThan(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintLessThan(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@@ -406,12 +418,11 @@ func constraintLessThan(v *Version, c *constraint) (bool, error) {
|
||||
return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
func constraintGreaterThanEqual(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@@ -422,11 +433,10 @@ func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
return false, fmt.Errorf("%s is less than %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintLessThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintLessThanEqual(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@@ -455,11 +465,10 @@ func constraintLessThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
|
||||
// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
|
||||
// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
|
||||
func constraintTilde(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintTilde(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@@ -487,16 +496,15 @@ func constraintTilde(v *Version, c *constraint) (bool, error) {
|
||||
|
||||
// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
|
||||
// it's a straight =
|
||||
func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintTildeOrEqual(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.dirty {
|
||||
return constraintTilde(v, c)
|
||||
return constraintTilde(v, c, includePre)
|
||||
}
|
||||
|
||||
eq := v.Equal(c.con)
|
||||
@@ -516,11 +524,10 @@ func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) {
|
||||
// ^0.0.3 --> >=0.0.3 <0.0.4
|
||||
// ^0.0 --> >=0.0.0 <0.1.0
|
||||
// ^0 --> >=0.0.0 <1.0.0
|
||||
func constraintCaret(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintCaret(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
|
||||
163
vendor/github.com/Masterminds/semver/v3/version.go
generated
vendored
163
vendor/github.com/Masterminds/semver/v3/version.go
generated
vendored
@@ -14,28 +14,40 @@ import (
|
||||
// The compiled version of the regex created at init() is cached here so it
|
||||
// only needs to be created once.
|
||||
var versionRegex *regexp.Regexp
|
||||
var looseVersionRegex *regexp.Regexp
|
||||
|
||||
// CoerceNewVersion sets if leading 0's are allowd in the version part. Leading 0's are
|
||||
// not allowed in a valid semantic version. When set to true, NewVersion will coerce
|
||||
// leading 0's into a valid version.
|
||||
var CoerceNewVersion = true
|
||||
|
||||
// DetailedNewVersionErrors specifies if detailed errors are returned from the NewVersion
|
||||
// function. This is used when CoerceNewVersion is set to false. If set to false
|
||||
// ErrInvalidSemVer is returned for an invalid version. This does not apply to
|
||||
// StrictNewVersion. Setting this function to false returns errors more quickly.
|
||||
var DetailedNewVersionErrors = true
|
||||
|
||||
var (
|
||||
// ErrInvalidSemVer is returned a version is found to be invalid when
|
||||
// being parsed.
|
||||
ErrInvalidSemVer = errors.New("Invalid Semantic Version")
|
||||
ErrInvalidSemVer = errors.New("invalid semantic version")
|
||||
|
||||
// ErrEmptyString is returned when an empty string is passed in for parsing.
|
||||
ErrEmptyString = errors.New("Version string empty")
|
||||
ErrEmptyString = errors.New("version string empty")
|
||||
|
||||
// ErrInvalidCharacters is returned when invalid characters are found as
|
||||
// part of a version
|
||||
ErrInvalidCharacters = errors.New("Invalid characters in version")
|
||||
ErrInvalidCharacters = errors.New("invalid characters in version")
|
||||
|
||||
// ErrSegmentStartsZero is returned when a version segment starts with 0.
|
||||
// This is invalid in SemVer.
|
||||
ErrSegmentStartsZero = errors.New("Version segment starts with 0")
|
||||
ErrSegmentStartsZero = errors.New("version segment starts with 0")
|
||||
|
||||
// ErrInvalidMetadata is returned when the metadata is an invalid format
|
||||
ErrInvalidMetadata = errors.New("Invalid Metadata string")
|
||||
ErrInvalidMetadata = errors.New("invalid metadata string")
|
||||
|
||||
// ErrInvalidPrerelease is returned when the pre-release is an invalid format
|
||||
ErrInvalidPrerelease = errors.New("Invalid Prerelease string")
|
||||
ErrInvalidPrerelease = errors.New("invalid prerelease string")
|
||||
)
|
||||
|
||||
// semVerRegex is the regular expression used to parse a semantic version.
|
||||
@@ -45,6 +57,12 @@ const semVerRegex string = `v?(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?
|
||||
`(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` +
|
||||
`(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?`
|
||||
|
||||
// looseSemVerRegex is a regular expression that lets invalid semver expressions through
|
||||
// with enough detail that certain errors can be checked for.
|
||||
const looseSemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
|
||||
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
|
||||
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
|
||||
|
||||
// Version represents a single semantic version.
|
||||
type Version struct {
|
||||
major, minor, patch uint64
|
||||
@@ -55,6 +73,7 @@ type Version struct {
|
||||
|
||||
func init() {
|
||||
versionRegex = regexp.MustCompile("^" + semVerRegex + "$")
|
||||
looseVersionRegex = regexp.MustCompile("^" + looseSemVerRegex + "$")
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -142,8 +161,27 @@ func StrictNewVersion(v string) (*Version, error) {
|
||||
// attempts to convert it to SemVer. If you want to validate it was a strict
|
||||
// semantic version at parse time see StrictNewVersion().
|
||||
func NewVersion(v string) (*Version, error) {
|
||||
if CoerceNewVersion {
|
||||
return coerceNewVersion(v)
|
||||
}
|
||||
m := versionRegex.FindStringSubmatch(v)
|
||||
if m == nil {
|
||||
|
||||
// Disabling detailed errors is first so that it is in the fast path.
|
||||
if !DetailedNewVersionErrors {
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
|
||||
// Check for specific errors with the semver string and return a more detailed
|
||||
// error.
|
||||
m = looseVersionRegex.FindStringSubmatch(v)
|
||||
if m == nil {
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
err := validateVersion(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
|
||||
@@ -156,13 +194,13 @@ func NewVersion(v string) (*Version, error) {
|
||||
var err error
|
||||
sv.major, err = strconv.ParseUint(m[1], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing version segment: %s", err)
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
|
||||
if m[2] != "" {
|
||||
sv.minor, err = strconv.ParseUint(m[2], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing version segment: %s", err)
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
} else {
|
||||
sv.minor = 0
|
||||
@@ -171,7 +209,61 @@ func NewVersion(v string) (*Version, error) {
|
||||
if m[3] != "" {
|
||||
sv.patch, err = strconv.ParseUint(m[3], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing version segment: %s", err)
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
} else {
|
||||
sv.patch = 0
|
||||
}
|
||||
|
||||
// Perform some basic due diligence on the extra parts to ensure they are
|
||||
// valid.
|
||||
|
||||
if sv.pre != "" {
|
||||
if err = validatePrerelease(sv.pre); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if sv.metadata != "" {
|
||||
if err = validateMetadata(sv.metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return sv, nil
|
||||
}
|
||||
|
||||
func coerceNewVersion(v string) (*Version, error) {
|
||||
m := looseVersionRegex.FindStringSubmatch(v)
|
||||
if m == nil {
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
|
||||
sv := &Version{
|
||||
metadata: m[8],
|
||||
pre: m[5],
|
||||
original: v,
|
||||
}
|
||||
|
||||
var err error
|
||||
sv.major, err = strconv.ParseUint(m[1], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
|
||||
if m[2] != "" {
|
||||
sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
} else {
|
||||
sv.minor = 0
|
||||
}
|
||||
|
||||
if m[3] != "" {
|
||||
sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
} else {
|
||||
sv.patch = 0
|
||||
@@ -615,7 +707,7 @@ func validatePrerelease(p string) error {
|
||||
eparts := strings.Split(p, ".")
|
||||
for _, p := range eparts {
|
||||
if p == "" {
|
||||
return ErrInvalidMetadata
|
||||
return ErrInvalidPrerelease
|
||||
} else if containsOnly(p, num) {
|
||||
if len(p) > 1 && p[0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
@@ -643,3 +735,54 @@ func validateMetadata(m string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateVersion checks for common validation issues but may not catch all errors
|
||||
func validateVersion(m []string) error {
|
||||
var err error
|
||||
var v string
|
||||
if m[1] != "" {
|
||||
if len(m[1]) > 1 && m[1][0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
}
|
||||
_, err = strconv.ParseUint(m[1], 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m[2] != "" {
|
||||
v = strings.TrimPrefix(m[2], ".")
|
||||
if len(v) > 1 && v[0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
}
|
||||
_, err = strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m[3] != "" {
|
||||
v = strings.TrimPrefix(m[3], ".")
|
||||
if len(v) > 1 && v[0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
}
|
||||
_, err = strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m[5] != "" {
|
||||
if err = validatePrerelease(m[5]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if m[8] != "" {
|
||||
if err = validateMetadata(m[8]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
12
vendor/github.com/Microsoft/hcsshim/.clang-format
generated
vendored
Normal file
12
vendor/github.com/Microsoft/hcsshim/.clang-format
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Language: Cpp
|
||||
BasedOnStyle: Microsoft
|
||||
BreakBeforeBraces: Attach
|
||||
PointerAlignment: Left
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
# match Go style
|
||||
IndentCaseLabels: false
|
||||
# don't break comments over line limit (needed for CodeQL exceptions)
|
||||
ReflowComments: false
|
||||
InsertNewlineAtEOF: true
|
||||
KeepEmptyLines:
|
||||
AtEndOfFile: true
|
||||
43
vendor/github.com/Microsoft/hcsshim/.golangci.yml
generated
vendored
43
vendor/github.com/Microsoft/hcsshim/.golangci.yml
generated
vendored
@@ -5,9 +5,6 @@ run:
|
||||
- admin
|
||||
- functional
|
||||
- integration
|
||||
skip-dirs:
|
||||
# paths are relative to module root
|
||||
- cri-containerd/test-images
|
||||
|
||||
linters:
|
||||
enable:
|
||||
@@ -34,13 +31,15 @@ linters-settings:
|
||||
# struct order is often for Win32 compat
|
||||
# also, ignore pointer bytes/GC issues for now until performance becomes an issue
|
||||
- fieldalignment
|
||||
check-shadowing: true
|
||||
|
||||
stylecheck:
|
||||
# https://staticcheck.io/docs/checks
|
||||
checks: ["all"]
|
||||
|
||||
issues:
|
||||
exclude-dirs:
|
||||
# paths are relative to module root
|
||||
- cri-containerd/test-images
|
||||
exclude-rules:
|
||||
# err is very often shadowed in nested scopes
|
||||
- linters:
|
||||
@@ -70,22 +69,22 @@ issues:
|
||||
- path: layer.go
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: hcsshim.go
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: cmd\\ncproxy\\nodenetsvc\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: cmd\\ncproxy_mock\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\hcs\\schema2\\
|
||||
linters:
|
||||
@@ -95,67 +94,67 @@ issues:
|
||||
- path: internal\\wclayer\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: hcn\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\hcs\\schema1\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\hns\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: ext4\\internal\\compactext4\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: ext4\\internal\\format\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\guestrequest\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\guest\\prot\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\windevice\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\winapi\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\vmcompute\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\regstate\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
- path: internal\\hcserror\\
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
# v0 APIs are deprecated, but still retained for backwards compatability
|
||||
- path: cmd\\ncproxy\\
|
||||
@@ -171,4 +170,4 @@ issues:
|
||||
- path: internal\\vhdx\\info
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
text: "ST1003:"
|
||||
|
||||
116
vendor/github.com/Microsoft/hcsshim/Makefile
generated
vendored
116
vendor/github.com/Microsoft/hcsshim/Makefile
generated
vendored
@@ -1,13 +1,20 @@
|
||||
BASE:=base.tar.gz
|
||||
DEV_BUILD:=0
|
||||
include Makefile.bootfiles
|
||||
|
||||
GO:=go
|
||||
GO_FLAGS:=-ldflags "-s -w" # strip Go binaries
|
||||
CGO_ENABLED:=0
|
||||
GOMODVENDOR:=
|
||||
KMOD:=0
|
||||
|
||||
CFLAGS:=-O2 -Wall
|
||||
LDFLAGS:=-static -s # strip C binaries
|
||||
LDFLAGS:=-static -s #strip C binaries
|
||||
LDLIBS:=
|
||||
PREPROCESSORFLAGS:=
|
||||
ifeq "$(KMOD)" "1"
|
||||
LDFLAGS:= -s
|
||||
LDLIBS:= -lkmod
|
||||
PREPROCESSORFLAGS:=-DMODULES=1
|
||||
endif
|
||||
|
||||
GO_FLAGS_EXTRA:=
|
||||
ifeq "$(GOMODVENDOR)" "1"
|
||||
@@ -23,108 +30,14 @@ SRCROOT=$(dir $(abspath $(firstword $(MAKEFILE_LIST))))
|
||||
# additional directories to search for rule prerequisites and targets
|
||||
VPATH=$(SRCROOT)
|
||||
|
||||
DELTA_TARGET=out/delta.tar.gz
|
||||
|
||||
ifeq "$(DEV_BUILD)" "1"
|
||||
DELTA_TARGET=out/delta-dev.tar.gz
|
||||
endif
|
||||
|
||||
ifeq "$(SNP_BUILD)" "1"
|
||||
DELTA_TARGET=out/delta-snp.tar.gz
|
||||
endif
|
||||
|
||||
# The link aliases for gcstools
|
||||
GCS_TOOLS=\
|
||||
generichook \
|
||||
install-drivers
|
||||
|
||||
# Common path prefix.
|
||||
PATH_PREFIX:=
|
||||
# These have PATH_PREFIX prepended to obtain the full path in recipies e.g. $(PATH_PREFIX)/$(VMGS_TOOL)
|
||||
VMGS_TOOL:=
|
||||
IGVM_TOOL:=
|
||||
KERNEL_PATH:=
|
||||
|
||||
.PHONY: all always rootfs test snp simple
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
all: out/initrd.img out/rootfs.tar.gz
|
||||
|
||||
clean:
|
||||
find -name '*.o' -print0 | xargs -0 -r rm
|
||||
rm -rf bin deps rootfs out
|
||||
|
||||
test:
|
||||
cd $(SRCROOT) && $(GO) test -v ./internal/guest/...
|
||||
|
||||
rootfs: out/rootfs.vhd
|
||||
|
||||
snp: out/kernelinitrd.vmgs out/rootfs.hash.vhd out/rootfs.vhd out/v2056.vmgs
|
||||
|
||||
simple: out/simple.vmgs snp
|
||||
|
||||
%.vmgs: %.bin
|
||||
rm -f $@
|
||||
# du -BM returns the size of the bin file in M, eg 7M. The sed command replaces the M with *1024*1024 and then bc does the math to convert to bytes
|
||||
$(PATH_PREFIX)/$(VMGS_TOOL) create --filepath $@ --filesize `du -BM $< | sed "s/M.*/*1024*1024/" | bc`
|
||||
$(PATH_PREFIX)/$(VMGS_TOOL) write --filepath $@ --datapath $< -i=8
|
||||
|
||||
# Simplest debug UVM used to test changes to the linux kernel. No dmverity protection. Boots an initramdisk rather than directly booting a vhd disk.
|
||||
out/simple.bin: out/initrd.img $(PATH_PREFIX)/$(KERNEL_PATH) boot/startup_simple.sh
|
||||
rm -f $@
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 rdinit=/startup_simple.sh" -rdinit out/initrd.img -vtl 0
|
||||
|
||||
ROOTFS_DEVICE:=/dev/sda
|
||||
VERITY_DEVICE:=/dev/sdb
|
||||
# Debug build for use with uvmtester. UVM with dm-verity protected vhd disk mounted directly via the kernel command line. Ignores corruption in dm-verity protected disk. (Use dmesg to see if dm-verity is ignoring data corruption.)
|
||||
out/v2056.bin: out/rootfs.vhd out/rootfs.hash.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup_v2056.sh
|
||||
rm -f $@
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(VERITY_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) 0 sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\" init=/startup_v2056.sh" -vtl 0
|
||||
|
||||
# Full UVM with dm-verity protected vhd disk mounted directly via the kernel command line.
|
||||
out/kernelinitrd.bin: out/rootfs.vhd out/rootfs.hash.vhd out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt $(PATH_PREFIX)/$(KERNEL_PATH) boot/startup.sh
|
||||
rm -f $@
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(VERITY_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) 0 sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt)\" init=/startup.sh" -vtl 0
|
||||
|
||||
# Rule to make a vhd from a file. This is used to create the rootfs.hash.vhd from rootfs.hash.
|
||||
%.vhd: % bin/cmd/tar2ext4
|
||||
./bin/cmd/tar2ext4 -only-vhd -i $< -o $@
|
||||
|
||||
# Rule to make a vhd from an ext4 file. This is used to create the rootfs.vhd from rootfs.ext4.
|
||||
%.vhd: %.ext4 bin/cmd/tar2ext4
|
||||
./bin/cmd/tar2ext4 -only-vhd -i $< -o $@
|
||||
|
||||
%.hash %.hash.info %.hash.datablocks %.hash.rootdigest %hash.datablocksize %.hash.datasectors %.hash.hashblocksize: %.ext4 %.hash.salt
|
||||
veritysetup format --no-superblock --salt $(shell cat out/rootfs.hash.salt) $< $*.hash > $*.hash.info
|
||||
# Retrieve info required by dm-verity at boot time
|
||||
# Get the blocksize of rootfs
|
||||
cat $*.hash.info | awk '/^Root hash:/{ print $$3 }' > $*.hash.rootdigest
|
||||
cat $*.hash.info | awk '/^Salt:/{ print $$2 }' > $*.hash.salt
|
||||
cat $*.hash.info | awk '/^Data block size:/{ print $$4 }' > $*.hash.datablocksize
|
||||
cat $*.hash.info | awk '/^Hash block size:/{ print $$4 }' > $*.hash.hashblocksize
|
||||
cat $*.hash.info | awk '/^Data blocks:/{ print $$3 }' > $*.hash.datablocks
|
||||
echo $$(( $$(cat $*.hash.datablocks) * $$(cat $*.hash.datablocksize) / 512 )) > $*.hash.datasectors
|
||||
|
||||
out/rootfs.hash.salt:
|
||||
hexdump -vn32 -e'8/4 "%08X" 1 "\n"' /dev/random > $@
|
||||
|
||||
out/rootfs.ext4: out/rootfs.tar.gz bin/cmd/tar2ext4
|
||||
gzip -f -d ./out/rootfs.tar.gz
|
||||
./bin/cmd/tar2ext4 -i ./out/rootfs.tar -o $@
|
||||
|
||||
out/rootfs.tar.gz: out/initrd.img
|
||||
rm -rf rootfs-conv
|
||||
mkdir rootfs-conv
|
||||
gunzip -c out/initrd.img | (cd rootfs-conv && cpio -imd)
|
||||
tar -zcf $@ -C rootfs-conv .
|
||||
rm -rf rootfs-conv
|
||||
|
||||
out/initrd.img: $(BASE) $(DELTA_TARGET) $(SRCROOT)/hack/catcpio.sh
|
||||
$(SRCROOT)/hack/catcpio.sh "$(BASE)" $(DELTA_TARGET) > out/initrd.img.uncompressed
|
||||
gzip -c out/initrd.img.uncompressed > $@
|
||||
rm out/initrd.img.uncompressed
|
||||
|
||||
# This target includes utilities which may be useful for testing purposes.
|
||||
out/delta-dev.tar.gz: out/delta.tar.gz bin/internal/tools/snp-report
|
||||
rm -rf rootfs-dev
|
||||
@@ -168,10 +81,7 @@ out/delta.tar.gz: bin/init bin/vsockexec bin/cmd/gcs bin/cmd/gcstools bin/cmd/ho
|
||||
tar -zcf $@ -C rootfs .
|
||||
rm -rf rootfs
|
||||
|
||||
out/containerd-shim-runhcs-v1.exe:
|
||||
GOOS=windows $(GO_BUILD) -o $@ $(SRCROOT)/cmd/containerd-shim-runhcs-v1
|
||||
|
||||
bin/cmd/gcs bin/cmd/gcstools bin/cmd/hooks/wait-paths bin/cmd/tar2ext4 bin/internal/tools/snp-report bin/cmd/dmverity-vhd:
|
||||
bin/cmd/gcs bin/cmd/gcstools bin/cmd/hooks/wait-paths bin/cmd/tar2ext4 bin/internal/tools/snp-report:
|
||||
@mkdir -p $(dir $@)
|
||||
GOOS=linux $(GO_BUILD) -o $@ $(SRCROOT)/$(@:bin/%=%)
|
||||
|
||||
@@ -181,8 +91,8 @@ bin/vsockexec: vsockexec/vsockexec.o vsockexec/vsock.o
|
||||
|
||||
bin/init: init/init.o vsockexec/vsock.o
|
||||
@mkdir -p bin
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
|
||||
%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
$(CC) $(PREPROCESSORFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
197
vendor/github.com/Microsoft/hcsshim/Makefile.bootfiles
generated
vendored
Normal file
197
vendor/github.com/Microsoft/hcsshim/Makefile.bootfiles
generated
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
BASE:=base.tar.gz
|
||||
DEV_BUILD:=0
|
||||
|
||||
DELTA_TARGET=out/delta.tar.gz
|
||||
|
||||
ifeq "$(DEV_BUILD)" "1"
|
||||
DELTA_TARGET=out/delta-dev.tar.gz
|
||||
endif
|
||||
|
||||
ifeq "$(SNP_BUILD)" "1"
|
||||
DELTA_TARGET=out/delta-snp.tar.gz
|
||||
endif
|
||||
|
||||
SRCROOT=$(dir $(abspath $(firstword $(MAKEFILE_LIST))))
|
||||
|
||||
PATH_PREFIX:=
|
||||
# These have PATH_PREFIX prepended to obtain the full path in recipies e.g. $(PATH_PREFIX)/$(VMGS_TOOL)
|
||||
VMGS_TOOL:=
|
||||
IGVM_TOOL:=
|
||||
KERNEL_PATH:=
|
||||
TAR2EXT4_TOOL:=bin/cmd/tar2ext4
|
||||
|
||||
ROOTFS_DEVICE:=/dev/sda
|
||||
HASH_DEVICE:=/dev/sdb
|
||||
|
||||
.PHONY: all always rootfs test snp simple
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
all: out/initrd.img out/rootfs.tar.gz
|
||||
|
||||
clean:
|
||||
find -name '*.o' -print0 | xargs -0 -r rm
|
||||
rm -rf bin rootfs out
|
||||
|
||||
rootfs: out/rootfs.vhd
|
||||
|
||||
snp: out/kernel.vmgs out/rootfs-verity.vhd out/v2056.vmgs out/v2056combined.vmgs
|
||||
|
||||
simple: out/simple.vmgs snp
|
||||
|
||||
%.vmgs: %.bin
|
||||
rm -f $@
|
||||
# du -BM returns the size of the bin file in M, eg 7M. The sed command replaces the M with *1024*1024 and then bc does the math to convert to bytes
|
||||
$(PATH_PREFIX)/$(VMGS_TOOL) create --filepath $@ --filesize `du -BM $< | sed "s/M.*/*1024*1024/" | bc`
|
||||
$(PATH_PREFIX)/$(VMGS_TOOL) write --filepath $@ --datapath $< -i=8
|
||||
|
||||
# Simplest debug UVM used to test changes to the linux kernel. No dmverity protection. Boots an initramdisk rather than directly booting a vhd disk.
|
||||
out/simple.bin: out/initrd.img $(PATH_PREFIX)/$(KERNEL_PATH) boot/startup_simple.sh
|
||||
rm -f $@
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) \
|
||||
-o $@ \
|
||||
-kernel $(PATH_PREFIX)/$(KERNEL_PATH) \
|
||||
-append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 rdinit=/startup_simple.sh" \
|
||||
-rdinit out/initrd.img \
|
||||
-vtl 0
|
||||
|
||||
# The boot performance is optimized by supplying rootfs as a SCSI attachment. In this case the kernel boots with
|
||||
# dm-verity to ensure the integrity. Similar to layer VHDs the verity Merkle tree is appended to ext4 filesystem.
|
||||
# It transpires that the /dev/sd* order is not deterministic wrt the scsi device order. Thus build a single userland
|
||||
# fs + merkle tree device and boot that.
|
||||
#
|
||||
# From https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-init.html
|
||||
#
|
||||
# dm-mod.create=<name>,<uuid>,<minor>,<flags>,<table>[,<table>+][;<name>,<uuid>,<minor>,<flags>,<table>[,<table>+]+]
|
||||
#
|
||||
# where:
|
||||
# <name> ::= The device name.
|
||||
# <uuid> ::= xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ""
|
||||
# <minor> ::= The device minor number | ""
|
||||
# <flags> ::= "ro" | "rw"
|
||||
# <table> ::= <start_sector> <num_sectors> <target_type> <target_args>
|
||||
# <target_type> ::= "verity" | "linear" | ... (see list below)
|
||||
#
|
||||
# From https://docs.kernel.org/admin-guide/device-mapper/verity.html
|
||||
# <version> <dev> <hash_dev>
|
||||
# <data_block_size> <hash_block_size>
|
||||
# <num_data_blocks> <hash_start_block>
|
||||
# <algorithm> <digest> <salt>
|
||||
# [<#opt_params> <opt_params>]
|
||||
#
|
||||
# typical igvm tool line once all the macros are expanded
|
||||
# python3 /home/user/igvmfile.py -o out/v2056.bin -kernel /hose/user/bzImage -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=9 ignore_loglevel dev.scsi.logging_level=9411 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 196744 verity 1 /dev/sda /dev/sdb 4096 4096 24593 0 sha256 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba 1 ignore_corruption\" init=/startup_v2056.sh" -vtl 0
|
||||
#
|
||||
# so a kernel command line of:
|
||||
# 8250_core.nr_uarts=0 panic=-1 debug loglevel=9 ignore_loglevel dev.scsi.logging_level=9411 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 196744 verity 1 /dev/sda /dev/sdb 4096 4096 24593 0 sha256 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba 1 ignore_corruption\" init=/startup_v2056.sh
|
||||
#
|
||||
# and a dm-mod.create of:
|
||||
# dmverity,,,ro,0 196744 verity 1 /dev/sda /dev/sdb 4096 4096 24593 0 sha256 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba 1 ignore_corruption
|
||||
#
|
||||
# which breaks down to:
|
||||
#
|
||||
# name = "dmverity"
|
||||
# uuid = ""
|
||||
# minor = ""
|
||||
# flags = "ro"
|
||||
# table = 0 196744 verity "args"
|
||||
# start_sector = 0
|
||||
# num_sectors = 196744
|
||||
# target_type = verity
|
||||
# target_args = 1 /dev/sda /dev/sdb 4096 4096 24593 0 sha256 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba 1 ignore_corruption
|
||||
# args:
|
||||
# version 1
|
||||
# dev /dev/sda
|
||||
# hash_dev /dev/sdb
|
||||
# data_block_size 4096
|
||||
# hash_block_size 4096
|
||||
# num_data_blocks 24593
|
||||
# hash_start_block 0
|
||||
# algorithm sha256
|
||||
# digest 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66
|
||||
# salt b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba
|
||||
# opt_params
|
||||
# count = 1
|
||||
# ignore_corruption
|
||||
#
|
||||
# combined typical (not bigger count of sectors for the whole device)
|
||||
# dmverity,,,ro,0 199672 verity 1 /dev/sda /dev/sda 4096 4096 24959 24959 sha256 4aa6e79866ee946ddbd9cddd6554bc6449272942fcc65934326817785a3bd374 adc4956274489c936395bab046a2d476f21ef436e571ba53da2fdf3aee59bf0a
|
||||
#
|
||||
# A few notes:
|
||||
# - num_sectors is the size of the final (aka target) verity device, i.e. the size of our rootfs excluding the Merkle
|
||||
# tree.
|
||||
# - We don't add verity superblock, so the <hash_start_block> will be exactly at the end of ext4 filesystem and equal
|
||||
# to its size. In the case when verity superblock is present an extra block should be added to the offset value,
|
||||
# i.e. 24959 becomes 24960.
|
||||
|
||||
|
||||
# Debug build for use with uvmtester. UVM with dm-verity protected vhd disk mounted directly via the kernel command line.
|
||||
# Ignores corruption in dm-verity protected disk. (Use dmesg to see if dm-verity is ignoring data corruption.)
|
||||
out/v2056.bin: out/rootfs.vhd out/rootfs.hash.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup_v2056.sh
|
||||
rm -f $@
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) \
|
||||
-o $@ \
|
||||
-kernel $(PATH_PREFIX)/$(KERNEL_PATH) \
|
||||
-append "8250_core.nr_uarts=0 panic=-1 debug loglevel=9 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(HASH_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\" init=/startup_v2056.sh" \
|
||||
-vtl 0
|
||||
|
||||
out/v2056combined.bin: out/rootfs-verity.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup_v2056.sh
|
||||
rm -f $@
|
||||
echo root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(ROOTFS_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\"
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) \
|
||||
-o $@ \
|
||||
-kernel $(PATH_PREFIX)/$(KERNEL_PATH) \
|
||||
-append "8250_core.nr_uarts=0 panic=-1 debug loglevel=9 ignore_loglevel dev.scsi.logging_level=9411 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(ROOTFS_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\" init=/startup_v2056.sh" \
|
||||
-vtl 0
|
||||
|
||||
# Full UVM with dm-verity protected vhd disk mounted directly via the kernel command line.
|
||||
out/kernel.bin: out/rootfs-verity.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup.sh
|
||||
rm -f $@
|
||||
echo root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(ROOTFS_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt)\"
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) \
|
||||
-o $@ \
|
||||
-kernel $(PATH_PREFIX)/$(KERNEL_PATH) \
|
||||
-append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(ROOTFS_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt)\" init=/startup.sh" \
|
||||
-vtl 0
|
||||
|
||||
# Rule to make a vhd from a file. This is used to create the rootfs.hash.vhd from rootfs.hash.
|
||||
%.vhd: % $(TAR2EXT4_TOOL)
|
||||
$(TAR2EXT4_TOOL) -only-vhd -i $< -o $@
|
||||
|
||||
# Rule to make a vhd from an ext4 file. This is used to create the rootfs.vhd from rootfs.ext4.
|
||||
%.vhd: %.ext4 $(TAR2EXT4_TOOL)
|
||||
$(TAR2EXT4_TOOL) -only-vhd -i $< -o $@
|
||||
|
||||
%.hash %.hash.info %.hash.datablocks %.hash.rootdigest %hash.datablocksize %.hash.datasectors %.hash.hashblocksize: %.ext4 %.hash.salt
|
||||
veritysetup format --no-superblock --salt $(shell cat out/rootfs.hash.salt) $< $*.hash > $*.hash.info
|
||||
# Retrieve info required by dm-verity at boot time
|
||||
# Get the blocksize of rootfs
|
||||
cat $*.hash.info | awk '/^Root hash:/{ print $$3 }' > $*.hash.rootdigest
|
||||
cat $*.hash.info | awk '/^Salt:/{ print $$2 }' > $*.hash.salt
|
||||
cat $*.hash.info | awk '/^Data block size:/{ print $$4 }' > $*.hash.datablocksize
|
||||
cat $*.hash.info | awk '/^Hash block size:/{ print $$4 }' > $*.hash.hashblocksize
|
||||
cat $*.hash.info | awk '/^Data blocks:/{ print $$3 }' > $*.hash.datablocks
|
||||
echo $$(( $$(cat $*.hash.datablocks) * $$(cat $*.hash.datablocksize) / 512 )) > $*.hash.datasectors
|
||||
|
||||
out/rootfs.hash.salt:
|
||||
hexdump -vn32 -e'8/4 "%08X" 1 "\n"' /dev/random > $@
|
||||
|
||||
out/rootfs.ext4: out/rootfs.tar.gz $(TAR2EXT4_TOOL)
|
||||
gzip -f -d ./out/rootfs.tar.gz
|
||||
$(TAR2EXT4_TOOL) -i ./out/rootfs.tar -o $@
|
||||
|
||||
out/rootfs-verity.ext4: out/rootfs.ext4 out/rootfs.hash
|
||||
cp out/rootfs.ext4 $@
|
||||
cat out/rootfs.hash >> $@
|
||||
|
||||
out/rootfs.tar.gz: out/initrd.img
|
||||
rm -rf rootfs-conv
|
||||
mkdir rootfs-conv
|
||||
gunzip -c out/initrd.img | (cd rootfs-conv && cpio -imd)
|
||||
tar -zcf $@ -C rootfs-conv .
|
||||
rm -rf rootfs-conv
|
||||
|
||||
out/initrd.img: $(BASE) $(DELTA_TARGET) $(SRCROOT)/hack/catcpio.sh
|
||||
$(SRCROOT)/hack/catcpio.sh "$(BASE)" $(DELTA_TARGET) > out/initrd.img.uncompressed
|
||||
gzip -c out/initrd.img.uncompressed > $@
|
||||
rm out/initrd.img.uncompressed
|
||||
2
vendor/github.com/Microsoft/hcsshim/README.md
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/README.md
generated
vendored
@@ -44,7 +44,7 @@ delta.tar.gz initrd.img rootfs.tar.gz
|
||||
|
||||
### Containerd Shim
|
||||
|
||||
For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/master/runtime/v2/README.md).
|
||||
For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md).
|
||||
|
||||
Contrary to the typical Linux architecture of shim -> runc, the runhcs shim is used both to launch and manage the lifetime of containers.
|
||||
|
||||
|
||||
9
vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
generated
vendored
9
vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
generated
vendored
@@ -63,10 +63,10 @@ func (process *Process) SystemID() string {
|
||||
}
|
||||
|
||||
func (process *Process) processSignalResult(ctx context.Context, err error) (bool, error) {
|
||||
switch err { //nolint:errorlint
|
||||
case nil:
|
||||
if err == nil {
|
||||
return true, nil
|
||||
case ErrVmcomputeOperationInvalidState, ErrComputeSystemDoesNotExist, ErrElementNotFound:
|
||||
}
|
||||
if errors.Is(err, ErrVmcomputeOperationInvalidState) || errors.Is(err, ErrComputeSystemDoesNotExist) || errors.Is(err, ErrElementNotFound) {
|
||||
if !process.stopped() {
|
||||
// The process should be gone, but we have not received the notification.
|
||||
// After a second, force unblock the process wait to work around a possible
|
||||
@@ -82,9 +82,8 @@ func (process *Process) processSignalResult(ctx context.Context, err error) (boo
|
||||
}()
|
||||
}
|
||||
return false, nil
|
||||
default:
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Signal signals the process with `options`.
|
||||
|
||||
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/chipset.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/chipset.go
generated
vendored
@@ -24,4 +24,6 @@ type Chipset struct {
|
||||
|
||||
// LinuxKernelDirect - Added in v2.2 Builds >=181117
|
||||
LinuxKernelDirect *LinuxKernelDirect `json:"LinuxKernelDirect,omitempty"`
|
||||
|
||||
FirmwareFile *FirmwareFile `json:"FirmwareFile,omitempty"`
|
||||
}
|
||||
|
||||
@@ -9,14 +9,6 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
const (
|
||||
CimMountFlagNone uint32 = 0x0
|
||||
CimMountFlagChildOnly uint32 = 0x1
|
||||
CimMountFlagEnableDax uint32 = 0x2
|
||||
CimMountFlagCacheFiles uint32 = 0x4
|
||||
CimMountFlagCacheRegions uint32 = 0x8
|
||||
)
|
||||
|
||||
type CimMount struct {
|
||||
ImagePath string `json:"ImagePath,omitempty"`
|
||||
FileSystemName string `json:"FileSystemName,omitempty"`
|
||||
8
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/firmware.go
generated
vendored
Normal file
8
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/firmware.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
package hcsschema
|
||||
|
||||
type FirmwareFile struct {
|
||||
// Parameters is an experimental/pre-release field. The field itself or its
|
||||
// behavior can change in future iterations of the schema. Avoid taking a hard
|
||||
// dependency on this field.
|
||||
Parameters []byte `json:"Parameters,omitempty"`
|
||||
}
|
||||
49
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_2.go
generated
vendored
49
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_2.go
generated
vendored
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.1
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type Memory2 struct {
|
||||
SizeInMB uint64 `json:"SizeInMB,omitempty"`
|
||||
|
||||
AllowOvercommit bool `json:"AllowOvercommit,omitempty"`
|
||||
|
||||
EnableHotHint bool `json:"EnableHotHint,omitempty"`
|
||||
|
||||
EnableColdHint bool `json:"EnableColdHint,omitempty"`
|
||||
|
||||
EnableEpf bool `json:"EnableEpf,omitempty"`
|
||||
|
||||
// EnableDeferredCommit is private in the schema. If regenerated need to add back.
|
||||
EnableDeferredCommit bool `json:"EnableDeferredCommit,omitempty"`
|
||||
|
||||
// EnableColdDiscardHint if enabled, then the memory cold discard hint feature is exposed
|
||||
// to the VM, allowing it to trim non-zeroed pages from the working set (if supported by
|
||||
// the guest operating system).
|
||||
EnableColdDiscardHint bool `json:"EnableColdDiscardHint,omitempty"`
|
||||
|
||||
// LowMmioGapInMB is the low MMIO region allocated below 4GB.
|
||||
//
|
||||
// TODO: This is pre-release support in schema 2.3. Need to add build number
|
||||
// docs when a public build with this is out.
|
||||
LowMMIOGapInMB uint64 `json:"LowMmioGapInMB,omitempty"`
|
||||
|
||||
// HighMmioBaseInMB is the high MMIO region allocated above 4GB (base and
|
||||
// size).
|
||||
//
|
||||
// TODO: This is pre-release support in schema 2.3. Need to add build number
|
||||
// docs when a public build with this is out.
|
||||
HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"`
|
||||
|
||||
// HighMmioGapInMB is the high MMIO region.
|
||||
//
|
||||
// TODO: This is pre-release support in schema 2.3. Need to add build number
|
||||
// docs when a public build with this is out.
|
||||
HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"`
|
||||
}
|
||||
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_backing_type.go
generated
vendored
Normal file
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_backing_type.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swaggerapi/swaggercodegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swaggerapi/swaggercodegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type MemoryBackingType string
|
||||
|
||||
// List of MemoryBackingType
|
||||
const (
|
||||
MemoryBackingType_PHYSICAL MemoryBackingType = "Physical"
|
||||
MemoryBackingType_VIRTUAL MemoryBackingType = "Virtual"
|
||||
MemoryBackingType_HYBRID MemoryBackingType = "Hybrid"
|
||||
)
|
||||
19
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa.go
generated
vendored
Normal file
19
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type Numa struct {
|
||||
VirtualNodeCount uint8 `json:"VirtualNodeCount,omitempty"`
|
||||
PreferredPhysicalNodes []int64 `json:"PreferredPhysicalNodes,omitempty"`
|
||||
Settings []NumaSetting `json:"Settings,omitempty"`
|
||||
MaxSizePerNode uint64 `json:"MaxSizePerNode,omitempty"`
|
||||
}
|
||||
17
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node.go
generated
vendored
Normal file
17
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type NumaNode struct {
|
||||
VirtualNodeIndex uint32 `json:"VirtualNodeIndex,omitempty"`
|
||||
PhysicalNodeIndex uint32 `json:"PhysicalNodeIndex,omitempty"`
|
||||
}
|
||||
19
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_memory.go
generated
vendored
Normal file
19
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_memory.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type NumaNodeMemory struct {
|
||||
// Total physical memory on on this physical NUMA node that is consumable by the VMs.
|
||||
TotalConsumableMemoryInPages uint64 `json:"TotalConsumableMemoryInPages,omitempty"`
|
||||
// Currently available physical memory on this physical NUMA node for the VMs.
|
||||
AvailableMemoryInPages uint64 `json:"AvailableMemoryInPages,omitempty"`
|
||||
}
|
||||
17
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_processor.go
generated
vendored
Normal file
17
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_processor.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type NumaNodeProcessor struct {
|
||||
TotalAssignedProcessors uint32 `json:"TotalAssignedProcessors,omitempty"`
|
||||
TotalAvailableProcessors uint32 `json:"TotalAvailableProcessors,omitempty"`
|
||||
}
|
||||
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_processors.go
generated
vendored
Normal file
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_processors.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type NumaProcessors struct {
|
||||
CountPerNode Range `json:"count_per_node,omitempty"`
|
||||
NodePerSocket uint32 `json:"node_per_socket,omitempty"`
|
||||
}
|
||||
|
||||
type Range struct {
|
||||
Max uint32 `json:"max,omitempty"`
|
||||
}
|
||||
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go
generated
vendored
Normal file
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type NumaSetting struct {
|
||||
VirtualNodeNumber uint32 `json:"VirtualNodeNumber,omitempty"`
|
||||
PhysicalNodeNumber uint32 `json:"PhysicalNodeNumber,omitempty"`
|
||||
VirtualSocketNumber uint32 `json:"VirtualSocketNumber,omitempty"`
|
||||
CountOfProcessors uint32 `json:"CountOfProcessors,omitempty"`
|
||||
CountOfMemoryBlocks uint64 `json:"CountOfMemoryBlocks,omitempty"`
|
||||
MemoryBackingType MemoryBackingType `json:"MemoryBackingType,omitempty"`
|
||||
}
|
||||
23
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_2.go
generated
vendored
23
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_2.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.5
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type Processor2 struct {
|
||||
Count int32 `json:"Count,omitempty"`
|
||||
|
||||
Limit int32 `json:"Limit,omitempty"`
|
||||
|
||||
Weight int32 `json:"Weight,omitempty"`
|
||||
|
||||
ExposeVirtualizationExtensions bool `json:"ExposeVirtualizationExtensions,omitempty"`
|
||||
|
||||
// An optional object that configures the CPU Group to which a Virtual Machine is going to bind to.
|
||||
CpuGroup *CpuGroup `json:"CpuGroup,omitempty"`
|
||||
}
|
||||
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go
generated
vendored
@@ -26,6 +26,8 @@ type Properties struct {
|
||||
|
||||
RuntimeId string `json:"RuntimeId,omitempty"`
|
||||
|
||||
SystemGUID string `json:"SystemGUID,omitempty"`
|
||||
|
||||
RuntimeTemplateId string `json:"RuntimeTemplateId,omitempty"`
|
||||
|
||||
State string `json:"State,omitempty"`
|
||||
|
||||
1
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_type.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_type.go
generated
vendored
@@ -23,4 +23,5 @@ const (
|
||||
PTICHeartbeatStatus PropertyType = "ICHeartbeatStatus"
|
||||
PTProcessorTopology PropertyType = "ProcessorTopology"
|
||||
PTCPUGroup PropertyType = "CpuGroup"
|
||||
PTSystemGUID PropertyType = "SystemGUID"
|
||||
)
|
||||
|
||||
12
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go
generated
vendored
12
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go
generated
vendored
@@ -1,16 +1,18 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* HCS API
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.1
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type Topology struct {
|
||||
Memory *Memory2 `json:"Memory,omitempty"`
|
||||
|
||||
Processor *Processor2 `json:"Processor,omitempty"`
|
||||
Memory *VirtualMachineMemory `json:"Memory,omitempty"`
|
||||
Processor *VirtualMachineProcessor `json:"Processor,omitempty"`
|
||||
Numa *Numa `json:"Numa,omitempty"`
|
||||
}
|
||||
|
||||
39
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go
generated
vendored
39
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go
generated
vendored
@@ -1,36 +1,29 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* HCS API
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.1
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Configuration of a virtual machine, used during its creation to set up and/or use resources.
|
||||
type VirtualMachine struct {
|
||||
|
||||
// StopOnReset is private in the schema. If regenerated need to put back.
|
||||
StopOnReset bool `json:"StopOnReset,omitempty"`
|
||||
|
||||
Chipset *Chipset `json:"Chipset,omitempty"`
|
||||
|
||||
ComputeTopology *Topology `json:"ComputeTopology,omitempty"`
|
||||
|
||||
Devices *Devices `json:"Devices,omitempty"`
|
||||
|
||||
GuestState *GuestState `json:"GuestState,omitempty"`
|
||||
|
||||
RestoreState *RestoreState `json:"RestoreState,omitempty"`
|
||||
|
||||
Version *Version `json:"Version,omitempty"`
|
||||
// When set to true, the virtual machine will treat a reset as a stop, releasing resources and cleaning up state.
|
||||
StopOnReset bool `json:"StopOnReset,omitempty"`
|
||||
Chipset *Chipset `json:"Chipset,omitempty"`
|
||||
ComputeTopology *Topology `json:"ComputeTopology,omitempty"`
|
||||
Devices *Devices `json:"Devices,omitempty"`
|
||||
GuestState *GuestState `json:"GuestState,omitempty"`
|
||||
RestoreState *RestoreState `json:"RestoreState,omitempty"`
|
||||
RegistryChanges *RegistryChanges `json:"RegistryChanges,omitempty"`
|
||||
|
||||
StorageQoS *StorageQoS `json:"StorageQoS,omitempty"`
|
||||
|
||||
StorageQoS *StorageQoS `json:"StorageQoS,omitempty"`
|
||||
DebugOptions *DebugOptions `json:"DebugOptions,omitempty"`
|
||||
GuestConnection *GuestConnection `json:"GuestConnection,omitempty"`
|
||||
|
||||
SecuritySettings *SecuritySettings `json:"SecuritySettings,omitempty"`
|
||||
|
||||
DebugOptions *DebugOptions `json:"DebugOptions,omitempty"`
|
||||
SecuritySettings *SecuritySettings `json:"SecuritySettings,omitempty"`
|
||||
}
|
||||
|
||||
33
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go
generated
vendored
Normal file
33
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type VirtualMachineMemory struct {
|
||||
SizeInMB uint64 `json:"SizeInMB,omitempty"`
|
||||
Backing *MemoryBackingType `json:"Backing,omitempty"`
|
||||
// If enabled, then the VM's memory is backed by the Windows pagefile rather than physically backed, statically allocated memory.
|
||||
AllowOvercommit bool `json:"AllowOvercommit,omitempty"`
|
||||
// If enabled, then the memory hot hint feature is exposed to the VM, allowing it to prefetch pages into its working set. (if supported by the guest operating system).
|
||||
EnableHotHint bool `json:"EnableHotHint,omitempty"`
|
||||
// If enabled, then the memory cold hint feature is exposed to the VM, allowing it to trim zeroed pages from its working set (if supported by the guest operating system).
|
||||
EnableColdHint bool `json:"EnableColdHint,omitempty"`
|
||||
// If enabled, then the memory cold discard hint feature is exposed to the VM, allowing it to trim non-zeroed pages from the working set (if supported by the guest operating system).
|
||||
EnableColdDiscardHint bool `json:"EnableColdDiscardHint,omitempty"`
|
||||
// If enabled, then commit is not charged for each backing page until first access.
|
||||
EnableDeferredCommit bool `json:"EnableDeferredCommit,omitempty"`
|
||||
// Low MMIO region allocated below 4GB
|
||||
LowMMIOGapInMB uint64 `json:"LowMmioGapInMB,omitempty"`
|
||||
// High MMIO region allocated above 4GB (base and size)
|
||||
HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"`
|
||||
HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"`
|
||||
SlitType *VirtualSlitType `json:"SlitType,omitempty"`
|
||||
}
|
||||
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go
generated
vendored
Normal file
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type VirtualMachineProcessor struct {
|
||||
Count uint32 `json:"Count,omitempty"`
|
||||
Limit uint64 `json:"Limit,omitempty"`
|
||||
Weight uint64 `json:"Weight,omitempty"`
|
||||
Reservation uint64 `json:"Reservation,omitempty"`
|
||||
CpuGroup *CpuGroup `json:"CpuGroup,omitempty"`
|
||||
NumaProcessorsSettings *NumaProcessors `json:"NumaProcessorsSettings,omitempty"`
|
||||
}
|
||||
3
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go
generated
vendored
3
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go
generated
vendored
@@ -9,8 +9,9 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// TODO: This is pre-release support in schema 2.3. Need to add build number
|
||||
// TODO: PropagateNumaAffinity is pre-release/experimental field in schema 2.11. Need to add build number
|
||||
// docs when a public build with this is out.
|
||||
type VirtualPciDevice struct {
|
||||
Functions []VirtualPciFunction `json:",omitempty"`
|
||||
PropagateNumaAffinity *bool `json:"PropagateNumaAffinity,omitempty"`
|
||||
}
|
||||
|
||||
23
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_slit_type.go
generated
vendored
Normal file
23
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_slit_type.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Autogenerated code; DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Schema Open API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
// VirtualSlitType : Indicates if a virtual SLIT should ne enabled for a VM and the type of virtual SLIT to be enabled.
|
||||
type VirtualSlitType string
|
||||
|
||||
// List of VirtualSlitType
|
||||
const (
|
||||
VirtualSlitType_NONE VirtualSlitType = "None"
|
||||
VirtualSlitType_FIRMWARE VirtualSlitType = "Firmware"
|
||||
VirtualSlitType_MEASURED VirtualSlitType = "Measured"
|
||||
VirtualSlitType_FIRMWARE_FALLBACK_MEASURED VirtualSlitType = "FirmwareFallbackMeasured"
|
||||
)
|
||||
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/windows_crash_reporting.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/windows_crash_reporting.go
generated
vendored
@@ -13,4 +13,6 @@ type WindowsCrashReporting struct {
|
||||
DumpFileName string `json:"DumpFileName,omitempty"`
|
||||
|
||||
MaxDumpSize int64 `json:"MaxDumpSize,omitempty"`
|
||||
|
||||
DumpType string `json:"DumpType,omitempty"`
|
||||
}
|
||||
|
||||
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
generated
vendored
21
vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
generated
vendored
@@ -238,9 +238,10 @@ func (computeSystem *System) Shutdown(ctx context.Context) error {
|
||||
|
||||
resultJSON, err := vmcompute.HcsShutdownComputeSystem(ctx, computeSystem.handle, "")
|
||||
events := processHcsResult(ctx, resultJSON)
|
||||
switch err { //nolint:errorlint
|
||||
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending:
|
||||
default:
|
||||
if err != nil &&
|
||||
!errors.Is(err, ErrVmcomputeAlreadyStopped) &&
|
||||
!errors.Is(err, ErrComputeSystemDoesNotExist) &&
|
||||
!errors.Is(err, ErrVmcomputeOperationPending) {
|
||||
return makeSystemError(computeSystem, operation, err, events)
|
||||
}
|
||||
return nil
|
||||
@@ -259,9 +260,10 @@ func (computeSystem *System) Terminate(ctx context.Context) error {
|
||||
|
||||
resultJSON, err := vmcompute.HcsTerminateComputeSystem(ctx, computeSystem.handle, "")
|
||||
events := processHcsResult(ctx, resultJSON)
|
||||
switch err { //nolint:errorlint
|
||||
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending:
|
||||
default:
|
||||
if err != nil &&
|
||||
!errors.Is(err, ErrVmcomputeAlreadyStopped) &&
|
||||
!errors.Is(err, ErrComputeSystemDoesNotExist) &&
|
||||
!errors.Is(err, ErrVmcomputeOperationPending) {
|
||||
return makeSystemError(computeSystem, operation, err, events)
|
||||
}
|
||||
return nil
|
||||
@@ -279,14 +281,13 @@ func (computeSystem *System) waitBackground() {
|
||||
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
|
||||
|
||||
err := waitForNotification(ctx, computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
|
||||
switch err { //nolint:errorlint
|
||||
case nil:
|
||||
if err == nil {
|
||||
log.G(ctx).Debug("system exited")
|
||||
case ErrVmcomputeUnexpectedExit:
|
||||
} else if errors.Is(err, ErrVmcomputeUnexpectedExit) {
|
||||
log.G(ctx).Debug("unexpected system exit")
|
||||
computeSystem.exitError = makeSystemError(computeSystem, operation, err, nil)
|
||||
err = nil
|
||||
default:
|
||||
} else {
|
||||
err = makeSystemError(computeSystem, operation, err, nil)
|
||||
}
|
||||
computeSystem.closedWaitOnce.Do(func() {
|
||||
|
||||
4
vendor/github.com/Microsoft/hcsshim/internal/hns/hnsaccelnet.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/hns/hnsaccelnet.go
generated
vendored
@@ -47,7 +47,7 @@ func (nnvManagementMacList *HNSNnvManagementMacList) Set() (*HNSNnvManagementMac
|
||||
func GetNnvManagementMacAddressList() (*HNSNnvManagementMacList, error) {
|
||||
operation := "Get"
|
||||
title := "hcsshim::nnvManagementMacList::" + operation
|
||||
logrus.Debugf(title)
|
||||
logrus.Debug(title)
|
||||
return HNSNnvManagementMacRequest("GET", "", "")
|
||||
}
|
||||
|
||||
@@ -55,6 +55,6 @@ func GetNnvManagementMacAddressList() (*HNSNnvManagementMacList, error) {
|
||||
func DeleteNnvManagementMacAddressList() (*HNSNnvManagementMacList, error) {
|
||||
operation := "Delete"
|
||||
title := "hcsshim::nnvManagementMacList::" + operation
|
||||
logrus.Debugf(title)
|
||||
logrus.Debug(title)
|
||||
return HNSNnvManagementMacRequest("DELETE", "", "")
|
||||
}
|
||||
|
||||
20
vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go
generated
vendored
20
vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go
generated
vendored
@@ -22,9 +22,8 @@ import (
|
||||
// of the job and a mutex for synchronized handle access.
|
||||
type JobObject struct {
|
||||
handle windows.Handle
|
||||
// All accesses to this MUST be done atomically except in `Open` as the object
|
||||
// is being created in the function. 1 signifies that this job is currently a silo.
|
||||
silo uint32
|
||||
// silo signifies that this job is currently a silo.
|
||||
silo atomic.Bool
|
||||
mq *queue.MessageQueue
|
||||
handleLock sync.RWMutex
|
||||
}
|
||||
@@ -204,9 +203,7 @@ func Open(ctx context.Context, options *Options) (_ *JobObject, err error) {
|
||||
handle: jobHandle,
|
||||
}
|
||||
|
||||
if isJobSilo(jobHandle) {
|
||||
job.silo = 1
|
||||
}
|
||||
job.silo.Store(isJobSilo(jobHandle))
|
||||
|
||||
// If the IOCP we'll be using to receive messages for all jobs hasn't been
|
||||
// created, create it and start polling.
|
||||
@@ -479,7 +476,7 @@ func (job *JobObject) ApplyFileBinding(root, target string, readOnly bool) error
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
|
||||
if !job.isSilo() {
|
||||
if !job.silo.Load() {
|
||||
return ErrNotSilo
|
||||
}
|
||||
|
||||
@@ -546,7 +543,7 @@ func (job *JobObject) PromoteToSilo() error {
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
|
||||
if job.isSilo() {
|
||||
if job.silo.Load() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -569,15 +566,10 @@ func (job *JobObject) PromoteToSilo() error {
|
||||
return fmt.Errorf("failed to promote job to silo: %w", err)
|
||||
}
|
||||
|
||||
atomic.StoreUint32(&job.silo, 1)
|
||||
job.silo.Store(true)
|
||||
return nil
|
||||
}
|
||||
|
||||
// isSilo returns if the job object is a silo.
|
||||
func (job *JobObject) isSilo() bool {
|
||||
return atomic.LoadUint32(&job.silo) == 1
|
||||
}
|
||||
|
||||
// QueryPrivateWorkingSet returns the private working set size for the job. This is calculated by adding up the
|
||||
// private working set for every process running in the job.
|
||||
func (job *JobObject) QueryPrivateWorkingSet() (uint64, error) {
|
||||
|
||||
1
vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go
generated
vendored
@@ -150,6 +150,7 @@ func (job *JobObject) SetCPUAffinity(affinityBitMask uint64) error {
|
||||
return fmt.Errorf("affinity bitmask (%d) exceeds max allowable value (%d)", affinityBitMask, maxUintptr)
|
||||
}
|
||||
|
||||
// CodeQL [SM03681] checked against max value above (there is no math.MaxUintPtr ...)
|
||||
info.BasicLimitInformation.Affinity = uintptr(affinityBitMask)
|
||||
return job.setExtendedInformation(info)
|
||||
}
|
||||
|
||||
28
vendor/github.com/Microsoft/hcsshim/internal/log/context.go
generated
vendored
28
vendor/github.com/Microsoft/hcsshim/internal/log/context.go
generated
vendored
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
type entryContextKeyType int
|
||||
@@ -20,13 +19,13 @@ var (
|
||||
// Instead, use `L.With*` or `L.Dup()`. Or `G(context.Background())`.
|
||||
L = logrus.NewEntry(logrus.StandardLogger())
|
||||
|
||||
// G is an alias for GetEntry
|
||||
// G is an alias for GetEntry.
|
||||
G = GetEntry
|
||||
|
||||
// S is an alias for SetEntry
|
||||
// S is an alias for SetEntry.
|
||||
S = SetEntry
|
||||
|
||||
// U is an alias for UpdateContext
|
||||
// U is an alias for UpdateContext.
|
||||
U = UpdateContext
|
||||
)
|
||||
|
||||
@@ -83,7 +82,7 @@ func UpdateContext(ctx context.Context) context.Context {
|
||||
// WithContext returns a context that contains the provided log entry.
|
||||
// The entry can be extracted with `GetEntry` (`G`)
|
||||
//
|
||||
// The entry in the context is a copy of `entry` (generated by `entry.WithContext`)
|
||||
// The entry in the context is a copy of `entry` (generated by `entry.WithContext`).
|
||||
func WithContext(ctx context.Context, entry *logrus.Entry) (context.Context, *logrus.Entry) {
|
||||
// regardless of the order, entry.Context != GetEntry(ctx)
|
||||
// here, the returned entry will reference the supplied context
|
||||
@@ -93,25 +92,6 @@ func WithContext(ctx context.Context, entry *logrus.Entry) (context.Context, *lo
|
||||
return ctx, entry
|
||||
}
|
||||
|
||||
// Copy extracts the tracing Span and logging entry from the src Context, if they
|
||||
// exist, and adds them to the dst Context.
|
||||
//
|
||||
// This is useful to share tracing and logging between contexts, but not the
|
||||
// cancellation. For example, if the src Context has been cancelled but cleanup
|
||||
// operations triggered by the cancellation require a non-cancelled context to
|
||||
// execute.
|
||||
func Copy(dst context.Context, src context.Context) context.Context {
|
||||
if s := trace.FromContext(src); s != nil {
|
||||
dst = trace.NewContext(dst, s)
|
||||
}
|
||||
|
||||
if e := fromContext(src); e != nil {
|
||||
dst, _ = WithContext(dst, e)
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
func fromContext(ctx context.Context) *logrus.Entry {
|
||||
e, _ := ctx.Value(_entryContextKey).(*logrus.Entry)
|
||||
return e
|
||||
|
||||
4
vendor/github.com/Microsoft/hcsshim/internal/log/format.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/log/format.go
generated
vendored
@@ -103,9 +103,7 @@ func encode(v interface{}) (_ []byte, err error) {
|
||||
|
||||
if jErr := enc.Encode(v); jErr != nil {
|
||||
if err != nil {
|
||||
// TODO (go1.20): use multierror via fmt.Errorf("...: %w; ...: %w", ...)
|
||||
//nolint:errorlint // non-wrapping format verb for fmt.Errorf
|
||||
return nil, fmt.Errorf("protojson encoding: %v; json encoding: %w", err, jErr)
|
||||
return nil, fmt.Errorf("protojson encoding: %w; json encoding: %w", err, jErr)
|
||||
}
|
||||
return nil, fmt.Errorf("json encoding: %w", jErr)
|
||||
}
|
||||
|
||||
15
vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go
generated
vendored
15
vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go
generated
vendored
@@ -22,23 +22,14 @@ var (
|
||||
// case sensitive keywords, so "env" is not a substring on "Environment"
|
||||
_scrubKeywords = [][]byte{[]byte("env"), []byte("Environment")}
|
||||
|
||||
_scrub int32
|
||||
_scrub atomic.Bool
|
||||
)
|
||||
|
||||
// SetScrubbing enables scrubbing
|
||||
func SetScrubbing(enable bool) {
|
||||
v := int32(0) // cant convert from bool to int32 directly
|
||||
if enable {
|
||||
v = 1
|
||||
}
|
||||
atomic.StoreInt32(&_scrub, v)
|
||||
}
|
||||
func SetScrubbing(enable bool) { _scrub.Store(enable) }
|
||||
|
||||
// IsScrubbingEnabled checks if scrubbing is enabled
|
||||
func IsScrubbingEnabled() bool {
|
||||
v := atomic.LoadInt32(&_scrub)
|
||||
return v != 0
|
||||
}
|
||||
func IsScrubbingEnabled() bool { return _scrub.Load() }
|
||||
|
||||
// ScrubProcessParameters scrubs HCS Create Process requests with config parameters of
|
||||
// type internal/hcs/schema2.ScrubProcessParameters (aka hcsshema.ScrubProcessParameters)
|
||||
|
||||
2
vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go
generated
vendored
@@ -104,7 +104,7 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error
|
||||
}()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if ctx.Err() == gcontext.DeadlineExceeded { //nolint:errorlint
|
||||
if ctx.Err() == gcontext.DeadlineExceeded {
|
||||
log.G(ctx).WithField(logfields.Timeout, trueTimeout).
|
||||
Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. " +
|
||||
"If it appears to be making no forward progress, obtain the stacks and see if there is a syscall " +
|
||||
|
||||
1
vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go
generated
vendored
@@ -34,6 +34,7 @@ const (
|
||||
UtilityVMPath = `UtilityVM`
|
||||
UtilityVMFilesPath = `UtilityVM\Files`
|
||||
RegFilesPath = `Files\Windows\System32\config`
|
||||
BootDirRelativePath = `\EFI\Microsoft\Boot`
|
||||
BcdFilePath = `UtilityVM\Files\EFI\Microsoft\Boot\BCD`
|
||||
BootMgrFilePath = `UtilityVM\Files\EFI\Microsoft\Boot\bootmgfw.efi`
|
||||
ContainerBaseVhd = `blank-base.vhdx`
|
||||
|
||||
11
vendor/github.com/Microsoft/hcsshim/internal/winapi/cimfs.go
generated
vendored
11
vendor/github.com/Microsoft/hcsshim/internal/winapi/cimfs.go
generated
vendored
@@ -32,10 +32,16 @@ type CimFsFileMetadata struct {
|
||||
EACount uint32
|
||||
}
|
||||
|
||||
type CimFsImagePath struct {
|
||||
ImageDir *uint16
|
||||
ImageName *uint16
|
||||
}
|
||||
|
||||
//sys CimMountImage(imagePath string, fsName string, flags uint32, volumeID *g) (hr error) = cimfs.CimMountImage?
|
||||
//sys CimDismountImage(volumeID *g) (hr error) = cimfs.CimDismountImage?
|
||||
|
||||
//sys CimCreateImage(imagePath string, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) = cimfs.CimCreateImage?
|
||||
//sys CimCreateImage2(imagePath string, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) = cimfs.CimCreateImage2?
|
||||
//sys CimCloseImage(cimFSHandle FsHandle) = cimfs.CimCloseImage?
|
||||
//sys CimCommitImage(cimFSHandle FsHandle) (hr error) = cimfs.CimCommitImage?
|
||||
|
||||
@@ -45,3 +51,8 @@ type CimFsFileMetadata struct {
|
||||
//sys CimDeletePath(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimDeletePath?
|
||||
//sys CimCreateHardLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) = cimfs.CimCreateHardLink?
|
||||
//sys CimCreateAlternateStream(cimFSHandle FsHandle, path string, size uint64, cimStreamHandle *StreamHandle) (hr error) = cimfs.CimCreateAlternateStream?
|
||||
//sys CimAddFsToMergedImage(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimAddFsToMergedImage?
|
||||
//sys CimAddFsToMergedImage2(cimFSHandle FsHandle, path string, flags uint32) (hr error) = cimfs.CimAddFsToMergedImage2?
|
||||
//sys CimMergeMountImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g) (hr error) = cimfs.CimMergeMountImage?
|
||||
//sys CimTombstoneFile(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimTombstoneFile?
|
||||
//sys CimCreateMergeLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) = cimfs.CimCreateMergeLink?
|
||||
|
||||
146
vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go
generated
vendored
146
vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go
generated
vendored
@@ -53,6 +53,8 @@ var (
|
||||
procCM_Get_Device_ID_ListA = modcfgmgr32.NewProc("CM_Get_Device_ID_ListA")
|
||||
procCM_Get_Device_ID_List_SizeA = modcfgmgr32.NewProc("CM_Get_Device_ID_List_SizeA")
|
||||
procCM_Locate_DevNodeW = modcfgmgr32.NewProc("CM_Locate_DevNodeW")
|
||||
procCimAddFsToMergedImage = modcimfs.NewProc("CimAddFsToMergedImage")
|
||||
procCimAddFsToMergedImage2 = modcimfs.NewProc("CimAddFsToMergedImage2")
|
||||
procCimCloseImage = modcimfs.NewProc("CimCloseImage")
|
||||
procCimCloseStream = modcimfs.NewProc("CimCloseStream")
|
||||
procCimCommitImage = modcimfs.NewProc("CimCommitImage")
|
||||
@@ -60,9 +62,13 @@ var (
|
||||
procCimCreateFile = modcimfs.NewProc("CimCreateFile")
|
||||
procCimCreateHardLink = modcimfs.NewProc("CimCreateHardLink")
|
||||
procCimCreateImage = modcimfs.NewProc("CimCreateImage")
|
||||
procCimCreateImage2 = modcimfs.NewProc("CimCreateImage2")
|
||||
procCimCreateMergeLink = modcimfs.NewProc("CimCreateMergeLink")
|
||||
procCimDeletePath = modcimfs.NewProc("CimDeletePath")
|
||||
procCimDismountImage = modcimfs.NewProc("CimDismountImage")
|
||||
procCimMergeMountImage = modcimfs.NewProc("CimMergeMountImage")
|
||||
procCimMountImage = modcimfs.NewProc("CimMountImage")
|
||||
procCimTombstoneFile = modcimfs.NewProc("CimTombstoneFile")
|
||||
procCimWriteStream = modcimfs.NewProc("CimWriteStream")
|
||||
procSetJobCompartmentId = modiphlpapi.NewProc("SetJobCompartmentId")
|
||||
procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole")
|
||||
@@ -181,6 +187,54 @@ func _CMLocateDevNode(pdnDevInst *uint32, pDeviceID *uint16, uFlags uint32) (hr
|
||||
return
|
||||
}
|
||||
|
||||
func CimAddFsToMergedImage(cimFSHandle FsHandle, path string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(path)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _CimAddFsToMergedImage(cimFSHandle, _p0)
|
||||
}
|
||||
|
||||
func _CimAddFsToMergedImage(cimFSHandle FsHandle, path *uint16) (hr error) {
|
||||
hr = procCimAddFsToMergedImage.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.SyscallN(procCimAddFsToMergedImage.Addr(), uintptr(cimFSHandle), uintptr(unsafe.Pointer(path)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CimAddFsToMergedImage2(cimFSHandle FsHandle, path string, flags uint32) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(path)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _CimAddFsToMergedImage2(cimFSHandle, _p0, flags)
|
||||
}
|
||||
|
||||
func _CimAddFsToMergedImage2(cimFSHandle FsHandle, path *uint16, flags uint32) (hr error) {
|
||||
hr = procCimAddFsToMergedImage2.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.SyscallN(procCimAddFsToMergedImage2.Addr(), uintptr(cimFSHandle), uintptr(unsafe.Pointer(path)), uintptr(flags))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CimCloseImage(cimFSHandle FsHandle) (err error) {
|
||||
err = procCimCloseImage.Find()
|
||||
if err != nil {
|
||||
@@ -321,6 +375,59 @@ func _CimCreateImage(imagePath *uint16, oldFSName *uint16, newFSName *uint16, ci
|
||||
return
|
||||
}
|
||||
|
||||
func CimCreateImage2(imagePath string, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(imagePath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _CimCreateImage2(_p0, flags, oldFSName, newFSName, cimFSHandle)
|
||||
}
|
||||
|
||||
func _CimCreateImage2(imagePath *uint16, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) {
|
||||
hr = procCimCreateImage2.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.SyscallN(procCimCreateImage2.Addr(), uintptr(unsafe.Pointer(imagePath)), uintptr(flags), uintptr(unsafe.Pointer(oldFSName)), uintptr(unsafe.Pointer(newFSName)), uintptr(unsafe.Pointer(cimFSHandle)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CimCreateMergeLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(newPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(oldPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _CimCreateMergeLink(cimFSHandle, _p0, _p1)
|
||||
}
|
||||
|
||||
func _CimCreateMergeLink(cimFSHandle FsHandle, newPath *uint16, oldPath *uint16) (hr error) {
|
||||
hr = procCimCreateMergeLink.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.SyscallN(procCimCreateMergeLink.Addr(), uintptr(cimFSHandle), uintptr(unsafe.Pointer(newPath)), uintptr(unsafe.Pointer(oldPath)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CimDeletePath(cimFSHandle FsHandle, path string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(path)
|
||||
@@ -360,6 +467,21 @@ func CimDismountImage(volumeID *g) (hr error) {
|
||||
return
|
||||
}
|
||||
|
||||
func CimMergeMountImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g) (hr error) {
|
||||
hr = procCimMergeMountImage.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.SyscallN(procCimMergeMountImage.Addr(), uintptr(numCimPaths), uintptr(unsafe.Pointer(backingImagePaths)), uintptr(flags), uintptr(unsafe.Pointer(volumeID)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CimMountImage(imagePath string, fsName string, flags uint32, volumeID *g) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(imagePath)
|
||||
@@ -389,6 +511,30 @@ func _CimMountImage(imagePath *uint16, fsName *uint16, flags uint32, volumeID *g
|
||||
return
|
||||
}
|
||||
|
||||
func CimTombstoneFile(cimFSHandle FsHandle, path string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(path)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _CimTombstoneFile(cimFSHandle, _p0)
|
||||
}
|
||||
|
||||
func _CimTombstoneFile(cimFSHandle FsHandle, path *uint16) (hr error) {
|
||||
hr = procCimTombstoneFile.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.SyscallN(procCimTombstoneFile.Addr(), uintptr(cimFSHandle), uintptr(unsafe.Pointer(path)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CimWriteStream(cimStreamHandle StreamHandle, buffer uintptr, bufferSize uint32) (hr error) {
|
||||
hr = procCimWriteStream.Find()
|
||||
if hr != nil {
|
||||
|
||||
22
vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go
generated
vendored
22
vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go
generated
vendored
@@ -3,7 +3,8 @@ package osversion
|
||||
// List of stable ABI compliant ltsc releases
|
||||
// Note: List must be sorted in ascending order
|
||||
var compatLTSCReleases = []uint16{
|
||||
V21H2Server,
|
||||
LTSC2022,
|
||||
LTSC2025,
|
||||
}
|
||||
|
||||
// CheckHostAndContainerCompat checks if given host and container
|
||||
@@ -20,16 +21,25 @@ func CheckHostAndContainerCompat(host, ctr OSVersion) bool {
|
||||
}
|
||||
|
||||
// If host is < WS 2022, exact version match is required
|
||||
if host.Build < V21H2Server {
|
||||
if host.Build < LTSC2022 {
|
||||
return host.Build == ctr.Build
|
||||
}
|
||||
|
||||
var supportedLtscRelease uint16
|
||||
// Find the latest LTSC version that is earlier than the host version.
|
||||
// This is the earliest version of container that the host can run.
|
||||
//
|
||||
// If the host version is an LTSC, then it supports compatibility with
|
||||
// everything from the previous LTSC up to itself, so we want supportedLTSCRelease
|
||||
// to be the previous entry.
|
||||
//
|
||||
// If no match is found, then we know that the host is LTSC2022 exactly,
|
||||
// since we already checked that it's not less than LTSC2022.
|
||||
var supportedLTSCRelease uint16 = LTSC2022
|
||||
for i := len(compatLTSCReleases) - 1; i >= 0; i-- {
|
||||
if host.Build >= compatLTSCReleases[i] {
|
||||
supportedLtscRelease = compatLTSCReleases[i]
|
||||
if host.Build > compatLTSCReleases[i] {
|
||||
supportedLTSCRelease = compatLTSCReleases[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
return ctr.Build >= supportedLtscRelease && ctr.Build <= host.Build
|
||||
return supportedLTSCRelease <= ctr.Build && ctr.Build <= host.Build
|
||||
}
|
||||
|
||||
7
vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
generated
vendored
7
vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
generated
vendored
@@ -81,4 +81,11 @@ const (
|
||||
|
||||
// V22H2Win11 corresponds to Windows 11 (2022 Update).
|
||||
V22H2Win11 = 22621
|
||||
|
||||
// V23H2 is the 23H2 release in the Windows Server annual channel.
|
||||
V23H2 = 25398
|
||||
|
||||
// Windows Server 2025 build 26100
|
||||
V25H1Server = 26100
|
||||
LTSC2025 = V25H1Server
|
||||
)
|
||||
|
||||
15
vendor/github.com/asaskevich/govalidator/.gitignore
generated
vendored
15
vendor/github.com/asaskevich/govalidator/.gitignore
generated
vendored
@@ -1,15 +0,0 @@
|
||||
bin/
|
||||
.idea/
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
12
vendor/github.com/asaskevich/govalidator/.travis.yml
generated
vendored
12
vendor/github.com/asaskevich/govalidator/.travis.yml
generated
vendored
@@ -1,12 +0,0 @@
|
||||
language: go
|
||||
dist: xenial
|
||||
go:
|
||||
- '1.10'
|
||||
- '1.11'
|
||||
- '1.12'
|
||||
- '1.13'
|
||||
- 'tip'
|
||||
|
||||
script:
|
||||
- go test -coverpkg=./... -coverprofile=coverage.info -timeout=5s
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
43
vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md
generated
vendored
43
vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md
generated
vendored
@@ -1,43 +0,0 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
This project adheres to [The Code Manifesto](http://codemanifesto.com)
|
||||
as its guidelines for contributor interactions.
|
||||
|
||||
## The Code Manifesto
|
||||
|
||||
We want to work in an ecosystem that empowers developers to reach their
|
||||
potential — one that encourages growth and effective collaboration. A space
|
||||
that is safe for all.
|
||||
|
||||
A space such as this benefits everyone that participates in it. It encourages
|
||||
new developers to enter our field. It is through discussion and collaboration
|
||||
that we grow, and through growth that we improve.
|
||||
|
||||
In the effort to create such a place, we hold to these values:
|
||||
|
||||
1. **Discrimination limits us.** This includes discrimination on the basis of
|
||||
race, gender, sexual orientation, gender identity, age, nationality,
|
||||
technology and any other arbitrary exclusion of a group of people.
|
||||
2. **Boundaries honor us.** Your comfort levels are not everyone’s comfort
|
||||
levels. Remember that, and if brought to your attention, heed it.
|
||||
3. **We are our biggest assets.** None of us were born masters of our trade.
|
||||
Each of us has been helped along the way. Return that favor, when and where
|
||||
you can.
|
||||
4. **We are resources for the future.** As an extension of #3, share what you
|
||||
know. Make yourself a resource to help those that come after you.
|
||||
5. **Respect defines us.** Treat others as you wish to be treated. Make your
|
||||
discussions, criticisms and debates from a position of respectfulness. Ask
|
||||
yourself, is it true? Is it necessary? Is it constructive? Anything less is
|
||||
unacceptable.
|
||||
6. **Reactions require grace.** Angry responses are valid, but abusive language
|
||||
and vindictive actions are toxic. When something happens that offends you,
|
||||
handle it assertively, but be respectful. Escalate reasonably, and try to
|
||||
allow the offender an opportunity to explain themselves, and possibly
|
||||
correct the issue.
|
||||
7. **Opinions are just that: opinions.** Each and every one of us, due to our
|
||||
background and upbringing, have varying opinions. That is perfectly
|
||||
acceptable. Remember this: if you respect your own opinions, you should
|
||||
respect the opinions of others.
|
||||
8. **To err is human.** You might not intend it, but mistakes do happen and
|
||||
contribute to build experience. Tolerate honest mistakes, and don't
|
||||
hesitate to apologize if you make one yourself.
|
||||
63
vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md
generated
vendored
63
vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md
generated
vendored
@@ -1,63 +0,0 @@
|
||||
#### Support
|
||||
If you do have a contribution to the package, feel free to create a Pull Request or an Issue.
|
||||
|
||||
#### What to contribute
|
||||
If you don't know what to do, there are some features and functions that need to be done
|
||||
|
||||
- [ ] Refactor code
|
||||
- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check
|
||||
- [ ] Create actual list of contributors and projects that currently using this package
|
||||
- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues)
|
||||
- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions)
|
||||
- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new
|
||||
- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc
|
||||
- [x] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
|
||||
- [ ] Implement fuzzing testing
|
||||
- [ ] Implement some struct/map/array utilities
|
||||
- [ ] Implement map/array validation
|
||||
- [ ] Implement benchmarking
|
||||
- [ ] Implement batch of examples
|
||||
- [ ] Look at forks for new features and fixes
|
||||
|
||||
#### Advice
|
||||
Feel free to create what you want, but keep in mind when you implement new features:
|
||||
- Code must be clear and readable, names of variables/constants clearly describes what they are doing
|
||||
- Public functions must be documented and described in source file and added to README.md to the list of available functions
|
||||
- There are must be unit-tests for any new functions and improvements
|
||||
|
||||
## Financial contributions
|
||||
|
||||
We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/govalidator).
|
||||
Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed.
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
### Contributors
|
||||
|
||||
Thank you to all the people who have already contributed to govalidator!
|
||||
<a href="https://github.com/asaskevich/govalidator/graphs/contributors"><img src="https://opencollective.com/govalidator/contributors.svg?width=890" /></a>
|
||||
|
||||
|
||||
### Backers
|
||||
|
||||
Thank you to all our backers! [[Become a backer](https://opencollective.com/govalidator#backer)]
|
||||
|
||||
<a href="https://opencollective.com/govalidator#backers" target="_blank"><img src="https://opencollective.com/govalidator/backers.svg?width=890"></a>
|
||||
|
||||
|
||||
### Sponsors
|
||||
|
||||
Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/govalidator#sponsor))
|
||||
|
||||
<a href="https://opencollective.com/govalidator/sponsor/0/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/1/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/2/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/3/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/4/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/5/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/6/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/7/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/8/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/9/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/9/avatar.svg"></a>
|
||||
21
vendor/github.com/asaskevich/govalidator/LICENSE
generated
vendored
21
vendor/github.com/asaskevich/govalidator/LICENSE
generated
vendored
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2020 Alex Saskevich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
622
vendor/github.com/asaskevich/govalidator/README.md
generated
vendored
622
vendor/github.com/asaskevich/govalidator/README.md
generated
vendored
@@ -1,622 +0,0 @@
|
||||
govalidator
|
||||
===========
|
||||
[](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [](https://godoc.org/github.com/asaskevich/govalidator)
|
||||
[](https://travis-ci.org/asaskevich/govalidator)
|
||||
[](https://codecov.io/gh/asaskevich/govalidator) [](https://goreportcard.com/report/github.com/asaskevich/govalidator) [](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [](#backers) [](#sponsors) [](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield)
|
||||
|
||||
A package of validators and sanitizers for strings, structs and collections. Based on [validator.js](https://github.com/chriso/validator.js).
|
||||
|
||||
#### Installation
|
||||
Make sure that Go is installed on your computer.
|
||||
Type the following command in your terminal:
|
||||
|
||||
go get github.com/asaskevich/govalidator
|
||||
|
||||
or you can get specified release of the package with `gopkg.in`:
|
||||
|
||||
go get gopkg.in/asaskevich/govalidator.v10
|
||||
|
||||
After it the package is ready to use.
|
||||
|
||||
|
||||
#### Import package in your project
|
||||
Add following line in your `*.go` file:
|
||||
```go
|
||||
import "github.com/asaskevich/govalidator"
|
||||
```
|
||||
If you are unhappy to use long `govalidator`, you can do something like this:
|
||||
```go
|
||||
import (
|
||||
valid "github.com/asaskevich/govalidator"
|
||||
)
|
||||
```
|
||||
|
||||
#### Activate behavior to require all fields have a validation tag by default
|
||||
`SetFieldsRequiredByDefault` causes validation to fail when struct fields do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). A good place to activate this is a package init function or the main() function.
|
||||
|
||||
`SetNilPtrAllowedByRequired` causes validation to pass when struct fields marked by `required` are set to nil. This is disabled by default for consistency, but some packages that need to be able to determine between `nil` and `zero value` state can use this. If disabled, both `nil` and `zero` values cause validation errors.
|
||||
|
||||
```go
|
||||
import "github.com/asaskevich/govalidator"
|
||||
|
||||
func init() {
|
||||
govalidator.SetFieldsRequiredByDefault(true)
|
||||
}
|
||||
```
|
||||
|
||||
Here's some code to explain it:
|
||||
```go
|
||||
// this struct definition will fail govalidator.ValidateStruct() (and the field values do not matter):
|
||||
type exampleStruct struct {
|
||||
Name string ``
|
||||
Email string `valid:"email"`
|
||||
}
|
||||
|
||||
// this, however, will only fail when Email is empty or an invalid email address:
|
||||
type exampleStruct2 struct {
|
||||
Name string `valid:"-"`
|
||||
Email string `valid:"email"`
|
||||
}
|
||||
|
||||
// lastly, this will only fail when Email is an invalid email address but not when it's empty:
|
||||
type exampleStruct2 struct {
|
||||
Name string `valid:"-"`
|
||||
Email string `valid:"email,optional"`
|
||||
}
|
||||
```
|
||||
|
||||
#### Recent breaking changes (see [#123](https://github.com/asaskevich/govalidator/pull/123))
|
||||
##### Custom validator function signature
|
||||
A context was added as the second parameter, for structs this is the object being validated – this makes dependent validation possible.
|
||||
```go
|
||||
import "github.com/asaskevich/govalidator"
|
||||
|
||||
// old signature
|
||||
func(i interface{}) bool
|
||||
|
||||
// new signature
|
||||
func(i interface{}, o interface{}) bool
|
||||
```
|
||||
|
||||
##### Adding a custom validator
|
||||
This was changed to prevent data races when accessing custom validators.
|
||||
```go
|
||||
import "github.com/asaskevich/govalidator"
|
||||
|
||||
// before
|
||||
govalidator.CustomTypeTagMap["customByteArrayValidator"] = func(i interface{}, o interface{}) bool {
|
||||
// ...
|
||||
}
|
||||
|
||||
// after
|
||||
govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, o interface{}) bool {
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
#### List of functions:
|
||||
```go
|
||||
func Abs(value float64) float64
|
||||
func BlackList(str, chars string) string
|
||||
func ByteLength(str string, params ...string) bool
|
||||
func CamelCaseToUnderscore(str string) string
|
||||
func Contains(str, substring string) bool
|
||||
func Count(array []interface{}, iterator ConditionIterator) int
|
||||
func Each(array []interface{}, iterator Iterator)
|
||||
func ErrorByField(e error, field string) string
|
||||
func ErrorsByField(e error) map[string]string
|
||||
func Filter(array []interface{}, iterator ConditionIterator) []interface{}
|
||||
func Find(array []interface{}, iterator ConditionIterator) interface{}
|
||||
func GetLine(s string, index int) (string, error)
|
||||
func GetLines(s string) []string
|
||||
func HasLowerCase(str string) bool
|
||||
func HasUpperCase(str string) bool
|
||||
func HasWhitespace(str string) bool
|
||||
func HasWhitespaceOnly(str string) bool
|
||||
func InRange(value interface{}, left interface{}, right interface{}) bool
|
||||
func InRangeFloat32(value, left, right float32) bool
|
||||
func InRangeFloat64(value, left, right float64) bool
|
||||
func InRangeInt(value, left, right interface{}) bool
|
||||
func IsASCII(str string) bool
|
||||
func IsAlpha(str string) bool
|
||||
func IsAlphanumeric(str string) bool
|
||||
func IsBase64(str string) bool
|
||||
func IsByteLength(str string, min, max int) bool
|
||||
func IsCIDR(str string) bool
|
||||
func IsCRC32(str string) bool
|
||||
func IsCRC32b(str string) bool
|
||||
func IsCreditCard(str string) bool
|
||||
func IsDNSName(str string) bool
|
||||
func IsDataURI(str string) bool
|
||||
func IsDialString(str string) bool
|
||||
func IsDivisibleBy(str, num string) bool
|
||||
func IsEmail(str string) bool
|
||||
func IsExistingEmail(email string) bool
|
||||
func IsFilePath(str string) (bool, int)
|
||||
func IsFloat(str string) bool
|
||||
func IsFullWidth(str string) bool
|
||||
func IsHalfWidth(str string) bool
|
||||
func IsHash(str string, algorithm string) bool
|
||||
func IsHexadecimal(str string) bool
|
||||
func IsHexcolor(str string) bool
|
||||
func IsHost(str string) bool
|
||||
func IsIP(str string) bool
|
||||
func IsIPv4(str string) bool
|
||||
func IsIPv6(str string) bool
|
||||
func IsISBN(str string, version int) bool
|
||||
func IsISBN10(str string) bool
|
||||
func IsISBN13(str string) bool
|
||||
func IsISO3166Alpha2(str string) bool
|
||||
func IsISO3166Alpha3(str string) bool
|
||||
func IsISO4217(str string) bool
|
||||
func IsISO693Alpha2(str string) bool
|
||||
func IsISO693Alpha3b(str string) bool
|
||||
func IsIn(str string, params ...string) bool
|
||||
func IsInRaw(str string, params ...string) bool
|
||||
func IsInt(str string) bool
|
||||
func IsJSON(str string) bool
|
||||
func IsLatitude(str string) bool
|
||||
func IsLongitude(str string) bool
|
||||
func IsLowerCase(str string) bool
|
||||
func IsMAC(str string) bool
|
||||
func IsMD4(str string) bool
|
||||
func IsMD5(str string) bool
|
||||
func IsMagnetURI(str string) bool
|
||||
func IsMongoID(str string) bool
|
||||
func IsMultibyte(str string) bool
|
||||
func IsNatural(value float64) bool
|
||||
func IsNegative(value float64) bool
|
||||
func IsNonNegative(value float64) bool
|
||||
func IsNonPositive(value float64) bool
|
||||
func IsNotNull(str string) bool
|
||||
func IsNull(str string) bool
|
||||
func IsNumeric(str string) bool
|
||||
func IsPort(str string) bool
|
||||
func IsPositive(value float64) bool
|
||||
func IsPrintableASCII(str string) bool
|
||||
func IsRFC3339(str string) bool
|
||||
func IsRFC3339WithoutZone(str string) bool
|
||||
func IsRGBcolor(str string) bool
|
||||
func IsRegex(str string) bool
|
||||
func IsRequestURI(rawurl string) bool
|
||||
func IsRequestURL(rawurl string) bool
|
||||
func IsRipeMD128(str string) bool
|
||||
func IsRipeMD160(str string) bool
|
||||
func IsRsaPub(str string, params ...string) bool
|
||||
func IsRsaPublicKey(str string, keylen int) bool
|
||||
func IsSHA1(str string) bool
|
||||
func IsSHA256(str string) bool
|
||||
func IsSHA384(str string) bool
|
||||
func IsSHA512(str string) bool
|
||||
func IsSSN(str string) bool
|
||||
func IsSemver(str string) bool
|
||||
func IsTiger128(str string) bool
|
||||
func IsTiger160(str string) bool
|
||||
func IsTiger192(str string) bool
|
||||
func IsTime(str string, format string) bool
|
||||
func IsType(v interface{}, params ...string) bool
|
||||
func IsURL(str string) bool
|
||||
func IsUTFDigit(str string) bool
|
||||
func IsUTFLetter(str string) bool
|
||||
func IsUTFLetterNumeric(str string) bool
|
||||
func IsUTFNumeric(str string) bool
|
||||
func IsUUID(str string) bool
|
||||
func IsUUIDv3(str string) bool
|
||||
func IsUUIDv4(str string) bool
|
||||
func IsUUIDv5(str string) bool
|
||||
func IsULID(str string) bool
|
||||
func IsUnixTime(str string) bool
|
||||
func IsUpperCase(str string) bool
|
||||
func IsVariableWidth(str string) bool
|
||||
func IsWhole(value float64) bool
|
||||
func LeftTrim(str, chars string) string
|
||||
func Map(array []interface{}, iterator ResultIterator) []interface{}
|
||||
func Matches(str, pattern string) bool
|
||||
func MaxStringLength(str string, params ...string) bool
|
||||
func MinStringLength(str string, params ...string) bool
|
||||
func NormalizeEmail(str string) (string, error)
|
||||
func PadBoth(str string, padStr string, padLen int) string
|
||||
func PadLeft(str string, padStr string, padLen int) string
|
||||
func PadRight(str string, padStr string, padLen int) string
|
||||
func PrependPathToErrors(err error, path string) error
|
||||
func Range(str string, params ...string) bool
|
||||
func RemoveTags(s string) string
|
||||
func ReplacePattern(str, pattern, replace string) string
|
||||
func Reverse(s string) string
|
||||
func RightTrim(str, chars string) string
|
||||
func RuneLength(str string, params ...string) bool
|
||||
func SafeFileName(str string) string
|
||||
func SetFieldsRequiredByDefault(value bool)
|
||||
func SetNilPtrAllowedByRequired(value bool)
|
||||
func Sign(value float64) float64
|
||||
func StringLength(str string, params ...string) bool
|
||||
func StringMatches(s string, params ...string) bool
|
||||
func StripLow(str string, keepNewLines bool) string
|
||||
func ToBoolean(str string) (bool, error)
|
||||
func ToFloat(str string) (float64, error)
|
||||
func ToInt(value interface{}) (res int64, err error)
|
||||
func ToJSON(obj interface{}) (string, error)
|
||||
func ToString(obj interface{}) string
|
||||
func Trim(str, chars string) string
|
||||
func Truncate(str string, length int, ending string) string
|
||||
func TruncatingErrorf(str string, args ...interface{}) error
|
||||
func UnderscoreToCamelCase(s string) string
|
||||
func ValidateMap(inputMap map[string]interface{}, validationMap map[string]interface{}) (bool, error)
|
||||
func ValidateStruct(s interface{}) (bool, error)
|
||||
func WhiteList(str, chars string) string
|
||||
type ConditionIterator
|
||||
type CustomTypeValidator
|
||||
type Error
|
||||
func (e Error) Error() string
|
||||
type Errors
|
||||
func (es Errors) Error() string
|
||||
func (es Errors) Errors() []error
|
||||
type ISO3166Entry
|
||||
type ISO693Entry
|
||||
type InterfaceParamValidator
|
||||
type Iterator
|
||||
type ParamValidator
|
||||
type ResultIterator
|
||||
type UnsupportedTypeError
|
||||
func (e *UnsupportedTypeError) Error() string
|
||||
type Validator
|
||||
```
|
||||
|
||||
#### Examples
|
||||
###### IsURL
|
||||
```go
|
||||
println(govalidator.IsURL(`http://user@pass:domain.com/path/page`))
|
||||
```
|
||||
###### IsType
|
||||
```go
|
||||
println(govalidator.IsType("Bob", "string"))
|
||||
println(govalidator.IsType(1, "int"))
|
||||
i := 1
|
||||
println(govalidator.IsType(&i, "*int"))
|
||||
```
|
||||
|
||||
IsType can be used through the tag `type` which is essential for map validation:
|
||||
```go
|
||||
type User struct {
|
||||
Name string `valid:"type(string)"`
|
||||
Age int `valid:"type(int)"`
|
||||
Meta interface{} `valid:"type(string)"`
|
||||
}
|
||||
result, err := govalidator.ValidateStruct(User{"Bob", 20, "meta"})
|
||||
if err != nil {
|
||||
println("error: " + err.Error())
|
||||
}
|
||||
println(result)
|
||||
```
|
||||
###### ToString
|
||||
```go
|
||||
type User struct {
|
||||
FirstName string
|
||||
LastName string
|
||||
}
|
||||
|
||||
str := govalidator.ToString(&User{"John", "Juan"})
|
||||
println(str)
|
||||
```
|
||||
###### Each, Map, Filter, Count for slices
|
||||
Each iterates over the slice/array and calls Iterator for every item
|
||||
```go
|
||||
data := []interface{}{1, 2, 3, 4, 5}
|
||||
var fn govalidator.Iterator = func(value interface{}, index int) {
|
||||
println(value.(int))
|
||||
}
|
||||
govalidator.Each(data, fn)
|
||||
```
|
||||
```go
|
||||
data := []interface{}{1, 2, 3, 4, 5}
|
||||
var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} {
|
||||
return value.(int) * 3
|
||||
}
|
||||
_ = govalidator.Map(data, fn) // result = []interface{}{1, 6, 9, 12, 15}
|
||||
```
|
||||
```go
|
||||
data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||
var fn govalidator.ConditionIterator = func(value interface{}, index int) bool {
|
||||
return value.(int)%2 == 0
|
||||
}
|
||||
_ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10}
|
||||
_ = govalidator.Count(data, fn) // result = 5
|
||||
```
|
||||
###### ValidateStruct [#2](https://github.com/asaskevich/govalidator/pull/2)
|
||||
If you want to validate structs, you can use tag `valid` for any field in your structure. All validators used with this field in one tag are separated by comma. If you want to skip validation, place `-` in your tag. If you need a validator that is not on the list below, you can add it like this:
|
||||
```go
|
||||
govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
|
||||
return str == "duck"
|
||||
})
|
||||
```
|
||||
For completely custom validators (interface-based), see below.
|
||||
|
||||
Here is a list of available validators for struct fields (validator - used function):
|
||||
```go
|
||||
"email": IsEmail,
|
||||
"url": IsURL,
|
||||
"dialstring": IsDialString,
|
||||
"requrl": IsRequestURL,
|
||||
"requri": IsRequestURI,
|
||||
"alpha": IsAlpha,
|
||||
"utfletter": IsUTFLetter,
|
||||
"alphanum": IsAlphanumeric,
|
||||
"utfletternum": IsUTFLetterNumeric,
|
||||
"numeric": IsNumeric,
|
||||
"utfnumeric": IsUTFNumeric,
|
||||
"utfdigit": IsUTFDigit,
|
||||
"hexadecimal": IsHexadecimal,
|
||||
"hexcolor": IsHexcolor,
|
||||
"rgbcolor": IsRGBcolor,
|
||||
"lowercase": IsLowerCase,
|
||||
"uppercase": IsUpperCase,
|
||||
"int": IsInt,
|
||||
"float": IsFloat,
|
||||
"null": IsNull,
|
||||
"uuid": IsUUID,
|
||||
"uuidv3": IsUUIDv3,
|
||||
"uuidv4": IsUUIDv4,
|
||||
"uuidv5": IsUUIDv5,
|
||||
"creditcard": IsCreditCard,
|
||||
"isbn10": IsISBN10,
|
||||
"isbn13": IsISBN13,
|
||||
"json": IsJSON,
|
||||
"multibyte": IsMultibyte,
|
||||
"ascii": IsASCII,
|
||||
"printableascii": IsPrintableASCII,
|
||||
"fullwidth": IsFullWidth,
|
||||
"halfwidth": IsHalfWidth,
|
||||
"variablewidth": IsVariableWidth,
|
||||
"base64": IsBase64,
|
||||
"datauri": IsDataURI,
|
||||
"ip": IsIP,
|
||||
"port": IsPort,
|
||||
"ipv4": IsIPv4,
|
||||
"ipv6": IsIPv6,
|
||||
"dns": IsDNSName,
|
||||
"host": IsHost,
|
||||
"mac": IsMAC,
|
||||
"latitude": IsLatitude,
|
||||
"longitude": IsLongitude,
|
||||
"ssn": IsSSN,
|
||||
"semver": IsSemver,
|
||||
"rfc3339": IsRFC3339,
|
||||
"rfc3339WithoutZone": IsRFC3339WithoutZone,
|
||||
"ISO3166Alpha2": IsISO3166Alpha2,
|
||||
"ISO3166Alpha3": IsISO3166Alpha3,
|
||||
"ulid": IsULID,
|
||||
```
|
||||
Validators with parameters
|
||||
|
||||
```go
|
||||
"range(min|max)": Range,
|
||||
"length(min|max)": ByteLength,
|
||||
"runelength(min|max)": RuneLength,
|
||||
"stringlength(min|max)": StringLength,
|
||||
"matches(pattern)": StringMatches,
|
||||
"in(string1|string2|...|stringN)": IsIn,
|
||||
"rsapub(keylength)" : IsRsaPub,
|
||||
"minstringlength(int): MinStringLength,
|
||||
"maxstringlength(int): MaxStringLength,
|
||||
```
|
||||
Validators with parameters for any type
|
||||
|
||||
```go
|
||||
"type(type)": IsType,
|
||||
```
|
||||
|
||||
And here is small example of usage:
|
||||
```go
|
||||
type Post struct {
|
||||
Title string `valid:"alphanum,required"`
|
||||
Message string `valid:"duck,ascii"`
|
||||
Message2 string `valid:"animal(dog)"`
|
||||
AuthorIP string `valid:"ipv4"`
|
||||
Date string `valid:"-"`
|
||||
}
|
||||
post := &Post{
|
||||
Title: "My Example Post",
|
||||
Message: "duck",
|
||||
Message2: "dog",
|
||||
AuthorIP: "123.234.54.3",
|
||||
}
|
||||
|
||||
// Add your own struct validation tags
|
||||
govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
|
||||
return str == "duck"
|
||||
})
|
||||
|
||||
// Add your own struct validation tags with parameter
|
||||
govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool {
|
||||
species := params[0]
|
||||
return str == species
|
||||
})
|
||||
govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$")
|
||||
|
||||
result, err := govalidator.ValidateStruct(post)
|
||||
if err != nil {
|
||||
println("error: " + err.Error())
|
||||
}
|
||||
println(result)
|
||||
```
|
||||
###### ValidateMap [#2](https://github.com/asaskevich/govalidator/pull/338)
|
||||
If you want to validate maps, you can use the map to be validated and a validation map that contain the same tags used in ValidateStruct, both maps have to be in the form `map[string]interface{}`
|
||||
|
||||
So here is small example of usage:
|
||||
```go
|
||||
var mapTemplate = map[string]interface{}{
|
||||
"name":"required,alpha",
|
||||
"family":"required,alpha",
|
||||
"email":"required,email",
|
||||
"cell-phone":"numeric",
|
||||
"address":map[string]interface{}{
|
||||
"line1":"required,alphanum",
|
||||
"line2":"alphanum",
|
||||
"postal-code":"numeric",
|
||||
},
|
||||
}
|
||||
|
||||
var inputMap = map[string]interface{}{
|
||||
"name":"Bob",
|
||||
"family":"Smith",
|
||||
"email":"foo@bar.baz",
|
||||
"address":map[string]interface{}{
|
||||
"line1":"",
|
||||
"line2":"",
|
||||
"postal-code":"",
|
||||
},
|
||||
}
|
||||
|
||||
result, err := govalidator.ValidateMap(inputMap, mapTemplate)
|
||||
if err != nil {
|
||||
println("error: " + err.Error())
|
||||
}
|
||||
println(result)
|
||||
```
|
||||
|
||||
###### WhiteList
|
||||
```go
|
||||
// Remove all characters from string ignoring characters between "a" and "z"
|
||||
println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa")
|
||||
```
|
||||
|
||||
###### Custom validation functions
|
||||
Custom validation using your own domain specific validators is also available - here's an example of how to use it:
|
||||
```go
|
||||
import "github.com/asaskevich/govalidator"
|
||||
|
||||
type CustomByteArray [6]byte // custom types are supported and can be validated
|
||||
|
||||
type StructWithCustomByteArray struct {
|
||||
ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // multiple custom validators are possible as well and will be evaluated in sequence
|
||||
Email string `valid:"email"`
|
||||
CustomMinLength int `valid:"-"`
|
||||
}
|
||||
|
||||
govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, context interface{}) bool {
|
||||
switch v := context.(type) { // you can type switch on the context interface being validated
|
||||
case StructWithCustomByteArray:
|
||||
// you can check and validate against some other field in the context,
|
||||
// return early or not validate against the context at all – your choice
|
||||
case SomeOtherType:
|
||||
// ...
|
||||
default:
|
||||
// expecting some other type? Throw/panic here or continue
|
||||
}
|
||||
|
||||
switch v := i.(type) { // type switch on the struct field being validated
|
||||
case CustomByteArray:
|
||||
for _, e := range v { // this validator checks that the byte array is not empty, i.e. not all zeroes
|
||||
if e != 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
govalidator.CustomTypeTagMap.Set("customMinLengthValidator", func(i interface{}, context interface{}) bool {
|
||||
switch v := context.(type) { // this validates a field against the value in another field, i.e. dependent validation
|
||||
case StructWithCustomByteArray:
|
||||
return len(v.ID) >= v.CustomMinLength
|
||||
}
|
||||
return false
|
||||
})
|
||||
```
|
||||
|
||||
###### Loop over Error()
|
||||
By default .Error() returns all errors in a single String. To access each error you can do this:
|
||||
```go
|
||||
if err != nil {
|
||||
errs := err.(govalidator.Errors).Errors()
|
||||
for _, e := range errs {
|
||||
fmt.Println(e.Error())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
###### Custom error messages
|
||||
Custom error messages are supported via annotations by adding the `~` separator - here's an example of how to use it:
|
||||
```go
|
||||
type Ticket struct {
|
||||
Id int64 `json:"id"`
|
||||
FirstName string `json:"firstname" valid:"required~First name is blank"`
|
||||
}
|
||||
```
|
||||
|
||||
#### Notes
|
||||
Documentation is available here: [godoc.org](https://godoc.org/github.com/asaskevich/govalidator).
|
||||
Full information about code coverage is also available here: [govalidator on gocover.io](http://gocover.io/github.com/asaskevich/govalidator).
|
||||
|
||||
#### Support
|
||||
If you do have a contribution to the package, feel free to create a Pull Request or an Issue.
|
||||
|
||||
#### What to contribute
|
||||
If you don't know what to do, there are some features and functions that need to be done
|
||||
|
||||
- [ ] Refactor code
|
||||
- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check
|
||||
- [ ] Create actual list of contributors and projects that currently using this package
|
||||
- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues)
|
||||
- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions)
|
||||
- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new
|
||||
- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc
|
||||
- [x] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
|
||||
- [ ] Implement fuzzing testing
|
||||
- [ ] Implement some struct/map/array utilities
|
||||
- [ ] Implement map/array validation
|
||||
- [ ] Implement benchmarking
|
||||
- [ ] Implement batch of examples
|
||||
- [ ] Look at forks for new features and fixes
|
||||
|
||||
#### Advice
|
||||
Feel free to create what you want, but keep in mind when you implement new features:
|
||||
- Code must be clear and readable, names of variables/constants clearly describes what they are doing
|
||||
- Public functions must be documented and described in source file and added to README.md to the list of available functions
|
||||
- There are must be unit-tests for any new functions and improvements
|
||||
|
||||
## Credits
|
||||
### Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||
|
||||
#### Special thanks to [contributors](https://github.com/asaskevich/govalidator/graphs/contributors)
|
||||
* [Daniel Lohse](https://github.com/annismckenzie)
|
||||
* [Attila Oláh](https://github.com/attilaolah)
|
||||
* [Daniel Korner](https://github.com/Dadie)
|
||||
* [Steven Wilkin](https://github.com/stevenwilkin)
|
||||
* [Deiwin Sarjas](https://github.com/deiwin)
|
||||
* [Noah Shibley](https://github.com/slugmobile)
|
||||
* [Nathan Davies](https://github.com/nathj07)
|
||||
* [Matt Sanford](https://github.com/mzsanford)
|
||||
* [Simon ccl1115](https://github.com/ccl1115)
|
||||
|
||||
<a href="https://github.com/asaskevich/govalidator/graphs/contributors"><img src="https://opencollective.com/govalidator/contributors.svg?width=890" /></a>
|
||||
|
||||
|
||||
### Backers
|
||||
|
||||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/govalidator#backer)]
|
||||
|
||||
<a href="https://opencollective.com/govalidator#backers" target="_blank"><img src="https://opencollective.com/govalidator/backers.svg?width=890"></a>
|
||||
|
||||
|
||||
### Sponsors
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/govalidator#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/govalidator/sponsor/0/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/1/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/2/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/3/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/4/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/5/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/6/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/7/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/8/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/govalidator/sponsor/9/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/9/avatar.svg"></a>
|
||||
|
||||
|
||||
|
||||
|
||||
## License
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_large)
|
||||
87
vendor/github.com/asaskevich/govalidator/arrays.go
generated
vendored
87
vendor/github.com/asaskevich/govalidator/arrays.go
generated
vendored
@@ -1,87 +0,0 @@
|
||||
package govalidator
|
||||
|
||||
// Iterator is the function that accepts element of slice/array and its index
|
||||
type Iterator func(interface{}, int)
|
||||
|
||||
// ResultIterator is the function that accepts element of slice/array and its index and returns any result
|
||||
type ResultIterator func(interface{}, int) interface{}
|
||||
|
||||
// ConditionIterator is the function that accepts element of slice/array and its index and returns boolean
|
||||
type ConditionIterator func(interface{}, int) bool
|
||||
|
||||
// ReduceIterator is the function that accepts two element of slice/array and returns result of merging those values
|
||||
type ReduceIterator func(interface{}, interface{}) interface{}
|
||||
|
||||
// Some validates that any item of array corresponds to ConditionIterator. Returns boolean.
|
||||
func Some(array []interface{}, iterator ConditionIterator) bool {
|
||||
res := false
|
||||
for index, data := range array {
|
||||
res = res || iterator(data, index)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Every validates that every item of array corresponds to ConditionIterator. Returns boolean.
|
||||
func Every(array []interface{}, iterator ConditionIterator) bool {
|
||||
res := true
|
||||
for index, data := range array {
|
||||
res = res && iterator(data, index)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Reduce boils down a list of values into a single value by ReduceIterator
|
||||
func Reduce(array []interface{}, iterator ReduceIterator, initialValue interface{}) interface{} {
|
||||
for _, data := range array {
|
||||
initialValue = iterator(initialValue, data)
|
||||
}
|
||||
return initialValue
|
||||
}
|
||||
|
||||
// Each iterates over the slice and apply Iterator to every item
|
||||
func Each(array []interface{}, iterator Iterator) {
|
||||
for index, data := range array {
|
||||
iterator(data, index)
|
||||
}
|
||||
}
|
||||
|
||||
// Map iterates over the slice and apply ResultIterator to every item. Returns new slice as a result.
|
||||
func Map(array []interface{}, iterator ResultIterator) []interface{} {
|
||||
var result = make([]interface{}, len(array))
|
||||
for index, data := range array {
|
||||
result[index] = iterator(data, index)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Find iterates over the slice and apply ConditionIterator to every item. Returns first item that meet ConditionIterator or nil otherwise.
|
||||
func Find(array []interface{}, iterator ConditionIterator) interface{} {
|
||||
for index, data := range array {
|
||||
if iterator(data, index) {
|
||||
return data
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Filter iterates over the slice and apply ConditionIterator to every item. Returns new slice.
|
||||
func Filter(array []interface{}, iterator ConditionIterator) []interface{} {
|
||||
var result = make([]interface{}, 0)
|
||||
for index, data := range array {
|
||||
if iterator(data, index) {
|
||||
result = append(result, data)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Count iterates over the slice and apply ConditionIterator to every item. Returns count of items that meets ConditionIterator.
|
||||
func Count(array []interface{}, iterator ConditionIterator) int {
|
||||
count := 0
|
||||
for index, data := range array {
|
||||
if iterator(data, index) {
|
||||
count = count + 1
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user