diff --git a/CONTRIBUTING_GO.md b/CONTRIBUTING_GO.md index 950ef9af7d..a6d26d32fa 100644 --- a/CONTRIBUTING_GO.md +++ b/CONTRIBUTING_GO.md @@ -14,6 +14,7 @@ At present, this means the following repositories: ## Topics * [Unit Tests](#unit-tests) +* [Go Format and lint](#go-format-and-lint) * [Go Dependency updates](#go-dependency-updates) * [Testing changes in a dependent repository](#testing-changes-in-a-dependent-repository) * [git bisect a change in a Go dependency](#git-bisect-a-change-in-a-go-dependency) @@ -23,6 +24,11 @@ At present, this means the following repositories: Unit tests for Go code are added in a separate file within the same directory, named `..._test.go` (where the first part of the name is often the name of the file whose code is being tested). Our Go projects to not require unit tests, but contributors are strongly encouraged to unit test any code that can have a reasonable unit test written. +### Go Format and lint + +We are using the [`gofumpt`](https://github.com/mvdan/gofumpt) formatter for our go code, you can either use it directly or format via `make fmt`. +For linting we use [`golangci-lint`](github.com/golangci/golangci-lint), use `make validate` to run it together with some other basic commit checks. + ## Go Dependency updates To automatically keep dependencies up to date we use the [renovate](https://github.com/renovatebot/renovate) bot. diff --git a/Makefile b/Makefile index 533f7ca00f..0a4eff7dcd 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,12 @@ lint: .install.golangci-lint @$(MAKE) -C image lint @$(MAKE) -C storage lint +.PHONY: fmt +fmt: .install.golangci-lint + @$(MAKE) -C common fmt + @$(MAKE) -C image fmt + @$(MAKE) -C storage fmt + .PHONY: vendor-in-container vendor-in-container: podman run --privileged --rm --env HOME=/root -v `pwd`:/src -w /src golang make vendor diff --git a/common/Makefile b/common/Makefile index 9d7a1c3f5b..c32772e858 100644 --- a/common/Makefile +++ b/common/Makefile @@ -74,6 +74,10 @@ docs: lint: golangci-lint run +.PHONY: fmt +fmt: + golangci-lint fmt + .PHONY: validate validate: lint ./tools/validate_seccomp.sh ./pkg/seccomp diff --git a/image/.golangci.yml b/image/.golangci.yml index 763f695cbd..229173380f 100644 --- a/image/.golangci.yml +++ b/image/.golangci.yml @@ -1,4 +1,9 @@ version: "2" + +formatters: + enable: + - gofumpt + linters: enable: - errorlint diff --git a/image/Makefile b/image/Makefile index 2340ae1bcb..d47d43aeb6 100644 --- a/image/Makefile +++ b/image/Makefile @@ -75,7 +75,7 @@ test: .PHONY: fmt fmt: - @gofmt -l -s -w $(SOURCE_DIRS) + golangci-lint fmt .PHONY: lint lint: diff --git a/image/copy/blob.go b/image/copy/blob.go index a881e06238..9db6338d75 100644 --- a/image/copy/blob.go +++ b/image/copy/blob.go @@ -18,7 +18,8 @@ import ( // and returns a complete blobInfo of the copied blob. func (ic *imageCopier) copyBlobFromStream(ctx context.Context, srcReader io.Reader, srcInfo types.BlobInfo, getOriginalLayerCopyWriter func(decompressor compressiontypes.DecompressorFunc) io.Writer, - isConfig bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool) (types.BlobInfo, error) { + isConfig bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool, +) (types.BlobInfo, error) { // The copying happens through a pipeline of connected io.Readers; // that pipeline is built by updating stream. // === Input: srcReader diff --git a/image/copy/compression.go b/image/copy/compression.go index e3e5230292..5b57bf1764 100644 --- a/image/copy/compression.go +++ b/image/copy/compression.go @@ -109,7 +109,8 @@ const ( // Returns data for other steps; the caller should eventually call updateCompressionEdits and perhaps recordValidatedBlobData, // and must eventually call close. func (ic *imageCopier) blobPipelineCompressionStep(stream *sourceStream, canModifyBlob bool, srcInfo types.BlobInfo, - detected bpDetectCompressionStepData) (*bpCompressionStepData, error) { + detected bpDetectCompressionStepData, +) (*bpCompressionStepData, error) { // WARNING: If you are adding new reasons to change the blob, update also the OptimizeDestinationImageAlreadyExists // short-circuit conditions layerCompressionChangeSupported := ic.src.CanChangeLayerCompression(stream.info.MediaType) @@ -265,7 +266,8 @@ func (ic *imageCopier) bpcDecompressCompressed(stream *sourceStream, detected bp // This does not change the sourceStream parameter; we include it for symmetry with other // pipeline steps. func (ic *imageCopier) bpcPreserveOriginal(_ *sourceStream, detected bpDetectCompressionStepData, - layerCompressionChangeSupported bool) *bpCompressionStepData { + layerCompressionChangeSupported bool, +) *bpCompressionStepData { logrus.Debugf("Using original blob without modification") // Remember if the original blob was compressed, and if so how, so that if // LayerInfosForCopy() returned something that differs from what was in the @@ -320,7 +322,8 @@ func (d *bpCompressionStepData) updateCompressionEdits(operation *types.LayerCom // and the original srcInfo (which the caller guarantees has been validated). // This must ONLY be called if all data has been validated by OUR code, and is not coming from third parties. func (d *bpCompressionStepData) recordValidatedDigestData(c *copier, uploadedInfo types.BlobInfo, srcInfo types.BlobInfo, - encryptionStep *bpEncryptionStepData, decryptionStep *bpDecryptionStepData) error { + encryptionStep *bpEncryptionStepData, decryptionStep *bpDecryptionStepData, +) error { // Don’t record any associations that involve encrypted data. This is a bit crude, // some blob substitutions (replacing pulls of encrypted data with local reuse of known decryption outcomes) // might be safe, but it’s not trivially obvious, so let’s be conservative for now. diff --git a/image/copy/encryption.go b/image/copy/encryption.go index 59aecf1a11..0b7396d8a2 100644 --- a/image/copy/encryption.go +++ b/image/copy/encryption.go @@ -84,7 +84,8 @@ type bpEncryptionStepData struct { // srcInfo is primarily used for error messages. // Returns data for other steps; the caller should eventually call updateCryptoOperationAndAnnotations. func (ic *imageCopier) blobPipelineEncryptionStep(stream *sourceStream, toEncrypt bool, srcInfo types.BlobInfo, - decryptionStep *bpDecryptionStepData) (*bpEncryptionStepData, error) { + decryptionStep *bpDecryptionStepData, +) (*bpEncryptionStepData, error) { if !toEncrypt || isOciEncrypted(srcInfo.MediaType) || ic.c.options.OciEncryptConfig == nil { return &bpEncryptionStepData{ encrypting: false, diff --git a/image/copy/manifest_test.go b/image/copy/manifest_test.go index da7098753f..8b3e02c4ab 100644 --- a/image/copy/manifest_test.go +++ b/image/copy/manifest_test.go @@ -126,7 +126,8 @@ func TestDetermineManifestConversion(t *testing.T) { }, // Conversion necessary, a preferred format is not acceptable { - "s2→OCI", manifest.DockerV2Schema2MediaType, []string{v1.MediaTypeImageManifest}, + "s2→OCI", manifest.DockerV2Schema2MediaType, + []string{v1.MediaTypeImageManifest}, manifestConversionPlan{ preferredMIMEType: v1.MediaTypeImageManifest, preferredMIMETypeNeedsConversion: true, @@ -135,7 +136,8 @@ func TestDetermineManifestConversion(t *testing.T) { }, // text/plain is converted if the destination does not accept s1 { - "text→s2", "text/plain", []string{manifest.DockerV2Schema2MediaType}, + "text→s2", "text/plain", + []string{manifest.DockerV2Schema2MediaType}, manifestConversionPlan{ preferredMIMEType: manifest.DockerV2Schema2MediaType, preferredMIMETypeNeedsConversion: true, @@ -162,7 +164,8 @@ func TestDetermineManifestConversion(t *testing.T) { }, }, { - "special→OCI", manifest.DockerV2ListMediaType, []string{v1.MediaTypeImageManifest, "other options", "with lower priority"}, + "special→OCI", manifest.DockerV2ListMediaType, + []string{v1.MediaTypeImageManifest, "other options", "with lower priority"}, manifestConversionPlan{ preferredMIMEType: v1.MediaTypeImageManifest, preferredMIMETypeNeedsConversion: true, diff --git a/image/copy/multiple.go b/image/copy/multiple.go index 0594aa20f5..85bba72885 100644 --- a/image/copy/multiple.go +++ b/image/copy/multiple.go @@ -60,8 +60,9 @@ func platformV1ToPlatformComparable(platform *imgspecv1.Platform) platformCompar } osFeatures := slices.Clone(platform.OSFeatures) sort.Strings(osFeatures) - return platformComparable{architecture: platform.Architecture, - os: platform.OS, + return platformComparable{ + architecture: platform.Architecture, + os: platform.OS, // This is strictly speaking ambiguous, fields of OSFeatures can contain a ','. Probably good enough for now. osFeatures: strings.Join(osFeatures, ","), osVersion: platform.OSVersion, @@ -252,7 +253,8 @@ func (c *copier) copyMultipleImages(ctx context.Context) (copiedManifest []byte, UpdateDigest: updated.manifestDigest, UpdateSize: int64(len(updated.manifest)), UpdateCompressionAlgorithms: updated.compressionAlgorithms, - UpdateMediaType: updated.manifestMIMEType}) + UpdateMediaType: updated.manifestMIMEType, + }) case instanceCopyClone: logrus.Debugf("Replicating instance %s (%d/%d)", instance.sourceDigest, i+1, len(instanceCopyList)) c.Printf("Replicating image %s (%d/%d)\n", instance.sourceDigest, i+1, len(instanceCopyList)) @@ -260,7 +262,8 @@ func (c *copier) copyMultipleImages(ctx context.Context) (copiedManifest []byte, updated, err := c.copySingleImage(ctx, unparsedInstance, &instanceCopyList[i].sourceDigest, copySingleImageOptions{ requireCompressionFormatMatch: true, compressionFormat: &instance.cloneCompressionVariant.Algorithm, - compressionLevel: instance.cloneCompressionVariant.Level}) + compressionLevel: instance.cloneCompressionVariant.Level, + }) if err != nil { return nil, fmt.Errorf("replicating image %d/%d from manifest list: %w", i+1, len(instanceCopyList), err) } diff --git a/image/copy/multiple_test.go b/image/copy/multiple_test.go index 5026f7d835..d6fdd40603 100644 --- a/image/copy/multiple_test.go +++ b/image/copy/multiple_test.go @@ -31,16 +31,20 @@ func TestPrepareCopyInstancesforInstanceCopyCopy(t *testing.T) { compare := []instanceCopy{} for _, instance := range sourceInstances { - compare = append(compare, instanceCopy{op: instanceCopyCopy, - sourceDigest: instance, copyForceCompressionFormat: false}) + compare = append(compare, instanceCopy{ + op: instanceCopyCopy, + sourceDigest: instance, copyForceCompressionFormat: false, + }) } assert.Equal(t, instancesToCopy, compare) // Test CopySpecificImages where selected instance is sourceInstances[1] instancesToCopy, err = prepareInstanceCopies(list, sourceInstances, &Options{Instances: []digest.Digest{sourceInstances[1]}, ImageListSelection: CopySpecificImages}) require.NoError(t, err) - compare = []instanceCopy{{op: instanceCopyCopy, - sourceDigest: sourceInstances[1]}} + compare = []instanceCopy{{ + op: instanceCopyCopy, + sourceDigest: sourceInstances[1], + }} assert.Equal(t, instancesToCopy, compare) _, err = prepareInstanceCopies(list, sourceInstances, &Options{Instances: []digest.Digest{sourceInstances[1]}, ImageListSelection: CopySpecificImages, ForceCompressionFormat: true}) @@ -64,9 +68,11 @@ func TestPrepareCopyInstancesforInstanceCopyClone(t *testing.T) { } // CopySpecificImage must fail with error - _, err = prepareInstanceCopies(list, sourceInstances, &Options{EnsureCompressionVariantsExist: ensureCompressionVariantsExist, - Instances: []digest.Digest{sourceInstances[1]}, - ImageListSelection: CopySpecificImages}) + _, err = prepareInstanceCopies(list, sourceInstances, &Options{ + EnsureCompressionVariantsExist: ensureCompressionVariantsExist, + Instances: []digest.Digest{sourceInstances[1]}, + ImageListSelection: CopySpecificImages, + }) require.EqualError(t, err, "EnsureCompressionVariantsExist is not implemented for CopySpecificImages") // Test copying all images with replication @@ -83,8 +89,10 @@ func TestPrepareCopyInstancesforInstanceCopyClone(t *testing.T) { // and still copy `sourceInstance[2]`. expectedResponse := []simplerInstanceCopy{} for _, instance := range sourceInstances { - expectedResponse = append(expectedResponse, simplerInstanceCopy{op: instanceCopyCopy, - sourceDigest: instance}) + expectedResponse = append(expectedResponse, simplerInstanceCopy{ + op: instanceCopyCopy, + sourceDigest: instance, + }) // If its `arm64` and sourceDigest[2] , expect a clone to happen if instance == sourceInstances[2] { expectedResponse = append(expectedResponse, simplerInstanceCopy{op: instanceCopyClone, sourceDigest: instance, cloneCompressionVariant: "zstd", clonePlatform: "arm64-linux-"}) @@ -100,8 +108,10 @@ func TestPrepareCopyInstancesforInstanceCopyClone(t *testing.T) { require.NoError(t, err) expectedResponse = []simplerInstanceCopy{} for _, instance := range sourceInstances { - expectedResponse = append(expectedResponse, simplerInstanceCopy{op: instanceCopyCopy, - sourceDigest: instance}) + expectedResponse = append(expectedResponse, simplerInstanceCopy{ + op: instanceCopyCopy, + sourceDigest: instance, + }) // If its `arm64` and sourceDigest[2] , expect a clone to happen if instance == sourceInstances[2] { expectedResponse = append(expectedResponse, simplerInstanceCopy{op: instanceCopyClone, sourceDigest: instance, cloneCompressionVariant: "zstd", clonePlatform: "arm64-linux-"}) diff --git a/image/copy/progress_channel_test.go b/image/copy/progress_channel_test.go index 9707e1a02a..6b4bb16863 100644 --- a/image/copy/progress_channel_test.go +++ b/image/copy/progress_channel_test.go @@ -76,5 +76,4 @@ func TestReadWithEvent(t *testing.T) { read, err := reader.Read(b) assert.Equal(t, read, 5) assert.Nil(t, err) - } diff --git a/image/copy/sign.go b/image/copy/sign.go index 96038f3f83..70295538d0 100644 --- a/image/copy/sign.go +++ b/image/copy/sign.go @@ -54,7 +54,8 @@ func (c *copier) setupSigners() error { // and verifies that they can be used (to avoid copying a large image when we // can tell in advance that it would ultimately fail) func (c *copier) sourceSignatures(ctx context.Context, unparsed private.UnparsedImage, - gettingSignaturesMessage, checkingDestMessage string) ([]internalsig.Signature, error) { + gettingSignaturesMessage, checkingDestMessage string, +) ([]internalsig.Signature, error) { var sigs []internalsig.Signature if c.options.RemoveSignatures { sigs = []internalsig.Signature{} diff --git a/image/copy/single.go b/image/copy/single.go index 5c81fd2d53..588ad9ab3a 100644 --- a/image/copy/single.go +++ b/image/copy/single.go @@ -934,7 +934,8 @@ func updatedBlobInfoFromReuse(inputInfo types.BlobInfo, reusedBlob private.Reuse // perhaps (de/re/)compressing the stream, // and returns a complete blobInfo of the copied blob and perhaps a <-chan diffIDResult if diffIDIsNeeded, to be read by the caller. func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo, - diffIDIsNeeded bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool) (types.BlobInfo, <-chan diffIDResult, error) { + diffIDIsNeeded bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool, +) (types.BlobInfo, <-chan diffIDResult, error) { var getDiffIDRecorder func(compressiontypes.DecompressorFunc) io.Writer // = nil var diffIDChan chan diffIDResult diff --git a/image/directory/directory_dest.go b/image/directory/directory_dest.go index 31842f7260..fc82c969f1 100644 --- a/image/directory/directory_dest.go +++ b/image/directory/directory_dest.go @@ -90,12 +90,12 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (private.Im } } else { // create directory if it doesn't exist - if err := os.MkdirAll(ref.resolvedPath, 0755); err != nil { + if err := os.MkdirAll(ref.resolvedPath, 0o755); err != nil { return nil, fmt.Errorf("unable to create directory %q: %w", ref.resolvedPath, err) } } // create version file - err = os.WriteFile(ref.versionPath(), []byte(version), 0644) + err = os.WriteFile(ref.versionPath(), []byte(version), 0o644) if err != nil { return nil, fmt.Errorf("creating version file %q: %w", ref.versionPath(), err) } @@ -170,7 +170,7 @@ func (d *dirImageDestination) PutBlobWithOptions(ctx context.Context, stream io. // ignored and the file is already readable; besides, blobFile.Chmod, i.e. syscall.Fchmod, // always fails on Windows. if runtime.GOOS != "windows" { - if err := blobFile.Chmod(0644); err != nil { + if err := blobFile.Chmod(0o644); err != nil { return private.UploadedBlob{}, err } } @@ -228,7 +228,7 @@ func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, if err != nil { return err } - return os.WriteFile(path, manifest, 0644) + return os.WriteFile(path, manifest, 0o644) } // PutSignaturesWithFormat writes a set of signatures to the destination. @@ -245,7 +245,7 @@ func (d *dirImageDestination) PutSignaturesWithFormat(ctx context.Context, signa if err != nil { return err } - if err := os.WriteFile(path, blob, 0644); err != nil { + if err := os.WriteFile(path, blob, 0o644); err != nil { return err } } diff --git a/image/directory/directory_test.go b/image/directory/directory_test.go index fe00b6738c..1d5fb96947 100644 --- a/image/directory/directory_test.go +++ b/image/directory/directory_test.go @@ -17,8 +17,10 @@ import ( "go.podman.io/image/v5/types" ) -var _ private.ImageSource = (*dirImageSource)(nil) -var _ private.ImageDestination = (*dirImageDestination)(nil) +var ( + _ private.ImageSource = (*dirImageSource)(nil) + _ private.ImageDestination = (*dirImageDestination)(nil) +) func TestDestinationReference(t *testing.T) { ref, tmpDir := refToTempDir(t) diff --git a/image/directory/explicitfilepath/path_test.go b/image/directory/explicitfilepath/path_test.go index 3a9db35f7a..5df97c21b8 100644 --- a/image/directory/explicitfilepath/path_test.go +++ b/image/directory/explicitfilepath/path_test.go @@ -19,7 +19,7 @@ type pathResolvingTestCase struct { var testCases = []pathResolvingTestCase{ { // A straightforward subdirectory hierarchy func(t *testing.T, top string) string { - err := os.MkdirAll(filepath.Join(top, "dir1/dir2/dir3"), 0755) + err := os.MkdirAll(filepath.Join(top, "dir1/dir2/dir3"), 0o755) require.NoError(t, err) return "dir1/dir2/dir3" }, @@ -33,7 +33,7 @@ var testCases = []pathResolvingTestCase{ }, { // Symlink on the path func(t *testing.T, top string) string { - err := os.MkdirAll(filepath.Join(top, "dir1/dir2"), 0755) + err := os.MkdirAll(filepath.Join(top, "dir1/dir2"), 0o755) require.NoError(t, err) err = os.Symlink("dir1", filepath.Join(top, "link1")) require.NoError(t, err) @@ -43,7 +43,7 @@ var testCases = []pathResolvingTestCase{ }, { // Trailing symlink func(t *testing.T, top string) string { - err := os.MkdirAll(filepath.Join(top, "dir1/dir2"), 0755) + err := os.MkdirAll(filepath.Join(top, "dir1/dir2"), 0o755) require.NoError(t, err) err = os.Symlink("dir2", filepath.Join(top, "dir1/link2")) require.NoError(t, err) @@ -69,7 +69,7 @@ var testCases = []pathResolvingTestCase{ }, { // Relative components in a path func(t *testing.T, top string) string { - err := os.MkdirAll(filepath.Join(top, "dir1/dir2/dir3"), 0755) + err := os.MkdirAll(filepath.Join(top, "dir1/dir2/dir3"), 0o755) require.NoError(t, err) return "dir1/./dir2/../dir2/dir3" }, @@ -77,7 +77,7 @@ var testCases = []pathResolvingTestCase{ }, { // Trailing relative components func(t *testing.T, top string) string { - err := os.MkdirAll(filepath.Join(top, "dir1/dir2"), 0755) + err := os.MkdirAll(filepath.Join(top, "dir1/dir2"), 0o755) require.NoError(t, err) return "dir1/dir2/.." }, @@ -85,7 +85,7 @@ var testCases = []pathResolvingTestCase{ }, { // Relative components in symlink func(t *testing.T, top string) string { - err := os.MkdirAll(filepath.Join(top, "dir1/dir2"), 0755) + err := os.MkdirAll(filepath.Join(top, "dir1/dir2"), 0o755) require.NoError(t, err) err = os.Symlink("../dir1/dir2", filepath.Join(top, "dir1/link2")) require.NoError(t, err) @@ -95,7 +95,7 @@ var testCases = []pathResolvingTestCase{ }, { // Relative component pointing "into" a symlink func(t *testing.T, top string) string { - err := os.MkdirAll(filepath.Join(top, "dir1/dir2/dir3"), 0755) + err := os.MkdirAll(filepath.Join(top, "dir1/dir2/dir3"), 0o755) require.NoError(t, err) err = os.Symlink("dir3", filepath.Join(top, "dir1/dir2/link3")) require.NoError(t, err) @@ -105,9 +105,9 @@ var testCases = []pathResolvingTestCase{ }, { // Unreadable directory func(t *testing.T, top string) string { - err := os.MkdirAll(filepath.Join(top, "unreadable/dir2"), 0755) + err := os.MkdirAll(filepath.Join(top, "unreadable/dir2"), 0o755) require.NoError(t, err) - err = os.Chmod(filepath.Join(top, "unreadable"), 000) + err = os.Chmod(filepath.Join(top, "unreadable"), 0o00) require.NoError(t, err) return "unreadable/dir2" }, @@ -127,7 +127,7 @@ func runPathResolvingTestCase(t *testing.T, f func(string) (string, error), c pa topDir := t.TempDir() defer func() { // Clean up after the "Unreadable directory" case; os.RemoveAll just fails without this. - _ = os.Chmod(filepath.Join(topDir, "unreadable"), 0755) // Ignore errors, especially if this does not exist. + _ = os.Chmod(filepath.Join(topDir, "unreadable"), 0o755) // Ignore errors, especially if this does not exist. }() input := c.setup(t, topDir) + suffix // Do not call filepath.Join() on input, it calls filepath.Clean() internally! diff --git a/image/docker/archive/transport.go b/image/docker/archive/transport.go index 706655ddcf..a1b77adbef 100644 --- a/image/docker/archive/transport.go +++ b/image/docker/archive/transport.go @@ -110,7 +110,8 @@ func NewIndexReference(path string, sourceIndex int) (types.ImageReference, erro // newReference returns a docker archive reference for a path, an optional reference or sourceIndex, // and optionally a tarfile.Reader and/or a tarfile.Writer matching path. func newReference(path string, ref reference.NamedTagged, sourceIndex int, - archiveReader *tarfile.Reader, writer *Writer) (types.ImageReference, error) { + archiveReader *tarfile.Reader, writer *Writer, +) (types.ImageReference, error) { if strings.Contains(path, ":") { return nil, fmt.Errorf("Invalid docker-archive: reference: colon in path %q is not supported", path) } diff --git a/image/docker/archive/transport_test.go b/image/docker/archive/transport_test.go index ce15ebff62..0b3c1b84a5 100644 --- a/image/docker/archive/transport_test.go +++ b/image/docker/archive/transport_test.go @@ -272,7 +272,7 @@ func TestReferenceDeleteImage(t *testing.T) { for i, suffix := range []string{"", ":some-reference", ":@0"} { testFile := filepath.Join(tmpDir, fmt.Sprintf("file%d.tar", i)) - err := os.WriteFile(testFile, []byte("nonempty"), 0644) + err := os.WriteFile(testFile, []byte("nonempty"), 0o644) require.NoError(t, err, suffix) ref, err := ParseReference(testFile + suffix) diff --git a/image/docker/archive/writer.go b/image/docker/archive/writer.go index 0a59d89d0a..ea8375bea9 100644 --- a/image/docker/archive/writer.go +++ b/image/docker/archive/writer.go @@ -32,7 +32,7 @@ func NewWriter(sys *types.SystemContext, path string) (*Writer, error) { // in the case of a regular file, we don't want to overwrite any pre-existing file // so we check for Size() == 0 below (This is racy, but using O_EXCL would also be racy, // only in a different way. Either way, it’s up to the user to not have two writers to the same path.) - fh, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) + fh, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644) if err != nil { return nil, fmt.Errorf("opening file %q: %w", path, err) } diff --git a/image/docker/daemon/client_test.go b/image/docker/daemon/client_test.go index 435600bcab..16f3b0fe97 100644 --- a/image/docker/daemon/client_test.go +++ b/image/docker/daemon/client_test.go @@ -69,7 +69,7 @@ func TestTlsConfigFromCertPath(t *testing.T) { } func TestSkipTLSVerifyOnly(t *testing.T) { - //testDir := testDir(t) + // testDir := testDir(t) ctx := &types.SystemContext{ DockerDaemonInsecureSkipTLSVerify: true, diff --git a/image/docker/daemon/daemon_dest.go b/image/docker/daemon/daemon_dest.go index 337ba63316..ebf7d238ec 100644 --- a/image/docker/daemon/daemon_dest.go +++ b/image/docker/daemon/daemon_dest.go @@ -38,10 +38,7 @@ func newImageDestination(ctx context.Context, sys *types.SystemContext, ref daem return nil, fmt.Errorf("Invalid destination docker-daemon:%s: a destination must be a name:tag", ref.StringWithinTransport()) } - var mustMatchRuntimeOS = true - if sys != nil && sys.DockerDaemonHost != client.DefaultDockerHost { - mustMatchRuntimeOS = false - } + mustMatchRuntimeOS := sys == nil || sys.DockerDaemonHost == client.DefaultDockerHost c, err := newDockerClient(sys) if err != nil { diff --git a/image/docker/docker_client.go b/image/docker/docker_client.go index 467879c236..b166bfbf2e 100644 --- a/image/docker/docker_client.go +++ b/image/docker/docker_client.go @@ -823,7 +823,8 @@ func (c *dockerClient) obtainBearerToken(ctx context.Context, challenge challeng // https://github.com/distribution/distribution/blob/main/docs/spec/auth/oauth.md for challenge and scopes, // and writes it into dest. func (c *dockerClient) getBearerTokenOAuth2(ctx context.Context, dest *bearerToken, challenge challenge, - scopes []authScope) error { + scopes []authScope, +) error { realm, ok := challenge.Parameters["realm"] if !ok { return errors.New("missing realm in bearer auth challenge") @@ -870,7 +871,8 @@ func (c *dockerClient) getBearerTokenOAuth2(ctx context.Context, dest *bearerTok // https://github.com/distribution/distribution/blob/main/docs/spec/auth/token.md for challenge and scopes, // and writes it into dest. func (c *dockerClient) getBearerToken(ctx context.Context, dest *bearerToken, challenge challenge, - scopes []authScope) error { + scopes []authScope, +) error { realm, ok := challenge.Parameters["realm"] if !ok { return errors.New("missing realm in bearer auth challenge") diff --git a/image/docker/docker_client_test.go b/image/docker/docker_client_test.go index d5b9fd460f..229fea332f 100644 --- a/image/docker/docker_client_test.go +++ b/image/docker/docker_client_test.go @@ -294,7 +294,8 @@ func TestNeedsNoRetry(t *testing.T) { Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, - Header: map[string][]string{"Apptime": {"D=49722"}, + Header: map[string][]string{ + "Apptime": {"D=49722"}, "Content-Length": {"1683"}, "Content-Type": {"application/json; charset=utf-8"}, "Date": {"Fri, 26 Aug 2022 09:00:21 GMT"}, diff --git a/image/docker/docker_image_dest.go b/image/docker/docker_image_dest.go index 86077fe932..2172d0adc6 100644 --- a/image/docker/docker_image_dest.go +++ b/image/docker/docker_image_dest.go @@ -679,7 +679,7 @@ func (d *dockerImageDestination) putOneSignature(sigURL *url.URL, sig signature. switch sigURL.Scheme { case "file": logrus.Debugf("Writing to %s", sigURL.Path) - err := os.MkdirAll(filepath.Dir(sigURL.Path), 0755) + err := os.MkdirAll(filepath.Dir(sigURL.Path), 0o755) if err != nil { return err } @@ -687,7 +687,7 @@ func (d *dockerImageDestination) putOneSignature(sigURL *url.URL, sig signature. if err != nil { return err } - err = os.WriteFile(sigURL.Path, blob, 0644) + err = os.WriteFile(sigURL.Path, blob, 0o644) if err != nil { return err } @@ -800,7 +800,8 @@ func (d *dockerImageDestination) putSignaturesToSigstoreAttachments(ctx context. } func layerMatchesSigstoreSignature(layer imgspecv1.Descriptor, mimeType string, - payloadBlob []byte, annotations map[string]string) bool { + payloadBlob []byte, annotations map[string]string, +) bool { if layer.MediaType != mimeType || layer.Size != int64(len(payloadBlob)) || // This is not quite correct, we should use the layer’s digest algorithm. diff --git a/image/docker/docker_image_src.go b/image/docker/docker_image_src.go index 553dddeefe..4003af5d27 100644 --- a/image/docker/docker_image_src.go +++ b/image/docker/docker_image_src.go @@ -129,7 +129,8 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef // Given a logicalReference and a pullSource, return a dockerImageSource if it is reachable. // The caller must call .Close() on the returned ImageSource. func newImageSourceAttempt(ctx context.Context, sys *types.SystemContext, logicalRef dockerReference, pullSource sysregistriesv2.PullSource, - registryConfig *registryConfiguration) (*dockerImageSource, error) { + registryConfig *registryConfiguration, +) (*dockerImageSource, error) { physicalRef, err := newReference(pullSource.Reference, false) if err != nil { return nil, err diff --git a/image/docker/docker_image_src_test.go b/image/docker/docker_image_src_test.go index c1322ccc71..bb4f97e421 100644 --- a/image/docker/docker_image_src_test.go +++ b/image/docker/docker_image_src_test.go @@ -54,7 +54,7 @@ location = "@REGISTRY@/with-mirror" require.NoError(t, err) defer registriesConf.Close() defer os.Remove(registriesConf.Name()) - err = os.WriteFile(registriesConf.Name(), []byte(mirrorConfiguration), 0600) + err = os.WriteFile(registriesConf.Name(), []byte(mirrorConfiguration), 0o600) require.NoError(t, err) for _, c := range []struct{ input, physical string }{ diff --git a/image/docker/internal/tarfile/dest.go b/image/docker/internal/tarfile/dest.go index 812749bad9..d078f4daee 100644 --- a/image/docker/internal/tarfile/dest.go +++ b/image/docker/internal/tarfile/dest.go @@ -39,7 +39,8 @@ type Destination struct { // NewDestination returns a tarfile.Destination adding images to the specified Writer. // commitWithOptions implements ImageDestination.CommitWithOptions. func NewDestination(sys *types.SystemContext, archive *Writer, transportName string, ref reference.NamedTagged, - commitWithOptions func(ctx context.Context, options private.CommitOptions) error) *Destination { + commitWithOptions func(ctx context.Context, options private.CommitOptions) error, +) *Destination { repoTags := []reference.NamedTagged{} if ref != nil { repoTags = append(repoTags, ref) diff --git a/image/docker/internal/tarfile/writer.go b/image/docker/internal/tarfile/writer.go index 460224f445..604da073a6 100644 --- a/image/docker/internal/tarfile/writer.go +++ b/image/docker/internal/tarfile/writer.go @@ -338,21 +338,26 @@ type tarFI struct { func (t *tarFI) Name() string { return t.path } + func (t *tarFI) Size() int64 { return t.size } + func (t *tarFI) Mode() os.FileMode { if t.isSymlink { return os.ModeSymlink } - return 0444 + return 0o444 } + func (t *tarFI) ModTime() time.Time { return time.Unix(0, 0) } + func (t *tarFI) IsDir() bool { return false } + func (t *tarFI) Sys() any { return nil } diff --git a/image/docker/reference/regexp_test.go b/image/docker/reference/regexp_test.go index 289e559fd2..b9842e9eef 100644 --- a/image/docker/reference/regexp_test.go +++ b/image/docker/reference/regexp_test.go @@ -489,7 +489,6 @@ func TestReferenceRegexp(t *testing.T) { for i := range testcases { checkRegexp(t, ReferenceRegexp, testcases[i]) } - } func TestIdentifierRegexp(t *testing.T) { diff --git a/image/docker/registries_d_test.go b/image/docker/registries_d_test.go index edc962b262..3d54e933f3 100644 --- a/image/docker/registries_d_test.go +++ b/image/docker/registries_d_test.go @@ -71,7 +71,7 @@ func TestRegistriesDirPath(t *testing.T) { const variableReference = "$HOME" const rootPrefix = "/root/prefix" tempHome := t.TempDir() - var userRegistriesDir = filepath.FromSlash(".config/containers/registries.d") + userRegistriesDir := filepath.FromSlash(".config/containers/registries.d") userRegistriesDirPath := filepath.Join(tempHome, userRegistriesDir) for _, c := range []struct { sys *types.SystemContext @@ -116,7 +116,7 @@ func TestRegistriesDirPath(t *testing.T) { {&types.SystemContext{RegistriesDirPath: variableReference}, false, variableReference}, } { if c.userFilePresent { - err := os.MkdirAll(userRegistriesDirPath, 0700) + err := os.MkdirAll(userRegistriesDirPath, 0o700) require.NoError(t, err) } else { err := os.RemoveAll(userRegistriesDirPath) @@ -137,7 +137,7 @@ func TestLoadAndMergeConfig(t *testing.T) { // Empty registries.d directory emptyDir := filepath.Join(tmpDir, "empty") - err = os.Mkdir(emptyDir, 0755) + err = os.Mkdir(emptyDir, 0o755) require.NoError(t, err) config, err = loadAndMergeConfig(emptyDir) require.NoError(t, err) @@ -145,40 +145,40 @@ func TestLoadAndMergeConfig(t *testing.T) { // Unreadable registries.d directory unreadableDir := filepath.Join(tmpDir, "unreadable") - err = os.Mkdir(unreadableDir, 0000) + err = os.Mkdir(unreadableDir, 0o000) require.NoError(t, err) _, err = loadAndMergeConfig(unreadableDir) assert.Error(t, err) // An unreadable file in a registries.d directory unreadableFileDir := filepath.Join(tmpDir, "unreadableFile") - err = os.Mkdir(unreadableFileDir, 0755) + err = os.Mkdir(unreadableFileDir, 0o755) require.NoError(t, err) - err = os.WriteFile(filepath.Join(unreadableFileDir, "0.yaml"), []byte("{}"), 0644) + err = os.WriteFile(filepath.Join(unreadableFileDir, "0.yaml"), []byte("{}"), 0o644) require.NoError(t, err) - err = os.WriteFile(filepath.Join(unreadableFileDir, "1.yaml"), nil, 0000) + err = os.WriteFile(filepath.Join(unreadableFileDir, "1.yaml"), nil, 0o000) require.NoError(t, err) _, err = loadAndMergeConfig(unreadableFileDir) assert.Error(t, err) // Invalid YAML invalidYAMLDir := filepath.Join(tmpDir, "invalidYAML") - err = os.Mkdir(invalidYAMLDir, 0755) + err = os.Mkdir(invalidYAMLDir, 0o755) require.NoError(t, err) - err = os.WriteFile(filepath.Join(invalidYAMLDir, "0.yaml"), []byte("}"), 0644) + err = os.WriteFile(filepath.Join(invalidYAMLDir, "0.yaml"), []byte("}"), 0o644) require.NoError(t, err) _, err = loadAndMergeConfig(invalidYAMLDir) assert.Error(t, err) // Duplicate DefaultDocker duplicateDefault := filepath.Join(tmpDir, "duplicateDefault") - err = os.Mkdir(duplicateDefault, 0755) + err = os.Mkdir(duplicateDefault, 0o755) require.NoError(t, err) err = os.WriteFile(filepath.Join(duplicateDefault, "0.yaml"), - []byte("default-docker:\n lookaside: file:////tmp/something"), 0644) + []byte("default-docker:\n lookaside: file:////tmp/something"), 0o644) require.NoError(t, err) err = os.WriteFile(filepath.Join(duplicateDefault, "1.yaml"), - []byte("default-docker:\n lookaside: file:////tmp/different"), 0644) + []byte("default-docker:\n lookaside: file:////tmp/different"), 0o644) require.NoError(t, err) _, err = loadAndMergeConfig(duplicateDefault) assert.ErrorContains(t, err, "0.yaml") @@ -186,13 +186,13 @@ func TestLoadAndMergeConfig(t *testing.T) { // Duplicate DefaultDocker duplicateNS := filepath.Join(tmpDir, "duplicateNS") - err = os.Mkdir(duplicateNS, 0755) + err = os.Mkdir(duplicateNS, 0o755) require.NoError(t, err) err = os.WriteFile(filepath.Join(duplicateNS, "0.yaml"), - []byte("docker:\n example.com:\n lookaside: file:////tmp/something"), 0644) + []byte("docker:\n example.com:\n lookaside: file:////tmp/something"), 0o644) require.NoError(t, err) err = os.WriteFile(filepath.Join(duplicateNS, "1.yaml"), - []byte("docker:\n example.com:\n lookaside: file:////tmp/different"), 0644) + []byte("docker:\n example.com:\n lookaside: file:////tmp/different"), 0o644) require.NoError(t, err) _, err = loadAndMergeConfig(duplicateNS) assert.ErrorContains(t, err, "0.yaml") diff --git a/image/internal/image/docker_schema1_test.go b/image/internal/image/docker_schema1_test.go index 9d399eae4c..b23bed7423 100644 --- a/image/internal/image/docker_schema1_test.go +++ b/image/internal/image/docker_schema1_test.go @@ -303,32 +303,37 @@ func TestManifestSchema1Inspect(t *testing.T) { "sha256:62e48e39dc5b30b75a97f05bccc66efbae6058b860ee20a5c9a184b9d5e25788", "sha256:e623934bca8d1a74f51014256445937714481e49343a31bda2bc5f534748184d", }, - LayersData: []types.ImageInspectLayer{{ - MIMEType: "", - Digest: "sha256:9cadd93b16ff2a0c51ac967ea2abfadfac50cfa3af8b5bf983d89b8f8647f3e4", - Size: -1, - Annotations: emptyAnnotations, - }, { - MIMEType: "", - Digest: "sha256:4aa565ad8b7a87248163ce7dba1dd3894821aac97e846b932ff6b8ef9a8a508a", - Size: -1, - Annotations: emptyAnnotations, - }, { - MIMEType: "", - Digest: "sha256:f576d102e09b9eef0e305aaef705d2d43a11bebc3fd5810a761624bd5e11997e", - Size: -1, - Annotations: emptyAnnotations, - }, { - MIMEType: "", - Digest: "sha256:9e92df2aea7dc0baf5f1f8d509678d6a6306de27ad06513f8e218371938c07a6", - Size: -1, - Annotations: emptyAnnotations, - }, { - MIMEType: "", - Digest: "sha256:62e48e39dc5b30b75a97f05bccc66efbae6058b860ee20a5c9a184b9d5e25788", - Size: -1, - Annotations: emptyAnnotations, - }, + LayersData: []types.ImageInspectLayer{ + { + MIMEType: "", + Digest: "sha256:9cadd93b16ff2a0c51ac967ea2abfadfac50cfa3af8b5bf983d89b8f8647f3e4", + Size: -1, + Annotations: emptyAnnotations, + }, + { + MIMEType: "", + Digest: "sha256:4aa565ad8b7a87248163ce7dba1dd3894821aac97e846b932ff6b8ef9a8a508a", + Size: -1, + Annotations: emptyAnnotations, + }, + { + MIMEType: "", + Digest: "sha256:f576d102e09b9eef0e305aaef705d2d43a11bebc3fd5810a761624bd5e11997e", + Size: -1, + Annotations: emptyAnnotations, + }, + { + MIMEType: "", + Digest: "sha256:9e92df2aea7dc0baf5f1f8d509678d6a6306de27ad06513f8e218371938c07a6", + Size: -1, + Annotations: emptyAnnotations, + }, + { + MIMEType: "", + Digest: "sha256:62e48e39dc5b30b75a97f05bccc66efbae6058b860ee20a5c9a184b9d5e25788", + Size: -1, + Annotations: emptyAnnotations, + }, { MIMEType: "", Digest: "sha256:e623934bca8d1a74f51014256445937714481e49343a31bda2bc5f534748184d", diff --git a/image/internal/image/docker_schema2_test.go b/image/internal/image/docker_schema2_test.go index 788eb70876..b51db63240 100644 --- a/image/internal/image/docker_schema2_test.go +++ b/image/internal/image/docker_schema2_test.go @@ -268,32 +268,33 @@ func TestManifestSchema2Inspect(t *testing.T) { "sha256:bbd6b22eb11afce63cc76f6bc41042d99f10d6024c96b655dafba930b8d25909", "sha256:960e52ecf8200cbd84e70eb2ad8678f4367e50d14357021872c10fa3fc5935fa", }, - LayersData: []types.ImageInspectLayer{{ - MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", - Digest: "sha256:6a5a5368e0c2d3e5909184fa28ddfd56072e7ff3ee9a945876f7eee5896ef5bb", - Size: 51354364, - Annotations: emptyAnnotations, - }, { - MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", - Digest: "sha256:1bbf5d58d24c47512e234a5623474acf65ae00d4d1414272a893204f44cc680c", - Size: 150, - Annotations: emptyAnnotations, - }, { - MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", - Digest: "sha256:8f5dc8a4b12c307ac84de90cdd9a7f3915d1be04c9388868ca118831099c67a9", - Size: 11739507, - Annotations: emptyAnnotations, - }, { - MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", - Digest: "sha256:bbd6b22eb11afce63cc76f6bc41042d99f10d6024c96b655dafba930b8d25909", - Size: 8841833, - Annotations: emptyAnnotations, - }, { - MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", - Digest: "sha256:960e52ecf8200cbd84e70eb2ad8678f4367e50d14357021872c10fa3fc5935fa", - Size: 291, - Annotations: emptyAnnotations, - }, + LayersData: []types.ImageInspectLayer{ + { + MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", + Digest: "sha256:6a5a5368e0c2d3e5909184fa28ddfd56072e7ff3ee9a945876f7eee5896ef5bb", + Size: 51354364, + Annotations: emptyAnnotations, + }, { + MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", + Digest: "sha256:1bbf5d58d24c47512e234a5623474acf65ae00d4d1414272a893204f44cc680c", + Size: 150, + Annotations: emptyAnnotations, + }, { + MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", + Digest: "sha256:8f5dc8a4b12c307ac84de90cdd9a7f3915d1be04c9388868ca118831099c67a9", + Size: 11739507, + Annotations: emptyAnnotations, + }, { + MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", + Digest: "sha256:bbd6b22eb11afce63cc76f6bc41042d99f10d6024c96b655dafba930b8d25909", + Size: 8841833, + Annotations: emptyAnnotations, + }, { + MIMEType: "application/vnd.docker.image.rootfs.diff.tar.gzip", + Digest: "sha256:960e52ecf8200cbd84e70eb2ad8678f4367e50d14357021872c10fa3fc5935fa", + Size: 291, + Annotations: emptyAnnotations, + }, }, Author: "", Env: []string{ @@ -373,30 +374,39 @@ type memoryImageDest struct { func (d *memoryImageDest) Reference() types.ImageReference { return refImageReferenceMock{ref: d.ref} } + func (d *memoryImageDest) Close() error { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) SupportedManifestMIMETypes() []string { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) SupportsSignatures(ctx context.Context) error { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) DesiredLayerCompression() types.LayerCompression { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) AcceptsForeignLayerURLs() bool { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) MustMatchRuntimeOS() bool { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) IgnoresEmbeddedDockerReference() bool { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) HasThreadSafePutBlob() bool { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) PutBlob(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) { if d.storedBlobs == nil { d.storedBlobs = make(map[digest.Digest][]byte) @@ -411,15 +421,19 @@ func (d *memoryImageDest) PutBlob(ctx context.Context, stream io.Reader, inputIn d.storedBlobs[inputInfo.Digest] = contents return types.BlobInfo{Digest: inputInfo.Digest, Size: int64(len(contents))}, nil } + func (d *memoryImageDest) TryReusingBlob(context.Context, types.BlobInfo, types.BlobInfoCache, bool) (bool, types.BlobInfo, error) { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) PutManifest(context.Context, []byte, *digest.Digest) error { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) PutSignatures(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error { panic("Unexpected call to a mock function") } + func (d *memoryImageDest) Commit(context.Context, types.UnparsedImage) error { panic("Unexpected call to a mock function") } diff --git a/image/internal/image/oci_test.go b/image/internal/image/oci_test.go index 9f3837883f..af6ee7349f 100644 --- a/image/internal/image/oci_test.go +++ b/image/internal/image/oci_test.go @@ -326,32 +326,33 @@ func TestManifestOCI1Inspect(t *testing.T) { "sha256:bbd6b22eb11afce63cc76f6bc41042d99f10d6024c96b655dafba930b8d25909", "sha256:960e52ecf8200cbd84e70eb2ad8678f4367e50d14357021872c10fa3fc5935fa", }, - LayersData: []types.ImageInspectLayer{{ - MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", - Digest: "sha256:6a5a5368e0c2d3e5909184fa28ddfd56072e7ff3ee9a945876f7eee5896ef5bb", - Size: 51354364, - Annotations: emptyAnnotations, - }, { - MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", - Digest: "sha256:1bbf5d58d24c47512e234a5623474acf65ae00d4d1414272a893204f44cc680c", - Size: 150, - Annotations: emptyAnnotations, - }, { - MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", - Digest: "sha256:8f5dc8a4b12c307ac84de90cdd9a7f3915d1be04c9388868ca118831099c67a9", - Size: 11739507, - Annotations: emptyAnnotations, - }, { - MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", - Digest: "sha256:bbd6b22eb11afce63cc76f6bc41042d99f10d6024c96b655dafba930b8d25909", - Size: 8841833, - Annotations: map[string]string{"test-annotation-2": "two"}, - }, { - MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", - Digest: "sha256:960e52ecf8200cbd84e70eb2ad8678f4367e50d14357021872c10fa3fc5935fa", - Size: 291, - Annotations: emptyAnnotations, - }, + LayersData: []types.ImageInspectLayer{ + { + MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", + Digest: "sha256:6a5a5368e0c2d3e5909184fa28ddfd56072e7ff3ee9a945876f7eee5896ef5bb", + Size: 51354364, + Annotations: emptyAnnotations, + }, { + MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", + Digest: "sha256:1bbf5d58d24c47512e234a5623474acf65ae00d4d1414272a893204f44cc680c", + Size: 150, + Annotations: emptyAnnotations, + }, { + MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", + Digest: "sha256:8f5dc8a4b12c307ac84de90cdd9a7f3915d1be04c9388868ca118831099c67a9", + Size: 11739507, + Annotations: emptyAnnotations, + }, { + MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", + Digest: "sha256:bbd6b22eb11afce63cc76f6bc41042d99f10d6024c96b655dafba930b8d25909", + Size: 8841833, + Annotations: map[string]string{"test-annotation-2": "two"}, + }, { + MIMEType: "application/vnd.oci.image.layer.v1.tar+gzip", + Digest: "sha256:960e52ecf8200cbd84e70eb2ad8678f4367e50d14357021872c10fa3fc5935fa", + Size: 291, + Annotations: emptyAnnotations, + }, }, Author: "", Env: []string{ @@ -478,7 +479,8 @@ func TestManifestOCI1UpdatedImage(t *testing.T) { // successfulOCI1Conversion verifies that an edit of original with edits suceeeds, and and original continues to match originalClone. // It returns the resulting image, for more checks func successfulOCI1Conversion(t *testing.T, original genericManifest, originalClone genericManifest, - edits types.ManifestUpdateOptions) types.Image { + edits types.ManifestUpdateOptions, +) types.Image { res, err := original.UpdatedImage(context.Background(), edits) require.NoError(t, err) diff --git a/image/internal/manifest/common.go b/image/internal/manifest/common.go index 1f2ccb5286..623362cf7c 100644 --- a/image/internal/manifest/common.go +++ b/image/internal/manifest/common.go @@ -26,7 +26,8 @@ const ( // identification/version, or other “magic numbers”) before calling this, to cleanly reject unambiguous // data that just isn’t what was expected, as opposed to actually ambiguous data. func ValidateUnambiguousManifestFormat(manifest []byte, expectedMIMEType string, - allowed AllowedManifestFields) error { + allowed AllowedManifestFields, +) error { if allowed >= AllowedFieldFirstUnusedBit { return fmt.Errorf("internal error: invalid allowedManifestFields value %#v", allowed) } diff --git a/image/internal/manifest/common_test.go b/image/internal/manifest/common_test.go index ff3a6efaae..bf4599c6cb 100644 --- a/image/internal/manifest/common_test.go +++ b/image/internal/manifest/common_test.go @@ -75,7 +75,8 @@ func testManifestFixturesAreRejected(t *testing.T, parser func([]byte) error, fi // Test that parser() rejects validManifest with an added top-level field with any of the provided field names. // Intended to help test callers of validateUnambiguousManifestFormat. func testValidManifestWithExtraFieldsIsRejected(t *testing.T, parser func([]byte) error, - validManifest []byte, fields []string) { + validManifest []byte, fields []string, +) { for _, field := range fields { // end (the final '}') is not always at len(validManifest)-1 because the manifest can end with // white space. diff --git a/image/internal/manifest/docker_schema2_list.go b/image/internal/manifest/docker_schema2_list.go index fdcc420832..47a5699fb1 100644 --- a/image/internal/manifest/docker_schema2_list.go +++ b/image/internal/manifest/docker_schema2_list.go @@ -82,7 +82,8 @@ func (list *Schema2ListPublic) UpdateInstances(updates []ListUpdate) error { UpdateDigest: instance.Digest, UpdateSize: instance.Size, UpdateMediaType: instance.MediaType, - ListOperation: ListOpUpdate}) + ListOperation: ListOpUpdate, + }) } return list.editInstances(editInstances) } diff --git a/image/internal/manifest/docker_schema2_list_test.go b/image/internal/manifest/docker_schema2_list_test.go index 2c86aabec8..9bcd9682ee 100644 --- a/image/internal/manifest/docker_schema2_list_test.go +++ b/image/internal/manifest/docker_schema2_list_test.go @@ -45,7 +45,8 @@ func TestSchema2ListEditInstances(t *testing.T) { UpdateDigest: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", UpdateSize: 32, UpdateMediaType: "something", - ListOperation: ListOpUpdate}) + ListOperation: ListOpUpdate, + }) err = list.EditInstances(editInstances) require.NoError(t, err) @@ -72,13 +73,15 @@ func TestSchema2ListEditInstances(t *testing.T) { AddSize: 32, AddMediaType: "application/vnd.oci.image.manifest.v1+json", AddPlatform: &imgspecv1.Platform{Architecture: "amd64", OS: "linux", OSFeatures: []string{"sse4"}}, - ListOperation: ListOpAdd}) + ListOperation: ListOpAdd, + }) editInstances = append(editInstances, ListEdit{ AddDigest: "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", AddSize: 32, AddMediaType: "application/vnd.oci.image.manifest.v1+json", AddPlatform: &imgspecv1.Platform{Architecture: "amd64", OS: "linux", OSFeatures: []string{"sse4"}}, - ListOperation: ListOpAdd}) + ListOperation: ListOpAdd, + }) err = list.EditInstances(editInstances) require.NoError(t, err) diff --git a/image/internal/manifest/oci_index.go b/image/internal/manifest/oci_index.go index 046d8e6070..922c8754c9 100644 --- a/image/internal/manifest/oci_index.go +++ b/image/internal/manifest/oci_index.go @@ -79,7 +79,8 @@ func (index *OCI1IndexPublic) UpdateInstances(updates []ListUpdate) error { UpdateDigest: instance.Digest, UpdateSize: instance.Size, UpdateMediaType: instance.MediaType, - ListOperation: ListOpUpdate}) + ListOperation: ListOpUpdate, + }) } return index.editInstances(editInstances) } diff --git a/image/internal/manifest/oci_index_test.go b/image/internal/manifest/oci_index_test.go index bcf067b2c5..06e55cc08a 100644 --- a/image/internal/manifest/oci_index_test.go +++ b/image/internal/manifest/oci_index_test.go @@ -96,7 +96,8 @@ func TestOCI1EditInstances(t *testing.T) { AddSize: 32, AddMediaType: "application/vnd.oci.image.manifest.v1+json", AddPlatform: &imgspecv1.Platform{Architecture: "amd64", OS: "linux", OSFeatures: []string{"sse4"}}, - ListOperation: ListOpAdd}) + ListOperation: ListOpAdd, + }) // with zstd editInstances = append(editInstances, ListEdit{ AddDigest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", @@ -115,7 +116,8 @@ func TestOCI1EditInstances(t *testing.T) { AddPlatform: &imgspecv1.Platform{Architecture: "amd64", OS: "linux", OSFeatures: []string{"sse4"}}, AddCompressionAlgorithms: []compression.Algorithm{compression.Zstd}, AddAnnotations: map[string]string{}, - ListOperation: ListOpAdd}) + ListOperation: ListOpAdd, + }) // with zstd but with compression, annotation must be added automatically and AddAnnotations is unset editInstances = append(editInstances, ListEdit{ AddDigest: "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -123,14 +125,16 @@ func TestOCI1EditInstances(t *testing.T) { AddMediaType: "application/vnd.oci.image.manifest.v1+json", AddPlatform: &imgspecv1.Platform{Architecture: "amd64", OS: "linux", OSFeatures: []string{"sse4"}}, AddCompressionAlgorithms: []compression.Algorithm{compression.Zstd}, - ListOperation: ListOpAdd}) + ListOperation: ListOpAdd, + }) // without zstd editInstances = append(editInstances, ListEdit{ AddDigest: "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", AddSize: 32, AddMediaType: "application/vnd.oci.image.manifest.v1+json", AddPlatform: &imgspecv1.Platform{Architecture: "amd64", OS: "linux", OSFeatures: []string{"sse4"}}, - ListOperation: ListOpAdd}) + ListOperation: ListOpAdd, + }) err = list.EditInstances(editInstances) require.NoError(t, err) @@ -156,7 +160,8 @@ func TestOCI1EditInstances(t *testing.T) { UpdateMediaType: "application/vnd.oci.image.manifest.v1+json", UpdateAffectAnnotations: true, UpdateAnnotations: map[string]string{}, - ListOperation: ListOpUpdate}) + ListOperation: ListOpUpdate, + }) err = list.EditInstances(editInstances) require.NoError(t, err) // Digest `ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff` should be re-ordered on update. diff --git a/image/internal/putblobdigest/put_blob_digest_test.go b/image/internal/putblobdigest/put_blob_digest_test.go index f7fe92feb7..8ca42954a8 100644 --- a/image/internal/putblobdigest/put_blob_digest_test.go +++ b/image/internal/putblobdigest/put_blob_digest_test.go @@ -20,7 +20,8 @@ type testCase struct { } func testDigester(t *testing.T, constructor func(io.Reader, types.BlobInfo) (Digester, io.Reader), - cases []testCase) { + cases []testCase, +) { for _, c := range cases { stream := bytes.NewReader(testData) digester, newStream := constructor(stream, types.BlobInfo{Digest: c.inputDigest}) diff --git a/image/internal/signature/signature.go b/image/internal/signature/signature.go index 6f95115a13..59f4aedefc 100644 --- a/image/internal/signature/signature.go +++ b/image/internal/signature/signature.go @@ -87,7 +87,6 @@ func FromBlob(blob []byte) (Signature, error) { default: return nil, fmt.Errorf("unrecognized signature format, starting with binary %#x", blob[0]) } - } // UnsupportedFormatError returns an error complaining about sig having an unsupported format. diff --git a/image/internal/signature/signature_test.go b/image/internal/signature/signature_test.go index 924c32d85e..ca01d9b14c 100644 --- a/image/internal/signature/signature_test.go +++ b/image/internal/signature/signature_test.go @@ -31,7 +31,6 @@ func TestBlobSimpleSigning(t *testing.T) { fromBlobSimple, ok = fromBlob.(SimpleSigning) require.True(t, ok) assert.Equal(t, simpleSigData, fromBlobSimple.UntrustedSignature()) - } func TestBlobSigstore(t *testing.T) { diff --git a/image/internal/signature/sigstore.go b/image/internal/signature/sigstore.go index 8025cd2700..a87b4651ff 100644 --- a/image/internal/signature/sigstore.go +++ b/image/internal/signature/sigstore.go @@ -77,6 +77,7 @@ func (s Sigstore) blobChunk() ([]byte, error) { func (s Sigstore) UntrustedMIMEType() string { return s.untrustedMIMEType } + func (s Sigstore) UntrustedPayload() []byte { return bytes.Clone(s.untrustedPayload) } diff --git a/image/internal/signature/sigstore_test.go b/image/internal/signature/sigstore_test.go index c1d3c9b90d..a2be966354 100644 --- a/image/internal/signature/sigstore_test.go +++ b/image/internal/signature/sigstore_test.go @@ -58,7 +58,7 @@ func TestSigstoreBlobChunk(t *testing.T) { } func TestSigstoreUntrustedPayload(t *testing.T) { - var payload = []byte("payload") + payload := []byte("payload") sig := SigstoreFromComponents("mime-type", payload, map[string]string{"a": "b", "c": "d"}) assert.Equal(t, payload, sig.UntrustedPayload()) diff --git a/image/internal/signature/simple_test.go b/image/internal/signature/simple_test.go index 76537e21d9..04f7af63da 100644 --- a/image/internal/signature/simple_test.go +++ b/image/internal/signature/simple_test.go @@ -8,7 +8,7 @@ import ( ) func TestSimpleSigningFromBlob(t *testing.T) { - var data = []byte("some contents") + data := []byte("some contents") sig := SimpleSigningFromBlob(data) assert.Equal(t, SimpleSigning{untrustedSignature: data}, sig) @@ -20,7 +20,7 @@ func TestSimpleSigningFormatID(t *testing.T) { } func TestSimpleSigningBlobChunk(t *testing.T) { - var data = []byte("some contents") + data := []byte("some contents") sig := SimpleSigningFromBlob(data) chunk, err := sig.blobChunk() @@ -29,7 +29,7 @@ func TestSimpleSigningBlobChunk(t *testing.T) { } func TestSimpleSigningUntrustedSignature(t *testing.T) { - var data = []byte("some contents") + data := []byte("some contents") sig := SimpleSigningFromBlob(data) assert.Equal(t, data, sig.UntrustedSignature()) diff --git a/image/internal/tmpdir/tmpdir_test.go b/image/internal/tmpdir/tmpdir_test.go index 5adfef4fb8..44a50e9a79 100644 --- a/image/internal/tmpdir/tmpdir_test.go +++ b/image/internal/tmpdir/tmpdir_test.go @@ -32,7 +32,6 @@ func TestCreateBigFileTemp(t *testing.T) { sys.BigFilesTemporaryDir = "/tmp/bogus" _, err = CreateBigFileTemp(&sys, "foobar1") assert.Error(t, err) - } func TestMkDirBigFileTemp(t *testing.T) { diff --git a/image/manifest/common.go b/image/manifest/common.go index dde1bf3c84..dc24e1c9c5 100644 --- a/image/manifest/common.go +++ b/image/manifest/common.go @@ -24,8 +24,10 @@ func layerInfosToStrings(infos []LayerInfo) []string { // the map value is a MIME type, or mtsUnsupportedMIMEType to mean "recognized but unsupported". type compressionMIMETypeSet map[string]string -const mtsUncompressed = "" // A key in compressionMIMETypeSet for the uncompressed variant -const mtsUnsupportedMIMEType = "" // A value in compressionMIMETypeSet that means “recognized but unsupported” +const ( + mtsUncompressed = "" // A key in compressionMIMETypeSet for the uncompressed variant + mtsUnsupportedMIMEType = "" // A value in compressionMIMETypeSet that means “recognized but unsupported” +) // findCompressionMIMETypeSet returns a pointer to a compressionMIMETypeSet in variantTable that contains a value of mimeType, or nil if not found func findCompressionMIMETypeSet(variantTable []compressionMIMETypeSet, mimeType string) compressionMIMETypeSet { diff --git a/image/manifest/common_test.go b/image/manifest/common_test.go index ab53d938ae..d8c7992985 100644 --- a/image/manifest/common_test.go +++ b/image/manifest/common_test.go @@ -29,7 +29,8 @@ func testManifestFixturesAreRejected(t *testing.T, parser func([]byte) error, fi // Test that parser() rejects validManifest with an added top-level field with any of the provided field names. // Intended to help test callers of validateUnambiguousManifestFormat. func testValidManifestWithExtraFieldsIsRejected(t *testing.T, parser func([]byte) error, - validManifest []byte, fields []string) { + validManifest []byte, fields []string, +) { for _, field := range fields { // end (the final '}') is not always at len(validManifest)-1 because the manifest can end with // white space. @@ -103,15 +104,23 @@ func TestCompressionVariantMIMEType(t *testing.T) { algo *compressiontypes.Algorithm expected string }{ - {"AU", nil, "AU"}, {"AU", &compression.Gzip, "AG"}, {"AU", &compression.Zstd, ""}, - {"AG", nil, "AU"}, {"AG", &compression.Gzip, "AG"}, {"AG", &compression.Zstd, ""}, + {"AU", nil, "AU"}, + {"AU", &compression.Gzip, "AG"}, + {"AU", &compression.Zstd, ""}, + {"AG", nil, "AU"}, + {"AG", &compression.Gzip, "AG"}, + {"AG", &compression.Zstd, ""}, {"BU", &compression.Zstd, ""}, {"BG", &compression.Zstd, ""}, - {"CG", nil, ""}, {"CG", &compression.Zstd, "CZ"}, - {"CZ", nil, ""}, {"CZ", &compression.Gzip, "CG"}, + {"CG", nil, ""}, + {"CG", &compression.Zstd, "CZ"}, + {"CZ", nil, ""}, + {"CZ", &compression.Gzip, "CG"}, {"DG", nil, ""}, - {"unknown", nil, ""}, {"unknown", &compression.Gzip, ""}, - {"", nil, ""}, {"", &compression.Gzip, ""}, + {"unknown", nil, ""}, + {"unknown", &compression.Gzip, ""}, + {"", nil, ""}, + {"", &compression.Gzip, ""}, } { res, err := compressionVariantMIMEType(sets, c.input, c.algo) if c.expected == "" { diff --git a/image/manifest/list.go b/image/manifest/list.go index 846ea7d43c..3d8045a8d7 100644 --- a/image/manifest/list.go +++ b/image/manifest/list.go @@ -5,14 +5,12 @@ import ( "go.podman.io/image/v5/internal/manifest" ) -var ( - // SupportedListMIMETypes is a list of the manifest list types that we know how to - // read/manipulate/write. - SupportedListMIMETypes = []string{ - DockerV2ListMediaType, - imgspecv1.MediaTypeImageIndex, - } -) +// SupportedListMIMETypes is a list of the manifest list types that we know how to +// read/manipulate/write. +var SupportedListMIMETypes = []string{ + DockerV2ListMediaType, + imgspecv1.MediaTypeImageIndex, +} // List is an interface for parsing, modifying lists of image manifests. // Callers can either use this abstract interface without understanding the details of the formats, diff --git a/image/oci/archive/oci_transport_test.go b/image/oci/archive/oci_transport_test.go index 1a4e3b75df..41520795b1 100644 --- a/image/oci/archive/oci_transport_test.go +++ b/image/oci/archive/oci_transport_test.go @@ -133,7 +133,7 @@ func refToTempOCI(t *testing.T) (types.ImageReference, string) { ] } ` - err := os.WriteFile(filepath.Join(tmpDir, "index.json"), []byte(m), 0644) + err := os.WriteFile(filepath.Join(tmpDir, "index.json"), []byte(m), 0o644) require.NoError(t, err) ref, err := NewReference(tmpDir, "imageValue") require.NoError(t, err) @@ -162,7 +162,7 @@ func refToTempOCIArchive(t *testing.T, tarEntryTimestamp *time.Time) (ref types. ] } ` - err := os.WriteFile(filepath.Join(tmpDir, "index.json"), []byte(m), 0644) + err := os.WriteFile(filepath.Join(tmpDir, "index.json"), []byte(m), 0o644) require.NoError(t, err) tarFile, err := os.CreateTemp("", "oci-transport-test.tar") require.NoError(t, err) diff --git a/image/oci/internal/oci_util.go b/image/oci/internal/oci_util.go index c4eaed0eee..9620b6384f 100644 --- a/image/oci/internal/oci_util.go +++ b/image/oci/internal/oci_util.go @@ -17,8 +17,10 @@ const ( component = `(?:` + alphanum + `(?:` + separator + alphanum + `)*)` ) -var refRegexp = regexp.MustCompile(`^` + component + `(?:/` + component + `)*$`) -var windowsRefRegexp = regexp.MustCompile(`^([a-zA-Z]:\\.+?):(.*)$`) +var ( + refRegexp = regexp.MustCompile(`^` + component + `(?:/` + component + `)*$`) + windowsRefRegexp = regexp.MustCompile(`^([a-zA-Z]:\\.+?):(.*)$`) +) // ValidateImageName returns nil if the image name is empty or matches the open-containers image name specs. // In any other case an error is returned. diff --git a/image/oci/layout/oci_delete.go b/image/oci/layout/oci_delete.go index 7eaf6f0889..484cbb66fe 100644 --- a/image/oci/layout/oci_delete.go +++ b/image/oci/layout/oci_delete.go @@ -124,7 +124,7 @@ func (ref ociReference) getBlobsToDelete(blobsUsedByDescriptorToDelete map[diges // So, NOTE: the blobPath() call below hard-codes "" even in calls where OCISharedBlobDirPath is set func (ref ociReference) deleteBlobs(blobsToDelete *set.Set[digest.Digest]) error { for digest := range blobsToDelete.All() { - blobPath, err := ref.blobPath(digest, "") //Only delete in the local directory, see comment above + blobPath, err := ref.blobPath(digest, "") // Only delete in the local directory, see comment above if err != nil { return err } @@ -167,7 +167,7 @@ func saveJSON(path string, content any) (retErr error) { if !os.IsNotExist(err) { return err } else { // File does not exist, use default mode - mode = 0644 + mode = 0o644 } } else { mode = existingfi.Mode() diff --git a/image/oci/layout/oci_dest.go b/image/oci/layout/oci_dest.go index 48fe812df5..c4eee7db4d 100644 --- a/image/oci/layout/oci_dest.go +++ b/image/oci/layout/oci_dest.go @@ -165,7 +165,7 @@ func (d *ociImageDestination) blobFileSyncAndRename(blobFile *os.File, blobDiges // ignored and the file is already readable; besides, blobFile.Chmod, i.e. syscall.Fchmod, // always fails on Windows. if runtime.GOOS != "windows" { - if err := blobFile.Chmod(0644); err != nil { + if err := blobFile.Chmod(0o644); err != nil { return err } } @@ -248,7 +248,7 @@ func (d *ociImageDestination) PutManifest(ctx context.Context, m []byte, instanc if err := ensureParentDirectoryExists(blobPath); err != nil { return err } - if err := os.WriteFile(blobPath, m, 0644); err != nil { + if err := os.WriteFile(blobPath, m, 0o644); err != nil { return err } @@ -312,14 +312,14 @@ func (d *ociImageDestination) CommitWithOptions(ctx context.Context, options pri if err != nil { return err } - if err := os.WriteFile(d.ref.ociLayoutPath(), layoutBytes, 0644); err != nil { + if err := os.WriteFile(d.ref.ociLayoutPath(), layoutBytes, 0o644); err != nil { return err } indexJSON, err := json.Marshal(d.index) if err != nil { return err } - return os.WriteFile(d.ref.indexPath(), indexJSON, 0644) + return os.WriteFile(d.ref.indexPath(), indexJSON, 0o644) } // PutBlobFromLocalFileOption is unused but may receive functionality in the future. @@ -388,7 +388,7 @@ func PutBlobFromLocalFile(ctx context.Context, dest types.ImageDestination, file func ensureDirectoryExists(path string) error { if err := fileutils.Exists(path); err != nil && errors.Is(err, fs.ErrNotExist) { - if err := os.MkdirAll(path, 0755); err != nil { + if err := os.MkdirAll(path, 0o755); err != nil { return err } } diff --git a/image/oci/layout/oci_transport_test.go b/image/oci/layout/oci_transport_test.go index 5a1616fd46..1f24ca4bcc 100644 --- a/image/oci/layout/oci_transport_test.go +++ b/image/oci/layout/oci_transport_test.go @@ -135,7 +135,8 @@ func TestGetManifestDescriptor(t *testing.T) { Platform: &imgspecv1.Platform{ Architecture: "ppc64le", OS: "linux", - }}, res) + }, + }, res) // Out of bounds ref, err = NewIndexReference("fixtures/two_images_manifest", 6) @@ -338,7 +339,7 @@ func refToTempOCI(t *testing.T, sourceIndex bool) (types.ImageReference, string) ` } - err := os.WriteFile(filepath.Join(tmpDir, "index.json"), []byte(m), 0644) + err := os.WriteFile(filepath.Join(tmpDir, "index.json"), []byte(m), 0o644) require.NoError(t, err) var ref types.ImageReference if sourceIndex { diff --git a/image/oci/layout/reader_test.go b/image/oci/layout/reader_test.go index 3d964c3e6d..d53ea815a1 100644 --- a/image/oci/layout/reader_test.go +++ b/image/oci/layout/reader_test.go @@ -9,7 +9,6 @@ import ( ) func TestList(t *testing.T) { - for _, test := range []struct { path string num int diff --git a/image/pkg/blobcache/blobcache.go b/image/pkg/blobcache/blobcache.go index 7ce75283f2..ab2c430ede 100644 --- a/image/pkg/blobcache/blobcache.go +++ b/image/pkg/blobcache/blobcache.go @@ -112,7 +112,6 @@ func (b *BlobCache) findBlob(info types.BlobInfo) (string, int64, bool, error) { } return "", -1, false, nil - } func (b *BlobCache) HasBlob(blobinfo types.BlobInfo) (bool, int64, error) { diff --git a/image/pkg/blobcache/dest.go b/image/pkg/blobcache/dest.go index c1f74a42cd..c56eed7a01 100644 --- a/image/pkg/blobcache/dest.go +++ b/image/pkg/blobcache/dest.go @@ -127,10 +127,10 @@ func (d *blobCacheDestination) saveStream(wg *sync.WaitGroup, decompressReader i succeeded = true *alternateDigest = digester.Digest() // Note the relationship between the two files. - if err := ioutils.AtomicWriteFile(decompressedFilename+compressedNote, []byte(compressedDigest.String()), 0600); err != nil { + if err := ioutils.AtomicWriteFile(decompressedFilename+compressedNote, []byte(compressedDigest.String()), 0o600); err != nil { logrus.Debugf("error noting that the compressed version of %q is %q: %v", digester.Digest().String(), compressedDigest.String(), err) } - if err := ioutils.AtomicWriteFile(compressedFilename+decompressedNote, []byte(digester.Digest().String()), 0600); err != nil { + if err := ioutils.AtomicWriteFile(compressedFilename+decompressedNote, []byte(digester.Digest().String()), 0o600); err != nil { logrus.Debugf("error noting that the decompressed version of %q is %q: %v", compressedDigest.String(), digester.Digest().String(), err) } } @@ -301,7 +301,7 @@ func (d *blobCacheDestination) PutManifest(ctx context.Context, manifestBytes [] if err != nil { return err } - if err = ioutils.AtomicWriteFile(filename, manifestBytes, 0600); err != nil { + if err = ioutils.AtomicWriteFile(filename, manifestBytes, 0o600); err != nil { logrus.Warnf("error saving manifest as %q: %v", filename, err) } } diff --git a/image/pkg/blobcache/src.go b/image/pkg/blobcache/src.go index 309543fbb7..806d2de269 100644 --- a/image/pkg/blobcache/src.go +++ b/image/pkg/blobcache/src.go @@ -215,7 +215,8 @@ func (s *blobCacheSource) SupportsGetBlobAt() bool { // streamChunksFromFile generates the channels returned by GetBlobAt for chunks of seekable file func streamChunksFromFile(streams chan io.ReadCloser, errs chan error, file io.ReadSeekCloser, - chunks []private.ImageSourceChunk) { + chunks []private.ImageSourceChunk, +) { defer close(streams) defer close(errs) defer file.Close() diff --git a/image/pkg/blobinfocache/boltdb/boltdb.go b/image/pkg/blobinfocache/boltdb/boltdb.go index 6b71ce8343..dcb9e02c09 100644 --- a/image/pkg/blobinfocache/boltdb/boltdb.go +++ b/image/pkg/blobinfocache/boltdb/boltdb.go @@ -116,6 +116,7 @@ type cache struct { func New(path string) types.BlobInfoCache { return new2(path) } + func new2(path string) *cache { return &cache{path: path} } @@ -142,7 +143,7 @@ func (bdc *cache) view(fn func(tx *bolt.Tx) error) (retErr error) { lockPath(bdc.path) defer unlockPath(bdc.path) - db, err := bolt.Open(bdc.path, 0600, &bolt.Options{ReadOnly: true}) + db, err := bolt.Open(bdc.path, 0o600, &bolt.Options{ReadOnly: true}) if err != nil { return err } @@ -159,7 +160,7 @@ func (bdc *cache) view(fn func(tx *bolt.Tx) error) (retErr error) { func (bdc *cache) update(fn func(tx *bolt.Tx) error) (retErr error) { lockPath(bdc.path) defer unlockPath(bdc.path) - db, err := bolt.Open(bdc.path, 0600, nil) + db, err := bolt.Open(bdc.path, 0o600, nil) if err != nil { return err } @@ -408,7 +409,8 @@ func (bdc *cache) RecordKnownLocation(transport types.ImageTransport, scope type // v2Options is not nil if the caller is CandidateLocations2: this allows including candidates with unknown location, and filters out candidates // with unknown compression. func (bdc *cache) appendReplacementCandidates(candidates []prioritize.CandidateWithTime, scopeBucket, compressionBucket, specificVariantCompresssionBucket *bolt.Bucket, - digest digest.Digest, v2Options *blobinfocache.CandidateLocations2Options) []prioritize.CandidateWithTime { + digest digest.Digest, v2Options *blobinfocache.CandidateLocations2Options, +) []prioritize.CandidateWithTime { digestKey := []byte(digest.String()) compressionData := blobinfocache.DigestCompressorData{ BaseVariantCompressor: blobinfocache.UnknownCompression, @@ -466,7 +468,8 @@ func (bdc *cache) CandidateLocations2(transport types.ImageTransport, scope type // candidateLocations implements CandidateLocations / CandidateLocations2. // v2Options is not nil if the caller is CandidateLocations2. func (bdc *cache) candidateLocations(transport types.ImageTransport, scope types.BICTransportScope, primaryDigest digest.Digest, canSubstitute bool, - v2Options *blobinfocache.CandidateLocations2Options) []blobinfocache.BICReplacementCandidate2 { + v2Options *blobinfocache.CandidateLocations2Options, +) []blobinfocache.BICReplacementCandidate2 { res := []prioritize.CandidateWithTime{} var uncompressedDigestValue digest.Digest // = "" if err := bdc.view(func(tx *bolt.Tx) error { diff --git a/image/pkg/blobinfocache/default.go b/image/pkg/blobinfocache/default.go index 7fe615e348..e3c28d58c9 100644 --- a/image/pkg/blobinfocache/default.go +++ b/image/pkg/blobinfocache/default.go @@ -56,7 +56,7 @@ func DefaultCache(sys *types.SystemContext) types.BlobInfoCache { return memory.New() } path := filepath.Join(dir, blobInfoCacheFilename) - if err := os.MkdirAll(dir, 0700); err != nil { + if err := os.MkdirAll(dir, 0o700); err != nil { logrus.Debugf("Error creating parent directories for %s, using a memory-only cache: %v", path, err) return memory.New() } diff --git a/image/pkg/blobinfocache/default_test.go b/image/pkg/blobinfocache/default_test.go index a4a36dbcd2..f035b5e51e 100644 --- a/image/pkg/blobinfocache/default_test.go +++ b/image/pkg/blobinfocache/default_test.go @@ -119,13 +119,13 @@ func TestDefaultCache(t *testing.T) { // Error creating the parent directory: unwritableDir := filepath.Join(tmpDir, "unwritable") - err = os.Mkdir(unwritableDir, 0700) + err = os.Mkdir(unwritableDir, 0o700) require.NoError(t, err) defer func() { - err = os.Chmod(unwritableDir, 0700) // To make it possible to remove it again + err = os.Chmod(unwritableDir, 0o700) // To make it possible to remove it again require.NoError(t, err) }() - err = os.Chmod(unwritableDir, 0500) + err = os.Chmod(unwritableDir, 0o500) require.NoError(t, err) st, _ := os.Stat(unwritableDir) logrus.Errorf("%s: %#v", unwritableDir, st) diff --git a/image/pkg/blobinfocache/internal/test/test.go b/image/pkg/blobinfocache/internal/test/test.go index be1ac2da56..1ee83cbb0b 100644 --- a/image/pkg/blobinfocache/internal/test/test.go +++ b/image/pkg/blobinfocache/internal/test/test.go @@ -243,19 +243,24 @@ func testGenericCandidateLocations(t *testing.T, cache blobinfocache.BlobInfoCac // With substitutions: The original digest is always preferred, then other compressed, then the uncompressed one. assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestCompressedA, lr: "A1"}, {d: digestCompressedA, lr: "A2"}, - {d: digestCompressedB, lr: "B1"}, {d: digestCompressedB, lr: "B2"}, + {d: digestCompressedA, lr: "A1"}, + {d: digestCompressedA, lr: "A2"}, + {d: digestCompressedB, lr: "B1"}, + {d: digestCompressedB, lr: "B2"}, {d: digestUncompressed, lr: "U1"}, // Beyond the replacementAttempts limit: {d: digestUncompressed, lr: "U2"}, }, cache.CandidateLocations(transport, scope, digestCompressedA, true)) assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestCompressedB, lr: "B1"}, {d: digestCompressedB, lr: "B2"}, - {d: digestCompressedA, lr: "A1"}, {d: digestCompressedA, lr: "A2"}, + {d: digestCompressedB, lr: "B1"}, + {d: digestCompressedB, lr: "B2"}, + {d: digestCompressedA, lr: "A1"}, + {d: digestCompressedA, lr: "A2"}, {d: digestUncompressed, lr: "U1"}, // Beyond the replacementAttempts limit: {d: digestUncompressed, lr: "U2"}, }, cache.CandidateLocations(transport, scope, digestCompressedB, true)) assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestUncompressed, lr: "U1"}, {d: digestUncompressed, lr: "U2"}, + {d: digestUncompressed, lr: "U1"}, + {d: digestUncompressed, lr: "U2"}, // "1" entries were added after "2", and A/Bs are sorted in the reverse of digestNameSet order {d: digestCompressedB, lr: "B1"}, {d: digestCompressedA, lr: "A1"}, @@ -333,7 +338,8 @@ func testGenericCandidateLocations2(t *testing.T, cache blobinfocache.BlobInfoCa CompressionAlgorithm: &compression.Bzip2, UnknownLocation: true, Location: types.BICLocationReference{Opaque: ""}, - }}, res) + }, + }, res) // When another entry with scope and Location is set then it should be returned as it has higher // priority. cache.RecordKnownLocation(transport, scope, digestUnknownLocation, types.BICLocationReference{Opaque: "somelocation"}) @@ -347,7 +353,8 @@ func testGenericCandidateLocations2(t *testing.T, cache blobinfocache.BlobInfoCa CompressionAlgorithm: &compression.Bzip2, UnknownLocation: false, Location: types.BICLocationReference{Opaque: "somelocation"}, - }}, res) + }, + }, res) // Tests of lookups / prioritization when compression is unknown // ------------------------------------------------------------- @@ -385,8 +392,10 @@ func testGenericCandidateLocations2(t *testing.T, cache blobinfocache.BlobInfoCa // With substitutions: The original digest is always preferred, then other compressed, then the uncompressed one. assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestCompressedA, lr: "A1"}, {d: digestCompressedA, lr: "A2"}, - {d: digestCompressedB, lr: "B1"}, {d: digestCompressedB, lr: "B2"}, + {d: digestCompressedA, lr: "A1"}, + {d: digestCompressedA, lr: "A2"}, + {d: digestCompressedB, lr: "B1"}, + {d: digestCompressedB, lr: "B2"}, {d: digestUncompressed, lr: "U1"}, // Beyond the replacementAttempts limit: {d: digestUncompressed, cn: compressorNameCU, lr: "U2"}, }, cache.CandidateLocations(transport, scope, digestCompressedA, true)) // Unknown compression -> no candidates @@ -396,8 +405,10 @@ func testGenericCandidateLocations2(t *testing.T, cache blobinfocache.BlobInfoCa assertCandidatesMatch2(t, scopeName, []candidate{}, res) assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestCompressedB, lr: "B1"}, {d: digestCompressedB, lr: "B2"}, - {d: digestCompressedA, lr: "A1"}, {d: digestCompressedA, lr: "A2"}, + {d: digestCompressedB, lr: "B1"}, + {d: digestCompressedB, lr: "B2"}, + {d: digestCompressedA, lr: "A1"}, + {d: digestCompressedA, lr: "A2"}, {d: digestUncompressed, lr: "U1"}, // Beyond the replacementAttempts limit: {d: digestUncompressed, lr: "U2"}, }, cache.CandidateLocations(transport, scope, digestCompressedB, true)) // Unknown compression -> no candidates @@ -407,7 +418,8 @@ func testGenericCandidateLocations2(t *testing.T, cache blobinfocache.BlobInfoCa assertCandidatesMatch2(t, scopeName, []candidate{}, res) assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestUncompressed, lr: "U1"}, {d: digestUncompressed, lr: "U2"}, + {d: digestUncompressed, lr: "U1"}, + {d: digestUncompressed, lr: "U2"}, // "1" entries were added after "2", and A/Bs are sorted in the reverse of digestNameSetPrioritization order {d: digestCompressedB, lr: "B1"}, {d: digestCompressedA, lr: "A1"}, @@ -457,35 +469,44 @@ func testGenericCandidateLocations2(t *testing.T, cache blobinfocache.BlobInfoCa // With substitutions: The original digest is always preferred, then other compressed, then the uncompressed one. assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestCompressedA, lr: "A1"}, {d: digestCompressedA, lr: "A2"}, - {d: digestCompressedB, lr: "B1"}, {d: digestCompressedB, lr: "B2"}, + {d: digestCompressedA, lr: "A1"}, + {d: digestCompressedA, lr: "A2"}, + {d: digestCompressedB, lr: "B1"}, + {d: digestCompressedB, lr: "B2"}, {d: digestUncompressed, lr: "U1"}, // Beyond the replacementAttempts limit: {d: digestUncompressed, lr: "U2"}, }, cache.CandidateLocations(transport, scope, digestCompressedA, true)) res = cache.CandidateLocations2(transport, scope, digestCompressedA, blobinfocache.CandidateLocations2Options{ CanSubstitute: true, }) assertCandidatesMatch2(t, scopeName, []candidate{ - {d: digestCompressedA, cn: compressorNameA, lr: "A1"}, {d: digestCompressedA, cn: compressorNameA, lr: "A2"}, - {d: digestCompressedB, cn: compressorNameB, lr: "B1"}, {d: digestCompressedB, cn: compressorNameB, lr: "B2"}, + {d: digestCompressedA, cn: compressorNameA, lr: "A1"}, + {d: digestCompressedA, cn: compressorNameA, lr: "A2"}, + {d: digestCompressedB, cn: compressorNameB, lr: "B1"}, + {d: digestCompressedB, cn: compressorNameB, lr: "B2"}, {d: digestUncompressed, cn: compressorNameU, lr: "U1"}, // Beyond the replacementAttempts limit: {d: digestUncompressed, cn: compressorNameCU, lr: "U2"}, }, res) assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestCompressedB, lr: "B1"}, {d: digestCompressedB, lr: "B2"}, - {d: digestCompressedA, lr: "A1"}, {d: digestCompressedA, lr: "A2"}, + {d: digestCompressedB, lr: "B1"}, + {d: digestCompressedB, lr: "B2"}, + {d: digestCompressedA, lr: "A1"}, + {d: digestCompressedA, lr: "A2"}, {d: digestUncompressed, lr: "U1"}, // Beyond the replacementAttempts limit: {d: digestUncompressed, lr: "U2"}, }, cache.CandidateLocations(transport, scope, digestCompressedB, true)) res = cache.CandidateLocations2(transport, scope, digestCompressedB, blobinfocache.CandidateLocations2Options{ CanSubstitute: true, }) assertCandidatesMatch2(t, scopeName, []candidate{ - {d: digestCompressedB, cn: compressorNameB, lr: "B1"}, {d: digestCompressedB, cn: compressorNameB, lr: "B2"}, - {d: digestCompressedA, cn: compressorNameA, lr: "A1"}, {d: digestCompressedA, cn: compressorNameA, lr: "A2"}, + {d: digestCompressedB, cn: compressorNameB, lr: "B1"}, + {d: digestCompressedB, cn: compressorNameB, lr: "B2"}, + {d: digestCompressedA, cn: compressorNameA, lr: "A1"}, + {d: digestCompressedA, cn: compressorNameA, lr: "A2"}, {d: digestUncompressed, cn: compressorNameU, lr: "U1"}, // Beyond the replacementAttempts limit: {d: digestUncompressed, cn: compressorNameU, lr: "U2"}, }, res) assertCandidatesMatch(t, scopeName, []candidate{ - {d: digestUncompressed, lr: "U1"}, {d: digestUncompressed, lr: "U2"}, + {d: digestUncompressed, lr: "U1"}, + {d: digestUncompressed, lr: "U2"}, // "1" entries were added after "2", and A/Bs are sorted in the reverse of digestNameSetPrioritization order {d: digestCompressedB, lr: "B1"}, {d: digestCompressedA, lr: "A1"}, @@ -496,7 +517,8 @@ func testGenericCandidateLocations2(t *testing.T, cache blobinfocache.BlobInfoCa CanSubstitute: true, }) assertCandidatesMatch2(t, scopeName, []candidate{ - {d: digestUncompressed, cn: compressorNameU, lr: "U1"}, {d: digestUncompressed, cn: compressorNameU, lr: "U2"}, + {d: digestUncompressed, cn: compressorNameU, lr: "U1"}, + {d: digestUncompressed, cn: compressorNameU, lr: "U2"}, // "1" entries were added after "2", and A/Bs are sorted in the reverse of digestNameSetPrioritization order {d: digestCompressedB, cn: compressorNameB, lr: "B1"}, {d: digestCompressedA, cn: compressorNameA, lr: "A1"}, diff --git a/image/pkg/blobinfocache/memory/memory.go b/image/pkg/blobinfocache/memory/memory.go index 84e9b7d6d3..6190284df1 100644 --- a/image/pkg/blobinfocache/memory/memory.go +++ b/image/pkg/blobinfocache/memory/memory.go @@ -186,7 +186,8 @@ func (mem *cache) RecordDigestCompressorData(anyDigest digest.Digest, data blobi // v2Options is not nil if the caller is CandidateLocations2: this allows including candidates with unknown location, and filters out candidates // with unknown compression. func (mem *cache) appendReplacementCandidates(candidates []prioritize.CandidateWithTime, transport types.ImageTransport, scope types.BICTransportScope, digest digest.Digest, - v2Options *blobinfocache.CandidateLocations2Options) []prioritize.CandidateWithTime { + v2Options *blobinfocache.CandidateLocations2Options, +) []prioritize.CandidateWithTime { compressionData := blobinfocache.DigestCompressorData{ BaseVariantCompressor: blobinfocache.UnknownCompression, SpecificVariantCompressor: blobinfocache.UnknownCompression, @@ -230,7 +231,8 @@ func (mem *cache) CandidateLocations2(transport types.ImageTransport, scope type // candidateLocations implements CandidateLocations / CandidateLocations2. // v2Options is not nil if the caller is CandidateLocations2. func (mem *cache) candidateLocations(transport types.ImageTransport, scope types.BICTransportScope, primaryDigest digest.Digest, canSubstitute bool, - v2Options *blobinfocache.CandidateLocations2Options) []blobinfocache.BICReplacementCandidate2 { + v2Options *blobinfocache.CandidateLocations2Options, +) []blobinfocache.BICReplacementCandidate2 { mem.mutex.Lock() defer mem.mutex.Unlock() res := []prioritize.CandidateWithTime{} diff --git a/image/pkg/blobinfocache/none/none.go b/image/pkg/blobinfocache/none/none.go index 88c9024fd2..e242ce29e7 100644 --- a/image/pkg/blobinfocache/none/none.go +++ b/image/pkg/blobinfocache/none/none.go @@ -8,8 +8,7 @@ import ( ) // noCache implements a dummy BlobInfoCache which records no data. -type noCache struct { -} +type noCache struct{} // NoCache implements BlobInfoCache by not recording any data. // diff --git a/image/pkg/blobinfocache/sqlite/sqlite.go b/image/pkg/blobinfocache/sqlite/sqlite.go index 1d01275730..3e6916637c 100644 --- a/image/pkg/blobinfocache/sqlite/sqlite.go +++ b/image/pkg/blobinfocache/sqlite/sqlite.go @@ -542,7 +542,8 @@ func (sqc *cache) RecordDigestCompressorData(anyDigest digest.Digest, data blobi // v2Options is not nil if the caller is CandidateLocations2: this allows including candidates with unknown location, and filters out candidates // with unknown compression. func (sqc *cache) appendReplacementCandidates(candidates []prioritize.CandidateWithTime, tx *sql.Tx, transport types.ImageTransport, scope types.BICTransportScope, digest digest.Digest, - v2Options *blobinfocache.CandidateLocations2Options) ([]prioritize.CandidateWithTime, error) { + v2Options *blobinfocache.CandidateLocations2Options, +) ([]prioritize.CandidateWithTime, error) { compressionData := blobinfocache.DigestCompressorData{ BaseVariantCompressor: blobinfocache.UnknownCompression, SpecificVariantCompressor: blobinfocache.UnknownCompression, @@ -611,7 +612,8 @@ func (sqc *cache) CandidateLocations2(transport types.ImageTransport, scope type // candidateLocations implements CandidateLocations / CandidateLocations2. // v2Options is not nil if the caller is CandidateLocations2. func (sqc *cache) candidateLocations(transport types.ImageTransport, scope types.BICTransportScope, primaryDigest digest.Digest, canSubstitute bool, - v2Options *blobinfocache.CandidateLocations2Options) []blobinfocache.BICReplacementCandidate2 { + v2Options *blobinfocache.CandidateLocations2Options, +) []blobinfocache.BICReplacementCandidate2 { var uncompressedDigest digest.Digest // = "" res, err := transaction(sqc, func(tx *sql.Tx) ([]prioritize.CandidateWithTime, error) { res := []prioritize.CandidateWithTime{} @@ -668,7 +670,6 @@ func (sqc *cache) candidateLocations(transport types.ImageTransport, scope types return []blobinfocache.BICReplacementCandidate2{} // FIXME? Log err (but throttle the log volume on repeated accesses)? } return prioritize.DestructivelyPrioritizeReplacementCandidates(res, primaryDigest, uncompressedDigest) - } // CandidateLocations returns a prioritized, limited, number of blobs and their locations that could possibly be reused diff --git a/image/pkg/docker/config/config.go b/image/pkg/docker/config/config.go index 56d4eb916c..755a495541 100644 --- a/image/pkg/docker/config/config.go +++ b/image/pkg/docker/config/config.go @@ -640,7 +640,7 @@ func modifyJSON(sys *types.SystemContext, editor func(fileContents *dockerConfig } dir := filepath.Dir(path.path) - if err = os.MkdirAll(dir, 0700); err != nil { + if err = os.MkdirAll(dir, 0o700); err != nil { return "", err } @@ -659,7 +659,7 @@ func modifyJSON(sys *types.SystemContext, editor func(fileContents *dockerConfig return "", fmt.Errorf("marshaling JSON %q: %w", path.path, err) } - if err = ioutils.AtomicWriteFile(path.path, newData, 0600); err != nil { + if err = ioutils.AtomicWriteFile(path.path, newData, 0o600); err != nil { return "", fmt.Errorf("writing to file %q: %w", path.path, err) } } @@ -683,7 +683,7 @@ func modifyDockerConfigJSON(sys *types.SystemContext, editor func(fileContents * path := sys.DockerCompatAuthFilePath dir := filepath.Dir(path) - if err := os.MkdirAll(dir, 0700); err != nil { + if err := os.MkdirAll(dir, 0o700); err != nil { return "", err } @@ -719,7 +719,6 @@ func modifyDockerConfigJSON(sys *types.SystemContext, editor func(fileContents * if rawCH, ok := rawContents["credHelpers"]; ok { if err := json.Unmarshal(rawCH, &syntheticContents.CredHelpers); err != nil { return "", fmt.Errorf(`unmarshaling "credHelpers" in JSON at %q: %w`, path, err) - } } @@ -739,7 +738,7 @@ func modifyDockerConfigJSON(sys *types.SystemContext, editor func(fileContents * return "", fmt.Errorf("marshaling JSON %q: %w", path, err) } - if err = ioutils.AtomicWriteFile(path, newData, 0600); err != nil { + if err = ioutils.AtomicWriteFile(path, newData, 0o600); err != nil { return "", fmt.Errorf("writing to file %q: %w", path, err) } } diff --git a/image/pkg/docker/config/config_test.go b/image/pkg/docker/config/config_test.go index 580274d103..7dbd9436ed 100644 --- a/image/pkg/docker/config/config_test.go +++ b/image/pkg/docker/config/config_test.go @@ -107,11 +107,11 @@ func TestGetAuth(t *testing.T) { if runtime.GOOS != "linux" { configDir1 = filepath.Join(tmpHomeDir, ".config", "containers") } - if err := os.MkdirAll(configDir1, 0700); err != nil { + if err := os.MkdirAll(configDir1, 0o700); err != nil { t.Fatal(err) } configDir2 := filepath.Join(tmpHomeDir, ".docker") - if err := os.MkdirAll(configDir2, 0700); err != nil { + if err := os.MkdirAll(configDir2, 0o700); err != nil { t.Fatal(err) } configPaths := [2]string{filepath.Join(configDir1, "auth.json"), filepath.Join(configDir2, "config.json")} @@ -290,7 +290,7 @@ func TestGetAuth(t *testing.T) { t.Fatal(err) } - if err := os.WriteFile(configPath, contents, 0640); err != nil { + if err := os.WriteFile(configPath, contents, 0o640); err != nil { t.Fatal(err) } } @@ -353,7 +353,7 @@ func TestGetAuthFromLegacyFile(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - if err := os.WriteFile(configPath, contents, 0640); err != nil { + if err := os.WriteFile(configPath, contents, 0o640); err != nil { t.Fatal(err) } @@ -375,7 +375,7 @@ func TestGetAuthPreferNewConfig(t *testing.T) { t.Logf("using temporary home directory: %q", tmpDir) configDir := filepath.Join(tmpDir, ".docker") - if err := os.Mkdir(configDir, 0750); err != nil { + if err := os.Mkdir(configDir, 0o750); err != nil { t.Fatal(err) } @@ -397,7 +397,7 @@ func TestGetAuthPreferNewConfig(t *testing.T) { t.Fatal(err) } - if err := os.WriteFile(data.target, contents, 0640); err != nil { + if err := os.WriteFile(data.target, contents, 0o640); err != nil { t.Fatal(err) } } @@ -420,7 +420,7 @@ func TestGetAuthFailsOnBadInput(t *testing.T) { if runtime.GOOS != "linux" { configDir = filepath.Join(tmpHomeDir, ".config", "containers") } - if err := os.MkdirAll(configDir, 0750); err != nil { + if err := os.MkdirAll(configDir, 0o750); err != nil { t.Fatal(err) } configPath := filepath.Join(configDir, "auth.json") @@ -432,7 +432,7 @@ func TestGetAuthFailsOnBadInput(t *testing.T) { } assert.Equal(t, types.DockerAuthConfig{}, auth) - if err := os.WriteFile(configPath, []byte("Json rocks! Unless it doesn't."), 0640); err != nil { + if err := os.WriteFile(configPath, []byte("Json rocks! Unless it doesn't."), 0o640); err != nil { t.Fatalf("failed to write file %q: %v", configPath, err) } _, err = getCredentialsWithHomeDir(nil, "index.docker.io", tmpHomeDir) @@ -448,7 +448,7 @@ func TestGetAuthFailsOnBadInput(t *testing.T) { assert.Equal(t, types.DockerAuthConfig{}, auth) configPath = filepath.Join(tmpHomeDir, ".dockercfg") - if err := os.WriteFile(configPath, []byte("I'm certainly not a json string."), 0640); err != nil { + if err := os.WriteFile(configPath, []byte("I'm certainly not a json string."), 0o640); err != nil { t.Fatalf("failed to write file %q: %v", configPath, err) } _, err = getCredentialsWithHomeDir(nil, "index.docker.io", tmpHomeDir) @@ -617,7 +617,7 @@ func TestGetAllCredentials(t *testing.T) { }, } { // Write the credentials to the authfile. - err := os.WriteFile(authFilePath, []byte{'{', '}'}, 0700) + err := os.WriteFile(authFilePath, []byte{'{', '}'}, 0o700) require.NoError(t, err) for _, d := range data { diff --git a/image/pkg/sysregistriesv2/shortnames.go b/image/pkg/sysregistriesv2/shortnames.go index 8c72ce7ffc..0da7c693b8 100644 --- a/image/pkg/sysregistriesv2/shortnames.go +++ b/image/pkg/sysregistriesv2/shortnames.go @@ -174,7 +174,7 @@ func editShortNameAlias(ctx *types.SystemContext, name string, value *string) (r delete(conf.Aliases, name) } - f, err := os.OpenFile(confPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) + f, err := os.OpenFile(confPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600) if err != nil { return err } @@ -343,7 +343,7 @@ func shortNameAliasesConfPathAndLock(ctx *types.SystemContext) (string, *lockfil return "", nil, err } // Make sure the path to file exists. - if err := os.MkdirAll(filepath.Dir(shortNameAliasesConfPath), 0700); err != nil { + if err := os.MkdirAll(filepath.Dir(shortNameAliasesConfPath), 0o700); err != nil { return "", nil, err } diff --git a/image/pkg/sysregistriesv2/shortnames_test.go b/image/pkg/sysregistriesv2/shortnames_test.go index 8c64b41803..2aaa33651b 100644 --- a/image/pkg/sysregistriesv2/shortnames_test.go +++ b/image/pkg/sysregistriesv2/shortnames_test.go @@ -72,7 +72,6 @@ func TestParseShortNameValue(t *testing.T) { require.NoError(t, err) assert.NotNil(t, named) assert.Equal(t, "docker.io/library/fedora", named.String()) - } func TestValidateShortName(t *testing.T) { diff --git a/image/pkg/sysregistriesv2/system_registries_v2.go b/image/pkg/sysregistriesv2/system_registries_v2.go index 1a1fcccf81..0cf44571d3 100644 --- a/image/pkg/sysregistriesv2/system_registries_v2.go +++ b/image/pkg/sysregistriesv2/system_registries_v2.go @@ -438,8 +438,8 @@ func (config *V2RegistriesConf) postProcessRegistries() error { return err } - //FIXME: unqualifiedSearchRegistries now also accepts empty values - //and shouldn't + // FIXME: unqualifiedSearchRegistries now also accepts empty values + // and shouldn't // https://github.com/containers/image/pull/1191#discussion_r610623216 if mir.Location == "" { return &InvalidRegistries{s: "invalid condition: mirror location is unset"} diff --git a/image/pkg/sysregistriesv2/system_registries_v2_test.go b/image/pkg/sysregistriesv2/system_registries_v2_test.go index fa499f95d5..b253714809 100644 --- a/image/pkg/sysregistriesv2/system_registries_v2_test.go +++ b/image/pkg/sysregistriesv2/system_registries_v2_test.go @@ -221,8 +221,10 @@ func TestRefMatchingPrefix(t *testing.T) { {"example.com/foo:bar2", "example.com/foo:bar", -1}, {"example.com", "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -1}, {"example.com/foo", "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -1}, - {"example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - len("example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")}, + { + "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + len("example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), + }, {"example.com/foo@sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -1}, // Prefix is invalid, but we shouldn’t crash. // (Note that this is necessary only because loadConfigFile doesn’t reject single-character values outright, @@ -240,7 +242,7 @@ func TestNewConfigWrapper(t *testing.T) { const variableReference = "$HOME" const rootPrefix = "/root/prefix" tempHome := t.TempDir() - var userRegistriesFile = filepath.FromSlash(".config/containers/registries.conf") + userRegistriesFile := filepath.FromSlash(".config/containers/registries.conf") userRegistriesFilePath := filepath.Join(tempHome, userRegistriesFile) for _, c := range []struct { @@ -531,7 +533,7 @@ insecure = true [[registry]] location = "untrusted.registry.com" -insecure = true`), 0600) +insecure = true`), 0o600) require.NoError(t, err) ctx := &types.SystemContext{SystemRegistriesConfPath: configFile.Name()} @@ -543,7 +545,7 @@ insecure = true`), 0600) // empty the config, but use the same SystemContext to show that the // previously specified registries are in the cache - err = os.WriteFile(configFile.Name(), []byte{}, 0600) + err = os.WriteFile(configFile.Name(), []byte{}, 0o600) require.NoError(t, err) registries, err = GetRegistries(ctx) assert.Nil(t, err) @@ -583,9 +585,11 @@ func TestRewriteReferenceSuccess(t *testing.T) { {"example.com:5000/image", "example.com:5000", "example.com:5000", "example.com:5000/image"}, {"example.com:5000/image:latest", "example.com:5000", "example.com:5000", "example.com:5000/image:latest"}, // Separator test ('/', '@', ':') - {"example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + { + "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "example.com", "example.com", - "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, + "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, {"example.com/foo/image:latest", "example.com/foo", "example.com", "example.com/image:latest"}, {"example.com/foo/image:latest", "example.com/foo", "example.com/path", "example.com/path/image:latest"}, // Docker examples @@ -604,8 +608,10 @@ func TestRewriteReferenceSuccess(t *testing.T) { {"abc.internal.registry.com/foo:bar", "*.internal.registry.com", "", "abc.internal.registry.com/foo:bar"}, {"blah.foo.bar.com/omg:bbq", "*.com", "", "blah.foo.bar.com/omg:bbq"}, {"alien.vs.predator.foobar.io:5000/omg", "*.foobar.io", "", "alien.vs.predator.foobar.io:5000/omg"}, - {"alien.vs.predator.foobar.io:5000/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "*.foobar.io", "", - "alien.vs.predator.foobar.io:5000/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, + { + "alien.vs.predator.foobar.io:5000/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "*.foobar.io", "", + "alien.vs.predator.foobar.io:5000/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, {"alien.vs.predator.foobar.io:5000/omg:bbq", "*.foobar.io", "", "alien.vs.predator.foobar.io:5000/omg:bbq"}, } { ref := toNamedRef(t, c.inputRef) @@ -620,8 +626,10 @@ func TestRewriteReferenceFailedDuringParseNamed(t *testing.T) { for _, c := range []struct{ inputRef, prefix, location string }{ // Invalid reference format {"example.com/foo/image:latest", "example.com/foo", "example.com/path/"}, - {"example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "example.com/foo", "example.com"}, + { + "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "example.com/foo", "example.com", + }, {"example.com:5000/image:latest", "example.com", ""}, {"example.com:5000/image:latest", "example.com", "example.com:5000"}, // Malformed prefix @@ -630,8 +638,10 @@ func TestRewriteReferenceFailedDuringParseNamed(t *testing.T) { {"example.com/foo/image:latest", "example.com/foo/", "example.com"}, {"example.com/foo/image", "example.com/f", "example.com/foo"}, {"example.com/foo:latest", "example.com/f", "example.com/foo"}, - {"example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "example.com/f", "example.com/foo"}, + { + "example.com/foo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "example.com/f", "example.com/foo", + }, {"docker.io/library/image", "example.com", "example.com"}, {"docker.io/library/image", "*.com", "example.com"}, {"foo.docker.io/library/image", "*.example.com", "example.com/image"}, @@ -804,7 +814,6 @@ func TestInvalidMirrorConfig(t *testing.T) { _, err := GetRegistries(tc.sys) assert.ErrorContains(t, err, tc.expectErr) } - } func TestTryUpdatingCache(t *testing.T) { diff --git a/image/pkg/tlsclientconfig/tlsclientconfig_test.go b/image/pkg/tlsclientconfig/tlsclientconfig_test.go index 76a96542a4..7dabe322b0 100644 --- a/image/pkg/tlsclientconfig/tlsclientconfig_test.go +++ b/image/pkg/tlsclientconfig/tlsclientconfig_test.go @@ -90,9 +90,9 @@ func TestSetupCertificates(t *testing.T) { // Directory not accessible unreadableDir := t.TempDir() defer func() { - _ = os.Chmod(unreadableDir, 0700) + _ = os.Chmod(unreadableDir, 0o700) }() - err = os.Chmod(unreadableDir, 000) + err = os.Chmod(unreadableDir, 0o00) require.NoError(t, err) tlsc = tls.Config{} err = SetupCertificates(unreadableDir, &tlsc) diff --git a/image/sif/load.go b/image/sif/load.go index 43937b63e4..e64e4e832a 100644 --- a/image/sif/load.go +++ b/image/sif/load.go @@ -99,10 +99,10 @@ func writeInjectedScript(extractedRootPath string, injectedScript []byte) error } filePath := filepath.Join(extractedRootPath, injectedScriptTargetPath) parentDirPath := filepath.Dir(filePath) - if err := os.MkdirAll(parentDirPath, 0755); err != nil { + if err := os.MkdirAll(parentDirPath, 0o755); err != nil { return fmt.Errorf("creating %s: %w", parentDirPath, err) } - if err := os.WriteFile(filePath, injectedScript, 0755); err != nil { + if err := os.WriteFile(filePath, injectedScript, 0o755); err != nil { return fmt.Errorf("writing %s to %s: %w", injectedScriptTargetPath, filePath, err) } return nil @@ -120,7 +120,7 @@ func createTarFromSIFInputs(ctx context.Context, tarPath, squashFSPath string, i conversionCommand := fmt.Sprintf("unsquashfs -d %s -f %s && tar --acls --xattrs -C %s -cpf %s ./", extractedRootPath, squashFSPath, extractedRootPath, tarPath) script := "#!/bin/sh\n" + conversionCommand + "\n" - if err := os.WriteFile(scriptPath, []byte(script), 0755); err != nil { + if err := os.WriteFile(scriptPath, []byte(script), 0o755); err != nil { return err } defer os.Remove(scriptPath) diff --git a/image/sif/transport_test.go b/image/sif/transport_test.go index 5fcfb60e92..49837c8a45 100644 --- a/image/sif/transport_test.go +++ b/image/sif/transport_test.go @@ -50,7 +50,7 @@ func TestNewReference(t *testing.T) { func testNewReference(t *testing.T, fn func(string) (types.ImageReference, error)) { tmpDir := t.TempDir() tmpFile := filepath.Join(tmpDir, "image.sif") - err := os.WriteFile(tmpFile, nil, 0600) + err := os.WriteFile(tmpFile, nil, 0o600) require.NoError(t, err) for _, file := range []string{ diff --git a/image/signature/docker.go b/image/signature/docker.go index 954eda4a52..3e6c3fa95e 100644 --- a/image/signature/docker.go +++ b/image/signature/docker.go @@ -49,7 +49,8 @@ func SignDockerManifest(m []byte, dockerReference string, mech SigningMechanism, // VerifyDockerManifestSignature checks that unverifiedSignature uses expectedKeyIdentity to sign unverifiedManifest as expectedDockerReference, // using mech. func VerifyDockerManifestSignature(unverifiedSignature, unverifiedManifest []byte, - expectedDockerReference string, mech SigningMechanism, expectedKeyIdentity string) (*Signature, error) { + expectedDockerReference string, mech SigningMechanism, expectedKeyIdentity string, +) (*Signature, error) { sig, _, err := VerifyImageManifestSignatureUsingKeyIdentityList(unverifiedSignature, unverifiedManifest, expectedDockerReference, mech, []string{expectedKeyIdentity}) return sig, err } @@ -58,7 +59,8 @@ func VerifyDockerManifestSignature(unverifiedSignature, unverifiedManifest []byt // to sign unverifiedManifest as expectedDockerReference, using mech. Returns the verified signature and the key identity that // was used to verify it. func VerifyImageManifestSignatureUsingKeyIdentityList(unverifiedSignature, unverifiedManifest []byte, - expectedDockerReference string, mech SigningMechanism, expectedKeyIdentities []string) (*Signature, string, error) { + expectedDockerReference string, mech SigningMechanism, expectedKeyIdentities []string, +) (*Signature, string, error) { expectedRef, err := reference.ParseNormalizedNamed(expectedDockerReference) if err != nil { return nil, "", err diff --git a/image/signature/fulcio_cert.go b/image/signature/fulcio_cert.go index e9d98368f7..203ed2ca5b 100644 --- a/image/signature/fulcio_cert.go +++ b/image/signature/fulcio_cert.go @@ -200,7 +200,8 @@ func parseLeafCertFromPEM(untrustedCertificateBytes []byte) (*x509.Certificate, func verifyRekorFulcio(rekorPublicKeys []*ecdsa.PublicKey, fulcioTrustRoot *fulcioTrustRoot, untrustedRekorSET []byte, untrustedCertificateBytes []byte, untrustedIntermediateChainBytes []byte, untrustedBase64Signature string, - untrustedPayloadBytes []byte) (crypto.PublicKey, error) { + untrustedPayloadBytes []byte, +) (crypto.PublicKey, error) { rekorSETTime, err := internal.VerifyRekorSET(rekorPublicKeys, untrustedRekorSET, untrustedCertificateBytes, untrustedBase64Signature, untrustedPayloadBytes) if err != nil { diff --git a/image/signature/internal/rekor_set.go b/image/signature/internal/rekor_set.go index 1c20e496a7..391f53a272 100644 --- a/image/signature/internal/rekor_set.go +++ b/image/signature/internal/rekor_set.go @@ -51,8 +51,10 @@ func (s *UntrustedRekorSET) strictUnmarshalJSON(data []byte) error { } // A compile-time check that UntrustedRekorSET and *UntrustedRekorSET implements json.Marshaler -var _ json.Marshaler = UntrustedRekorSET{} -var _ json.Marshaler = (*UntrustedRekorSET)(nil) +var ( + _ json.Marshaler = UntrustedRekorSET{} + _ json.Marshaler = (*UntrustedRekorSET)(nil) +) // MarshalJSON implements the json.Marshaler interface. func (s UntrustedRekorSET) MarshalJSON() ([]byte, error) { @@ -82,8 +84,10 @@ func (p *UntrustedRekorPayload) strictUnmarshalJSON(data []byte) error { } // A compile-time check that UntrustedRekorPayload and *UntrustedRekorPayload implements json.Marshaler -var _ json.Marshaler = UntrustedRekorPayload{} -var _ json.Marshaler = (*UntrustedRekorPayload)(nil) +var ( + _ json.Marshaler = UntrustedRekorPayload{} + _ json.Marshaler = (*UntrustedRekorPayload)(nil) +) // MarshalJSON implements the json.Marshaler interface. func (p UntrustedRekorPayload) MarshalJSON() ([]byte, error) { @@ -157,7 +161,6 @@ func VerifyRekorSET(publicKeys []*ecdsa.PublicKey, unverifiedRekorSET []byte, un } if hashedRekordV001.Signature.PublicKey == nil { return time.Time{}, NewInvalidSignatureError(`Missing "signature.publicKey" field in hashedrekord`) - } rekorKeyOrCertPEM, rest := pem.Decode(hashedRekordV001.Signature.PublicKey.Content) if rekorKeyOrCertPEM == nil { @@ -212,7 +215,6 @@ func VerifyRekorSET(publicKeys []*ecdsa.PublicKey, unverifiedRekorSET []byte, un rekorPayloadHash, err := hex.DecodeString(*hashedRekordV001.Data.Hash.Value) if err != nil { return time.Time{}, NewInvalidSignatureError(fmt.Sprintf(`Invalid "data.hash.value" field in hashedrekord: %v`, err)) - } unverifiedPayloadHash := sha256.Sum256(unverifiedPayloadBytes) if !bytes.Equal(rekorPayloadHash, unverifiedPayloadHash[:]) { diff --git a/image/signature/internal/sigstore_payload.go b/image/signature/internal/sigstore_payload.go index 682360bae9..e59bc79a95 100644 --- a/image/signature/internal/sigstore_payload.go +++ b/image/signature/internal/sigstore_payload.go @@ -48,8 +48,10 @@ func NewUntrustedSigstorePayload(dockerManifestDigest digest.Digest, dockerRefer } // A compile-time check that UntrustedSigstorePayload and *UntrustedSigstorePayload implements json.Marshaler -var _ json.Marshaler = UntrustedSigstorePayload{} -var _ json.Marshaler = (*UntrustedSigstorePayload)(nil) +var ( + _ json.Marshaler = UntrustedSigstorePayload{} + _ json.Marshaler = (*UntrustedSigstorePayload)(nil) +) // MarshalJSON implements the json.Marshaler interface. func (s UntrustedSigstorePayload) MarshalJSON() ([]byte, error) { @@ -96,7 +98,7 @@ func (s *UntrustedSigstorePayload) strictUnmarshalJSON(data []byte) error { var creatorID string var timestamp float64 - var gotCreatorID, gotTimestamp = false, false + gotCreatorID, gotTimestamp := false, false // /usr/bin/cosign generates "optional": null if there are no user-specified annotations. if !bytes.Equal(optional, []byte("null")) { if err := ParanoidUnmarshalJSONObject(optional, func(key string) any { diff --git a/image/signature/mechanism_test.go b/image/signature/mechanism_test.go index 7edcdea055..445b9ed4cf 100644 --- a/image/signature/mechanism_test.go +++ b/image/signature/mechanism_test.go @@ -76,7 +76,7 @@ func TestNewGPGSigningMechanismInDirectory(t *testing.T) { // the mechanism fails (with openpgp), or it succeeds (sadly, gpgme) and // later verification fails. unreadableDir := t.TempDir() - f, err := os.OpenFile(filepath.Join(unreadableDir, "pubring.gpg"), os.O_RDONLY|os.O_CREATE, 0000) + f, err := os.OpenFile(filepath.Join(unreadableDir, "pubring.gpg"), os.O_RDONLY|os.O_CREATE, 0o000) require.NoError(t, err) f.Close() mech, err = newGPGSigningMechanismInDirectory(unreadableDir) diff --git a/image/signature/policy_config.go b/image/signature/policy_config.go index 50f445148f..5e06531192 100644 --- a/image/signature/policy_config.go +++ b/image/signature/policy_config.go @@ -394,7 +394,7 @@ var _ json.Unmarshaler = (*prSignedBy)(nil) func (pr *prSignedBy) UnmarshalJSON(data []byte) error { *pr = prSignedBy{} var tmp prSignedBy - var gotKeyPath, gotKeyPaths, gotKeyData = false, false, false + gotKeyPath, gotKeyPaths, gotKeyData := false, false, false var signedIdentity json.RawMessage if err := internal.ParanoidUnmarshalJSONObject(data, func(key string) any { switch key { diff --git a/image/signature/policy_config_test.go b/image/signature/policy_config_test.go index b9bade4e9d..fd19a4d270 100644 --- a/image/signature/policy_config_test.go +++ b/image/signature/policy_config_test.go @@ -521,7 +521,8 @@ func TestPolicyTransportScopesUnmarshalJSON(t *testing.T) { // Return the result of modifying validJSON with fn and unmarshaling it into *pts // using transport. func tryUnmarshalModifiedPTS(t *testing.T, pts *PolicyTransportScopes, transport types.ImageTransport, - validJSON []byte, modifyFn func(mSA)) error { + validJSON []byte, modifyFn func(mSA), +) error { var tmp mSA err := json.Unmarshal(validJSON, &tmp) require.NoError(t, err) diff --git a/image/signature/policy_eval_signedby_test.go b/image/signature/policy_eval_signedby_test.go index 7cce194765..a1793249ae 100644 --- a/image/signature/policy_eval_signedby_test.go +++ b/image/signature/policy_eval_signedby_test.go @@ -84,7 +84,8 @@ func TestPRSignedByIsSignatureAuthorAccepted(t *testing.T) { } // Unimplemented and invalid KeyType values - for _, keyType := range []sbKeyType{SBKeyTypeSignedByGPGKeys, + for _, keyType := range []sbKeyType{ + SBKeyTypeSignedByGPGKeys, SBKeyTypeX509Certificates, SBKeyTypeSignedByX509CAs, sbKeyType("This is invalid"), @@ -213,7 +214,7 @@ func TestPRSignedByIsSignatureAuthorAccepted(t *testing.T) { // fails. func createInvalidSigDir(t *testing.T) string { dir := t.TempDir() - err := os.WriteFile(path.Join(dir, "manifest.json"), []byte("{}"), 0644) + err := os.WriteFile(path.Join(dir, "manifest.json"), []byte("{}"), 0o644) require.NoError(t, err) // Creating a 000-permissions file would work for unprivileged accounts, but root (in particular, // in the Docker container we use for testing) would still have access. So, create a symlink diff --git a/image/signature/policy_eval_sigstore.go b/image/signature/policy_eval_sigstore.go index cee04dc4ed..eb29bd8b57 100644 --- a/image/signature/policy_eval_sigstore.go +++ b/image/signature/policy_eval_sigstore.go @@ -210,7 +210,6 @@ func (pr *prSigstoreSigned) prepareTrustRoot() (*sigstoreSignedTrustRoot, error) pkECDSA, ok := pk.(*ecdsa.PublicKey) if !ok { return nil, fmt.Errorf("Rekor public key %d is not using ECDSA", index+1) - } res.rekorPublicKeys = append(res.rekorPublicKeys, pkECDSA) } diff --git a/image/signature/policy_eval_simple_test.go b/image/signature/policy_eval_simple_test.go index bda14049a2..b5b6806b24 100644 --- a/image/signature/policy_eval_simple_test.go +++ b/image/signature/policy_eval_simple_test.go @@ -26,6 +26,7 @@ type nameOnlyImageReferenceMock struct { func (ref nameOnlyImageReferenceMock) Transport() types.ImageTransport { return mocks.NameImageTransport("== Transport mock") } + func (ref nameOnlyImageReferenceMock) StringWithinTransport() string { return ref.s } diff --git a/image/signature/policy_eval_test.go b/image/signature/policy_eval_test.go index a140d241d2..06c72e1f23 100644 --- a/image/signature/policy_eval_test.go +++ b/image/signature/policy_eval_test.go @@ -78,13 +78,16 @@ type pcImageReferenceMock struct { func (ref pcImageReferenceMock) Transport() types.ImageTransport { return mocks.NameImageTransport(ref.transportName) } + func (ref pcImageReferenceMock) StringWithinTransport() string { // We use this in error messages, so sadly we must return something. return "== StringWithinTransport mock" } + func (ref pcImageReferenceMock) DockerReference() reference.Named { return ref.ref } + func (ref pcImageReferenceMock) PolicyConfigurationIdentity() string { res, err := policyconfiguration.DockerReferenceIdentity(ref.ref) if res == "" || err != nil { @@ -92,6 +95,7 @@ func (ref pcImageReferenceMock) PolicyConfigurationIdentity() string { } return res } + func (ref pcImageReferenceMock) PolicyConfigurationNamespaces() []string { if ref.ref == nil { panic("unexpected call to a mock function") @@ -127,7 +131,6 @@ func TestPolicyContextRequirementsForImageRefNotRegisteredTransport(t *testing.T reqs := pc.requirementsForImageRef(pcImageReferenceMock{transportName: "docker", ref: ref}) assert.True(t, &(reqs[0]) == &(pr[0])) assert.True(t, len(reqs) == len(pr)) - } func TestPolicyContextRequirementsForImageRef(t *testing.T) { diff --git a/image/signature/policy_reference_match.go b/image/signature/policy_reference_match.go index 0755c0399a..df57c7d952 100644 --- a/image/signature/policy_reference_match.go +++ b/image/signature/policy_reference_match.go @@ -56,6 +56,7 @@ func matchRepoDigestOrExactReferenceValues(intended, signature reference.Named) return false } } + func (prm *prmMatchRepoDigestOrExact) matchesDockerReference(image private.UnparsedImage, signatureDockerReference string) bool { intended, signature, err := parseImageAndDockerReference(image, signatureDockerReference) if err != nil { diff --git a/image/signature/policy_reference_match_test.go b/image/signature/policy_reference_match_test.go index 49f7825c8d..5b807f1885 100644 --- a/image/signature/policy_reference_match_test.go +++ b/image/signature/policy_reference_match_test.go @@ -71,6 +71,7 @@ type refImageReferenceMock struct { func (ref refImageReferenceMock) Transport() types.ImageTransport { return mocks.NameImageTransport("== Transport mock") } + func (ref refImageReferenceMock) StringWithinTransport() string { // We use this in error messages, so sadly we must return something. But right now we do so only when DockerReference is nil, so restrict to that. if ref.ref == nil { @@ -78,6 +79,7 @@ func (ref refImageReferenceMock) StringWithinTransport() string { } panic("unexpected call to a mock function") } + func (ref refImageReferenceMock) DockerReference() reference.Named { return ref.ref } diff --git a/image/signature/sigstore/fulcio/fulcio.go b/image/signature/sigstore/fulcio/fulcio.go index ad82bd0d6b..377c28553f 100644 --- a/image/signature/sigstore/fulcio/fulcio.go +++ b/image/signature/sigstore/fulcio/fulcio.go @@ -102,7 +102,8 @@ func WithFulcioAndPreexistingOIDCIDToken(fulcioURL *url.URL, oidcIDToken string) // // interactiveOutput must be directly accessible to a human user in real time (i.e. not be just a log file). func WithFulcioAndDeviceAuthorizationGrantOIDC(fulcioURL *url.URL, oidcIssuerURL *url.URL, oidcClientID, oidcClientSecret string, - interactiveOutput io.Writer) internal.Option { + interactiveOutput io.Writer, +) internal.Option { return func(s *internal.SigstoreSigner) error { if s.PrivateKey != nil { return fmt.Errorf("multiple private key sources specified when preparing to create sigstore signatures") @@ -132,7 +133,8 @@ func WithFulcioAndDeviceAuthorizationGrantOIDC(fulcioURL *url.URL, oidcIssuerURL // // interactiveInput and interactiveOutput must both be directly operable by a human user in real time (i.e. not be just a log file). func WithFulcioAndInteractiveOIDC(fulcioURL *url.URL, oidcIssuerURL *url.URL, oidcClientID, oidcClientSecret string, - interactiveInput io.Reader, interactiveOutput io.Writer) internal.Option { + interactiveInput io.Reader, interactiveOutput io.Writer, +) internal.Option { return func(s *internal.SigstoreSigner) error { if s.PrivateKey != nil { return fmt.Errorf("multiple private key sources specified when preparing to create sigstore signatures") diff --git a/image/signature/sigstore/generate_test.go b/image/signature/sigstore/generate_test.go index 6855c6c9d5..1b5765e119 100644 --- a/image/signature/sigstore/generate_test.go +++ b/image/signature/sigstore/generate_test.go @@ -30,7 +30,7 @@ func TestGenerateKeyPair(t *testing.T) { tmpDir := t.TempDir() privateKeyFile := filepath.Join(tmpDir, "private.key") - err = os.WriteFile(privateKeyFile, keyPair.PrivateKey, 0600) + err = os.WriteFile(privateKeyFile, keyPair.PrivateKey, 0o600) require.NoError(t, err) signer, err := NewSigner(WithPrivateKeyFile(privateKeyFile, passphrase)) diff --git a/image/signature/simple.go b/image/signature/simple.go index 8711f69080..8ec1517ea0 100644 --- a/image/signature/simple.go +++ b/image/signature/simple.go @@ -74,8 +74,10 @@ func newUntrustedSignature(dockerManifestDigest digest.Digest, dockerReference s } // A compile-time check that untrustedSignature and *untrustedSignature implements json.Marshaler -var _ json.Marshaler = untrustedSignature{} -var _ json.Marshaler = (*untrustedSignature)(nil) +var ( + _ json.Marshaler = untrustedSignature{} + _ json.Marshaler = (*untrustedSignature)(nil) +) // MarshalJSON implements the json.Marshaler interface. func (s untrustedSignature) MarshalJSON() ([]byte, error) { @@ -122,7 +124,7 @@ func (s *untrustedSignature) strictUnmarshalJSON(data []byte) error { var creatorID string var timestamp float64 - var gotCreatorID, gotTimestamp = false, false + gotCreatorID, gotTimestamp := false, false if err := internal.ParanoidUnmarshalJSONObject(optional, func(key string) any { switch key { case "creator": diff --git a/image/storage/storage_dest.go b/image/storage/storage_dest.go index 5909570007..000be3ccd1 100644 --- a/image/storage/storage_dest.go +++ b/image/storage/storage_dest.go @@ -267,7 +267,7 @@ func (s *storageImageDestination) putBlobToPendingFile(stream io.Reader, blobinf // Set up to digest the blob if necessary, and count its size while saving it to a file. filename := s.computeNextBlobCacheFile() - file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_EXCL, 0600) + file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_EXCL, 0o600) if err != nil { return private.UploadedBlob{}, fmt.Errorf("creating temporary file %q: %w", filename, err) } @@ -285,7 +285,6 @@ func (s *storageImageDestination) putBlobToPendingFile(stream io.Reader, blobinf decompressed, err := archive.DecompressStream(stream) if err != nil { return "", "", 0, fmt.Errorf("setting up to decompress blob: %w", err) - } defer decompressed.Close() @@ -348,7 +347,6 @@ func (f *zstdFetcher) GetBlobAt(chunks []chunked.ImageSourceChunk) (chan io.Read err = chunked.ErrBadRequest{} } return rc, errs, err - } // PutBlobPartial attempts to create a blob using the data that is already present diff --git a/image/storage/storage_image.go b/image/storage/storage_image.go index d493c14db6..7d14668357 100644 --- a/image/storage/storage_image.go +++ b/image/storage/storage_image.go @@ -11,11 +11,9 @@ import ( "go.podman.io/storage" ) -var ( - // ErrNoSuchImage is returned when we attempt to access an image which - // doesn't exist in the storage area. - ErrNoSuchImage = storage.ErrNotAnImage -) +// ErrNoSuchImage is returned when we attempt to access an image which +// doesn't exist in the storage area. +var ErrNoSuchImage = storage.ErrNotAnImage // manifestBigDataKey returns a key suitable for recording a manifest with the specified digest using storage.Store.ImageBigData and related functions. // If a specific manifest digest is explicitly requested by the user, the key returned by this function should be used preferably; diff --git a/image/storage/storage_test.go b/image/storage/storage_test.go index 509c664769..1f2e441087 100644 --- a/image/storage/storage_test.go +++ b/image/storage/storage_test.go @@ -229,7 +229,7 @@ func makeLayerGoroutine(dest io.Writer, uncompressedCount *int64, uncompressedDi if err := twriter.WriteHeader(&tar.Header{ Name: "/random-single-file", - Mode: 0600, + Mode: 0o600, Size: int64(len(buf)), ModTime: time.Now(), AccessTime: time.Now(), @@ -348,7 +348,8 @@ func configForLayers(t *testing.T, layers []testBlob) testBlob { } func createUncommittedImageDest(t *testing.T, ref types.ImageReference, cache types.BlobInfoCache, - layers []testBlob, config *testBlob) (types.ImageDestination, types.UnparsedImage) { + layers []testBlob, config *testBlob, +) (types.ImageDestination, types.UnparsedImage) { dest, err := ref.NewImageDestination(context.Background(), nil) require.NoError(t, err) @@ -379,7 +380,8 @@ func createUncommittedImageDest(t *testing.T, ref types.ImageReference, cache ty } func createImage(t *testing.T, ref types.ImageReference, cache types.BlobInfoCache, - layers []testBlob, config *testBlob) { + layers []testBlob, config *testBlob, +) { dest, unparsedToplevel := createUncommittedImageDest(t, ref, cache, layers, config) err := dest.Commit(context.Background(), unparsedToplevel) require.NoError(t, err) @@ -740,9 +742,11 @@ type unparsedImage struct { func (u *unparsedImage) Reference() types.ImageReference { return u.imageReference } + func (u *unparsedImage) Manifest(context.Context) ([]byte, string, error) { return u.manifestBytes, u.manifestType, nil } + func (u *unparsedImage) Signatures(context.Context) ([][]byte, error) { return u.signatures, nil } diff --git a/image/storage/storage_transport_test.go b/image/storage/storage_transport_test.go index b37c698088..f0f2382e8d 100644 --- a/image/storage/storage_transport_test.go +++ b/image/storage/storage_transport_test.go @@ -110,14 +110,18 @@ func TestTransportParseReference(t *testing.T) { {"[thisisunknown@" + root + "suffix2]", "", "", ""}, // Unknown graph driver {"[" + root + "suffix1]", "", "", ""}, // A valid root path, but no run dir {"[" + driver + "@" + root + "suffix3+relative/path]", "", "", ""}, // Non-absolute run dir - {"[" + driver + "@" + root + "suffix3+" + root + "suffix4]", + { + "[" + driver + "@" + root + "suffix3+" + root + "suffix4]", driver, root + "suffix3", - root + "suffix4"}, // A valid root@graph+run set - {"[" + driver + "@" + root + "suffix3+" + root + "suffix4:options,options,options]", + root + "suffix4", + }, // A valid root@graph+run set + { + "[" + driver + "@" + root + "suffix3+" + root + "suffix4:options,options,options]", driver, root + "suffix3", - root + "suffix4"}, // A valid root@graph+run+options set + root + "suffix4", + }, // A valid root@graph+run+options set } { t.Logf("parsing %q", c.prefix+"busybox") ref, err := Transport.ParseReference(c.prefix + "busybox") diff --git a/image/tarball/tarball_transport.go b/image/tarball/tarball_transport.go index 8c26e0c383..ccd60d3758 100644 --- a/image/tarball/tarball_transport.go +++ b/image/tarball/tarball_transport.go @@ -16,15 +16,12 @@ const ( separator = ":" ) -var ( - // Transport implements the types.ImageTransport interface for "tarball:" images, - // which are makeshift images constructed using one or more possibly-compressed tar - // archives. - Transport = &tarballTransport{} -) +// Transport implements the types.ImageTransport interface for "tarball:" images, +// which are makeshift images constructed using one or more possibly-compressed tar +// archives. +var Transport = &tarballTransport{} -type tarballTransport struct { -} +type tarballTransport struct{} func (t *tarballTransport) Name() string { return transportName diff --git a/storage/Makefile b/storage/Makefile index d411ce38c4..cf19be195c 100644 --- a/storage/Makefile +++ b/storage/Makefile @@ -69,6 +69,10 @@ install: install.docs lint: golangci-lint run --build-tags="$(AUTOTAGS) $(TAGS)" +.PHONY: fmt +fmt: + golangci-lint fmt + help: ## this help @awk 'BEGIN {FS = ":.*?## "} /^[a-z A-Z_-]+:.*?## / {gsub(" ",",",$$1);gsub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-21s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)