Unverified Commit a8382564 authored by Chris Kim's avatar Chris Kim Committed by GitHub

[release-1.20] Bump Kubernetes to v1.20.13-k3s1 (#4532)

* Update to v1.20.13 * Bump sonobuoy and golang * Change test timeout to 60m * Bump containerd to v1.14.12-k3s1 Signed-off-by: 's avatarChris Kim <oats87g@gmail.com>
parent 2f3d398c
ARG GOLANG=golang:1.15.14-alpine3.13 ARG GOLANG=golang:1.15.15-alpine3.13
FROM ${GOLANG} FROM ${GOLANG}
ARG http_proxy=$http_proxy ARG http_proxy=$http_proxy
......
ARG GOLANG=golang:1.15.14-alpine3.13 ARG GOLANG=golang:1.15.15-alpine3.13
FROM ${GOLANG} FROM ${GOLANG}
RUN apk -U --no-cache add bash git gcc musl-dev docker curl jq coreutils python3 openssl py3-pip RUN apk -U --no-cache add bash git gcc musl-dev docker curl jq coreutils python3 openssl py3-pip
ENV SONOBUOY_VERSION 0.20.0 ENV SONOBUOY_VERSION 0.55.0
RUN OS=linux; \ RUN OS=linux; \
ARCH=$(go env GOARCH); \ ARCH=$(go env GOARCH); \
......
ARG GOLANG=golang:1.15.14-alpine3.13 ARG GOLANG=golang:1.15.15-alpine3.13
FROM ${GOLANG} FROM ${GOLANG}
RUN apk -U --no-cache add bash jq RUN apk -U --no-cache add bash jq
......
...@@ -9,7 +9,7 @@ replace ( ...@@ -9,7 +9,7 @@ replace (
github.com/containerd/btrfs => github.com/containerd/btrfs v1.0.0 github.com/containerd/btrfs => github.com/containerd/btrfs v1.0.0
github.com/containerd/cgroups => github.com/containerd/cgroups v1.0.1 github.com/containerd/cgroups => github.com/containerd/cgroups v1.0.1
github.com/containerd/console => github.com/containerd/console v1.0.2 github.com/containerd/console => github.com/containerd/console v1.0.2
github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.11-k3s1 // k3s-release/1.4 github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.12-k3s1 // k3s-release/1.4
github.com/containerd/continuity => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1 github.com/containerd/continuity => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1
github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.7 // k3s-release/1.4 github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.7 // k3s-release/1.4
github.com/containerd/fifo => github.com/containerd/fifo v1.0.0 github.com/containerd/fifo => github.com/containerd/fifo v1.0.0
...@@ -37,34 +37,34 @@ replace ( ...@@ -37,34 +37,34 @@ replace (
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
google.golang.org/grpc => google.golang.org/grpc v1.27.1 google.golang.org/grpc => google.golang.org/grpc v1.27.1
gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.2.2 gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.2.2
k8s.io/api => github.com/k3s-io/kubernetes/staging/src/k8s.io/api v1.20.12-k3s1 k8s.io/api => github.com/k3s-io/kubernetes/staging/src/k8s.io/api v1.20.13-k3s1
k8s.io/apiextensions-apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.20.12-k3s1 k8s.io/apiextensions-apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.20.13-k3s1
k8s.io/apimachinery => github.com/k3s-io/kubernetes/staging/src/k8s.io/apimachinery v1.20.12-k3s1 k8s.io/apimachinery => github.com/k3s-io/kubernetes/staging/src/k8s.io/apimachinery v1.20.13-k3s1
k8s.io/apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/apiserver v1.20.12-k3s1 k8s.io/apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/apiserver v1.20.13-k3s1
k8s.io/cli-runtime => github.com/k3s-io/kubernetes/staging/src/k8s.io/cli-runtime v1.20.12-k3s1 k8s.io/cli-runtime => github.com/k3s-io/kubernetes/staging/src/k8s.io/cli-runtime v1.20.13-k3s1
k8s.io/client-go => github.com/k3s-io/kubernetes/staging/src/k8s.io/client-go v1.20.12-k3s1 k8s.io/client-go => github.com/k3s-io/kubernetes/staging/src/k8s.io/client-go v1.20.13-k3s1
k8s.io/cloud-provider => github.com/k3s-io/kubernetes/staging/src/k8s.io/cloud-provider v1.20.12-k3s1 k8s.io/cloud-provider => github.com/k3s-io/kubernetes/staging/src/k8s.io/cloud-provider v1.20.13-k3s1
k8s.io/cluster-bootstrap => github.com/k3s-io/kubernetes/staging/src/k8s.io/cluster-bootstrap v1.20.12-k3s1 k8s.io/cluster-bootstrap => github.com/k3s-io/kubernetes/staging/src/k8s.io/cluster-bootstrap v1.20.13-k3s1
k8s.io/code-generator => github.com/k3s-io/kubernetes/staging/src/k8s.io/code-generator v1.20.12-k3s1 k8s.io/code-generator => github.com/k3s-io/kubernetes/staging/src/k8s.io/code-generator v1.20.13-k3s1
k8s.io/component-base => github.com/k3s-io/kubernetes/staging/src/k8s.io/component-base v1.20.12-k3s1 k8s.io/component-base => github.com/k3s-io/kubernetes/staging/src/k8s.io/component-base v1.20.13-k3s1
k8s.io/component-helpers => github.com/k3s-io/kubernetes/staging/src/k8s.io/component-helpers v1.20.12-k3s1 k8s.io/component-helpers => github.com/k3s-io/kubernetes/staging/src/k8s.io/component-helpers v1.20.13-k3s1
k8s.io/controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/controller-manager v1.20.12-k3s1 k8s.io/controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/controller-manager v1.20.13-k3s1
k8s.io/cri-api => github.com/k3s-io/kubernetes/staging/src/k8s.io/cri-api v1.20.12-k3s1 k8s.io/cri-api => github.com/k3s-io/kubernetes/staging/src/k8s.io/cri-api v1.20.13-k3s1
k8s.io/csi-translation-lib => github.com/k3s-io/kubernetes/staging/src/k8s.io/csi-translation-lib v1.20.12-k3s1 k8s.io/csi-translation-lib => github.com/k3s-io/kubernetes/staging/src/k8s.io/csi-translation-lib v1.20.13-k3s1
k8s.io/kube-aggregator => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-aggregator v1.20.12-k3s1 k8s.io/kube-aggregator => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-aggregator v1.20.13-k3s1
k8s.io/kube-controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-controller-manager v1.20.12-k3s1 k8s.io/kube-controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-controller-manager v1.20.13-k3s1
k8s.io/kube-proxy => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-proxy v1.20.12-k3s1 k8s.io/kube-proxy => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-proxy v1.20.13-k3s1
k8s.io/kube-scheduler => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-scheduler v1.20.12-k3s1 k8s.io/kube-scheduler => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-scheduler v1.20.13-k3s1
k8s.io/kubectl => github.com/k3s-io/kubernetes/staging/src/k8s.io/kubectl v1.20.12-k3s1 k8s.io/kubectl => github.com/k3s-io/kubernetes/staging/src/k8s.io/kubectl v1.20.13-k3s1
k8s.io/kubelet => github.com/k3s-io/kubernetes/staging/src/k8s.io/kubelet v1.20.12-k3s1 k8s.io/kubelet => github.com/k3s-io/kubernetes/staging/src/k8s.io/kubelet v1.20.13-k3s1
k8s.io/kubernetes => github.com/k3s-io/kubernetes v1.20.12-k3s1 k8s.io/kubernetes => github.com/k3s-io/kubernetes v1.20.13-k3s1
k8s.io/legacy-cloud-providers => github.com/k3s-io/kubernetes/staging/src/k8s.io/legacy-cloud-providers v1.20.12-k3s1 k8s.io/legacy-cloud-providers => github.com/k3s-io/kubernetes/staging/src/k8s.io/legacy-cloud-providers v1.20.13-k3s1
k8s.io/metrics => github.com/k3s-io/kubernetes/staging/src/k8s.io/metrics v1.20.12-k3s1 k8s.io/metrics => github.com/k3s-io/kubernetes/staging/src/k8s.io/metrics v1.20.13-k3s1
k8s.io/mount-utils => github.com/k3s-io/kubernetes/staging/src/k8s.io/mount-utils v1.20.12-k3s1 k8s.io/mount-utils => github.com/k3s-io/kubernetes/staging/src/k8s.io/mount-utils v1.20.13-k3s1
k8s.io/node-api => github.com/k3s-io/kubernetes/staging/src/k8s.io/node-api v1.20.12-k3s1 k8s.io/node-api => github.com/k3s-io/kubernetes/staging/src/k8s.io/node-api v1.20.13-k3s1
k8s.io/sample-apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-apiserver v1.20.12-k3s1 k8s.io/sample-apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-apiserver v1.20.13-k3s1
k8s.io/sample-cli-plugin => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-cli-plugin v1.20.12-k3s1 k8s.io/sample-cli-plugin => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-cli-plugin v1.20.13-k3s1
k8s.io/sample-controller => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-controller v1.20.12-k3s1 k8s.io/sample-controller => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-controller v1.20.13-k3s1
mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34 mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34
) )
...@@ -130,7 +130,7 @@ require ( ...@@ -130,7 +130,7 @@ require (
k8s.io/cri-api v1.20.11 k8s.io/cri-api v1.20.11
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/kubectl v1.20.11 k8s.io/kubectl v1.20.11
k8s.io/kubernetes v1.20.12 k8s.io/kubernetes v1.20.13
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 k8s.io/utils v0.0.0-20201110183641-67b214c5f920
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
...@@ -240,7 +240,7 @@ sonobuoy-test() { ...@@ -240,7 +240,7 @@ sonobuoy-test() {
local sonobuoyPID=$! local sonobuoyPID=$!
local code=0 local code=0
time timeout --foreground 30m bash -c test-wait $sonobuoyPID || code=$? time timeout --foreground 60m bash -c test-wait $sonobuoyPID || code=$?
echo "Sonobuoy finished with code $code" echo "Sonobuoy finished with code $code"
retrieve-sonobuoy-logs retrieve-sonobuoy-logs
return $code return $code
......
...@@ -15,7 +15,7 @@ os: ...@@ -15,7 +15,7 @@ os:
- linux - linux
go: go:
- "1.16.8" - "1.16.10"
env: env:
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v1 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic GOPROXY=direct - TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v1 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic GOPROXY=direct
......
...@@ -77,7 +77,7 @@ Vagrant.configure("2") do |config| ...@@ -77,7 +77,7 @@ Vagrant.configure("2") do |config|
config.vm.provision "install-golang", type: "shell", run: "once" do |sh| config.vm.provision "install-golang", type: "shell", run: "once" do |sh|
sh.upload_path = "/tmp/vagrant-install-golang" sh.upload_path = "/tmp/vagrant-install-golang"
sh.env = { sh.env = {
'GO_VERSION': ENV['GO_VERSION'] || "1.16.8", 'GO_VERSION': ENV['GO_VERSION'] || "1.16.10",
} }
sh.inline = <<~SHELL sh.inline = <<~SHELL
#!/usr/bin/env bash #!/usr/bin/env bash
......
...@@ -19,6 +19,7 @@ package images ...@@ -19,6 +19,7 @@ package images
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"sort" "sort"
"time" "time"
...@@ -154,6 +155,10 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc ...@@ -154,6 +155,10 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc
return nil, err return nil, err
} }
if err := validateMediaType(p, desc.MediaType); err != nil {
return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest)
}
var manifest ocispec.Manifest var manifest ocispec.Manifest
if err := json.Unmarshal(p, &manifest); err != nil { if err := json.Unmarshal(p, &manifest); err != nil {
return nil, err return nil, err
...@@ -194,6 +199,10 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc ...@@ -194,6 +199,10 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc
return nil, err return nil, err
} }
if err := validateMediaType(p, desc.MediaType); err != nil {
return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest)
}
var idx ocispec.Index var idx ocispec.Index
if err := json.Unmarshal(p, &idx); err != nil { if err := json.Unmarshal(p, &idx); err != nil {
return nil, err return nil, err
...@@ -336,6 +345,10 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr ...@@ -336,6 +345,10 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr
return nil, err return nil, err
} }
if err := validateMediaType(p, desc.MediaType); err != nil {
return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest)
}
// TODO(stevvooe): We just assume oci manifest, for now. There may be // TODO(stevvooe): We just assume oci manifest, for now. There may be
// subtle differences from the docker version. // subtle differences from the docker version.
var manifest ocispec.Manifest var manifest ocispec.Manifest
...@@ -351,6 +364,10 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr ...@@ -351,6 +364,10 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr
return nil, err return nil, err
} }
if err := validateMediaType(p, desc.MediaType); err != nil {
return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest)
}
var index ocispec.Index var index ocispec.Index
if err := json.Unmarshal(p, &index); err != nil { if err := json.Unmarshal(p, &index); err != nil {
return nil, err return nil, err
...@@ -368,6 +385,44 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr ...@@ -368,6 +385,44 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr
return descs, nil return descs, nil
} }
// unknownDocument represents a manifest, manifest list, or index that has not
// yet been validated.
type unknownDocument struct {
MediaType string `json:"mediaType,omitempty"`
Config json.RawMessage `json:"config,omitempty"`
Layers json.RawMessage `json:"layers,omitempty"`
Manifests json.RawMessage `json:"manifests,omitempty"`
FSLayers json.RawMessage `json:"fsLayers,omitempty"` // schema 1
}
// validateMediaType returns an error if the byte slice is invalid JSON or if
// the media type identifies the blob as one format but it contains elements of
// another format.
func validateMediaType(b []byte, mt string) error {
var doc unknownDocument
if err := json.Unmarshal(b, &doc); err != nil {
return err
}
if len(doc.FSLayers) != 0 {
return fmt.Errorf("media-type: schema 1 not supported")
}
switch mt {
case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
if len(doc.Manifests) != 0 ||
doc.MediaType == MediaTypeDockerSchema2ManifestList ||
doc.MediaType == ocispec.MediaTypeImageIndex {
return fmt.Errorf("media-type: expected manifest but found index (%s)", mt)
}
case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
if len(doc.Config) != 0 || len(doc.Layers) != 0 ||
doc.MediaType == MediaTypeDockerSchema2Manifest ||
doc.MediaType == ocispec.MediaTypeImageManifest {
return fmt.Errorf("media-type: expected index but found manifest (%s)", mt)
}
}
return nil
}
// RootFS returns the unpacked diffids that make up and images rootfs. // RootFS returns the unpacked diffids that make up and images rootfs.
// //
// These are used to verify that a set of layers unpacked to the expected // These are used to verify that a set of layers unpacked to the expected
......
...@@ -60,6 +60,10 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R ...@@ -60,6 +60,10 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
log.G(ctx).WithError(err).Debug("failed to parse") log.G(ctx).WithError(err).Debug("failed to parse")
continue continue
} }
if u.Scheme != "http" && u.Scheme != "https" {
log.G(ctx).Debug("non-http(s) alternative url is unsupported")
continue
}
log.G(ctx).Debug("trying alternative url") log.G(ctx).Debug("trying alternative url")
// Try this first, parse it // Try this first, parse it
......
...@@ -256,6 +256,9 @@ func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor) ...@@ -256,6 +256,9 @@ func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor)
if err := json.Unmarshal(b, &m); err != nil { if err := json.Unmarshal(b, &m); err != nil {
return err return err
} }
if len(m.Manifests) != 0 || len(m.Layers) != 0 {
return errors.New("converter: expected schema1 document but found extra keys")
}
c.pulledManifest = &m c.pulledManifest = &m
return nil return nil
...@@ -472,8 +475,10 @@ type history struct { ...@@ -472,8 +475,10 @@ type history struct {
} }
type manifest struct { type manifest struct {
FSLayers []fsLayer `json:"fsLayers"` FSLayers []fsLayer `json:"fsLayers"`
History []history `json:"history"` History []history `json:"history"`
Layers json.RawMessage `json:"layers,omitempty"` // OCI manifest
Manifests json.RawMessage `json:"manifests,omitempty"` // OCI index
} }
type v1History struct { type v1History struct {
......
...@@ -23,7 +23,7 @@ var ( ...@@ -23,7 +23,7 @@ var (
Package = "github.com/containerd/containerd" Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time. // Version holds the complete version number. Filled in at linking time.
Version = "1.4.11+unknown" Version = "1.4.12+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build // Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time. // the program at linking time.
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"net" "net"
"net/http" "net/http"
"runtime" "runtime"
"sync"
"time" "time"
"k8s.io/klog/v2" "k8s.io/klog/v2"
...@@ -51,13 +52,17 @@ type respLogger struct { ...@@ -51,13 +52,17 @@ type respLogger struct {
statusRecorded bool statusRecorded bool
status int status int
statusStack string statusStack string
addedInfo string // mutex is used when accessing addedInfo
startTime time.Time // It can be modified by other goroutine when logging happens (in case of request timeout)
mutex sync.Mutex
addedInfo string
startTime time.Time
captureErrorOutput bool captureErrorOutput bool
req *http.Request req *http.Request
w http.ResponseWriter userAgent string
w http.ResponseWriter
logStacktracePred StacktracePred logStacktracePred StacktracePred
} }
...@@ -107,6 +112,7 @@ func newLogged(req *http.Request, w http.ResponseWriter) *respLogger { ...@@ -107,6 +112,7 @@ func newLogged(req *http.Request, w http.ResponseWriter) *respLogger {
return &respLogger{ return &respLogger{
startTime: time.Now(), startTime: time.Now(),
req: req, req: req,
userAgent: req.UserAgent(),
w: w, w: w,
logStacktracePred: DefaultStacktracePred, logStacktracePred: DefaultStacktracePred,
} }
...@@ -152,6 +158,8 @@ func StatusIsNot(statuses ...int) StacktracePred { ...@@ -152,6 +158,8 @@ func StatusIsNot(statuses ...int) StacktracePred {
// Addf adds additional data to be logged with this request. // Addf adds additional data to be logged with this request.
func (rl *respLogger) Addf(format string, data ...interface{}) { func (rl *respLogger) Addf(format string, data ...interface{}) {
rl.mutex.Lock()
defer rl.mutex.Unlock()
rl.addedInfo += "\n" + fmt.Sprintf(format, data...) rl.addedInfo += "\n" + fmt.Sprintf(format, data...)
} }
...@@ -162,7 +170,7 @@ func (rl *respLogger) LogArgs() []interface{} { ...@@ -162,7 +170,7 @@ func (rl *respLogger) LogArgs() []interface{} {
"verb", rl.req.Method, "verb", rl.req.Method,
"URI", rl.req.RequestURI, "URI", rl.req.RequestURI,
"latency", latency, "latency", latency,
"userAgent", rl.req.UserAgent(), "userAgent", rl.userAgent,
"srcIP", rl.req.RemoteAddr, "srcIP", rl.req.RemoteAddr,
"hijacked", true, "hijacked", true,
} }
...@@ -171,10 +179,17 @@ func (rl *respLogger) LogArgs() []interface{} { ...@@ -171,10 +179,17 @@ func (rl *respLogger) LogArgs() []interface{} {
"verb", rl.req.Method, "verb", rl.req.Method,
"URI", rl.req.RequestURI, "URI", rl.req.RequestURI,
"latency", latency, "latency", latency,
"userAgent", rl.req.UserAgent(), // We can't get UserAgent from rl.req.UserAgent() here as it accesses headers map,
// which can be modified in another goroutine when apiserver request times out.
// For example authentication filter modifies request's headers,
// This can cause apiserver to crash with unrecoverable fatal error.
// More info about concurrent read and write for maps: https://golang.org/doc/go1.6#runtime
"userAgent", rl.userAgent,
"srcIP", rl.req.RemoteAddr, "srcIP", rl.req.RemoteAddr,
"resp", rl.status, "resp", rl.status,
} }
rl.mutex.Lock()
defer rl.mutex.Unlock()
if len(rl.statusStack) > 0 { if len(rl.statusStack) > 0 {
args = append(args, "statusStack", rl.statusStack) args = append(args, "statusStack", rl.statusStack)
} }
......
...@@ -3,8 +3,8 @@ package version ...@@ -3,8 +3,8 @@ package version
var ( var (
gitMajor = "1" gitMajor = "1"
gitMinor = "20" gitMinor = "20"
gitVersion = "v1.20.12-k3s1" gitVersion = "v1.20.13-k3s1"
gitCommit = "ea9c1b99bd42e157dae782e2add8321cc3a6165a" gitCommit = "00ac75d2198c72709eea88425cbc3d71993bdb6d"
gitTreeState = "clean" gitTreeState = "clean"
buildDate = "2021-10-28T17:00:10Z" buildDate = "2021-11-17T22:42:11Z"
) )
...@@ -663,8 +663,8 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 ...@@ -663,8 +663,8 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ= k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c= k8s.io/kube-openapi v0.0.0-20211110013926-83f114cd0513 h1:pbudjNtv90nOgR0/DUhPwKHnQ55Khz8+sNhJBIK7A5M=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20211110013926-83f114cd0513/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
......
...@@ -3,8 +3,8 @@ package version ...@@ -3,8 +3,8 @@ package version
var ( var (
gitMajor = "1" gitMajor = "1"
gitMinor = "20" gitMinor = "20"
gitVersion = "v1.20.12-k3s1" gitVersion = "v1.20.13-k3s1"
gitCommit = "ea9c1b99bd42e157dae782e2add8321cc3a6165a" gitCommit = "00ac75d2198c72709eea88425cbc3d71993bdb6d"
gitTreeState = "clean" gitTreeState = "clean"
buildDate = "2021-10-28T17:00:10Z" buildDate = "2021-11-17T22:42:11Z"
) )
...@@ -197,7 +197,7 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 ...@@ -197,7 +197,7 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ= k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20211110013926-83f114cd0513/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
......
...@@ -35,7 +35,7 @@ import ( ...@@ -35,7 +35,7 @@ import (
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
"github.com/munnerz/goautoneg" "github.com/munnerz/goautoneg"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
klog "k8s.io/klog/v2"
"k8s.io/kube-openapi/pkg/builder" "k8s.io/kube-openapi/pkg/builder"
"k8s.io/kube-openapi/pkg/common" "k8s.io/kube-openapi/pkg/common"
) )
...@@ -57,13 +57,40 @@ type OpenAPIService struct { ...@@ -57,13 +57,40 @@ type OpenAPIService struct {
lastModified time.Time lastModified time.Time
specBytes []byte jsonCache cache
specPb []byte protoCache cache
specPbGz []byte }
type cache struct {
BuildCache func() ([]byte, error)
once sync.Once
bytes []byte
etag string
err error
}
func (c *cache) Get() ([]byte, string, error) {
c.once.Do(func() {
bytes, err := c.BuildCache()
// if there is an error updating the cache, there can be situations where
// c.bytes contains a valid value (carried over from the previous update)
// but c.err is also not nil; the cache user is expected to check for this
c.err = err
if c.err == nil {
// don't override previous spec if we had an error
c.bytes = bytes
c.etag = computeETag(c.bytes)
}
})
return c.bytes, c.etag, c.err
}
specBytesETag string func (c *cache) New(cacheBuilder func() ([]byte, error)) cache {
specPbETag string return cache{
specPbGzETag string bytes: c.bytes,
etag: c.etag,
BuildCache: cacheBuilder,
}
} }
func init() { func init() {
...@@ -73,6 +100,9 @@ func init() { ...@@ -73,6 +100,9 @@ func init() {
} }
func computeETag(data []byte) string { func computeETag(data []byte) string {
if data == nil {
return ""
}
return fmt.Sprintf("\"%X\"", sha512.Sum512(data)) return fmt.Sprintf("\"%X\"", sha512.Sum512(data))
} }
...@@ -85,55 +115,44 @@ func NewOpenAPIService(spec *spec.Swagger) (*OpenAPIService, error) { ...@@ -85,55 +115,44 @@ func NewOpenAPIService(spec *spec.Swagger) (*OpenAPIService, error) {
return o, nil return o, nil
} }
func (o *OpenAPIService) getSwaggerBytes() ([]byte, string, time.Time) { func (o *OpenAPIService) getSwaggerBytes() ([]byte, string, time.Time, error) {
o.rwMutex.RLock() o.rwMutex.RLock()
defer o.rwMutex.RUnlock() defer o.rwMutex.RUnlock()
return o.specBytes, o.specBytesETag, o.lastModified specBytes, etag, err := o.jsonCache.Get()
} if err != nil {
return nil, "", time.Time{}, err
func (o *OpenAPIService) getSwaggerPbBytes() ([]byte, string, time.Time) { }
o.rwMutex.RLock() return specBytes, etag, o.lastModified, nil
defer o.rwMutex.RUnlock()
return o.specPb, o.specPbETag, o.lastModified
} }
func (o *OpenAPIService) getSwaggerPbGzBytes() ([]byte, string, time.Time) { func (o *OpenAPIService) getSwaggerPbBytes() ([]byte, string, time.Time, error) {
o.rwMutex.RLock() o.rwMutex.RLock()
defer o.rwMutex.RUnlock() defer o.rwMutex.RUnlock()
return o.specPbGz, o.specPbGzETag, o.lastModified specPb, etag, err := o.protoCache.Get()
}
func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) {
specBytes, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(openapiSpec)
if err != nil { if err != nil {
return err return nil, "", time.Time{}, err
}
var json map[string]interface{}
if err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(specBytes, &json); err != nil {
return err
} }
specPb, err := ToProtoBinary(json) return specPb, etag, o.lastModified, nil
if err != nil { }
return err
}
specPbGz := toGzip(specPb)
specBytesETag := computeETag(specBytes)
specPbETag := computeETag(specPb)
specPbGzETag := computeETag(specPbGz)
lastModified := time.Now()
func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) {
o.rwMutex.Lock() o.rwMutex.Lock()
defer o.rwMutex.Unlock() defer o.rwMutex.Unlock()
o.jsonCache = o.jsonCache.New(func() ([]byte, error) {
o.specBytes = specBytes return jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(openapiSpec)
o.specPb = specPb })
o.specPbGz = specPbGz o.protoCache = o.protoCache.New(func() ([]byte, error) {
o.specBytesETag = specBytesETag json, _, err := o.jsonCache.Get()
o.specPbETag = specPbETag if err != nil {
o.specPbGzETag = specPbGzETag return nil, err
o.lastModified = lastModified }
var jMap map[string]interface{}
if err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(json, &jMap); err != nil {
return nil, err
}
return ToProtoBinary(jMap)
})
o.lastModified = time.Now()
return nil return nil
} }
...@@ -212,7 +231,7 @@ func (o *OpenAPIService) RegisterOpenAPIVersionedService(servePath string, handl ...@@ -212,7 +231,7 @@ func (o *OpenAPIService) RegisterOpenAPIVersionedService(servePath string, handl
accepted := []struct { accepted := []struct {
Type string Type string
SubType string SubType string
GetDataAndETag func() ([]byte, string, time.Time) GetDataAndETag func() ([]byte, string, time.Time, error)
}{ }{
{"application", "json", o.getSwaggerBytes}, {"application", "json", o.getSwaggerBytes},
{"application", "com.github.proto-openapi.spec.v2@v1.0+protobuf", o.getSwaggerPbBytes}, {"application", "com.github.proto-openapi.spec.v2@v1.0+protobuf", o.getSwaggerPbBytes},
...@@ -236,7 +255,15 @@ func (o *OpenAPIService) RegisterOpenAPIVersionedService(servePath string, handl ...@@ -236,7 +255,15 @@ func (o *OpenAPIService) RegisterOpenAPIVersionedService(servePath string, handl
} }
// serve the first matching media type in the sorted clause list // serve the first matching media type in the sorted clause list
data, etag, lastModified := accepts.GetDataAndETag() data, etag, lastModified, err := accepts.GetDataAndETag()
if err != nil {
klog.Errorf("Error in OpenAPI handler: %s", err)
// only return a 503 if we have no older cache data to serve
if data == nil {
w.WriteHeader(http.StatusServiceUnavailable)
return
}
}
w.Header().Set("Etag", etag) w.Header().Set("Etag", etag)
// ServeContent will take care of caching using eTag. // ServeContent will take care of caching using eTag.
http.ServeContent(w, r, servePath, lastModified, bytes.NewReader(data)) http.ServeContent(w, r, servePath, lastModified, bytes.NewReader(data))
......
...@@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ...@@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["cp.go"], srcs = [
"cp.go",
"filespec.go",
],
importmap = "k8s.io/kubernetes/vendor/k8s.io/kubectl/pkg/cmd/cp", importmap = "k8s.io/kubernetes/vendor/k8s.io/kubectl/pkg/cmd/cp",
importpath = "k8s.io/kubectl/pkg/cmd/cp", importpath = "k8s.io/kubectl/pkg/cmd/cp",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
...@@ -14,7 +17,6 @@ go_library( ...@@ -14,7 +17,6 @@ go_library(
"//staging/src/k8s.io/kubectl/pkg/cmd/util:go_default_library", "//staging/src/k8s.io/kubectl/pkg/cmd/util:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/util/i18n:go_default_library", "//staging/src/k8s.io/kubectl/pkg/util/i18n:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library", "//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
"//vendor/github.com/lithammer/dedent:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",
], ],
) )
......
/*
Copyright 2021 The Kubernetes 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 cp
import (
"path"
"path/filepath"
"strings"
)
type fileSpec struct {
PodName string
PodNamespace string
File pathSpec
}
type pathSpec interface {
String() string
}
// localPath represents a client-native path, which will differ based
// on the client OS, its methods will use path/filepath package which
// is OS dependant
type localPath struct {
file string
}
func newLocalPath(fileName string) localPath {
file := stripTrailingSlash(fileName)
return localPath{file: file}
}
func (p localPath) String() string {
return p.file
}
func (p localPath) Dir() localPath {
return newLocalPath(filepath.Dir(p.file))
}
func (p localPath) Base() localPath {
return newLocalPath(filepath.Base(p.file))
}
func (p localPath) Clean() localPath {
return newLocalPath(filepath.Clean(p.file))
}
func (p localPath) Join(elem pathSpec) localPath {
return newLocalPath(filepath.Join(p.file, elem.String()))
}
func (p localPath) Glob() (matches []string, err error) {
return filepath.Glob(p.file)
}
func (p localPath) StripSlashes() localPath {
return newLocalPath(stripLeadingSlash(p.file))
}
func isRelative(base, target localPath) bool {
relative, err := filepath.Rel(base.String(), target.String())
if err != nil {
return false
}
return relative == "." || relative == stripPathShortcuts(relative)
}
// remotePath represents always UNIX path, its methods will use path
// package which is always using `/`
type remotePath struct {
file string
}
func newRemotePath(fileName string) remotePath {
// we assume remote file is a linux container but we need to convert
// windows path separators to unix style for consistent processing
file := strings.ReplaceAll(stripTrailingSlash(fileName), `\`, "/")
return remotePath{file: file}
}
func (p remotePath) String() string {
return p.file
}
func (p remotePath) Dir() remotePath {
return newRemotePath(path.Dir(p.file))
}
func (p remotePath) Base() remotePath {
return newRemotePath(path.Base(p.file))
}
func (p remotePath) Clean() remotePath {
return newRemotePath(path.Clean(p.file))
}
func (p remotePath) Join(elem pathSpec) remotePath {
return newRemotePath(path.Join(p.file, elem.String()))
}
func (p remotePath) StripShortcuts() remotePath {
p = p.Clean()
return newRemotePath(stripPathShortcuts(p.file))
}
func (p remotePath) StripSlashes() remotePath {
return newRemotePath(stripLeadingSlash(p.file))
}
// strips trailing slash (if any) both unix and windows style
func stripTrailingSlash(file string) string {
if len(file) == 0 {
return file
}
if file != "/" && strings.HasSuffix(string(file[len(file)-1]), "/") {
return file[:len(file)-1]
}
return file
}
func stripLeadingSlash(file string) string {
// tar strips the leading '/' and '\' if it's there, so we will too
return strings.TrimLeft(file, `/\`)
}
// stripPathShortcuts removes any leading or trailing "../" from a given path
func stripPathShortcuts(p string) string {
newPath := p
trimmed := strings.TrimPrefix(newPath, "../")
for trimmed != newPath {
newPath = trimmed
trimmed = strings.TrimPrefix(newPath, "../")
}
// trim leftover {".", ".."}
if newPath == "." || newPath == ".." {
newPath = ""
}
if len(newPath) > 0 && string(newPath[0]) == "/" {
return newPath[1:]
}
return newPath
}
...@@ -303,12 +303,11 @@ func (c *Controller) syncEndpoints(key string) error { ...@@ -303,12 +303,11 @@ func (c *Controller) syncEndpoints(key string) error {
return err return err
} }
// This means that if a Service transitions away from a nil selector, any // If a selector is specified, clean up any mirrored slices.
// mirrored EndpointSlices will not be cleaned up. #91072 tracks this issue
// for this controller along with the Endpoints and EndpointSlice
// controllers.
if svc.Spec.Selector != nil { if svc.Spec.Selector != nil {
return nil klog.V(4).Infof("%s/%s Service now has selector, cleaning up any mirrored EndpointSlices", namespace, name)
c.endpointSliceTracker.DeleteService(namespace, name)
return c.deleteMirroredSlices(namespace, name)
} }
endpointSlices, err := endpointSlicesMirroredForService(c.endpointSliceLister, namespace, name) endpointSlices, err := endpointSlicesMirroredForService(c.endpointSliceLister, namespace, name)
...@@ -371,7 +370,7 @@ func (c *Controller) onServiceUpdate(prevObj, obj interface{}) { ...@@ -371,7 +370,7 @@ func (c *Controller) onServiceUpdate(prevObj, obj interface{}) {
service := obj.(*v1.Service) service := obj.(*v1.Service)
prevService := prevObj.(*v1.Service) prevService := prevObj.(*v1.Service)
if service == nil || prevService == nil { if service == nil || prevService == nil {
utilruntime.HandleError(fmt.Errorf("onServiceUpdate() expected type v1.Endpoints, got %T, %T", prevObj, obj)) utilruntime.HandleError(fmt.Errorf("onServiceUpdate() expected type v1.Service, got %T, %T", prevObj, obj))
return return
} }
if (service.Spec.Selector == nil) != (prevService.Spec.Selector == nil) { if (service.Spec.Selector == nil) != (prevService.Spec.Selector == nil) {
......
...@@ -359,6 +359,7 @@ func ReadLogs(ctx context.Context, path, containerID string, opts *LogOptions, r ...@@ -359,6 +359,7 @@ func ReadLogs(ctx context.Context, path, containerID string, opts *LogOptions, r
} }
return fmt.Errorf("failed to open log file %q: %v", path, err) return fmt.Errorf("failed to open log file %q: %v", path, err)
} }
defer newF.Close()
f.Close() f.Close()
if err := watcher.Remove(f.Name()); err != nil && !os.IsNotExist(err) { if err := watcher.Remove(f.Name()); err != nil && !os.IsNotExist(err) {
klog.Errorf("failed to remove file watch %q: %v", f.Name(), err) klog.Errorf("failed to remove file watch %q: %v", f.Name(), err)
......
...@@ -263,7 +263,8 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error ...@@ -263,7 +263,8 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error
c.supportsSELinux, err = c.kubeVolHost.GetHostUtil().GetSELinuxSupport(dir) c.supportsSELinux, err = c.kubeVolHost.GetHostUtil().GetSELinuxSupport(dir)
if err != nil { if err != nil {
klog.V(2).Info(log("error checking for SELinux support: %s", err)) // The volume is mounted. Return UncertainProgressError, so kubelet will unmount it when user deletes the pod.
return volumetypes.NewUncertainProgressError(fmt.Sprintf("error checking for SELinux support: %s", err))
} }
if c.supportsFSGroup(fsType, mounterArgs.FsGroup, c.fsGroupPolicy) { if c.supportsFSGroup(fsType, mounterArgs.FsGroup, c.fsGroupPolicy) {
......
...@@ -15,11 +15,13 @@ go_library( ...@@ -15,11 +15,13 @@ go_library(
"//staging/src/k8s.io/mount-utils:go_default_library", "//staging/src/k8s.io/mount-utils:go_default_library",
] + select({ ] + select({
"@io_bazel_rules_go//go/platform:android": [ "@io_bazel_rules_go//go/platform:android": [
"//pkg/util/selinux:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library", "//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library",
"//vendor/k8s.io/utils/path:go_default_library", "//vendor/k8s.io/utils/path:go_default_library",
], ],
"@io_bazel_rules_go//go/platform:linux": [ "@io_bazel_rules_go//go/platform:linux": [
"//pkg/util/selinux:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library", "//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library",
"//vendor/k8s.io/utils/path:go_default_library", "//vendor/k8s.io/utils/path:go_default_library",
......
...@@ -108,7 +108,7 @@ func (hu *FakeHostUtil) GetOwner(pathname string) (int64, int64, error) { ...@@ -108,7 +108,7 @@ func (hu *FakeHostUtil) GetOwner(pathname string) (int64, int64, error) {
// GetSELinuxSupport tests if pathname is on a mount that supports SELinux. // GetSELinuxSupport tests if pathname is on a mount that supports SELinux.
// Not implemented for testing // Not implemented for testing
func (hu *FakeHostUtil) GetSELinuxSupport(pathname string) (bool, error) { func (hu *FakeHostUtil) GetSELinuxSupport(pathname string) (bool, error) {
return false, errors.New("GetSELinuxSupport not implemented") return false, nil
} }
// GetMode returns permissions of pathname. // GetMode returns permissions of pathname.
......
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/util/selinux"
"k8s.io/mount-utils" "k8s.io/mount-utils"
utilpath "k8s.io/utils/path" utilpath "k8s.io/utils/path"
) )
...@@ -229,8 +230,16 @@ func DoMakeRShared(path string, mountInfoFilename string) error { ...@@ -229,8 +230,16 @@ func DoMakeRShared(path string, mountInfoFilename string) error {
return nil return nil
} }
// selinux.SELinuxEnabled implementation for unit tests
type seLinuxEnabledFunc func() bool
// GetSELinux is common implementation of GetSELinuxSupport on Linux. // GetSELinux is common implementation of GetSELinuxSupport on Linux.
func GetSELinux(path string, mountInfoFilename string) (bool, error) { func GetSELinux(path string, mountInfoFilename string, selinuxEnabled seLinuxEnabledFunc) (bool, error) {
// Skip /proc/mounts parsing if SELinux is disabled.
if !selinuxEnabled() {
return false, nil
}
info, err := findMountInfo(path, mountInfoFilename) info, err := findMountInfo(path, mountInfoFilename)
if err != nil { if err != nil {
return false, err return false, err
...@@ -253,7 +262,7 @@ func GetSELinux(path string, mountInfoFilename string) (bool, error) { ...@@ -253,7 +262,7 @@ func GetSELinux(path string, mountInfoFilename string) (bool, error) {
// GetSELinuxSupport returns true if given path is on a mount that supports // GetSELinuxSupport returns true if given path is on a mount that supports
// SELinux. // SELinux.
func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) { func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) {
return GetSELinux(pathname, procMountInfoPath) return GetSELinux(pathname, procMountInfoPath, selinux.SELinuxEnabled)
} }
// GetOwner returns the integer ID for the user and group of the given path // GetOwner returns the integer ID for the user and group of the given path
......
...@@ -16,7 +16,6 @@ go_library( ...@@ -16,7 +16,6 @@ go_library(
"//vendor/k8s.io/utils/nsenter:go_default_library", "//vendor/k8s.io/utils/nsenter:go_default_library",
], ],
"@io_bazel_rules_go//go/platform:android": [ "@io_bazel_rules_go//go/platform:android": [
"//pkg/volume/util/hostutil:go_default_library",
"//staging/src/k8s.io/mount-utils:go_default_library", "//staging/src/k8s.io/mount-utils:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library", "//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library",
...@@ -46,7 +45,6 @@ go_library( ...@@ -46,7 +45,6 @@ go_library(
"//vendor/k8s.io/utils/nsenter:go_default_library", "//vendor/k8s.io/utils/nsenter:go_default_library",
], ],
"@io_bazel_rules_go//go/platform:linux": [ "@io_bazel_rules_go//go/platform:linux": [
"//pkg/volume/util/hostutil:go_default_library",
"//staging/src/k8s.io/mount-utils:go_default_library", "//staging/src/k8s.io/mount-utils:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library", "//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library",
......
...@@ -29,7 +29,6 @@ import ( ...@@ -29,7 +29,6 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/mount-utils" "k8s.io/mount-utils"
) )
...@@ -109,12 +108,12 @@ func prepareSubpathTarget(mounter mount.Interface, subpath Subpath) (bool, strin ...@@ -109,12 +108,12 @@ func prepareSubpathTarget(mounter mount.Interface, subpath Subpath) (bool, strin
notMount = true notMount = true
} }
if !notMount { if !notMount {
linuxHostUtil := hostutil.NewHostUtil() // It's already mounted, so check if it's bind-mounted to the same path
mntInfo, err := linuxHostUtil.FindMountInfo(bindPathTarget) samePath, err := checkSubPathFileEqual(subpath, bindPathTarget)
if err != nil { if err != nil {
return false, "", fmt.Errorf("error calling findMountInfo for %s: %s", bindPathTarget, err) return false, "", fmt.Errorf("error checking subpath mount info for %s: %s", bindPathTarget, err)
} }
if mntInfo.Root != subpath.Path { if !samePath {
// It's already mounted but not what we want, unmount it // It's already mounted but not what we want, unmount it
if err = mounter.Unmount(bindPathTarget); err != nil { if err = mounter.Unmount(bindPathTarget); err != nil {
return false, "", fmt.Errorf("error ummounting %s: %s", bindPathTarget, err) return false, "", fmt.Errorf("error ummounting %s: %s", bindPathTarget, err)
...@@ -155,6 +154,23 @@ func prepareSubpathTarget(mounter mount.Interface, subpath Subpath) (bool, strin ...@@ -155,6 +154,23 @@ func prepareSubpathTarget(mounter mount.Interface, subpath Subpath) (bool, strin
return false, bindPathTarget, nil return false, bindPathTarget, nil
} }
func checkSubPathFileEqual(subpath Subpath, bindMountTarget string) (bool, error) {
s, err := os.Lstat(subpath.Path)
if err != nil {
return false, fmt.Errorf("stat %s failed: %s", subpath.Path, err)
}
t, err := os.Lstat(bindMountTarget)
if err != nil {
return false, fmt.Errorf("lstat %s failed: %s", bindMountTarget, err)
}
if !os.SameFile(s, t) {
return false, nil
}
return true, nil
}
func getSubpathBindTarget(subpath Subpath) string { func getSubpathBindTarget(subpath Subpath) string {
// containerName is DNS label, i.e. safe as a directory name. // containerName is DNS label, i.e. safe as a directory name.
return filepath.Join(subpath.PodDir, containerSubPathDirectoryName, subpath.VolumeName, subpath.ContainerName, strconv.Itoa(subpath.VolumeMountIndex)) return filepath.Join(subpath.PodDir, containerSubPathDirectoryName, subpath.VolumeName, subpath.ContainerName, strconv.Itoa(subpath.VolumeMountIndex))
......
...@@ -84,15 +84,9 @@ func NormalizeWindowsPath(path string) string { ...@@ -84,15 +84,9 @@ func NormalizeWindowsPath(path string) string {
// ValidateDiskNumber : disk number should be a number in [0, 99] // ValidateDiskNumber : disk number should be a number in [0, 99]
func ValidateDiskNumber(disk string) error { func ValidateDiskNumber(disk string) error {
diskNum, err := strconv.Atoi(disk) if _, err := strconv.Atoi(disk); err != nil {
if err != nil { return fmt.Errorf("wrong disk number format: %q, err: %v", disk, err)
return fmt.Errorf("wrong disk number format: %q, err:%v", disk, err)
} }
if diskNum < 0 || diskNum > 99 {
return fmt.Errorf("disk number out of range: %q", disk)
}
return nil return nil
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment