Upgrade k8s package verison (#5358)

* upgrade k8s package version

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

* Script upgrade and code formatting.

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
hongzhouzi
2022-11-15 14:56:38 +08:00
committed by GitHub
parent 5f91c1663a
commit 44167aa47a
3106 changed files with 321340 additions and 172080 deletions

View File

@@ -0,0 +1,213 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package oras
import (
"bytes"
"context"
"fmt"
"sync"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/remotes"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/pkg/target"
)
// Copy copy a ref from one target.Target to a ref in another target.Target. If toRef is blank, reuses fromRef
// Returns the root
// Descriptor of the copied item. Can use the root to retrieve child elements from target.Target.
func Copy(ctx context.Context, from target.Target, fromRef string, to target.Target, toRef string, opts ...CopyOpt) (ocispec.Descriptor, error) {
if from == nil {
return ocispec.Descriptor{}, ErrFromTargetUndefined
}
if to == nil {
return ocispec.Descriptor{}, ErrToTargetUndefined
}
// blank toRef
if toRef == "" {
toRef = fromRef
}
opt := copyOptsDefaults()
for _, o := range opts {
if err := o(opt); err != nil {
return ocispec.Descriptor{}, err
}
}
if from == nil {
return ocispec.Descriptor{}, ErrFromResolverUndefined
}
if to == nil {
return ocispec.Descriptor{}, ErrToResolverUndefined
}
// for the "from", we resolve the ref, then use resolver.Fetcher to fetch the various content blobs
// for the "to", we simply use resolver.Pusher to push the various content blobs
_, desc, err := from.Resolve(ctx, fromRef)
if err != nil {
return ocispec.Descriptor{}, err
}
fetcher, err := from.Fetcher(ctx, fromRef)
if err != nil {
return ocispec.Descriptor{}, err
}
// construct the reference we send to the pusher using the digest, so it knows what the root is
pushRef := fmt.Sprintf("%s@%s", toRef, desc.Digest.String())
pusher, err := to.Pusher(ctx, pushRef)
if err != nil {
return ocispec.Descriptor{}, err
}
if err := transferContent(ctx, desc, fetcher, pusher, opt); err != nil {
return ocispec.Descriptor{}, err
}
return desc, nil
}
func transferContent(ctx context.Context, desc ocispec.Descriptor, fetcher remotes.Fetcher, pusher remotes.Pusher, opts *copyOpts) error {
var descriptors, manifests []ocispec.Descriptor
lock := &sync.Mutex{}
picker := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
if isAllowedMediaType(desc.MediaType, opts.allowedMediaTypes...) {
if opts.filterName(desc) {
lock.Lock()
defer lock.Unlock()
descriptors = append(descriptors, desc)
}
return nil, nil
}
return nil, nil
})
// we use a hybrid store - a cache wrapping the underlying pusher - for two reasons:
// 1. so that we can cache the manifests as pushing them, then retrieve them later to push in reverse order after the blobs
// 2. so that we can retrieve them to analyze and find children in the Dispatch routine
store := opts.contentProvideIngesterPusherFetcher
if store == nil {
store = newHybridStoreFromPusher(pusher, opts.cachedMediaTypes, true)
}
// fetchHandler pushes to the *store*, which may or may not cache it
baseFetchHandler := func(p remotes.Pusher, f remotes.Fetcher) images.HandlerFunc {
return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
cw, err := p.Push(ctx, desc)
if err != nil {
if !errdefs.IsAlreadyExists(err) {
return nil, err
}
return nil, nil
}
defer cw.Close()
rc, err := f.Fetch(ctx, desc)
if err != nil {
return nil, err
}
defer rc.Close()
return nil, content.Copy(ctx, cw, rc, desc.Size, desc.Digest)
})
}
// track all of our manifests that will be cached
fetchHandler := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
if isAllowedMediaType(desc.MediaType, opts.cachedMediaTypes...) {
lock.Lock()
defer lock.Unlock()
manifests = append(manifests, desc)
}
return baseFetchHandler(store, fetcher)(ctx, desc)
})
handlers := []images.Handler{
filterHandler(opts, opts.allowedMediaTypes...),
}
handlers = append(handlers, opts.baseHandlers...)
handlers = append(handlers,
fetchHandler,
picker,
images.ChildrenHandler(&ProviderWrapper{Fetcher: store}),
)
handlers = append(handlers, opts.callbackHandlers...)
if err := opts.dispatch(ctx, images.Handlers(handlers...), nil, desc); err != nil {
return err
}
// we cached all of the manifests, so push those out
// Iterate in reverse order as seen, parent always uploaded after child
for i := len(manifests) - 1; i >= 0; i-- {
_, err := baseFetchHandler(pusher, store)(ctx, manifests[i])
if err != nil {
return err
}
}
// if the option to request the root manifest was passed, accommodate it
if opts.saveManifest != nil && len(manifests) > 0 {
rc, err := store.Fetch(ctx, manifests[0])
if err != nil {
return fmt.Errorf("could not get root manifest to save based on CopyOpt: %v", err)
}
defer rc.Close()
buf := new(bytes.Buffer)
if _, err := buf.ReadFrom(rc); err != nil {
return fmt.Errorf("unable to read data for root manifest to save based on CopyOpt: %v", err)
}
// get the root manifest from the store
opts.saveManifest(buf.Bytes())
}
// if the option to request the layers was passed, accommodate it
if opts.saveLayers != nil && len(descriptors) > 0 {
opts.saveLayers(descriptors)
}
return nil
}
func filterHandler(opts *copyOpts, allowedMediaTypes ...string) images.HandlerFunc {
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
switch {
case isAllowedMediaType(desc.MediaType, ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex):
return nil, nil
case isAllowedMediaType(desc.MediaType, allowedMediaTypes...):
if opts.filterName(desc) {
return nil, nil
}
log.G(ctx).Warnf("blob no name: %v", desc.Digest)
default:
log.G(ctx).Warnf("unknown type: %v", desc.MediaType)
}
return nil, images.ErrStopHandler
}
}
func isAllowedMediaType(mediaType string, allowedMediaTypes ...string) bool {
if len(allowedMediaTypes) == 0 {
return true
}
for _, allowedMediaType := range allowedMediaTypes {
if mediaType == allowedMediaType {
return true
}
}
return false
}

View File

@@ -0,0 +1,42 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package oras
import (
"errors"
"fmt"
)
// Common errors
var (
ErrResolverUndefined = errors.New("resolver undefined")
ErrFromResolverUndefined = errors.New("from target resolver undefined")
ErrToResolverUndefined = errors.New("to target resolver undefined")
ErrFromTargetUndefined = errors.New("from target undefined")
ErrToTargetUndefined = errors.New("from target undefined")
)
// Path validation related errors
var (
ErrDirtyPath = errors.New("dirty path")
ErrPathNotSlashSeparated = errors.New("path not slash separated")
ErrAbsolutePathDisallowed = errors.New("absolute path disallowed")
ErrPathTraversalDisallowed = errors.New("path traversal disallowed")
)
// ErrStopProcessing is used to stop processing an oras operation.
// This error only makes sense in sequential pulling operation.
var ErrStopProcessing = fmt.Errorf("stop processing")

View File

@@ -0,0 +1,254 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package oras
import (
"context"
"fmt"
"io"
"path/filepath"
"strings"
"sync"
"github.com/containerd/containerd/images"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"golang.org/x/sync/semaphore"
orascontent "oras.land/oras-go/pkg/content"
)
func copyOptsDefaults() *copyOpts {
return &copyOpts{
dispatch: images.Dispatch,
filterName: filterName,
cachedMediaTypes: []string{ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex},
validateName: ValidateNameAsPath,
}
}
type CopyOpt func(o *copyOpts) error
type copyOpts struct {
allowedMediaTypes []string
dispatch func(context.Context, images.Handler, *semaphore.Weighted, ...ocispec.Descriptor) error
baseHandlers []images.Handler
callbackHandlers []images.Handler
contentProvideIngesterPusherFetcher orascontent.Store
filterName func(ocispec.Descriptor) bool
cachedMediaTypes []string
saveManifest func([]byte)
saveLayers func([]ocispec.Descriptor)
validateName func(desc ocispec.Descriptor) error
userAgent string
}
// ValidateNameAsPath validates name in the descriptor as file path in order
// to generate good packages intended to be pulled using the FileStore or
// the oras cli.
// For cross-platform considerations, only unix paths are accepted.
func ValidateNameAsPath(desc ocispec.Descriptor) error {
// no empty name
path, ok := orascontent.ResolveName(desc)
if !ok || path == "" {
return orascontent.ErrNoName
}
// path should be clean
if target := filepath.ToSlash(filepath.Clean(path)); target != path {
return errors.Wrap(ErrDirtyPath, path)
}
// path should be slash-separated
if strings.Contains(path, "\\") {
return errors.Wrap(ErrPathNotSlashSeparated, path)
}
// disallow absolute path: covers unix and windows format
if strings.HasPrefix(path, "/") {
return errors.Wrap(ErrAbsolutePathDisallowed, path)
}
if len(path) > 2 {
c := path[0]
if path[1] == ':' && path[2] == '/' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
return errors.Wrap(ErrAbsolutePathDisallowed, path)
}
}
// disallow path traversal
if strings.HasPrefix(path, "../") || path == ".." {
return errors.Wrap(ErrPathTraversalDisallowed, path)
}
return nil
}
// dispatchBFS behaves the same as images.Dispatch() but in sequence with breath-first search.
func dispatchBFS(ctx context.Context, handler images.Handler, weighted *semaphore.Weighted, descs ...ocispec.Descriptor) error {
for i := 0; i < len(descs); i++ {
desc := descs[i]
children, err := handler.Handle(ctx, desc)
if err != nil {
switch err := errors.Cause(err); err {
case images.ErrSkipDesc:
continue // don't traverse the children.
case ErrStopProcessing:
return nil
}
return err
}
descs = append(descs, children...)
}
return nil
}
func filterName(desc ocispec.Descriptor) bool {
// needs to be filled in
return true
}
// WithAdditionalCachedMediaTypes adds media types normally cached in memory when pulling.
// This does not replace the default media types, but appends to them
func WithAdditionalCachedMediaTypes(cachedMediaTypes ...string) CopyOpt {
return func(o *copyOpts) error {
o.cachedMediaTypes = append(o.cachedMediaTypes, cachedMediaTypes...)
return nil
}
}
// WithAllowedMediaType sets the allowed media types
func WithAllowedMediaType(allowedMediaTypes ...string) CopyOpt {
return func(o *copyOpts) error {
o.allowedMediaTypes = append(o.allowedMediaTypes, allowedMediaTypes...)
return nil
}
}
// WithAllowedMediaTypes sets the allowed media types
func WithAllowedMediaTypes(allowedMediaTypes []string) CopyOpt {
return func(o *copyOpts) error {
o.allowedMediaTypes = append(o.allowedMediaTypes, allowedMediaTypes...)
return nil
}
}
// WithPullByBFS opt to pull in sequence with breath-first search
func WithPullByBFS(o *copyOpts) error {
o.dispatch = dispatchBFS
return nil
}
// WithPullBaseHandler provides base handlers, which will be called before
// any pull specific handlers.
func WithPullBaseHandler(handlers ...images.Handler) CopyOpt {
return func(o *copyOpts) error {
o.baseHandlers = append(o.baseHandlers, handlers...)
return nil
}
}
// WithPullCallbackHandler provides callback handlers, which will be called after
// any pull specific handlers.
func WithPullCallbackHandler(handlers ...images.Handler) CopyOpt {
return func(o *copyOpts) error {
o.callbackHandlers = append(o.callbackHandlers, handlers...)
return nil
}
}
// WithContentProvideIngester opt to the provided Provider and Ingester
// for file system I/O, including caches.
func WithContentStore(store orascontent.Store) CopyOpt {
return func(o *copyOpts) error {
o.contentProvideIngesterPusherFetcher = store
return nil
}
}
// WithPullEmptyNameAllowed allows pulling blobs with empty name.
func WithPullEmptyNameAllowed() CopyOpt {
return func(o *copyOpts) error {
o.filterName = func(ocispec.Descriptor) bool {
return true
}
return nil
}
}
// WithPullStatusTrack report results to stdout
func WithPullStatusTrack(writer io.Writer) CopyOpt {
return WithPullCallbackHandler(pullStatusTrack(writer))
}
func pullStatusTrack(writer io.Writer) images.Handler {
var printLock sync.Mutex
return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
if name, ok := orascontent.ResolveName(desc); ok {
digestString := desc.Digest.String()
if err := desc.Digest.Validate(); err == nil {
if algo := desc.Digest.Algorithm(); algo == digest.SHA256 {
digestString = desc.Digest.Encoded()[:12]
}
}
printLock.Lock()
defer printLock.Unlock()
fmt.Fprintln(writer, "Downloaded", digestString, name)
}
return nil, nil
})
}
// WithNameValidation validates the image title in the descriptor.
// Pass nil to disable name validation.
func WithNameValidation(validate func(desc ocispec.Descriptor) error) CopyOpt {
return func(o *copyOpts) error {
o.validateName = validate
return nil
}
}
// WithUserAgent set the user agent string in http communications
func WithUserAgent(agent string) CopyOpt {
return func(o *copyOpts) error {
o.userAgent = agent
return nil
}
}
// WithLayerDescriptors passes the slice of Descriptors for layers to the
// provided func. If the passed parameter is nil, returns an error.
func WithLayerDescriptors(save func([]ocispec.Descriptor)) CopyOpt {
return func(o *copyOpts) error {
if save == nil {
return errors.New("layers save func must be non-nil")
}
o.saveLayers = save
return nil
}
}
// WithRootManifest passes the root manifest for the artifacts to the provided
// func. If the passed parameter is nil, returns an error.
func WithRootManifest(save func(b []byte)) CopyOpt {
return func(o *copyOpts) error {
if save == nil {
return errors.New("manifest save func must be non-nil")
}
o.saveManifest = save
return nil
}
}

View File

@@ -0,0 +1,79 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package oras
import (
"context"
"errors"
"io"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/remotes"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// ProviderWrapper wraps a remote.Fetcher to make a content.Provider, which is useful for things
type ProviderWrapper struct {
Fetcher remotes.Fetcher
}
func (p *ProviderWrapper) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
if p.Fetcher == nil {
return nil, errors.New("no Fetcher provided")
}
return &fetcherReaderAt{
ctx: ctx,
fetcher: p.Fetcher,
desc: desc,
offset: 0,
}, nil
}
type fetcherReaderAt struct {
ctx context.Context
fetcher remotes.Fetcher
desc ocispec.Descriptor
rc io.ReadCloser
offset int64
}
func (f *fetcherReaderAt) Close() error {
if f.rc == nil {
return nil
}
return f.rc.Close()
}
func (f *fetcherReaderAt) Size() int64 {
return f.desc.Size
}
func (f *fetcherReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
// if we do not have a readcloser, get it
if f.rc == nil || f.offset != off {
rc, err := f.fetcher.Fetch(f.ctx, f.desc)
if err != nil {
return 0, err
}
f.rc = rc
}
n, err = io.ReadFull(f.rc, p)
if err != nil {
return n, err
}
f.offset += int64(n)
return n, err
}

View File

@@ -0,0 +1,213 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package oras
import (
"context"
"io"
"io/ioutil"
"time"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/remotes"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/sync/errgroup"
orascontent "oras.land/oras-go/pkg/content"
)
type hybridStore struct {
cache *orascontent.Memory
cachedMediaTypes []string
cacheOnly bool
provider content.Provider
ingester content.Ingester
}
func newHybridStoreFromPusher(pusher remotes.Pusher, cachedMediaTypes []string, cacheOnly bool) *hybridStore {
// construct an ingester from a pusher
ingester := pusherIngester{
pusher: pusher,
}
return &hybridStore{
cache: orascontent.NewMemory(),
cachedMediaTypes: cachedMediaTypes,
ingester: ingester,
cacheOnly: cacheOnly,
}
}
func (s *hybridStore) Set(desc ocispec.Descriptor, content []byte) {
s.cache.Set(desc, content)
}
func (s *hybridStore) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.ReadCloser, error) {
reader, err := s.cache.Fetch(ctx, desc)
if err == nil {
return reader, err
}
if s.provider != nil {
rat, err := s.provider.ReaderAt(ctx, desc)
return ioutil.NopCloser(orascontent.NewReaderAtWrapper(rat)), err
}
return nil, err
}
func (s *hybridStore) Push(ctx context.Context, desc ocispec.Descriptor) (content.Writer, error) {
return s.Writer(ctx, content.WithDescriptor(desc))
}
// Writer begins or resumes the active writer identified by desc
func (s *hybridStore) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) {
var wOpts content.WriterOpts
for _, opt := range opts {
if err := opt(&wOpts); err != nil {
return nil, err
}
}
if isAllowedMediaType(wOpts.Desc.MediaType, s.cachedMediaTypes...) || s.ingester == nil {
pusher, err := s.cache.Pusher(ctx, "")
if err != nil {
return nil, err
}
cacheWriter, err := pusher.Push(ctx, wOpts.Desc)
if err != nil {
return nil, err
}
// if we cache it only, do not pass it through
if s.cacheOnly {
return cacheWriter, nil
}
ingesterWriter, err := s.ingester.Writer(ctx, opts...)
switch {
case err == nil:
return newTeeWriter(wOpts.Desc, cacheWriter, ingesterWriter), nil
case errdefs.IsAlreadyExists(err):
return cacheWriter, nil
}
return nil, err
}
return s.ingester.Writer(ctx, opts...)
}
// teeWriter tees the content to one or more content.Writer
type teeWriter struct {
writers []content.Writer
digester digest.Digester
status content.Status
}
func newTeeWriter(desc ocispec.Descriptor, writers ...content.Writer) *teeWriter {
now := time.Now()
return &teeWriter{
writers: writers,
digester: digest.Canonical.Digester(),
status: content.Status{
Total: desc.Size,
StartedAt: now,
UpdatedAt: now,
},
}
}
func (t *teeWriter) Close() error {
g := new(errgroup.Group)
for _, w := range t.writers {
w := w // closure issues, see https://golang.org/doc/faq#closures_and_goroutines
g.Go(func() error {
return w.Close()
})
}
return g.Wait()
}
func (t *teeWriter) Write(p []byte) (n int, err error) {
g := new(errgroup.Group)
for _, w := range t.writers {
w := w // closure issues, see https://golang.org/doc/faq#closures_and_goroutines
g.Go(func() error {
n, err := w.Write(p[:])
if err != nil {
return err
}
if n != len(p) {
return io.ErrShortWrite
}
return nil
})
}
err = g.Wait()
n = len(p)
if err != nil {
return n, err
}
_, _ = t.digester.Hash().Write(p[:n])
t.status.Offset += int64(len(p))
t.status.UpdatedAt = time.Now()
return n, nil
}
// Digest may return empty digest or panics until committed.
func (t *teeWriter) Digest() digest.Digest {
return t.digester.Digest()
}
func (t *teeWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
g := new(errgroup.Group)
for _, w := range t.writers {
w := w // closure issues, see https://golang.org/doc/faq#closures_and_goroutines
g.Go(func() error {
return w.Commit(ctx, size, expected, opts...)
})
}
return g.Wait()
}
// Status returns the current state of write
func (t *teeWriter) Status() (content.Status, error) {
return t.status, nil
}
// Truncate updates the size of the target blob
func (t *teeWriter) Truncate(size int64) error {
g := new(errgroup.Group)
for _, w := range t.writers {
w := w // closure issues, see https://golang.org/doc/faq#closures_and_goroutines
g.Go(func() error {
return w.Truncate(size)
})
}
return g.Wait()
}
// pusherIngester simple wrapper to get an ingester from a pusher
type pusherIngester struct {
pusher remotes.Pusher
}
func (p pusherIngester) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) {
var wOpts content.WriterOpts
for _, opt := range opts {
if err := opt(&wOpts); err != nil {
return nil, err
}
}
return p.pusher.Push(ctx, wOpts.Desc)
}