Skip to content

Commit

Permalink
Merge branch 'main' into golangci
Browse files Browse the repository at this point in the history
  • Loading branch information
Terry Howe authored Jul 12, 2023
2 parents 1e42348 + 21d0b71 commit bf0fae8
Show file tree
Hide file tree
Showing 47 changed files with 1,077 additions and 127 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/release-ghcr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ jobs:
if [[ "${VERSION}" == "${BRANCH_NAME}" ]]; then
VERSION=$(git rev-parse --short HEAD)
fi
echo ::set-output name=version::${VERSION}
echo ::set-output name=ref::ghcr.io/${{ github.repository }}:${VERSION}
echo "ref=ghcr.io/${{ github.repository }}:${VERSION}" >> $GITHUB_OUTPUT
- name: docker login
uses: docker/login-action@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-github.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: setup go environment
uses: actions/setup-go@v3
with:
go-version: '1.20.2'
go-version: '1.20.5'
- name: run goreleaser
uses: goreleaser/goreleaser-action@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Contributing

Please refer to the [ORAS Contributing guide](https://oras.land/docs/contributing).
Please refer to the [ORAS Contributing guide](https://oras.land/docs/community/contributing_guide).
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.20.2-alpine as builder
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.20.5-alpine as builder
ARG TARGETPLATFORM
RUN apk add git make
ENV ORASPKG /oras
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
## Docs

Documentation for the ORAS CLI is located on
the project website: [oras.land/cli](https://oras.land/docs/category/cli)
the project website: [oras.land/cli](https://oras.land/docs/category/oras-commands)

## Development Environment Setup

Refer to the [development guide](https://oras.land/docs/CLI/developer_guide) to get started [contributing to ORAS](https://oras.land/docs/contributing).
Refer to the [development guide](https://oras.land/docs/community/developer_guide) to get started [contributing to ORAS](https://oras.land/docs/community/contributing_guide).

## Code of Conduct

Expand Down
5 changes: 3 additions & 2 deletions cmd/oras/internal/display/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (p *tagManifestStatusForRepo) PushReference(ctx context.Context, expected o
if p.printHint != nil {
p.printHint.Do(func() {
ref := p.refPrefix + "@" + expected.Digest.String()
Print("Tagging", ref)
_ = Print("Tagging", ref)
})
}
if err := p.Repository.PushReference(ctx, expected, content, reference); err != nil {
Expand All @@ -136,9 +136,10 @@ func (p *tagManifestStatusForTarget) Tag(ctx context.Context, desc ocispec.Descr
if p.printHint != nil {
p.printHint.Do(func() {
ref := p.refPrefix + "@" + desc.Digest.String()
Print("Tagging", ref)
_ = Print("Tagging", ref)
})
}

if err := p.Target.Tag(ctx, desc, reference); err != nil {
return err
}
Expand Down
8 changes: 8 additions & 0 deletions cmd/oras/internal/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ limitations under the License.
package errors

import (
"errors"
"fmt"

"oras.land/oras-go/v2/registry"
"oras.land/oras-go/v2/registry/remote"
)

// NewErrInvalidReference creates a new error based on the reference string.
Expand All @@ -30,3 +32,9 @@ func NewErrInvalidReference(ref registry.Reference) error {
func NewErrInvalidReferenceStr(ref string) error {
return fmt.Errorf("%s: invalid image reference, expecting <name:tag|name@digest>", ref)
}

// IsReferrersIndexDelete checks if err is a referrers index delete error.
func IsReferrersIndexDelete(err error) bool {
var re *remote.ReferrersError
return errors.As(err, &re) && re.IsReferrersIndexDelete()
}
2 changes: 1 addition & 1 deletion cmd/oras/internal/option/applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type FlagApplier interface {
// NOTE: The option argument need to be a pointer to the options, so its value
// becomes addressable.
func ApplyFlags(optsPtr interface{}, target *pflag.FlagSet) {
rangeFields(optsPtr, func(fa FlagApplier) error {
_ = rangeFields(optsPtr, func(fa FlagApplier) error {
fa.ApplyFlags(target)
return nil
})
Expand Down
22 changes: 22 additions & 0 deletions cmd/oras/internal/option/packer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/pflag"
"oras.land/oras-go/v2/content"
"oras.land/oras/cmd/oras/internal/fileref"
)

// Pre-defined annotation keys for annotation file
Expand All @@ -38,6 +40,7 @@ var (
errAnnotationConflict = errors.New("`--annotation` and `--annotation-file` cannot be both specified")
errAnnotationFormat = errors.New("missing key in `--annotation` flag")
errAnnotationDuplication = errors.New("duplicate annotation key")
errPathValidation = errors.New("absolute file path detected. If it's intentional, use --disable-path-validation flag to skip this check")
)

// Packer option struct.
Expand Down Expand Up @@ -69,6 +72,25 @@ func (opts *Packer) ExportManifest(ctx context.Context, fetcher content.Fetcher,
}
return os.WriteFile(opts.ManifestExportPath, manifestBytes, 0666)
}
func (opts *Packer) Parse() error {
if !opts.PathValidationDisabled {
var failedPaths []string
for _, path := range opts.FileRefs {
// Remove the type if specified in the path <file>[:<type>] format
path, _, err := fileref.Parse(path, "")
if err != nil {
return err
}
if filepath.IsAbs(path) {
failedPaths = append(failedPaths, path)
}
}
if len(failedPaths) > 0 {
return fmt.Errorf("%w: %v", errPathValidation, strings.Join(failedPaths, ", "))
}
}
return nil
}

// LoadManifestAnnotations loads the manifest annotation map.
func (opts *Packer) LoadManifestAnnotations() (annotations map[string]map[string]string, err error) {
Expand Down
16 changes: 10 additions & 6 deletions cmd/oras/internal/option/packer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ func TestPacker_LoadManifestAnnotations_err(t *testing.T) {

func TestPacker_LoadManifestAnnotations_annotationFile(t *testing.T) {
testFile := filepath.Join(t.TempDir(), "testAnnotationFile")
os.WriteFile(testFile, []byte(testContent), fs.ModePerm)
err := os.WriteFile(testFile, []byte(testContent), fs.ModePerm)
if err != nil {
t.Fatalf("Error writing %s: %v", testFile, err)
}
opts := Packer{AnnotationFilePath: testFile}

anno, err := opts.LoadManifestAnnotations()
Expand Down Expand Up @@ -120,11 +123,12 @@ func TestPacker_LoadManifestAnnotations_annotationFlag(t *testing.T) {
t.Fatalf("unexpected error: failed when looking for '$manifest' in annotations")
}
if !reflect.DeepEqual(annotations,
map[string]map[string]string{"$manifest": {
"Key0": "",
"Key1": "Val",
"Key2": "${env:USERNAME}",
},
map[string]map[string]string{
"$manifest": {
"Key0": "",
"Key1": "Val",
"Key2": "${env:USERNAME}",
},
}) {
t.Fatalf("unexpected error: %v", errors.New("content not match"))
}
Expand Down
42 changes: 42 additions & 0 deletions cmd/oras/internal/option/referrers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package option

import (
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"oras.land/oras-go/v2/registry/remote"
)

// Referrers option struct.
type Referrers struct {
SkipDeleteReferrers bool
}

// ApplyFlags applies flags to a command flag set.
func (opts *Referrers) ApplyFlags(fs *pflag.FlagSet) {
fs.BoolVarP(&opts.SkipDeleteReferrers, "skip-delete-referrers", "", false, "skip deleting old referrers index, only work on registry when referrers API is not supported")
}

// SetReferrersGC sets the referrers GC option for the passed-in target.
func (opts *Referrers) SetReferrersGC(target any, logger logrus.FieldLogger) {
if repo, ok := target.(*remote.Repository); ok {
repo.SkipReferrersGC = opts.SkipDeleteReferrers
} else if opts.SkipDeleteReferrers {
// not a registry, can't skip referrers deletion
logger.Warnln("referrers deletion can only be enforced upon registry")
}
}
4 changes: 3 additions & 1 deletion cmd/oras/internal/option/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ func (opts *Remote) NewRepository(reference string, common Common) (repo *remote
return nil, err
}
if opts.distributionSpec.referrersAPI != nil {
repo.SetReferrersCapability(*opts.distributionSpec.referrersAPI)
if err := repo.SetReferrersCapability(*opts.distributionSpec.referrersAPI); err != nil {
return nil, err
}
}
return
}
Expand Down
9 changes: 7 additions & 2 deletions cmd/oras/internal/option/remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ func TestMain(m *testing.M) {
case p == "/v2/" && m == "GET":
w.WriteHeader(http.StatusOK)
case p == fmt.Sprintf("/v2/%s/tags/list", testRepo) && m == "GET":
json.NewEncoder(w).Encode(testTagList)
if err := json.NewEncoder(w).Encode(testTagList); err != nil {
http.Error(w, "error encoding", http.StatusBadRequest)
}
}
}))
defer ts.Close()
Expand Down Expand Up @@ -233,7 +235,10 @@ func TestRemote_NewRepository_Retry(t *testing.T) {
http.Error(w, "error", http.StatusTooManyRequests)
return
}
json.NewEncoder(w).Encode(testTagList)
err := json.NewEncoder(w).Encode(testTagList)
if err != nil {
http.Error(w, "error encoding", http.StatusBadRequest)
}
}))
defer ts.Close()
opts := struct {
Expand Down
15 changes: 11 additions & 4 deletions cmd/oras/root/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import (
"context"
"errors"
"fmt"
"os"
"strings"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/content"
"oras.land/oras-go/v2/content/file"
oerr "oras.land/oras/cmd/oras/internal/errors"
"oras.land/oras/cmd/oras/internal/option"
"oras.land/oras/internal/graph"
)
Expand All @@ -35,6 +37,7 @@ type attachOptions struct {
option.Packer
option.ImageSpec
option.Target
option.Referrers

artifactType string
concurrency int
Expand Down Expand Up @@ -72,7 +75,7 @@ Example - Attach file 'hi.txt' and add manifest annotations:
Example - Attach file 'hi.txt' and export the pushed manifest to 'manifest.json':
oras attach --artifact-type doc/example --export-manifest manifest.json localhost:5000/hello:v1 hi.txt
Example - Attach file to the manifest tagged 'v1' in an OCI layout folder 'layout-dir':
Example - Attach file to the manifest tagged 'v1' in an OCI image layout folder 'layout-dir':
oras attach --oci-layout --artifact-type doc/example layout-dir:v1 hi.txt
`,
Args: cobra.MinimumNArgs(1),
Expand All @@ -91,14 +94,14 @@ Example - Attach file to the manifest tagged 'v1' in an OCI layout folder 'layou

cmd.Flags().StringVarP(&opts.artifactType, "artifact-type", "", "", "artifact type")
cmd.Flags().IntVarP(&opts.concurrency, "concurrency", "", 5, "concurrency level")
cmd.MarkFlagRequired("artifact-type")
_ = cmd.MarkFlagRequired("artifact-type")
opts.EnableDistributionSpecFlag()
option.ApplyFlags(&opts, cmd.Flags())
return cmd
}

func runAttach(ctx context.Context, opts attachOptions) error {
ctx, _ = opts.WithContext(ctx)
ctx, logger := opts.WithContext(ctx)
annotations, err := opts.LoadManifestAnnotations()
if err != nil {
return err
Expand All @@ -113,7 +116,6 @@ func runAttach(ctx context.Context, opts attachOptions) error {
return err
}
defer store.Close()
store.AllowPathTraversalOnWrite = opts.PathValidationDisabled

dst, err := opts.NewTarget(opts.Common)
if err != nil {
Expand All @@ -122,6 +124,8 @@ func runAttach(ctx context.Context, opts attachOptions) error {
if err := opts.EnsureReferenceNotEmpty(); err != nil {
return err
}
opts.SetReferrersGC(dst, logger)

subject, err := dst.Resolve(ctx, opts.Reference)
if err != nil {
return err
Expand Down Expand Up @@ -164,6 +168,9 @@ func runAttach(ctx context.Context, opts attachOptions) error {

root, err := pushArtifact(dst, pack, copy)
if err != nil {
if oerr.IsReferrersIndexDelete(err) {
fmt.Fprintln(os.Stderr, "attached successfully but failed to remove the outdated referrers index, please use `--skip-delete-referrers` if you want to skip the deletion")
}
return err
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/oras/root/blob/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func fetchCmd() *cobra.Command {
var opts fetchBlobOptions
cmd := &cobra.Command{
Use: "fetch [flags] {--output <file> | --descriptor} <name>@<digest>",
Short: "Fetch a blob from a remote registry",
Long: `Fetch a blob from a remote registry
Short: "Fetch a blob from a registry or an OCI image layout",
Long: `Fetch a blob from a registry or an OCI image layout
Example - Fetch a blob from registry and save it to a local file:
oras blob fetch --output blob.tar.gz localhost:5000/hello@sha256:9a201d228ebd966211f7d1131be19f152be428bd373a92071c71d8deaf83b3e5
Expand Down
6 changes: 3 additions & 3 deletions cmd/oras/root/blob/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func pushCmd() *cobra.Command {
var opts pushBlobOptions
cmd := &cobra.Command{
Use: "push [flags] <name>[@digest] <file>",
Short: "Push a blob to a remote registry",
Long: `Push a blob to a remote registry
Short: "Push a blob to a registry or an OCI image layout",
Long: `Push a blob to a registry or an OCI image layout
Example - Push blob 'hi.txt' to a registry:
oras blob push localhost:5000/hello hi.txt
Expand All @@ -67,7 +67,7 @@ Example - Push blob 'hi.txt' and output the prettified descriptor:
Example - Push blob without TLS:
oras blob push --insecure localhost:5000/hello hi.txt
Example - Push blob 'hi.txt' into an OCI layout folder 'layout-dir':
Example - Push blob 'hi.txt' into an OCI image layout folder 'layout-dir':
oras blob push --oci-layout layout-dir hi.txt
`,
Args: cobra.ExactArgs(2),
Expand Down
Loading

0 comments on commit bf0fae8

Please sign in to comment.