update c/common

Update containers common to the latest HEAD.  Some bug fixes in libimage
forced us to have a clearer separation between ordinary images and
manifest lists.  Hence, when looking up manifest lists without recursing
into any of their instances, we need to use `LookupManifestList()`.

Also account for some other changes in c/common (e.g., the changed order
in the security labels).

Further vendor the latest HEAD from Buildah which is required to get the
bud tests to pass.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2021-05-18 10:05:03 +02:00
parent 8bc39f4a90
commit 898a8ad285
186 changed files with 2720 additions and 1771 deletions

File diff suppressed because it is too large Load Diff

View File

@ -517,21 +517,21 @@ file {
number: 1
label: LABEL_OPTIONAL
type: TYPE_UINT64
json_name: "oom_kill_disable"
json_name: "oomKillDisable"
}
field {
name: "under_oom"
number: 2
label: LABEL_OPTIONAL
type: TYPE_UINT64
json_name: "under_oom"
json_name: "underOom"
}
field {
name: "oom_kill"
number: 3
label: LABEL_OPTIONAL
type: TYPE_UINT64
json_name: "oom_kill"
json_name: "oomKill"
}
}
message_type {

View File

@ -14,7 +14,7 @@
limitations under the License.
*/
package sys
package userns
import (
"bufio"

View File

@ -16,7 +16,7 @@
limitations under the License.
*/
package sys
package userns
// RunningInUserNS is a stub for non-Linux systems
// Always returns false

View File

@ -19,15 +19,63 @@
package platforms
import (
"fmt"
"runtime"
"strconv"
"strings"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/sys/windows"
)
// Default returns the default matcher for the platform.
func Default() MatchComparer {
return Ordered(DefaultSpec(), specs.Platform{
OS: "linux",
Architecture: runtime.GOARCH,
})
type matchComparer struct {
defaults Matcher
osVersionPrefix string
}
// Match matches platform with the same windows major, minor
// and build version.
func (m matchComparer) Match(p imagespec.Platform) bool {
if m.defaults.Match(p) {
// TODO(windows): Figure out whether OSVersion is deprecated.
return strings.HasPrefix(p.OSVersion, m.osVersionPrefix)
}
return false
}
// Less sorts matched platforms in front of other platforms.
// For matched platforms, it puts platforms with larger revision
// number in front.
func (m matchComparer) Less(p1, p2 imagespec.Platform) bool {
m1, m2 := m.Match(p1), m.Match(p2)
if m1 && m2 {
r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion)
return r1 > r2
}
return m1 && !m2
}
func revision(v string) int {
parts := strings.Split(v, ".")
if len(parts) < 4 {
return 0
}
r, err := strconv.Atoi(parts[3])
if err != nil {
return 0
}
return r
}
// Default returns the current platform's default platform specification.
func Default() MatchComparer {
major, minor, build := windows.RtlGetNtVersionNumbers()
return matchComparer{
defaults: Ordered(DefaultSpec(), specs.Platform{
OS: "linux",
Architecture: runtime.GOARCH,
}),
osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build),
}
}

View File

@ -1,35 +0,0 @@
/*
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 sys
import "os"
// IsFifo checks if a file is a (named pipe) fifo
// if the file does not exist then it returns false
func IsFifo(path string) (bool, error) {
stat, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
return true, nil
}
return false, nil
}

View File

@ -22,11 +22,14 @@ import (
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
"syscall"
"unsafe"
"github.com/Microsoft/hcsshim"
"github.com/pkg/errors"
"golang.org/x/sys/windows"
)
@ -257,12 +260,71 @@ func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle,
return h, e
}
// ForceRemoveAll is the same as os.RemoveAll, but uses hcsshim.DestroyLayer in order
// to delete container layers.
// ForceRemoveAll is the same as os.RemoveAll, but is aware of io.containerd.snapshotter.v1.windows
// and uses hcsshim to unmount and delete container layers contained therein, in the correct order,
// when passed a containerd root data directory (i.e. the `--root` directory for containerd).
func ForceRemoveAll(path string) error {
info := hcsshim.DriverInfo{
HomeDir: filepath.Dir(path),
// snapshots/windows/windows.go init()
const snapshotPlugin = "io.containerd.snapshotter.v1" + "." + "windows"
// snapshots/windows/windows.go NewSnapshotter()
snapshotDir := filepath.Join(path, snapshotPlugin, "snapshots")
if stat, err := os.Stat(snapshotDir); err == nil && stat.IsDir() {
if err := cleanupWCOWLayers(snapshotDir); err != nil {
return errors.Wrapf(err, "failed to cleanup WCOW layers in %s", snapshotDir)
}
}
return hcsshim.DestroyLayer(info, filepath.Base(path))
return os.RemoveAll(path)
}
func cleanupWCOWLayers(root string) error {
// See snapshots/windows/windows.go getSnapshotDir()
var layerNums []int
if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if path != root && info.IsDir() {
if layerNum, err := strconv.Atoi(filepath.Base(path)); err == nil {
layerNums = append(layerNums, layerNum)
} else {
return err
}
return filepath.SkipDir
}
return nil
}); err != nil {
return err
}
sort.Sort(sort.Reverse(sort.IntSlice(layerNums)))
for _, layerNum := range layerNums {
if err := cleanupWCOWLayer(filepath.Join(root, strconv.Itoa(layerNum))); err != nil {
return err
}
}
return nil
}
func cleanupWCOWLayer(layerPath string) error {
info := hcsshim.DriverInfo{
HomeDir: filepath.Dir(layerPath),
}
// ERROR_DEV_NOT_EXIST is returned if the layer is not currently prepared.
if err := hcsshim.UnprepareLayer(info, filepath.Base(layerPath)); err != nil {
if hcserror, ok := err.(*hcsshim.HcsError); !ok || hcserror.Err != windows.ERROR_DEV_NOT_EXIST {
return errors.Wrapf(err, "failed to unprepare %s", layerPath)
}
}
if err := hcsshim.DeactivateLayer(info, filepath.Base(layerPath)); err != nil {
return errors.Wrapf(err, "failed to deactivate %s", layerPath)
}
if err := hcsshim.DestroyLayer(info, filepath.Base(layerPath)); err != nil {
return errors.Wrapf(err, "failed to destroy %s", layerPath)
}
return nil
}

View File

@ -1,5 +1,3 @@
// +build !windows
/*
Copyright The containerd Authors.
@ -24,17 +22,34 @@ import (
"os"
"strconv"
"strings"
"github.com/containerd/containerd/pkg/userns"
"golang.org/x/sys/unix"
)
const (
// OOMScoreMaxKillable is the maximum score keeping the process killable by the oom killer
OOMScoreMaxKillable = -999
// OOMScoreAdjMax is from OOM_SCORE_ADJ_MAX https://github.com/torvalds/linux/blob/master/include/uapi/linux/oom.h
// OOMScoreAdjMin is from OOM_SCORE_ADJ_MIN https://github.com/torvalds/linux/blob/v5.10/include/uapi/linux/oom.h#L9
OOMScoreAdjMin = -1000
// OOMScoreAdjMax is from OOM_SCORE_ADJ_MAX https://github.com/torvalds/linux/blob/v5.10/include/uapi/linux/oom.h#L10
OOMScoreAdjMax = 1000
)
// AdjustOOMScore sets the oom score for the provided pid. If the provided score
// is out of range (-1000 - 1000), it is clipped to the min/max value.
func AdjustOOMScore(pid, score int) error {
if score > OOMScoreAdjMax {
score = OOMScoreAdjMax
} else if score < OOMScoreAdjMin {
score = OOMScoreAdjMin
}
return SetOOMScore(pid, score)
}
// SetOOMScore sets the oom score for the provided pid
func SetOOMScore(pid, score int) error {
if score > OOMScoreAdjMax || score < OOMScoreAdjMin {
return fmt.Errorf("value out of range (%d): OOM score must be between %d and %d", score, OOMScoreAdjMin, OOMScoreAdjMax)
}
path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
f, err := os.OpenFile(path, os.O_WRONLY, 0)
if err != nil {
@ -42,7 +57,7 @@ func SetOOMScore(pid, score int) error {
}
defer f.Close()
if _, err = f.WriteString(strconv.Itoa(score)); err != nil {
if os.IsPermission(err) && (RunningInUserNS() || RunningUnprivileged()) {
if os.IsPermission(err) && (!runningPrivileged() || userns.RunningInUserNS()) {
return nil
}
return err
@ -50,7 +65,8 @@ func SetOOMScore(pid, score int) error {
return nil
}
// GetOOMScoreAdj gets the oom score for a process
// GetOOMScoreAdj gets the oom score for a process. It returns 0 (zero) if either
// no oom score is set, or a sore is set to 0.
func GetOOMScoreAdj(pid int) (int, error) {
path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
data, err := ioutil.ReadFile(path)
@ -59,3 +75,9 @@ func GetOOMScoreAdj(pid int) (int, error) {
}
return strconv.Atoi(strings.TrimSpace(string(data)))
}
// runningPrivileged returns true if the effective user ID of the
// calling process is 0
func runningPrivileged() bool {
return unix.Geteuid() == 0
}

View File

@ -1,3 +1,5 @@
// +build !linux
/*
Copyright The containerd Authors.
@ -17,10 +19,20 @@
package sys
const (
// OOMScoreAdjMax is not implemented on Windows
// OOMScoreMaxKillable is not implemented on non Linux
OOMScoreMaxKillable = 0
// OOMScoreAdjMax is not implemented on non Linux
OOMScoreAdjMax = 0
)
// AdjustOOMScore sets the oom score for the provided pid. If the provided score
// is out of range (-1000 - 1000), it is clipped to the min/max value.
//
// Not implemented on Windows
func AdjustOOMScore(pid, score int) error {
return nil
}
// SetOOMScore sets the oom score for the process
//
// Not implemented on Windows

View File

@ -1,5 +1,3 @@
// +build !windows
/*
Copyright The containerd Authors.
@ -18,16 +16,8 @@
package sys
import "golang.org/x/sys/unix"
import "github.com/containerd/containerd/pkg/userns"
// RunningPrivileged returns true if the effective user ID of the
// calling process is 0
func RunningPrivileged() bool {
return unix.Geteuid() == 0
}
// RunningUnprivileged returns true if the effective user ID of the
// calling process is not 0
func RunningUnprivileged() bool {
return !RunningPrivileged()
}
// RunningInUserNS detects whether we are currently running in a user namespace.
// Deprecated: use github.com/containerd/containerd/pkg/userns.RunningInUserNS instead.
var RunningInUserNS = userns.RunningInUserNS