mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
Update devfile library (#7240)
* Update go.mod Signed-off-by: thepetk <thepetk@gmail.com> * Update vendor Signed-off-by: thepetk <thepetk@gmail.com> * Bump up devfile library to 2.2.2 Signed-off-by: thepetk <thepetk@gmail.com> * Update vendor Signed-off-by: thepetk <thepetk@gmail.com> --------- Signed-off-by: thepetk <thepetk@gmail.com>
This commit is contained in:
2
vendor/github.com/containerd/containerd/archive/compression/compression.go
generated
vendored
2
vendor/github.com/containerd/containerd/archive/compression/compression.go
generated
vendored
@@ -25,12 +25,12 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/klauspost/compress/zstd"
|
||||
exec "golang.org/x/sys/execabs"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
6
vendor/github.com/containerd/containerd/content/content.go
generated
vendored
6
vendor/github.com/containerd/containerd/content/content.go
generated
vendored
@@ -108,6 +108,12 @@ type Status struct {
|
||||
// WalkFunc defines the callback for a blob walk.
|
||||
type WalkFunc func(Info) error
|
||||
|
||||
// InfoReaderProvider provides both info and reader for the specific content.
|
||||
type InfoReaderProvider interface {
|
||||
InfoProvider
|
||||
Provider
|
||||
}
|
||||
|
||||
// InfoProvider provides info for content inspection.
|
||||
type InfoProvider interface {
|
||||
// Info will return metadata about content available in the content store.
|
||||
|
||||
11
vendor/github.com/containerd/containerd/content/helpers.go
generated
vendored
11
vendor/github.com/containerd/containerd/content/helpers.go
generated
vendored
@@ -332,3 +332,14 @@ func copyWithBuffer(dst io.Writer, src io.Reader) (written int64, err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Exists returns whether an attempt to access the content would not error out
|
||||
// with an ErrNotFound error. It will return an encountered error if it was
|
||||
// different than ErrNotFound.
|
||||
func Exists(ctx context.Context, provider InfoProvider, desc ocispec.Descriptor) (bool, error) {
|
||||
_, err := provider.Info(ctx, desc.Digest)
|
||||
if errdefs.IsNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
return err == nil, err
|
||||
}
|
||||
|
||||
2
vendor/github.com/containerd/containerd/version/version.go
generated
vendored
2
vendor/github.com/containerd/containerd/version/version.go
generated
vendored
@@ -23,7 +23,7 @@ var (
|
||||
Package = "github.com/containerd/containerd"
|
||||
|
||||
// Version holds the complete version number. Filled in at linking time.
|
||||
Version = "1.7.11+unknown"
|
||||
Version = "1.7.13+unknown"
|
||||
|
||||
// Revision is filled with the VCS (e.g. git) revision being used to build
|
||||
// the program at linking time.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/generator/generators.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/generator/generators.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022-2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/generator/policy.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/generator/policy.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/generator/utils.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/generator/utils.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/imageNameSelector.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/imageNameSelector.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
5
vendor/github.com/devfile/library/v2/pkg/devfile/parse.go
generated
vendored
5
vendor/github.com/devfile/library/v2/pkg/devfile/parse.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package devfile
|
||||
import (
|
||||
"github.com/devfile/api/v2/pkg/validation/variables"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser"
|
||||
errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
|
||||
"github.com/devfile/library/v2/pkg/devfile/validate"
|
||||
)
|
||||
|
||||
@@ -121,7 +122,7 @@ func ParseDevfileAndValidate(args parser.ParserArgs) (d parser.DevfileObj, varWa
|
||||
// generic validation on devfile content
|
||||
err = validate.ValidateDevfileData(d.Data)
|
||||
if err != nil {
|
||||
return d, varWarning, err
|
||||
return d, varWarning, &errPkg.NonCompliantDevfile{Err: err.Error()}
|
||||
}
|
||||
|
||||
return d, varWarning, err
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/configurables.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/configurables.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
10
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/apiVersion.go
generated
vendored
10
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/apiVersion.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data"
|
||||
"github.com/pkg/errors"
|
||||
errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
@@ -32,7 +32,7 @@ func (d *DevfileCtx) SetDevfileAPIVersion() error {
|
||||
var r map[string]interface{}
|
||||
err := json.Unmarshal(d.rawContent, &r)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to decode devfile json")
|
||||
return &errPkg.NonCompliantDevfile{Err: err.Error()}
|
||||
}
|
||||
|
||||
// Get "schemaVersion" value from map for devfile V2
|
||||
@@ -47,10 +47,10 @@ func (d *DevfileCtx) SetDevfileAPIVersion() error {
|
||||
if okSchema {
|
||||
// SchemaVersion cannot be empty
|
||||
if schemaVersion.(string) == "" {
|
||||
return fmt.Errorf("schemaVersion in devfile: %s cannot be empty", devfilePath)
|
||||
return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion in devfile: %s cannot be empty", devfilePath)}
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("schemaVersion not present in devfile: %s", devfilePath)
|
||||
return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion not present in devfile: %s", devfilePath)}
|
||||
}
|
||||
|
||||
// Successful
|
||||
|
||||
10
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/content.go
generated
vendored
10
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/content.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022-2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,8 @@ import (
|
||||
"bytes"
|
||||
"unicode"
|
||||
|
||||
errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
|
||||
parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
|
||||
"github.com/devfile/library/v2/pkg/util"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/klog"
|
||||
@@ -41,7 +43,7 @@ func YAMLToJSON(data []byte) ([]byte, error) {
|
||||
// Is YAML, convert to JSON
|
||||
data, err := yaml.YAMLToJSON(data)
|
||||
if err != nil {
|
||||
return data, errors.Wrapf(err, "failed to convert devfile yaml to json")
|
||||
return data, &errPkg.NonCompliantDevfile{Err: err.Error()}
|
||||
}
|
||||
|
||||
// Successful
|
||||
@@ -62,7 +64,7 @@ func hasPrefix(buf []byte, prefix []byte) bool {
|
||||
}
|
||||
|
||||
// SetDevfileContent reads devfile and if devfile is in YAML format converts it to JSON
|
||||
func (d *DevfileCtx) SetDevfileContent() error {
|
||||
func (d *DevfileCtx) SetDevfileContent(devfileUtilsClient parserUtil.DevfileUtils) error {
|
||||
|
||||
var err error
|
||||
var data []byte
|
||||
@@ -72,7 +74,7 @@ func (d *DevfileCtx) SetDevfileContent() error {
|
||||
if d.token != "" {
|
||||
params.Token = d.token
|
||||
}
|
||||
data, err = util.DownloadInMemory(params)
|
||||
data, err = devfileUtilsClient.DownloadInMemory(params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error getting devfile info from url")
|
||||
}
|
||||
|
||||
11
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/context.go
generated
vendored
11
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/context.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022-2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package parser
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
|
||||
"github.com/devfile/library/v2/pkg/testingutil/filesystem"
|
||||
"github.com/devfile/library/v2/pkg/util"
|
||||
"k8s.io/klog"
|
||||
@@ -94,7 +95,7 @@ func (d *DevfileCtx) populateDevfile() (err error) {
|
||||
}
|
||||
|
||||
// Populate fills the DevfileCtx struct with relevant context info
|
||||
func (d *DevfileCtx) Populate() (err error) {
|
||||
func (d *DevfileCtx) Populate(devfileUtilsClient parserUtil.DevfileUtils) (err error) {
|
||||
d.relPath, err = lookupDevfileFromPath(d.fs, d.relPath)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -104,20 +105,20 @@ func (d *DevfileCtx) Populate() (err error) {
|
||||
}
|
||||
klog.V(4).Infof("absolute devfile path: '%s'", d.absPath)
|
||||
// Read and save devfile content
|
||||
if err = d.SetDevfileContent(); err != nil {
|
||||
if err = d.SetDevfileContent(devfileUtilsClient); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.populateDevfile()
|
||||
}
|
||||
|
||||
// PopulateFromURL fills the DevfileCtx struct with relevant context info
|
||||
func (d *DevfileCtx) PopulateFromURL() (err error) {
|
||||
func (d *DevfileCtx) PopulateFromURL(devfileUtilsClient parserUtil.DevfileUtils) (err error) {
|
||||
_, err = url.ParseRequestURI(d.url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Read and save devfile content
|
||||
if err := d.SetDevfileContent(); err != nil {
|
||||
if err := d.SetDevfileContent(devfileUtilsClient); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.populateDevfile()
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/fakecontext.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/fakecontext.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/fs.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/fs.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/location.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/location.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
7
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/schema.go
generated
vendored
7
vendor/github.com/devfile/library/v2/pkg/devfile/parser/context/schema.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data"
|
||||
errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
"k8s.io/klog"
|
||||
@@ -30,7 +31,7 @@ func (d *DevfileCtx) SetDevfileJSONSchema() error {
|
||||
// Check if json schema is present for the given apiVersion
|
||||
jsonSchema, err := data.GetDevfileJSONSchema(d.apiVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
return &errPkg.NonCompliantDevfile{Err: err.Error()}
|
||||
}
|
||||
d.jsonSchema = jsonSchema
|
||||
return nil
|
||||
@@ -54,7 +55,7 @@ func (d *DevfileCtx) ValidateDevfileSchema() error {
|
||||
for _, desc := range result.Errors() {
|
||||
errMsg = errMsg + fmt.Sprintf("- %s\n", desc)
|
||||
}
|
||||
return fmt.Errorf(errMsg)
|
||||
return &errPkg.NonCompliantDevfile{Err: errMsg}
|
||||
}
|
||||
|
||||
// Sucessful
|
||||
|
||||
4
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/helper.go
generated
vendored
4
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/helper.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package data
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog"
|
||||
@@ -51,6 +52,7 @@ func GetDevfileJSONSchema(version string) (string, error) {
|
||||
for version := range devfileApiVersionToJSONSchema {
|
||||
supportedVersions = append(supportedVersions, string(version))
|
||||
}
|
||||
sort.Strings(supportedVersions)
|
||||
return "", fmt.Errorf("unable to find schema for version %q. The parser supports devfile schema for version %s", version, strings.Join(supportedVersions, ", "))
|
||||
}
|
||||
klog.V(4).Infof("devfile apiVersion '%s' is supported", version)
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/interface.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/interface.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
package version220
|
||||
|
||||
// https://raw.githubusercontent.com/devfile/api/main/schemas/latest/devfile.json
|
||||
// https://raw.githubusercontent.com/devfile/api/v2.2.0/schemas/latest/devfile.json
|
||||
const JsonSchema220 = `{
|
||||
"description": "Devfile describes the structure of a cloud-native devworkspace and development environment.",
|
||||
"type": "object",
|
||||
"title": "Devfile schema - Version 2.2.1-alpha",
|
||||
"title": "Devfile schema - Version 2.2.0",
|
||||
"required": [
|
||||
"schemaVersion"
|
||||
],
|
||||
@@ -212,7 +212,7 @@ const JsonSchema220 = `{
|
||||
"additionalProperties": false
|
||||
},
|
||||
"hotReloadCapable": {
|
||||
"description": "Specify whether the command is restarted or not when the source code changes. If set to 'true' the command won't be restarted. A *hotReloadCapable* 'run' or 'debug' command is expected to handle file changes on its own and won't be restarted. A *hotReloadCapable* 'build' command is expected to be executed only once and won't be executed again. This field is taken into account only for commands 'build', 'run' and 'debug' with 'isDefault' set to 'true'.\n\nDefault value is 'false'",
|
||||
"description": "Whether the command is capable to reload itself when source code changes. If set to 'true' the command won't be restarted and it is expected to handle file changes on its own.\n\nDefault value is 'false'",
|
||||
"type": "boolean"
|
||||
},
|
||||
"label": {
|
||||
@@ -1104,7 +1104,7 @@ const JsonSchema220 = `{
|
||||
"additionalProperties": false
|
||||
},
|
||||
"hotReloadCapable": {
|
||||
"description": "Specify whether the command is restarted or not when the source code changes. If set to 'true' the command won't be restarted. A *hotReloadCapable* 'run' or 'debug' command is expected to handle file changes on its own and won't be restarted. A *hotReloadCapable* 'build' command is expected to be executed only once and won't be executed again. This field is taken into account only for commands 'build', 'run' and 'debug' with 'isDefault' set to 'true'.\n\nDefault value is 'false'",
|
||||
"description": "Whether the command is capable to reload itself when source code changes. If set to 'true' the command won't be restarted and it is expected to handle file changes on its own.\n\nDefault value is 'false'",
|
||||
"type": "boolean"
|
||||
},
|
||||
"label": {
|
||||
|
||||
2067
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.1/devfileJsonSchema221.go
generated
vendored
Normal file
2067
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.1/devfileJsonSchema221.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2230
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.2/devfileJsonSchema222.go
generated
vendored
Normal file
2230
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.2/devfileJsonSchema222.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/attributes.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/attributes.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
7
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/commands.go
generated
vendored
7
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/commands.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -17,10 +17,11 @@ package v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
)
|
||||
|
||||
// GetCommands returns the slice of Command objects parsed from the Devfile
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common/errors.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common/errors.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common/options.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common/options.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/components.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/components.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/containers.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/containers.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
5
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/events.go
generated
vendored
5
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/events.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -17,9 +17,10 @@ package v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetEvents returns the Events Object parsed from devfile
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/header.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/header.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/parent.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/parent.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
7
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/projects.go
generated
vendored
7
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/projects.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -17,10 +17,11 @@ package v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
)
|
||||
|
||||
// GetProjects returns the Project Object parsed from devfile
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/types.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/types.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/volumes.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/volumes.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/workspace.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/v2/workspace.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
12
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/versions.go
generated
vendored
12
vendor/github.com/devfile/library/v2/pkg/devfile/parser/data/versions.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,8 @@ import (
|
||||
v200 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.0.0"
|
||||
v210 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.1.0"
|
||||
v220 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.0"
|
||||
v221 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.1"
|
||||
v222 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.2"
|
||||
)
|
||||
|
||||
// SupportedApiVersions stores the supported devfile API versions
|
||||
@@ -32,6 +34,8 @@ const (
|
||||
APISchemaVersion200 supportedApiVersion = "2.0.0"
|
||||
APISchemaVersion210 supportedApiVersion = "2.1.0"
|
||||
APISchemaVersion220 supportedApiVersion = "2.2.0"
|
||||
APISchemaVersion221 supportedApiVersion = "2.2.1"
|
||||
APISchemaVersion222 supportedApiVersion = "2.2.2"
|
||||
APIVersionAlpha2 supportedApiVersion = "v1alpha2"
|
||||
)
|
||||
|
||||
@@ -46,6 +50,8 @@ func init() {
|
||||
apiVersionToDevfileStruct[APISchemaVersion200] = reflect.TypeOf(v2.DevfileV2{})
|
||||
apiVersionToDevfileStruct[APISchemaVersion210] = reflect.TypeOf(v2.DevfileV2{})
|
||||
apiVersionToDevfileStruct[APISchemaVersion220] = reflect.TypeOf(v2.DevfileV2{})
|
||||
apiVersionToDevfileStruct[APISchemaVersion221] = reflect.TypeOf(v2.DevfileV2{})
|
||||
apiVersionToDevfileStruct[APISchemaVersion222] = reflect.TypeOf(v2.DevfileV2{})
|
||||
apiVersionToDevfileStruct[APIVersionAlpha2] = reflect.TypeOf(v2.DevfileV2{})
|
||||
}
|
||||
|
||||
@@ -58,6 +64,8 @@ func init() {
|
||||
devfileApiVersionToJSONSchema[APISchemaVersion200] = v200.JsonSchema200
|
||||
devfileApiVersionToJSONSchema[APISchemaVersion210] = v210.JsonSchema210
|
||||
devfileApiVersionToJSONSchema[APISchemaVersion220] = v220.JsonSchema220
|
||||
devfileApiVersionToJSONSchema[APISchemaVersion221] = v221.JsonSchema221
|
||||
devfileApiVersionToJSONSchema[APISchemaVersion222] = v222.JsonSchema222
|
||||
// should use hightest v2 schema version since it is expected to be backward compatible with the same api version
|
||||
devfileApiVersionToJSONSchema[APIVersionAlpha2] = v220.JsonSchema220
|
||||
devfileApiVersionToJSONSchema[APIVersionAlpha2] = v222.JsonSchema222
|
||||
}
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/devfileobj.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/devfileobj.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
31
vendor/github.com/devfile/library/v2/pkg/devfile/parser/errors/errors.go
generated
vendored
Normal file
31
vendor/github.com/devfile/library/v2/pkg/devfile/parser/errors/errors.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// 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 errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
// NonCompliantDevfile returns an error if devfile parsing failed due to Non-Compliant Devfile
|
||||
type NonCompliantDevfile struct {
|
||||
Err string
|
||||
}
|
||||
|
||||
func (e *NonCompliantDevfile) Error() string {
|
||||
errMsg := "error parsing devfile because of non-compliant data"
|
||||
if e.Err != "" {
|
||||
errMsg = fmt.Sprintf("%s due to %v", errMsg, e.Err)
|
||||
}
|
||||
return errMsg
|
||||
}
|
||||
63
vendor/github.com/devfile/library/v2/pkg/devfile/parser/parse.go
generated
vendored
63
vendor/github.com/devfile/library/v2/pkg/devfile/parser/parse.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022-2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
@@ -30,6 +29,7 @@ import (
|
||||
devfileCtx "github.com/devfile/library/v2/pkg/devfile/parser/context"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
|
||||
"github.com/devfile/library/v2/pkg/util"
|
||||
registryLibrary "github.com/devfile/registry-support/registry-library/library"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -37,6 +37,8 @@ import (
|
||||
"k8s.io/klog"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
|
||||
|
||||
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
apiOverride "github.com/devfile/api/v2/pkg/utils/overriding"
|
||||
"github.com/devfile/api/v2/pkg/validation"
|
||||
@@ -63,7 +65,7 @@ func parseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolver
|
||||
// Unmarshal devfile content into devfile struct
|
||||
err = json.Unmarshal(d.Ctx.GetDevfileContent(), &d.Data)
|
||||
if err != nil {
|
||||
return d, errors.Wrapf(err, "failed to decode devfile content")
|
||||
return d, &errPkg.NonCompliantDevfile{Err: err.Error()}
|
||||
}
|
||||
|
||||
if flattenedDevfile {
|
||||
@@ -120,7 +122,7 @@ type ParserArgs struct {
|
||||
// DownloadGitResources downloads the resources from Git repository if true
|
||||
DownloadGitResources *bool
|
||||
// DevfileUtilsClient exposes the interface for mock implementation.
|
||||
DevfileUtilsClient DevfileUtils
|
||||
DevfileUtilsClient parserUtil.DevfileUtils
|
||||
}
|
||||
|
||||
// ImageSelectorArgs defines the structure to leverage for using image names as selectors after parsing the Devfile.
|
||||
@@ -154,14 +156,14 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
|
||||
if args.Data != nil {
|
||||
d.Ctx, err = devfileCtx.NewByteContentDevfileCtx(args.Data)
|
||||
if err != nil {
|
||||
return d, errors.Wrap(err, "failed to set devfile content from bytes")
|
||||
return d, err
|
||||
}
|
||||
} else if args.Path != "" {
|
||||
d.Ctx = devfileCtx.NewDevfileCtx(args.Path)
|
||||
} else if args.URL != "" {
|
||||
d.Ctx = devfileCtx.NewURLDevfileCtx(args.URL)
|
||||
} else {
|
||||
return d, errors.Wrap(err, "the devfile source is not provided")
|
||||
return d, fmt.Errorf("the devfile source is not provided")
|
||||
}
|
||||
|
||||
if args.Token != "" {
|
||||
@@ -169,7 +171,7 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
|
||||
}
|
||||
|
||||
if args.DevfileUtilsClient == nil {
|
||||
args.DevfileUtilsClient = NewDevfileUtilsClient()
|
||||
args.DevfileUtilsClient = parserUtil.NewDevfileUtilsClient()
|
||||
}
|
||||
|
||||
downloadGitResources := true
|
||||
@@ -194,7 +196,7 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
|
||||
|
||||
d, err = populateAndParseDevfile(d, &resolutionContextTree{}, tool, flattenedDevfile)
|
||||
if err != nil {
|
||||
return d, errors.Wrap(err, "failed to populateAndParseDevfile")
|
||||
return d, err
|
||||
}
|
||||
|
||||
setBooleanDefaults := true
|
||||
@@ -216,7 +218,7 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
|
||||
|
||||
if convertUriToInlined {
|
||||
d.Ctx.SetConvertUriToInlined(true)
|
||||
err = parseKubeResourceFromURI(d)
|
||||
err = parseKubeResourceFromURI(d, tool.devfileUtilsClient)
|
||||
if err != nil {
|
||||
return d, err
|
||||
}
|
||||
@@ -241,21 +243,21 @@ type resolverTools struct {
|
||||
// downloadGitResources downloads the resources from Git repository if true
|
||||
downloadGitResources bool
|
||||
// devfileUtilsClient exposes the Git Interface to be able to use mock implementation.
|
||||
devfileUtilsClient DevfileUtils
|
||||
devfileUtilsClient parserUtil.DevfileUtils
|
||||
}
|
||||
|
||||
func populateAndParseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) {
|
||||
var err error
|
||||
if err = resolveCtx.hasCycle(); err != nil {
|
||||
return DevfileObj{}, err
|
||||
return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: err.Error()}
|
||||
}
|
||||
// Fill the fields of DevfileCtx struct
|
||||
if d.Ctx.GetURL() != "" {
|
||||
err = d.Ctx.PopulateFromURL()
|
||||
err = d.Ctx.PopulateFromURL(tool.devfileUtilsClient)
|
||||
} else if d.Ctx.GetDevfileContent() != nil {
|
||||
err = d.Ctx.PopulateFromRaw()
|
||||
} else {
|
||||
err = d.Ctx.Populate()
|
||||
err = d.Ctx.Populate(tool.devfileUtilsClient)
|
||||
}
|
||||
if err != nil {
|
||||
return d, err
|
||||
@@ -328,7 +330,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
|
||||
case parent.Kubernetes != nil:
|
||||
parentDevfileObj, err = parseFromKubeCRD(parent.ImportReference, resolveCtx, tool)
|
||||
default:
|
||||
return fmt.Errorf("devfile parent does not define any resources")
|
||||
err = &errPkg.NonCompliantDevfile{Err: "devfile parent does not define any resources"}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -343,8 +345,9 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to parse version of parent devfile from: %v", resolveImportReference(parent.ImportReference))
|
||||
}
|
||||
|
||||
if parentDevfileVerson.GreaterThan(mainDevfileVersion) {
|
||||
return fmt.Errorf("the parent devfile version from %v is greater than the child devfile version from %v", resolveImportReference(parent.ImportReference), resolveImportReference(resolveCtx.importReference))
|
||||
return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the parent devfile version from %v is greater than the child devfile version from %v", resolveImportReference(parent.ImportReference), resolveImportReference(resolveCtx.importReference))}
|
||||
}
|
||||
}
|
||||
parentWorkspaceContent := parentDevfileObj.Data.GetDevfileWorkspaceSpecContent()
|
||||
@@ -389,7 +392,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
|
||||
case plugin.Kubernetes != nil:
|
||||
pluginDevfileObj, err = parseFromKubeCRD(plugin.ImportReference, resolveCtx, tool)
|
||||
default:
|
||||
return fmt.Errorf("plugin %s does not define any resources", component.Name)
|
||||
err = &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("plugin %s does not define any resources", component.Name)}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -405,7 +408,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
|
||||
return fmt.Errorf("fail to parse version of plugin devfile from: %v", resolveImportReference(component.Plugin.ImportReference))
|
||||
}
|
||||
if pluginDevfileVerson.GreaterThan(mainDevfileVersion) {
|
||||
return fmt.Errorf("the plugin devfile version from %v is greater than the child devfile version from %v", resolveImportReference(component.Plugin.ImportReference), resolveImportReference(resolveCtx.importReference))
|
||||
return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the plugin devfile version from %v is greater than the child devfile version from %v", resolveImportReference(component.Plugin.ImportReference), resolveImportReference(resolveCtx.importReference))}
|
||||
}
|
||||
}
|
||||
pluginWorkspaceContent := pluginDevfileObj.Data.GetDevfileWorkspaceSpecContent()
|
||||
@@ -459,7 +462,7 @@ func parseFromURI(importReference v1.ImportReference, curDevfileCtx devfileCtx.D
|
||||
newUri = path.Join(path.Dir(curDevfileCtx.GetAbsPath()), uri)
|
||||
d.Ctx = devfileCtx.NewDevfileCtx(newUri)
|
||||
if util.ValidateFile(newUri) != nil {
|
||||
return DevfileObj{}, fmt.Errorf("the provided path is not a valid filepath %s", newUri)
|
||||
return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the provided path is not a valid filepath %s", newUri)}
|
||||
}
|
||||
srcDir := path.Dir(newUri)
|
||||
destDir := path.Dir(curDevfileCtx.GetAbsPath())
|
||||
@@ -517,7 +520,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio
|
||||
}
|
||||
d.Ctx, err = devfileCtx.NewByteContentDevfileCtx(devfileContent)
|
||||
if err != nil {
|
||||
return d, errors.Wrap(err, "failed to set devfile content from bytes")
|
||||
return d, err
|
||||
}
|
||||
newResolveCtx := resolveCtx.appendNode(importReference)
|
||||
|
||||
@@ -548,7 +551,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return DevfileObj{}, fmt.Errorf("failed to fetch from registry, registry URL is not provided")
|
||||
return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: "failed to fetch from registry, registry URL is not provided"}
|
||||
}
|
||||
|
||||
return DevfileObj{}, fmt.Errorf("failed to get id: %s from registry URLs provided", id)
|
||||
@@ -556,7 +559,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio
|
||||
|
||||
func getDevfileFromRegistry(id, registryURL, version string, httpTimeout *int) ([]byte, error) {
|
||||
if !strings.HasPrefix(registryURL, "http://") && !strings.HasPrefix(registryURL, "https://") {
|
||||
return nil, fmt.Errorf("the provided registryURL: %s is not a valid URL", registryURL)
|
||||
return nil, &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the provided registryURL: %s is not a valid URL", registryURL)}
|
||||
}
|
||||
param := util.HTTPRequestParams{
|
||||
URL: fmt.Sprintf("%s/devfiles/%s/%s", registryURL, id, version),
|
||||
@@ -569,7 +572,7 @@ func getDevfileFromRegistry(id, registryURL, version string, httpTimeout *int) (
|
||||
}
|
||||
|
||||
func getResourcesFromRegistry(id, registryURL, destDir string) error {
|
||||
stackDir, err := ioutil.TempDir(os.TempDir(), fmt.Sprintf("registry-resources-%s", id))
|
||||
stackDir, err := os.MkdirTemp(os.TempDir(), fmt.Sprintf("registry-resources-%s", id))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
|
||||
}
|
||||
@@ -591,7 +594,7 @@ func getResourcesFromRegistry(id, registryURL, destDir string) error {
|
||||
func parseFromKubeCRD(importReference v1.ImportReference, resolveCtx *resolutionContextTree, tool resolverTools) (d DevfileObj, err error) {
|
||||
|
||||
if tool.k8sClient == nil || tool.context == nil {
|
||||
return DevfileObj{}, fmt.Errorf("Kubernetes client and context are required to parse from Kubernetes CRD")
|
||||
return DevfileObj{}, fmt.Errorf("kubernetes client and context are required to parse from Kubernetes CRD")
|
||||
}
|
||||
namespace := importReference.Kubernetes.Namespace
|
||||
|
||||
@@ -765,7 +768,7 @@ func setEndpoints(endpoints []v1.Endpoint) {
|
||||
}
|
||||
|
||||
// parseKubeResourceFromURI iterate through all kubernetes & openshift components, and parse from uri and update the content to inlined field in devfileObj
|
||||
func parseKubeResourceFromURI(devObj DevfileObj) error {
|
||||
func parseKubeResourceFromURI(devObj DevfileObj, devfileUtilsClient parserUtil.DevfileUtils) error {
|
||||
getKubeCompOptions := common.DevfileOptions{
|
||||
ComponentOptions: common.ComponentOptions{
|
||||
ComponentType: v1.KubernetesComponentType,
|
||||
@@ -787,7 +790,7 @@ func parseKubeResourceFromURI(devObj DevfileObj) error {
|
||||
for _, kubeComp := range kubeComponents {
|
||||
if kubeComp.Kubernetes != nil && kubeComp.Kubernetes.Uri != "" {
|
||||
/* #nosec G601 -- not an issue, kubeComp is de-referenced in sequence*/
|
||||
err := convertK8sLikeCompUriToInlined(&kubeComp, devObj.Ctx)
|
||||
err := convertK8sLikeCompUriToInlined(&kubeComp, devObj.Ctx, devfileUtilsClient)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to convert kubernetes uri to inlined for component '%s'", kubeComp.Name)
|
||||
}
|
||||
@@ -800,7 +803,7 @@ func parseKubeResourceFromURI(devObj DevfileObj) error {
|
||||
for _, openshiftComp := range openshiftComponents {
|
||||
if openshiftComp.Openshift != nil && openshiftComp.Openshift.Uri != "" {
|
||||
/* #nosec G601 -- not an issue, openshiftComp is de-referenced in sequence*/
|
||||
err := convertK8sLikeCompUriToInlined(&openshiftComp, devObj.Ctx)
|
||||
err := convertK8sLikeCompUriToInlined(&openshiftComp, devObj.Ctx, devfileUtilsClient)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to convert openshift uri to inlined for component '%s'", openshiftComp.Name)
|
||||
}
|
||||
@@ -814,14 +817,14 @@ func parseKubeResourceFromURI(devObj DevfileObj) error {
|
||||
}
|
||||
|
||||
// convertK8sLikeCompUriToInlined read in kubernetes resources definition from uri and converts to kubernetest inlined field
|
||||
func convertK8sLikeCompUriToInlined(component *v1.Component, d devfileCtx.DevfileCtx) error {
|
||||
func convertK8sLikeCompUriToInlined(component *v1.Component, d devfileCtx.DevfileCtx, devfileUtilsClient parserUtil.DevfileUtils) error {
|
||||
var uri string
|
||||
if component.Kubernetes != nil {
|
||||
uri = component.Kubernetes.Uri
|
||||
} else if component.Openshift != nil {
|
||||
uri = component.Openshift.Uri
|
||||
}
|
||||
data, err := getKubernetesDefinitionFromUri(uri, d)
|
||||
data, err := getKubernetesDefinitionFromUri(uri, d, devfileUtilsClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -841,7 +844,7 @@ func convertK8sLikeCompUriToInlined(component *v1.Component, d devfileCtx.Devfil
|
||||
}
|
||||
|
||||
// getKubernetesDefinitionFromUri read in kubernetes resources definition from uri and returns the raw content
|
||||
func getKubernetesDefinitionFromUri(uri string, d devfileCtx.DevfileCtx) ([]byte, error) {
|
||||
func getKubernetesDefinitionFromUri(uri string, d devfileCtx.DevfileCtx, devfileUtilsClient parserUtil.DevfileUtils) ([]byte, error) {
|
||||
// validate URI
|
||||
err := validation.ValidateURI(uri)
|
||||
if err != nil {
|
||||
@@ -876,7 +879,7 @@ func getKubernetesDefinitionFromUri(uri string, d devfileCtx.DevfileCtx) ([]byte
|
||||
if d.GetToken() != "" {
|
||||
params.Token = d.GetToken()
|
||||
}
|
||||
data, err = util.DownloadInMemory(params)
|
||||
data, err = devfileUtilsClient.DownloadInMemory(params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error getting kubernetes resources definition information")
|
||||
}
|
||||
|
||||
75
vendor/github.com/devfile/library/v2/pkg/devfile/parser/parser_mock.go
generated
vendored
75
vendor/github.com/devfile/library/v2/pkg/devfile/parser/parser_mock.go
generated
vendored
@@ -1,75 +0,0 @@
|
||||
//
|
||||
// Copyright 2023 Red Hat, Inc.
|
||||
//
|
||||
// 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 parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/devfile/library/v2/pkg/util"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type MockDevfileUtilsClient struct {
|
||||
ParentURLAlias string // Specify a valid git URL as an alias if using a localhost HTTP server in order to pass validation.
|
||||
MockGitURL util.MockGitUrl
|
||||
GitTestToken string // Mock Git token. Specify the string "valid-token" for the mock CloneGitRepo to pass
|
||||
}
|
||||
|
||||
func NewMockDevfileUtilsClient() MockDevfileUtilsClient {
|
||||
return MockDevfileUtilsClient{}
|
||||
}
|
||||
|
||||
func (gc MockDevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
|
||||
|
||||
//the url parameter that gets passed in will be the localhost IP of the test server, so it will fail all the validation checks. We will use the global testURL variable instead
|
||||
//skip the Git Provider check since it'll fail
|
||||
if util.IsGitProviderRepo(gc.ParentURLAlias) {
|
||||
// this converts the test git URL to a mock URL
|
||||
mockGitUrl := gc.MockGitURL
|
||||
mockGitUrl.Token = gc.GitTestToken
|
||||
|
||||
if !mockGitUrl.IsFile || mockGitUrl.Revision == "" || !strings.Contains(mockGitUrl.Path, OutputDevfileYamlPath) {
|
||||
return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url+"/"+mockGitUrl.Path)
|
||||
}
|
||||
|
||||
stackDir, err := os.MkdirTemp("", fmt.Sprintf("git-resources"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
|
||||
}
|
||||
|
||||
defer func(path string) {
|
||||
err := os.RemoveAll(path)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
|
||||
}
|
||||
}(stackDir)
|
||||
|
||||
err = mockGitUrl.CloneGitRepo(stackDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = util.CopyAllDirFiles(stackDir, destDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
return fmt.Errorf("Failed to download resources from parent devfile. Unsupported Git Provider for %s ", gc.ParentURLAlias)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
23
vendor/github.com/devfile/library/v2/pkg/devfile/parser/reader.go
generated
vendored
23
vendor/github.com/devfile/library/v2/pkg/devfile/parser/reader.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022-2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
|
||||
parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
|
||||
"github.com/devfile/library/v2/pkg/util"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/afero"
|
||||
@@ -38,6 +40,8 @@ type YamlSrc struct {
|
||||
Path string
|
||||
// URL of the yaml file
|
||||
URL string
|
||||
// Token to access a private URL like a private repository
|
||||
Token string
|
||||
// Data is the yaml content in []byte format
|
||||
Data []byte
|
||||
}
|
||||
@@ -56,15 +60,20 @@ type KubernetesResources struct {
|
||||
// It returns all the parsed Kubernetes objects as an array of interface.
|
||||
// Consumers interested in the Kubernetes resources are expected to Unmarshal
|
||||
// it to the struct of the respective Kubernetes resource. If a Path is being passed,
|
||||
// provide a filesystem, otherwise nil can be passed in
|
||||
func ReadKubernetesYaml(src YamlSrc, fs *afero.Afero) ([]interface{}, error) {
|
||||
// provide a filesystem, otherwise nil can be passed in.
|
||||
// Pass in an optional client to use either the actual implementation or a mock implementation of the interface.
|
||||
func ReadKubernetesYaml(src YamlSrc, fs *afero.Afero, devfileUtilsClient parserUtil.DevfileUtils) ([]interface{}, error) {
|
||||
|
||||
var data []byte
|
||||
var err error
|
||||
|
||||
if src.URL != "" {
|
||||
params := util.HTTPRequestParams{URL: src.URL}
|
||||
data, err = util.DownloadInMemory(params)
|
||||
if devfileUtilsClient == nil {
|
||||
devfileUtilsClient = parserUtil.NewDevfileUtilsClient()
|
||||
}
|
||||
|
||||
params := util.HTTPRequestParams{URL: src.URL, Token: src.Token}
|
||||
data, err = devfileUtilsClient.DownloadInMemory(params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to download file %q", src.URL)
|
||||
}
|
||||
@@ -124,7 +133,7 @@ func ParseKubernetesYaml(values []interface{}) (KubernetesResources, error) {
|
||||
var kubernetesMap map[string]interface{}
|
||||
err = k8yaml.Unmarshal(byteData, &kubernetesMap)
|
||||
if err != nil {
|
||||
return KubernetesResources{}, err
|
||||
return KubernetesResources{}, &errPkg.NonCompliantDevfile{Err: err.Error()}
|
||||
}
|
||||
kind := kubernetesMap["kind"]
|
||||
|
||||
@@ -147,7 +156,7 @@ func ParseKubernetesYaml(values []interface{}) (KubernetesResources, error) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return KubernetesResources{}, err
|
||||
return KubernetesResources{}, &errPkg.NonCompliantDevfile{Err: err.Error()}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/resolutionContext.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/resolutionContext.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/sourceAttribute.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/sourceAttribute.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
23
vendor/github.com/devfile/library/v2/pkg/devfile/parser/util/interface.go
generated
vendored
Normal file
23
vendor/github.com/devfile/library/v2/pkg/devfile/parser/util/interface.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// 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 util
|
||||
|
||||
import "github.com/devfile/library/v2/pkg/util"
|
||||
|
||||
type DevfileUtils interface {
|
||||
DownloadGitRepoResources(url string, destDir string, token string) error
|
||||
DownloadInMemory(params util.HTTPRequestParams) ([]byte, error)
|
||||
}
|
||||
147
vendor/github.com/devfile/library/v2/pkg/devfile/parser/util/mock.go
generated
vendored
Normal file
147
vendor/github.com/devfile/library/v2/pkg/devfile/parser/util/mock.go
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/devfile/library/v2/pkg/util"
|
||||
)
|
||||
|
||||
// Default filenames for create devfile to be used in mocks
|
||||
const (
|
||||
OutputDevfileYamlPath = "devfile.yaml"
|
||||
)
|
||||
|
||||
type MockDevfileUtilsClient struct {
|
||||
// Specify a valid git URL as an alias if using a localhost HTTP server in order to pass validation.
|
||||
ParentURLAlias string
|
||||
|
||||
// MockGitUrl struct for mocking git related ops
|
||||
MockGitURL util.MockGitUrl
|
||||
|
||||
// Mock Git token. Specify the string "valid-token" for the mock CloneGitRepo to pass
|
||||
GitTestToken string
|
||||
|
||||
// Options to specify what file download needs to be mocked
|
||||
DownloadOptions util.MockDownloadOptions
|
||||
}
|
||||
|
||||
func NewMockDevfileUtilsClient() MockDevfileUtilsClient {
|
||||
return MockDevfileUtilsClient{}
|
||||
}
|
||||
|
||||
func (gc *MockDevfileUtilsClient) DownloadInMemory(params util.HTTPRequestParams) ([]byte, error) {
|
||||
var httpClient = &http.Client{Transport: &http.Transport{
|
||||
ResponseHeaderTimeout: util.HTTPRequestResponseTimeout,
|
||||
}, Timeout: util.HTTPRequestResponseTimeout}
|
||||
|
||||
if gc.MockGitURL.Host != "" {
|
||||
if util.IsGitProviderRepo(gc.MockGitURL.Host) {
|
||||
gc.MockGitURL.Token = gc.GitTestToken
|
||||
}
|
||||
} else if params.URL != "" {
|
||||
// Not all clients have the ability to pass in mock data
|
||||
// So we should be adaptable and use the function params
|
||||
// and mock the output
|
||||
if util.IsGitProviderRepo(params.URL) {
|
||||
gc.MockGitURL.Host = params.URL
|
||||
gc.MockGitURL.Token = params.Token
|
||||
}
|
||||
}
|
||||
|
||||
if gc.DownloadOptions.MockParent == nil {
|
||||
gc.DownloadOptions.MockParent = &util.MockParent{}
|
||||
}
|
||||
|
||||
file, err := gc.MockGitURL.DownloadInMemoryWithClient(params, httpClient, gc.DownloadOptions)
|
||||
|
||||
if gc.DownloadOptions.MockParent != nil && gc.DownloadOptions.MockParent.IsMainDevfileDownloaded && gc.DownloadOptions.MockParent.IsParentDevfileDownloaded {
|
||||
// Since gc is a pointer, if both the main and parent devfiles are downloaded, reset the flag.
|
||||
// So that other tests can use the Mock Parent Devfile download if required.
|
||||
gc.DownloadOptions.MockParent.IsMainDevfileDownloaded = false
|
||||
gc.DownloadOptions.MockParent.IsParentDevfileDownloaded = false
|
||||
}
|
||||
|
||||
if gc.MockGitURL.Host != "" && params.URL != "" {
|
||||
// Since gc is a pointer, reset the mock data if both the URL and Host are present
|
||||
gc.MockGitURL.Host = ""
|
||||
gc.MockGitURL.Token = ""
|
||||
}
|
||||
|
||||
return file, err
|
||||
}
|
||||
|
||||
func (gc MockDevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
|
||||
|
||||
// if mock data is unavailable as certain clients cant provide mock data
|
||||
// then adapt and create mock data from actual params
|
||||
if gc.ParentURLAlias == "" {
|
||||
gc.ParentURLAlias = url
|
||||
gc.MockGitURL.IsFile = true
|
||||
gc.MockGitURL.Revision = "main"
|
||||
gc.MockGitURL.Path = OutputDevfileYamlPath
|
||||
gc.MockGitURL.Host = "github.com"
|
||||
gc.MockGitURL.Protocol = "https"
|
||||
gc.MockGitURL.Owner = "devfile"
|
||||
gc.MockGitURL.Repo = "library"
|
||||
}
|
||||
|
||||
if gc.GitTestToken == "" {
|
||||
gc.GitTestToken = token
|
||||
}
|
||||
|
||||
//the url parameter that gets passed in will be the localhost IP of the test server, so it will fail all the validation checks. We will use the global testURL variable instead
|
||||
//skip the Git Provider check since it'll fail
|
||||
if util.IsGitProviderRepo(gc.ParentURLAlias) {
|
||||
// this converts the test git URL to a mock URL
|
||||
mockGitUrl := gc.MockGitURL
|
||||
mockGitUrl.Token = gc.GitTestToken
|
||||
|
||||
if !mockGitUrl.IsFile || mockGitUrl.Revision == "" || !ValidateDevfileExistence((mockGitUrl.Path)) {
|
||||
return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url+"/"+mockGitUrl.Path)
|
||||
}
|
||||
|
||||
stackDir, err := os.MkdirTemp("", "git-resources")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
|
||||
}
|
||||
|
||||
defer func(path string) {
|
||||
err = os.RemoveAll(path)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
|
||||
}
|
||||
}(stackDir)
|
||||
|
||||
err = mockGitUrl.CloneGitRepo(stackDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = util.CopyAllDirFiles(stackDir, destDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
return fmt.Errorf("failed to download resources from parent devfile. Unsupported Git Provider for %s ", gc.ParentURLAlias)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
98
vendor/github.com/devfile/library/v2/pkg/devfile/parser/util/utils.go
generated
vendored
Normal file
98
vendor/github.com/devfile/library/v2/pkg/devfile/parser/util/utils.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/devfile/library/v2/pkg/util"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
// Contains common naming conventions for devfiles to look for when downloading resources
|
||||
var DevfilePossibilities = [...]string{"devfile.yaml", ".devfile.yaml", "devfile.yml", ".devfile.yml"}
|
||||
|
||||
type DevfileUtilsClient struct {
|
||||
}
|
||||
|
||||
func NewDevfileUtilsClient() DevfileUtilsClient {
|
||||
return DevfileUtilsClient{}
|
||||
}
|
||||
|
||||
// DownloadInMemory is a wrapper to the util.DownloadInMemory() call.
|
||||
// This is done to help devfile/library clients invoke this function with a client.
|
||||
func (c DevfileUtilsClient) DownloadInMemory(params util.HTTPRequestParams) ([]byte, error) {
|
||||
return util.DownloadInMemory(params)
|
||||
}
|
||||
|
||||
// DownloadGitRepoResources downloads the git repository resources
|
||||
func (c DevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
|
||||
var returnedErr error
|
||||
if util.IsGitProviderRepo(url) {
|
||||
gitUrl, err := util.NewGitURL(url, token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !gitUrl.IsFile || gitUrl.Revision == "" || !ValidateDevfileExistence((gitUrl.Path)) {
|
||||
return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url)
|
||||
}
|
||||
|
||||
stackDir, err := os.MkdirTemp("", "git-resources")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
|
||||
}
|
||||
|
||||
defer func(path string) {
|
||||
err := os.RemoveAll(path)
|
||||
if err != nil {
|
||||
returnedErr = multierror.Append(returnedErr, err)
|
||||
}
|
||||
}(stackDir)
|
||||
|
||||
gitUrl.Token = token
|
||||
|
||||
err = gitUrl.CloneGitRepo(stackDir)
|
||||
if err != nil {
|
||||
returnedErr = multierror.Append(returnedErr, err)
|
||||
return returnedErr
|
||||
}
|
||||
|
||||
dir := path.Dir(path.Join(stackDir, gitUrl.Path))
|
||||
err = util.CopyAllDirFiles(dir, destDir)
|
||||
if err != nil {
|
||||
returnedErr = multierror.Append(returnedErr, err)
|
||||
return returnedErr
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("failed to download resources from parent devfile. Unsupported Git Provider for %s ", url)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateDevfileExistence verifies if any of the naming possibilities for devfile are present in the url path
|
||||
func ValidateDevfileExistence(path string) bool {
|
||||
for _, devfile := range DevfilePossibilities {
|
||||
if strings.Contains(path, devfile) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
64
vendor/github.com/devfile/library/v2/pkg/devfile/parser/utils.go
generated
vendored
64
vendor/github.com/devfile/library/v2/pkg/devfile/parser/utils.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022-2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -17,75 +17,13 @@ package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/devfile/library/v2/pkg/util"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
)
|
||||
|
||||
type DevfileUtilsClient struct {
|
||||
}
|
||||
|
||||
func NewDevfileUtilsClient() DevfileUtilsClient {
|
||||
return DevfileUtilsClient{}
|
||||
}
|
||||
|
||||
type DevfileUtils interface {
|
||||
DownloadGitRepoResources(url string, destDir string, token string) error
|
||||
}
|
||||
|
||||
// DownloadGitRepoResources mock implementation of the real method.
|
||||
func (gc DevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
|
||||
var returnedErr error
|
||||
if util.IsGitProviderRepo(url) {
|
||||
gitUrl, err := util.NewGitURL(url, token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !gitUrl.IsFile || gitUrl.Revision == "" || !strings.Contains(gitUrl.Path, OutputDevfileYamlPath) {
|
||||
return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url)
|
||||
}
|
||||
|
||||
stackDir, err := os.MkdirTemp("", fmt.Sprintf("git-resources"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
|
||||
}
|
||||
|
||||
defer func(path string) {
|
||||
err := os.RemoveAll(path)
|
||||
if err != nil {
|
||||
returnedErr = multierror.Append(returnedErr, err)
|
||||
}
|
||||
}(stackDir)
|
||||
|
||||
gitUrl.Token = token
|
||||
|
||||
err = gitUrl.CloneGitRepo(stackDir)
|
||||
if err != nil {
|
||||
returnedErr = multierror.Append(returnedErr, err)
|
||||
return returnedErr
|
||||
}
|
||||
|
||||
dir := path.Dir(path.Join(stackDir, gitUrl.Path))
|
||||
err = util.CopyAllDirFiles(dir, destDir)
|
||||
if err != nil {
|
||||
returnedErr = multierror.Append(returnedErr, err)
|
||||
return returnedErr
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("Failed to download resources from parent devfile. Unsupported Git Provider for %s ", url)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDeployComponents gets the default deploy command associated components
|
||||
func GetDeployComponents(devfileData data.DevfileData) (map[string]string, error) {
|
||||
deployCommandFilter := common.DevfileOptions{
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/writer.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/devfile/parser/writer.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
3
vendor/github.com/devfile/library/v2/pkg/devfile/validate/validate.go
generated
vendored
3
vendor/github.com/devfile/library/v2/pkg/devfile/validate/validate.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@ package validate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v2Validation "github.com/devfile/api/v2/pkg/validation"
|
||||
devfileData "github.com/devfile/library/v2/pkg/devfile/parser/data"
|
||||
v2 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2"
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/testingutil/containers.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/testingutil/containers.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/testingutil/devfile.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/testingutil/devfile.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
56
vendor/github.com/devfile/library/v2/pkg/testingutil/filesystem/default_fs.go
generated
vendored
56
vendor/github.com/devfile/library/v2/pkg/testingutil/filesystem/default_fs.go
generated
vendored
@@ -22,13 +22,12 @@ limitations under the License.
|
||||
package filesystem
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DefaultFs implements Filesystem using same-named functions from "os" and "io/ioutil"
|
||||
// DefaultFs implements Filesystem using same-named functions from "os"
|
||||
type DefaultFs struct{}
|
||||
|
||||
var _ Filesystem = DefaultFs{}
|
||||
@@ -97,33 +96,64 @@ func (DefaultFs) Getwd() (dir string, err error) {
|
||||
return os.Getwd()
|
||||
}
|
||||
|
||||
// ReadFile via ioutil.ReadFile
|
||||
// ReadFile via os.ReadFile
|
||||
func (DefaultFs) ReadFile(filename string) ([]byte, error) {
|
||||
return ioutil.ReadFile(filename)
|
||||
return os.ReadFile(filename)
|
||||
}
|
||||
|
||||
// WriteFile via ioutil.WriteFile
|
||||
// WriteFile via os.WriteFile
|
||||
func (DefaultFs) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||
return ioutil.WriteFile(filename, data, perm)
|
||||
return os.WriteFile(filename, data, perm)
|
||||
}
|
||||
|
||||
// MkdirTemp via os.MkdirTemp
|
||||
func (DefaultFs) MkdirTemp(dir, prefix string) (string, error) {
|
||||
return os.MkdirTemp(dir, prefix)
|
||||
}
|
||||
|
||||
// TempDir via ioutil.TempDir
|
||||
func (DefaultFs) TempDir(dir, prefix string) (string, error) {
|
||||
return ioutil.TempDir(dir, prefix)
|
||||
// Deprecated: as ioutil.TempDir is deprecated TempDir is replaced by MkdirTemp which uses os.MkdirTemp.
|
||||
// TempDir now uses MkdirTemp.
|
||||
func (fs DefaultFs) TempDir(dir, prefix string) (string, error) {
|
||||
return fs.MkdirTemp(dir, prefix)
|
||||
}
|
||||
|
||||
// TempFile via ioutil.TempFile
|
||||
func (DefaultFs) TempFile(dir, prefix string) (File, error) {
|
||||
file, err := ioutil.TempFile(dir, prefix)
|
||||
// CreateTemp via os.CreateTemp
|
||||
func (DefaultFs) CreateTemp(dir, prefix string) (File, error) {
|
||||
file, err := os.CreateTemp(dir, prefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &defaultFile{file}, nil
|
||||
}
|
||||
|
||||
// ReadDir via ioutil.ReadDir
|
||||
// TempFile via ioutil.TempFile
|
||||
// Deprecated: as ioutil.TempFile is deprecated TempFile is replaced by CreateTemp which uses os.CreateTemp.
|
||||
// TempFile now uses CreateTemp.
|
||||
func (fs DefaultFs) TempFile(dir, prefix string) (File, error) {
|
||||
return fs.CreateTemp(dir, prefix)
|
||||
}
|
||||
|
||||
// ReadDir via os.ReadDir
|
||||
func (DefaultFs) ReadDir(dirname string) ([]os.FileInfo, error) {
|
||||
return ioutil.ReadDir(dirname)
|
||||
dirEntries, err := os.ReadDir(dirname)
|
||||
|
||||
if err != nil {
|
||||
return []os.FileInfo{}, err
|
||||
}
|
||||
|
||||
dirsInfo := make([]os.FileInfo, 0, len(dirEntries))
|
||||
for _, dirEntry := range dirEntries {
|
||||
info, err := dirEntry.Info()
|
||||
|
||||
if err != nil {
|
||||
return dirsInfo, err
|
||||
}
|
||||
|
||||
dirsInfo = append(dirsInfo, info)
|
||||
}
|
||||
|
||||
return dirsInfo, nil
|
||||
}
|
||||
|
||||
// Walk via filepath.Walk
|
||||
|
||||
4
vendor/github.com/devfile/library/v2/pkg/testingutil/filesystem/filesystem.go
generated
vendored
4
vendor/github.com/devfile/library/v2/pkg/testingutil/filesystem/filesystem.go
generated
vendored
@@ -41,13 +41,13 @@ type Filesystem interface {
|
||||
Remove(name string) error
|
||||
Chmod(name string, mode os.FileMode) error
|
||||
Getwd() (dir string, err error)
|
||||
|
||||
// from "io/ioutil"
|
||||
ReadFile(filename string) ([]byte, error)
|
||||
WriteFile(filename string, data []byte, perm os.FileMode) error
|
||||
TempDir(dir, prefix string) (string, error)
|
||||
TempFile(dir, prefix string) (File, error)
|
||||
ReadDir(dirname string) ([]os.FileInfo, error)
|
||||
|
||||
// from "filepath"
|
||||
Walk(root string, walkFn filepath.WalkFunc) error
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/testingutil/filesystem/singleton.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/testingutil/filesystem/singleton.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/testingutil/k8sClient.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/testingutil/k8sClient.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/testingutil/resources.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/testingutil/resources.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/github.com/devfile/library/v2/pkg/util/git.go
generated
vendored
2
vendor/github.com/devfile/library/v2/pkg/util/git.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
15
vendor/github.com/devfile/library/v2/pkg/util/httpcache.go
generated
vendored
15
vendor/github.com/devfile/library/v2/pkg/util/httpcache.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@@ -26,11 +25,21 @@ import (
|
||||
|
||||
// cleanHttpCache checks cacheDir and deletes all files that were modified more than cacheTime back
|
||||
func cleanHttpCache(cacheDir string, cacheTime time.Duration) error {
|
||||
cacheFiles, err := ioutil.ReadDir(cacheDir)
|
||||
cacheEntries, err := os.ReadDir(cacheDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cacheFiles := make([]os.FileInfo, 0, len(cacheEntries))
|
||||
for _, cacheEntry := range cacheEntries {
|
||||
info, err := cacheEntry.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cacheFiles = append(cacheFiles, info)
|
||||
}
|
||||
|
||||
for _, f := range cacheFiles {
|
||||
if f.ModTime().Add(cacheTime).Before(time.Now()) {
|
||||
klog.V(4).Infof("Removing cache file %s, because it is older than %s", f.Name(), cacheTime.String())
|
||||
|
||||
246
vendor/github.com/devfile/library/v2/pkg/util/mock.go
generated
vendored
246
vendor/github.com/devfile/library/v2/pkg/util/mock.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -33,6 +33,18 @@ type MockGitUrl struct {
|
||||
IsFile bool // defines if the URL points to a file in the repo
|
||||
}
|
||||
|
||||
type MockDownloadOptions struct {
|
||||
MockDevfile bool
|
||||
MockDockerfile bool
|
||||
MockFile string
|
||||
MockParent *MockParent
|
||||
}
|
||||
|
||||
type MockParent struct {
|
||||
IsMainDevfileDownloaded bool
|
||||
IsParentDevfileDownloaded bool
|
||||
}
|
||||
|
||||
func (m *MockGitUrl) GetToken() string {
|
||||
return m.Token
|
||||
}
|
||||
@@ -51,6 +63,8 @@ var mockExecute = func(baseDir string, cmd CommandType, args ...string) ([]byte,
|
||||
// private repository
|
||||
if hasPassword {
|
||||
switch password {
|
||||
case "parent-devfile":
|
||||
fallthrough
|
||||
case "valid-token":
|
||||
_, err := resourceFile.WriteString("private repo\n")
|
||||
if err != nil {
|
||||
@@ -130,6 +144,236 @@ func (m *MockGitUrl) CloneGitRepo(destDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var mockDevfile = `
|
||||
schemaVersion: 2.2.0
|
||||
metadata:
|
||||
displayName: Go Mock Runtime
|
||||
icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg
|
||||
language: go
|
||||
name: go
|
||||
projectType: go
|
||||
tags:
|
||||
- Go
|
||||
version: 1.0.0
|
||||
components:
|
||||
- container:
|
||||
image: golang:latest
|
||||
memoryLimit: 1024Mi
|
||||
mountSources: true
|
||||
sourceMapping: /project
|
||||
name: runtime
|
||||
- name: image-build
|
||||
image:
|
||||
imageName: go-image:latest
|
||||
dockerfile:
|
||||
uri: docker/Dockerfile
|
||||
buildContext: .
|
||||
rootRequired: false
|
||||
- name: kubernetes-deploy
|
||||
kubernetes:
|
||||
inlined: |-
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
test: test
|
||||
name: deploy-sample
|
||||
endpoints:
|
||||
- name: http-8081
|
||||
targetPort: 8081
|
||||
path: /
|
||||
commands:
|
||||
- exec:
|
||||
commandLine: GOCACHE=/project/.cache go build main.go
|
||||
component: runtime
|
||||
group:
|
||||
kind: build
|
||||
workingDir: /project
|
||||
id: build
|
||||
- exec:
|
||||
commandLine: ./main
|
||||
component: runtime
|
||||
group:
|
||||
kind: run
|
||||
workingDir: /project
|
||||
id: run
|
||||
- id: build-image
|
||||
apply:
|
||||
component: image-build
|
||||
- id: deployk8s
|
||||
apply:
|
||||
component: kubernetes-deploy
|
||||
- id: deploy
|
||||
composite:
|
||||
commands:
|
||||
- build-image
|
||||
- deployk8s
|
||||
group:
|
||||
kind: deploy
|
||||
isDefault: true
|
||||
`
|
||||
|
||||
var MockDevfileWithParentRef = `
|
||||
schemaVersion: 2.2.0
|
||||
metadata:
|
||||
displayName: Go Mock Runtime
|
||||
icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg
|
||||
language: go
|
||||
name: go
|
||||
projectType: go
|
||||
tags:
|
||||
- Go
|
||||
version: 1.0.0
|
||||
parent:
|
||||
uri: https://github.com/private-url-devfile
|
||||
components:
|
||||
- container:
|
||||
image: golang:latest
|
||||
memoryLimit: 1024Mi
|
||||
mountSources: true
|
||||
sourceMapping: /project
|
||||
name: runtime
|
||||
- name: image-build
|
||||
image:
|
||||
imageName: go-image:latest
|
||||
dockerfile:
|
||||
uri: docker/Dockerfile
|
||||
buildContext: .
|
||||
rootRequired: false
|
||||
- name: kubernetes-deploy
|
||||
kubernetes:
|
||||
inlined: |-
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
test: test
|
||||
name: deploy-sample
|
||||
endpoints:
|
||||
- name: http-8081
|
||||
targetPort: 8081
|
||||
path: /
|
||||
commands:
|
||||
- exec:
|
||||
commandLine: GOCACHE=/project/.cache go build main.go
|
||||
component: runtime
|
||||
group:
|
||||
kind: build
|
||||
workingDir: /project
|
||||
id: build
|
||||
- exec:
|
||||
commandLine: ./main
|
||||
component: runtime
|
||||
group:
|
||||
kind: run
|
||||
workingDir: /project
|
||||
id: run
|
||||
- id: build-image
|
||||
apply:
|
||||
component: image-build
|
||||
- id: deployk8s
|
||||
apply:
|
||||
component: kubernetes-deploy
|
||||
- id: deploy
|
||||
composite:
|
||||
commands:
|
||||
- build-image
|
||||
- deployk8s
|
||||
group:
|
||||
kind: deploy
|
||||
isDefault: true
|
||||
`
|
||||
|
||||
var MockParentDevfile = `
|
||||
schemaVersion: 2.2.0
|
||||
metadata:
|
||||
displayName: Go Mock Parent
|
||||
language: go
|
||||
name: goparent
|
||||
projectType: go
|
||||
tags:
|
||||
- Go
|
||||
version: 1.0.0
|
||||
components:
|
||||
- container:
|
||||
endpoints:
|
||||
- name: http
|
||||
targetPort: 8080
|
||||
image: golang:latest
|
||||
memoryLimit: 1024Mi
|
||||
mountSources: true
|
||||
sourceMapping: /project
|
||||
name: runtime2
|
||||
commands:
|
||||
- exec:
|
||||
commandLine: GOCACHE=/project/.cache go build main.go
|
||||
component: runtime2
|
||||
group:
|
||||
isDefault: true
|
||||
kind: build
|
||||
workingDir: /project
|
||||
id: build2
|
||||
- exec:
|
||||
commandLine: ./main
|
||||
component: runtime2
|
||||
group:
|
||||
isDefault: true
|
||||
kind: run
|
||||
workingDir: /project
|
||||
id: run2
|
||||
`
|
||||
|
||||
var mockDockerfile = `
|
||||
FROM python:slim
|
||||
|
||||
WORKDIR /projects
|
||||
|
||||
RUN python3 -m venv venv
|
||||
RUN . venv/bin/activate
|
||||
|
||||
# optimize image caching
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 8081
|
||||
CMD [ "waitress-serve", "--port=8081", "app:app"]
|
||||
`
|
||||
|
||||
func (m MockGitUrl) DownloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient, options MockDownloadOptions) ([]byte, error) {
|
||||
|
||||
if m.GetToken() == "valid-token" {
|
||||
switch {
|
||||
case options.MockDevfile:
|
||||
return []byte(mockDevfile), nil
|
||||
case options.MockDockerfile:
|
||||
return []byte(mockDockerfile), nil
|
||||
case len(options.MockFile) > 0:
|
||||
return []byte(options.MockFile), nil
|
||||
default:
|
||||
return []byte(mockDevfile), nil
|
||||
}
|
||||
} else if m.GetToken() == "parent-devfile" {
|
||||
if options.MockParent != nil && !options.MockParent.IsMainDevfileDownloaded {
|
||||
options.MockParent.IsMainDevfileDownloaded = true
|
||||
return []byte(MockDevfileWithParentRef), nil
|
||||
}
|
||||
|
||||
if options.MockParent != nil && !options.MockParent.IsParentDevfileDownloaded {
|
||||
options.MockParent.IsParentDevfileDownloaded = true
|
||||
return []byte(MockParentDevfile), nil
|
||||
}
|
||||
} else if m.GetToken() == "" {
|
||||
// if no token is provided, assume normal operation
|
||||
return DownloadInMemory(params)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("failed to retrieve %s", params.URL)
|
||||
}
|
||||
|
||||
func (m *MockGitUrl) SetToken(token string) error {
|
||||
m.Token = token
|
||||
return nil
|
||||
|
||||
36
vendor/github.com/devfile/library/v2/pkg/util/util.go
generated
vendored
36
vendor/github.com/devfile/library/v2/pkg/util/util.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022-2023 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -21,12 +21,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
gitpkg "github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/gregjones/httpcache"
|
||||
"github.com/gregjones/httpcache/diskcache"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -45,6 +40,11 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
gitpkg "github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/gregjones/httpcache"
|
||||
"github.com/gregjones/httpcache/diskcache"
|
||||
|
||||
"github.com/devfile/library/v2/pkg/testingutil/filesystem"
|
||||
"github.com/fatih/color"
|
||||
"github.com/gobwas/glob"
|
||||
@@ -819,7 +819,7 @@ func HTTPGetRequest(request HTTPRequestParams, cacheFor int) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Process http response
|
||||
bytes, err := ioutil.ReadAll(resp.Body)
|
||||
bytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -855,7 +855,11 @@ func FilterIgnores(filesChanged, filesDeleted, absIgnoreRules []string) (filesCh
|
||||
// IsValidProjectDir checks that the folder to download the project from devfile is
|
||||
// either empty or only contains the devfile used.
|
||||
func IsValidProjectDir(path string, devfilePath string) error {
|
||||
files, err := ioutil.ReadDir(path)
|
||||
return isValidProjectDirOnFS(path, devfilePath, filesystem.DefaultFs{})
|
||||
}
|
||||
|
||||
func isValidProjectDirOnFS(path string, devfilePath string, fs filesystem.Filesystem) error {
|
||||
files, err := fs.ReadDir(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1090,29 +1094,31 @@ func DownloadFileInMemory(url string) ([]byte, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ioutil.ReadAll(resp.Body)
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
// DownloadInMemory uses HTTPRequestParams to download the file and return bytes
|
||||
// DownloadInMemory uses HTTPRequestParams to download the file and return bytes.
|
||||
// Use the pkg/devfile/parser/utils.go DownloadInMemory() invocation if you want to
|
||||
// call with a client instead.
|
||||
func DownloadInMemory(params HTTPRequestParams) ([]byte, error) {
|
||||
var httpClient = &http.Client{Transport: &http.Transport{
|
||||
ResponseHeaderTimeout: HTTPRequestResponseTimeout,
|
||||
}, Timeout: HTTPRequestResponseTimeout}
|
||||
|
||||
var g GitUrl
|
||||
var g *GitUrl
|
||||
var err error
|
||||
|
||||
if IsGitProviderRepo(params.URL) {
|
||||
g, err = NewGitUrlWithURL(params.URL)
|
||||
g, err = NewGitURL(params.URL, params.Token)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to parse git repo. error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return downloadInMemoryWithClient(params, httpClient, g)
|
||||
return g.downloadInMemoryWithClient(params, httpClient)
|
||||
}
|
||||
|
||||
func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient, g GitUrl) ([]byte, error) {
|
||||
func (g *GitUrl) downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient) ([]byte, error) {
|
||||
var url string
|
||||
url = params.URL
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
@@ -1144,7 +1150,7 @@ func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient,
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ioutil.ReadAll(resp.Body)
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
// ValidateK8sResourceName sanitizes kubernetes resource name with the following requirements:
|
||||
|
||||
2
vendor/github.com/devfile/registry-support/index/generator/schema/schema.go
generated
vendored
2
vendor/github.com/devfile/registry-support/index/generator/schema/schema.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2022 Red Hat, Inc.
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
35
vendor/github.com/devfile/registry-support/registry-library/library/library.go
generated
vendored
35
vendor/github.com/devfile/registry-support/registry-library/library/library.go
generated
vendored
@@ -1,17 +1,17 @@
|
||||
/* Copyright 2020-2022 Red Hat, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
//
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// 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 library
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -66,7 +65,7 @@ type Registry struct {
|
||||
err error
|
||||
}
|
||||
|
||||
//TelemetryData structure to pass in client telemetry information
|
||||
// TelemetryData structure to pass in client telemetry information
|
||||
// The User and Locale fields should be passed in by clients if telemetry opt-in is enabled
|
||||
// the generic Client name will be passed in regardless of opt-in/out choice. The value
|
||||
// will be assigned to the UserId field for opt-outs
|
||||
@@ -179,7 +178,7 @@ func GetRegistryIndex(registryURL string, options RegistryOptions, devfileTypes
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bytes, err := ioutil.ReadAll(resp.Body)
|
||||
bytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -454,7 +453,7 @@ func DownloadStarterProjectAsBytes(registryURL string, stack string, starterProj
|
||||
}
|
||||
|
||||
// Return downloaded starter project as bytes or error if unsuccessful.
|
||||
return ioutil.ReadAll(resp.Body)
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
// IsStarterProjectExists checks if starter project exists for a given stack
|
||||
|
||||
45
vendor/github.com/devfile/registry-support/registry-library/library/util.go
generated
vendored
45
vendor/github.com/devfile/registry-support/registry-library/library/util.go
generated
vendored
@@ -1,17 +1,17 @@
|
||||
/* Copyright 2020-2022 Red Hat, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
//
|
||||
// Copyright Red Hat
|
||||
//
|
||||
// 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 library
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"compress/gzip"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -30,6 +29,8 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
// SplitVersionFromStack takes a stack/version tag and splits the stack name from the version
|
||||
@@ -112,7 +113,7 @@ func decompress(targetDir string, tarFile string, excludeFiles []string) error {
|
||||
continue
|
||||
}
|
||||
|
||||
target := path.Join(targetDir, filepath.Clean(header.Name))
|
||||
target := CleanFilepath(targetDir, header.Name)
|
||||
switch header.Typeflag {
|
||||
case tar.TypeDir:
|
||||
err = os.MkdirAll(target, os.FileMode(header.Mode))
|
||||
@@ -121,7 +122,6 @@ func decompress(targetDir string, tarFile string, excludeFiles []string) error {
|
||||
return returnedErr
|
||||
}
|
||||
case tar.TypeReg:
|
||||
/* #nosec G304 -- target is produced using path.Join which cleans the dir path */
|
||||
w, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
|
||||
if err != nil {
|
||||
returnedErr = multierror.Append(returnedErr, err)
|
||||
@@ -156,7 +156,7 @@ func isExcluded(name string, excludeFiles []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//setHeaders sets the request headers
|
||||
// setHeaders sets the request headers
|
||||
func setHeaders(headers *http.Header, options RegistryOptions) {
|
||||
t := options.Telemetry
|
||||
if t.User != "" {
|
||||
@@ -170,7 +170,7 @@ func setHeaders(headers *http.Header, options RegistryOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
//getHTTPClient returns a new http client object
|
||||
// getHTTPClient returns a new http client object
|
||||
func getHTTPClient(options RegistryOptions) *http.Client {
|
||||
|
||||
overriddenTimeout := httpRequestResponseTimeout
|
||||
@@ -191,3 +191,10 @@ func getHTTPClient(options RegistryOptions) *http.Client {
|
||||
Timeout: overriddenTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
// Cleans a child path to ensure that there is no escaping from the parent directory with the use of ../ escape methods
|
||||
// Ensures that the child path is always contained and absolutely pathed from the parent
|
||||
func CleanFilepath(parent string, child string)string{
|
||||
target := path.Join(parent, filepath.Clean("/"+child))
|
||||
return target
|
||||
}
|
||||
|
||||
2
vendor/github.com/distribution/distribution/v3/reference/helpers.go
generated
vendored
2
vendor/github.com/distribution/distribution/v3/reference/helpers.go
generated
vendored
@@ -32,7 +32,7 @@ func FamiliarString(ref Reference) string {
|
||||
}
|
||||
|
||||
// FamiliarMatch reports whether ref matches the specified pattern.
|
||||
// See https://godoc.org/path#Match for supported patterns.
|
||||
// See [path.Match] for supported patterns.
|
||||
func FamiliarMatch(pattern string, ref Reference) (bool, error) {
|
||||
matched, err := path.Match(pattern, FamiliarString(ref))
|
||||
if namedRef, isNamed := ref.(Named); isNamed && !matched {
|
||||
|
||||
128
vendor/github.com/distribution/distribution/v3/reference/normalize.go
generated
vendored
128
vendor/github.com/distribution/distribution/v3/reference/normalize.go
generated
vendored
@@ -4,15 +4,39 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/distribution/distribution/v3/digestset"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
var (
|
||||
const (
|
||||
// legacyDefaultDomain is the legacy domain for Docker Hub (which was
|
||||
// originally named "the Docker Index"). This domain is still used for
|
||||
// authentication and image search, which were part of the "v1" Docker
|
||||
// registry specification.
|
||||
//
|
||||
// This domain will continue to be supported, but there are plans to consolidate
|
||||
// legacy domains to new "canonical" domains. Once those domains are decided
|
||||
// on, we must update the normalization functions, but preserve compatibility
|
||||
// with existing installs, clients, and user configuration.
|
||||
legacyDefaultDomain = "index.docker.io"
|
||||
defaultDomain = "docker.io"
|
||||
officialRepoName = "library"
|
||||
defaultTag = "latest"
|
||||
|
||||
// defaultDomain is the default domain used for images on Docker Hub.
|
||||
// It is used to normalize "familiar" names to canonical names, for example,
|
||||
// to convert "ubuntu" to "docker.io/library/ubuntu:latest".
|
||||
//
|
||||
// Note that actual domain of Docker Hub's registry is registry-1.docker.io.
|
||||
// This domain will continue to be supported, but there are plans to consolidate
|
||||
// legacy domains to new "canonical" domains. Once those domains are decided
|
||||
// on, we must update the normalization functions, but preserve compatibility
|
||||
// with existing installs, clients, and user configuration.
|
||||
defaultDomain = "docker.io"
|
||||
|
||||
// officialRepoPrefix is the namespace used for official images on Docker Hub.
|
||||
// It is used to normalize "familiar" names to canonical names, for example,
|
||||
// to convert "ubuntu" to "docker.io/library/ubuntu:latest".
|
||||
officialRepoPrefix = "library/"
|
||||
|
||||
// defaultTag is the default tag if no tag is provided.
|
||||
defaultTag = "latest"
|
||||
)
|
||||
|
||||
// normalizedNamed represents a name which has been
|
||||
@@ -34,14 +58,14 @@ func ParseNormalizedNamed(s string) (Named, error) {
|
||||
return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s)
|
||||
}
|
||||
domain, remainder := splitDockerDomain(s)
|
||||
var remoteName string
|
||||
var remote string
|
||||
if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {
|
||||
remoteName = remainder[:tagSep]
|
||||
remote = remainder[:tagSep]
|
||||
} else {
|
||||
remoteName = remainder
|
||||
remote = remainder
|
||||
}
|
||||
if strings.ToLower(remoteName) != remoteName {
|
||||
return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remoteName)
|
||||
if strings.ToLower(remote) != remote {
|
||||
return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remote)
|
||||
}
|
||||
|
||||
ref, err := Parse(domain + "/" + remainder)
|
||||
@@ -55,41 +79,53 @@ func ParseNormalizedNamed(s string) (Named, error) {
|
||||
return named, nil
|
||||
}
|
||||
|
||||
// ParseDockerRef normalizes the image reference following the docker convention. This is added
|
||||
// mainly for backward compatibility.
|
||||
// The reference returned can only be either tagged or digested. For reference contains both tag
|
||||
// and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@
|
||||
// sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as
|
||||
// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa.
|
||||
// namedTaggedDigested is a reference that has both a tag and a digest.
|
||||
type namedTaggedDigested interface {
|
||||
NamedTagged
|
||||
Digested
|
||||
}
|
||||
|
||||
// ParseDockerRef normalizes the image reference following the docker convention,
|
||||
// which allows for references to contain both a tag and a digest. It returns a
|
||||
// reference that is either tagged or digested. For references containing both
|
||||
// a tag and a digest, it returns a digested reference. For example, the following
|
||||
// reference:
|
||||
//
|
||||
// docker.io/library/busybox:latest@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
|
||||
//
|
||||
// Is returned as a digested reference (with the ":latest" tag removed):
|
||||
//
|
||||
// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
|
||||
//
|
||||
// References that are already "tagged" or "digested" are returned unmodified:
|
||||
//
|
||||
// // Already a digested reference
|
||||
// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
|
||||
//
|
||||
// // Already a named reference
|
||||
// docker.io/library/busybox:latest
|
||||
func ParseDockerRef(ref string) (Named, error) {
|
||||
named, err := ParseNormalizedNamed(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := named.(NamedTagged); ok {
|
||||
if canonical, ok := named.(Canonical); ok {
|
||||
// The reference is both tagged and digested, only
|
||||
// return digested.
|
||||
newNamed, err := WithName(canonical.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newCanonical, err := WithDigest(newNamed, canonical.Digest())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newCanonical, nil
|
||||
if canonical, ok := named.(namedTaggedDigested); ok {
|
||||
// The reference is both tagged and digested; only return digested.
|
||||
newNamed, err := WithName(canonical.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return WithDigest(newNamed, canonical.Digest())
|
||||
}
|
||||
return TagNameOnly(named), nil
|
||||
}
|
||||
|
||||
// splitDockerDomain splits a repository name to domain and remotename string.
|
||||
// splitDockerDomain splits a repository name to domain and remote-name.
|
||||
// If no valid domain is found, the default domain is used. Repository name
|
||||
// needs to be already validated before.
|
||||
func splitDockerDomain(name string) (domain, remainder string) {
|
||||
i := strings.IndexRune(name, '/')
|
||||
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost" && strings.ToLower(name[:i]) == name[:i]) {
|
||||
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != localhost && strings.ToLower(name[:i]) == name[:i]) {
|
||||
domain, remainder = defaultDomain, name
|
||||
} else {
|
||||
domain, remainder = name[:i], name[i+1:]
|
||||
@@ -98,7 +134,7 @@ func splitDockerDomain(name string) (domain, remainder string) {
|
||||
domain = defaultDomain
|
||||
}
|
||||
if domain == defaultDomain && !strings.ContainsRune(remainder, '/') {
|
||||
remainder = officialRepoName + "/" + remainder
|
||||
remainder = officialRepoPrefix + remainder
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -118,8 +154,15 @@ func familiarizeName(named namedRepository) repository {
|
||||
if repo.domain == defaultDomain {
|
||||
repo.domain = ""
|
||||
// Handle official repositories which have the pattern "library/<official repo name>"
|
||||
if split := strings.Split(repo.path, "/"); len(split) == 2 && split[0] == officialRepoName {
|
||||
repo.path = split[1]
|
||||
if strings.HasPrefix(repo.path, officialRepoPrefix) {
|
||||
// TODO(thaJeztah): this check may be too strict, as it assumes the
|
||||
// "library/" namespace does not have nested namespaces. While this
|
||||
// is true (currently), technically it would be possible for Docker
|
||||
// Hub to use those (e.g. "library/distros/ubuntu:latest").
|
||||
// See https://github.com/distribution/distribution/pull/3769#issuecomment-1302031785.
|
||||
if remainder := strings.TrimPrefix(repo.path, officialRepoPrefix); !strings.ContainsRune(remainder, '/') {
|
||||
repo.path = remainder
|
||||
}
|
||||
}
|
||||
}
|
||||
return repo
|
||||
@@ -179,20 +222,3 @@ func ParseAnyReference(ref string) (Reference, error) {
|
||||
|
||||
return ParseNormalizedNamed(ref)
|
||||
}
|
||||
|
||||
// ParseAnyReferenceWithSet parses a reference string as a possible short
|
||||
// identifier to be matched in a digest set, a full digest, or familiar name.
|
||||
func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) {
|
||||
if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok {
|
||||
dgst, err := ds.Lookup(ref)
|
||||
if err == nil {
|
||||
return digestReference(dgst), nil
|
||||
}
|
||||
} else {
|
||||
if dgst, err := digest.Parse(ref); err == nil {
|
||||
return digestReference(dgst), nil
|
||||
}
|
||||
}
|
||||
|
||||
return ParseNormalizedNamed(ref)
|
||||
}
|
||||
|
||||
31
vendor/github.com/distribution/distribution/v3/reference/reference.go
generated
vendored
31
vendor/github.com/distribution/distribution/v3/reference/reference.go
generated
vendored
@@ -3,13 +3,16 @@
|
||||
//
|
||||
// Grammar
|
||||
//
|
||||
// reference := name [ ":" tag ] [ "@" digest ]
|
||||
// name := [domain '/'] path-component ['/' path-component]*
|
||||
// domain := domain-component ['.' domain-component]* [':' port-number]
|
||||
// reference := name [ ":" tag ] [ "@" digest ]
|
||||
// name := [domain '/'] remote-name
|
||||
// domain := host [':' port-number]
|
||||
// host := domain-name | IPv4address | \[ IPv6address \] ; rfc3986 appendix-A
|
||||
// domain-name := domain-component ['.' domain-component]*
|
||||
// domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
|
||||
// port-number := /[0-9]+/
|
||||
// path-component := alpha-numeric [separator alpha-numeric]*
|
||||
// alpha-numeric := /[a-z0-9]+/
|
||||
// path (or "remote-name") := path-component ['/' path-component]*
|
||||
// alpha-numeric := /[a-z0-9]+/
|
||||
// separator := /[_.]|__|[-]*/
|
||||
//
|
||||
// tag := /[\w][\w.-]{0,127}/
|
||||
@@ -21,7 +24,6 @@
|
||||
// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
|
||||
//
|
||||
// identifier := /[a-f0-9]{64}/
|
||||
// short-identifier := /[a-f0-9]{6,64}/
|
||||
package reference
|
||||
|
||||
import (
|
||||
@@ -145,7 +147,7 @@ type namedRepository interface {
|
||||
Path() string
|
||||
}
|
||||
|
||||
// Domain returns the domain part of the Named reference
|
||||
// Domain returns the domain part of the [Named] reference.
|
||||
func Domain(named Named) string {
|
||||
if r, ok := named.(namedRepository); ok {
|
||||
return r.Domain()
|
||||
@@ -154,7 +156,7 @@ func Domain(named Named) string {
|
||||
return domain
|
||||
}
|
||||
|
||||
// Path returns the name without the domain part of the Named reference
|
||||
// Path returns the name without the domain part of the [Named] reference.
|
||||
func Path(named Named) (name string) {
|
||||
if r, ok := named.(namedRepository); ok {
|
||||
return r.Path()
|
||||
@@ -175,7 +177,8 @@ func splitDomain(name string) (string, string) {
|
||||
// hostname and name string. If no valid hostname is
|
||||
// found, the hostname is empty and the full value
|
||||
// is returned as name
|
||||
// DEPRECATED: Use Domain or Path
|
||||
//
|
||||
// Deprecated: Use [Domain] or [Path].
|
||||
func SplitHostname(named Named) (string, string) {
|
||||
if r, ok := named.(namedRepository); ok {
|
||||
return r.Domain(), r.Path()
|
||||
@@ -185,7 +188,6 @@ func SplitHostname(named Named) (string, string) {
|
||||
|
||||
// Parse parses s and returns a syntactically valid Reference.
|
||||
// If an error was encountered it is returned, along with a nil Reference.
|
||||
// NOTE: Parse will not handle short digests.
|
||||
func Parse(s string) (Reference, error) {
|
||||
matches := ReferenceRegexp.FindStringSubmatch(s)
|
||||
if matches == nil {
|
||||
@@ -237,7 +239,6 @@ func Parse(s string) (Reference, error) {
|
||||
// the Named interface. The reference must have a name and be in the canonical
|
||||
// form, otherwise an error is returned.
|
||||
// If an error was encountered it is returned, along with a nil Reference.
|
||||
// NOTE: ParseNamed will not handle short digests.
|
||||
func ParseNamed(s string) (Named, error) {
|
||||
named, err := ParseNormalizedNamed(s)
|
||||
if err != nil {
|
||||
@@ -320,11 +321,13 @@ func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
|
||||
|
||||
// TrimNamed removes any tag or digest from the named reference.
|
||||
func TrimNamed(ref Named) Named {
|
||||
domain, path := SplitHostname(ref)
|
||||
return repository{
|
||||
domain: domain,
|
||||
path: path,
|
||||
repo := repository{}
|
||||
if r, ok := ref.(namedRepository); ok {
|
||||
repo.domain, repo.path = r.Domain(), r.Path()
|
||||
} else {
|
||||
repo.domain, repo.path = splitDomain(ref.Name())
|
||||
}
|
||||
return repo
|
||||
}
|
||||
|
||||
func getBestReferenceType(ref reference) Reference {
|
||||
|
||||
224
vendor/github.com/distribution/distribution/v3/reference/regexp.go
generated
vendored
224
vendor/github.com/distribution/distribution/v3/reference/regexp.go
generated
vendored
@@ -1,147 +1,163 @@
|
||||
package reference
|
||||
|
||||
import "regexp"
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// alphaNumericRegexp defines the alpha numeric atom, typically a
|
||||
// DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
|
||||
var DigestRegexp = regexp.MustCompile(digestPat)
|
||||
|
||||
// DomainRegexp matches hostname or IP-addresses, optionally including a port
|
||||
// number. It defines the structure of potential domain components that may be
|
||||
// part of image names. This is purposely a subset of what is allowed by DNS to
|
||||
// ensure backwards compatibility with Docker image names. It may be a subset of
|
||||
// DNS domain name, an IPv4 address in decimal format, or an IPv6 address between
|
||||
// square brackets (excluding zone identifiers as defined by [RFC 6874] or special
|
||||
// addresses such as IPv4-Mapped).
|
||||
//
|
||||
// [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874.
|
||||
var DomainRegexp = regexp.MustCompile(domainAndPort)
|
||||
|
||||
// IdentifierRegexp is the format for string identifier used as a
|
||||
// content addressable identifier using sha256. These identifiers
|
||||
// are like digests without the algorithm, since sha256 is used.
|
||||
var IdentifierRegexp = regexp.MustCompile(identifier)
|
||||
|
||||
// NameRegexp is the format for the name component of references, including
|
||||
// an optional domain and port, but without tag or digest suffix.
|
||||
var NameRegexp = regexp.MustCompile(namePat)
|
||||
|
||||
// ReferenceRegexp is the full supported format of a reference. The regexp
|
||||
// is anchored and has capturing groups for name, tag, and digest
|
||||
// components.
|
||||
var ReferenceRegexp = regexp.MustCompile(referencePat)
|
||||
|
||||
// TagRegexp matches valid tag names. From [docker/docker:graph/tags.go].
|
||||
//
|
||||
// [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28
|
||||
var TagRegexp = regexp.MustCompile(tag)
|
||||
|
||||
const (
|
||||
// alphanumeric defines the alphanumeric atom, typically a
|
||||
// component of names. This only allows lower case characters and digits.
|
||||
alphaNumericRegexp = match(`[a-z0-9]+`)
|
||||
alphanumeric = `[a-z0-9]+`
|
||||
|
||||
// separatorRegexp defines the separators allowed to be embedded in name
|
||||
// components. This allow one period, one or two underscore and multiple
|
||||
// separator defines the separators allowed to be embedded in name
|
||||
// components. This allows one period, one or two underscore and multiple
|
||||
// dashes. Repeated dashes and underscores are intentionally treated
|
||||
// differently. In order to support valid hostnames as name components,
|
||||
// supporting repeated dash was added. Additionally double underscore is
|
||||
// now allowed as a separator to loosen the restriction for previously
|
||||
// supported names.
|
||||
separatorRegexp = match(`(?:[._]|__|[-]*)`)
|
||||
separator = `(?:[._]|__|[-]*)`
|
||||
|
||||
// nameComponentRegexp restricts registry path component names to start
|
||||
// with at least one letter or number, with following parts able to be
|
||||
// separated by one period, one or two underscore and multiple dashes.
|
||||
nameComponentRegexp = expression(
|
||||
alphaNumericRegexp,
|
||||
optional(repeated(separatorRegexp, alphaNumericRegexp)))
|
||||
// localhost is treated as a special value for domain-name. Any other
|
||||
// domain-name without a "." or a ":port" are considered a path component.
|
||||
localhost = `localhost`
|
||||
|
||||
// domainComponentRegexp restricts the registry domain component of a
|
||||
// repository name to start with a component as defined by DomainRegexp
|
||||
// and followed by an optional port.
|
||||
domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
|
||||
// domainNameComponent restricts the registry domain component of a
|
||||
// repository name to start with a component as defined by DomainRegexp.
|
||||
domainNameComponent = `(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`
|
||||
|
||||
// DomainRegexp defines the structure of potential domain components
|
||||
// optionalPort matches an optional port-number including the port separator
|
||||
// (e.g. ":80").
|
||||
optionalPort = `(?::[0-9]+)?`
|
||||
|
||||
// tag matches valid tag names. From docker/docker:graph/tags.go.
|
||||
tag = `[\w][\w.-]{0,127}`
|
||||
|
||||
// digestPat matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
|
||||
//
|
||||
// TODO(thaJeztah): this should follow the same rules as https://pkg.go.dev/github.com/opencontainers/go-digest@v1.0.0#DigestRegexp
|
||||
// so that go-digest defines the canonical format. Note that the go-digest is
|
||||
// more relaxed:
|
||||
// - it allows multiple algorithms (e.g. "sha256+b64:<encoded>") to allow
|
||||
// future expansion of supported algorithms.
|
||||
// - it allows the "<encoded>" value to use urlsafe base64 encoding as defined
|
||||
// in [rfc4648, section 5].
|
||||
//
|
||||
// [rfc4648, section 5]: https://www.rfc-editor.org/rfc/rfc4648#section-5.
|
||||
digestPat = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`
|
||||
|
||||
// identifier is the format for a content addressable identifier using sha256.
|
||||
// These identifiers are like digests without the algorithm, since sha256 is used.
|
||||
identifier = `([a-f0-9]{64})`
|
||||
|
||||
// ipv6address are enclosed between square brackets and may be represented
|
||||
// in many ways, see rfc5952. Only IPv6 in compressed or uncompressed format
|
||||
// are allowed, IPv6 zone identifiers (rfc6874) or Special addresses such as
|
||||
// IPv4-Mapped are deliberately excluded.
|
||||
ipv6address = `\[(?:[a-fA-F0-9:]+)\]`
|
||||
)
|
||||
|
||||
var (
|
||||
// domainName defines the structure of potential domain components
|
||||
// that may be part of image names. This is purposely a subset of what is
|
||||
// allowed by DNS to ensure backwards compatibility with Docker image
|
||||
// names.
|
||||
DomainRegexp = expression(
|
||||
domainComponentRegexp,
|
||||
optional(repeated(literal(`.`), domainComponentRegexp)),
|
||||
optional(literal(`:`), match(`[0-9]+`)))
|
||||
// names. This includes IPv4 addresses on decimal format.
|
||||
domainName = domainNameComponent + anyTimes(`\.`+domainNameComponent)
|
||||
|
||||
// TagRegexp matches valid tag names. From docker/docker:graph/tags.go.
|
||||
TagRegexp = match(`[\w][\w.-]{0,127}`)
|
||||
// host defines the structure of potential domains based on the URI
|
||||
// Host subcomponent on rfc3986. It may be a subset of DNS domain name,
|
||||
// or an IPv4 address in decimal format, or an IPv6 address between square
|
||||
// brackets (excluding zone identifiers as defined by rfc6874 or special
|
||||
// addresses such as IPv4-Mapped).
|
||||
host = `(?:` + domainName + `|` + ipv6address + `)`
|
||||
|
||||
// allowed by the URI Host subcomponent on rfc3986 to ensure backwards
|
||||
// compatibility with Docker image names.
|
||||
domainAndPort = host + optionalPort
|
||||
|
||||
// anchoredTagRegexp matches valid tag names, anchored at the start and
|
||||
// end of the matched string.
|
||||
anchoredTagRegexp = anchored(TagRegexp)
|
||||
|
||||
// DigestRegexp matches valid digests.
|
||||
DigestRegexp = match(`[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`)
|
||||
anchoredTagRegexp = regexp.MustCompile(anchored(tag))
|
||||
|
||||
// anchoredDigestRegexp matches valid digests, anchored at the start and
|
||||
// end of the matched string.
|
||||
anchoredDigestRegexp = anchored(DigestRegexp)
|
||||
anchoredDigestRegexp = regexp.MustCompile(anchored(digestPat))
|
||||
|
||||
// NameRegexp is the format for the name component of references. The
|
||||
// regexp has capturing groups for the domain and name part omitting
|
||||
// the separating forward slash from either.
|
||||
NameRegexp = expression(
|
||||
optional(DomainRegexp, literal(`/`)),
|
||||
nameComponentRegexp,
|
||||
optional(repeated(literal(`/`), nameComponentRegexp)))
|
||||
// pathComponent restricts path-components to start with an alphanumeric
|
||||
// character, with following parts able to be separated by a separator
|
||||
// (one period, one or two underscore and multiple dashes).
|
||||
pathComponent = alphanumeric + anyTimes(separator+alphanumeric)
|
||||
|
||||
// remoteName matches the remote-name of a repository. It consists of one
|
||||
// or more forward slash (/) delimited path-components:
|
||||
//
|
||||
// pathComponent[[/pathComponent] ...] // e.g., "library/ubuntu"
|
||||
remoteName = pathComponent + anyTimes(`/`+pathComponent)
|
||||
namePat = optional(domainAndPort+`/`) + remoteName
|
||||
|
||||
// anchoredNameRegexp is used to parse a name value, capturing the
|
||||
// domain and trailing components.
|
||||
anchoredNameRegexp = anchored(
|
||||
optional(capture(DomainRegexp), literal(`/`)),
|
||||
capture(nameComponentRegexp,
|
||||
optional(repeated(literal(`/`), nameComponentRegexp))))
|
||||
anchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(remoteName)))
|
||||
|
||||
// ReferenceRegexp is the full supported format of a reference. The regexp
|
||||
// is anchored and has capturing groups for name, tag, and digest
|
||||
// components.
|
||||
ReferenceRegexp = anchored(capture(NameRegexp),
|
||||
optional(literal(":"), capture(TagRegexp)),
|
||||
optional(literal("@"), capture(DigestRegexp)))
|
||||
|
||||
// IdentifierRegexp is the format for string identifier used as a
|
||||
// content addressable identifier using sha256. These identifiers
|
||||
// are like digests without the algorithm, since sha256 is used.
|
||||
IdentifierRegexp = match(`([a-f0-9]{64})`)
|
||||
|
||||
// ShortIdentifierRegexp is the format used to represent a prefix
|
||||
// of an identifier. A prefix may be used to match a sha256 identifier
|
||||
// within a list of trusted identifiers.
|
||||
ShortIdentifierRegexp = match(`([a-f0-9]{6,64})`)
|
||||
referencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat)))
|
||||
|
||||
// anchoredIdentifierRegexp is used to check or match an
|
||||
// identifier value, anchored at start and end of string.
|
||||
anchoredIdentifierRegexp = anchored(IdentifierRegexp)
|
||||
|
||||
// anchoredShortIdentifierRegexp is used to check if a value
|
||||
// is a possible identifier prefix, anchored at start and end
|
||||
// of string.
|
||||
anchoredShortIdentifierRegexp = anchored(ShortIdentifierRegexp)
|
||||
anchoredIdentifierRegexp = regexp.MustCompile(anchored(identifier))
|
||||
)
|
||||
|
||||
// match compiles the string to a regular expression.
|
||||
var match = regexp.MustCompile
|
||||
|
||||
// literal compiles s into a literal regular expression, escaping any regexp
|
||||
// reserved characters.
|
||||
func literal(s string) *regexp.Regexp {
|
||||
re := match(regexp.QuoteMeta(s))
|
||||
|
||||
if _, complete := re.LiteralPrefix(); !complete {
|
||||
panic("must be a literal")
|
||||
}
|
||||
|
||||
return re
|
||||
}
|
||||
|
||||
// expression defines a full expression, where each regular expression must
|
||||
// follow the previous.
|
||||
func expression(res ...*regexp.Regexp) *regexp.Regexp {
|
||||
var s string
|
||||
for _, re := range res {
|
||||
s += re.String()
|
||||
}
|
||||
|
||||
return match(s)
|
||||
}
|
||||
|
||||
// optional wraps the expression in a non-capturing group and makes the
|
||||
// production optional.
|
||||
func optional(res ...*regexp.Regexp) *regexp.Regexp {
|
||||
return match(group(expression(res...)).String() + `?`)
|
||||
func optional(res ...string) string {
|
||||
return `(?:` + strings.Join(res, "") + `)?`
|
||||
}
|
||||
|
||||
// repeated wraps the regexp in a non-capturing group to get one or more
|
||||
// matches.
|
||||
func repeated(res ...*regexp.Regexp) *regexp.Regexp {
|
||||
return match(group(expression(res...)).String() + `+`)
|
||||
}
|
||||
|
||||
// group wraps the regexp in a non-capturing group.
|
||||
func group(res ...*regexp.Regexp) *regexp.Regexp {
|
||||
return match(`(?:` + expression(res...).String() + `)`)
|
||||
// anyTimes wraps the expression in a non-capturing group that can occur
|
||||
// any number of times.
|
||||
func anyTimes(res ...string) string {
|
||||
return `(?:` + strings.Join(res, "") + `)*`
|
||||
}
|
||||
|
||||
// capture wraps the expression in a capturing group.
|
||||
func capture(res ...*regexp.Regexp) *regexp.Regexp {
|
||||
return match(`(` + expression(res...).String() + `)`)
|
||||
func capture(res ...string) string {
|
||||
return `(` + strings.Join(res, "") + `)`
|
||||
}
|
||||
|
||||
// anchored anchors the regular expression by adding start and end delimiters.
|
||||
func anchored(res ...*regexp.Regexp) *regexp.Regexp {
|
||||
return match(`^` + expression(res...).String() + `$`)
|
||||
func anchored(res ...string) string {
|
||||
return `^` + strings.Join(res, "") + `$`
|
||||
}
|
||||
|
||||
75
vendor/github.com/distribution/distribution/v3/reference/sort.go
generated
vendored
Normal file
75
vendor/github.com/distribution/distribution/v3/reference/sort.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright The containerd 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 reference
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Sort sorts string references preferring higher information references.
|
||||
//
|
||||
// The precedence is as follows:
|
||||
//
|
||||
// 1. [Named] + [Tagged] + [Digested] (e.g., "docker.io/library/busybox:latest@sha256:<digest>")
|
||||
// 2. [Named] + [Tagged] (e.g., "docker.io/library/busybox:latest")
|
||||
// 3. [Named] + [Digested] (e.g., "docker.io/library/busybo@sha256:<digest>")
|
||||
// 4. [Named] (e.g., "docker.io/library/busybox")
|
||||
// 5. [Digested] (e.g., "docker.io@sha256:<digest>")
|
||||
// 6. Parse error
|
||||
func Sort(references []string) []string {
|
||||
var prefs []Reference
|
||||
var bad []string
|
||||
|
||||
for _, ref := range references {
|
||||
pref, err := ParseAnyReference(ref)
|
||||
if err != nil {
|
||||
bad = append(bad, ref)
|
||||
} else {
|
||||
prefs = append(prefs, pref)
|
||||
}
|
||||
}
|
||||
sort.Slice(prefs, func(a, b int) bool {
|
||||
ar := refRank(prefs[a])
|
||||
br := refRank(prefs[b])
|
||||
if ar == br {
|
||||
return prefs[a].String() < prefs[b].String()
|
||||
}
|
||||
return ar < br
|
||||
})
|
||||
sort.Strings(bad)
|
||||
var refs []string
|
||||
for _, pref := range prefs {
|
||||
refs = append(refs, pref.String())
|
||||
}
|
||||
return append(refs, bad...)
|
||||
}
|
||||
|
||||
func refRank(ref Reference) uint8 {
|
||||
if _, ok := ref.(Named); ok {
|
||||
if _, ok = ref.(Tagged); ok {
|
||||
if _, ok = ref.(Digested); ok {
|
||||
return 1
|
||||
}
|
||||
return 2
|
||||
}
|
||||
if _, ok = ref.(Digested); ok {
|
||||
return 3
|
||||
}
|
||||
return 4
|
||||
}
|
||||
return 5
|
||||
}
|
||||
1
vendor/github.com/distribution/reference/.gitattributes
generated
vendored
Normal file
1
vendor/github.com/distribution/reference/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.go text eol=lf
|
||||
2
vendor/github.com/distribution/reference/.gitignore
generated
vendored
Normal file
2
vendor/github.com/distribution/reference/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Cover profiles
|
||||
*.out
|
||||
18
vendor/github.com/distribution/reference/.golangci.yml
generated
vendored
Normal file
18
vendor/github.com/distribution/reference/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
- dupword # Checks for duplicate words in the source code
|
||||
- gofmt
|
||||
- goimports
|
||||
- ineffassign
|
||||
- misspell
|
||||
- revive
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- unused
|
||||
- vet
|
||||
disable:
|
||||
- errcheck
|
||||
|
||||
run:
|
||||
deadline: 2m
|
||||
5
vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md
generated
vendored
Normal file
5
vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Code of Conduct
|
||||
|
||||
We follow the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).
|
||||
|
||||
Please contact the [CNCF Code of Conduct Committee](mailto:conduct@cncf.io) in order to report violations of the Code of Conduct.
|
||||
114
vendor/github.com/distribution/reference/CONTRIBUTING.md
generated
vendored
Normal file
114
vendor/github.com/distribution/reference/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
# Contributing to the reference library
|
||||
|
||||
## Community help
|
||||
|
||||
If you need help, please ask in the [#distribution](https://cloud-native.slack.com/archives/C01GVR8SY4R) channel on CNCF community slack.
|
||||
[Click here for an invite to the CNCF community slack](https://slack.cncf.io/)
|
||||
|
||||
## Reporting security issues
|
||||
|
||||
The maintainers take security seriously. If you discover a security
|
||||
issue, please bring it to their attention right away!
|
||||
|
||||
Please **DO NOT** file a public issue, instead send your report privately to
|
||||
[cncf-distribution-security@lists.cncf.io](mailto:cncf-distribution-security@lists.cncf.io).
|
||||
|
||||
## Reporting an issue properly
|
||||
|
||||
By following these simple rules you will get better and faster feedback on your issue.
|
||||
|
||||
- search the bugtracker for an already reported issue
|
||||
|
||||
### If you found an issue that describes your problem:
|
||||
|
||||
- please read other user comments first, and confirm this is the same issue: a given error condition might be indicative of different problems - you may also find a workaround in the comments
|
||||
- please refrain from adding "same thing here" or "+1" comments
|
||||
- you don't need to comment on an issue to get notified of updates: just hit the "subscribe" button
|
||||
- comment if you have some new, technical and relevant information to add to the case
|
||||
- __DO NOT__ comment on closed issues or merged PRs. If you think you have a related problem, open up a new issue and reference the PR or issue.
|
||||
|
||||
### If you have not found an existing issue that describes your problem:
|
||||
|
||||
1. create a new issue, with a succinct title that describes your issue:
|
||||
- bad title: "It doesn't work with my docker"
|
||||
- good title: "Private registry push fail: 400 error with E_INVALID_DIGEST"
|
||||
2. copy the output of (or similar for other container tools):
|
||||
- `docker version`
|
||||
- `docker info`
|
||||
- `docker exec <registry-container> registry --version`
|
||||
3. copy the command line you used to launch your Registry
|
||||
4. restart your docker daemon in debug mode (add `-D` to the daemon launch arguments)
|
||||
5. reproduce your problem and get your docker daemon logs showing the error
|
||||
6. if relevant, copy your registry logs that show the error
|
||||
7. provide any relevant detail about your specific Registry configuration (e.g., storage backend used)
|
||||
8. indicate if you are using an enterprise proxy, Nginx, or anything else between you and your Registry
|
||||
|
||||
## Contributing Code
|
||||
|
||||
Contributions should be made via pull requests. Pull requests will be reviewed
|
||||
by one or more maintainers or reviewers and merged when acceptable.
|
||||
|
||||
You should follow the basic GitHub workflow:
|
||||
|
||||
1. Use your own [fork](https://help.github.com/en/articles/about-forks)
|
||||
2. Create your [change](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)
|
||||
3. Test your code
|
||||
4. [Commit](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages) your work, always [sign your commits](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages)
|
||||
5. Push your change to your fork and create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork)
|
||||
|
||||
Refer to [containerd's contribution guide](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)
|
||||
for tips on creating a successful contribution.
|
||||
|
||||
## Sign your work
|
||||
|
||||
The sign-off is a simple line at the end of the explanation for the patch. Your
|
||||
signature certifies that you wrote the patch or otherwise have the right to pass
|
||||
it on as an open-source patch. The rules are pretty simple: if you can certify
|
||||
the below (from [developercertificate.org](http://developercertificate.org/)):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
Then you just add a line to every git commit message:
|
||||
|
||||
Signed-off-by: Joe Smith <joe.smith@email.com>
|
||||
|
||||
Use your real name (sorry, no pseudonyms or anonymous contributions.)
|
||||
|
||||
If you set your `user.name` and `user.email` git configs, you can sign your
|
||||
commit automatically with `git commit -s`.
|
||||
144
vendor/github.com/distribution/reference/GOVERNANCE.md
generated
vendored
Normal file
144
vendor/github.com/distribution/reference/GOVERNANCE.md
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
# distribution/reference Project Governance
|
||||
|
||||
Distribution [Code of Conduct](./CODE-OF-CONDUCT.md) can be found here.
|
||||
|
||||
For specific guidance on practical contribution steps please
|
||||
see our [CONTRIBUTING.md](./CONTRIBUTING.md) guide.
|
||||
|
||||
## Maintainership
|
||||
|
||||
There are different types of maintainers, with different responsibilities, but
|
||||
all maintainers have 3 things in common:
|
||||
|
||||
1) They share responsibility in the project's success.
|
||||
2) They have made a long-term, recurring time investment to improve the project.
|
||||
3) They spend that time doing whatever needs to be done, not necessarily what
|
||||
is the most interesting or fun.
|
||||
|
||||
Maintainers are often under-appreciated, because their work is harder to appreciate.
|
||||
It's easy to appreciate a really cool and technically advanced feature. It's harder
|
||||
to appreciate the absence of bugs, the slow but steady improvement in stability,
|
||||
or the reliability of a release process. But those things distinguish a good
|
||||
project from a great one.
|
||||
|
||||
## Reviewers
|
||||
|
||||
A reviewer is a core role within the project.
|
||||
They share in reviewing issues and pull requests and their LGTM counts towards the
|
||||
required LGTM count to merge a code change into the project.
|
||||
|
||||
Reviewers are part of the organization but do not have write access.
|
||||
Becoming a reviewer is a core aspect in the journey to becoming a maintainer.
|
||||
|
||||
## Adding maintainers
|
||||
|
||||
Maintainers are first and foremost contributors that have shown they are
|
||||
committed to the long term success of a project. Contributors wanting to become
|
||||
maintainers are expected to be deeply involved in contributing code, pull
|
||||
request review, and triage of issues in the project for more than three months.
|
||||
|
||||
Just contributing does not make you a maintainer, it is about building trust
|
||||
with the current maintainers of the project and being a person that they can
|
||||
depend on and trust to make decisions in the best interest of the project.
|
||||
|
||||
Periodically, the existing maintainers curate a list of contributors that have
|
||||
shown regular activity on the project over the prior months. From this list,
|
||||
maintainer candidates are selected and proposed in a pull request or a
|
||||
maintainers communication channel.
|
||||
|
||||
After a candidate has been announced to the maintainers, the existing
|
||||
maintainers are given five business days to discuss the candidate, raise
|
||||
objections and cast their vote. Votes may take place on the communication
|
||||
channel or via pull request comment. Candidates must be approved by at least 66%
|
||||
of the current maintainers by adding their vote on the mailing list. The
|
||||
reviewer role has the same process but only requires 33% of current maintainers.
|
||||
Only maintainers of the repository that the candidate is proposed for are
|
||||
allowed to vote.
|
||||
|
||||
If a candidate is approved, a maintainer will contact the candidate to invite
|
||||
the candidate to open a pull request that adds the contributor to the
|
||||
MAINTAINERS file. The voting process may take place inside a pull request if a
|
||||
maintainer has already discussed the candidacy with the candidate and a
|
||||
maintainer is willing to be a sponsor by opening the pull request. The candidate
|
||||
becomes a maintainer once the pull request is merged.
|
||||
|
||||
## Stepping down policy
|
||||
|
||||
Life priorities, interests, and passions can change. If you're a maintainer but
|
||||
feel you must remove yourself from the list, inform other maintainers that you
|
||||
intend to step down, and if possible, help find someone to pick up your work.
|
||||
At the very least, ensure your work can be continued where you left off.
|
||||
|
||||
After you've informed other maintainers, create a pull request to remove
|
||||
yourself from the MAINTAINERS file.
|
||||
|
||||
## Removal of inactive maintainers
|
||||
|
||||
Similar to the procedure for adding new maintainers, existing maintainers can
|
||||
be removed from the list if they do not show significant activity on the
|
||||
project. Periodically, the maintainers review the list of maintainers and their
|
||||
activity over the last three months.
|
||||
|
||||
If a maintainer has shown insufficient activity over this period, a neutral
|
||||
person will contact the maintainer to ask if they want to continue being
|
||||
a maintainer. If the maintainer decides to step down as a maintainer, they
|
||||
open a pull request to be removed from the MAINTAINERS file.
|
||||
|
||||
If the maintainer wants to remain a maintainer, but is unable to perform the
|
||||
required duties they can be removed with a vote of at least 66% of the current
|
||||
maintainers. In this case, maintainers should first propose the change to
|
||||
maintainers via the maintainers communication channel, then open a pull request
|
||||
for voting. The voting period is five business days. The voting pull request
|
||||
should not come as a surpise to any maintainer and any discussion related to
|
||||
performance must not be discussed on the pull request.
|
||||
|
||||
## How are decisions made?
|
||||
|
||||
Docker distribution is an open-source project with an open design philosophy.
|
||||
This means that the repository is the source of truth for EVERY aspect of the
|
||||
project, including its philosophy, design, road map, and APIs. *If it's part of
|
||||
the project, it's in the repo. If it's in the repo, it's part of the project.*
|
||||
|
||||
As a result, all decisions can be expressed as changes to the repository. An
|
||||
implementation change is a change to the source code. An API change is a change
|
||||
to the API specification. A philosophy change is a change to the philosophy
|
||||
manifesto, and so on.
|
||||
|
||||
All decisions affecting distribution, big and small, follow the same 3 steps:
|
||||
|
||||
* Step 1: Open a pull request. Anyone can do this.
|
||||
|
||||
* Step 2: Discuss the pull request. Anyone can do this.
|
||||
|
||||
* Step 3: Merge or refuse the pull request. Who does this depends on the nature
|
||||
of the pull request and which areas of the project it affects.
|
||||
|
||||
## Helping contributors with the DCO
|
||||
|
||||
The [DCO or `Sign your work`](./CONTRIBUTING.md#sign-your-work)
|
||||
requirement is not intended as a roadblock or speed bump.
|
||||
|
||||
Some contributors are not as familiar with `git`, or have used a web
|
||||
based editor, and thus asking them to `git commit --amend -s` is not the best
|
||||
way forward.
|
||||
|
||||
In this case, maintainers can update the commits based on clause (c) of the DCO.
|
||||
The most trivial way for a contributor to allow the maintainer to do this, is to
|
||||
add a DCO signature in a pull requests's comment, or a maintainer can simply
|
||||
note that the change is sufficiently trivial that it does not substantially
|
||||
change the existing contribution - i.e., a spelling change.
|
||||
|
||||
When you add someone's DCO, please also add your own to keep a log.
|
||||
|
||||
## I'm a maintainer. Should I make pull requests too?
|
||||
|
||||
Yes. Nobody should ever push to master directly. All changes should be
|
||||
made through a pull request.
|
||||
|
||||
## Conflict Resolution
|
||||
|
||||
If you have a technical dispute that you feel has reached an impasse with a
|
||||
subset of the community, any contributor may open an issue, specifically
|
||||
calling for a resolution vote of the current core maintainers to resolve the
|
||||
dispute. The same voting quorums required (2/3) for adding and removing
|
||||
maintainers will apply to conflict resolution.
|
||||
202
vendor/github.com/distribution/reference/LICENSE
generated
vendored
Normal file
202
vendor/github.com/distribution/reference/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
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.
|
||||
|
||||
26
vendor/github.com/distribution/reference/MAINTAINERS
generated
vendored
Normal file
26
vendor/github.com/distribution/reference/MAINTAINERS
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Distribution project maintainers & reviewers
|
||||
#
|
||||
# See GOVERNANCE.md for maintainer versus reviewer roles
|
||||
#
|
||||
# MAINTAINERS (cncf-distribution-maintainers@lists.cncf.io)
|
||||
# GitHub ID, Name, Email address
|
||||
"chrispat","Chris Patterson","chrispat@github.com"
|
||||
"clarkbw","Bryan Clark","clarkbw@github.com"
|
||||
"corhere","Cory Snider","csnider@mirantis.com"
|
||||
"deleteriousEffect","Hayley Swimelar","hswimelar@gitlab.com"
|
||||
"heww","He Weiwei","hweiwei@vmware.com"
|
||||
"joaodrp","João Pereira","jpereira@gitlab.com"
|
||||
"justincormack","Justin Cormack","justin.cormack@docker.com"
|
||||
"squizzi","Kyle Squizzato","ksquizzato@mirantis.com"
|
||||
"milosgajdos","Milos Gajdos","milosthegajdos@gmail.com"
|
||||
"sargun","Sargun Dhillon","sargun@sargun.me"
|
||||
"wy65701436","Wang Yan","wangyan@vmware.com"
|
||||
"stevelasker","Steve Lasker","steve.lasker@microsoft.com"
|
||||
#
|
||||
# REVIEWERS
|
||||
# GitHub ID, Name, Email address
|
||||
"dmcgowan","Derek McGowan","derek@mcgstyle.net"
|
||||
"stevvooe","Stephen Day","stevvooe@gmail.com"
|
||||
"thajeztah","Sebastiaan van Stijn","github@gone.nl"
|
||||
"DavidSpek", "David van der Spek", "vanderspek.david@gmail.com"
|
||||
"Jamstah", "James Hewitt", "james.hewitt@gmail.com"
|
||||
25
vendor/github.com/distribution/reference/Makefile
generated
vendored
Normal file
25
vendor/github.com/distribution/reference/Makefile
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Project packages.
|
||||
PACKAGES=$(shell go list ./...)
|
||||
|
||||
# Flags passed to `go test`
|
||||
BUILDFLAGS ?=
|
||||
TESTFLAGS ?=
|
||||
|
||||
.PHONY: all build test coverage
|
||||
.DEFAULT: all
|
||||
|
||||
all: build
|
||||
|
||||
build: ## no binaries to build, so just check compilation suceeds
|
||||
go build ${BUILDFLAGS} ./...
|
||||
|
||||
test: ## run tests
|
||||
go test ${TESTFLAGS} ./...
|
||||
|
||||
coverage: ## generate coverprofiles from the unit tests
|
||||
rm -f coverage.txt
|
||||
go test ${TESTFLAGS} -cover -coverprofile=cover.out ./...
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_\/%-]+:.*?##/ { printf " \033[36m%-27s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
30
vendor/github.com/distribution/reference/README.md
generated
vendored
Normal file
30
vendor/github.com/distribution/reference/README.md
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Distribution reference
|
||||
|
||||
Go library to handle references to container images.
|
||||
|
||||
<img src="/distribution-logo.svg" width="200px" />
|
||||
|
||||
[](https://github.com/distribution/reference/actions?query=workflow%3ACI)
|
||||
[](https://pkg.go.dev/github.com/distribution/reference)
|
||||
[](LICENSE)
|
||||
[](https://codecov.io/gh/distribution/reference)
|
||||
[](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference?ref=badge_shield)
|
||||
|
||||
This repository contains a library for handling refrences to container images held in container registries. Please see [godoc](https://pkg.go.dev/github.com/distribution/reference) for details.
|
||||
|
||||
## Contribution
|
||||
|
||||
Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute
|
||||
issues, fixes, and patches to this project.
|
||||
|
||||
## Communication
|
||||
|
||||
For async communication and long running discussions please use issues and pull requests on the github repo.
|
||||
This will be the best place to discuss design and implementation.
|
||||
|
||||
For sync communication we have a #distribution channel in the [CNCF Slack](https://slack.cncf.io/)
|
||||
that everyone is welcome to join and chat about development.
|
||||
|
||||
## Licenses
|
||||
|
||||
The distribution codebase is released under the [Apache 2.0 license](LICENSE).
|
||||
7
vendor/github.com/distribution/reference/SECURITY.md
generated
vendored
Normal file
7
vendor/github.com/distribution/reference/SECURITY.md
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
The maintainers take security seriously. If you discover a security issue, please bring it to their attention right away!
|
||||
|
||||
Please DO NOT file a public issue, instead send your report privately to cncf-distribution-security@lists.cncf.io.
|
||||
1
vendor/github.com/distribution/reference/distribution-logo.svg
generated
vendored
Normal file
1
vendor/github.com/distribution/reference/distribution-logo.svg
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 8.6 KiB |
@@ -32,7 +32,7 @@ func FamiliarString(ref Reference) string {
|
||||
}
|
||||
|
||||
// FamiliarMatch reports whether ref matches the specified pattern.
|
||||
// See https://godoc.org/path#Match for supported patterns.
|
||||
// See [path.Match] for supported patterns.
|
||||
func FamiliarMatch(pattern string, ref Reference) (bool, error) {
|
||||
matched, err := path.Match(pattern, FamiliarString(ref))
|
||||
if namedRef, isNamed := ref.(Named); isNamed && !matched {
|
||||
@@ -1,19 +1,42 @@
|
||||
package reference
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/digestset"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
var (
|
||||
const (
|
||||
// legacyDefaultDomain is the legacy domain for Docker Hub (which was
|
||||
// originally named "the Docker Index"). This domain is still used for
|
||||
// authentication and image search, which were part of the "v1" Docker
|
||||
// registry specification.
|
||||
//
|
||||
// This domain will continue to be supported, but there are plans to consolidate
|
||||
// legacy domains to new "canonical" domains. Once those domains are decided
|
||||
// on, we must update the normalization functions, but preserve compatibility
|
||||
// with existing installs, clients, and user configuration.
|
||||
legacyDefaultDomain = "index.docker.io"
|
||||
defaultDomain = "docker.io"
|
||||
officialRepoName = "library"
|
||||
defaultTag = "latest"
|
||||
|
||||
// defaultDomain is the default domain used for images on Docker Hub.
|
||||
// It is used to normalize "familiar" names to canonical names, for example,
|
||||
// to convert "ubuntu" to "docker.io/library/ubuntu:latest".
|
||||
//
|
||||
// Note that actual domain of Docker Hub's registry is registry-1.docker.io.
|
||||
// This domain will continue to be supported, but there are plans to consolidate
|
||||
// legacy domains to new "canonical" domains. Once those domains are decided
|
||||
// on, we must update the normalization functions, but preserve compatibility
|
||||
// with existing installs, clients, and user configuration.
|
||||
defaultDomain = "docker.io"
|
||||
|
||||
// officialRepoPrefix is the namespace used for official images on Docker Hub.
|
||||
// It is used to normalize "familiar" names to canonical names, for example,
|
||||
// to convert "ubuntu" to "docker.io/library/ubuntu:latest".
|
||||
officialRepoPrefix = "library/"
|
||||
|
||||
// defaultTag is the default tag if no tag is provided.
|
||||
defaultTag = "latest"
|
||||
)
|
||||
|
||||
// normalizedNamed represents a name which has been
|
||||
@@ -35,14 +58,14 @@ func ParseNormalizedNamed(s string) (Named, error) {
|
||||
return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s)
|
||||
}
|
||||
domain, remainder := splitDockerDomain(s)
|
||||
var remoteName string
|
||||
var remote string
|
||||
if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {
|
||||
remoteName = remainder[:tagSep]
|
||||
remote = remainder[:tagSep]
|
||||
} else {
|
||||
remoteName = remainder
|
||||
remote = remainder
|
||||
}
|
||||
if strings.ToLower(remoteName) != remoteName {
|
||||
return nil, errors.New("invalid reference format: repository name must be lowercase")
|
||||
if strings.ToLower(remote) != remote {
|
||||
return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remote)
|
||||
}
|
||||
|
||||
ref, err := Parse(domain + "/" + remainder)
|
||||
@@ -56,41 +79,53 @@ func ParseNormalizedNamed(s string) (Named, error) {
|
||||
return named, nil
|
||||
}
|
||||
|
||||
// ParseDockerRef normalizes the image reference following the docker convention. This is added
|
||||
// mainly for backward compatibility.
|
||||
// The reference returned can only be either tagged or digested. For reference contains both tag
|
||||
// and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@
|
||||
// sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as
|
||||
// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa.
|
||||
// namedTaggedDigested is a reference that has both a tag and a digest.
|
||||
type namedTaggedDigested interface {
|
||||
NamedTagged
|
||||
Digested
|
||||
}
|
||||
|
||||
// ParseDockerRef normalizes the image reference following the docker convention,
|
||||
// which allows for references to contain both a tag and a digest. It returns a
|
||||
// reference that is either tagged or digested. For references containing both
|
||||
// a tag and a digest, it returns a digested reference. For example, the following
|
||||
// reference:
|
||||
//
|
||||
// docker.io/library/busybox:latest@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
|
||||
//
|
||||
// Is returned as a digested reference (with the ":latest" tag removed):
|
||||
//
|
||||
// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
|
||||
//
|
||||
// References that are already "tagged" or "digested" are returned unmodified:
|
||||
//
|
||||
// // Already a digested reference
|
||||
// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
|
||||
//
|
||||
// // Already a named reference
|
||||
// docker.io/library/busybox:latest
|
||||
func ParseDockerRef(ref string) (Named, error) {
|
||||
named, err := ParseNormalizedNamed(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := named.(NamedTagged); ok {
|
||||
if canonical, ok := named.(Canonical); ok {
|
||||
// The reference is both tagged and digested, only
|
||||
// return digested.
|
||||
newNamed, err := WithName(canonical.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newCanonical, err := WithDigest(newNamed, canonical.Digest())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newCanonical, nil
|
||||
if canonical, ok := named.(namedTaggedDigested); ok {
|
||||
// The reference is both tagged and digested; only return digested.
|
||||
newNamed, err := WithName(canonical.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return WithDigest(newNamed, canonical.Digest())
|
||||
}
|
||||
return TagNameOnly(named), nil
|
||||
}
|
||||
|
||||
// splitDockerDomain splits a repository name to domain and remotename string.
|
||||
// splitDockerDomain splits a repository name to domain and remote-name.
|
||||
// If no valid domain is found, the default domain is used. Repository name
|
||||
// needs to be already validated before.
|
||||
func splitDockerDomain(name string) (domain, remainder string) {
|
||||
i := strings.IndexRune(name, '/')
|
||||
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
|
||||
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != localhost && strings.ToLower(name[:i]) == name[:i]) {
|
||||
domain, remainder = defaultDomain, name
|
||||
} else {
|
||||
domain, remainder = name[:i], name[i+1:]
|
||||
@@ -99,13 +134,13 @@ func splitDockerDomain(name string) (domain, remainder string) {
|
||||
domain = defaultDomain
|
||||
}
|
||||
if domain == defaultDomain && !strings.ContainsRune(remainder, '/') {
|
||||
remainder = officialRepoName + "/" + remainder
|
||||
remainder = officialRepoPrefix + remainder
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// familiarizeName returns a shortened version of the name familiar
|
||||
// to to the Docker UI. Familiar names have the default domain
|
||||
// to the Docker UI. Familiar names have the default domain
|
||||
// "docker.io" and "library/" repository prefix removed.
|
||||
// For example, "docker.io/library/redis" will have the familiar
|
||||
// name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp".
|
||||
@@ -119,8 +154,15 @@ func familiarizeName(named namedRepository) repository {
|
||||
if repo.domain == defaultDomain {
|
||||
repo.domain = ""
|
||||
// Handle official repositories which have the pattern "library/<official repo name>"
|
||||
if split := strings.Split(repo.path, "/"); len(split) == 2 && split[0] == officialRepoName {
|
||||
repo.path = split[1]
|
||||
if strings.HasPrefix(repo.path, officialRepoPrefix) {
|
||||
// TODO(thaJeztah): this check may be too strict, as it assumes the
|
||||
// "library/" namespace does not have nested namespaces. While this
|
||||
// is true (currently), technically it would be possible for Docker
|
||||
// Hub to use those (e.g. "library/distros/ubuntu:latest").
|
||||
// See https://github.com/distribution/distribution/pull/3769#issuecomment-1302031785.
|
||||
if remainder := strings.TrimPrefix(repo.path, officialRepoPrefix); !strings.ContainsRune(remainder, '/') {
|
||||
repo.path = remainder
|
||||
}
|
||||
}
|
||||
}
|
||||
return repo
|
||||
@@ -180,20 +222,3 @@ func ParseAnyReference(ref string) (Reference, error) {
|
||||
|
||||
return ParseNormalizedNamed(ref)
|
||||
}
|
||||
|
||||
// ParseAnyReferenceWithSet parses a reference string as a possible short
|
||||
// identifier to be matched in a digest set, a full digest, or familiar name.
|
||||
func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) {
|
||||
if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok {
|
||||
dgst, err := ds.Lookup(ref)
|
||||
if err == nil {
|
||||
return digestReference(dgst), nil
|
||||
}
|
||||
} else {
|
||||
if dgst, err := digest.Parse(ref); err == nil {
|
||||
return digestReference(dgst), nil
|
||||
}
|
||||
}
|
||||
|
||||
return ParseNormalizedNamed(ref)
|
||||
}
|
||||
@@ -4,11 +4,14 @@
|
||||
// Grammar
|
||||
//
|
||||
// reference := name [ ":" tag ] [ "@" digest ]
|
||||
// name := [domain '/'] path-component ['/' path-component]*
|
||||
// domain := domain-component ['.' domain-component]* [':' port-number]
|
||||
// name := [domain '/'] remote-name
|
||||
// domain := host [':' port-number]
|
||||
// host := domain-name | IPv4address | \[ IPv6address \] ; rfc3986 appendix-A
|
||||
// domain-name := domain-component ['.' domain-component]*
|
||||
// domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
|
||||
// port-number := /[0-9]+/
|
||||
// path-component := alpha-numeric [separator alpha-numeric]*
|
||||
// path (or "remote-name") := path-component ['/' path-component]*
|
||||
// alpha-numeric := /[a-z0-9]+/
|
||||
// separator := /[_.]|__|[-]*/
|
||||
//
|
||||
@@ -21,7 +24,6 @@
|
||||
// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
|
||||
//
|
||||
// identifier := /[a-f0-9]{64}/
|
||||
// short-identifier := /[a-f0-9]{6,64}/
|
||||
package reference
|
||||
|
||||
import (
|
||||
@@ -145,7 +147,7 @@ type namedRepository interface {
|
||||
Path() string
|
||||
}
|
||||
|
||||
// Domain returns the domain part of the Named reference
|
||||
// Domain returns the domain part of the [Named] reference.
|
||||
func Domain(named Named) string {
|
||||
if r, ok := named.(namedRepository); ok {
|
||||
return r.Domain()
|
||||
@@ -154,7 +156,7 @@ func Domain(named Named) string {
|
||||
return domain
|
||||
}
|
||||
|
||||
// Path returns the name without the domain part of the Named reference
|
||||
// Path returns the name without the domain part of the [Named] reference.
|
||||
func Path(named Named) (name string) {
|
||||
if r, ok := named.(namedRepository); ok {
|
||||
return r.Path()
|
||||
@@ -175,7 +177,8 @@ func splitDomain(name string) (string, string) {
|
||||
// hostname and name string. If no valid hostname is
|
||||
// found, the hostname is empty and the full value
|
||||
// is returned as name
|
||||
// DEPRECATED: Use Domain or Path
|
||||
//
|
||||
// Deprecated: Use [Domain] or [Path].
|
||||
func SplitHostname(named Named) (string, string) {
|
||||
if r, ok := named.(namedRepository); ok {
|
||||
return r.Domain(), r.Path()
|
||||
@@ -185,7 +188,6 @@ func SplitHostname(named Named) (string, string) {
|
||||
|
||||
// Parse parses s and returns a syntactically valid Reference.
|
||||
// If an error was encountered it is returned, along with a nil Reference.
|
||||
// NOTE: Parse will not handle short digests.
|
||||
func Parse(s string) (Reference, error) {
|
||||
matches := ReferenceRegexp.FindStringSubmatch(s)
|
||||
if matches == nil {
|
||||
@@ -237,7 +239,6 @@ func Parse(s string) (Reference, error) {
|
||||
// the Named interface. The reference must have a name and be in the canonical
|
||||
// form, otherwise an error is returned.
|
||||
// If an error was encountered it is returned, along with a nil Reference.
|
||||
// NOTE: ParseNamed will not handle short digests.
|
||||
func ParseNamed(s string) (Named, error) {
|
||||
named, err := ParseNormalizedNamed(s)
|
||||
if err != nil {
|
||||
@@ -320,11 +321,13 @@ func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
|
||||
|
||||
// TrimNamed removes any tag or digest from the named reference.
|
||||
func TrimNamed(ref Named) Named {
|
||||
domain, path := SplitHostname(ref)
|
||||
return repository{
|
||||
domain: domain,
|
||||
path: path,
|
||||
repo := repository{}
|
||||
if r, ok := ref.(namedRepository); ok {
|
||||
repo.domain, repo.path = r.Domain(), r.Path()
|
||||
} else {
|
||||
repo.domain, repo.path = splitDomain(ref.Name())
|
||||
}
|
||||
return repo
|
||||
}
|
||||
|
||||
func getBestReferenceType(ref reference) Reference {
|
||||
163
vendor/github.com/distribution/reference/regexp.go
generated
vendored
Normal file
163
vendor/github.com/distribution/reference/regexp.go
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
package reference
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
|
||||
var DigestRegexp = regexp.MustCompile(digestPat)
|
||||
|
||||
// DomainRegexp matches hostname or IP-addresses, optionally including a port
|
||||
// number. It defines the structure of potential domain components that may be
|
||||
// part of image names. This is purposely a subset of what is allowed by DNS to
|
||||
// ensure backwards compatibility with Docker image names. It may be a subset of
|
||||
// DNS domain name, an IPv4 address in decimal format, or an IPv6 address between
|
||||
// square brackets (excluding zone identifiers as defined by [RFC 6874] or special
|
||||
// addresses such as IPv4-Mapped).
|
||||
//
|
||||
// [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874.
|
||||
var DomainRegexp = regexp.MustCompile(domainAndPort)
|
||||
|
||||
// IdentifierRegexp is the format for string identifier used as a
|
||||
// content addressable identifier using sha256. These identifiers
|
||||
// are like digests without the algorithm, since sha256 is used.
|
||||
var IdentifierRegexp = regexp.MustCompile(identifier)
|
||||
|
||||
// NameRegexp is the format for the name component of references, including
|
||||
// an optional domain and port, but without tag or digest suffix.
|
||||
var NameRegexp = regexp.MustCompile(namePat)
|
||||
|
||||
// ReferenceRegexp is the full supported format of a reference. The regexp
|
||||
// is anchored and has capturing groups for name, tag, and digest
|
||||
// components.
|
||||
var ReferenceRegexp = regexp.MustCompile(referencePat)
|
||||
|
||||
// TagRegexp matches valid tag names. From [docker/docker:graph/tags.go].
|
||||
//
|
||||
// [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28
|
||||
var TagRegexp = regexp.MustCompile(tag)
|
||||
|
||||
const (
|
||||
// alphanumeric defines the alphanumeric atom, typically a
|
||||
// component of names. This only allows lower case characters and digits.
|
||||
alphanumeric = `[a-z0-9]+`
|
||||
|
||||
// separator defines the separators allowed to be embedded in name
|
||||
// components. This allows one period, one or two underscore and multiple
|
||||
// dashes. Repeated dashes and underscores are intentionally treated
|
||||
// differently. In order to support valid hostnames as name components,
|
||||
// supporting repeated dash was added. Additionally double underscore is
|
||||
// now allowed as a separator to loosen the restriction for previously
|
||||
// supported names.
|
||||
separator = `(?:[._]|__|[-]+)`
|
||||
|
||||
// localhost is treated as a special value for domain-name. Any other
|
||||
// domain-name without a "." or a ":port" are considered a path component.
|
||||
localhost = `localhost`
|
||||
|
||||
// domainNameComponent restricts the registry domain component of a
|
||||
// repository name to start with a component as defined by DomainRegexp.
|
||||
domainNameComponent = `(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`
|
||||
|
||||
// optionalPort matches an optional port-number including the port separator
|
||||
// (e.g. ":80").
|
||||
optionalPort = `(?::[0-9]+)?`
|
||||
|
||||
// tag matches valid tag names. From docker/docker:graph/tags.go.
|
||||
tag = `[\w][\w.-]{0,127}`
|
||||
|
||||
// digestPat matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
|
||||
//
|
||||
// TODO(thaJeztah): this should follow the same rules as https://pkg.go.dev/github.com/opencontainers/go-digest@v1.0.0#DigestRegexp
|
||||
// so that go-digest defines the canonical format. Note that the go-digest is
|
||||
// more relaxed:
|
||||
// - it allows multiple algorithms (e.g. "sha256+b64:<encoded>") to allow
|
||||
// future expansion of supported algorithms.
|
||||
// - it allows the "<encoded>" value to use urlsafe base64 encoding as defined
|
||||
// in [rfc4648, section 5].
|
||||
//
|
||||
// [rfc4648, section 5]: https://www.rfc-editor.org/rfc/rfc4648#section-5.
|
||||
digestPat = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`
|
||||
|
||||
// identifier is the format for a content addressable identifier using sha256.
|
||||
// These identifiers are like digests without the algorithm, since sha256 is used.
|
||||
identifier = `([a-f0-9]{64})`
|
||||
|
||||
// ipv6address are enclosed between square brackets and may be represented
|
||||
// in many ways, see rfc5952. Only IPv6 in compressed or uncompressed format
|
||||
// are allowed, IPv6 zone identifiers (rfc6874) or Special addresses such as
|
||||
// IPv4-Mapped are deliberately excluded.
|
||||
ipv6address = `\[(?:[a-fA-F0-9:]+)\]`
|
||||
)
|
||||
|
||||
var (
|
||||
// domainName defines the structure of potential domain components
|
||||
// that may be part of image names. This is purposely a subset of what is
|
||||
// allowed by DNS to ensure backwards compatibility with Docker image
|
||||
// names. This includes IPv4 addresses on decimal format.
|
||||
domainName = domainNameComponent + anyTimes(`\.`+domainNameComponent)
|
||||
|
||||
// host defines the structure of potential domains based on the URI
|
||||
// Host subcomponent on rfc3986. It may be a subset of DNS domain name,
|
||||
// or an IPv4 address in decimal format, or an IPv6 address between square
|
||||
// brackets (excluding zone identifiers as defined by rfc6874 or special
|
||||
// addresses such as IPv4-Mapped).
|
||||
host = `(?:` + domainName + `|` + ipv6address + `)`
|
||||
|
||||
// allowed by the URI Host subcomponent on rfc3986 to ensure backwards
|
||||
// compatibility with Docker image names.
|
||||
domainAndPort = host + optionalPort
|
||||
|
||||
// anchoredTagRegexp matches valid tag names, anchored at the start and
|
||||
// end of the matched string.
|
||||
anchoredTagRegexp = regexp.MustCompile(anchored(tag))
|
||||
|
||||
// anchoredDigestRegexp matches valid digests, anchored at the start and
|
||||
// end of the matched string.
|
||||
anchoredDigestRegexp = regexp.MustCompile(anchored(digestPat))
|
||||
|
||||
// pathComponent restricts path-components to start with an alphanumeric
|
||||
// character, with following parts able to be separated by a separator
|
||||
// (one period, one or two underscore and multiple dashes).
|
||||
pathComponent = alphanumeric + anyTimes(separator+alphanumeric)
|
||||
|
||||
// remoteName matches the remote-name of a repository. It consists of one
|
||||
// or more forward slash (/) delimited path-components:
|
||||
//
|
||||
// pathComponent[[/pathComponent] ...] // e.g., "library/ubuntu"
|
||||
remoteName = pathComponent + anyTimes(`/`+pathComponent)
|
||||
namePat = optional(domainAndPort+`/`) + remoteName
|
||||
|
||||
// anchoredNameRegexp is used to parse a name value, capturing the
|
||||
// domain and trailing components.
|
||||
anchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(remoteName)))
|
||||
|
||||
referencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat)))
|
||||
|
||||
// anchoredIdentifierRegexp is used to check or match an
|
||||
// identifier value, anchored at start and end of string.
|
||||
anchoredIdentifierRegexp = regexp.MustCompile(anchored(identifier))
|
||||
)
|
||||
|
||||
// optional wraps the expression in a non-capturing group and makes the
|
||||
// production optional.
|
||||
func optional(res ...string) string {
|
||||
return `(?:` + strings.Join(res, "") + `)?`
|
||||
}
|
||||
|
||||
// anyTimes wraps the expression in a non-capturing group that can occur
|
||||
// any number of times.
|
||||
func anyTimes(res ...string) string {
|
||||
return `(?:` + strings.Join(res, "") + `)*`
|
||||
}
|
||||
|
||||
// capture wraps the expression in a capturing group.
|
||||
func capture(res ...string) string {
|
||||
return `(` + strings.Join(res, "") + `)`
|
||||
}
|
||||
|
||||
// anchored anchors the regular expression by adding start and end delimiters.
|
||||
func anchored(res ...string) string {
|
||||
return `^` + strings.Join(res, "") + `$`
|
||||
}
|
||||
75
vendor/github.com/distribution/reference/sort.go
generated
vendored
Normal file
75
vendor/github.com/distribution/reference/sort.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright The containerd 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 reference
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Sort sorts string references preferring higher information references.
|
||||
//
|
||||
// The precedence is as follows:
|
||||
//
|
||||
// 1. [Named] + [Tagged] + [Digested] (e.g., "docker.io/library/busybox:latest@sha256:<digest>")
|
||||
// 2. [Named] + [Tagged] (e.g., "docker.io/library/busybox:latest")
|
||||
// 3. [Named] + [Digested] (e.g., "docker.io/library/busybo@sha256:<digest>")
|
||||
// 4. [Named] (e.g., "docker.io/library/busybox")
|
||||
// 5. [Digested] (e.g., "docker.io@sha256:<digest>")
|
||||
// 6. Parse error
|
||||
func Sort(references []string) []string {
|
||||
var prefs []Reference
|
||||
var bad []string
|
||||
|
||||
for _, ref := range references {
|
||||
pref, err := ParseAnyReference(ref)
|
||||
if err != nil {
|
||||
bad = append(bad, ref)
|
||||
} else {
|
||||
prefs = append(prefs, pref)
|
||||
}
|
||||
}
|
||||
sort.Slice(prefs, func(a, b int) bool {
|
||||
ar := refRank(prefs[a])
|
||||
br := refRank(prefs[b])
|
||||
if ar == br {
|
||||
return prefs[a].String() < prefs[b].String()
|
||||
}
|
||||
return ar < br
|
||||
})
|
||||
sort.Strings(bad)
|
||||
var refs []string
|
||||
for _, pref := range prefs {
|
||||
refs = append(refs, pref.String())
|
||||
}
|
||||
return append(refs, bad...)
|
||||
}
|
||||
|
||||
func refRank(ref Reference) uint8 {
|
||||
if _, ok := ref.(Named); ok {
|
||||
if _, ok = ref.(Tagged); ok {
|
||||
if _, ok = ref.(Digested); ok {
|
||||
return 1
|
||||
}
|
||||
return 2
|
||||
}
|
||||
if _, ok = ref.(Digested); ok {
|
||||
return 3
|
||||
}
|
||||
return 4
|
||||
}
|
||||
return 5
|
||||
}
|
||||
10
vendor/github.com/docker/distribution/.golangci.yml
generated
vendored
10
vendor/github.com/docker/distribution/.golangci.yml
generated
vendored
@@ -1,7 +1,5 @@
|
||||
linters:
|
||||
enable:
|
||||
- structcheck
|
||||
- varcheck
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- gofmt
|
||||
@@ -14,6 +12,14 @@ linters:
|
||||
disable:
|
||||
- errcheck
|
||||
|
||||
linters-settings:
|
||||
revive:
|
||||
rules:
|
||||
# TODO(thaJeztah): temporarily disabled the "unused-parameter" check.
|
||||
# It produces many warnings, and some of those may need to be looked at.
|
||||
- name: unused-parameter
|
||||
disabled: true
|
||||
|
||||
run:
|
||||
deadline: 2m
|
||||
skip-dirs:
|
||||
|
||||
3
vendor/github.com/docker/distribution/.mailmap
generated
vendored
3
vendor/github.com/docker/distribution/.mailmap
generated
vendored
@@ -49,3 +49,6 @@ Hayley Swimelar <hswimelar@gmail.com>
|
||||
Jose D. Gomez R <jose.gomez@suse.com>
|
||||
Shengjing Zhu <zhsj@debian.org>
|
||||
Silvin Lubecki <31478878+silvin-lubecki@users.noreply.github.com>
|
||||
James Hewitt <james.hewitt@gmail.com>
|
||||
Marcus Pettersen Irgens <m@mrcus.dev>
|
||||
Ben Manuel <bmanuel@users.noreply.github.com>
|
||||
|
||||
2
vendor/github.com/docker/distribution/BUILDING.md
generated
vendored
2
vendor/github.com/docker/distribution/BUILDING.md
generated
vendored
@@ -114,4 +114,4 @@ the registry binary generated in the "./bin" directory:
|
||||
### Optional build tags
|
||||
|
||||
Optional [build tags](http://golang.org/pkg/go/build/) can be provided using
|
||||
the environment variable `DOCKER_BUILDTAGS`.
|
||||
the environment variable `BUILDTAGS`.
|
||||
|
||||
8
vendor/github.com/docker/distribution/Dockerfile
generated
vendored
8
vendor/github.com/docker/distribution/Dockerfile
generated
vendored
@@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.19.9
|
||||
ARG ALPINE_VERSION=3.16
|
||||
ARG GO_VERSION=1.20.8
|
||||
ARG ALPINE_VERSION=3.18
|
||||
ARG XX_VERSION=1.2.1
|
||||
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||
@@ -22,12 +22,12 @@ RUN --mount=target=. \
|
||||
FROM base AS build
|
||||
ARG TARGETPLATFORM
|
||||
ARG LDFLAGS="-s -w"
|
||||
ARG BUILDTAGS="include_oss include_gcs"
|
||||
ARG BUILDTAGS="include_oss,include_gcs"
|
||||
RUN --mount=type=bind,target=/go/src/github.com/docker/distribution,rw \
|
||||
--mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=target=/go/pkg/mod,type=cache \
|
||||
--mount=type=bind,source=/tmp/.ldflags,target=/tmp/.ldflags,from=version \
|
||||
set -x ; xx-go build -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/registry ./cmd/registry \
|
||||
set -x ; xx-go build -tags "${BUILDTAGS}" -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/registry ./cmd/registry \
|
||||
&& xx-verify --static /usr/bin/registry
|
||||
|
||||
FROM scratch AS binary
|
||||
|
||||
2
vendor/github.com/docker/distribution/Makefile
generated
vendored
2
vendor/github.com/docker/distribution/Makefile
generated
vendored
@@ -50,7 +50,7 @@ version/version.go:
|
||||
|
||||
check: ## run all linters (TODO: enable "unused", "varcheck", "ineffassign", "unconvert", "staticheck", "goimports", "structcheck")
|
||||
@echo "$(WHALE) $@"
|
||||
@GO111MODULE=off golangci-lint run
|
||||
@GO111MODULE=off golangci-lint --build-tags "${BUILDTAGS}" run
|
||||
|
||||
test: ## run tests, except integration test with test.short
|
||||
@echo "$(WHALE) $@"
|
||||
|
||||
2
vendor/github.com/docker/distribution/blobs.go
generated
vendored
2
vendor/github.com/docker/distribution/blobs.go
generated
vendored
@@ -8,7 +8,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
247
vendor/github.com/docker/distribution/digestset/set.go
generated
vendored
247
vendor/github.com/docker/distribution/digestset/set.go
generated
vendored
@@ -1,247 +0,0 @@
|
||||
package digestset
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrDigestNotFound is used when a matching digest
|
||||
// could not be found in a set.
|
||||
ErrDigestNotFound = errors.New("digest not found")
|
||||
|
||||
// ErrDigestAmbiguous is used when multiple digests
|
||||
// are found in a set. None of the matching digests
|
||||
// should be considered valid matches.
|
||||
ErrDigestAmbiguous = errors.New("ambiguous digest string")
|
||||
)
|
||||
|
||||
// Set is used to hold a unique set of digests which
|
||||
// may be easily referenced by easily referenced by a string
|
||||
// representation of the digest as well as short representation.
|
||||
// The uniqueness of the short representation is based on other
|
||||
// digests in the set. If digests are omitted from this set,
|
||||
// collisions in a larger set may not be detected, therefore it
|
||||
// is important to always do short representation lookups on
|
||||
// the complete set of digests. To mitigate collisions, an
|
||||
// appropriately long short code should be used.
|
||||
type Set struct {
|
||||
mutex sync.RWMutex
|
||||
entries digestEntries
|
||||
}
|
||||
|
||||
// NewSet creates an empty set of digests
|
||||
// which may have digests added.
|
||||
func NewSet() *Set {
|
||||
return &Set{
|
||||
entries: digestEntries{},
|
||||
}
|
||||
}
|
||||
|
||||
// checkShortMatch checks whether two digests match as either whole
|
||||
// values or short values. This function does not test equality,
|
||||
// rather whether the second value could match against the first
|
||||
// value.
|
||||
func checkShortMatch(alg digest.Algorithm, hex, shortAlg, shortHex string) bool {
|
||||
if len(hex) == len(shortHex) {
|
||||
if hex != shortHex {
|
||||
return false
|
||||
}
|
||||
if len(shortAlg) > 0 && string(alg) != shortAlg {
|
||||
return false
|
||||
}
|
||||
} else if !strings.HasPrefix(hex, shortHex) {
|
||||
return false
|
||||
} else if len(shortAlg) > 0 && string(alg) != shortAlg {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Lookup looks for a digest matching the given string representation.
|
||||
// If no digests could be found ErrDigestNotFound will be returned
|
||||
// with an empty digest value. If multiple matches are found
|
||||
// ErrDigestAmbiguous will be returned with an empty digest value.
|
||||
func (dst *Set) Lookup(d string) (digest.Digest, error) {
|
||||
dst.mutex.RLock()
|
||||
defer dst.mutex.RUnlock()
|
||||
if len(dst.entries) == 0 {
|
||||
return "", ErrDigestNotFound
|
||||
}
|
||||
var (
|
||||
searchFunc func(int) bool
|
||||
alg digest.Algorithm
|
||||
hex string
|
||||
)
|
||||
dgst, err := digest.Parse(d)
|
||||
if err == digest.ErrDigestInvalidFormat {
|
||||
hex = d
|
||||
searchFunc = func(i int) bool {
|
||||
return dst.entries[i].val >= d
|
||||
}
|
||||
} else {
|
||||
hex = dgst.Hex()
|
||||
alg = dgst.Algorithm()
|
||||
searchFunc = func(i int) bool {
|
||||
if dst.entries[i].val == hex {
|
||||
return dst.entries[i].alg >= alg
|
||||
}
|
||||
return dst.entries[i].val >= hex
|
||||
}
|
||||
}
|
||||
idx := sort.Search(len(dst.entries), searchFunc)
|
||||
if idx == len(dst.entries) || !checkShortMatch(dst.entries[idx].alg, dst.entries[idx].val, string(alg), hex) {
|
||||
return "", ErrDigestNotFound
|
||||
}
|
||||
if dst.entries[idx].alg == alg && dst.entries[idx].val == hex {
|
||||
return dst.entries[idx].digest, nil
|
||||
}
|
||||
if idx+1 < len(dst.entries) && checkShortMatch(dst.entries[idx+1].alg, dst.entries[idx+1].val, string(alg), hex) {
|
||||
return "", ErrDigestAmbiguous
|
||||
}
|
||||
|
||||
return dst.entries[idx].digest, nil
|
||||
}
|
||||
|
||||
// Add adds the given digest to the set. An error will be returned
|
||||
// if the given digest is invalid. If the digest already exists in the
|
||||
// set, this operation will be a no-op.
|
||||
func (dst *Set) Add(d digest.Digest) error {
|
||||
if err := d.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
dst.mutex.Lock()
|
||||
defer dst.mutex.Unlock()
|
||||
entry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d}
|
||||
searchFunc := func(i int) bool {
|
||||
if dst.entries[i].val == entry.val {
|
||||
return dst.entries[i].alg >= entry.alg
|
||||
}
|
||||
return dst.entries[i].val >= entry.val
|
||||
}
|
||||
idx := sort.Search(len(dst.entries), searchFunc)
|
||||
if idx == len(dst.entries) {
|
||||
dst.entries = append(dst.entries, entry)
|
||||
return nil
|
||||
} else if dst.entries[idx].digest == d {
|
||||
return nil
|
||||
}
|
||||
|
||||
entries := append(dst.entries, nil)
|
||||
copy(entries[idx+1:], entries[idx:len(entries)-1])
|
||||
entries[idx] = entry
|
||||
dst.entries = entries
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove removes the given digest from the set. An err will be
|
||||
// returned if the given digest is invalid. If the digest does
|
||||
// not exist in the set, this operation will be a no-op.
|
||||
func (dst *Set) Remove(d digest.Digest) error {
|
||||
if err := d.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
dst.mutex.Lock()
|
||||
defer dst.mutex.Unlock()
|
||||
entry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d}
|
||||
searchFunc := func(i int) bool {
|
||||
if dst.entries[i].val == entry.val {
|
||||
return dst.entries[i].alg >= entry.alg
|
||||
}
|
||||
return dst.entries[i].val >= entry.val
|
||||
}
|
||||
idx := sort.Search(len(dst.entries), searchFunc)
|
||||
// Not found if idx is after or value at idx is not digest
|
||||
if idx == len(dst.entries) || dst.entries[idx].digest != d {
|
||||
return nil
|
||||
}
|
||||
|
||||
entries := dst.entries
|
||||
copy(entries[idx:], entries[idx+1:])
|
||||
entries = entries[:len(entries)-1]
|
||||
dst.entries = entries
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// All returns all the digests in the set
|
||||
func (dst *Set) All() []digest.Digest {
|
||||
dst.mutex.RLock()
|
||||
defer dst.mutex.RUnlock()
|
||||
retValues := make([]digest.Digest, len(dst.entries))
|
||||
for i := range dst.entries {
|
||||
retValues[i] = dst.entries[i].digest
|
||||
}
|
||||
|
||||
return retValues
|
||||
}
|
||||
|
||||
// ShortCodeTable returns a map of Digest to unique short codes. The
|
||||
// length represents the minimum value, the maximum length may be the
|
||||
// entire value of digest if uniqueness cannot be achieved without the
|
||||
// full value. This function will attempt to make short codes as short
|
||||
// as possible to be unique.
|
||||
func ShortCodeTable(dst *Set, length int) map[digest.Digest]string {
|
||||
dst.mutex.RLock()
|
||||
defer dst.mutex.RUnlock()
|
||||
m := make(map[digest.Digest]string, len(dst.entries))
|
||||
l := length
|
||||
resetIdx := 0
|
||||
for i := 0; i < len(dst.entries); i++ {
|
||||
var short string
|
||||
extended := true
|
||||
for extended {
|
||||
extended = false
|
||||
if len(dst.entries[i].val) <= l {
|
||||
short = dst.entries[i].digest.String()
|
||||
} else {
|
||||
short = dst.entries[i].val[:l]
|
||||
for j := i + 1; j < len(dst.entries); j++ {
|
||||
if checkShortMatch(dst.entries[j].alg, dst.entries[j].val, "", short) {
|
||||
if j > resetIdx {
|
||||
resetIdx = j
|
||||
}
|
||||
extended = true
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if extended {
|
||||
l++
|
||||
}
|
||||
}
|
||||
}
|
||||
m[dst.entries[i].digest] = short
|
||||
if i >= resetIdx {
|
||||
l = length
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
type digestEntry struct {
|
||||
alg digest.Algorithm
|
||||
val string
|
||||
digest digest.Digest
|
||||
}
|
||||
|
||||
type digestEntries []*digestEntry
|
||||
|
||||
func (d digestEntries) Len() int {
|
||||
return len(d)
|
||||
}
|
||||
|
||||
func (d digestEntries) Less(i, j int) bool {
|
||||
if d[i].val != d[j].val {
|
||||
return d[i].val < d[j].val
|
||||
}
|
||||
return d[i].alg < d[j].alg
|
||||
}
|
||||
|
||||
func (d digestEntries) Swap(i, j int) {
|
||||
d[i], d[j] = d[j], d[i]
|
||||
}
|
||||
34
vendor/github.com/docker/distribution/reference/helpers_deprecated.go
generated
vendored
Normal file
34
vendor/github.com/docker/distribution/reference/helpers_deprecated.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package reference
|
||||
|
||||
import "github.com/distribution/reference"
|
||||
|
||||
// IsNameOnly returns true if reference only contains a repo name.
|
||||
//
|
||||
// Deprecated: use [reference.IsNameOnly].
|
||||
func IsNameOnly(ref reference.Named) bool {
|
||||
return reference.IsNameOnly(ref)
|
||||
}
|
||||
|
||||
// FamiliarName returns the familiar name string
|
||||
// for the given named, familiarizing if needed.
|
||||
//
|
||||
// Deprecated: use [reference.FamiliarName].
|
||||
func FamiliarName(ref reference.Named) string {
|
||||
return reference.FamiliarName(ref)
|
||||
}
|
||||
|
||||
// FamiliarString returns the familiar string representation
|
||||
// for the given reference, familiarizing if needed.
|
||||
//
|
||||
// Deprecated: use [reference.FamiliarString].
|
||||
func FamiliarString(ref reference.Reference) string {
|
||||
return reference.FamiliarString(ref)
|
||||
}
|
||||
|
||||
// FamiliarMatch reports whether ref matches the specified pattern.
|
||||
// See [path.Match] for supported patterns.
|
||||
//
|
||||
// Deprecated: use [reference.FamiliarMatch].
|
||||
func FamiliarMatch(pattern string, ref reference.Reference) (bool, error) {
|
||||
return reference.FamiliarMatch(pattern, ref)
|
||||
}
|
||||
92
vendor/github.com/docker/distribution/reference/normalize_deprecated.go
generated
vendored
Normal file
92
vendor/github.com/docker/distribution/reference/normalize_deprecated.go
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
package reference
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/go-digest/digestset"
|
||||
)
|
||||
|
||||
// ParseNormalizedNamed parses a string into a named reference
|
||||
// transforming a familiar name from Docker UI to a fully
|
||||
// qualified reference. If the value may be an identifier
|
||||
// use ParseAnyReference.
|
||||
//
|
||||
// Deprecated: use [reference.ParseNormalizedNamed].
|
||||
func ParseNormalizedNamed(s string) (reference.Named, error) {
|
||||
return reference.ParseNormalizedNamed(s)
|
||||
}
|
||||
|
||||
// ParseDockerRef normalizes the image reference following the docker convention,
|
||||
// which allows for references to contain both a tag and a digest.
|
||||
//
|
||||
// Deprecated: use [reference.ParseDockerRef].
|
||||
func ParseDockerRef(ref string) (reference.Named, error) {
|
||||
return reference.ParseDockerRef(ref)
|
||||
}
|
||||
|
||||
// TagNameOnly adds the default tag "latest" to a reference if it only has
|
||||
// a repo name.
|
||||
//
|
||||
// Deprecated: use [reference.TagNameOnly].
|
||||
func TagNameOnly(ref reference.Named) reference.Named {
|
||||
return reference.TagNameOnly(ref)
|
||||
}
|
||||
|
||||
// ParseAnyReference parses a reference string as a possible identifier,
|
||||
// full digest, or familiar name.
|
||||
//
|
||||
// Deprecated: use [reference.ParseAnyReference].
|
||||
func ParseAnyReference(ref string) (reference.Reference, error) {
|
||||
return reference.ParseAnyReference(ref)
|
||||
}
|
||||
|
||||
// Functions and types below have been removed in distribution v3 and
|
||||
// have not been ported to github.com/distribution/reference. See
|
||||
// https://github.com/distribution/distribution/pull/3774
|
||||
|
||||
var (
|
||||
// ShortIdentifierRegexp is the format used to represent a prefix
|
||||
// of an identifier. A prefix may be used to match a sha256 identifier
|
||||
// within a list of trusted identifiers.
|
||||
//
|
||||
// Deprecated: support for short-identifiers is deprecated, and will be removed in v3.
|
||||
ShortIdentifierRegexp = regexp.MustCompile(shortIdentifier)
|
||||
|
||||
shortIdentifier = `([a-f0-9]{6,64})`
|
||||
|
||||
// anchoredShortIdentifierRegexp is used to check if a value
|
||||
// is a possible identifier prefix, anchored at start and end
|
||||
// of string.
|
||||
anchoredShortIdentifierRegexp = regexp.MustCompile(`^` + shortIdentifier + `$`)
|
||||
)
|
||||
|
||||
type digestReference digest.Digest
|
||||
|
||||
func (d digestReference) String() string {
|
||||
return digest.Digest(d).String()
|
||||
}
|
||||
|
||||
func (d digestReference) Digest() digest.Digest {
|
||||
return digest.Digest(d)
|
||||
}
|
||||
|
||||
// ParseAnyReferenceWithSet parses a reference string as a possible short
|
||||
// identifier to be matched in a digest set, a full digest, or familiar name.
|
||||
//
|
||||
// Deprecated: support for short-identifiers is deprecated, and will be removed in v3.
|
||||
func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) {
|
||||
if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok {
|
||||
dgst, err := ds.Lookup(ref)
|
||||
if err == nil {
|
||||
return digestReference(dgst), nil
|
||||
}
|
||||
} else {
|
||||
if dgst, err := digest.Parse(ref); err == nil {
|
||||
return digestReference(dgst), nil
|
||||
}
|
||||
}
|
||||
|
||||
return reference.ParseNormalizedNamed(ref)
|
||||
}
|
||||
172
vendor/github.com/docker/distribution/reference/reference_deprecated.go
generated
vendored
Normal file
172
vendor/github.com/docker/distribution/reference/reference_deprecated.go
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
// Package reference is deprecated, and has moved to github.com/distribution/reference.
|
||||
//
|
||||
// Deprecated: use github.com/distribution/reference instead.
|
||||
package reference
|
||||
|
||||
import (
|
||||
"github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
const (
|
||||
// NameTotalLengthMax is the maximum total number of characters in a repository name.
|
||||
//
|
||||
// Deprecated: use [reference.NameTotalLengthMax].
|
||||
NameTotalLengthMax = reference.NameTotalLengthMax
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.
|
||||
//
|
||||
// Deprecated: use [reference.ErrReferenceInvalidFormat].
|
||||
ErrReferenceInvalidFormat = reference.ErrReferenceInvalidFormat
|
||||
|
||||
// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.
|
||||
//
|
||||
// Deprecated: use [reference.ErrTagInvalidFormat].
|
||||
ErrTagInvalidFormat = reference.ErrTagInvalidFormat
|
||||
|
||||
// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.
|
||||
//
|
||||
// Deprecated: use [reference.ErrDigestInvalidFormat].
|
||||
ErrDigestInvalidFormat = reference.ErrDigestInvalidFormat
|
||||
|
||||
// ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.
|
||||
//
|
||||
// Deprecated: use [reference.ErrNameContainsUppercase].
|
||||
ErrNameContainsUppercase = reference.ErrNameContainsUppercase
|
||||
|
||||
// ErrNameEmpty is returned for empty, invalid repository names.
|
||||
//
|
||||
// Deprecated: use [reference.ErrNameEmpty].
|
||||
ErrNameEmpty = reference.ErrNameEmpty
|
||||
|
||||
// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
|
||||
//
|
||||
// Deprecated: use [reference.ErrNameTooLong].
|
||||
ErrNameTooLong = reference.ErrNameTooLong
|
||||
|
||||
// ErrNameNotCanonical is returned when a name is not canonical.
|
||||
//
|
||||
// Deprecated: use [reference.ErrNameNotCanonical].
|
||||
ErrNameNotCanonical = reference.ErrNameNotCanonical
|
||||
)
|
||||
|
||||
// Reference is an opaque object reference identifier that may include
|
||||
// modifiers such as a hostname, name, tag, and digest.
|
||||
//
|
||||
// Deprecated: use [reference.Reference].
|
||||
type Reference = reference.Reference
|
||||
|
||||
// Field provides a wrapper type for resolving correct reference types when
|
||||
// working with encoding.
|
||||
//
|
||||
// Deprecated: use [reference.Field].
|
||||
type Field = reference.Field
|
||||
|
||||
// AsField wraps a reference in a Field for encoding.
|
||||
//
|
||||
// Deprecated: use [reference.AsField].
|
||||
func AsField(ref reference.Reference) reference.Field {
|
||||
return reference.AsField(ref)
|
||||
}
|
||||
|
||||
// Named is an object with a full name
|
||||
//
|
||||
// Deprecated: use [reference.Named].
|
||||
type Named = reference.Named
|
||||
|
||||
// Tagged is an object which has a tag
|
||||
//
|
||||
// Deprecated: use [reference.Tagged].
|
||||
type Tagged = reference.Tagged
|
||||
|
||||
// NamedTagged is an object including a name and tag.
|
||||
//
|
||||
// Deprecated: use [reference.NamedTagged].
|
||||
type NamedTagged reference.NamedTagged
|
||||
|
||||
// Digested is an object which has a digest
|
||||
// in which it can be referenced by
|
||||
//
|
||||
// Deprecated: use [reference.Digested].
|
||||
type Digested reference.Digested
|
||||
|
||||
// Canonical reference is an object with a fully unique
|
||||
// name including a name with domain and digest
|
||||
//
|
||||
// Deprecated: use [reference.Canonical].
|
||||
type Canonical reference.Canonical
|
||||
|
||||
// Domain returns the domain part of the [Named] reference.
|
||||
//
|
||||
// Deprecated: use [reference.Domain].
|
||||
func Domain(named reference.Named) string {
|
||||
return reference.Domain(named)
|
||||
}
|
||||
|
||||
// Path returns the name without the domain part of the [Named] reference.
|
||||
//
|
||||
// Deprecated: use [reference.Path].
|
||||
func Path(named reference.Named) (name string) {
|
||||
return reference.Path(named)
|
||||
}
|
||||
|
||||
// SplitHostname splits a named reference into a
|
||||
// hostname and name string. If no valid hostname is
|
||||
// found, the hostname is empty and the full value
|
||||
// is returned as name
|
||||
//
|
||||
// Deprecated: Use [reference.Domain] or [reference.Path].
|
||||
func SplitHostname(named reference.Named) (string, string) {
|
||||
return reference.SplitHostname(named)
|
||||
}
|
||||
|
||||
// Parse parses s and returns a syntactically valid Reference.
|
||||
// If an error was encountered it is returned, along with a nil Reference.
|
||||
//
|
||||
// Deprecated: use [reference.Parse].
|
||||
func Parse(s string) (reference.Reference, error) {
|
||||
return reference.Parse(s)
|
||||
}
|
||||
|
||||
// ParseNamed parses s and returns a syntactically valid reference implementing
|
||||
// the Named interface. The reference must have a name and be in the canonical
|
||||
// form, otherwise an error is returned.
|
||||
// If an error was encountered it is returned, along with a nil Reference.
|
||||
//
|
||||
// Deprecated: use [reference.ParseNamed].
|
||||
func ParseNamed(s string) (reference.Named, error) {
|
||||
return reference.ParseNamed(s)
|
||||
}
|
||||
|
||||
// WithName returns a named object representing the given string. If the input
|
||||
// is invalid ErrReferenceInvalidFormat will be returned.
|
||||
//
|
||||
// Deprecated: use [reference.WithName].
|
||||
func WithName(name string) (reference.Named, error) {
|
||||
return reference.WithName(name)
|
||||
}
|
||||
|
||||
// WithTag combines the name from "name" and the tag from "tag" to form a
|
||||
// reference incorporating both the name and the tag.
|
||||
//
|
||||
// Deprecated: use [reference.WithTag].
|
||||
func WithTag(name reference.Named, tag string) (reference.NamedTagged, error) {
|
||||
return reference.WithTag(name, tag)
|
||||
}
|
||||
|
||||
// WithDigest combines the name from "name" and the digest from "digest" to form
|
||||
// a reference incorporating both the name and the digest.
|
||||
//
|
||||
// Deprecated: use [reference.WithDigest].
|
||||
func WithDigest(name reference.Named, digest digest.Digest) (reference.Canonical, error) {
|
||||
return reference.WithDigest(name, digest)
|
||||
}
|
||||
|
||||
// TrimNamed removes any tag or digest from the named reference.
|
||||
//
|
||||
// Deprecated: use [reference.TrimNamed].
|
||||
func TrimNamed(ref reference.Named) reference.Named {
|
||||
return reference.TrimNamed(ref)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user