commit
b862929a21
24
apply-patch
Normal file
24
apply-patch
Normal file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||
# Description: This shell script is used to apply patches for the project
|
||||
# Author: jingrui@huawei.com
|
||||
# Create: 2019-03-02
|
||||
|
||||
pkg=runc-1.0.0-rc3
|
||||
cwd=$PWD
|
||||
src=$cwd/$pkg
|
||||
|
||||
unzip $pkg.zip
|
||||
|
||||
series=$cwd/series.conf
|
||||
while IPF= read -r line
|
||||
do
|
||||
if [[ "$line" =~ ^0.* ]]; then
|
||||
cd $src && patch -p1 < $cwd/patch/$line
|
||||
fi
|
||||
done <"$series"
|
||||
|
||||
cd $cwd
|
||||
cp -rf $src/* .
|
||||
rm -rf runc-1.0.0-rc3
|
||||
40
patch/0001-.travis.yml-Don-t-require-FETCH_HEAD.patch
Normal file
40
patch/0001-.travis.yml-Don-t-require-FETCH_HEAD.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 3eb678a633ddf3be06851a1b8c69a98650e9a367 Mon Sep 17 00:00:00 2001
|
||||
From: "W. Trevor King" <wking@tremily.us>
|
||||
Date: Tue, 21 Mar 2017 11:48:39 -0700
|
||||
Subject: [PATCH 01/94] .travis.yml: Don't require FETCH_HEAD
|
||||
|
||||
Master builds only have a 'git clone ...' [1] so FETCH_HEAD isn't
|
||||
defined and git-validation crashes [2]. We don't want to be
|
||||
hard-coding a range here, and should update git-validation to handle
|
||||
these cases automatically.
|
||||
|
||||
Also echo TRAVIS_* variables during testing to make debugging
|
||||
git-validation easier.
|
||||
|
||||
[1]: https://travis-ci.org/opencontainers/runc/jobs/213508696#L243
|
||||
[2]: https://travis-ci.org/opencontainers/runc/jobs/213508696#L347
|
||||
|
||||
Change-Id: I325ae392323133b123f0ef7577a4464ae10a54cb
|
||||
Signed-off-by: W. Trevor King <wking@tremily.us>
|
||||
---
|
||||
.travis.yml | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/.travis.yml b/.travis.yml
|
||||
index 04f71f5..244c643 100644
|
||||
--- a/.travis.yml
|
||||
+++ b/.travis.yml
|
||||
@@ -23,8 +23,9 @@ before_install:
|
||||
- go get -u github.com/golang/lint/golint
|
||||
- go get -u github.com/vbatts/git-validation
|
||||
- go get -u github.com/mvdan/sh/cmd/shfmt
|
||||
+ - env | grep TRAVIS_
|
||||
|
||||
script:
|
||||
- - git-validation -run DCO,short-subject -v -range ${TRAVIS_BRANCH}..FETCH_HEAD
|
||||
+ - git-validation -run DCO,short-subject -v
|
||||
- make BUILDTAGS="${BUILDTAGS}"
|
||||
- make BUILDTAGS="${BUILDTAGS}" clean validate test
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
43
patch/0002-Don-t-try-to-read-freezer.state-from-the-cu.patch
Normal file
43
patch/0002-Don-t-try-to-read-freezer.state-from-the-cu.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 4ccbadc228c9e4fc0fd20690ca13517f02aab59d Mon Sep 17 00:00:00 2001
|
||||
From: Andrei Vagin <avagin@virtuozzo.com>
|
||||
Date: Thu, 23 Mar 2017 01:43:39 +0300
|
||||
Subject: [PATCH 02/94] Don't try to read freezer.state from the
|
||||
current directory
|
||||
|
||||
If we try to pause a container on the system without freezer cgroups,
|
||||
we can found that runc tries to open ./freezer.state. It is obviously wrong.
|
||||
|
||||
$ ./runc pause test
|
||||
no such directory for freezer.state
|
||||
|
||||
$ echo FROZEN > freezer.state
|
||||
$ ./runc pause test
|
||||
container not running or created: paused
|
||||
|
||||
Change-Id: Ia7eba3a300a7ca6f1e8e10e4b1cbb4360e083e33
|
||||
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 28dff86..cd9235d 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -1284,7 +1284,12 @@ func (c *linuxContainer) runType() (Status, error) {
|
||||
}
|
||||
|
||||
func (c *linuxContainer) isPaused() (bool, error) {
|
||||
- data, err := ioutil.ReadFile(filepath.Join(c.cgroupManager.GetPaths()["freezer"], "freezer.state"))
|
||||
+ fcg := c.cgroupManager.GetPaths()["freezer"]
|
||||
+ if fcg == "" {
|
||||
+ // A container doesn't have a freezer cgroup
|
||||
+ return false, nil
|
||||
+ }
|
||||
+ data, err := ioutil.ReadFile(filepath.Join(fcg, "freezer.state"))
|
||||
if err != nil {
|
||||
// If freezer cgroup is not mounted, the container would just be not paused.
|
||||
if os.IsNotExist(err) {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
2424
patch/0003-Use-opencontainers-selinux-package.patch
Normal file
2424
patch/0003-Use-opencontainers-selinux-package.patch
Normal file
File diff suppressed because it is too large
Load Diff
272
patch/0004-handle-unprivileged-operations-and-dumpable.patch
Normal file
272
patch/0004-handle-unprivileged-operations-and-dumpable.patch
Normal file
@ -0,0 +1,272 @@
|
||||
From 511eb03806523b4f51cbde7daedd563a3b5810e4 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Tue, 17 Jan 2017 12:25:21 +1100
|
||||
Subject: [PATCH 04/94] *: handle unprivileged operations and
|
||||
!dumpable
|
||||
|
||||
Effectively, !dumpable makes implementing rootless containers quite
|
||||
hard, due to a bunch of different operations on /proc/self no longer
|
||||
being possible without reordering everything.
|
||||
|
||||
!dumpable only really makes sense when you are switching between
|
||||
different security contexts, which is only the case when we are joining
|
||||
namespaces. Unfortunately this means that !dumpable will still have
|
||||
issues in this instance, and it should only be necessary to set
|
||||
!dumpable if we are not joining USER namespaces (new kernels have
|
||||
protections that make !dumpable no longer necessary). But that's a topic
|
||||
for another time.
|
||||
|
||||
This also includes code to unset and then re-set dumpable when doing the
|
||||
USER namespace mappings. This should also be safe because in principle
|
||||
processes in a container can't see us until after we fork into the PID
|
||||
namespace (which happens after the user mapping).
|
||||
|
||||
In rootless containers, it is not possible to set a non-dumpable
|
||||
process's /proc/self/oom_score_adj (it's owned by root and thus not
|
||||
writeable). Thus, it needs to be set inside nsexec before we set
|
||||
ourselves as non-dumpable.
|
||||
|
||||
Change-Id: Iab9e2d9bf3997284253b4b33a504e8581fd787ae
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
libcontainer/container_linux.go | 6 ++++
|
||||
libcontainer/init_linux.go | 8 ------
|
||||
libcontainer/message_linux.go | 14 +++++----
|
||||
libcontainer/nsenter/nsexec.c | 64 ++++++++++++++++++++++++++++++++++-------
|
||||
libcontainer/process_linux.go | 8 ------
|
||||
5 files changed, 68 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index cd9235d..d2e0e2b 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -1460,5 +1460,11 @@ func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.Na
|
||||
}
|
||||
}
|
||||
|
||||
+ // write oom_score_adj
|
||||
+ r.AddData(&Bytemsg{
|
||||
+ Type: OomScoreAdjAttr,
|
||||
+ Value: []byte(fmt.Sprintf("%d", c.config.OomScoreAdj)),
|
||||
+ })
|
||||
+
|
||||
return bytes.NewReader(r.Serialize()), nil
|
||||
}
|
||||
diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go
|
||||
index 39b83a4..0f5d412 100644
|
||||
--- a/libcontainer/init_linux.go
|
||||
+++ b/libcontainer/init_linux.go
|
||||
@@ -6,10 +6,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
- "io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
- "strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
@@ -369,12 +367,6 @@ func setupRlimits(limits []configs.Rlimit, pid int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
-func setOomScoreAdj(oomScoreAdj int, pid int) error {
|
||||
- path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
|
||||
-
|
||||
- return ioutil.WriteFile(path, []byte(strconv.Itoa(oomScoreAdj)), 0600)
|
||||
-}
|
||||
-
|
||||
const _P_PID = 1
|
||||
|
||||
type siginfo struct {
|
||||
diff --git a/libcontainer/message_linux.go b/libcontainer/message_linux.go
|
||||
index a189c72..321d664 100644
|
||||
--- a/libcontainer/message_linux.go
|
||||
+++ b/libcontainer/message_linux.go
|
||||
@@ -11,12 +11,14 @@ import (
|
||||
// list of known message types we want to send to bootstrap program
|
||||
// The number is randomly chosen to not conflict with known netlink types
|
||||
const (
|
||||
- InitMsg uint16 = 62000
|
||||
- CloneFlagsAttr uint16 = 27281
|
||||
- NsPathsAttr uint16 = 27282
|
||||
- UidmapAttr uint16 = 27283
|
||||
- GidmapAttr uint16 = 27284
|
||||
- SetgroupAttr uint16 = 27285
|
||||
+ InitMsg uint16 = 62000
|
||||
+ CloneFlagsAttr uint16 = 27281
|
||||
+ NsPathsAttr uint16 = 27282
|
||||
+ UidmapAttr uint16 = 27283
|
||||
+ GidmapAttr uint16 = 27284
|
||||
+ SetgroupAttr uint16 = 27285
|
||||
+ OomScoreAdjAttr uint16 = 27286
|
||||
+
|
||||
// When syscall.NLA_HDRLEN is in gccgo, take this out.
|
||||
syscall_NLA_HDRLEN = (syscall.SizeofNlAttr + syscall.NLA_ALIGNTO - 1) & ^(syscall.NLA_ALIGNTO - 1)
|
||||
)
|
||||
diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c
|
||||
index 51bd1e3..9630206 100644
|
||||
--- a/libcontainer/nsenter/nsexec.c
|
||||
+++ b/libcontainer/nsenter/nsexec.c
|
||||
@@ -72,18 +72,21 @@ struct nlconfig_t {
|
||||
char *namespaces;
|
||||
size_t namespaces_len;
|
||||
uint8_t is_setgroup;
|
||||
+ char *oom_score_adj;
|
||||
+ size_t oom_score_adj_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* List of netlink message types sent to us as part of bootstrapping the init.
|
||||
* These constants are defined in libcontainer/message_linux.go.
|
||||
*/
|
||||
-#define INIT_MSG 62000
|
||||
+#define INIT_MSG 62000
|
||||
#define CLONE_FLAGS_ATTR 27281
|
||||
#define NS_PATHS_ATTR 27282
|
||||
-#define UIDMAP_ATTR 27283
|
||||
-#define GIDMAP_ATTR 27284
|
||||
+#define UIDMAP_ATTR 27283
|
||||
+#define GIDMAP_ATTR 27284
|
||||
#define SETGROUP_ATTR 27285
|
||||
+#define OOM_SCORE_ADJ_ATTR 27286
|
||||
|
||||
/*
|
||||
* Use the raw syscall for versions of glibc which don't include a function for
|
||||
@@ -186,7 +189,7 @@ static void update_setgroups(int pid, enum policy_t setgroup)
|
||||
}
|
||||
}
|
||||
|
||||
-static void update_uidmap(int pid, char *map, int map_len)
|
||||
+static void update_uidmap(int pid, char *map, size_t map_len)
|
||||
{
|
||||
if (map == NULL || map_len <= 0)
|
||||
return;
|
||||
@@ -195,7 +198,7 @@ static void update_uidmap(int pid, char *map, int map_len)
|
||||
bail("failed to update /proc/%d/uid_map", pid);
|
||||
}
|
||||
|
||||
-static void update_gidmap(int pid, char *map, int map_len)
|
||||
+static void update_gidmap(int pid, char *map, size_t map_len)
|
||||
{
|
||||
if (map == NULL || map_len <= 0)
|
||||
return;
|
||||
@@ -204,6 +207,15 @@ static void update_gidmap(int pid, char *map, int map_len)
|
||||
bail("failed to update /proc/%d/gid_map", pid);
|
||||
}
|
||||
|
||||
+static void update_oom_score_adj(char *data, size_t len)
|
||||
+{
|
||||
+ if (data == NULL || len <= 0)
|
||||
+ return;
|
||||
+
|
||||
+ if (write_file(data, len, "/proc/self/oom_score_adj") < 0)
|
||||
+ bail("failed to update /proc/self/oom_score_adj");
|
||||
+}
|
||||
+
|
||||
/* A dummy function that just jumps to the given jumpval. */
|
||||
static int child_func(void *arg) __attribute__ ((noinline));
|
||||
static int child_func(void *arg)
|
||||
@@ -317,6 +329,10 @@ static void nl_parse(int fd, struct nlconfig_t *config)
|
||||
case CLONE_FLAGS_ATTR:
|
||||
config->cloneflags = readint32(current);
|
||||
break;
|
||||
+ case OOM_SCORE_ADJ_ATTR:
|
||||
+ config->oom_score_adj = current;
|
||||
+ config->oom_score_adj_len = payload_len;
|
||||
+ break;
|
||||
case NS_PATHS_ATTR:
|
||||
config->namespaces = current;
|
||||
config->namespaces_len = payload_len;
|
||||
@@ -425,14 +441,32 @@ void nsexec(void)
|
||||
if (pipenum == -1)
|
||||
return;
|
||||
|
||||
- /* make the process non-dumpable */
|
||||
- if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) {
|
||||
- bail("failed to set process as non-dumpable");
|
||||
- }
|
||||
-
|
||||
/* Parse all of the netlink configuration. */
|
||||
nl_parse(pipenum, &config);
|
||||
|
||||
+ /* Set oom_score_adj. This has to be done before !dumpable because
|
||||
+ * /proc/self/oom_score_adj is not writeable unless you're an privileged
|
||||
+ * user (if !dumpable is set). All children inherit their parent's
|
||||
+ * oom_score_adj value on fork(2) so this will always be propagated
|
||||
+ * properly.
|
||||
+ */
|
||||
+ update_oom_score_adj(config.oom_score_adj, config.oom_score_adj_len);
|
||||
+
|
||||
+ /*
|
||||
+ * Make the process non-dumpable, to avoid various race conditions that
|
||||
+ * could cause processes in namespaces we're joining to access host
|
||||
+ * resources (or potentially execute code).
|
||||
+ *
|
||||
+ * However, if the number of namespaces we are joining is 0, we are not
|
||||
+ * going to be switching to a different security context. Thus setting
|
||||
+ * ourselves to be non-dumpable only breaks things (like rootless
|
||||
+ * containers), which is the recommendation from the kernel folks.
|
||||
+ */
|
||||
+ if (config.namespaces) {
|
||||
+ if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) < 0)
|
||||
+ bail("failed to set process as non-dumpable");
|
||||
+ }
|
||||
+
|
||||
/* Pipe so we can tell the child when we've finished setting up. */
|
||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sync_child_pipe) < 0)
|
||||
bail("failed to setup sync pipe between parent and child");
|
||||
@@ -681,6 +715,11 @@ void nsexec(void)
|
||||
* clone_parent rant). So signal our parent to hook us up.
|
||||
*/
|
||||
|
||||
+ /* Switching is only necessary if we joined namespaces. */
|
||||
+ if (config.namespaces) {
|
||||
+ if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0)
|
||||
+ bail("failed to set process as dumpable");
|
||||
+ }
|
||||
s = SYNC_USERMAP_PLS;
|
||||
if (write(syncfd, &s, sizeof(s)) != sizeof(s))
|
||||
bail("failed to sync with parent: write(SYNC_USERMAP_PLS)");
|
||||
@@ -691,6 +730,11 @@ void nsexec(void)
|
||||
bail("failed to sync with parent: read(SYNC_USERMAP_ACK)");
|
||||
if (s != SYNC_USERMAP_ACK)
|
||||
bail("failed to sync with parent: SYNC_USERMAP_ACK: got %u", s);
|
||||
+ /* Switching is only necessary if we joined namespaces. */
|
||||
+ if (config.namespaces) {
|
||||
+ if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) < 0)
|
||||
+ bail("failed to set process as dumpable");
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index 0f79a38..c60f473 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -85,10 +85,6 @@ func (p *setnsProcess) start() (err error) {
|
||||
return newSystemErrorWithCausef(err, "adding pid %d to cgroups", p.pid())
|
||||
}
|
||||
}
|
||||
- // set oom_score_adj
|
||||
- if err := setOomScoreAdj(p.config.Config.OomScoreAdj, p.pid()); err != nil {
|
||||
- return newSystemErrorWithCause(err, "setting oom score")
|
||||
- }
|
||||
// set rlimits, this has to be done here because we lose permissions
|
||||
// to raise the limits once we enter a user-namespace
|
||||
if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil {
|
||||
@@ -285,10 +281,6 @@ func (p *initProcess) start() error {
|
||||
if err := p.manager.Set(p.config.Config); err != nil {
|
||||
return newSystemErrorWithCause(err, "setting cgroup config for ready process")
|
||||
}
|
||||
- // set oom_score_adj
|
||||
- if err := setOomScoreAdj(p.config.Config.OomScoreAdj, p.pid()); err != nil {
|
||||
- return newSystemErrorWithCause(err, "setting oom score for ready process")
|
||||
- }
|
||||
// set rlimits, this has to be done here because we lose permissions
|
||||
// to raise the limits once we enter a user-namespace
|
||||
if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
1490
patch/0005-runc-add-support-for-rootless-containers.patch
Normal file
1490
patch/0005-runc-add-support-for-rootless-containers.patch
Normal file
File diff suppressed because it is too large
Load Diff
421
patch/0006-rootless-add-rootless-cgroup-manager.patch
Normal file
421
patch/0006-rootless-add-rootless-cgroup-manager.patch
Normal file
@ -0,0 +1,421 @@
|
||||
From 6c69b3f5c8eb23eb47917371b4ae69a76912ec83 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Tue, 26 Apr 2016 02:19:39 +1000
|
||||
Subject: [PATCH 06/94] rootless: add rootless cgroup manager
|
||||
|
||||
The rootless cgroup manager acts as a noop for all set and apply
|
||||
operations. It is just used for rootless setups. Currently this is far
|
||||
too simple (we need to add opportunistic cgroup management), but is good
|
||||
enough as a first-pass at a noop cgroup manager.
|
||||
|
||||
Change-Id: Iae5668680e5e2896246792fe6f2ac1bb37eab1d5
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
libcontainer/cgroups/fs/apply_raw.go | 24 +----
|
||||
libcontainer/cgroups/rootless/rootless.go | 128 ++++++++++++++++++++++++++
|
||||
libcontainer/cgroups/systemd/apply_systemd.go | 2 +-
|
||||
libcontainer/cgroups/utils.go | 41 ++++++++-
|
||||
libcontainer/container_linux.go | 8 ++
|
||||
libcontainer/factory_linux.go | 22 +++++
|
||||
libcontainer/process_linux.go | 20 ++--
|
||||
libcontainer/rootfs_linux.go | 2 +-
|
||||
8 files changed, 210 insertions(+), 37 deletions(-)
|
||||
create mode 100644 libcontainer/cgroups/rootless/rootless.go
|
||||
|
||||
diff --git a/libcontainer/cgroups/fs/apply_raw.go b/libcontainer/cgroups/fs/apply_raw.go
|
||||
index d316313..22d82ac 100644
|
||||
--- a/libcontainer/cgroups/fs/apply_raw.go
|
||||
+++ b/libcontainer/cgroups/fs/apply_raw.go
|
||||
@@ -267,25 +267,8 @@ func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
-func (raw *cgroupData) parentPath(subsystem, mountpoint, root string) (string, error) {
|
||||
- // Use GetThisCgroupDir instead of GetInitCgroupDir, because the creating
|
||||
- // process could in container and shared pid namespace with host, and
|
||||
- // /proc/1/cgroup could point to whole other world of cgroups.
|
||||
- initPath, err := cgroups.GetThisCgroupDir(subsystem)
|
||||
- if err != nil {
|
||||
- return "", err
|
||||
- }
|
||||
- // This is needed for nested containers, because in /proc/self/cgroup we
|
||||
- // see pathes from host, which don't exist in container.
|
||||
- relDir, err := filepath.Rel(root, initPath)
|
||||
- if err != nil {
|
||||
- return "", err
|
||||
- }
|
||||
- return filepath.Join(mountpoint, relDir), nil
|
||||
-}
|
||||
-
|
||||
func (raw *cgroupData) path(subsystem string) (string, error) {
|
||||
- mnt, root, err := cgroups.FindCgroupMountpointAndRoot(subsystem)
|
||||
+ mnt, err := cgroups.FindCgroupMountpoint(subsystem)
|
||||
// If we didn't mount the subsystem, there is no point we make the path.
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -297,7 +280,10 @@ func (raw *cgroupData) path(subsystem string) (string, error) {
|
||||
return filepath.Join(raw.root, filepath.Base(mnt), raw.innerPath), nil
|
||||
}
|
||||
|
||||
- parentPath, err := raw.parentPath(subsystem, mnt, root)
|
||||
+ // Use GetOwnCgroupPath instead of GetInitCgroupPath, because the creating
|
||||
+ // process could in container and shared pid namespace with host, and
|
||||
+ // /proc/1/cgroup could point to whole other world of cgroups.
|
||||
+ parentPath, err := cgroups.GetOwnCgroupPath(subsystem)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
diff --git a/libcontainer/cgroups/rootless/rootless.go b/libcontainer/cgroups/rootless/rootless.go
|
||||
new file mode 100644
|
||||
index 0000000..b1efbfd
|
||||
--- /dev/null
|
||||
+++ b/libcontainer/cgroups/rootless/rootless.go
|
||||
@@ -0,0 +1,128 @@
|
||||
+// +build linux
|
||||
+
|
||||
+package rootless
|
||||
+
|
||||
+import (
|
||||
+ "fmt"
|
||||
+
|
||||
+ "github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
+ "github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
||||
+ "github.com/opencontainers/runc/libcontainer/configs"
|
||||
+ "github.com/opencontainers/runc/libcontainer/configs/validate"
|
||||
+)
|
||||
+
|
||||
+// TODO: This is copied from libcontainer/cgroups/fs, which duplicates this code
|
||||
+// needlessly. We should probably export this list.
|
||||
+
|
||||
+var subsystems = []subsystem{
|
||||
+ &fs.CpusetGroup{},
|
||||
+ &fs.DevicesGroup{},
|
||||
+ &fs.MemoryGroup{},
|
||||
+ &fs.CpuGroup{},
|
||||
+ &fs.CpuacctGroup{},
|
||||
+ &fs.PidsGroup{},
|
||||
+ &fs.BlkioGroup{},
|
||||
+ &fs.HugetlbGroup{},
|
||||
+ &fs.NetClsGroup{},
|
||||
+ &fs.NetPrioGroup{},
|
||||
+ &fs.PerfEventGroup{},
|
||||
+ &fs.FreezerGroup{},
|
||||
+ &fs.NameGroup{GroupName: "name=systemd"},
|
||||
+}
|
||||
+
|
||||
+type subsystem interface {
|
||||
+ // Name returns the name of the subsystem.
|
||||
+ Name() string
|
||||
+
|
||||
+ // Returns the stats, as 'stats', corresponding to the cgroup under 'path'.
|
||||
+ GetStats(path string, stats *cgroups.Stats) error
|
||||
+}
|
||||
+
|
||||
+// The noop cgroup manager is used for rootless containers, because we currently
|
||||
+// cannot manage cgroups if we are in a rootless setup. This manager is chosen
|
||||
+// by factory if we are in rootless mode. We error out if any cgroup options are
|
||||
+// set in the config -- this may change in the future with upcoming kernel features
|
||||
+// like the cgroup namespace.
|
||||
+
|
||||
+type Manager struct {
|
||||
+ Cgroups *configs.Cgroup
|
||||
+ Paths map[string]string
|
||||
+}
|
||||
+
|
||||
+func (m *Manager) Apply(pid int) error {
|
||||
+ // If there are no cgroup settings, there's nothing to do.
|
||||
+ if m.Cgroups == nil {
|
||||
+ return nil
|
||||
+ }
|
||||
+
|
||||
+ // We can't set paths.
|
||||
+ // TODO(cyphar): Implement the case where the runner of a rootless container
|
||||
+ // owns their own cgroup, which would allow us to set up a
|
||||
+ // cgroup for each path.
|
||||
+ if m.Cgroups.Paths != nil {
|
||||
+ return fmt.Errorf("cannot change cgroup path in rootless container")
|
||||
+ }
|
||||
+
|
||||
+ // We load the paths into the manager.
|
||||
+ paths := make(map[string]string)
|
||||
+ for _, sys := range subsystems {
|
||||
+ name := sys.Name()
|
||||
+
|
||||
+ path, err := cgroups.GetOwnCgroupPath(name)
|
||||
+ if err != nil {
|
||||
+ // Ignore paths we couldn't resolve.
|
||||
+ continue
|
||||
+ }
|
||||
+
|
||||
+ paths[name] = path
|
||||
+ }
|
||||
+
|
||||
+ m.Paths = paths
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+func (m *Manager) GetPaths() map[string]string {
|
||||
+ return m.Paths
|
||||
+}
|
||||
+
|
||||
+func (m *Manager) Set(container *configs.Config) error {
|
||||
+ // We have to re-do the validation here, since someone might decide to
|
||||
+ // update a rootless container.
|
||||
+ return validate.New().Validate(container)
|
||||
+}
|
||||
+
|
||||
+func (m *Manager) GetPids() ([]int, error) {
|
||||
+ dir, err := cgroups.GetOwnCgroupPath("devices")
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ return cgroups.GetPids(dir)
|
||||
+}
|
||||
+
|
||||
+func (m *Manager) GetAllPids() ([]int, error) {
|
||||
+ dir, err := cgroups.GetOwnCgroupPath("devices")
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ return cgroups.GetAllPids(dir)
|
||||
+}
|
||||
+
|
||||
+func (m *Manager) GetStats() (*cgroups.Stats, error) {
|
||||
+ // TODO(cyphar): We can make this work if we figure out a way to allow usage
|
||||
+ // of cgroups with a rootless container. While this doesn't
|
||||
+ // actually require write access to a cgroup directory, the
|
||||
+ // statistics are not useful if they can be affected by
|
||||
+ // non-container processes.
|
||||
+ return nil, fmt.Errorf("cannot get cgroup stats in rootless container")
|
||||
+}
|
||||
+
|
||||
+func (m *Manager) Freeze(state configs.FreezerState) error {
|
||||
+ // TODO(cyphar): We can make this work if we figure out a way to allow usage
|
||||
+ // of cgroups with a rootless container.
|
||||
+ return fmt.Errorf("cannot use freezer cgroup in rootless container")
|
||||
+}
|
||||
+
|
||||
+func (m *Manager) Destroy() error {
|
||||
+ // We don't have to do anything here because we didn't do any setup.
|
||||
+ return nil
|
||||
+}
|
||||
diff --git a/libcontainer/cgroups/systemd/apply_systemd.go b/libcontainer/cgroups/systemd/apply_systemd.go
|
||||
index 2872bfa..456c57d 100644
|
||||
--- a/libcontainer/cgroups/systemd/apply_systemd.go
|
||||
+++ b/libcontainer/cgroups/systemd/apply_systemd.go
|
||||
@@ -426,7 +426,7 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
- initPath, err := cgroups.GetInitCgroupDir(subsystem)
|
||||
+ initPath, err := cgroups.GetInitCgroup(subsystem)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go
|
||||
index 52fc87e..5db3734 100644
|
||||
--- a/libcontainer/cgroups/utils.go
|
||||
+++ b/libcontainer/cgroups/utils.go
|
||||
@@ -109,7 +109,7 @@ type Mount struct {
|
||||
Subsystems []string
|
||||
}
|
||||
|
||||
-func (m Mount) GetThisCgroupDir(cgroups map[string]string) (string, error) {
|
||||
+func (m Mount) GetOwnCgroup(cgroups map[string]string) (string, error) {
|
||||
if len(m.Subsystems) == 0 {
|
||||
return "", fmt.Errorf("no subsystem for mount")
|
||||
}
|
||||
@@ -203,8 +203,8 @@ func GetAllSubsystems() ([]string, error) {
|
||||
return subsystems, nil
|
||||
}
|
||||
|
||||
-// GetThisCgroupDir returns the relative path to the cgroup docker is running in.
|
||||
-func GetThisCgroupDir(subsystem string) (string, error) {
|
||||
+// GetOwnCgroup returns the relative path to the cgroup docker is running in.
|
||||
+func GetOwnCgroup(subsystem string) (string, error) {
|
||||
cgroups, err := ParseCgroupFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -213,8 +213,16 @@ func GetThisCgroupDir(subsystem string) (string, error) {
|
||||
return getControllerPath(subsystem, cgroups)
|
||||
}
|
||||
|
||||
-func GetInitCgroupDir(subsystem string) (string, error) {
|
||||
+func GetOwnCgroupPath(subsystem string) (string, error) {
|
||||
+ cgroup, err := GetOwnCgroup(subsystem)
|
||||
+ if err != nil {
|
||||
+ return "", err
|
||||
+ }
|
||||
|
||||
+ return getCgroupPathHelper(subsystem, cgroup)
|
||||
+}
|
||||
+
|
||||
+func GetInitCgroup(subsystem string) (string, error) {
|
||||
cgroups, err := ParseCgroupFile("/proc/1/cgroup")
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -223,6 +231,31 @@ func GetInitCgroupDir(subsystem string) (string, error) {
|
||||
return getControllerPath(subsystem, cgroups)
|
||||
}
|
||||
|
||||
+func GetInitCgroupPath(subsystem string) (string, error) {
|
||||
+ cgroup, err := GetInitCgroup(subsystem)
|
||||
+ if err != nil {
|
||||
+ return "", err
|
||||
+ }
|
||||
+
|
||||
+ return getCgroupPathHelper(subsystem, cgroup)
|
||||
+}
|
||||
+
|
||||
+func getCgroupPathHelper(subsystem, cgroup string) (string, error) {
|
||||
+ mnt, root, err := FindCgroupMountpointAndRoot(subsystem)
|
||||
+ if err != nil {
|
||||
+ return "", err
|
||||
+ }
|
||||
+
|
||||
+ // This is needed for nested containers, because in /proc/self/cgroup we
|
||||
+ // see pathes from host, which don't exist in container.
|
||||
+ relCgroup, err := filepath.Rel(root, cgroup)
|
||||
+ if err != nil {
|
||||
+ return "", err
|
||||
+ }
|
||||
+
|
||||
+ return filepath.Join(mnt, relCgroup), nil
|
||||
+}
|
||||
+
|
||||
func readProcsFile(dir string) ([]int, error) {
|
||||
f, err := os.Open(filepath.Join(dir, CgroupProcesses))
|
||||
if err != nil {
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 372763a..d847f18 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -520,10 +520,18 @@ func (c *linuxContainer) Resume() error {
|
||||
}
|
||||
|
||||
func (c *linuxContainer) NotifyOOM() (<-chan struct{}, error) {
|
||||
+ // XXX(cyphar): This requires cgroups.
|
||||
+ if c.config.Rootless {
|
||||
+ return nil, fmt.Errorf("cannot get OOM notifications from rootless container")
|
||||
+ }
|
||||
return notifyOnOOM(c.cgroupManager.GetPaths())
|
||||
}
|
||||
|
||||
func (c *linuxContainer) NotifyMemoryPressure(level PressureLevel) (<-chan struct{}, error) {
|
||||
+ // XXX(cyphar): This requires cgroups.
|
||||
+ if c.config.Rootless {
|
||||
+ return nil, fmt.Errorf("cannot get memory pressure notifications from rootless container")
|
||||
+ }
|
||||
return notifyMemoryPressure(c.cgroupManager.GetPaths(), level)
|
||||
}
|
||||
|
||||
diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go
|
||||
index d553287..1f965e6 100644
|
||||
--- a/libcontainer/factory_linux.go
|
||||
+++ b/libcontainer/factory_linux.go
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
||||
+ "github.com/opencontainers/runc/libcontainer/cgroups/rootless"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/configs/validate"
|
||||
@@ -73,6 +74,20 @@ func Cgroupfs(l *LinuxFactory) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
+// RootlessCgroups is an options func to configure a LinuxFactory to
|
||||
+// return containers that use the "rootless" cgroup manager, which will
|
||||
+// fail to do any operations not possible to do with an unprivileged user.
|
||||
+// It should only be used in conjunction with rootless containers.
|
||||
+func RootlessCgroups(l *LinuxFactory) error {
|
||||
+ l.NewCgroupsManager = func(config *configs.Cgroup, paths map[string]string) cgroups.Manager {
|
||||
+ return &rootless.Manager{
|
||||
+ Cgroups: config,
|
||||
+ Paths: paths,
|
||||
+ }
|
||||
+ }
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
// TmpfsRoot is an option func to mount LinuxFactory.Root to tmpfs.
|
||||
func TmpfsRoot(l *LinuxFactory) error {
|
||||
mounted, err := mount.Mounted(l.Root)
|
||||
@@ -169,6 +184,9 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
|
||||
if err := os.Chown(containerRoot, uid, gid); err != nil {
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
+ if config.Rootless {
|
||||
+ RootlessCgroups(l)
|
||||
+ }
|
||||
c := &linuxContainer{
|
||||
id: id,
|
||||
root: containerRoot,
|
||||
@@ -195,6 +213,10 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
|
||||
processStartTime: state.InitProcessStartTime,
|
||||
fds: state.ExternalDescriptors,
|
||||
}
|
||||
+ // We have to use the RootlessManager.
|
||||
+ if state.Rootless {
|
||||
+ RootlessCgroups(l)
|
||||
+ }
|
||||
c := &linuxContainer{
|
||||
initProcess: r,
|
||||
initProcessStartTime: state.InitProcessStartTime,
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index e8b7506..bfe9955 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -254,15 +254,14 @@ func (p *initProcess) start() error {
|
||||
return newSystemErrorWithCausef(err, "getting pipe fds for pid %d", p.pid())
|
||||
}
|
||||
p.setExternalDescriptors(fds)
|
||||
- if !p.container.config.Rootless {
|
||||
- // Do this before syncing with child so that no children can escape the
|
||||
- // cgroup. We can't do this if we're not running as root.
|
||||
- if err := p.manager.Apply(p.pid()); err != nil {
|
||||
- return newSystemErrorWithCause(err, "applying cgroup configuration for process")
|
||||
- }
|
||||
+ // Do this before syncing with child so that no children can escape the
|
||||
+ // cgroup. We don't need to worry about not doing this and not being root
|
||||
+ // because we'd be using the rootless cgroup manager in that case.
|
||||
+ if err := p.manager.Apply(p.pid()); err != nil {
|
||||
+ return newSystemErrorWithCause(err, "applying cgroup configuration for process")
|
||||
}
|
||||
defer func() {
|
||||
- if err != nil && !p.container.config.Rootless {
|
||||
+ if err != nil {
|
||||
// TODO: should not be the responsibility to call here
|
||||
p.manager.Destroy()
|
||||
}
|
||||
@@ -281,11 +280,8 @@ func (p *initProcess) start() error {
|
||||
ierr := parseSync(p.parentPipe, func(sync *syncT) error {
|
||||
switch sync.Type {
|
||||
case procReady:
|
||||
- // We can't set cgroups if we're in a rootless container.
|
||||
- if !p.container.config.Rootless {
|
||||
- if err := p.manager.Set(p.config.Config); err != nil {
|
||||
- return newSystemErrorWithCause(err, "setting cgroup config for ready process")
|
||||
- }
|
||||
+ if err := p.manager.Set(p.config.Config); err != nil {
|
||||
+ return newSystemErrorWithCause(err, "setting cgroup config for ready process")
|
||||
}
|
||||
// set rlimits, this has to be done here because we lose permissions
|
||||
// to raise the limits once we enter a user-namespace
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index 1045a45..d507373 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -348,7 +348,7 @@ func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
|
||||
var binds []*configs.Mount
|
||||
|
||||
for _, mm := range mounts {
|
||||
- dir, err := mm.GetThisCgroupDir(cgroupPaths)
|
||||
+ dir, err := mm.GetOwnCgroup(cgroupPaths)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
256
patch/0007-libcontainer-configs-add-proper-HostUID-and.patch
Normal file
256
patch/0007-libcontainer-configs-add-proper-HostUID-and.patch
Normal file
@ -0,0 +1,256 @@
|
||||
From f139024bb220e087a20e8089b5dbd4fb4c06c4a8 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Sat, 18 Mar 2017 04:32:16 +1100
|
||||
Subject: [PATCH 07/94] libcontainer: configs: add proper HostUID and
|
||||
HostGID
|
||||
|
||||
Previously Host{U,G}ID only gave you the root mapping, which isn't very
|
||||
useful if you are trying to do other things with the IDMaps.
|
||||
|
||||
Change-Id: Idceb42455e258e5514c966fe8363693adb9d0028
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
libcontainer/configs/config_unix.go | 40 ++++++++++++++++++++-----------
|
||||
libcontainer/configs/config_unix_test.go | 16 ++++++-------
|
||||
libcontainer/configs/validate/rootless.go | 4 ++--
|
||||
libcontainer/container_linux.go | 4 ++--
|
||||
libcontainer/factory_linux.go | 4 ++--
|
||||
libcontainer/specconv/spec_linux.go | 4 ++--
|
||||
utils_linux.go | 4 ++--
|
||||
7 files changed, 44 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/config_unix.go b/libcontainer/configs/config_unix.go
|
||||
index a60554a..8446399 100644
|
||||
--- a/libcontainer/configs/config_unix.go
|
||||
+++ b/libcontainer/configs/config_unix.go
|
||||
@@ -4,38 +4,50 @@ package configs
|
||||
|
||||
import "fmt"
|
||||
|
||||
-// HostUID gets the root uid for the process on host which could be non-zero
|
||||
-// when user namespaces are enabled.
|
||||
-func (c Config) HostUID() (int, error) {
|
||||
+// HostUID gets the translated uid for the process on host which could be
|
||||
+// different when user namespaces are enabled.
|
||||
+func (c Config) HostUID(containerId int) (int, error) {
|
||||
if c.Namespaces.Contains(NEWUSER) {
|
||||
if c.UidMappings == nil {
|
||||
- return -1, fmt.Errorf("User namespaces enabled, but no user mappings found.")
|
||||
+ return -1, fmt.Errorf("User namespaces enabled, but no uid mappings found.")
|
||||
}
|
||||
- id, found := c.hostIDFromMapping(0, c.UidMappings)
|
||||
+ id, found := c.hostIDFromMapping(containerId, c.UidMappings)
|
||||
if !found {
|
||||
- return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
|
||||
+ return -1, fmt.Errorf("User namespaces enabled, but no user mapping found.")
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
- // Return default root uid 0
|
||||
- return 0, nil
|
||||
+ // Return unchanged id.
|
||||
+ return containerId, nil
|
||||
}
|
||||
|
||||
-// HostGID gets the root gid for the process on host which could be non-zero
|
||||
+// HostRootUID gets the root uid for the process on host which could be non-zero
|
||||
// when user namespaces are enabled.
|
||||
-func (c Config) HostGID() (int, error) {
|
||||
+func (c Config) HostRootUID() (int, error) {
|
||||
+ return c.HostUID(0)
|
||||
+}
|
||||
+
|
||||
+// HostGID gets the translated gid for the process on host which could be
|
||||
+// different when user namespaces are enabled.
|
||||
+func (c Config) HostGID(containerId int) (int, error) {
|
||||
if c.Namespaces.Contains(NEWUSER) {
|
||||
if c.GidMappings == nil {
|
||||
return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
|
||||
}
|
||||
- id, found := c.hostIDFromMapping(0, c.GidMappings)
|
||||
+ id, found := c.hostIDFromMapping(containerId, c.GidMappings)
|
||||
if !found {
|
||||
- return -1, fmt.Errorf("User namespaces enabled, but no root group mapping found.")
|
||||
+ return -1, fmt.Errorf("User namespaces enabled, but no group mapping found.")
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
- // Return default root gid 0
|
||||
- return 0, nil
|
||||
+ // Return unchanged id.
|
||||
+ return containerId, nil
|
||||
+}
|
||||
+
|
||||
+// HostRootGID gets the root gid for the process on host which could be non-zero
|
||||
+// when user namespaces are enabled.
|
||||
+func (c Config) HostRootGID() (int, error) {
|
||||
+ return c.HostGID(0)
|
||||
}
|
||||
|
||||
// Utility function that gets a host ID for a container ID from user namespace map
|
||||
diff --git a/libcontainer/configs/config_unix_test.go b/libcontainer/configs/config_unix_test.go
|
||||
index dc01cd0..7f96615 100644
|
||||
--- a/libcontainer/configs/config_unix_test.go
|
||||
+++ b/libcontainer/configs/config_unix_test.go
|
||||
@@ -65,11 +65,11 @@ func TestRemoveNamespace(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
-func TestHostUIDNoUSERNS(t *testing.T) {
|
||||
+func TestHostRootUIDNoUSERNS(t *testing.T) {
|
||||
config := &Config{
|
||||
Namespaces: Namespaces{},
|
||||
}
|
||||
- uid, err := config.HostUID()
|
||||
+ uid, err := config.HostRootUID()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -78,7 +78,7 @@ func TestHostUIDNoUSERNS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
-func TestHostUIDWithUSERNS(t *testing.T) {
|
||||
+func TestHostRootUIDWithUSERNS(t *testing.T) {
|
||||
config := &Config{
|
||||
Namespaces: Namespaces{{Type: NEWUSER}},
|
||||
UidMappings: []IDMap{
|
||||
@@ -89,7 +89,7 @@ func TestHostUIDWithUSERNS(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
- uid, err := config.HostUID()
|
||||
+ uid, err := config.HostRootUID()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -98,11 +98,11 @@ func TestHostUIDWithUSERNS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
-func TestHostGIDNoUSERNS(t *testing.T) {
|
||||
+func TestHostRootGIDNoUSERNS(t *testing.T) {
|
||||
config := &Config{
|
||||
Namespaces: Namespaces{},
|
||||
}
|
||||
- uid, err := config.HostGID()
|
||||
+ uid, err := config.HostRootGID()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func TestHostGIDNoUSERNS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
-func TestHostGIDWithUSERNS(t *testing.T) {
|
||||
+func TestHostRootGIDWithUSERNS(t *testing.T) {
|
||||
config := &Config{
|
||||
Namespaces: Namespaces{{Type: NEWUSER}},
|
||||
GidMappings: []IDMap{
|
||||
@@ -122,7 +122,7 @@ func TestHostGIDWithUSERNS(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
- uid, err := config.HostGID()
|
||||
+ uid, err := config.HostRootGID()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
diff --git a/libcontainer/configs/validate/rootless.go b/libcontainer/configs/validate/rootless.go
|
||||
index 1e83ced..0cebfaf 100644
|
||||
--- a/libcontainer/configs/validate/rootless.go
|
||||
+++ b/libcontainer/configs/validate/rootless.go
|
||||
@@ -37,7 +37,7 @@ func (v *ConfigValidator) rootless(config *configs.Config) error {
|
||||
}
|
||||
|
||||
func rootlessMappings(config *configs.Config) error {
|
||||
- rootuid, err := config.HostUID()
|
||||
+ rootuid, err := config.HostRootUID()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get root uid from uidMappings: %v", err)
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func rootlessMappings(config *configs.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
- rootgid, err := config.HostGID()
|
||||
+ rootgid, err := config.HostRootGID()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get root gid from gidMappings: %v", err)
|
||||
}
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index d847f18..71fa682 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -307,11 +307,11 @@ func (c *linuxContainer) Signal(s os.Signal, all bool) error {
|
||||
}
|
||||
|
||||
func (c *linuxContainer) createExecFifo() error {
|
||||
- rootuid, err := c.Config().HostUID()
|
||||
+ rootuid, err := c.Config().HostRootUID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
- rootgid, err := c.Config().HostGID()
|
||||
+ rootgid, err := c.Config().HostRootGID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go
|
||||
index 1f965e6..6a0f855 100644
|
||||
--- a/libcontainer/factory_linux.go
|
||||
+++ b/libcontainer/factory_linux.go
|
||||
@@ -164,11 +164,11 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
|
||||
if err := l.Validator.Validate(config); err != nil {
|
||||
return nil, newGenericError(err, ConfigInvalid)
|
||||
}
|
||||
- uid, err := config.HostUID()
|
||||
+ uid, err := config.HostRootUID()
|
||||
if err != nil {
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
- gid, err := config.HostGID()
|
||||
+ gid, err := config.HostRootGID()
|
||||
if err != nil {
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
|
||||
index 346b268..1575ae0 100644
|
||||
--- a/libcontainer/specconv/spec_linux.go
|
||||
+++ b/libcontainer/specconv/spec_linux.go
|
||||
@@ -610,11 +610,11 @@ func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
|
||||
for _, m := range spec.Linux.GIDMappings {
|
||||
config.GidMappings = append(config.GidMappings, create(m))
|
||||
}
|
||||
- rootUID, err := config.HostUID()
|
||||
+ rootUID, err := config.HostRootUID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
- rootGID, err := config.HostGID()
|
||||
+ rootGID, err := config.HostRootGID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
diff --git a/utils_linux.go b/utils_linux.go
|
||||
index 767015e..c6a8c02 100644
|
||||
--- a/utils_linux.go
|
||||
+++ b/utils_linux.go
|
||||
@@ -242,12 +242,12 @@ func (r *runner) run(config *specs.Process) (int, error) {
|
||||
for i := baseFd; i < baseFd+r.preserveFDs; i++ {
|
||||
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "PreserveFD:"+strconv.Itoa(i)))
|
||||
}
|
||||
- rootuid, err := r.container.Config().HostUID()
|
||||
+ rootuid, err := r.container.Config().HostRootUID()
|
||||
if err != nil {
|
||||
r.destroy()
|
||||
return -1, err
|
||||
}
|
||||
- rootgid, err := r.container.Config().HostGID()
|
||||
+ rootgid, err := r.container.Config().HostRootGID()
|
||||
if err != nil {
|
||||
r.destroy()
|
||||
return -1, err
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
64
patch/0008-libcontainer-init-fix-unmapped-console-fcho.patch
Normal file
64
patch/0008-libcontainer-init-fix-unmapped-console-fcho.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From f4158e00cac1f576f61904a73530c373c15354e2 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Sat, 18 Mar 2017 04:33:14 +1100
|
||||
Subject: [PATCH 08/94] libcontainer: init: fix unmapped console
|
||||
fchown
|
||||
|
||||
If the stdio of the container is owned by a group which is not mapped in
|
||||
the user namespace, attempting to fchown the file descriptor will result
|
||||
in EINVAL. Counteract this by simply not doing an fchown if the group
|
||||
owner of the file descriptor has no host mapping according to the
|
||||
configured GIDMappings.
|
||||
|
||||
Change-Id: I7a7911f398a38b2d21e1bb6bc4b3131f6504ca8d
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
libcontainer/init_linux.go | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go
|
||||
index 1187835..99cc02c 100644
|
||||
--- a/libcontainer/init_linux.go
|
||||
+++ b/libcontainer/init_linux.go
|
||||
@@ -277,7 +277,7 @@ func setupUser(config *initConfig) error {
|
||||
|
||||
// before we change to the container's user make sure that the processes STDIO
|
||||
// is correctly owned by the user that we are switching to.
|
||||
- if err := fixStdioPermissions(execUser); err != nil {
|
||||
+ if err := fixStdioPermissions(config, execUser); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ func setupUser(config *initConfig) error {
|
||||
// fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user.
|
||||
// The ownership needs to match because it is created outside of the container and needs to be
|
||||
// localized.
|
||||
-func fixStdioPermissions(u *user.ExecUser) error {
|
||||
+func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
|
||||
var null syscall.Stat_t
|
||||
if err := syscall.Stat("/dev/null", &null); err != nil {
|
||||
return err
|
||||
@@ -326,10 +326,20 @@ func fixStdioPermissions(u *user.ExecUser) error {
|
||||
if err := syscall.Fstat(int(fd), &s); err != nil {
|
||||
return err
|
||||
}
|
||||
+
|
||||
// Skip chown of /dev/null if it was used as one of the STDIO fds.
|
||||
if s.Rdev == null.Rdev {
|
||||
continue
|
||||
}
|
||||
+
|
||||
+ // Skip chown if s.Gid is actually an unmapped gid in the host. While
|
||||
+ // this is a bit dodgy if it just so happens that the console _is_
|
||||
+ // owned by overflow_gid, there's no way for us to disambiguate this as
|
||||
+ // a userspace program.
|
||||
+ if _, err := config.Config.HostGID(int(s.Gid)); err != nil {
|
||||
+ continue
|
||||
+ }
|
||||
+
|
||||
// We only change the uid owner (as it is possible for the mount to
|
||||
// prefer a different gid, and there's no reason for us to change it).
|
||||
// The reason why we don't just leave the default uid=X mount setup is
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
203
patch/0009-rootless-add-autogenerated-rootless-config-.patch
Normal file
203
patch/0009-rootless-add-autogenerated-rootless-config-.patch
Normal file
@ -0,0 +1,203 @@
|
||||
From bdc84a618b475cc21a39dfa2fe57eae68b6110b6 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Mon, 9 May 2016 21:26:11 +1000
|
||||
Subject: [PATCH 09/94] rootless: add autogenerated rootless config
|
||||
from `runc spec`
|
||||
|
||||
Since this is a runC-specific feature, this belongs here over in
|
||||
opencontainers/ocitools (which is for generic OCI runtimes).
|
||||
|
||||
In addition, we don't create a new network namespace. This is because
|
||||
currently if you want to set up a veth bridge you need CAP_NET_ADMIN in
|
||||
both network namespaces' pinned user namespace to create the necessary
|
||||
interfaces in each network namespace.
|
||||
|
||||
Change-Id: I682b9c82f75c04b58d523ddb084b6adbb543e3d1
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
libcontainer/specconv/example.go | 73 ++++++++++++++++++++++++++++++--
|
||||
libcontainer/specconv/spec_linux_test.go | 30 +++----------
|
||||
spec.go | 11 ++++-
|
||||
3 files changed, 85 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/specconv/example.go b/libcontainer/specconv/example.go
|
||||
index 44fad97..9a4460c 100644
|
||||
--- a/libcontainer/specconv/example.go
|
||||
+++ b/libcontainer/specconv/example.go
|
||||
@@ -1,16 +1,18 @@
|
||||
package specconv
|
||||
|
||||
import (
|
||||
+ "os"
|
||||
"runtime"
|
||||
+ "strings"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
func sPtr(s string) *string { return &s }
|
||||
|
||||
-// ExampleSpec returns an example spec file, with many options set so a user
|
||||
-// can see what a standard spec file looks like.
|
||||
-func ExampleSpec() *specs.Spec {
|
||||
+// Example returns an example spec file, with many options set so a user can
|
||||
+// see what a standard spec file looks like.
|
||||
+func Example() *specs.Spec {
|
||||
return &specs.Spec{
|
||||
Version: specs.Version,
|
||||
Platform: specs.Platform{
|
||||
@@ -158,3 +160,68 @@ func ExampleSpec() *specs.Spec {
|
||||
},
|
||||
}
|
||||
}
|
||||
+
|
||||
+// ExampleRootless returns an example spec file that works with rootless
|
||||
+// containers. It's essentially a modified version of the specfile from
|
||||
+// Example().
|
||||
+func ToRootless(spec *specs.Spec) {
|
||||
+ var namespaces []specs.LinuxNamespace
|
||||
+
|
||||
+ // Remove networkns from the spec.
|
||||
+ for _, ns := range spec.Linux.Namespaces {
|
||||
+ switch ns.Type {
|
||||
+ case specs.NetworkNamespace, specs.UserNamespace:
|
||||
+ // Do nothing.
|
||||
+ default:
|
||||
+ namespaces = append(namespaces, ns)
|
||||
+ }
|
||||
+ }
|
||||
+ // Add userns to the spec.
|
||||
+ namespaces = append(namespaces, specs.LinuxNamespace{
|
||||
+ Type: specs.UserNamespace,
|
||||
+ })
|
||||
+ spec.Linux.Namespaces = namespaces
|
||||
+
|
||||
+ // Add mappings for the current user.
|
||||
+ spec.Linux.UIDMappings = []specs.LinuxIDMapping{{
|
||||
+ HostID: uint32(os.Geteuid()),
|
||||
+ ContainerID: 0,
|
||||
+ Size: 1,
|
||||
+ }}
|
||||
+ spec.Linux.GIDMappings = []specs.LinuxIDMapping{{
|
||||
+ HostID: uint32(os.Getegid()),
|
||||
+ ContainerID: 0,
|
||||
+ Size: 1,
|
||||
+ }}
|
||||
+
|
||||
+ // Fix up mounts.
|
||||
+ var mounts []specs.Mount
|
||||
+ for _, mount := range spec.Mounts {
|
||||
+ // Ignore all mounts that are under /sys.
|
||||
+ if strings.HasPrefix(mount.Destination, "/sys") {
|
||||
+ continue
|
||||
+ }
|
||||
+
|
||||
+ // Remove all gid= and uid= mappings.
|
||||
+ var options []string
|
||||
+ for _, option := range mount.Options {
|
||||
+ if !strings.HasPrefix(option, "gid=") && !strings.HasPrefix(option, "uid=") {
|
||||
+ options = append(options, option)
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mount.Options = options
|
||||
+ mounts = append(mounts, mount)
|
||||
+ }
|
||||
+ // Add the sysfs mount as an rbind.
|
||||
+ mounts = append(mounts, specs.Mount{
|
||||
+ Source: "/sys",
|
||||
+ Destination: "/sys",
|
||||
+ Type: "none",
|
||||
+ Options: []string{"rbind", "nosuid", "noexec", "nodev", "ro"},
|
||||
+ })
|
||||
+ spec.Mounts = mounts
|
||||
+
|
||||
+ // Remove cgroup settings.
|
||||
+ spec.Linux.Resources = nil
|
||||
+}
|
||||
diff --git a/libcontainer/specconv/spec_linux_test.go b/libcontainer/specconv/spec_linux_test.go
|
||||
index 741fae6..f7292f3 100644
|
||||
--- a/libcontainer/specconv/spec_linux_test.go
|
||||
+++ b/libcontainer/specconv/spec_linux_test.go
|
||||
@@ -3,7 +3,6 @@
|
||||
package specconv
|
||||
|
||||
import (
|
||||
- "os"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs/validate"
|
||||
@@ -53,8 +52,9 @@ func TestLinuxCgroupsPathNotSpecified(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSpecconvExampleValidate(t *testing.T) {
|
||||
- spec := ExampleSpec()
|
||||
+ spec := Example()
|
||||
spec.Root.Path = "/"
|
||||
+
|
||||
opts := &CreateOpts{
|
||||
CgroupName: "ContainerID",
|
||||
UseSystemdCgroup: false,
|
||||
@@ -97,29 +97,9 @@ func TestDupNamespaces(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRootlessSpecconvValidate(t *testing.T) {
|
||||
- spec := &specs.Spec{
|
||||
- Linux: specs.Linux{
|
||||
- Namespaces: []specs.Namespace{
|
||||
- {
|
||||
- Type: specs.UserNamespace,
|
||||
- },
|
||||
- },
|
||||
- UIDMappings: []specs.IDMapping{
|
||||
- {
|
||||
- HostID: uint32(os.Geteuid()),
|
||||
- ContainerID: 0,
|
||||
- Size: 1,
|
||||
- },
|
||||
- },
|
||||
- GIDMappings: []specs.IDMapping{
|
||||
- {
|
||||
- HostID: uint32(os.Getegid()),
|
||||
- ContainerID: 0,
|
||||
- Size: 1,
|
||||
- },
|
||||
- },
|
||||
- },
|
||||
- }
|
||||
+ spec := Example()
|
||||
+ spec.Root.Path = "/"
|
||||
+ ToRootless(spec)
|
||||
|
||||
opts := &CreateOpts{
|
||||
CgroupName: "ContainerID",
|
||||
diff --git a/spec.go b/spec.go
|
||||
index d7df312..9024ad4 100644
|
||||
--- a/spec.go
|
||||
+++ b/spec.go
|
||||
@@ -64,12 +64,21 @@ container on your host.`,
|
||||
Value: "",
|
||||
Usage: "path to the root of the bundle directory",
|
||||
},
|
||||
+ cli.BoolFlag{
|
||||
+ Name: "rootless",
|
||||
+ Usage: "generate a configuration for a rootless container",
|
||||
+ },
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
if err := checkArgs(context, 0, exactArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
- spec := specconv.ExampleSpec()
|
||||
+ spec := specconv.Example()
|
||||
+
|
||||
+ rootless := context.Bool("rootless")
|
||||
+ if rootless {
|
||||
+ specconv.ToRootless(spec)
|
||||
+ }
|
||||
|
||||
checkNoFile := func(name string) error {
|
||||
_, err := os.Stat(name)
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
143
patch/0010-integration-added-root-requires.patch
Normal file
143
patch/0010-integration-added-root-requires.patch
Normal file
@ -0,0 +1,143 @@
|
||||
From 7c81f032861f5654e9063e5af82c7794401682f4 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Tue, 10 May 2016 22:22:13 +1000
|
||||
Subject: [PATCH 10/94] integration: added root requires
|
||||
|
||||
This is in preperation of allowing us to run the integration test suite
|
||||
on rootless containers.
|
||||
|
||||
Change-Id: I38f7115df4f931857659892b07745c86507d14bf
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
tests/integration/cgroups.bats | 8 ++++++--
|
||||
tests/integration/checkpoint.bats | 3 ++-
|
||||
tests/integration/helpers.bash | 10 +++++++++-
|
||||
tests/integration/kill.bats | 1 -
|
||||
tests/integration/pause.bats | 6 ++++++
|
||||
tests/integration/update.bats | 6 +++++-
|
||||
6 files changed, 28 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tests/integration/cgroups.bats b/tests/integration/cgroups.bats
|
||||
index 9ab6f43..90095a7 100644
|
||||
--- a/tests/integration/cgroups.bats
|
||||
+++ b/tests/integration/cgroups.bats
|
||||
@@ -28,7 +28,9 @@ function check_cgroup_value() {
|
||||
}
|
||||
|
||||
@test "runc update --kernel-memory (initialized)" {
|
||||
- requires cgroups_kmem
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ requires cgroups_kmem root
|
||||
+
|
||||
# Add cgroup path
|
||||
sed -i 's/\("linux": {\)/\1\n "cgroupsPath": "\/runc-cgroups-integration-test",/' ${BUSYBOX_BUNDLE}/config.json
|
||||
|
||||
@@ -56,7 +58,9 @@ EOF
|
||||
}
|
||||
|
||||
@test "runc update --kernel-memory (uninitialized)" {
|
||||
- requires cgroups_kmem
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ requires cgroups_kmem root
|
||||
+
|
||||
# Add cgroup path
|
||||
sed -i 's/\("linux": {\)/\1\n "cgroupsPath": "\/runc-cgroups-integration-test",/' ${BUSYBOX_BUNDLE}/config.json
|
||||
|
||||
diff --git a/tests/integration/checkpoint.bats b/tests/integration/checkpoint.bats
|
||||
index 34d1b03..e91fd65 100644
|
||||
--- a/tests/integration/checkpoint.bats
|
||||
+++ b/tests/integration/checkpoint.bats
|
||||
@@ -12,7 +12,8 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "checkpoint and restore" {
|
||||
- requires criu
|
||||
+ # XXX: currently criu require root containers.
|
||||
+ requires criu root
|
||||
|
||||
# criu does not work with external terminals so..
|
||||
# setting terminal and root:readonly: to false
|
||||
diff --git a/tests/integration/helpers.bash b/tests/integration/helpers.bash
|
||||
index e4c2cb9..6548333 100644
|
||||
--- a/tests/integration/helpers.bash
|
||||
+++ b/tests/integration/helpers.bash
|
||||
@@ -40,6 +40,9 @@ CGROUP_CPU_BASE_PATH=$(grep "cgroup" /proc/self/mountinfo | gawk 'toupper($NF) ~
|
||||
KMEM="${CGROUP_MEMORY_BASE_PATH}/memory.kmem.limit_in_bytes"
|
||||
RT_PERIOD="${CGROUP_CPU_BASE_PATH}/cpu.rt_period_us"
|
||||
|
||||
+# Check if we're in rootless mode.
|
||||
+ROOTLESS=$(id -u)
|
||||
+
|
||||
# Wrapper for runc.
|
||||
function runc() {
|
||||
run __runc "$@"
|
||||
@@ -68,7 +71,12 @@ function requires() {
|
||||
case $var in
|
||||
criu)
|
||||
if [ ! -e "$CRIU" ]; then
|
||||
- skip "Test requires ${var}."
|
||||
+ skip "test requires ${var}"
|
||||
+ fi
|
||||
+ ;;
|
||||
+ root)
|
||||
+ if [ "$ROOTLESS" -ne 0 ]; then
|
||||
+ skip "test requires ${var}"
|
||||
fi
|
||||
;;
|
||||
cgroups_kmem)
|
||||
diff --git a/tests/integration/kill.bats b/tests/integration/kill.bats
|
||||
index a049de6..74246fa 100644
|
||||
--- a/tests/integration/kill.bats
|
||||
+++ b/tests/integration/kill.bats
|
||||
@@ -13,7 +13,6 @@ function teardown() {
|
||||
|
||||
|
||||
@test "kill detached busybox" {
|
||||
-
|
||||
# run busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
diff --git a/tests/integration/pause.bats b/tests/integration/pause.bats
|
||||
index 2f46a6c..30d98b5 100644
|
||||
--- a/tests/integration/pause.bats
|
||||
+++ b/tests/integration/pause.bats
|
||||
@@ -12,6 +12,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc pause and resume" {
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ requires root
|
||||
+
|
||||
# run busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -34,6 +37,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc pause and resume with nonexist container" {
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ requires root
|
||||
+
|
||||
# run test_busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
diff --git a/tests/integration/update.bats b/tests/integration/update.bats
|
||||
index 9aaf1b9..4a6bf7f 100644
|
||||
--- a/tests/integration/update.bats
|
||||
+++ b/tests/integration/update.bats
|
||||
@@ -50,7 +50,11 @@ function check_cgroup_value() {
|
||||
|
||||
# TODO: test rt cgroup updating
|
||||
@test "update" {
|
||||
- requires cgroups_kmem
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ # XXX: Also, this test should be split into separate sections so that we
|
||||
+ # can skip kmem without skipping update tests overall.
|
||||
+ requires cgroups_kmem root
|
||||
+
|
||||
# run a few busyboxes detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_update
|
||||
[ "$status" -eq 0 ]
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
449
patch/0011-tests-add-rootless-integration-tests.patch
Normal file
449
patch/0011-tests-add-rootless-integration-tests.patch
Normal file
@ -0,0 +1,449 @@
|
||||
From c62d731fc7e928e944e0290df318042c46e80526 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Wed, 11 May 2016 17:45:00 +1000
|
||||
Subject: [PATCH 11/94] tests: add rootless integration tests
|
||||
|
||||
This adds targets for rootless integration tests, as well as all of the
|
||||
required setup in order to get the tests to run. This includes quite a
|
||||
few changes, because of a lot of assumptions about things running as
|
||||
root within the bats scripts (which is not true when setting up rootless
|
||||
containers).
|
||||
|
||||
Change-Id: I2fab9fd3ac984e06a7d3e1e1ac0cd888b1543801
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
Dockerfile | 7 ++++++
|
||||
Makefile | 11 +++++++--
|
||||
tests/integration/checkpoint.bats | 5 +++--
|
||||
tests/integration/delete.bats | 2 ++
|
||||
tests/integration/events.bats | 12 ++++++++++
|
||||
tests/integration/exec.bats | 3 +++
|
||||
tests/integration/help.bats | 1 +
|
||||
tests/integration/helpers.bash | 23 ++++++++++++++-----
|
||||
tests/integration/ps.bats | 11 ++++++++-
|
||||
tests/integration/spec.bats | 4 ++--
|
||||
tests/integration/start_detached.bats | 3 +++
|
||||
tests/integration/start_hello.bats | 3 +++
|
||||
tests/integration/state.bats | 42 ++++++++++++++++++++++++++---------
|
||||
tests/integration/tty.bats | 14 ++++++++++++
|
||||
14 files changed, 117 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/Dockerfile b/Dockerfile
|
||||
index c971448..fd9be94 100644
|
||||
--- a/Dockerfile
|
||||
+++ b/Dockerfile
|
||||
@@ -6,6 +6,7 @@ RUN echo 'deb http://httpredir.debian.org/debian jessie-backports main' > /etc/a
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential \
|
||||
curl \
|
||||
+ sudo \
|
||||
gawk \
|
||||
iptables \
|
||||
jq \
|
||||
@@ -22,6 +23,12 @@ RUN apt-get update && apt-get install -y \
|
||||
--no-install-recommends \
|
||||
&& apt-get clean
|
||||
|
||||
+# Add a dummy user for the rootless integration tests. While runC does
|
||||
+# not require an entry in /etc/passwd to operate, one of the tests uses
|
||||
+# `git clone` -- and `git clone` does not allow you to clone a
|
||||
+# repository if the current uid does not have an entry in /etc/passwd.
|
||||
+RUN useradd -u1000 -m -d/home/rootless -s/bin/bash rootless
|
||||
+
|
||||
# install bats
|
||||
RUN cd /tmp \
|
||||
&& git clone https://github.com/sstephenson/bats.git \
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 5fff515..1cecca1 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -79,10 +79,10 @@ runcimage:
|
||||
docker build -t $(RUNC_IMAGE) .
|
||||
|
||||
test:
|
||||
- make unittest integration
|
||||
+ make unittest integration rootlessintegration
|
||||
|
||||
localtest:
|
||||
- make localunittest localintegration
|
||||
+ make localunittest localintegration localrootlessintegration
|
||||
|
||||
unittest: runcimage
|
||||
docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) make localunittest
|
||||
@@ -96,6 +96,13 @@ integration: runcimage
|
||||
localintegration: all
|
||||
bats -t tests/integration${TESTFLAGS}
|
||||
|
||||
+rootlessintegration: runcimage
|
||||
+ docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) --cap-drop=ALL -u rootless $(RUNC_IMAGE) make localintegration
|
||||
+
|
||||
+# FIXME: This should not be separate from rootlessintegration's method of running.
|
||||
+localrootlessintegration: all
|
||||
+ sudo -u rootless -H PATH="${PATH}" bats -t tests/integration${TESTFLAGS}
|
||||
+
|
||||
shell: all
|
||||
docker run -e TESTFLAGS -ti --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) bash
|
||||
|
||||
diff --git a/tests/integration/checkpoint.bats b/tests/integration/checkpoint.bats
|
||||
index e91fd65..cd969a8 100644
|
||||
--- a/tests/integration/checkpoint.bats
|
||||
+++ b/tests/integration/checkpoint.bats
|
||||
@@ -59,8 +59,9 @@ function teardown() {
|
||||
[[ "${output}" == *"running"* ]]
|
||||
}
|
||||
|
||||
-@test "checkpoint(pre-dump) and restore" {
|
||||
- requires criu
|
||||
+@test "checkpoint --pre-dump and restore" {
|
||||
+ # XXX: currently criu require root containers.
|
||||
+ requires criu root
|
||||
|
||||
# criu does not work with external terminals so..
|
||||
# setting terminal and root:readonly: to false
|
||||
diff --git a/tests/integration/delete.bats b/tests/integration/delete.bats
|
||||
index cdadd7d..2c11e79 100644
|
||||
--- a/tests/integration/delete.bats
|
||||
+++ b/tests/integration/delete.bats
|
||||
@@ -22,11 +22,13 @@ function teardown() {
|
||||
testcontainer test_busybox running
|
||||
|
||||
runc kill test_busybox KILL
|
||||
+ [ "$status" -eq 0 ]
|
||||
# wait for busybox to be in the destroyed state
|
||||
retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
|
||||
|
||||
# delete test_busybox
|
||||
runc delete test_busybox
|
||||
+ [ "$status" -eq 0 ]
|
||||
|
||||
runc state test_busybox
|
||||
[ "$status" -ne 0 ]
|
||||
diff --git a/tests/integration/events.bats b/tests/integration/events.bats
|
||||
index 182b721..2350073 100644
|
||||
--- a/tests/integration/events.bats
|
||||
+++ b/tests/integration/events.bats
|
||||
@@ -12,6 +12,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "events --stats" {
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ requires root
|
||||
+
|
||||
# run busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -27,6 +30,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "events --interval default " {
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ requires root
|
||||
+
|
||||
# run busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -54,6 +60,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "events --interval 1s " {
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ requires root
|
||||
+
|
||||
# run busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -80,6 +89,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "events --interval 100ms " {
|
||||
+ # XXX: currently cgroups require root containers.
|
||||
+ requires root
|
||||
+
|
||||
# run busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
diff --git a/tests/integration/exec.bats b/tests/integration/exec.bats
|
||||
index ba60ea1..f172f9b 100644
|
||||
--- a/tests/integration/exec.bats
|
||||
+++ b/tests/integration/exec.bats
|
||||
@@ -112,6 +112,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc exec --user" {
|
||||
+ # --user can't work in rootless containers
|
||||
+ requires root
|
||||
+
|
||||
# run busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
diff --git a/tests/integration/help.bats b/tests/integration/help.bats
|
||||
index ca404f3..163de2d 100644
|
||||
--- a/tests/integration/help.bats
|
||||
+++ b/tests/integration/help.bats
|
||||
@@ -57,6 +57,7 @@ load helpers
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ${lines[1]} =~ runc\ resume+ ]]
|
||||
|
||||
+ # We don't use runc_spec here, because we're just testing the help page.
|
||||
runc spec -h
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ${lines[1]} =~ runc\ spec+ ]]
|
||||
diff --git a/tests/integration/helpers.bash b/tests/integration/helpers.bash
|
||||
index 6548333..fc8c290 100644
|
||||
--- a/tests/integration/helpers.bash
|
||||
+++ b/tests/integration/helpers.bash
|
||||
@@ -4,7 +4,7 @@
|
||||
INTEGRATION_ROOT=$(dirname "$(readlink -f "$BASH_SOURCE")")
|
||||
RUNC="${INTEGRATION_ROOT}/../../runc"
|
||||
RECVTTY="${INTEGRATION_ROOT}/../../contrib/cmd/recvtty/recvtty"
|
||||
-GOPATH="${INTEGRATION_ROOT}/../../../.."
|
||||
+GOPATH="$(mktemp -d --tmpdir runc-integration-gopath.XXXXXX)"
|
||||
|
||||
# Test data path.
|
||||
TESTDATA="${INTEGRATION_ROOT}/testdata"
|
||||
@@ -27,7 +27,7 @@ KERNEL_MINOR="${KERNEL_VERSION#$KERNEL_MAJOR.}"
|
||||
KERNEL_MINOR="${KERNEL_MINOR%%.*}"
|
||||
|
||||
# Root state path.
|
||||
-ROOT="$BATS_TMPDIR/runc"
|
||||
+ROOT=$(mktemp -d "$BATS_TMPDIR/runc.XXXXXX")
|
||||
|
||||
# Path to console socket.
|
||||
CONSOLE_SOCKET="$BATS_TMPDIR/console.sock"
|
||||
@@ -58,6 +58,17 @@ function __runc() {
|
||||
"$RUNC" --root "$ROOT" "$@"
|
||||
}
|
||||
|
||||
+# Wrapper for runc spec.
|
||||
+function runc_spec() {
|
||||
+ local args=""
|
||||
+
|
||||
+ if [ "$ROOTLESS" -ne 0 ]; then
|
||||
+ args+="--rootless"
|
||||
+ fi
|
||||
+
|
||||
+ runc spec $args "$@"
|
||||
+}
|
||||
+
|
||||
# Fails the current test, providing the error given.
|
||||
function fail() {
|
||||
echo "$@" >&2
|
||||
@@ -187,18 +198,18 @@ function setup_busybox() {
|
||||
if [ ! -e $BUSYBOX_IMAGE ]; then
|
||||
curl -o $BUSYBOX_IMAGE -sSL 'https://github.com/docker-library/busybox/raw/a0558a9006ce0dd6f6ec5d56cfd3f32ebeeb815f/glibc/busybox.tar.xz'
|
||||
fi
|
||||
- tar -C "$BUSYBOX_BUNDLE"/rootfs -xf "$BUSYBOX_IMAGE"
|
||||
+ tar --exclude './dev/*' -C "$BUSYBOX_BUNDLE"/rootfs -xf "$BUSYBOX_IMAGE"
|
||||
cd "$BUSYBOX_BUNDLE"
|
||||
- runc spec
|
||||
+ runc_spec
|
||||
}
|
||||
|
||||
function setup_hello() {
|
||||
setup_recvtty
|
||||
run mkdir "$HELLO_BUNDLE"
|
||||
run mkdir "$HELLO_BUNDLE"/rootfs
|
||||
- tar -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
|
||||
+ tar --exclude './dev/*' -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
|
||||
cd "$HELLO_BUNDLE"
|
||||
- runc spec
|
||||
+ runc_spec
|
||||
sed -i 's;"sh";"/hello";' config.json
|
||||
}
|
||||
|
||||
diff --git a/tests/integration/ps.bats b/tests/integration/ps.bats
|
||||
index 7a20015..c000af6 100644
|
||||
--- a/tests/integration/ps.bats
|
||||
+++ b/tests/integration/ps.bats
|
||||
@@ -12,6 +12,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "ps" {
|
||||
+ # ps is not supported, it requires cgroups
|
||||
+ requires root
|
||||
+
|
||||
# start busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -24,10 +27,13 @@ function teardown() {
|
||||
runc ps test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ${lines[0]} =~ UID\ +PID\ +PPID\ +C\ +STIME\ +TTY\ +TIME\ +CMD+ ]]
|
||||
- [[ "${lines[1]}" == *"root"*[0-9]* ]]
|
||||
+ [[ "${lines[1]}" == *"$(id -un 2>/dev/null)"*[0-9]* ]]
|
||||
}
|
||||
|
||||
@test "ps -f json" {
|
||||
+ # ps is not supported, it requires cgroups
|
||||
+ requires root
|
||||
+
|
||||
# start busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -43,6 +49,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "ps -e -x" {
|
||||
+ # ps is not supported, it requires cgroups
|
||||
+ requires root
|
||||
+
|
||||
# start busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
diff --git a/tests/integration/spec.bats b/tests/integration/spec.bats
|
||||
index 79bb690..e9f28fb 100644
|
||||
--- a/tests/integration/spec.bats
|
||||
+++ b/tests/integration/spec.bats
|
||||
@@ -26,7 +26,7 @@ function teardown() {
|
||||
[ ! -e config.json ]
|
||||
|
||||
# test generation of spec does not return an error
|
||||
- runc spec
|
||||
+ runc_spec
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# test generation of spec created our config.json (spec)
|
||||
@@ -51,7 +51,7 @@ function teardown() {
|
||||
[ ! -e "$HELLO_BUNDLE"/config.json ]
|
||||
|
||||
# test generation of spec does not return an error
|
||||
- runc spec --bundle "$HELLO_BUNDLE"
|
||||
+ runc_spec --bundle "$HELLO_BUNDLE"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# test generation of spec created our config.json (spec)
|
||||
diff --git a/tests/integration/start_detached.bats b/tests/integration/start_detached.bats
|
||||
index 605fde2..08036dd 100644
|
||||
--- a/tests/integration/start_detached.bats
|
||||
+++ b/tests/integration/start_detached.bats
|
||||
@@ -23,6 +23,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc run detached ({u,g}id != 0)" {
|
||||
+ # cannot start containers as another user in rootless setup
|
||||
+ requires root
|
||||
+
|
||||
# replace "uid": 0 with "uid": 1000
|
||||
# and do a similar thing for gid.
|
||||
sed -i 's;"uid": 0;"uid": 1000;g' config.json
|
||||
diff --git a/tests/integration/start_hello.bats b/tests/integration/start_hello.bats
|
||||
index 6de65e0..2e93572 100644
|
||||
--- a/tests/integration/start_hello.bats
|
||||
+++ b/tests/integration/start_hello.bats
|
||||
@@ -21,6 +21,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc run ({u,g}id != 0)" {
|
||||
+ # cannot start containers as another user in rootless setup
|
||||
+ requires root
|
||||
+
|
||||
# replace "uid": 0 with "uid": 1000
|
||||
# and do a similar thing for gid.
|
||||
sed -i 's;"uid": 0;"uid": 1000;g' config.json
|
||||
diff --git a/tests/integration/state.bats b/tests/integration/state.bats
|
||||
index eed2eb3..3772c1e 100644
|
||||
--- a/tests/integration/state.bats
|
||||
+++ b/tests/integration/state.bats
|
||||
@@ -11,7 +11,37 @@ function teardown() {
|
||||
teardown_busybox
|
||||
}
|
||||
|
||||
-@test "state" {
|
||||
+@test "state (kill + delete)" {
|
||||
+ runc state test_busybox
|
||||
+ [ "$status" -ne 0 ]
|
||||
+
|
||||
+ # run busybox detached
|
||||
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
+ [ "$status" -eq 0 ]
|
||||
+
|
||||
+ # check state
|
||||
+ wait_for_container 15 1 test_busybox
|
||||
+
|
||||
+ testcontainer test_busybox running
|
||||
+
|
||||
+ runc kill test_busybox KILL
|
||||
+ [ "$status" -eq 0 ]
|
||||
+
|
||||
+ # wait for busybox to be in the destroyed state
|
||||
+ retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
|
||||
+
|
||||
+ # delete test_busybox
|
||||
+ runc delete test_busybox
|
||||
+ [ "$status" -eq 0 ]
|
||||
+
|
||||
+ runc state test_busybox
|
||||
+ [ "$status" -ne 0 ]
|
||||
+}
|
||||
+
|
||||
+@test "state (pause + resume)" {
|
||||
+ # XXX: pause and resume require cgroups.
|
||||
+ requires root
|
||||
+
|
||||
runc state test_busybox
|
||||
[ "$status" -ne 0 ]
|
||||
|
||||
@@ -37,14 +67,4 @@ function teardown() {
|
||||
|
||||
# test state of busybox is back to running
|
||||
testcontainer test_busybox running
|
||||
-
|
||||
- runc kill test_busybox KILL
|
||||
- # wait for busybox to be in the destroyed state
|
||||
- retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
|
||||
-
|
||||
- # delete test_busybox
|
||||
- runc delete test_busybox
|
||||
-
|
||||
- runc state test_busybox
|
||||
- [ "$status" -ne 0 ]
|
||||
}
|
||||
diff --git a/tests/integration/tty.bats b/tests/integration/tty.bats
|
||||
index b9a1f10..9e817db 100644
|
||||
--- a/tests/integration/tty.bats
|
||||
+++ b/tests/integration/tty.bats
|
||||
@@ -24,6 +24,10 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc run [tty owner]" {
|
||||
+ # tty chmod is not doable in rootless containers.
|
||||
+ # TODO: this can be made as a change to the gid test.
|
||||
+ requires root
|
||||
+
|
||||
# Replace sh script with stat.
|
||||
sed -i 's/"sh"/"sh", "-c", "stat -c %u:%g $(tty) | tr : \\\\\\\\n"/' config.json
|
||||
|
||||
@@ -36,6 +40,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc run [tty owner] ({u,g}id != 0)" {
|
||||
+ # tty chmod is not doable in rootless containers.
|
||||
+ requires root
|
||||
+
|
||||
# replace "uid": 0 with "uid": 1000
|
||||
# and do a similar thing for gid.
|
||||
sed -i 's;"uid": 0;"uid": 1000;g' config.json
|
||||
@@ -72,6 +79,10 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc exec [tty owner]" {
|
||||
+ # tty chmod is not doable in rootless containers.
|
||||
+ # TODO: this can be made as a change to the gid test.
|
||||
+ requires root
|
||||
+
|
||||
# run busybox detached
|
||||
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -90,6 +101,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "runc exec [tty owner] ({u,g}id != 0)" {
|
||||
+ # tty chmod is not doable in rootless containers.
|
||||
+ requires root
|
||||
+
|
||||
# replace "uid": 0 with "uid": 1000
|
||||
# and do a similar thing for gid.
|
||||
sed -i 's;"uid": 0;"uid": 1000;g' config.json
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
123561
patch/0012-vendor-add-golang.org-x-sys-unix-9a7256cb28.patch
Normal file
123561
patch/0012-vendor-add-golang.org-x-sys-unix-9a7256cb28.patch
Normal file
File diff suppressed because it is too large
Load Diff
327
patch/0013-libcontainer-rewrite-cmsg-to-use-sys-unix.patch
Normal file
327
patch/0013-libcontainer-rewrite-cmsg-to-use-sys-unix.patch
Normal file
@ -0,0 +1,327 @@
|
||||
From c13a4de91dc2a3db4b9085015dbce2f8e050d7ca Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Wed, 29 Mar 2017 22:39:05 +1100
|
||||
Subject: [PATCH 13/94] libcontainer: rewrite cmsg to use sys/unix
|
||||
|
||||
The original implementation is in C, which increases cognitive load and
|
||||
possibly might cause us problems in the future. Since sys/unix is better
|
||||
maintained than the syscall standard library switching makes more sense.
|
||||
|
||||
Change-Id: I8d91c2d7b28116d3d9be49e328f9383b9b7052d7
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
libcontainer/utils/cmsg.c | 148 ---------------------------------------------
|
||||
libcontainer/utils/cmsg.go | 74 +++++++++++++++++------
|
||||
libcontainer/utils/cmsg.h | 36 -----------
|
||||
3 files changed, 56 insertions(+), 202 deletions(-)
|
||||
delete mode 100644 libcontainer/utils/cmsg.c
|
||||
delete mode 100644 libcontainer/utils/cmsg.h
|
||||
|
||||
diff --git a/libcontainer/utils/cmsg.c b/libcontainer/utils/cmsg.c
|
||||
deleted file mode 100644
|
||||
index 0ded494..0000000
|
||||
--- a/libcontainer/utils/cmsg.c
|
||||
+++ /dev/null
|
||||
@@ -1,148 +0,0 @@
|
||||
-/*
|
||||
- * Copyright 2016 SUSE LLC
|
||||
- *
|
||||
- * 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.
|
||||
- */
|
||||
-
|
||||
-#include <errno.h>
|
||||
-#include <stdio.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
-#include <sys/socket.h>
|
||||
-#include <sys/types.h>
|
||||
-#include <unistd.h>
|
||||
-
|
||||
-#include "cmsg.h"
|
||||
-
|
||||
-#define error(fmt, ...) \
|
||||
- ({ \
|
||||
- fprintf(stderr, "nsenter: " fmt ": %m\n", ##__VA_ARGS__); \
|
||||
- errno = ECOMM; \
|
||||
- goto err; /* return value */ \
|
||||
- })
|
||||
-
|
||||
-/*
|
||||
- * Sends a file descriptor along the sockfd provided. Returns the return
|
||||
- * value of sendmsg(2). Any synchronisation and preparation of state
|
||||
- * should be done external to this (we expect the other side to be in
|
||||
- * recvfd() in the code).
|
||||
- */
|
||||
-ssize_t sendfd(int sockfd, struct file_t file)
|
||||
-{
|
||||
- struct msghdr msg = {0};
|
||||
- struct iovec iov[1] = {0};
|
||||
- struct cmsghdr *cmsg;
|
||||
- int *fdptr;
|
||||
- int ret;
|
||||
-
|
||||
- union {
|
||||
- char buf[CMSG_SPACE(sizeof(file.fd))];
|
||||
- struct cmsghdr align;
|
||||
- } u;
|
||||
-
|
||||
- /*
|
||||
- * We need to send some other data along with the ancillary data,
|
||||
- * otherwise the other side won't recieve any data. This is very
|
||||
- * well-hidden in the documentation (and only applies to
|
||||
- * SOCK_STREAM). See the bottom part of unix(7).
|
||||
- */
|
||||
- iov[0].iov_base = file.name;
|
||||
- iov[0].iov_len = strlen(file.name) + 1;
|
||||
-
|
||||
- msg.msg_name = NULL;
|
||||
- msg.msg_namelen = 0;
|
||||
- msg.msg_iov = iov;
|
||||
- msg.msg_iovlen = 1;
|
||||
- msg.msg_control = u.buf;
|
||||
- msg.msg_controllen = sizeof(u.buf);
|
||||
-
|
||||
- cmsg = CMSG_FIRSTHDR(&msg);
|
||||
- cmsg->cmsg_level = SOL_SOCKET;
|
||||
- cmsg->cmsg_type = SCM_RIGHTS;
|
||||
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
-
|
||||
- fdptr = (int *) CMSG_DATA(cmsg);
|
||||
- memcpy(fdptr, &file.fd, sizeof(int));
|
||||
-
|
||||
- return sendmsg(sockfd, &msg, 0);
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * Receives a file descriptor from the sockfd provided. Returns the file
|
||||
- * descriptor as sent from sendfd(). It will return the file descriptor
|
||||
- * or die (literally) trying. Any synchronisation and preparation of
|
||||
- * state should be done external to this (we expect the other side to be
|
||||
- * in sendfd() in the code).
|
||||
- */
|
||||
-struct file_t recvfd(int sockfd)
|
||||
-{
|
||||
- struct msghdr msg = {0};
|
||||
- struct iovec iov[1] = {0};
|
||||
- struct cmsghdr *cmsg;
|
||||
- struct file_t file = {0};
|
||||
- int *fdptr;
|
||||
- int olderrno;
|
||||
-
|
||||
- union {
|
||||
- char buf[CMSG_SPACE(sizeof(file.fd))];
|
||||
- struct cmsghdr align;
|
||||
- } u;
|
||||
-
|
||||
- /* Allocate a buffer. */
|
||||
- /* TODO: Make this dynamic with MSG_PEEK. */
|
||||
- file.name = malloc(TAG_BUFFER);
|
||||
- if (!file.name)
|
||||
- error("recvfd: failed to allocate file.tag buffer\n");
|
||||
-
|
||||
- /*
|
||||
- * We need to "recieve" the non-ancillary data even though we don't
|
||||
- * plan to use it at all. Otherwise, things won't work as expected.
|
||||
- * See unix(7) and other well-hidden documentation.
|
||||
- */
|
||||
- iov[0].iov_base = file.name;
|
||||
- iov[0].iov_len = TAG_BUFFER;
|
||||
-
|
||||
- msg.msg_name = NULL;
|
||||
- msg.msg_namelen = 0;
|
||||
- msg.msg_iov = iov;
|
||||
- msg.msg_iovlen = 1;
|
||||
- msg.msg_control = u.buf;
|
||||
- msg.msg_controllen = sizeof(u.buf);
|
||||
-
|
||||
- ssize_t ret = recvmsg(sockfd, &msg, 0);
|
||||
- if (ret < 0)
|
||||
- goto err;
|
||||
-
|
||||
- cmsg = CMSG_FIRSTHDR(&msg);
|
||||
- if (!cmsg)
|
||||
- error("recvfd: got NULL from CMSG_FIRSTHDR");
|
||||
- if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
- error("recvfd: expected SOL_SOCKET in cmsg: %d", cmsg->cmsg_level);
|
||||
- if (cmsg->cmsg_type != SCM_RIGHTS)
|
||||
- error("recvfd: expected SCM_RIGHTS in cmsg: %d", cmsg->cmsg_type);
|
||||
- if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
|
||||
- error("recvfd: expected correct CMSG_LEN in cmsg: %lu", (unsigned long)cmsg->cmsg_len);
|
||||
-
|
||||
- fdptr = (int *) CMSG_DATA(cmsg);
|
||||
- if (!fdptr || *fdptr < 0)
|
||||
- error("recvfd: recieved invalid pointer");
|
||||
-
|
||||
- file.fd = *fdptr;
|
||||
- return file;
|
||||
-
|
||||
-err:
|
||||
- olderrno = errno;
|
||||
- free(file.name);
|
||||
- errno = olderrno;
|
||||
- return (struct file_t){0};
|
||||
-}
|
||||
diff --git a/libcontainer/utils/cmsg.go b/libcontainer/utils/cmsg.go
|
||||
index ee89374..2cbb649 100644
|
||||
--- a/libcontainer/utils/cmsg.go
|
||||
+++ b/libcontainer/utils/cmsg.go
|
||||
@@ -3,7 +3,7 @@
|
||||
package utils
|
||||
|
||||
/*
|
||||
- * Copyright 2016 SUSE LLC
|
||||
+ * Copyright 2016, 2017 SUSE LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,28 +18,66 @@ package utils
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
-/*
|
||||
-#include <errno.h>
|
||||
-#include <stdlib.h>
|
||||
-#include "cmsg.h"
|
||||
-*/
|
||||
-import "C"
|
||||
-
|
||||
import (
|
||||
+ "fmt"
|
||||
"os"
|
||||
- "unsafe"
|
||||
+
|
||||
+ "golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
+// MaxSendfdLen is the maximum length of the name of a file descriptor being
|
||||
+// sent using SendFd. The name of the file handle returned by RecvFd will never
|
||||
+// be larger than this value.
|
||||
+const MaxNameLen = 4096
|
||||
+
|
||||
+// oobSpace is the size of the oob slice required to store a single FD. Note
|
||||
+// that unix.UnixRights appears to make the assumption that fd is always int32,
|
||||
+// so sizeof(fd) = 4.
|
||||
+var oobSpace = unix.CmsgSpace(4)
|
||||
+
|
||||
// RecvFd waits for a file descriptor to be sent over the given AF_UNIX
|
||||
// socket. The file name of the remote file descriptor will be recreated
|
||||
// locally (it is sent as non-auxiliary data in the same payload).
|
||||
func RecvFd(socket *os.File) (*os.File, error) {
|
||||
- file, err := C.recvfd(C.int(socket.Fd()))
|
||||
+ // For some reason, unix.Recvmsg uses the length rather than the capacity
|
||||
+ // when passing the msg_controllen and other attributes to recvmsg. So we
|
||||
+ // have to actually set the length.
|
||||
+ name := make([]byte, MaxNameLen)
|
||||
+ oob := make([]byte, oobSpace)
|
||||
+
|
||||
+ sockfd := socket.Fd()
|
||||
+ n, oobn, _, _, err := unix.Recvmsg(int(sockfd), name, oob, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
- defer C.free(unsafe.Pointer(file.name))
|
||||
- return os.NewFile(uintptr(file.fd), C.GoString(file.name)), nil
|
||||
+
|
||||
+ if n >= MaxNameLen || oobn != oobSpace {
|
||||
+ return nil, fmt.Errorf("recvfd: incorrect number of bytes read (n=%d oobn=%d)", n, oobn)
|
||||
+ }
|
||||
+
|
||||
+ // Truncate.
|
||||
+ name = name[:n]
|
||||
+ oob = oob[:oobn]
|
||||
+
|
||||
+ scms, err := unix.ParseSocketControlMessage(oob)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ if len(scms) != 1 {
|
||||
+ return nil, fmt.Errorf("recvfd: number of SCMs is not 1: %d", len(scms))
|
||||
+ }
|
||||
+ scm := scms[0]
|
||||
+
|
||||
+ fds, err := unix.ParseUnixRights(&scm)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ if len(fds) != 1 {
|
||||
+ return nil, fmt.Errorf("recvfd: number of fds is not 1: %d", len(fds))
|
||||
+ }
|
||||
+ fd := uintptr(fds[0])
|
||||
+
|
||||
+ return os.NewFile(fd, string(name)), nil
|
||||
}
|
||||
|
||||
// SendFd sends a file descriptor over the given AF_UNIX socket. In
|
||||
@@ -47,11 +85,11 @@ func RecvFd(socket *os.File) (*os.File, error) {
|
||||
// non-auxiliary data in the same payload (allowing to send contextual
|
||||
// information for a file descriptor).
|
||||
func SendFd(socket, file *os.File) error {
|
||||
- var cfile C.struct_file_t
|
||||
- cfile.fd = C.int(file.Fd())
|
||||
- cfile.name = C.CString(file.Name())
|
||||
- defer C.free(unsafe.Pointer(cfile.name))
|
||||
+ name := []byte(file.Name())
|
||||
+ if len(name) >= MaxNameLen {
|
||||
+ return fmt.Errorf("sendfd: filename too long: %s", file.Name())
|
||||
+ }
|
||||
+ oob := unix.UnixRights(int(file.Fd()))
|
||||
|
||||
- _, err := C.sendfd(C.int(socket.Fd()), cfile)
|
||||
- return err
|
||||
+ return unix.Sendmsg(int(socket.Fd()), name, oob, nil, 0)
|
||||
}
|
||||
diff --git a/libcontainer/utils/cmsg.h b/libcontainer/utils/cmsg.h
|
||||
deleted file mode 100644
|
||||
index 3fe7642..0000000
|
||||
--- a/libcontainer/utils/cmsg.h
|
||||
+++ /dev/null
|
||||
@@ -1,36 +0,0 @@
|
||||
-/*
|
||||
- * Copyright 2016 SUSE LLC
|
||||
- *
|
||||
- * 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.
|
||||
- */
|
||||
-
|
||||
-#pragma once
|
||||
-
|
||||
-#if !defined(CMSG_H)
|
||||
-#define CMSG_H
|
||||
-
|
||||
-#include <sys/types.h>
|
||||
-
|
||||
-/* TODO: Implement this properly with MSG_PEEK. */
|
||||
-#define TAG_BUFFER 4096
|
||||
-
|
||||
-/* This mirrors Go's (*os.File). */
|
||||
-struct file_t {
|
||||
- char *name;
|
||||
- int fd;
|
||||
-};
|
||||
-
|
||||
-struct file_t recvfd(int sockfd);
|
||||
-ssize_t sendfd(int sockfd, struct file_t file);
|
||||
-
|
||||
-#endif /* !defined(CMSG_H) */
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
39
patch/0014-Set-container-state-only-once-during-start.patch
Normal file
39
patch/0014-Set-container-state-only-once-during-start.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From b9b6667861bcc98579489aa6cec8012249fedbab Mon Sep 17 00:00:00 2001
|
||||
From: Harshal Patil <harshal.patil@in.ibm.com>
|
||||
Date: Tue, 4 Apr 2017 15:08:04 +0530
|
||||
Subject: [PATCH 14/94] Set container state only once during start
|
||||
|
||||
Change-Id: Iae2bcd397cbc40c540e32807d946c3ec81783803
|
||||
Signed-off-by: Harshal Patil <harshal.patil@in.ibm.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 71fa682..26e51ae 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -263,9 +263,6 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
}
|
||||
// generate a timestamp indicating when the container was started
|
||||
c.created = time.Now().UTC()
|
||||
- c.state = &runningState{
|
||||
- c: c,
|
||||
- }
|
||||
if isInit {
|
||||
c.state = &createdState{
|
||||
c: c,
|
||||
@@ -292,6 +289,10 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
+ } else {
|
||||
+ c.state = &runningState{
|
||||
+ c: c,
|
||||
+ }
|
||||
}
|
||||
return nil
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
161
patch/0015-checkpoint-check-if-system-supports-pre-dum.patch
Normal file
161
patch/0015-checkpoint-check-if-system-supports-pre-dum.patch
Normal file
@ -0,0 +1,161 @@
|
||||
From 6397990e4ee68389c05fa2a0c89d1c4d4e5e5677 Mon Sep 17 00:00:00 2001
|
||||
From: Adrian Reber <areber@redhat.com>
|
||||
Date: Tue, 14 Mar 2017 20:21:58 +0000
|
||||
Subject: [PATCH 15/94] checkpoint: check if system supports
|
||||
pre-dumping
|
||||
|
||||
Instead of relying on version numbers it is possible to check if CRIU
|
||||
actually supports certain features. This introduces an initial
|
||||
implementation to check if CRIU and the underlying kernel actually
|
||||
support dirty memory tracking for memory pre-dumping.
|
||||
|
||||
Upstream CRIU also supports the lazy-page migration feature check and
|
||||
additional feature checks can be included in CRIU to reduce the version
|
||||
number parsing. There are also certain CRIU features which depend on one
|
||||
side on the CRIU version but also require certain kernel versions to
|
||||
actually work. CRIU knows if it can do certain things on the kernel it
|
||||
is running on and using the feature check RPC interface makes it easier
|
||||
for runc to decide if the criu+kernel combination will support that
|
||||
feature.
|
||||
|
||||
Feature checking was introduced with CRIU 1.8. Running with older CRIU
|
||||
versions will ignore the feature check functionality and behave just
|
||||
like it used to.
|
||||
|
||||
v2:
|
||||
- Do not use reflection to compare requested and responded
|
||||
features. Checking which feature is available is now hardcoded
|
||||
and needs to be adapted for every new feature check. The code
|
||||
is now much more readable and simpler.
|
||||
|
||||
v3:
|
||||
- Move the variable criuFeat out of the linuxContainer struct,
|
||||
as it is not container specific. Now it is a global variable.
|
||||
|
||||
Change-Id: Ide44007d031d1bc4572dab1e88d78762944b379b
|
||||
Signed-off-by: Adrian Reber <areber@redhat.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 85 ++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 76 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 26e51ae..705472a 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -536,6 +536,56 @@ func (c *linuxContainer) NotifyMemoryPressure(level PressureLevel) (<-chan struc
|
||||
return notifyMemoryPressure(c.cgroupManager.GetPaths(), level)
|
||||
}
|
||||
|
||||
+var criuFeatures *criurpc.CriuFeatures
|
||||
+
|
||||
+func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.CriuOpts, criuFeat *criurpc.CriuFeatures) error {
|
||||
+
|
||||
+ var t criurpc.CriuReqType
|
||||
+ t = criurpc.CriuReqType_FEATURE_CHECK
|
||||
+
|
||||
+ if err := c.checkCriuVersion("1.8"); err != nil {
|
||||
+ // Feature checking was introduced with CRIU 1.8.
|
||||
+ // Ignore the feature check if an older CRIU version is used
|
||||
+ // and just act as before.
|
||||
+ // As all automated PR testing is done using CRIU 1.7 this
|
||||
+ // code will not be tested by automated PR testing.
|
||||
+ return nil
|
||||
+ }
|
||||
+
|
||||
+ // make sure the features we are looking for are really not from
|
||||
+ // some previous check
|
||||
+ criuFeatures = nil
|
||||
+
|
||||
+ req := &criurpc.CriuReq{
|
||||
+ Type: &t,
|
||||
+ // Theoretically this should not be necessary but CRIU
|
||||
+ // segfaults if Opts is empty.
|
||||
+ // Fixed in CRIU 2.12
|
||||
+ Opts: rpcOpts,
|
||||
+ Features: criuFeat,
|
||||
+ }
|
||||
+
|
||||
+ err := c.criuSwrk(nil, req, criuOpts, false)
|
||||
+ if err != nil {
|
||||
+ logrus.Debugf("%s", err)
|
||||
+ return fmt.Errorf("CRIU feature check failed")
|
||||
+ }
|
||||
+
|
||||
+ logrus.Debugf("Feature check says: %s", criuFeatures)
|
||||
+ missingFeatures := false
|
||||
+
|
||||
+ if *criuFeat.MemTrack && !*criuFeatures.MemTrack {
|
||||
+ missingFeatures = true
|
||||
+ logrus.Debugf("CRIU does not support MemTrack")
|
||||
+ }
|
||||
+
|
||||
+ if missingFeatures {
|
||||
+ return fmt.Errorf("CRIU is missing features")
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
// checkCriuVersion checks Criu version greater than or equal to minVersion
|
||||
func (c *linuxContainer) checkCriuVersion(minVersion string) error {
|
||||
var x, y, z, versionReq int
|
||||
@@ -718,6 +768,14 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
|
||||
var t criurpc.CriuReqType
|
||||
if criuOpts.PreDump {
|
||||
+ feat := criurpc.CriuFeatures{
|
||||
+ MemTrack: proto.Bool(true),
|
||||
+ }
|
||||
+
|
||||
+ if err := c.checkCriuFeatures(criuOpts, &rpcOpts, &feat); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+
|
||||
t = criurpc.CriuReqType_PRE_DUMP
|
||||
} else {
|
||||
t = criurpc.CriuReqType_DUMP
|
||||
@@ -1019,16 +1077,21 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
||||
}
|
||||
|
||||
logrus.Debugf("Using CRIU in %s mode", req.GetType().String())
|
||||
- val := reflect.ValueOf(req.GetOpts())
|
||||
- v := reflect.Indirect(val)
|
||||
- for i := 0; i < v.NumField(); i++ {
|
||||
- st := v.Type()
|
||||
- name := st.Field(i).Name
|
||||
- if strings.HasPrefix(name, "XXX_") {
|
||||
- continue
|
||||
+ // In the case of criurpc.CriuReqType_FEATURE_CHECK req.GetOpts()
|
||||
+ // should be empty. For older CRIU versions it still will be
|
||||
+ // available but empty.
|
||||
+ if req.GetType() != criurpc.CriuReqType_FEATURE_CHECK {
|
||||
+ val := reflect.ValueOf(req.GetOpts())
|
||||
+ v := reflect.Indirect(val)
|
||||
+ for i := 0; i < v.NumField(); i++ {
|
||||
+ st := v.Type()
|
||||
+ name := st.Field(i).Name
|
||||
+ if strings.HasPrefix(name, "XXX_") {
|
||||
+ continue
|
||||
+ }
|
||||
+ value := val.MethodByName("Get" + name).Call([]reflect.Value{})
|
||||
+ logrus.Debugf("CRIU option %s with value %v", name, value[0])
|
||||
}
|
||||
- value := val.MethodByName("Get" + name).Call([]reflect.Value{})
|
||||
- logrus.Debugf("CRIU option %s with value %v", name, value[0])
|
||||
}
|
||||
data, err := proto.Marshal(req)
|
||||
if err != nil {
|
||||
@@ -1064,6 +1127,10 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
||||
|
||||
t := resp.GetType()
|
||||
switch {
|
||||
+ case t == criurpc.CriuReqType_FEATURE_CHECK:
|
||||
+ logrus.Debugf("Feature check says: %s", resp)
|
||||
+ criuFeatures = resp.GetFeatures()
|
||||
+ break
|
||||
case t == criurpc.CriuReqType_NOTIFY:
|
||||
if err := c.criuNotifications(resp, process, opts, extFds); err != nil {
|
||||
return err
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
129
patch/0016-Fix-console-syscalls.patch
Normal file
129
patch/0016-Fix-console-syscalls.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From 17199cf842a86765a21e2054e10e0c64f28353c8 Mon Sep 17 00:00:00 2001
|
||||
From: Christy Perez <christy@linux.vnet.ibm.com>
|
||||
Date: Mon, 27 Mar 2017 16:46:57 -0500
|
||||
Subject: [PATCH 16/94] Fix console syscalls
|
||||
|
||||
Fixes opencontainers/runc/issues/1364
|
||||
|
||||
Change-Id: Ic12237e2ce327f4d9eab3145d0c4c2cff9fb641a
|
||||
Signed-off-by: Christy Perez <christy@linux.vnet.ibm.com>
|
||||
---
|
||||
libcontainer/console_linux.go | 31 ++++++++++++++++---------------
|
||||
1 file changed, 16 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/console_linux.go b/libcontainer/console_linux.go
|
||||
index e431766..5e364a8 100644
|
||||
--- a/libcontainer/console_linux.go
|
||||
+++ b/libcontainer/console_linux.go
|
||||
@@ -3,8 +3,9 @@ package libcontainer
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
- "syscall"
|
||||
"unsafe"
|
||||
+
|
||||
+ "golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func ConsoleFromFile(f *os.File) Console {
|
||||
@@ -16,7 +17,7 @@ func ConsoleFromFile(f *os.File) Console {
|
||||
// newConsole returns an initialized console that can be used within a container by copying bytes
|
||||
// from the master side to the slave that is attached as the tty for the container's init process.
|
||||
func newConsole() (Console, error) {
|
||||
- master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
|
||||
+ master, err := os.OpenFile("/dev/ptmx", unix.O_RDWR|unix.O_NOCTTY|unix.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -68,8 +69,8 @@ func (c *linuxConsole) Close() error {
|
||||
// mount initializes the console inside the rootfs mounting with the specified mount label
|
||||
// and applying the correct ownership of the console.
|
||||
func (c *linuxConsole) mount() error {
|
||||
- oldMask := syscall.Umask(0000)
|
||||
- defer syscall.Umask(oldMask)
|
||||
+ oldMask := unix.Umask(0000)
|
||||
+ defer unix.Umask(oldMask)
|
||||
f, err := os.Create("/dev/console")
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
@@ -77,19 +78,19 @@ func (c *linuxConsole) mount() error {
|
||||
if f != nil {
|
||||
f.Close()
|
||||
}
|
||||
- return syscall.Mount(c.slavePath, "/dev/console", "bind", syscall.MS_BIND, "")
|
||||
+ return unix.Mount(c.slavePath, "/dev/console", "bind", unix.MS_BIND, "")
|
||||
}
|
||||
|
||||
// dupStdio opens the slavePath for the console and dups the fds to the current
|
||||
// processes stdio, fd 0,1,2.
|
||||
func (c *linuxConsole) dupStdio() error {
|
||||
- slave, err := c.open(syscall.O_RDWR)
|
||||
+ slave, err := c.open(unix.O_RDWR)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fd := int(slave.Fd())
|
||||
for _, i := range []int{0, 1, 2} {
|
||||
- if err := syscall.Dup3(fd, i, 0); err != nil {
|
||||
+ if err := unix.Dup3(fd, i, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -98,7 +99,7 @@ func (c *linuxConsole) dupStdio() error {
|
||||
|
||||
// open is a clone of os.OpenFile without the O_CLOEXEC used to open the pty slave.
|
||||
func (c *linuxConsole) open(flag int) (*os.File, error) {
|
||||
- r, e := syscall.Open(c.slavePath, flag, 0)
|
||||
+ r, e := unix.Open(c.slavePath, flag, 0)
|
||||
if e != nil {
|
||||
return nil, &os.PathError{
|
||||
Op: "open",
|
||||
@@ -110,7 +111,7 @@ func (c *linuxConsole) open(flag int) (*os.File, error) {
|
||||
}
|
||||
|
||||
func ioctl(fd uintptr, flag, data uintptr) error {
|
||||
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, flag, data); err != 0 {
|
||||
+ if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, flag, data); err != 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -120,13 +121,13 @@ func ioctl(fd uintptr, flag, data uintptr) error {
|
||||
// unlockpt should be called before opening the slave side of a pty.
|
||||
func unlockpt(f *os.File) error {
|
||||
var u int32
|
||||
- return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
|
||||
+ return ioctl(f.Fd(), unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
|
||||
}
|
||||
|
||||
// ptsname retrieves the name of the first available pts for the given master.
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
var n int32
|
||||
- if err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
|
||||
+ if err := ioctl(f.Fd(), unix.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("/dev/pts/%d", n), nil
|
||||
@@ -139,16 +140,16 @@ func ptsname(f *os.File) (string, error) {
|
||||
// also relay that funky line discipline.
|
||||
func saneTerminal(terminal *os.File) error {
|
||||
// Go doesn't have a wrapper for any of the termios ioctls.
|
||||
- var termios syscall.Termios
|
||||
+ var termios unix.Termios
|
||||
|
||||
- if err := ioctl(terminal.Fd(), syscall.TCGETS, uintptr(unsafe.Pointer(&termios))); err != nil {
|
||||
+ if err := ioctl(terminal.Fd(), unix.TCGETS, uintptr(unsafe.Pointer(&termios))); err != nil {
|
||||
return fmt.Errorf("ioctl(tty, tcgets): %s", err.Error())
|
||||
}
|
||||
|
||||
// Set -onlcr so we don't have to deal with \r.
|
||||
- termios.Oflag &^= syscall.ONLCR
|
||||
+ termios.Oflag &^= unix.ONLCR
|
||||
|
||||
- if err := ioctl(terminal.Fd(), syscall.TCSETS, uintptr(unsafe.Pointer(&termios))); err != nil {
|
||||
+ if err := ioctl(terminal.Fd(), unix.TCSETS, uintptr(unsafe.Pointer(&termios))); err != nil {
|
||||
return fmt.Errorf("ioctl(tty, tcsets): %s", err.Error())
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
34
patch/0017-restore-apply-resource-limits.patch
Normal file
34
patch/0017-restore-apply-resource-limits.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 7b92e178267794e026f5c38e632d82a00f038e96 Mon Sep 17 00:00:00 2001
|
||||
From: Andrei Vagin <avagin@virtuozzo.com>
|
||||
Date: Fri, 7 Apr 2017 02:34:41 +0300
|
||||
Subject: [PATCH 17/94] restore: apply resource limits
|
||||
|
||||
When C/R was implemented, it was enough to call manager.Set to apply
|
||||
limits and to move a task. Now .Set() and .Apply() have to be called
|
||||
separately.
|
||||
|
||||
Change-Id: I4786732a1779a65eeb902fc1ef42b194ba8dd3b4
|
||||
Fixes: 8a740d5391a7 ("libcontainer: cgroups: don't Set in Apply")
|
||||
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 705472a..b5563d6 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -1008,6 +1008,10 @@ func (c *linuxContainer) criuApplyCgroups(pid int, req *criurpc.CriuReq) error {
|
||||
return err
|
||||
}
|
||||
|
||||
+ if err := c.cgroupManager.Set(c.config); err != nil {
|
||||
+ return newSystemError(err)
|
||||
+ }
|
||||
+
|
||||
path := fmt.Sprintf("/proc/%d/cgroup", pid)
|
||||
cgroupsPaths, err := cgroups.ParseCgroupFile(path)
|
||||
if err != nil {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
35
patch/0018-could-load-a-stopped-container.patch
Normal file
35
patch/0018-could-load-a-stopped-container.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From d8ea288801363d61c46a5eecfe7e1a9001767bc7 Mon Sep 17 00:00:00 2001
|
||||
From: CuiHaozhi <cuihz@wise2c.com>
|
||||
Date: Fri, 7 Apr 2017 07:39:41 -0400
|
||||
Subject: [PATCH 18/94] could load a stopped container.
|
||||
|
||||
Change-Id: Ieabdef66ad7e9488a44b718093acf23f8aa947c4
|
||||
Signed-off-by: CuiHaozhi <cuihz@wise2c.com>
|
||||
---
|
||||
libcontainer/factory.go | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/factory.go b/libcontainer/factory.go
|
||||
index f0ccb52..0986cd7 100644
|
||||
--- a/libcontainer/factory.go
|
||||
+++ b/libcontainer/factory.go
|
||||
@@ -10,7 +10,7 @@ type Factory interface {
|
||||
// between 1 and 1024 characters, inclusive.
|
||||
//
|
||||
// The id must not already be in use by an existing container. Containers created using
|
||||
- // a factory with the same path (and file system) must have distinct ids.
|
||||
+ // a factory with the same path (and filesystem) must have distinct ids.
|
||||
//
|
||||
// Returns the new container with a running process.
|
||||
//
|
||||
@@ -28,7 +28,6 @@ type Factory interface {
|
||||
//
|
||||
// errors:
|
||||
// Path does not exist
|
||||
- // Container is stopped
|
||||
// System error
|
||||
Load(id string) (Container, error)
|
||||
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
32
patch/0019-Revert-back-to-using-sbin.patch
Normal file
32
patch/0019-Revert-back-to-using-sbin.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From a90e91c5fc8e6fb016d26666361e6d1bfd3f56c8 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Crosby <crosbymichael@gmail.com>
|
||||
Date: Fri, 14 Apr 2017 10:15:33 -0700
|
||||
Subject: [PATCH 19/94] Revert back to using /sbin
|
||||
|
||||
This was changed in
|
||||
https://github.com/opencontainers/runc/commit/d2f49696#diff-b67911656ef5d18c4ae36cb6741b7965R7
|
||||
and is causing install problems for people building runc and having it
|
||||
installed in /bin and /sbin.
|
||||
|
||||
Change-Id: Ibaef1dd279894342c48da5e6e8e7f1a7212003b8
|
||||
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 1cecca1..d6d337d 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
SOURCES := $(shell find . 2>&1 | grep -E '.*\.(c|h|go)$$')
|
||||
PREFIX := $(DESTDIR)/usr/local
|
||||
-BINDIR := $(PREFIX)/bin
|
||||
+BINDIR := $(PREFIX)/sbin
|
||||
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
||||
GIT_BRANCH_CLEAN := $(shell echo $(GIT_BRANCH) | sed -e "s/[^[:alnum:]]/-/g")
|
||||
RUNC_IMAGE := runc_dev$(if $(GIT_BRANCH_CLEAN),:$(GIT_BRANCH_CLEAN))
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
57
patch/0020-add-testcase-in-generic_error_test.go.patch
Normal file
57
patch/0020-add-testcase-in-generic_error_test.go.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 9d30f4580c68c7d16a94d0df04b61571b212e55f Mon Sep 17 00:00:00 2001
|
||||
From: chchliang <chen.chuanliang@zte.com.cn>
|
||||
Date: Wed, 12 Apr 2017 16:26:30 +0800
|
||||
Subject: [PATCH 20/94] add testcase in generic_error_test.go
|
||||
|
||||
Change-Id: Id0e21750ea9724d48423ab16f70786a1f62ea81c
|
||||
Signed-off-by: chchliang <chen.chuanliang@zte.com.cn>
|
||||
---
|
||||
libcontainer/generic_error_test.go | 35 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
|
||||
diff --git a/libcontainer/generic_error_test.go b/libcontainer/generic_error_test.go
|
||||
index 292d2a3..8fbdd4d 100644
|
||||
--- a/libcontainer/generic_error_test.go
|
||||
+++ b/libcontainer/generic_error_test.go
|
||||
@@ -12,3 +12,38 @@ func TestErrorDetail(t *testing.T) {
|
||||
t.Fatal(derr)
|
||||
}
|
||||
}
|
||||
+
|
||||
+func TestErrorWithCode(t *testing.T) {
|
||||
+ err := newGenericError(fmt.Errorf("test error"), SystemError)
|
||||
+ if code := err.Code(); code != SystemError {
|
||||
+ t.Fatalf("expected err code %q but %q", SystemError, code)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func TestErrorWithError(t *testing.T) {
|
||||
+ cc := []struct {
|
||||
+ errmsg string
|
||||
+ cause string
|
||||
+ }{
|
||||
+ {
|
||||
+ errmsg: "test error",
|
||||
+ },
|
||||
+ {
|
||||
+ errmsg: "test error",
|
||||
+ cause: "test",
|
||||
+ },
|
||||
+ }
|
||||
+
|
||||
+ for _, v := range cc {
|
||||
+ err := newSystemErrorWithCause(fmt.Errorf(v.errmsg), v.cause)
|
||||
+
|
||||
+ msg := err.Error()
|
||||
+ if v.cause == "" && msg != v.errmsg {
|
||||
+ t.Fatalf("expected err(%q) equal errmsg(%q)", msg, v.errmsg)
|
||||
+ }
|
||||
+ if v.cause != "" && msg == v.errmsg {
|
||||
+ t.Fatalf("unexpected err(%q) equal errmsg(%q)", msg, v.errmsg)
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
53
patch/0021-Fix-misspelling-of-properties-in-various-pl.patch
Normal file
53
patch/0021-Fix-misspelling-of-properties-in-various-pl.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From fe398ce943f5da085507be6a164568544fc0d1c4 Mon Sep 17 00:00:00 2001
|
||||
From: Tim Potter <tpot@hpe.com>
|
||||
Date: Fri, 21 Apr 2017 12:41:02 +1000
|
||||
Subject: [PATCH 21/94] Fix misspelling of "properties" in various
|
||||
places
|
||||
|
||||
Change-Id: I69229a0ba2472b52edd4c444ac7820ade837726d
|
||||
Signed-off-by: Tim Potter <tpot@hpe.com>
|
||||
---
|
||||
checkpoint.go | 2 +-
|
||||
man/runc-checkpoint.8.md | 2 +-
|
||||
restore.go | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/checkpoint.go b/checkpoint.go
|
||||
index 78977d7..9b5663f 100644
|
||||
--- a/checkpoint.go
|
||||
+++ b/checkpoint.go
|
||||
@@ -33,7 +33,7 @@ checkpointed.`,
|
||||
cli.BoolFlag{Name: "file-locks", Usage: "handle file locks, for safety"},
|
||||
cli.BoolFlag{Name: "pre-dump", Usage: "dump container's memory information only, leave the container running after this"},
|
||||
cli.StringFlag{Name: "manage-cgroups-mode", Value: "", Usage: "cgroups mode: 'soft' (default), 'full' and 'strict'"},
|
||||
- cli.StringSliceFlag{Name: "empty-ns", Usage: "create a namespace, but don't restore its properies"},
|
||||
+ cli.StringSliceFlag{Name: "empty-ns", Usage: "create a namespace, but don't restore its properties"},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
if err := checkArgs(context, 1, exactArgs); err != nil {
|
||||
diff --git a/man/runc-checkpoint.8.md b/man/runc-checkpoint.8.md
|
||||
index b0ce2f3..4c81fd4 100644
|
||||
--- a/man/runc-checkpoint.8.md
|
||||
+++ b/man/runc-checkpoint.8.md
|
||||
@@ -22,4 +22,4 @@ checkpointed.
|
||||
--file-locks handle file locks, for safety
|
||||
--pre-dump dump container's memory information only, leave the container running after this
|
||||
--manage-cgroups-mode value cgroups mode: 'soft' (default), 'full' and 'strict'
|
||||
- --empty-ns value create a namespace, but don't restore its properies
|
||||
+ --empty-ns value create a namespace, but don't restore its properties
|
||||
diff --git a/restore.go b/restore.go
|
||||
index 06f635f..7ddc337 100644
|
||||
--- a/restore.go
|
||||
+++ b/restore.go
|
||||
@@ -80,7 +80,7 @@ using the runc checkpoint command.`,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "empty-ns",
|
||||
- Usage: "create a namespace, but don't restore its properies",
|
||||
+ Usage: "create a namespace, but don't restore its properties",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
63
patch/0022-Add-a-rootless-containers-section-on-README.patch
Normal file
63
patch/0022-Add-a-rootless-containers-section-on-README.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From e287eae0ba5cb39df6f09b3ce8436af3810986f3 Mon Sep 17 00:00:00 2001
|
||||
From: Jonh Wendell <jonh.wendell@redhat.com>
|
||||
Date: Fri, 21 Apr 2017 20:43:56 -0300
|
||||
Subject: [PATCH 22/94] Add a rootless containers section on README
|
||||
|
||||
Closes #1413.
|
||||
|
||||
Change-Id: I9058fea54d9f25c2fc0f07ca74a83300eed40b73
|
||||
Signed-off-by: Jonh Wendell <jonh.wendell@redhat.com>
|
||||
---
|
||||
README.md | 20 ++++++++++++++++++--
|
||||
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/README.md b/README.md
|
||||
index ae1ab28..a951f0d 100644
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -117,8 +117,8 @@ Assuming you have an OCI bundle from the previous step you can execute the conta
|
||||
The first way is to use the convenience command `run` that will handle creating, starting, and deleting the container after it exits.
|
||||
|
||||
```bash
|
||||
+# run as root
|
||||
cd /mycontainer
|
||||
-
|
||||
runc run mycontainerid
|
||||
```
|
||||
|
||||
@@ -165,8 +165,8 @@ Now we can go though the lifecycle operations in your shell.
|
||||
|
||||
|
||||
```bash
|
||||
+# run as root
|
||||
cd /mycontainer
|
||||
-
|
||||
runc create mycontainerid
|
||||
|
||||
# view the container is created and in the "created" state
|
||||
@@ -185,6 +185,22 @@ runc delete mycontainerid
|
||||
This adds more complexity but allows higher level systems to manage runc and provides points in the containers creation to setup various settings after the container has created and/or before it is deleted.
|
||||
This is commonly used to setup the container's network stack after `create` but before `start` where the user's defined process will be running.
|
||||
|
||||
+#### Rootless containers
|
||||
+`runc` has the ability to run containers without root privileges. This is called `rootless`. You need to pass some parameters to `runc` in order to run rootless containers. See below and compare with the previous version. Run the following commands as an ordinary user:
|
||||
+```bash
|
||||
+# Same as the first example
|
||||
+mkdir ~/mycontainer
|
||||
+cd ~/mycontainer
|
||||
+mkdir rootfs
|
||||
+docker export $(docker create busybox) | tar -C rootfs -xvf -
|
||||
+
|
||||
+# The --rootless parameter instructs runc spec to generate a configuration for a rootless container, which will allow you to run the container as a non-root user.
|
||||
+runc spec --rootless
|
||||
+
|
||||
+# The --root parameter tells runc where to store the container state. It must be writable by the user.
|
||||
+runc --root /tmp/runc run mycontainerid
|
||||
+```
|
||||
+
|
||||
#### Supervisors
|
||||
|
||||
`runc` can be used with process supervisors and init systems to ensure that containers are restarted when they exit.
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
69
patch/0023-vendor-clean-up-to-be-better-written.patch
Normal file
69
patch/0023-vendor-clean-up-to-be-better-written.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From d6c62e91d7763bb88287a052f6f5a3dc7bee5284 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Sat, 15 Apr 2017 17:31:39 +1000
|
||||
Subject: [PATCH 23/94] vendor: clean up to be better written
|
||||
|
||||
vndr doesn't support non-top-level imports, and in addition we really
|
||||
should be using tagged releases far more than we currently are
|
||||
(*especially* when it come to the OCI specs).
|
||||
|
||||
Change-Id: Ifb997a6d9edf2d89d6b2d440ea4fa305b1b4df18
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
tests/integration/spec.bats | 2 +-
|
||||
vendor.conf | 28 +++++++++++++++++-----------
|
||||
2 files changed, 18 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/tests/integration/spec.bats b/tests/integration/spec.bats
|
||||
index e9f28fb..6061706 100644
|
||||
--- a/tests/integration/spec.bats
|
||||
+++ b/tests/integration/spec.bats
|
||||
@@ -72,7 +72,7 @@ function teardown() {
|
||||
run git clone https://github.com/opencontainers/runtime-spec.git src/runtime-spec
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
- SPEC_COMMIT=$(grep runtime-spec ${TESTDIR}/../../vendor.conf | cut -d ' ' -f 2)
|
||||
+ SPEC_COMMIT=$(grep '^github.com/opencontainers/runtime-spec' ${TESTDIR}/../../vendor.conf | cut -d ' ' -f 2)
|
||||
run git -C src/runtime-spec reset --hard "${SPEC_COMMIT}"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
diff --git a/vendor.conf b/vendor.conf
|
||||
index 17a546e..6ab9bf8 100644
|
||||
--- a/vendor.conf
|
||||
+++ b/vendor.conf
|
||||
@@ -1,15 +1,21 @@
|
||||
-github.com/Sirupsen/logrus 26709e2714106fb8ad40b773b711ebce25b78914
|
||||
-github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
|
||||
-github.com/coreos/pkg/dlopen 3ac0863d7acf3bc44daf49afef8919af12f704ef
|
||||
-github.com/docker/docker 0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d
|
||||
-github.com/docker/go-units 9b001659dd36225e356b4467c465d732e745f53d
|
||||
-github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||
-github.com/golang/protobuf/proto f7137ae6b19afbfd61a94b746fda3b3fe0491874
|
||||
+# OCI runtime-spec. When updating this, make sure you use a version tag rather
|
||||
+# than a commit ID so it's much more obvious what version of the spec we are
|
||||
+# using.
|
||||
+github.com/opencontainers/runtime-spec v1.0.0-rc5
|
||||
+# Core libcontainer functionality.
|
||||
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
|
||||
-github.com/opencontainers/runtime-spec/specs-go 035da1dca3dfbb00d752eb58b0b158d6129f3776
|
||||
-github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d
|
||||
+github.com/opencontainers/selinux v1.0.0-rc1
|
||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||
-github.com/syndtr/gocapability/capability e7cb7fa329f456b3855136a2642b197bad7366ba
|
||||
-github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
|
||||
+github.com/Sirupsen/logrus 26709e2714106fb8ad40b773b711ebce25b78914
|
||||
+github.com/syndtr/gocapability e7cb7fa329f456b3855136a2642b197bad7366ba
|
||||
github.com/vishvananda/netlink 1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270
|
||||
+# systemd integration.
|
||||
+github.com/coreos/go-systemd v14
|
||||
+github.com/coreos/pkg v3
|
||||
+github.com/godbus/dbus v3
|
||||
+github.com/golang/protobuf f7137ae6b19afbfd61a94b746fda3b3fe0491874
|
||||
+# Command-line interface.
|
||||
+github.com/docker/docker 0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d
|
||||
+github.com/docker/go-units v0.2.0
|
||||
+github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
|
||||
golang.org/x/sys 9a7256cb28ed514b4e1e5f68959914c4c28a92e0 https://github.com/golang/sys
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
58
patch/0024-Optimizing-looping-over-namespaces.patch
Normal file
58
patch/0024-Optimizing-looping-over-namespaces.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 6108649ff1f4f270bfeb5f2aec1de8917d9b7609 Mon Sep 17 00:00:00 2001
|
||||
From: Harshal Patil <harshal.patil@in.ibm.com>
|
||||
Date: Tue, 25 Apr 2017 15:56:40 +0530
|
||||
Subject: [PATCH 24/94] Optimizing looping over namespaces
|
||||
|
||||
Change-Id: I82612d1f8161b4656011ba45b619dcd9150a3c2f
|
||||
Signed-off-by: Harshal Patil <harshal.patil@in.ibm.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 21 +++++++++++----------
|
||||
1 file changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index b5563d6..aeaf583 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -1454,18 +1454,17 @@ func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceTyp
|
||||
configs.NEWNS,
|
||||
}
|
||||
|
||||
- // Remove namespaces that we don't need to join.
|
||||
- var nsTypes []configs.NamespaceType
|
||||
for _, ns := range order {
|
||||
- if c.config.Namespaces.Contains(ns) {
|
||||
- nsTypes = append(nsTypes, ns)
|
||||
+
|
||||
+ // Remove namespaces that we don't need to join.
|
||||
+ if !c.config.Namespaces.Contains(ns) {
|
||||
+ continue
|
||||
}
|
||||
- }
|
||||
- for _, nsType := range nsTypes {
|
||||
- if p, ok := namespaces[nsType]; ok && p != "" {
|
||||
+
|
||||
+ if p, ok := namespaces[ns]; ok && p != "" {
|
||||
// check if the requested namespace is supported
|
||||
- if !configs.IsNamespaceSupported(nsType) {
|
||||
- return nil, newSystemError(fmt.Errorf("namespace %s is not supported", nsType))
|
||||
+ if !configs.IsNamespaceSupported(ns) {
|
||||
+ return nil, newSystemError(fmt.Errorf("namespace %s is not supported", ns))
|
||||
}
|
||||
// only set to join this namespace if it exists
|
||||
if _, err := os.Lstat(p); err != nil {
|
||||
@@ -1476,9 +1475,11 @@ func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceTyp
|
||||
if strings.ContainsRune(p, ',') {
|
||||
return nil, newSystemError(fmt.Errorf("invalid path %s", p))
|
||||
}
|
||||
- paths = append(paths, fmt.Sprintf("%s:%s", configs.NsName(nsType), p))
|
||||
+ paths = append(paths, fmt.Sprintf("%s:%s", configs.NsName(ns), p))
|
||||
}
|
||||
+
|
||||
}
|
||||
+
|
||||
return paths, nil
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
54
patch/0025-Add-a-rootless-section-to-spec-man-page-and.patch
Normal file
54
patch/0025-Add-a-rootless-section-to-spec-man-page-and.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 06f6824badbdc3a8c89d106abe5337c869a7d95f Mon Sep 17 00:00:00 2001
|
||||
From: Jonh Wendell <jonh.wendell@redhat.com>
|
||||
Date: Thu, 27 Apr 2017 10:52:31 -0300
|
||||
Subject: [PATCH 25/94] Add a rootless section to "spec" man page and
|
||||
command help
|
||||
|
||||
Change-Id: I6211c1adf2f6428652c75cd7cb76b86d782e7237
|
||||
Signed-off-by: Jonh Wendell <jonh.wendell@redhat.com>
|
||||
---
|
||||
man/runc-spec.8.md | 3 +++
|
||||
spec.go | 9 +++++++--
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/man/runc-spec.8.md b/man/runc-spec.8.md
|
||||
index 3c69e23..4f8e9bb 100644
|
||||
--- a/man/runc-spec.8.md
|
||||
+++ b/man/runc-spec.8.md
|
||||
@@ -45,5 +45,8 @@ already running as root, you can use sudo to give runc root privilege. For
|
||||
example: "sudo runc start container1" will give runc root privilege to start the
|
||||
container on your host.
|
||||
|
||||
+Alternatively, you can start a rootless container, which has the ability to run without root privileges. For this to work, the specification file needs to be adjusted accordingly. You can pass the parameter --rootless to this command to generate a proper rootless spec file.
|
||||
+
|
||||
# OPTIONS
|
||||
--bundle value, -b value path to the root of the bundle directory
|
||||
+ --rootless generate a configuration for a rootless container
|
||||
diff --git a/spec.go b/spec.go
|
||||
index 9024ad4..a15c84e 100644
|
||||
--- a/spec.go
|
||||
+++ b/spec.go
|
||||
@@ -51,13 +51,18 @@ must be unique on your host.
|
||||
|
||||
An alternative for generating a customized spec config is to use "oci-runtime-tool", the
|
||||
sub-command "oci-runtime-tool generate" has lots of options that can be used to do any
|
||||
-customizations as you want, see [runtime-tools](https://github.com/opencontainers/runtime-tools)
|
||||
+customizations as you want, see runtime-tools (https://github.com/opencontainers/runtime-tools)
|
||||
to get more information.
|
||||
|
||||
When starting a container through runc, runc needs root privilege. If not
|
||||
already running as root, you can use sudo to give runc root privilege. For
|
||||
example: "sudo runc start container1" will give runc root privilege to start the
|
||||
-container on your host.`,
|
||||
+container on your host.
|
||||
+
|
||||
+Alternatively, you can start a rootless container, which has the ability to run
|
||||
+without root privileges. For this to work, the specification file needs to be
|
||||
+adjusted accordingly. You can pass the parameter --rootless to this command to
|
||||
+generate a proper rootless spec file.`,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "bundle, b",
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
150
patch/0026-Allow-updating-container-pids-limit.patch
Normal file
150
patch/0026-Allow-updating-container-pids-limit.patch
Normal file
@ -0,0 +1,150 @@
|
||||
From 01218c77284209117e40350419fb60f76896a369 Mon Sep 17 00:00:00 2001
|
||||
From: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
|
||||
Date: Wed, 26 Apr 2017 09:53:20 -0700
|
||||
Subject: [PATCH 26/94] Allow updating container pids limit
|
||||
|
||||
Change-Id: I5cc0d8804b1de3da943e4651806d0041eb33d7f2
|
||||
Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
|
||||
---
|
||||
tests/integration/update.bats | 23 +++++++++++++++++++++--
|
||||
update.go | 9 +++++++++
|
||||
2 files changed, 30 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tests/integration/update.bats b/tests/integration/update.bats
|
||||
index 4a6bf7f..a3f3782 100644
|
||||
--- a/tests/integration/update.bats
|
||||
+++ b/tests/integration/update.bats
|
||||
@@ -33,6 +33,9 @@ function setup() {
|
||||
"blockio": {
|
||||
"blkioWeight": 1000
|
||||
},
|
||||
+ "pids": {
|
||||
+ "limit": 20
|
||||
+ },
|
||||
EOF
|
||||
)
|
||||
DATA=$(echo ${DATA} | sed 's/\n/\\n/g')
|
||||
@@ -61,7 +64,7 @@ function check_cgroup_value() {
|
||||
wait_for_container 15 1 test_update
|
||||
|
||||
# get the cgroup paths
|
||||
- for g in MEMORY CPUSET CPU BLKIO; do
|
||||
+ for g in MEMORY CPUSET CPU BLKIO PIDS; do
|
||||
base_path=$(grep "cgroup" /proc/self/mountinfo | gawk 'toupper($NF) ~ /\<'${g}'\>/ { print $5; exit }')
|
||||
eval CGROUP_${g}="${base_path}/runc-update-integration-test"
|
||||
done
|
||||
@@ -78,6 +81,7 @@ function check_cgroup_value() {
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 11534336
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 33554432
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 25165824
|
||||
+ check_cgroup_value $CGROUP_PIDS "pids.max" 20
|
||||
|
||||
# update blkio-weight
|
||||
runc update test_update --blkio-weight 500
|
||||
@@ -160,6 +164,11 @@ function check_cgroup_value() {
|
||||
[ "$status" -eq 0 ]
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 41943040
|
||||
|
||||
+ # update pids limit
|
||||
+ runc update test_update --pids-limit 10
|
||||
+ [ "$status" -eq 0 ]
|
||||
+ check_cgroup_value $CGROUP_PIDS "pids.max" 10
|
||||
+
|
||||
# Revert to the test initial value via json on stding
|
||||
runc update -r - test_update <<EOF
|
||||
{
|
||||
@@ -177,6 +186,9 @@ function check_cgroup_value() {
|
||||
},
|
||||
"blockIO": {
|
||||
"blkioWeight": 1000
|
||||
+ },
|
||||
+ "pids": {
|
||||
+ "limit": 20
|
||||
}
|
||||
}
|
||||
EOF
|
||||
@@ -190,11 +202,13 @@ EOF
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 11534336
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 33554432
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 25165824
|
||||
+ check_cgroup_value $CGROUP_PIDS "pids.max" 20
|
||||
|
||||
# redo all the changes at once
|
||||
runc update test_update --blkio-weight 500 \
|
||||
--cpu-period 900000 --cpu-quota 600000 --cpu-share 200 --memory 67108864 \
|
||||
- --memory-reservation 33554432 --kernel-memory 50331648 --kernel-memory-tcp 41943040
|
||||
+ --memory-reservation 33554432 --kernel-memory 50331648 --kernel-memory-tcp 41943040 \
|
||||
+ --pids-limit 10
|
||||
[ "$status" -eq 0 ]
|
||||
check_cgroup_value $CGROUP_BLKIO "blkio.weight" 500
|
||||
check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 900000
|
||||
@@ -204,6 +218,7 @@ EOF
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 41943040
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 67108864
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 33554432
|
||||
+ check_cgroup_value $CGROUP_PIDS "pids.max" 10
|
||||
|
||||
# reset to initial test value via json file
|
||||
DATA=$(cat <<"EOF"
|
||||
@@ -222,6 +237,9 @@ EOF
|
||||
},
|
||||
"blockIO": {
|
||||
"blkioWeight": 1000
|
||||
+ },
|
||||
+ "pids": {
|
||||
+ "limit": 20
|
||||
}
|
||||
}
|
||||
EOF
|
||||
@@ -239,6 +257,7 @@ EOF
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 11534336
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 33554432
|
||||
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 25165824
|
||||
+ check_cgroup_value $CGROUP_PIDS "pids.max" 20
|
||||
}
|
||||
|
||||
@test "update rt period and runtime" {
|
||||
diff --git a/update.go b/update.go
|
||||
index 7af3a9c..5520681 100644
|
||||
--- a/update.go
|
||||
+++ b/update.go
|
||||
@@ -108,6 +108,10 @@ other options are ignored.
|
||||
Name: "memory-swap",
|
||||
Usage: "Total memory usage (memory + swap); set '-1' to enable unlimited swap",
|
||||
},
|
||||
+ cli.IntFlag{
|
||||
+ Name: "pids-limit",
|
||||
+ Usage: "Maximum number of pids allowed in the container",
|
||||
+ },
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
if err := checkArgs(context, 1, exactArgs); err != nil {
|
||||
@@ -138,6 +142,9 @@ other options are ignored.
|
||||
BlockIO: &specs.LinuxBlockIO{
|
||||
Weight: u16Ptr(0),
|
||||
},
|
||||
+ Pids: &specs.LinuxPids{
|
||||
+ Limit: 0,
|
||||
+ },
|
||||
}
|
||||
|
||||
config := container.Config()
|
||||
@@ -228,6 +235,7 @@ other options are ignored.
|
||||
*pair.dest = uint64(v)
|
||||
}
|
||||
}
|
||||
+ r.Pids.Limit = int64(context.Int("pids-limit"))
|
||||
}
|
||||
|
||||
// Update the value
|
||||
@@ -244,6 +252,7 @@ other options are ignored.
|
||||
config.Cgroups.Resources.Memory = *r.Memory.Limit
|
||||
config.Cgroups.Resources.MemoryReservation = *r.Memory.Reservation
|
||||
config.Cgroups.Resources.MemorySwap = *r.Memory.Swap
|
||||
+ config.Cgroups.Resources.PidsLimit = r.Pids.Limit
|
||||
|
||||
return container.Set(config)
|
||||
},
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
59
patch/0027-Remove-redundant-declaraion-of-namespace-sl.patch
Normal file
59
patch/0027-Remove-redundant-declaraion-of-namespace-sl.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From e35db3fff6d86c31ca0203ef02ffa1cf2b05bf89 Mon Sep 17 00:00:00 2001
|
||||
From: Harshal Patil <harshal.patil@in.ibm.com>
|
||||
Date: Fri, 28 Apr 2017 10:12:56 +0530
|
||||
Subject: [PATCH 27/94] Remove redundant declaraion of namespace
|
||||
slice
|
||||
|
||||
Change-Id: I7e7e45cec65264a91ef3dec804953a1285b23b96
|
||||
Signed-off-by: Harshal Patil <harshal.patil@in.ibm.com>
|
||||
---
|
||||
libcontainer/configs/namespaces_unix.go | 6 +++---
|
||||
libcontainer/container_linux.go | 11 +----------
|
||||
2 files changed, 4 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/namespaces_unix.go b/libcontainer/configs/namespaces_unix.go
|
||||
index 8beba9d..1f0b3ee 100644
|
||||
--- a/libcontainer/configs/namespaces_unix.go
|
||||
+++ b/libcontainer/configs/namespaces_unix.go
|
||||
@@ -64,12 +64,12 @@ func IsNamespaceSupported(ns NamespaceType) bool {
|
||||
|
||||
func NamespaceTypes() []NamespaceType {
|
||||
return []NamespaceType{
|
||||
+ NEWUSER, // Keep user NS always first, don't move it.
|
||||
+ NEWIPC,
|
||||
+ NEWUTS,
|
||||
NEWNET,
|
||||
NEWPID,
|
||||
NEWNS,
|
||||
- NEWUTS,
|
||||
- NEWIPC,
|
||||
- NEWUSER,
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index aeaf583..173a3f0 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -1444,17 +1444,8 @@ func (c *linuxContainer) currentState() (*State, error) {
|
||||
// can setns in order.
|
||||
func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceType]string) ([]string, error) {
|
||||
paths := []string{}
|
||||
- order := []configs.NamespaceType{
|
||||
- // The user namespace *must* be done first.
|
||||
- configs.NEWUSER,
|
||||
- configs.NEWIPC,
|
||||
- configs.NEWUTS,
|
||||
- configs.NEWNET,
|
||||
- configs.NEWPID,
|
||||
- configs.NEWNS,
|
||||
- }
|
||||
|
||||
- for _, ns := range order {
|
||||
+ for _, ns := range configs.NamespaceTypes() {
|
||||
|
||||
// Remove namespaces that we don't need to join.
|
||||
if !c.config.Namespaces.Contains(ns) {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
31
patch/0028-Revert-saneTerminal.patch
Normal file
31
patch/0028-Revert-saneTerminal.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 34dc868ee8515be89835bc98ccbf01f22bd6b1b9 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Crosby <crosbymichael@gmail.com>
|
||||
Date: Wed, 7 Jun 2017 10:51:42 -0700
|
||||
Subject: [PATCH 28/94] Revert saneTerminal
|
||||
|
||||
Keep the ONCLR for the terminal created by runc for backwards compat
|
||||
support of older clients.
|
||||
|
||||
Change-Id: Ibdf33687262f13ef98c882328d55c9c4212ce0b6
|
||||
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
|
||||
---
|
||||
libcontainer/console_linux.go | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/console_linux.go b/libcontainer/console_linux.go
|
||||
index 5e364a8..5927bdc 100644
|
||||
--- a/libcontainer/console_linux.go
|
||||
+++ b/libcontainer/console_linux.go
|
||||
@@ -21,9 +21,6 @@ func newConsole() (Console, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
- if err := saneTerminal(master); err != nil {
|
||||
- return nil, err
|
||||
- }
|
||||
console, err := ptsname(master)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
59
patch/0029-vendor-runtime-spec-fork-docker-runtime-spe.patch
Normal file
59
patch/0029-vendor-runtime-spec-fork-docker-runtime-spe.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From c9d66ffed85529579f4247581d0d387fc21d92fa Mon Sep 17 00:00:00 2001
|
||||
From: Tibor Vass <tibor@docker.com>
|
||||
Date: Thu, 6 Jul 2017 10:28:14 -0700
|
||||
Subject: [PATCH 29/94] vendor runtime-spec fork
|
||||
docker/runtime-spec@a45ba0989fc26c695fe166a49c45bb8b7618ab36
|
||||
|
||||
This vendoring brings in the change from uint64 to int64 in the Memory
|
||||
structs.
|
||||
|
||||
Change-Id: Ic928ff9cde8055a24ad039ccff64b8ceff917142
|
||||
Signed-off-by: Tibor Vass <tibor@docker.com>
|
||||
---
|
||||
vendor.conf | 2 +-
|
||||
.../opencontainers/runtime-spec/specs-go/config.go | 12 ++++++------
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/vendor.conf b/vendor.conf
|
||||
index 6ab9bf8..b961707 100644
|
||||
--- a/vendor.conf
|
||||
+++ b/vendor.conf
|
||||
@@ -1,7 +1,7 @@
|
||||
# OCI runtime-spec. When updating this, make sure you use a version tag rather
|
||||
# than a commit ID so it's much more obvious what version of the spec we are
|
||||
# using.
|
||||
-github.com/opencontainers/runtime-spec v1.0.0-rc5
|
||||
+github.com/opencontainers/runtime-spec a45ba0989fc26c695fe166a49c45bb8b7618ab36 https://github.com/docker/runtime-spec
|
||||
# Core libcontainer functionality.
|
||||
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
|
||||
github.com/opencontainers/selinux v1.0.0-rc1
|
||||
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
index bd8e96a..6d2a026 100644
|
||||
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
@@ -281,16 +281,16 @@ type LinuxBlockIO struct {
|
||||
// LinuxMemory for Linux cgroup 'memory' resource management
|
||||
type LinuxMemory struct {
|
||||
// Memory limit (in bytes).
|
||||
- Limit *uint64 `json:"limit,omitempty"`
|
||||
+ Limit *int64 `json:"limit,omitempty"`
|
||||
// Memory reservation or soft_limit (in bytes).
|
||||
- Reservation *uint64 `json:"reservation,omitempty"`
|
||||
+ Reservation *int64 `json:"reservation,omitempty"`
|
||||
// Total memory limit (memory + swap).
|
||||
- Swap *uint64 `json:"swap,omitempty"`
|
||||
+ Swap *int64 `json:"swap,omitempty"`
|
||||
// Kernel memory limit (in bytes).
|
||||
- Kernel *uint64 `json:"kernel,omitempty"`
|
||||
+ Kernel *int64 `json:"kernel,omitempty"`
|
||||
// Kernel memory limit for tcp (in bytes)
|
||||
- KernelTCP *uint64 `json:"kernelTCP,omitempty"`
|
||||
- // How aggressive the kernel will swap memory pages. Range from 0 to 100.
|
||||
+ KernelTCP *int64 `json:"kernelTCP,omitempty"`
|
||||
+ // How aggressive the kernel will swap memory pages.
|
||||
Swappiness *uint64 `json:"swappiness,omitempty"`
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
198
patch/0030-Update-memory-specs-to-use-int64-not-uint64.patch
Normal file
198
patch/0030-Update-memory-specs-to-use-int64-not-uint64.patch
Normal file
@ -0,0 +1,198 @@
|
||||
From 8ffbf2a8b8ae7119ae31bb15a30cb41711b809e2 Mon Sep 17 00:00:00 2001
|
||||
From: Justin Cormack <justin.cormack@docker.com>
|
||||
Date: Fri, 23 Jun 2017 17:17:00 -0700
|
||||
Subject: [PATCH 30/94] Update memory specs to use int64 not uint64
|
||||
|
||||
replace #1492 #1494
|
||||
fix #1422
|
||||
|
||||
Since https://github.com/opencontainers/runtime-spec/pull/876 the memory
|
||||
specifications are now `int64`, as that better matches the visible interface where
|
||||
`-1` is a valid value. Otherwise finding the correct value was difficult as it
|
||||
was kernel dependent.
|
||||
|
||||
Signed-off-by: Justin Cormack <justin.cormack@docker.com>
|
||||
(cherry picked from commit 3d9074ead33a5c27dc20bb49457c69c6d2ae6b57)
|
||||
Signed-off-by: Tibor Vass <tibor@docker.com>
|
||||
|
||||
Change-Id: I07ec53368c5058076d3bd35e122f32259bf69854
|
||||
---
|
||||
libcontainer/cgroups/fs/memory.go | 36 +++++++++++++++++-------------------
|
||||
libcontainer/configs/cgroup_unix.go | 10 +++++-----
|
||||
update.go | 14 +++++++-------
|
||||
3 files changed, 29 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/cgroups/fs/memory.go b/libcontainer/cgroups/fs/memory.go
|
||||
index 0981cfb..c993839 100644
|
||||
--- a/libcontainer/cgroups/fs/memory.go
|
||||
+++ b/libcontainer/cgroups/fs/memory.go
|
||||
@@ -71,14 +71,14 @@ func EnableKernelMemoryAccounting(path string) error {
|
||||
// until a limit is set on the cgroup and limit cannot be set once the
|
||||
// cgroup has children, or if there are already tasks in the cgroup.
|
||||
for _, i := range []int64{1, -1} {
|
||||
- if err := setKernelMemory(path, uint64(i)); err != nil {
|
||||
+ if err := setKernelMemory(path, i); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
-func setKernelMemory(path string, kernelMemoryLimit uint64) error {
|
||||
+func setKernelMemory(path string, kernelMemoryLimit int64) error {
|
||||
if path == "" {
|
||||
return fmt.Errorf("no such directory for %s", cgroupKernelMemoryLimit)
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func setKernelMemory(path string, kernelMemoryLimit uint64) error {
|
||||
// kernel memory is not enabled on the system so we should do nothing
|
||||
return nil
|
||||
}
|
||||
- if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatUint(kernelMemoryLimit, 10)), 0700); err != nil {
|
||||
+ if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil {
|
||||
// Check if the error number returned by the syscall is "EBUSY"
|
||||
// The EBUSY signal is returned on attempts to write to the
|
||||
// memory.kmem.limit_in_bytes file if the cgroup has children or
|
||||
@@ -104,14 +104,12 @@ func setKernelMemory(path string, kernelMemoryLimit uint64) error {
|
||||
}
|
||||
|
||||
func setMemoryAndSwap(path string, cgroup *configs.Cgroup) error {
|
||||
- ulimited := -1
|
||||
-
|
||||
- // If the memory update is set to uint64(-1) we should also
|
||||
- // set swap to uint64(-1), it means unlimited memory.
|
||||
- if cgroup.Resources.Memory == uint64(ulimited) {
|
||||
- // Only set swap if it's enbled in kernel
|
||||
+ // If the memory update is set to -1 we should also
|
||||
+ // set swap to -1, it means unlimited memory.
|
||||
+ if cgroup.Resources.Memory == -1 {
|
||||
+ // Only set swap if it's enabled in kernel
|
||||
if cgroups.PathExists(filepath.Join(path, cgroupMemorySwapLimit)) {
|
||||
- cgroup.Resources.MemorySwap = uint64(ulimited)
|
||||
+ cgroup.Resources.MemorySwap = -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,29 +124,29 @@ func setMemoryAndSwap(path string, cgroup *configs.Cgroup) error {
|
||||
// When update memory limit, we should adapt the write sequence
|
||||
// for memory and swap memory, so it won't fail because the new
|
||||
// value and the old value don't fit kernel's validation.
|
||||
- if cgroup.Resources.MemorySwap == uint64(ulimited) || memoryUsage.Limit < cgroup.Resources.MemorySwap {
|
||||
- if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatUint(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
+ if cgroup.Resources.MemorySwap == -1 || memoryUsage.Limit < uint64(cgroup.Resources.MemorySwap) {
|
||||
+ if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
- if err := writeFile(path, cgroupMemoryLimit, strconv.FormatUint(cgroup.Resources.Memory, 10)); err != nil {
|
||||
+ if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
- if err := writeFile(path, cgroupMemoryLimit, strconv.FormatUint(cgroup.Resources.Memory, 10)); err != nil {
|
||||
+ if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
- if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatUint(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
+ if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if cgroup.Resources.Memory != 0 {
|
||||
- if err := writeFile(path, cgroupMemoryLimit, strconv.FormatUint(cgroup.Resources.Memory, 10)); err != nil {
|
||||
+ if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if cgroup.Resources.MemorySwap != 0 {
|
||||
- if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatUint(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
+ if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -169,13 +167,13 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
}
|
||||
|
||||
if cgroup.Resources.MemoryReservation != 0 {
|
||||
- if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatUint(cgroup.Resources.MemoryReservation, 10)); err != nil {
|
||||
+ if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(cgroup.Resources.MemoryReservation, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if cgroup.Resources.KernelMemoryTCP != 0 {
|
||||
- if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatUint(cgroup.Resources.KernelMemoryTCP, 10)); err != nil {
|
||||
+ if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemoryTCP, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
diff --git a/libcontainer/configs/cgroup_unix.go b/libcontainer/configs/cgroup_unix.go
|
||||
index 7572289..e654960 100644
|
||||
--- a/libcontainer/configs/cgroup_unix.go
|
||||
+++ b/libcontainer/configs/cgroup_unix.go
|
||||
@@ -45,19 +45,19 @@ type Resources struct {
|
||||
Devices []*Device `json:"devices"`
|
||||
|
||||
// Memory limit (in bytes)
|
||||
- Memory uint64 `json:"memory"`
|
||||
+ Memory int64 `json:"memory"`
|
||||
|
||||
// Memory reservation or soft_limit (in bytes)
|
||||
- MemoryReservation uint64 `json:"memory_reservation"`
|
||||
+ MemoryReservation int64 `json:"memory_reservation"`
|
||||
|
||||
// Total memory usage (memory + swap); set `-1` to enable unlimited swap
|
||||
- MemorySwap uint64 `json:"memory_swap"`
|
||||
+ MemorySwap int64 `json:"memory_swap"`
|
||||
|
||||
// Kernel memory limit (in bytes)
|
||||
- KernelMemory uint64 `json:"kernel_memory"`
|
||||
+ KernelMemory int64 `json:"kernel_memory"`
|
||||
|
||||
// Kernel memory limit for TCP use (in bytes)
|
||||
- KernelMemoryTCP uint64 `json:"kernel_memory_tcp"`
|
||||
+ KernelMemoryTCP int64 `json:"kernel_memory_tcp"`
|
||||
|
||||
// CPU shares (relative weight vs. other containers)
|
||||
CpuShares uint64 `json:"cpu_shares"`
|
||||
diff --git a/update.go b/update.go
|
||||
index 5520681..226a18a 100644
|
||||
--- a/update.go
|
||||
+++ b/update.go
|
||||
@@ -124,11 +124,11 @@ other options are ignored.
|
||||
|
||||
r := specs.LinuxResources{
|
||||
Memory: &specs.LinuxMemory{
|
||||
- Limit: u64Ptr(0),
|
||||
- Reservation: u64Ptr(0),
|
||||
- Swap: u64Ptr(0),
|
||||
- Kernel: u64Ptr(0),
|
||||
- KernelTCP: u64Ptr(0),
|
||||
+ Limit: i64Ptr(0),
|
||||
+ Reservation: i64Ptr(0),
|
||||
+ Swap: i64Ptr(0),
|
||||
+ Kernel: i64Ptr(0),
|
||||
+ KernelTCP: i64Ptr(0),
|
||||
},
|
||||
CPU: &specs.LinuxCPU{
|
||||
Shares: u64Ptr(0),
|
||||
@@ -213,7 +213,7 @@ other options are ignored.
|
||||
}
|
||||
for _, pair := range []struct {
|
||||
opt string
|
||||
- dest *uint64
|
||||
+ dest *int64
|
||||
}{
|
||||
{"memory", r.Memory.Limit},
|
||||
{"memory-swap", r.Memory.Swap},
|
||||
@@ -232,7 +232,7 @@ other options are ignored.
|
||||
} else {
|
||||
v = -1
|
||||
}
|
||||
- *pair.dest = uint64(v)
|
||||
+ *pair.dest = v
|
||||
}
|
||||
}
|
||||
r.Pids.Limit = int64(context.Int("pids-limit"))
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
70
patch/0031-Add-spec-for-euleros.patch
Normal file
70
patch/0031-Add-spec-for-euleros.patch
Normal file
@ -0,0 +1,70 @@
|
||||
From 3a4b5e8752e2200d0b7967c0cf0fd8ab859b6d1a Mon Sep 17 00:00:00 2001
|
||||
From: Lei Jitang <leijitang@huawei.com>
|
||||
Date: Mon, 17 Jul 2017 02:39:37 -0400
|
||||
Subject: [PATCH 31/94] Add spec for euleros
|
||||
|
||||
Change-Id: I74128e7ba4aa7f2a15515ac753664c933432b149
|
||||
Signed-off-by: Lei Jitang <leijitang@huawei.com>
|
||||
---
|
||||
script/runc-euleros.spec | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 49 insertions(+)
|
||||
create mode 100644 script/runc-euleros.spec
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
new file mode 100644
|
||||
index 0000000..a925e02
|
||||
--- /dev/null
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -0,0 +1,49 @@
|
||||
+%global _bindir /usr/local/bin
|
||||
+
|
||||
+Name: docker-runc
|
||||
+Version: 1.0.0.rc3
|
||||
+Release: 1%{?dist}
|
||||
+Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
+
|
||||
+License: ASL 2.0
|
||||
+Source: %{name}.tar.gz
|
||||
+
|
||||
+URL: https://www.opencontainers.org/
|
||||
+Vendor: OCI
|
||||
+Packager: OCI
|
||||
+
|
||||
+BuildRequires: golang == 1.8.3
|
||||
+BuildRequires: glibc-static
|
||||
+BuildRequires: make
|
||||
+BuildRequires: libseccomp-devel
|
||||
+BuildRequires: libselinux-devel
|
||||
+
|
||||
+
|
||||
+%description
|
||||
+runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
+
|
||||
+%prep
|
||||
+%setup -c -n runc
|
||||
+
|
||||
+%install
|
||||
+
|
||||
+
|
||||
+mkdir -p .gopath/src/github.com/opencontainers
|
||||
+export GOPATH=`pwd`/.gopath
|
||||
+ln -sf `pwd` .gopath/src/github.com/opencontainers/runc
|
||||
+cd .gopath/src/github.com/opencontainers/runc
|
||||
+make BUILDTAGS="seccomp selinux" static
|
||||
+rm -rf .gopath
|
||||
+
|
||||
+install -d $RPM_BUILD_ROOT/%{_bindir}
|
||||
+install -p -m 755 runc $RPM_BUILD_ROOT/%{_bindir}/runc
|
||||
+
|
||||
+
|
||||
+%clean
|
||||
+%{__rm} -rf %{_bindir}/runc
|
||||
+
|
||||
+%files
|
||||
+%{_bindir}/runc
|
||||
+
|
||||
+%changelog
|
||||
+
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
84
patch/0032-runc-17-Always-save-own-namespace-paths.patch
Normal file
84
patch/0032-runc-17-Always-save-own-namespace-paths.patch
Normal file
@ -0,0 +1,84 @@
|
||||
From 59a5c027ef71cbad624c7547f3031dc87fc6220d Mon Sep 17 00:00:00 2001
|
||||
From: Yuanhong Peng <pengyuanhong@huawei.com>
|
||||
Date: Thu, 13 Jul 2017 16:57:00 +0800
|
||||
Subject: [PATCH 32/94] runc-17: Always save own namespace paths
|
||||
|
||||
[Changelog]: Always save own namespace paths
|
||||
|
||||
fix https://github.com/opencontainers/runc/issues/1476
|
||||
|
||||
If containerA shares namespace, say ipc namespace, with containerB, then
|
||||
its ipc namespace path would be the same as containerB and be stored in
|
||||
`state.json`. Exec into containerA will just read the namespace paths
|
||||
stored in this file and join these namespaces. So, if containerB has
|
||||
already been stopped, `docker exec containerA` will fail.
|
||||
|
||||
To address this issue, we should always save own namespace paths no
|
||||
matter if we share namespaces with other containers.
|
||||
|
||||
**before:**
|
||||
```
|
||||
# docker run -tid --name 111 ubuntu
|
||||
b123d1a43786523996a52f88c0484b77f778ff59435e257b901926366ba9e046
|
||||
# docker run -tid --name 222 --net container:111 ubuntu
|
||||
4685ca6a5e9fd03c634a88f6a07009738729f6210b13d32ea8fc46a058b1f004
|
||||
# docker restart 111
|
||||
111
|
||||
# docker exec -ti 222 bash
|
||||
rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:240:
|
||||
creating new parent process caused "container_linux.go:1266: running lstat on namespace
|
||||
path \"/proc/14575/ns/net\" caused \"lstat /proc/14575/ns/net: no such file or directory\""
|
||||
```
|
||||
|
||||
**after:**
|
||||
```
|
||||
# docker run -tid --name 111 ubuntu
|
||||
e00dbfe3bf56272d7bdec232135f707b4a715cb0d39cdc4d3e90b05075497175
|
||||
# docker run -tid --name 222 --net container:111 ubuntu
|
||||
0806efe28080392f5a3ef416c363be0d82c3bc64d069f227d57ab34170b6fb16
|
||||
# docker restart 111
|
||||
111
|
||||
# docker exec -ti 222 bash
|
||||
root@e00dbfe3bf56:/#
|
||||
```
|
||||
|
||||
related upstream PR: https://github.com/opencontainers/runc/pull/1477
|
||||
|
||||
Change-Id: I4278f64704c4b0ab0c2e5b44ec9ecdd34735144d
|
||||
Signed-off-by: Yuanhong Peng <pengyuanhong@huawei.com>
|
||||
Signed-off-by: yangshukui <yangshukui@huawei.com>
|
||||
---
|
||||
libcontainer/configs/namespaces_unix.go | 3 ---
|
||||
libcontainer/container_linux_test.go | 2 +-
|
||||
2 files changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/namespaces_unix.go b/libcontainer/configs/namespaces_unix.go
|
||||
index 1f0b3ee..12470a0 100644
|
||||
--- a/libcontainer/configs/namespaces_unix.go
|
||||
+++ b/libcontainer/configs/namespaces_unix.go
|
||||
@@ -81,9 +81,6 @@ type Namespace struct {
|
||||
}
|
||||
|
||||
func (n *Namespace) GetPath(pid int) string {
|
||||
- if n.Path != "" {
|
||||
- return n.Path
|
||||
- }
|
||||
return fmt.Sprintf("/proc/%d/ns/%s", pid, NsName(n.Type))
|
||||
}
|
||||
|
||||
diff --git a/libcontainer/container_linux_test.go b/libcontainer/container_linux_test.go
|
||||
index b7ce552..b69e344 100644
|
||||
--- a/libcontainer/container_linux_test.go
|
||||
+++ b/libcontainer/container_linux_test.go
|
||||
@@ -134,7 +134,7 @@ func TestGetContainerState(t *testing.T) {
|
||||
var (
|
||||
pid = os.Getpid()
|
||||
expectedMemoryPath = "/sys/fs/cgroup/memory/myid"
|
||||
- expectedNetworkPath = "/networks/fd"
|
||||
+ expectedNetworkPath = fmt.Sprintf("/proc/%d/ns/net", pid)
|
||||
)
|
||||
container := &linuxContainer{
|
||||
id: "myid",
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
52
patch/0033-runc-change-runc-default-umask-to-027.patch
Normal file
52
patch/0033-runc-change-runc-default-umask-to-027.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 49ff7be84939cf93b8bf4861ddc783704fb3f50b Mon Sep 17 00:00:00 2001
|
||||
From: dengguangxing <dengguangxing@huawei.com>
|
||||
Date: Mon, 8 Jan 2018 10:35:34 +0800
|
||||
Subject: [PATCH 33/94] runc: change runc default umask to 027
|
||||
|
||||
[Changelog]:change runc default umask to 027
|
||||
change exec process default umask to 0027
|
||||
|
||||
Change-Id: Ia7ff0216adc17d61586954de83031be21ab88338
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/rootfs_linux.go | 2 +-
|
||||
libcontainer/setns_init_linux.go | 3 +++
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index d507373..1c93903 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -136,7 +136,7 @@ func finalizeRootfs(config *configs.Config) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
- syscall.Umask(0022)
|
||||
+ syscall.Umask(0027)
|
||||
return nil
|
||||
}
|
||||
|
||||
diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go
|
||||
index 48cc0ae..e8e969a 100644
|
||||
--- a/libcontainer/setns_init_linux.go
|
||||
+++ b/libcontainer/setns_init_linux.go
|
||||
@@ -5,6 +5,7 @@ package libcontainer
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
+ "syscall"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
"github.com/opencontainers/runc/libcontainer/keys"
|
||||
@@ -40,6 +41,8 @@ func (l *linuxSetnsInit) Init() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
+ // set exec process umask to 0027 according to secure policy
|
||||
+ syscall.Umask(0027)
|
||||
if l.config.NoNewPrivileges {
|
||||
if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
|
||||
return err
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
From 661a5bf6a414ded19e8722e81ea20f6218d9b7de Mon Sep 17 00:00:00 2001
|
||||
From: yangshukui <yangshukui@huawei.com>
|
||||
Date: Fri, 20 Apr 2018 22:38:32 +0800
|
||||
Subject: [PATCH 34/94] runc-17: Add some compatibility code to surport
|
||||
docker's liverestore from docker-1.11.2 to docker-17.06
|
||||
|
||||
[Changelog]: Add some compatibility code to surport docker's liverestore from docker-1.11.2 to docker-17.06
|
||||
|
||||
[Author]:Shukui Yang <yangshukui@huawei.com>
|
||||
|
||||
Change-Id: I376cc81f781727ea8d0bc61bc0c6e72ca485d880
|
||||
Signed-off-by: yangshukui <yangshukui@huawei.com>
|
||||
---
|
||||
libcontainer/factory_linux.go | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go
|
||||
index 6a0f855..8bf448a 100644
|
||||
--- a/libcontainer/factory_linux.go
|
||||
+++ b/libcontainer/factory_linux.go
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
+ "strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
@@ -321,7 +322,17 @@ func (l *LinuxFactory) loadState(root, id string) (*State, error) {
|
||||
defer f.Close()
|
||||
var state *State
|
||||
if err := json.NewDecoder(f).Decode(&state); err != nil {
|
||||
- return nil, newGenericError(err, SystemError)
|
||||
+ if !strings.Contains(err.Error(), "memory_swappiness") {
|
||||
+ return nil, newGenericError(err, SystemError)
|
||||
+ }
|
||||
+
|
||||
+ if state.BaseState.Config.Cgroups != nil &&
|
||||
+ state.BaseState.Config.Cgroups.Resources != nil &&
|
||||
+ state.BaseState.Config.Cgroups.Resources.MemorySwappiness != nil {
|
||||
+ memorySwappiness := int64(-1)
|
||||
+ *state.BaseState.Config.Cgroups.Resources.MemorySwappiness = uint64(memorySwappiness)
|
||||
+ }
|
||||
+
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
141
patch/0035-runc-17-Add-root-to-HookState-for-compatibili.patch
Normal file
141
patch/0035-runc-17-Add-root-to-HookState-for-compatibili.patch
Normal file
@ -0,0 +1,141 @@
|
||||
From 35c1ee336b5714b077c0007ed6c37149bd965260 Mon Sep 17 00:00:00 2001
|
||||
From: yangshukui <yangshukui@huawei.com>
|
||||
Date: Fri, 27 Apr 2018 20:24:42 +0800
|
||||
Subject: [PATCH 35/94] runc-17: Add root to HookState for
|
||||
compatibility.
|
||||
|
||||
[Changelog]:refactor HookState for backward compatibility.
|
||||
[Author]:Shukui Yang
|
||||
|
||||
Change-Id: I471a748005fe5a7be69d5a857944bf8599408c3b
|
||||
Signed-off-by: yangshukui <yangshukui@huawei.com>
|
||||
---
|
||||
libcontainer/configs/config.go | 8 +++++++-
|
||||
libcontainer/container_linux.go | 22 ++++++++++++++--------
|
||||
libcontainer/process_linux.go | 22 ++++++++++++++--------
|
||||
libcontainer/state_linux.go | 9 ++++++---
|
||||
4 files changed, 41 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go
|
||||
index 98f4b85..af25972 100644
|
||||
--- a/libcontainer/configs/config.go
|
||||
+++ b/libcontainer/configs/config.go
|
||||
@@ -259,8 +259,14 @@ func (hooks Hooks) MarshalJSON() ([]byte, error) {
|
||||
})
|
||||
}
|
||||
|
||||
+// Alias of specs.State
|
||||
+type SpecState specs.State
|
||||
+
|
||||
// HookState is the payload provided to a hook on execution.
|
||||
-type HookState specs.State
|
||||
+type HookState struct {
|
||||
+ SpecState
|
||||
+ Root string `json:"root"`
|
||||
+}
|
||||
|
||||
type Hook interface {
|
||||
// Run executes the hook with the provided state.
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 173a3f0..ea6ef4c 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -275,10 +275,13 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
|
||||
if c.config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
- Version: c.config.Version,
|
||||
- ID: c.id,
|
||||
- Pid: parent.pid(),
|
||||
- Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
+ SpecState: configs.SpecState{
|
||||
+ Version: c.config.Version,
|
||||
+ ID: c.id,
|
||||
+ Pid: parent.pid(),
|
||||
+ Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
+ },
|
||||
+ Root: c.config.Rootfs,
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Poststart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
@@ -1243,10 +1246,13 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
|
||||
case notify.GetScript() == "setup-namespaces":
|
||||
if c.config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
- Version: c.config.Version,
|
||||
- ID: c.id,
|
||||
- Pid: int(notify.GetPid()),
|
||||
- Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
+ SpecState: configs.SpecState{
|
||||
+ Version: c.config.Version,
|
||||
+ ID: c.id,
|
||||
+ Pid: int(notify.GetPid()),
|
||||
+ Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
+ },
|
||||
+ Root: c.config.Rootfs,
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Prestart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index bfe9955..c9fb202 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -292,10 +292,13 @@ func (p *initProcess) start() error {
|
||||
if !p.config.Config.Namespaces.Contains(configs.NEWNS) {
|
||||
if p.config.Config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
- Version: p.container.config.Version,
|
||||
- ID: p.container.id,
|
||||
- Pid: p.pid(),
|
||||
- Bundle: utils.SearchLabels(p.config.Config.Labels, "bundle"),
|
||||
+ SpecState: configs.SpecState{
|
||||
+ Version: p.container.config.Version,
|
||||
+ ID: p.container.id,
|
||||
+ Pid: p.pid(),
|
||||
+ Bundle: utils.SearchLabels(p.config.Config.Labels, "bundle"),
|
||||
+ },
|
||||
+ Root: p.config.Config.Rootfs,
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
@@ -312,10 +315,13 @@ func (p *initProcess) start() error {
|
||||
case procHooks:
|
||||
if p.config.Config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
- Version: p.container.config.Version,
|
||||
- ID: p.container.id,
|
||||
- Pid: p.pid(),
|
||||
- Bundle: utils.SearchLabels(p.config.Config.Labels, "bundle"),
|
||||
+ SpecState: configs.SpecState{
|
||||
+ Version: p.container.config.Version,
|
||||
+ ID: p.container.id,
|
||||
+ Pid: p.pid(),
|
||||
+ Bundle: utils.SearchLabels(p.config.Config.Labels, "bundle"),
|
||||
+ },
|
||||
+ Root: p.config.Config.Rootfs,
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go
|
||||
index 62878ac..9f8def2 100644
|
||||
--- a/libcontainer/state_linux.go
|
||||
+++ b/libcontainer/state_linux.go
|
||||
@@ -58,9 +58,12 @@ func destroy(c *linuxContainer) error {
|
||||
func runPoststopHooks(c *linuxContainer) error {
|
||||
if c.config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
- Version: c.config.Version,
|
||||
- ID: c.id,
|
||||
- Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
+ SpecState: configs.SpecState{
|
||||
+ Version: c.config.Version,
|
||||
+ ID: c.id,
|
||||
+ Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
+ },
|
||||
+ Root: c.config.Rootfs,
|
||||
}
|
||||
for _, hook := range c.config.Hooks.Poststop {
|
||||
if err := hook.Run(s); err != nil {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
208
patch/0036-runc-17-add-compatibility-for-docker-1.11.2.patch
Normal file
208
patch/0036-runc-17-add-compatibility-for-docker-1.11.2.patch
Normal file
@ -0,0 +1,208 @@
|
||||
From 988554ab5c12971383bc717cda615ca672953cd5 Mon Sep 17 00:00:00 2001
|
||||
From: yangshukui <yangshukui@huawei.com>
|
||||
Date: Fri, 18 May 2018 11:03:48 +0800
|
||||
Subject: [PATCH 36/94] runc-17: add compatibility for docker-1.11.2
|
||||
|
||||
[Changelog]: add compatibility for docker-1.11.2
|
||||
[Author]: Shukui Yang
|
||||
|
||||
Change-Id: I188db47db8f4bcd744ac8218bfe966de48e97c22
|
||||
Signed-off-by: yangshukui <yangshukui@huawei.com>
|
||||
---
|
||||
libcontainer/configs/cgroup_unix.go | 6 +++
|
||||
libcontainer/configs/config.go | 11 ++++
|
||||
libcontainer/container_linux.go | 6 +++
|
||||
libcontainer/factory_linux.go | 102 +++++++++++++++++++++++++++++++-----
|
||||
4 files changed, 113 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/cgroup_unix.go b/libcontainer/configs/cgroup_unix.go
|
||||
index e654960..75a3db0 100644
|
||||
--- a/libcontainer/configs/cgroup_unix.go
|
||||
+++ b/libcontainer/configs/cgroup_unix.go
|
||||
@@ -33,6 +33,12 @@ type Cgroup struct {
|
||||
*Resources
|
||||
}
|
||||
|
||||
+// CompatCgroup
|
||||
+type CompatCgroup struct {
|
||||
+ Cgroup
|
||||
+ MemorySwappiness interface{} `json:"memory_swappiness"`
|
||||
+}
|
||||
+
|
||||
type Resources struct {
|
||||
// If this is true allow access to any kind of device within the container. If false, allow access only to devices explicitly listed in the allowed_devices list.
|
||||
// Deprecated
|
||||
diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go
|
||||
index af25972..3a2e824 100644
|
||||
--- a/libcontainer/configs/config.go
|
||||
+++ b/libcontainer/configs/config.go
|
||||
@@ -188,6 +188,17 @@ type Config struct {
|
||||
Rootless bool `json:"rootless"`
|
||||
}
|
||||
|
||||
+// CompatConfig is a structure inheriting from spec.Process defined
|
||||
+// in runtime-spec/specs-go package. The goal is to be compatible with
|
||||
+// both v1.0.0-rc4 and v1.0.0-rc5 since the latter introduced a change
|
||||
+// about the type of the Capabilities field.
|
||||
+// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb
|
||||
+type CompatConfig struct {
|
||||
+ Config
|
||||
+ Cgroups *CompatCgroup `json:"cgroups"`
|
||||
+ Capabilities interface{} `json:"capabilities,omitempty" platform:"linux"`
|
||||
+}
|
||||
+
|
||||
type Hooks struct {
|
||||
// Prestart commands are executed after the container namespaces are created,
|
||||
// but before the user supplied command is executed from init.
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index ea6ef4c..f4eec7e 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -66,6 +66,12 @@ type State struct {
|
||||
ExternalDescriptors []string `json:"external_descriptors,omitempty"`
|
||||
}
|
||||
|
||||
+// CompatState
|
||||
+type CompatState struct{
|
||||
+ State
|
||||
+ Config configs.CompatConfig `json:"config"`
|
||||
+}
|
||||
+
|
||||
// Container is a libcontainer container object.
|
||||
//
|
||||
// Each container is thread-safe within the same process. Since a container can
|
||||
diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go
|
||||
index 8bf448a..b533346 100644
|
||||
--- a/libcontainer/factory_linux.go
|
||||
+++ b/libcontainer/factory_linux.go
|
||||
@@ -10,8 +10,9 @@ import (
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
- "strings"
|
||||
"syscall"
|
||||
+ "io/ioutil"
|
||||
+ "errors"
|
||||
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
@@ -311,28 +312,105 @@ func (l *LinuxFactory) StartInitialization() (err error) {
|
||||
return i.Init()
|
||||
}
|
||||
|
||||
-func (l *LinuxFactory) loadState(root, id string) (*State, error) {
|
||||
- f, err := os.Open(filepath.Join(root, stateFilename))
|
||||
+func (l *LinuxFactory) updateStateCapabilites(compatState *CompatState, configPath string) error {
|
||||
+ needUpdate := false
|
||||
+
|
||||
+ // In spec v1.0.0-rc4, capabilities was a list of strings. This was changed
|
||||
+ // to an object with v1.0.0-rc5.
|
||||
+ // Check for the interface type to support both the versions.
|
||||
+ capabilities := compatState.Config.Capabilities
|
||||
+ switch caps := capabilities.(type) {
|
||||
+ case []interface{}:
|
||||
+ var list []string
|
||||
+ for _, str := range caps {
|
||||
+ list = append(list, str.(string))
|
||||
+ }
|
||||
+
|
||||
+ c := configs.Capabilities{
|
||||
+ Bounding: list,
|
||||
+ Effective: list,
|
||||
+ Inheritable: list,
|
||||
+ Ambient: list,
|
||||
+ Permitted: list,
|
||||
+ }
|
||||
+ compatState.Config.Capabilities = c
|
||||
+ needUpdate = true
|
||||
+ }
|
||||
+
|
||||
+ //In spec v1.0.0-rc4, MemorySwappiness was a *int64. This was changed
|
||||
+ // to an *uint64 with v1.0.0-rc5.
|
||||
+ if compatState.Config.Cgroups != nil &&
|
||||
+ compatState.Config.Cgroups.MemorySwappiness != nil {
|
||||
+ memorySwappiness, ok := compatState.Config.Cgroups.MemorySwappiness.(float64)
|
||||
+ if ok {
|
||||
+ var memSize int64 = int64(memorySwappiness)
|
||||
+ if memSize < 0 {
|
||||
+ memSize = 0
|
||||
+ var memUSize uint64 = uint64(memSize-1)
|
||||
+ compatState.Config.Cgroups.MemorySwappiness = &memUSize
|
||||
+ needUpdate = true
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if needUpdate {
|
||||
+ f, err := os.Create(configPath)
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ defer f.Close()
|
||||
+ if err := json.NewEncoder(f).Encode(&compatState); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ return nil
|
||||
+ }
|
||||
+
|
||||
+ return errors.New("updateStateCapabilites unexpected format for capabilities")
|
||||
+}
|
||||
+
|
||||
+func (l *LinuxFactory) loadOriginState(configPath string) (*State, error) {
|
||||
+ f, err := os.Open(configPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
- return nil, newGenericError(fmt.Errorf("container %q does not exist", id), ContainerNotExists)
|
||||
+ return nil, newGenericError(err, ContainerNotExists)
|
||||
}
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
defer f.Close()
|
||||
var state *State
|
||||
if err := json.NewDecoder(f).Decode(&state); err != nil {
|
||||
- if !strings.Contains(err.Error(), "memory_swappiness") {
|
||||
- return nil, newGenericError(err, SystemError)
|
||||
- }
|
||||
+ return nil, newGenericError(err, SystemError)
|
||||
+ }
|
||||
+ return state, nil
|
||||
+}
|
||||
|
||||
- if state.BaseState.Config.Cgroups != nil &&
|
||||
- state.BaseState.Config.Cgroups.Resources != nil &&
|
||||
- state.BaseState.Config.Cgroups.Resources.MemorySwappiness != nil {
|
||||
- memorySwappiness := int64(-1)
|
||||
- *state.BaseState.Config.Cgroups.Resources.MemorySwappiness = uint64(memorySwappiness)
|
||||
+func (l *LinuxFactory) loadCompatState(configPath string) (*State, error) {
|
||||
+ dt, err := ioutil.ReadFile(configPath)
|
||||
+ if err != nil {
|
||||
+ if os.IsNotExist(err) {
|
||||
+ return nil, newGenericError(err, ContainerNotExists)
|
||||
}
|
||||
+ return nil, newGenericError(err, SystemError)
|
||||
+ }
|
||||
|
||||
+ var state *CompatState
|
||||
+ if err := json.Unmarshal(dt, &state); err != nil {
|
||||
+ return nil, newGenericError(err, SystemError)
|
||||
+ }
|
||||
+
|
||||
+ err = l.updateStateCapabilites(state, configPath)
|
||||
+ if err != nil {
|
||||
+ return nil, newGenericError(err, SystemError)
|
||||
+ }
|
||||
+
|
||||
+ return l.loadOriginState(configPath)
|
||||
+}
|
||||
+
|
||||
+func (l *LinuxFactory) loadState(root, id string) (*State, error) {
|
||||
+ configPath := filepath.Join(root, stateFilename)
|
||||
+ state, err := l.loadOriginState(configPath)
|
||||
+ if err != nil {
|
||||
+ return l.loadCompatState(configPath)
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
61
patch/0037-docker-Don-t-enalbe-kmem-accounting-by-defa.patch
Normal file
61
patch/0037-docker-Don-t-enalbe-kmem-accounting-by-defa.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From 093594c58411b6a25844650b40463449e1af11ce Mon Sep 17 00:00:00 2001
|
||||
From: lujingxiao <lujingxiao@huawei.com>
|
||||
Date: Thu, 23 Aug 2018 15:03:50 +0800
|
||||
Subject: [PATCH 37/94] docker: Don't enalbe kmem accounting by
|
||||
default
|
||||
|
||||
reason:In kernel 3.10, kmem cgroup is unstable,
|
||||
we should not enable kmem accounting by default.
|
||||
Revert part of
|
||||
https://github.com/hqhq/runc/commit/fe898e7862f945fa3632580139602c627dcb9be0
|
||||
|
||||
Change-Id: I546d1da875b1df7d525fd5c96a89c439ed6642f2
|
||||
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||||
---
|
||||
libcontainer/cgroups/fs/memory.go | 6 ++----
|
||||
script/runc-euleros.spec | 8 ++++++--
|
||||
2 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/cgroups/fs/memory.go b/libcontainer/cgroups/fs/memory.go
|
||||
index c993839..118cce8 100644
|
||||
--- a/libcontainer/cgroups/fs/memory.go
|
||||
+++ b/libcontainer/cgroups/fs/memory.go
|
||||
@@ -41,10 +41,8 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
- // Only enable kernel memory accouting when this cgroup
|
||||
- // is created by libcontainer, otherwise we might get
|
||||
- // error when people use `cgroupsPath` to join an existed
|
||||
- // cgroup whose kernel memory is not initialized.
|
||||
+ }
|
||||
+ if d.config.KernelMemory != 0 {
|
||||
if err := EnableKernelMemoryAccounting(path); err != nil {
|
||||
return err
|
||||
}
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index a925e02..c3db7c9 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 1%{?dist}
|
||||
+Release: 2%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
@@ -46,4 +46,8 @@ install -p -m 755 runc $RPM_BUILD_ROOT/%{_bindir}/runc
|
||||
%{_bindir}/runc
|
||||
|
||||
%changelog
|
||||
-
|
||||
+* Thu Aug 23 2018 lujingxiao<lujingxiao@huawei.com> - 1.0.0.rc3-2
|
||||
+- Type:bugfix
|
||||
+- ID:NA
|
||||
+- SUG:NA
|
||||
+- DESC:Don't enalbe kmem accounting by default
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
From 423ffe00c5c0cdb999bf9a193ad43ed5b6473a2d Mon Sep 17 00:00:00 2001
|
||||
From: Wang Long <long.wanglong@huawei.com>
|
||||
Date: Tue, 24 Jan 2017 18:51:22 +0800
|
||||
Subject: [PATCH 39/94] Fix unittest and integration test error caused
|
||||
by tty
|
||||
|
||||
Change-Id: Iae44f5a598e60b9e026ced99ca9e92aa90771fcc
|
||||
Signed-off-by: Wang Long <long.wanglong@huawei.com>
|
||||
---
|
||||
libcontainer/integration/execin_test.go | 8 +-------
|
||||
tests/integration/exec.bats | 4 ++--
|
||||
2 files changed, 3 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/integration/execin_test.go b/libcontainer/integration/execin_test.go
|
||||
index 019757f..f06075e 100644
|
||||
--- a/libcontainer/integration/execin_test.go
|
||||
+++ b/libcontainer/integration/execin_test.go
|
||||
@@ -62,9 +62,6 @@ func TestExecIn(t *testing.T) {
|
||||
if !strings.Contains(out, "cat") || !strings.Contains(out, "ps") {
|
||||
t.Fatalf("unexpected running process, output %q", out)
|
||||
}
|
||||
- if strings.Contains(out, "\r") {
|
||||
- t.Fatalf("unexpected carriage-return in output")
|
||||
- }
|
||||
}
|
||||
|
||||
func TestExecInUsernsRlimit(t *testing.T) {
|
||||
@@ -327,12 +324,9 @@ func TestExecInTTY(t *testing.T) {
|
||||
waitProcess(process, t)
|
||||
|
||||
out := stdout.String()
|
||||
- if !strings.Contains(out, "cat") || !strings.Contains(out, "ps") {
|
||||
+ if !strings.Contains(out, "cat") || !strings.Contains(string(out), "ps") {
|
||||
t.Fatalf("unexpected running process, output %q", out)
|
||||
}
|
||||
- if strings.Contains(out, "\r") {
|
||||
- t.Fatalf("unexpected carriage-return in output")
|
||||
- }
|
||||
}
|
||||
|
||||
func TestExecInEnvironment(t *testing.T) {
|
||||
diff --git a/tests/integration/exec.bats b/tests/integration/exec.bats
|
||||
index f172f9b..268a7e1 100644
|
||||
--- a/tests/integration/exec.bats
|
||||
+++ b/tests/integration/exec.bats
|
||||
@@ -95,7 +95,7 @@ function teardown() {
|
||||
|
||||
runc exec --cwd /bin test_busybox pwd
|
||||
[ "$status" -eq 0 ]
|
||||
- [[ ${output} == "/bin" ]]
|
||||
+ [[ $(echo "${output}" | tr -d '\r') == "/bin" ]]
|
||||
}
|
||||
|
||||
@test "runc exec --env" {
|
||||
@@ -124,5 +124,5 @@ function teardown() {
|
||||
runc exec --user 1000:1000 test_busybox id
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
- [[ ${output} == "uid=1000 gid=1000" ]]
|
||||
+ [[ $(echo "${output}" | tr -d '\r') == "uid=1000 gid=1000" ]]
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
68
patch/0041-Add-timeout-for-syscall.Openat.patch
Normal file
68
patch/0041-Add-timeout-for-syscall.Openat.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From a2f81f8b740b371e710b63b8c81c704842140ace Mon Sep 17 00:00:00 2001
|
||||
From: yangshukui <yangshukui@huawei.com>
|
||||
Date: Tue, 18 Apr 2017 19:35:30 +0800
|
||||
Subject: [PATCH 41/94] Add timeout for syscall.Openat
|
||||
|
||||
Openat will be blocked until the fifo on the other side is opened, but in some
|
||||
abnomal scenario(e.g. containerd is killed), Openat maybe be blocked all the time.
|
||||
|
||||
Change-Id: If1d514408b522c8bdf5f1c1cb0d3c625f0ef4a6d
|
||||
Signed-off-by: yangshukui <yangshukui@huawei.com>
|
||||
---
|
||||
libcontainer/standard_init_linux.go | 30 ++++++++++++++++++++++++------
|
||||
1 file changed, 24 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go
|
||||
index ee6f19a..484ba42 100644
|
||||
--- a/libcontainer/standard_init_linux.go
|
||||
+++ b/libcontainer/standard_init_linux.go
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
+ "time"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
@@ -166,15 +167,32 @@ func (l *linuxStandardInit) Init() error {
|
||||
}
|
||||
// close the pipe to signal that we have completed our init.
|
||||
l.pipe.Close()
|
||||
+
|
||||
// wait for the fifo to be opened on the other side before
|
||||
// exec'ing the users process.
|
||||
- fd, err := syscall.Openat(l.stateDirFD, execFifoFilename, os.O_WRONLY|syscall.O_CLOEXEC, 0)
|
||||
- if err != nil {
|
||||
- return newSystemErrorWithCause(err, "openat exec fifo")
|
||||
- }
|
||||
- if _, err := syscall.Write(fd, []byte("0")); err != nil {
|
||||
- return newSystemErrorWithCause(err, "write 0 exec fifo")
|
||||
+ ch := make(chan Error, 1)
|
||||
+ go func() {
|
||||
+ fd, err := syscall.Openat(l.stateDirFD, execFifoFilename, os.O_WRONLY|syscall.O_CLOEXEC, 0)
|
||||
+ if err != nil {
|
||||
+ ch <- newSystemErrorWithCause(err, "openat exec fifo")
|
||||
+ return
|
||||
+ }
|
||||
+ if _, err := syscall.Write(fd, []byte("0")); err != nil {
|
||||
+ ch <- newSystemErrorWithCause(err, "write 0 exec fifo")
|
||||
+ return
|
||||
+ }
|
||||
+ ch <- nil
|
||||
+ }()
|
||||
+
|
||||
+ select {
|
||||
+ case chErr := <-ch:
|
||||
+ if chErr != nil {
|
||||
+ return chErr
|
||||
+ }
|
||||
+ case <-time.After(120 * time.Second):
|
||||
+ return newSystemErrorWithCause(fmt.Errorf("timeout"), "wait for the fifo to be opened on the other side ")
|
||||
}
|
||||
+
|
||||
if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges {
|
||||
if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
|
||||
return newSystemErrorWithCause(err, "init seccomp")
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
From 3b61668af89b820482b0a58f5af5316e1529116b Mon Sep 17 00:00:00 2001
|
||||
From: Deng Guangxing <dengguangxing@huawei.com>
|
||||
Date: Wed, 6 Sep 2017 15:04:47 +0800
|
||||
Subject: [PATCH 42/94] update state earlier to avoid cgroup leak when
|
||||
process failed
|
||||
|
||||
if process stuck in somewhere. upper caller like containerd may
|
||||
have a timeout for process launching.
|
||||
|
||||
process will be killed after this timeout, and then call `runc
|
||||
delete` to retrieve its resource like cgroup and perform poststop
|
||||
hook.
|
||||
|
||||
if process got stuck right before updating state, and after cgroup
|
||||
applied, like prestart-hook. In such case, `runc delete xxx` will
|
||||
do nothing because state file is missing, runc is not aware of this
|
||||
container. so process cgroup will stay and never get removed.
|
||||
|
||||
This patch perform state updating right after cgroup applying. so
|
||||
`runc delete` will do the cleaning job
|
||||
|
||||
Change-Id: I7b247f501986e712a86da3958d1be573af4e84a6
|
||||
Signed-off-by: Deng Guangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/process_linux.go | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index c9fb202..9373595 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -260,6 +260,11 @@ func (p *initProcess) start() error {
|
||||
if err := p.manager.Apply(p.pid()); err != nil {
|
||||
return newSystemErrorWithCause(err, "applying cgroup configuration for process")
|
||||
}
|
||||
+ // update state here, so we can retrieve process resource
|
||||
+ // even it get killed by accident
|
||||
+ if _, err := p.container.updateState(p); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
defer func() {
|
||||
if err != nil {
|
||||
// TODO: should not be the responsibility to call here
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
43
patch/0043-runc-Use-rslave-instead-of-rprivate-in-chro.patch
Normal file
43
patch/0043-runc-Use-rslave-instead-of-rprivate-in-chro.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 321679149dad13cdfd40831cc288495d4a5caf75 Mon Sep 17 00:00:00 2001
|
||||
From: caihaomin <caihaomin@huawei.com>
|
||||
Date: Fri, 15 Dec 2017 17:37:41 +0800
|
||||
Subject: [PATCH 43/94] runc: Use rslave instead of rprivate in
|
||||
chrootarchive
|
||||
|
||||
[Changelog]:With rprivate there exists a race where a reference to a mount has
|
||||
propagated to the new namespace, when rprivate is set the parent
|
||||
namespace is not able to remove the mount due to that reference.
|
||||
With rslave unmounts will propagate correctly into the namespace and
|
||||
prevent the sort of transient errors that are possible with rprivate.
|
||||
https://github.com/moby/moby/pull/35217
|
||||
[Author]git
|
||||
|
||||
Change-Id: I7a69a5b0c03e896b9cb1722eb676b7b84ea7dd77
|
||||
Signed-off-by: caihaomin <caihaomin@huawei.com>
|
||||
---
|
||||
libcontainer/rootfs_linux.go | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index 1c93903..7cf5edd 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -668,9 +668,12 @@ func pivotRoot(rootfs string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
- // Make oldroot rprivate to make sure our unmounts don't propagate to the
|
||||
- // host (and thus bork the machine).
|
||||
- if err := syscall.Mount("", ".", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
|
||||
+ // Make oldroot rslave to make sure our unmounts don't propagate to the
|
||||
+ // host (and thus bork the machine). We don't use rprivate because this is
|
||||
+ // known to cause issues due to races where we still have a reference to a
|
||||
+ // mount while a process in the host namespace are trying to operate on
|
||||
+ // something they think has no mounts (devicemapper in particular).
|
||||
+ if err := syscall.Mount("", ".", "", syscall.MS_SLAVE|syscall.MS_REC, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
// Preform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd.
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
43
patch/0044-runc-default-mount-propagation-correctly.patch
Normal file
43
patch/0044-runc-default-mount-propagation-correctly.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 06109d15b267af73d523817e6dcf501fa071a815 Mon Sep 17 00:00:00 2001
|
||||
From: caihaomin <caihaomin@huawei.com>
|
||||
Date: Fri, 15 Dec 2017 17:42:03 +0800
|
||||
Subject: [PATCH 44/94] runc: default mount propagation correctly
|
||||
|
||||
[Changelog]:The code in prepareRoot
|
||||
attempts to default the rootfs mount to `rslave`. However, since the spec
|
||||
conversion has already defaulted it to `rprivate`, that code doesn't
|
||||
actually ever do anything.
|
||||
|
||||
This changes the spec conversion code to accept "" and treat it as 0.
|
||||
|
||||
Implicitly, this makes rootfs propagation default to `rslave`, which is
|
||||
a part of fixing the moby bug moby/moby#34672
|
||||
|
||||
Alternate implementatoins include changing this defaulting to be
|
||||
`rslave` and removing the defaulting code in prepareRoot, or skipping
|
||||
the mapping entirely for "", but I think this change is the cleanest of
|
||||
those options.
|
||||
[Author]git
|
||||
|
||||
Change-Id: I35954e2c8a71c1d3713753669044b5bf9d6c57fa
|
||||
Signed-off-by: caihaomin <caihaomin@huawei.com>
|
||||
---
|
||||
libcontainer/specconv/spec_linux.go | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
|
||||
index 1575ae0..8a2947f 100644
|
||||
--- a/libcontainer/specconv/spec_linux.go
|
||||
+++ b/libcontainer/specconv/spec_linux.go
|
||||
@@ -36,7 +36,7 @@ var mountPropagationMapping = map[string]int{
|
||||
"slave": syscall.MS_SLAVE,
|
||||
"rshared": syscall.MS_SHARED | syscall.MS_REC,
|
||||
"shared": syscall.MS_SHARED,
|
||||
- "": syscall.MS_PRIVATE | syscall.MS_REC,
|
||||
+ "": 0,
|
||||
}
|
||||
|
||||
var allowedDevices = []*configs.Device{
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
128
patch/0045-runc-add-hook-specific-info-when-error-occurr.patch
Normal file
128
patch/0045-runc-add-hook-specific-info-when-error-occurr.patch
Normal file
@ -0,0 +1,128 @@
|
||||
From eed1c5ec5166a151da33b7b9cfd6535f4556c015 Mon Sep 17 00:00:00 2001
|
||||
From: dengguangxing <dengguangxing@huawei.com>
|
||||
Date: Tue, 16 Jan 2018 18:00:56 +0800
|
||||
Subject: [PATCH 45/94] runc: add hook specific info when error
|
||||
occurred
|
||||
|
||||
[Changelog]: print hook path and args when hook failed to make debug
|
||||
easier
|
||||
[Author]:Shukui Yang
|
||||
|
||||
Change-Id: Idf704706b73f1cfa5f7f02b01b2ec58caadca79d
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/configs/config.go | 10 ++++++++++
|
||||
libcontainer/container_linux.go | 2 +-
|
||||
libcontainer/factory_linux_test.go | 4 ++++
|
||||
libcontainer/process_linux.go | 4 ++--
|
||||
libcontainer/state_linux.go | 4 ++--
|
||||
5 files changed, 19 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go
|
||||
index 3a2e824..49bc7a3 100644
|
||||
--- a/libcontainer/configs/config.go
|
||||
+++ b/libcontainer/configs/config.go
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
+ "strings"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
@@ -282,6 +283,7 @@ type HookState struct {
|
||||
type Hook interface {
|
||||
// Run executes the hook with the provided state.
|
||||
Run(HookState) error
|
||||
+ Info() string
|
||||
}
|
||||
|
||||
// NewFunctionHook will call the provided function when the hook is run.
|
||||
@@ -299,6 +301,10 @@ func (f FuncHook) Run(s HookState) error {
|
||||
return f.run(s)
|
||||
}
|
||||
|
||||
+func (f FuncHook) Info() string {
|
||||
+ return "hook function"
|
||||
+}
|
||||
+
|
||||
type Command struct {
|
||||
Path string `json:"path"`
|
||||
Args []string `json:"args"`
|
||||
@@ -318,6 +324,10 @@ type CommandHook struct {
|
||||
Command
|
||||
}
|
||||
|
||||
+func (c Command) Info() string {
|
||||
+ return c.Path + "," + strings.Join(c.Args, ",")
|
||||
+}
|
||||
+
|
||||
func (c Command) Run(s HookState) error {
|
||||
b, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index f4eec7e..9fabadc 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -294,7 +294,7 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
if err := parent.terminate(); err != nil {
|
||||
logrus.Warn(err)
|
||||
}
|
||||
- return newSystemErrorWithCausef(err, "running poststart hook %d", i)
|
||||
+ return newSystemErrorWithCausef(err, "running poststart hook %d:%s", i, hook.Info())
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/libcontainer/factory_linux_test.go b/libcontainer/factory_linux_test.go
|
||||
index ea3b513..0a84a7d 100644
|
||||
--- a/libcontainer/factory_linux_test.go
|
||||
+++ b/libcontainer/factory_linux_test.go
|
||||
@@ -205,3 +205,7 @@ type unserializableHook struct{}
|
||||
func (unserializableHook) Run(configs.HookState) error {
|
||||
return nil
|
||||
}
|
||||
+
|
||||
+func (unserializableHook) Info() string {
|
||||
+ return ""
|
||||
+}
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index 9373595..1b478d7 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -307,7 +307,7 @@ func (p *initProcess) start() error {
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
- return newSystemErrorWithCausef(err, "running prestart hook %d", i)
|
||||
+ return newSystemErrorWithCausef(err, "running prestart hook %d:%s", i, hook.Info())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,7 +330,7 @@ func (p *initProcess) start() error {
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
- return newSystemErrorWithCausef(err, "running prestart hook %d", i)
|
||||
+ return newSystemErrorWithCausef(err, "running prestart hook %d:%s", i, hook.Info())
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go
|
||||
index 9f8def2..c4f0dfc 100644
|
||||
--- a/libcontainer/state_linux.go
|
||||
+++ b/libcontainer/state_linux.go
|
||||
@@ -65,9 +65,9 @@ func runPoststopHooks(c *linuxContainer) error {
|
||||
},
|
||||
Root: c.config.Rootfs,
|
||||
}
|
||||
- for _, hook := range c.config.Hooks.Poststop {
|
||||
+ for i, hook := range c.config.Hooks.Poststop {
|
||||
if err := hook.Run(s); err != nil {
|
||||
- return err
|
||||
+ return newSystemErrorWithCausef(err, "running poststop hook %d:%s", i, hook.Info())
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From a410e6a2f9adeb46813a5016812ad334c6560b2d Mon Sep 17 00:00:00 2001
|
||||
From: dengguangxing <dengguangxing@huawei.com>
|
||||
Date: Thu, 18 Jan 2018 11:47:04 +0800
|
||||
Subject: [PATCH 46/94] runc: print cgroup info if cpuset missing
|
||||
occurs
|
||||
|
||||
[Changelog]: print cgroup info if cpuset missing occurs
|
||||
[Author]:Shukui Yang
|
||||
|
||||
Change-Id: I3f8af2b57b441f5f2b4d38cb89d6826a7f24e24b
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/cgroups/fs/cpuset.go | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go
|
||||
index 918b9a3..069c491 100644
|
||||
--- a/libcontainer/cgroups/fs/cpuset.go
|
||||
+++ b/libcontainer/cgroups/fs/cpuset.go
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
|
||||
@@ -91,6 +92,26 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro
|
||||
}
|
||||
|
||||
func (s *CpusetGroup) getSubsystemSettings(parent string) (cpus []byte, mems []byte, err error) {
|
||||
+ defer func() {
|
||||
+ if err != nil {
|
||||
+ minfo, err1 := ioutil.ReadFile("/proc/self/mountinfo")
|
||||
+ if err1 != nil {
|
||||
+ logrus.Errorf("Failed to read mountinfo when getSubsystemSettings get an error")
|
||||
+ }
|
||||
+
|
||||
+ dirInfo := ""
|
||||
+ fs, err2 := ioutil.ReadDir(parent)
|
||||
+ if err2 != nil {
|
||||
+ logrus.Errorf("Failed to read mountinfo when getSubsystemSettings get an error")
|
||||
+ }
|
||||
+ for _, f := range fs {
|
||||
+ dirInfo = dirInfo + " " + f.Name()
|
||||
+ }
|
||||
+
|
||||
+ logrus.Errorf("Read cpuset cgroup failed, print mountinfo and cgroup info here"+
|
||||
+ "path: %s, mountinfo: [%s], dirinfo: [%s]", parent, string(minfo), dirInfo)
|
||||
+ }
|
||||
+ }()
|
||||
if cpus, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.cpus")); err != nil {
|
||||
return
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
104
patch/0047-runc-add-more-specific-log-for-hooks.patch
Normal file
104
patch/0047-runc-add-more-specific-log-for-hooks.patch
Normal file
@ -0,0 +1,104 @@
|
||||
From f5399113b70807b57ed557bfecf932e5448016c2 Mon Sep 17 00:00:00 2001
|
||||
From: dengguangxing <dengguangxing@huawei.com>
|
||||
Date: Mon, 22 Jan 2018 20:27:37 +0800
|
||||
Subject: [PATCH 47/94] runc: add more specific log for hooks
|
||||
|
||||
[Changelog]: add more specific log for hooks
|
||||
[Author]:Shukui Yang
|
||||
|
||||
Change-Id: I317232b42a5fd6bc16773fe4aa0a376d8b9b6806
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 5 +++++
|
||||
libcontainer/process_linux.go | 5 +++++
|
||||
libcontainer/state_linux.go | 3 +++
|
||||
3 files changed, 13 insertions(+)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 9fabadc..74b82c5 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -290,12 +290,15 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
Root: c.config.Rootfs,
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Poststart {
|
||||
+ logrus.Infof("run poststart hook %d:%s", i, hook.Info())
|
||||
if err := hook.Run(s); err != nil {
|
||||
+ logrus.Errorf("running poststart hook(%d:%s) failed: %s", i, hook.Info(), err)
|
||||
if err := parent.terminate(); err != nil {
|
||||
logrus.Warn(err)
|
||||
}
|
||||
return newSystemErrorWithCausef(err, "running poststart hook %d:%s", i, hook.Info())
|
||||
}
|
||||
+ logrus.Infof("poststart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1261,9 +1264,11 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
|
||||
Root: c.config.Rootfs,
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Prestart {
|
||||
+ logrus.Infof("run prestart hook: %d:%s", i, hook.Info())
|
||||
if err := hook.Run(s); err != nil {
|
||||
return newSystemErrorWithCausef(err, "running prestart hook %d", i)
|
||||
}
|
||||
+ logrus.Infof("prestart hook: %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
case notify.GetScript() == "post-restore":
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index 1b478d7..9064c0e 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
@@ -306,9 +307,11 @@ func (p *initProcess) start() error {
|
||||
Root: p.config.Config.Rootfs,
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
+ logrus.Infof("run prestart hook %d:%s", i, hook.Info())
|
||||
if err := hook.Run(s); err != nil {
|
||||
return newSystemErrorWithCausef(err, "running prestart hook %d:%s", i, hook.Info())
|
||||
}
|
||||
+ logrus.Infof("prestart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,9 +332,11 @@ func (p *initProcess) start() error {
|
||||
Root: p.config.Config.Rootfs,
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
+ logrus.Infof("run prestart hook %d:%s", i, hook.Info())
|
||||
if err := hook.Run(s); err != nil {
|
||||
return newSystemErrorWithCausef(err, "running prestart hook %d:%s", i, hook.Info())
|
||||
}
|
||||
+ logrus.Infof("prestart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
// Sync with child.
|
||||
diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go
|
||||
index c4f0dfc..b8d2a87 100644
|
||||
--- a/libcontainer/state_linux.go
|
||||
+++ b/libcontainer/state_linux.go
|
||||
@@ -66,9 +66,12 @@ func runPoststopHooks(c *linuxContainer) error {
|
||||
Root: c.config.Rootfs,
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Poststop {
|
||||
+ logrus.Infof("run poststop hook %d:%s", i, hook.Info())
|
||||
if err := hook.Run(s); err != nil {
|
||||
+ logrus.Errorf("running poststop hook %d: %s failed: %s", i, hook.Info(), err)
|
||||
return newSystemErrorWithCausef(err, "running poststop hook %d:%s", i, hook.Info())
|
||||
}
|
||||
+ logrus.Infof("poststop hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
40
patch/0048-runc-Only-configure-networking.patch
Normal file
40
patch/0048-runc-Only-configure-networking.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From caeb202a8a95863a44fa8f45e0515437239b173c Mon Sep 17 00:00:00 2001
|
||||
From: dengguangxing <dengguangxing@huawei.com>
|
||||
Date: Wed, 16 May 2018 15:16:51 +0800
|
||||
Subject: [PATCH 48/94] runc: Only configure networking
|
||||
|
||||
[Changelog]: Only configure networking when creating a net ns
|
||||
When joining an existing namespace, don't default to configuring a
|
||||
loopback interface in that namespace.
|
||||
|
||||
Its creator should have done that, and we don't want to fail to create
|
||||
the container when we don't have sufficient privileges to configure the
|
||||
network namespace.
|
||||
|
||||
This is cherry-picked from runc upstream:
|
||||
https://github.com/opencontainers/runc/pull/1777
|
||||
[Author]:Shukui Yang
|
||||
|
||||
Change-Id: I1f181f18e23c621db6718a185e35b50531d27c09
|
||||
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/specconv/spec_linux.go | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
|
||||
index 8a2947f..a968313 100644
|
||||
--- a/libcontainer/specconv/spec_linux.go
|
||||
+++ b/libcontainer/specconv/spec_linux.go
|
||||
@@ -194,7 +194,7 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
|
||||
}
|
||||
config.Namespaces.Add(t, ns.Path)
|
||||
}
|
||||
- if config.Namespaces.Contains(configs.NEWNET) {
|
||||
+ if config.Namespaces.Contains(configs.NEWNET) && config.Namespaces.PathOf(configs.NEWNET) == "" {
|
||||
config.Networks = []*configs.Network{
|
||||
{
|
||||
Type: "loopback",
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
37
patch/0049-cgroups-fs-fix-NPE-on-Destroy-than-no-cgrou.patch
Normal file
37
patch/0049-cgroups-fs-fix-NPE-on-Destroy-than-no-cgrou.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From ee3660e477b70d73812390ad96d82681f82f2e9b Mon Sep 17 00:00:00 2001
|
||||
From: Denys Smirnov <denys@sourced.tech>
|
||||
Date: Tue, 6 Mar 2018 23:31:31 +0100
|
||||
Subject: [PATCH 49/94] cgroups/fs: fix NPE on Destroy than no
|
||||
cgroups are set
|
||||
|
||||
|
||||
[Changelog]: Currently Manager accepts nil cgroups when calling Apply, but
|
||||
it will panic then trying to call Destroy with the same config.
|
||||
|
||||
This is cherry-picked from runc upstream:
|
||||
https://github.com/opencontainers/runc/pull/1752
|
||||
[Author]:Shukui Yang
|
||||
|
||||
Change-Id: Ie7aba1d1b7086a82a1d186038fb5e6c09b617f75
|
||||
Signed-off-by: Denys Smirnov <denys@sourced.tech>
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/cgroups/fs/apply_raw.go | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/cgroups/fs/apply_raw.go b/libcontainer/cgroups/fs/apply_raw.go
|
||||
index 22d82ac..66debae 100644
|
||||
--- a/libcontainer/cgroups/fs/apply_raw.go
|
||||
+++ b/libcontainer/cgroups/fs/apply_raw.go
|
||||
@@ -152,7 +152,7 @@ func (m *Manager) Apply(pid int) (err error) {
|
||||
}
|
||||
|
||||
func (m *Manager) Destroy() error {
|
||||
- if m.Cgroups.Paths != nil {
|
||||
+ if m.Cgroups == nil || m.Cgroups.Paths != nil {
|
||||
return nil
|
||||
}
|
||||
m.mu.Lock()
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
214
patch/0050-runc-Avoid-race-when-opening-exec-fifo.patch
Normal file
214
patch/0050-runc-Avoid-race-when-opening-exec-fifo.patch
Normal file
@ -0,0 +1,214 @@
|
||||
From 7e65e11136e81a834effe40a9f926416fb1eea78 Mon Sep 17 00:00:00 2001
|
||||
From: Will Martin <wmartin@pivotal.io>
|
||||
Date: Mon, 22 Jan 2018 17:03:02 +0000
|
||||
Subject: [PATCH 50/94] runc: Avoid race when opening exec fifo
|
||||
|
||||
|
||||
[Changelog]: Avoid race when opening exec fifo
|
||||
|
||||
When starting a container with `runc start` or `runc run`, the stub
|
||||
process (runc[2:INIT]) opens a fifo for writing. Its parent runc process
|
||||
will open the same fifo for reading. In this way, they synchronize.
|
||||
|
||||
If the stub process exits at the wrong time, the parent runc process
|
||||
will block forever.
|
||||
|
||||
This can happen when racing 2 runc operations against each other: `runc
|
||||
run/start`, and `runc delete`. It could also happen for other reasons,
|
||||
e.g. the kernel's OOM killer may select the stub process.
|
||||
|
||||
This commit resolves this race by racing the opening of the exec fifo
|
||||
from the runc parent process against the stub process exiting. If the
|
||||
stub process exits before we open the fifo, we return an error.
|
||||
|
||||
Another solution is to wait on the stub process. However, it seems it
|
||||
would require more refactoring to avoid calling wait multiple times on
|
||||
the same process, which is an error.
|
||||
|
||||
This is cherry-picked from runc upstream:
|
||||
https://github.com/opencontainers/runc/pull/1698
|
||||
[Author]:Shukui Yang
|
||||
|
||||
Change-Id: Id0ba756349b59463f7ee19ad63a6f243bee4a729
|
||||
Signed-off-by: Craig Furman <cfurman@pivotal.io>
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 69 +++++++++++++++++++++++++++++++++++------
|
||||
libcontainer/system/proc.go | 59 +++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 119 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 74b82c5..278f597 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -5,6 +5,7 @@ package libcontainer
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
+ "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -239,20 +240,70 @@ func (c *linuxContainer) Exec() error {
|
||||
|
||||
func (c *linuxContainer) exec() error {
|
||||
path := filepath.Join(c.root, execFifoFilename)
|
||||
- f, err := os.OpenFile(path, os.O_RDONLY, 0)
|
||||
- if err != nil {
|
||||
- return newSystemErrorWithCause(err, "open exec fifo for reading")
|
||||
+
|
||||
+ fifoOpen := make(chan struct{})
|
||||
+ select {
|
||||
+ case <-awaitProcessExit(c.initProcess.pid(), fifoOpen):
|
||||
+ return errors.New("container process is already dead")
|
||||
+ case result := <-awaitFifoOpen(path):
|
||||
+ close(fifoOpen)
|
||||
+ if result.err != nil {
|
||||
+ return result.err
|
||||
+ }
|
||||
+ f := result.file
|
||||
+ defer f.Close()
|
||||
+ if err := readFromExecFifo(f); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ return os.Remove(path)
|
||||
}
|
||||
- defer f.Close()
|
||||
- data, err := ioutil.ReadAll(f)
|
||||
+}
|
||||
+
|
||||
+func readFromExecFifo(execFifo io.Reader) error {
|
||||
+ data, err := ioutil.ReadAll(execFifo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
- if len(data) > 0 {
|
||||
- os.Remove(path)
|
||||
- return nil
|
||||
+ if len(data) <= 0 {
|
||||
+ return fmt.Errorf("cannot start an already running container")
|
||||
}
|
||||
- return fmt.Errorf("cannot start an already running container")
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+func awaitProcessExit(pid int, exit <-chan struct{}) <-chan struct{} {
|
||||
+ isDead := make(chan struct{})
|
||||
+ go func() {
|
||||
+ for {
|
||||
+ select {
|
||||
+ case <-exit:
|
||||
+ return
|
||||
+ case <-time.After(time.Millisecond * 100):
|
||||
+ stat, err := system.GetProcessState(pid)
|
||||
+ if err != nil || stat == system.Zombie {
|
||||
+ close(isDead)
|
||||
+ return
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }()
|
||||
+ return isDead
|
||||
+}
|
||||
+
|
||||
+func awaitFifoOpen(path string) <-chan openResult {
|
||||
+ fifoOpened := make(chan openResult)
|
||||
+ go func() {
|
||||
+ f, err := os.OpenFile(path, os.O_RDONLY, 0)
|
||||
+ if err != nil {
|
||||
+ fifoOpened <- openResult{err: newSystemErrorWithCause(err, "open exec fifo for reading")}
|
||||
+ }
|
||||
+ fifoOpened <- openResult{file: f}
|
||||
+ }()
|
||||
+ return fifoOpened
|
||||
+}
|
||||
+
|
||||
+type openResult struct {
|
||||
+ file *os.File
|
||||
+ err error
|
||||
}
|
||||
|
||||
func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
diff --git a/libcontainer/system/proc.go b/libcontainer/system/proc.go
|
||||
index a0e9637..03fd940 100644
|
||||
--- a/libcontainer/system/proc.go
|
||||
+++ b/libcontainer/system/proc.go
|
||||
@@ -1,12 +1,48 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
+ "fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
+type State rune
|
||||
+
|
||||
+const ( // Only values for Linux 3.14 and later are listed here
|
||||
+ Dead State = 'X'
|
||||
+ DiskSleep State = 'D'
|
||||
+ Running State = 'R'
|
||||
+ Sleeping State = 'S'
|
||||
+ Stopped State = 'T'
|
||||
+ TracingStop State = 't'
|
||||
+ Zombie State = 'Z'
|
||||
+)
|
||||
+
|
||||
+// String forms of the state from proc(5)'s documentation for
|
||||
+// /proc/[pid]/status' "State" field.
|
||||
+func (s State) String() string {
|
||||
+ switch s {
|
||||
+ case Dead:
|
||||
+ return "dead"
|
||||
+ case DiskSleep:
|
||||
+ return "disk sleep"
|
||||
+ case Running:
|
||||
+ return "running"
|
||||
+ case Sleeping:
|
||||
+ return "sleeping"
|
||||
+ case Stopped:
|
||||
+ return "stopped"
|
||||
+ case TracingStop:
|
||||
+ return "tracing stop"
|
||||
+ case Zombie:
|
||||
+ return "zombie"
|
||||
+ default:
|
||||
+ return fmt.Sprintf("unknown (%c)", s)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// look in /proc to find the process start time so that we can verify
|
||||
// that this pid has started after ourself
|
||||
func GetProcessStartTime(pid int) (string, error) {
|
||||
@@ -41,3 +77,26 @@ func parseStartTime(stat string) (string, error) {
|
||||
parts := strings.Split(strings.TrimSpace(s[len(s)-1]), " ")
|
||||
return parts[22-3], nil // starts at 3 (after the filename pos `2`)
|
||||
}
|
||||
+
|
||||
+func GetProcessState(pid int) (State, error) {
|
||||
+ data, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat"))
|
||||
+ if err != nil {
|
||||
+ return State(0), err
|
||||
+ }
|
||||
+ return parseState(string(data))
|
||||
+
|
||||
+}
|
||||
+
|
||||
+func parseState(data string) (State, error) {
|
||||
+ i := strings.LastIndex(data, ")")
|
||||
+ if i <= 2 || i >= len(data)-3 {
|
||||
+ return State(0), fmt.Errorf("invalid stat data: %q", data)
|
||||
+ }
|
||||
+
|
||||
+ parts := strings.Split(data[i+2:], " ")
|
||||
+
|
||||
+ var state int
|
||||
+ fmt.Sscanf(parts[3-3], "%c", &state)
|
||||
+ stateStr := State(state)
|
||||
+ return stateStr, nil
|
||||
+}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
33
patch/0051-runc-Return-from-goroutine-when-it-should-t.patch
Normal file
33
patch/0051-runc-Return-from-goroutine-when-it-should-t.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From df24ec79d3a69e9deab962eacc8ecbd46b0aefd9 Mon Sep 17 00:00:00 2001
|
||||
From: Ed King <eking@pivotal.io>
|
||||
Date: Tue, 23 Jan 2018 10:46:31 +0000
|
||||
Subject: [PATCH 51/94] runc: Return from goroutine when it should
|
||||
terminate
|
||||
|
||||
|
||||
[Changelog]: This is cherry-picked from runc upstream:
|
||||
https://github.com/opencontainers/runc/pull/1698
|
||||
[Author]:Shukui Yang
|
||||
|
||||
Change-Id: Ie99f80c1fb5912d99dd7426b47f93e9f5a6efb23
|
||||
Signed-off-by: Craig Furman <cfurman@pivotal.io>
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 278f597..50fe657 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -295,6 +295,7 @@ func awaitFifoOpen(path string) <-chan openResult {
|
||||
f, err := os.OpenFile(path, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
fifoOpened <- openResult{err: newSystemErrorWithCause(err, "open exec fifo for reading")}
|
||||
+ return
|
||||
}
|
||||
fifoOpened <- openResult{file: f}
|
||||
}()
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
32
patch/0052-runc-reduce-max-number-of-retries-to-10.patch
Normal file
32
patch/0052-runc-reduce-max-number-of-retries-to-10.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From c8b74f1b809d8fbf1ba2dc74c069e03d9e95be71 Mon Sep 17 00:00:00 2001
|
||||
From: liruilin4 <liruilin4@huawei.com>
|
||||
Date: Mon, 9 Jul 2018 12:02:33 +0800
|
||||
Subject: [PATCH 52/94] runc: reduce max number of retries to 10
|
||||
|
||||
[Changelog]:when killing containers in D state, now runc will do
|
||||
100 retries, which leads that containerd blocks for 10 seconds.
|
||||
[Author]:Ruilin Li
|
||||
|
||||
Change-Id: I1e08ef23ad065f5e3b88506726530187d2ccc797
|
||||
---
|
||||
delete.go | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/delete.go b/delete.go
|
||||
index b43dcaa..a2b14f3 100644
|
||||
--- a/delete.go
|
||||
+++ b/delete.go
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
)
|
||||
|
||||
func killContainer(container libcontainer.Container) error {
|
||||
- _ = container.Signal(syscall.SIGKILL, false)
|
||||
- for i := 0; i < 100; i++ {
|
||||
+ container.Signal(syscall.SIGKILL, false)
|
||||
+ for i := 0; i < 10; i++ {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if err := container.Signal(syscall.Signal(0), false); err != nil {
|
||||
destroy(container)
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
From 165870fb442ca29a208a3d17f8ece6b8e74da2de Mon Sep 17 00:00:00 2001
|
||||
From: panwenxiang <panwenxiang@huawei.com>
|
||||
Date: Wed, 22 Aug 2018 17:04:19 +0800
|
||||
Subject: [PATCH 53/94] runc: print error message during start into
|
||||
container log
|
||||
|
||||
[Changelog]:cherry-pick from vtwrse <75eba7a697edde39e25e39c870a33f3dc5fb327a>
|
||||
Change-Id: Id23f14690d77a4f79611e82f4e2ece41d9b19edf
|
||||
Signed-off-by: jiangpengfei9 <jiangpengfei9@huawei.com>
|
||||
---
|
||||
main_unix.go | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/main_unix.go b/main_unix.go
|
||||
index b601abc..56904e0 100644
|
||||
--- a/main_unix.go
|
||||
+++ b/main_unix.go
|
||||
@@ -3,6 +3,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
+ "fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
@@ -24,6 +25,7 @@ var initCommand = cli.Command{
|
||||
Action: func(context *cli.Context) error {
|
||||
factory, _ := libcontainer.New("")
|
||||
if err := factory.StartInitialization(); err != nil {
|
||||
+ fmt.Fprintf(os.Stderr, "libcontainer: container start initialization failed: %s", err)
|
||||
// as the error is sent back to the parent there is no need to log
|
||||
// or write it to stderr because the parent process will handle this
|
||||
os.Exit(1)
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
From a119a29bc908bfd1385cbdcee4cc800e2b022b09 Mon Sep 17 00:00:00 2001
|
||||
From: panwenxiang <panwenxiang@huawei.com>
|
||||
Date: Wed, 22 Aug 2018 17:06:01 +0800
|
||||
Subject: [PATCH 54/94] runc: ignore exec.fifo removing not exist error
|
||||
|
||||
[Changelog]:cherry-pick from vtwrse <4af7ee1635962fe3bd86ac87064fdcd7e60c1135>
|
||||
Change-Id: I34a30672fb92c974965b3a53cfb8ccc75932e6d8
|
||||
Signed-off-by: jiangpengfei9 <jiangpengfei9@huawei.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 50fe657..502a274 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -255,7 +255,10 @@ func (c *linuxContainer) exec() error {
|
||||
if err := readFromExecFifo(f); err != nil {
|
||||
return err
|
||||
}
|
||||
- return os.Remove(path)
|
||||
+ if err := os.Remove(path); !os.IsNotExist(err) {
|
||||
+ return err
|
||||
+ }
|
||||
+ return nil
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
246
patch/0055-Add-file-fds-limit.patch
Normal file
246
patch/0055-Add-file-fds-limit.patch
Normal file
@ -0,0 +1,246 @@
|
||||
From fdf82f9b9bac43cac5672226750c826e742559ce Mon Sep 17 00:00:00 2001
|
||||
From: yangshukui <yangshukui@huawei.com>
|
||||
Date: Mon, 18 Sep 2017 17:25:30 +0800
|
||||
Subject: [PATCH 55/94] Add file fds limit
|
||||
|
||||
With the patch(https://lwn.net/Articles/604129/),we can limit the
|
||||
num of open files in container.
|
||||
Conflicts:
|
||||
events.go
|
||||
vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
|
||||
Change-Id: I8264c0dd398227ebbd95b7dd9dae4688d76dee9b
|
||||
Signed-off-by: yangshukui <yangshukui@huawei.com>
|
||||
---
|
||||
events.go | 9 +++
|
||||
libcontainer/cgroups/fs/apply_raw.go | 1 +
|
||||
libcontainer/cgroups/fs/files.go | 74 ++++++++++++++++++++++
|
||||
libcontainer/cgroups/stats.go | 8 +++
|
||||
libcontainer/cgroups/systemd/apply_systemd.go | 1 +
|
||||
libcontainer/configs/cgroup_unix.go | 3 +
|
||||
libcontainer/specconv/spec_linux.go | 3 +
|
||||
.../opencontainers/runtime-spec/specs-go/config.go | 8 +++
|
||||
8 files changed, 107 insertions(+)
|
||||
create mode 100644 libcontainer/cgroups/fs/files.go
|
||||
|
||||
diff --git a/events.go b/events.go
|
||||
index 6c21e52..79a72bf 100644
|
||||
--- a/events.go
|
||||
+++ b/events.go
|
||||
@@ -27,6 +27,7 @@ type stats struct {
|
||||
CPU cpu `json:"cpu"`
|
||||
Memory memory `json:"memory"`
|
||||
Pids pids `json:"pids"`
|
||||
+ Files files `json:"files"`
|
||||
Blkio blkio `json:"blkio"`
|
||||
Hugetlb map[string]hugetlb `json:"hugetlb"`
|
||||
}
|
||||
@@ -60,6 +61,11 @@ type pids struct {
|
||||
Limit uint64 `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
+type files struct {
|
||||
+ Usage uint64 `json:"usage,omitempty"`
|
||||
+ Limit uint64 `json:"limit,omitempty"`
|
||||
+}
|
||||
+
|
||||
type throttling struct {
|
||||
Periods uint64 `json:"periods,omitempty"`
|
||||
ThrottledPeriods uint64 `json:"throttledPeriods,omitempty"`
|
||||
@@ -198,6 +204,9 @@ func convertLibcontainerStats(ls *libcontainer.Stats) *stats {
|
||||
s.Pids.Current = cg.PidsStats.Current
|
||||
s.Pids.Limit = cg.PidsStats.Limit
|
||||
|
||||
+ s.Files.Usage = cg.FilesStats.Usage
|
||||
+ s.Files.Limit = cg.FilesStats.Limit
|
||||
+
|
||||
s.CPU.Usage.Kernel = cg.CpuStats.CpuUsage.UsageInKernelmode
|
||||
s.CPU.Usage.User = cg.CpuStats.CpuUsage.UsageInUsermode
|
||||
s.CPU.Usage.Total = cg.CpuStats.CpuUsage.TotalUsage
|
||||
diff --git a/libcontainer/cgroups/fs/apply_raw.go b/libcontainer/cgroups/fs/apply_raw.go
|
||||
index 66debae..1bf59a4 100644
|
||||
--- a/libcontainer/cgroups/fs/apply_raw.go
|
||||
+++ b/libcontainer/cgroups/fs/apply_raw.go
|
||||
@@ -24,6 +24,7 @@ var (
|
||||
&CpuGroup{},
|
||||
&CpuacctGroup{},
|
||||
&PidsGroup{},
|
||||
+ &FilesGroup{},
|
||||
&BlkioGroup{},
|
||||
&HugetlbGroup{},
|
||||
&NetClsGroup{},
|
||||
diff --git a/libcontainer/cgroups/fs/files.go b/libcontainer/cgroups/fs/files.go
|
||||
new file mode 100644
|
||||
index 0000000..f2e253a
|
||||
--- /dev/null
|
||||
+++ b/libcontainer/cgroups/fs/files.go
|
||||
@@ -0,0 +1,74 @@
|
||||
+// +build linux
|
||||
+
|
||||
+package fs
|
||||
+
|
||||
+import (
|
||||
+ "fmt"
|
||||
+ "io/ioutil"
|
||||
+ "strconv"
|
||||
+
|
||||
+ "github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
+ "github.com/opencontainers/runc/libcontainer/configs"
|
||||
+)
|
||||
+
|
||||
+var (
|
||||
+ defaultFilesMax = "8192"
|
||||
+)
|
||||
+
|
||||
+type FilesGroup struct {
|
||||
+}
|
||||
+
|
||||
+func init() {
|
||||
+ contents, err := ioutil.ReadFile("/proc/sys/fs/file-max")
|
||||
+ if err != nil {
|
||||
+ return
|
||||
+ }
|
||||
+ defaultFilesMax = string(contents)
|
||||
+}
|
||||
+
|
||||
+func (s *FilesGroup) Name() string {
|
||||
+ return "files"
|
||||
+}
|
||||
+
|
||||
+func (s *FilesGroup) Apply(d *cgroupData) error {
|
||||
+ _, err := d.join("files")
|
||||
+ if err != nil && !cgroups.IsNotFound(err) {
|
||||
+ return err
|
||||
+ }
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+func (s *FilesGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
+ if cgroup.Resources.FilesLimit != 0 {
|
||||
+ limit := defaultFilesMax
|
||||
+ if cgroup.Resources.FilesLimit > 0 {
|
||||
+ limit = strconv.FormatInt(cgroup.Resources.FilesLimit, 10)
|
||||
+ }
|
||||
+
|
||||
+ if err := writeFile(path, "files.limit", limit); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+func (s *FilesGroup) Remove(d *cgroupData) error {
|
||||
+ return removePath(d.path("files"))
|
||||
+}
|
||||
+
|
||||
+func (s *FilesGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
+ usage, err := getCgroupParamUint(path, "files.usage")
|
||||
+ if err != nil {
|
||||
+ return fmt.Errorf("failed to parse files.usage - %s", err)
|
||||
+ }
|
||||
+
|
||||
+ limit, err := getCgroupParamUint(path, "files.limit")
|
||||
+ if err != nil {
|
||||
+ return fmt.Errorf("failed to parse files.limit - %s", err)
|
||||
+ }
|
||||
+
|
||||
+ stats.FilesStats.Usage = usage
|
||||
+ stats.FilesStats.Limit = limit
|
||||
+ return nil
|
||||
+}
|
||||
diff --git a/libcontainer/cgroups/stats.go b/libcontainer/cgroups/stats.go
|
||||
index b483f1b..5079410 100644
|
||||
--- a/libcontainer/cgroups/stats.go
|
||||
+++ b/libcontainer/cgroups/stats.go
|
||||
@@ -62,6 +62,13 @@ type PidsStats struct {
|
||||
Limit uint64 `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
+type FilesStats struct {
|
||||
+ // number of pids in the cgroup
|
||||
+ Usage uint64 `json:"usage,omitempty"`
|
||||
+ // active pids hard limit
|
||||
+ Limit uint64 `json:"limit,omitempty"`
|
||||
+}
|
||||
+
|
||||
type BlkioStatEntry struct {
|
||||
Major uint64 `json:"major,omitempty"`
|
||||
Minor uint64 `json:"minor,omitempty"`
|
||||
@@ -94,6 +101,7 @@ type Stats struct {
|
||||
CpuStats CpuStats `json:"cpu_stats,omitempty"`
|
||||
MemoryStats MemoryStats `json:"memory_stats,omitempty"`
|
||||
PidsStats PidsStats `json:"pids_stats,omitempty"`
|
||||
+ FilesStats FilesStats `json:"files_stats,omitempty"`
|
||||
BlkioStats BlkioStats `json:"blkio_stats,omitempty"`
|
||||
// the map is in the format "size of hugepage: stats of the hugepage"
|
||||
HugetlbStats map[string]HugetlbStats `json:"hugetlb_stats,omitempty"`
|
||||
diff --git a/libcontainer/cgroups/systemd/apply_systemd.go b/libcontainer/cgroups/systemd/apply_systemd.go
|
||||
index 456c57d..0411b72 100644
|
||||
--- a/libcontainer/cgroups/systemd/apply_systemd.go
|
||||
+++ b/libcontainer/cgroups/systemd/apply_systemd.go
|
||||
@@ -54,6 +54,7 @@ var subsystems = subsystemSet{
|
||||
&fs.CpuGroup{},
|
||||
&fs.CpuacctGroup{},
|
||||
&fs.PidsGroup{},
|
||||
+ &fs.FilesGroup{},
|
||||
&fs.BlkioGroup{},
|
||||
&fs.HugetlbGroup{},
|
||||
&fs.PerfEventGroup{},
|
||||
diff --git a/libcontainer/configs/cgroup_unix.go b/libcontainer/configs/cgroup_unix.go
|
||||
index 75a3db0..acf0562 100644
|
||||
--- a/libcontainer/configs/cgroup_unix.go
|
||||
+++ b/libcontainer/configs/cgroup_unix.go
|
||||
@@ -89,6 +89,9 @@ type Resources struct {
|
||||
// Process limit; set <= `0' to disable limit.
|
||||
PidsLimit int64 `json:"pids_limit"`
|
||||
|
||||
+ // Process open files limit.
|
||||
+ FilesLimit int64 `json:"files_limit"`
|
||||
+
|
||||
// Specifies per cgroup weight, range is from 10 to 1000.
|
||||
BlkioWeight uint16 `json:"blkio_weight"`
|
||||
|
||||
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
|
||||
index a968313..b82082e 100644
|
||||
--- a/libcontainer/specconv/spec_linux.go
|
||||
+++ b/libcontainer/specconv/spec_linux.go
|
||||
@@ -403,6 +403,9 @@ func createCgroupConfig(opts *CreateOpts) (*configs.Cgroup, error) {
|
||||
if r.Pids != nil {
|
||||
c.Resources.PidsLimit = r.Pids.Limit
|
||||
}
|
||||
+ if r.Files != nil && r.Files.Limit != nil {
|
||||
+ c.Resources.FilesLimit = *r.Files.Limit
|
||||
+ }
|
||||
if r.BlockIO != nil {
|
||||
if r.BlockIO.Weight != nil {
|
||||
c.Resources.BlkioWeight = *r.BlockIO.Weight
|
||||
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
index 6d2a026..603ecf4 100644
|
||||
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
@@ -318,6 +318,12 @@ type LinuxPids struct {
|
||||
Limit int64 `json:"limit"`
|
||||
}
|
||||
|
||||
+// Files for Linux cgroup 'files' resource management (https://lwn.net/Articles/604129/)
|
||||
+type Files struct {
|
||||
+ // Maximum number of open files".
|
||||
+ Limit *int64 `json:"limit,omitempty"`
|
||||
+}
|
||||
+
|
||||
// LinuxNetwork identification and priority configuration
|
||||
type LinuxNetwork struct {
|
||||
// Set class identifier for container's network packets
|
||||
@@ -340,6 +346,8 @@ type LinuxResources struct {
|
||||
CPU *LinuxCPU `json:"cpu,omitempty"`
|
||||
// Task resource restriction configuration.
|
||||
Pids *LinuxPids `json:"pids,omitempty"`
|
||||
+ // Files resource restriction configuration.
|
||||
+ Files *Files `json:"files,omitempty"`
|
||||
// BlockIO restriction configuration
|
||||
BlockIO *LinuxBlockIO `json:"blockIO,omitempty"`
|
||||
// Hugetlb limit (in bytes)
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
From 0a5b23584d79bba18429905c43774bc50a117b4b Mon Sep 17 00:00:00 2001
|
||||
From: yangshukui <yangshukui@huawei.com>
|
||||
Date: Sat, 4 Nov 2017 14:55:40 +0800
|
||||
Subject: [PATCH 56/94] runc: Modify max files.limit to max because of
|
||||
the change of kernel.
|
||||
|
||||
[Changelog]: Kernel has change max files.limit to max,So docker need
|
||||
change too.
|
||||
|
||||
Change-Id: Iea6e5eb1dddf0f8d2d55ee3182ed78957cb09a75
|
||||
Signed-off-by: yangshukui <yangshukui@huawei.com>
|
||||
---
|
||||
libcontainer/cgroups/fs/files.go | 16 ++--------------
|
||||
1 file changed, 2 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/cgroups/fs/files.go b/libcontainer/cgroups/fs/files.go
|
||||
index f2e253a..3214a82 100644
|
||||
--- a/libcontainer/cgroups/fs/files.go
|
||||
+++ b/libcontainer/cgroups/fs/files.go
|
||||
@@ -4,28 +4,15 @@ package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
- "io/ioutil"
|
||||
"strconv"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
-var (
|
||||
- defaultFilesMax = "8192"
|
||||
-)
|
||||
-
|
||||
type FilesGroup struct {
|
||||
}
|
||||
|
||||
-func init() {
|
||||
- contents, err := ioutil.ReadFile("/proc/sys/fs/file-max")
|
||||
- if err != nil {
|
||||
- return
|
||||
- }
|
||||
- defaultFilesMax = string(contents)
|
||||
-}
|
||||
-
|
||||
func (s *FilesGroup) Name() string {
|
||||
return "files"
|
||||
}
|
||||
@@ -40,7 +27,8 @@ func (s *FilesGroup) Apply(d *cgroupData) error {
|
||||
|
||||
func (s *FilesGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
if cgroup.Resources.FilesLimit != 0 {
|
||||
- limit := defaultFilesMax
|
||||
+ // "max" is the fallback value.
|
||||
+ limit := "max"
|
||||
if cgroup.Resources.FilesLimit > 0 {
|
||||
limit = strconv.FormatInt(cgroup.Resources.FilesLimit, 10)
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
From aff98c05dbaf30fec52a0afed19ebf4a03303d63 Mon Sep 17 00:00:00 2001
|
||||
From: caihaomin <caihaomin@huawei.com>
|
||||
Date: Mon, 6 Nov 2017 01:43:45 +0000
|
||||
Subject: [PATCH 57/94] runc: change read value of cgroup files.limit
|
||||
into string
|
||||
|
||||
[Changelog]:change read value of cgroup files.limit from int to string.
|
||||
For avoiding of value `max`
|
||||
[Author]git
|
||||
|
||||
Change-Id: Iec6197528b1aebb13a0ea64ba919a7b4c6f31d61
|
||||
Signed-off-by: caihaomin <caihaomin@huawei.com>
|
||||
---
|
||||
libcontainer/cgroups/fs/files.go | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/cgroups/fs/files.go b/libcontainer/cgroups/fs/files.go
|
||||
index 3214a82..70e9524 100644
|
||||
--- a/libcontainer/cgroups/fs/files.go
|
||||
+++ b/libcontainer/cgroups/fs/files.go
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
+ "path/filepath"
|
||||
)
|
||||
|
||||
type FilesGroup struct {
|
||||
@@ -51,12 +52,21 @@ func (s *FilesGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
return fmt.Errorf("failed to parse files.usage - %s", err)
|
||||
}
|
||||
|
||||
- limit, err := getCgroupParamUint(path, "files.limit")
|
||||
+ maxString, err := getCgroupParamString(path, "files.limit")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse files.limit - %s", err)
|
||||
}
|
||||
|
||||
+ // Default if files.limit == "max" is 0 -- which represents "no limit".
|
||||
+ var max uint64
|
||||
+ if maxString != "max" {
|
||||
+ max, err = parseUint(maxString, 10, 64)
|
||||
+ if err != nil {
|
||||
+ return fmt.Errorf("failed to parse files.limit -- unable to parse %q as a uint from Cgroup file %q", maxString, filepath.Join(path, "file.limits"))
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
stats.FilesStats.Usage = usage
|
||||
- stats.FilesStats.Limit = limit
|
||||
+ stats.FilesStats.Limit = max
|
||||
return nil
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
194
patch/0058-runc-fix-panic-when-Linux-is-nil.patch
Normal file
194
patch/0058-runc-fix-panic-when-Linux-is-nil.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From 20e119ab64e02e627671957bbfa445b988cc8687 Mon Sep 17 00:00:00 2001
|
||||
From: dengguangxing <dengguangxing@huawei.com>
|
||||
Date: Wed, 16 May 2018 15:50:27 +0800
|
||||
Subject: [PATCH 58/94] runc: fix panic when Linux is nil
|
||||
|
||||
|
||||
[Changelog]: Linux is not always not nil.
|
||||
If Linux is nil, panic will occur.
|
||||
|
||||
This is cherry-picked from runc upstream:
|
||||
https://github.com/opencontainers/runc/pull/1551
|
||||
[Author]:Shukui Yang
|
||||
Conflicts:
|
||||
libcontainer/specconv/spec_linux.go
|
||||
|
||||
Change-Id: Ib3bf9e80852dc079ab2d42a8234297397f3c56d9
|
||||
Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
|
||||
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
|
||||
Signed-off-by: dengguangxing <dengguangxing@huawei.com>
|
||||
---
|
||||
libcontainer/specconv/spec_linux.go | 121 +++++++++++++++++++-----------------
|
||||
1 file changed, 65 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
|
||||
index b82082e..a8cf114 100644
|
||||
--- a/libcontainer/specconv/spec_linux.go
|
||||
+++ b/libcontainer/specconv/spec_linux.go
|
||||
@@ -180,20 +180,6 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
|
||||
}
|
||||
|
||||
exists := false
|
||||
- if config.RootPropagation, exists = mountPropagationMapping[spec.Linux.RootfsPropagation]; !exists {
|
||||
- return nil, fmt.Errorf("rootfsPropagation=%v is not supported", spec.Linux.RootfsPropagation)
|
||||
- }
|
||||
-
|
||||
- for _, ns := range spec.Linux.Namespaces {
|
||||
- t, exists := namespaceMapping[ns.Type]
|
||||
- if !exists {
|
||||
- return nil, fmt.Errorf("namespace %q does not exist", ns)
|
||||
- }
|
||||
- if config.Namespaces.Contains(t) {
|
||||
- return nil, fmt.Errorf("malformed spec file: duplicated ns %q", ns)
|
||||
- }
|
||||
- config.Namespaces.Add(t, ns.Path)
|
||||
- }
|
||||
if config.Namespaces.Contains(configs.NEWNET) && config.Namespaces.PathOf(configs.NEWNET) == "" {
|
||||
config.Networks = []*configs.Network{
|
||||
{
|
||||
@@ -215,15 +201,35 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
config.Cgroups = c
|
||||
- // set extra path masking for libcontainer for the various unsafe places in proc
|
||||
- config.MaskPaths = spec.Linux.MaskedPaths
|
||||
- config.ReadonlyPaths = spec.Linux.ReadonlyPaths
|
||||
- if spec.Linux.Seccomp != nil {
|
||||
- seccomp, err := setupSeccomp(spec.Linux.Seccomp)
|
||||
- if err != nil {
|
||||
- return nil, err
|
||||
+ // set linux-specific config
|
||||
+ if spec.Linux != nil {
|
||||
+ if config.RootPropagation, exists = mountPropagationMapping[spec.Linux.RootfsPropagation]; !exists {
|
||||
+ return nil, fmt.Errorf("rootfsPropagation=%v is not supported", spec.Linux.RootfsPropagation)
|
||||
+ }
|
||||
+
|
||||
+ for _, ns := range spec.Linux.Namespaces {
|
||||
+ t, exists := namespaceMapping[ns.Type]
|
||||
+ if !exists {
|
||||
+ return nil, fmt.Errorf("namespace %q does not exist", ns)
|
||||
+ }
|
||||
+ if config.Namespaces.Contains(t) {
|
||||
+ return nil, fmt.Errorf("malformed spec file: duplicated ns %q", ns)
|
||||
+ }
|
||||
+ config.Namespaces.Add(t, ns.Path)
|
||||
+ }
|
||||
+
|
||||
+ // set extra path masking for libcontainer for the various unsafe places in proc
|
||||
+ config.MaskPaths = spec.Linux.MaskedPaths
|
||||
+ config.ReadonlyPaths = spec.Linux.ReadonlyPaths
|
||||
+ config.MountLabel = spec.Linux.MountLabel
|
||||
+ config.Sysctl = spec.Linux.Sysctl
|
||||
+ if spec.Linux.Seccomp != nil {
|
||||
+ seccomp, err := setupSeccomp(spec.Linux.Seccomp)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ config.Seccomp = seccomp
|
||||
}
|
||||
- config.Seccomp = seccomp
|
||||
}
|
||||
if spec.Process.SelinuxLabel != "" {
|
||||
config.ProcessLabel = spec.Process.SelinuxLabel
|
||||
@@ -242,7 +248,6 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
|
||||
}
|
||||
}
|
||||
createHooks(spec, config)
|
||||
- config.MountLabel = spec.Linux.MountLabel
|
||||
config.Version = specs.Version
|
||||
return config, nil
|
||||
}
|
||||
@@ -565,41 +570,40 @@ func createDevices(spec *specs.Spec, config *configs.Config) error {
|
||||
},
|
||||
}
|
||||
// merge in additional devices from the spec
|
||||
- for _, d := range spec.Linux.Devices {
|
||||
- var uid, gid uint32
|
||||
- var filemode os.FileMode = 0666
|
||||
+ if spec.Linux != nil {
|
||||
+ for _, d := range spec.Linux.Devices {
|
||||
+ var uid, gid uint32
|
||||
+ var filemode os.FileMode = 0666
|
||||
|
||||
- if d.UID != nil {
|
||||
- uid = *d.UID
|
||||
- }
|
||||
- if d.GID != nil {
|
||||
- gid = *d.GID
|
||||
- }
|
||||
- dt, err := stringToDeviceRune(d.Type)
|
||||
- if err != nil {
|
||||
- return err
|
||||
- }
|
||||
- if d.FileMode != nil {
|
||||
- filemode = *d.FileMode
|
||||
- }
|
||||
- device := &configs.Device{
|
||||
- Type: dt,
|
||||
- Path: d.Path,
|
||||
- Major: d.Major,
|
||||
- Minor: d.Minor,
|
||||
- FileMode: filemode,
|
||||
- Uid: uid,
|
||||
- Gid: gid,
|
||||
+ if d.UID != nil {
|
||||
+ uid = *d.UID
|
||||
+ }
|
||||
+ if d.GID != nil {
|
||||
+ gid = *d.GID
|
||||
+ }
|
||||
+ dt, err := stringToDeviceRune(d.Type)
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ if d.FileMode != nil {
|
||||
+ filemode = *d.FileMode
|
||||
+ }
|
||||
+ device := &configs.Device{
|
||||
+ Type: dt,
|
||||
+ Path: d.Path,
|
||||
+ Major: d.Major,
|
||||
+ Minor: d.Minor,
|
||||
+ FileMode: filemode,
|
||||
+ Uid: uid,
|
||||
+ Gid: gid,
|
||||
+ }
|
||||
+ config.Devices = append(config.Devices, device)
|
||||
}
|
||||
- config.Devices = append(config.Devices, device)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
|
||||
- if len(spec.Linux.UIDMappings) == 0 {
|
||||
- return nil
|
||||
- }
|
||||
create := func(m specs.LinuxIDMapping) configs.IDMap {
|
||||
return configs.IDMap{
|
||||
HostID: int(m.HostID),
|
||||
@@ -607,11 +611,16 @@ func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
|
||||
Size: int(m.Size),
|
||||
}
|
||||
}
|
||||
- for _, m := range spec.Linux.UIDMappings {
|
||||
- config.UidMappings = append(config.UidMappings, create(m))
|
||||
- }
|
||||
- for _, m := range spec.Linux.GIDMappings {
|
||||
- config.GidMappings = append(config.GidMappings, create(m))
|
||||
+ if spec.Linux != nil {
|
||||
+ if len(spec.Linux.UIDMappings) == 0 {
|
||||
+ return nil
|
||||
+ }
|
||||
+ for _, m := range spec.Linux.UIDMappings {
|
||||
+ config.UidMappings = append(config.UidMappings, create(m))
|
||||
+ }
|
||||
+ for _, m := range spec.Linux.GIDMappings {
|
||||
+ config.GidMappings = append(config.GidMappings, create(m))
|
||||
+ }
|
||||
}
|
||||
rootUID, err := config.HostRootUID()
|
||||
if err != nil {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
59
patch/0059-Fix-setup-cgroup-before-prestart-hook.patch
Normal file
59
patch/0059-Fix-setup-cgroup-before-prestart-hook.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 394c8695f22731938994fdc5d7db678762119481 Mon Sep 17 00:00:00 2001
|
||||
From: Wentao Zhang <zhangwentao234@huawei.com>
|
||||
Date: Tue, 20 Dec 2016 06:21:10 -0500
|
||||
Subject: [PATCH 59/94] Fix setup cgroup before prestart hook
|
||||
|
||||
* User Case:
|
||||
User could use prestart hook to add block devices to container. so the
|
||||
hook should have a way to set the permissions of the devices.
|
||||
|
||||
Just move cgroup config operation before prestart hook will work.
|
||||
Conflicts:
|
||||
libcontainer/process_linux.go
|
||||
|
||||
Change-Id: I991138f4e686c4268e0629204ce1eae6452fdecf
|
||||
Signed-off-by: Wentao Zhang <zhangwentao234@huawei.com>
|
||||
---
|
||||
libcontainer/process_linux.go | 12 +++++++++---
|
||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index 9064c0e..70e93de 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -286,9 +286,6 @@ func (p *initProcess) start() error {
|
||||
ierr := parseSync(p.parentPipe, func(sync *syncT) error {
|
||||
switch sync.Type {
|
||||
case procReady:
|
||||
- if err := p.manager.Set(p.config.Config); err != nil {
|
||||
- return newSystemErrorWithCause(err, "setting cgroup config for ready process")
|
||||
- }
|
||||
// set rlimits, this has to be done here because we lose permissions
|
||||
// to raise the limits once we enter a user-namespace
|
||||
if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil {
|
||||
@@ -296,6 +293,11 @@ func (p *initProcess) start() error {
|
||||
}
|
||||
// call prestart hooks
|
||||
if !p.config.Config.Namespaces.Contains(configs.NEWNS) {
|
||||
+ // Setup cgroup before prestart hook, so that the prestart hook could apply cgroup permissions.
|
||||
+ if err := p.manager.Set(p.config.Config); err != nil {
|
||||
+ return newSystemErrorWithCause(err, "setting cgroup config for ready process")
|
||||
+ }
|
||||
+
|
||||
if p.config.Config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
SpecState: configs.SpecState{
|
||||
@@ -321,6 +323,10 @@ func (p *initProcess) start() error {
|
||||
}
|
||||
sentRun = true
|
||||
case procHooks:
|
||||
+ // Setup cgroup before prestart hook, so that the prestart hook could apply cgroup permissions.
|
||||
+ if err := p.manager.Set(p.config.Config); err != nil {
|
||||
+ return newSystemErrorWithCause(err, "setting cgroup config for ready process")
|
||||
+ }
|
||||
if p.config.Config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
SpecState: configs.SpecState{
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
860
patch/0060-runc-runc-logs-forwarding-to-syslog.patch
Normal file
860
patch/0060-runc-runc-logs-forwarding-to-syslog.patch
Normal file
@ -0,0 +1,860 @@
|
||||
From c8d9a899d3425c342e83868540ca357bf9f7a661 Mon Sep 17 00:00:00 2001
|
||||
From: panwenxiang <panwenxiang@huawei.com>
|
||||
Date: Fri, 19 Oct 2018 15:00:34 +0800
|
||||
Subject: [PATCH 60/94] runc: runc logs forwarding to syslog
|
||||
|
||||
reason:runc logs forwarding to syslog and using the config "--log-level" to control the number of logs
|
||||
|
||||
Change-Id: Ia93f6f5c56131ea8558c4b7b7e5c4bec827a1bad
|
||||
|
||||
Conflicts:
|
||||
libcontainer/container_linux.go
|
||||
libcontainer/process_linux.go
|
||||
libcontainer/state_linux.go
|
||||
---
|
||||
create.go | 3 +-
|
||||
libcontainer/configs/config.go | 55 +++++++++---
|
||||
libcontainer/container_linux.go | 16 ++--
|
||||
libcontainer/process_linux.go | 19 ++--
|
||||
libcontainer/state_linux.go | 4 +-
|
||||
main.go | 33 +++++--
|
||||
script/runc-euleros.spec | 2 +-
|
||||
vendor/github.com/Sirupsen/logrus/Checklist | 1 +
|
||||
.../Sirupsen/logrus/hooks/airbrake/airbrake.go | 54 +++++++++++
|
||||
.../Sirupsen/logrus/hooks/bugsnag/bugsnag.go | 68 ++++++++++++++
|
||||
.../Sirupsen/logrus/hooks/papertrail/README.md | 28 ++++++
|
||||
.../Sirupsen/logrus/hooks/papertrail/papertrail.go | 55 ++++++++++++
|
||||
.../Sirupsen/logrus/hooks/sentry/README.md | 61 +++++++++++++
|
||||
.../Sirupsen/logrus/hooks/sentry/sentry.go | 100 +++++++++++++++++++++
|
||||
.../Sirupsen/logrus/hooks/syslog/README.md | 20 +++++
|
||||
.../Sirupsen/logrus/hooks/syslog/syslog.go | 59 ++++++++++++
|
||||
16 files changed, 535 insertions(+), 43 deletions(-)
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/Checklist
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
|
||||
create mode 100644 vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
|
||||
|
||||
diff --git a/create.go b/create.go
|
||||
index 096e8e3..d0246ad 100644
|
||||
--- a/create.go
|
||||
+++ b/create.go
|
||||
@@ -1,9 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
- "os"
|
||||
-
|
||||
"github.com/urfave/cli"
|
||||
+ "os"
|
||||
)
|
||||
|
||||
var createCommand = cli.Command{
|
||||
diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go
|
||||
index 49bc7a3..d6bc603 100644
|
||||
--- a/libcontainer/configs/config.go
|
||||
+++ b/libcontainer/configs/config.go
|
||||
@@ -4,12 +4,18 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
+)
|
||||
|
||||
- "github.com/Sirupsen/logrus"
|
||||
- "github.com/opencontainers/runtime-spec/specs-go"
|
||||
+const (
|
||||
+ minHookTimeOut = 1 * time.Second
|
||||
+ defaultHookTimeOut = 5 * time.Second
|
||||
+ //the runc default timeout is 120s, so set the defaultWarnTime to 80% of the default timeout.
|
||||
+ defaultWarnTime = 96 * time.Second
|
||||
)
|
||||
|
||||
type Rlimit struct {
|
||||
@@ -195,9 +201,9 @@ type Config struct {
|
||||
// about the type of the Capabilities field.
|
||||
// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb
|
||||
type CompatConfig struct {
|
||||
- Config
|
||||
- Cgroups *CompatCgroup `json:"cgroups"`
|
||||
- Capabilities interface{} `json:"capabilities,omitempty" platform:"linux"`
|
||||
+ Config
|
||||
+ Cgroups *CompatCgroup `json:"cgroups"`
|
||||
+ Capabilities interface{} `json:"capabilities,omitempty" platform:"linux"`
|
||||
}
|
||||
|
||||
type Hooks struct {
|
||||
@@ -342,29 +348,52 @@ func (c Command) Run(s HookState) error {
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
}
|
||||
+ startTime := time.Now()
|
||||
if err := cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
+ if c.Timeout != nil && *c.Timeout < minHookTimeOut {
|
||||
+ *c.Timeout = defaultHookTimeOut
|
||||
+ }
|
||||
errC := make(chan error, 1)
|
||||
+ var (
|
||||
+ timerCh <-chan time.Time
|
||||
+ warnTime = defaultWarnTime.Seconds()
|
||||
+ )
|
||||
go func() {
|
||||
err := cmd.Wait()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error running hook: %v, stdout: %s, stderr: %s", err, stdout.String(), stderr.String())
|
||||
}
|
||||
+ elapsedTime := time.Since(startTime)
|
||||
+ logrus.Infof("hook spends time %s, ContainerID: %s", elapsedTime, s.ID)
|
||||
+ if c.Timeout != nil {
|
||||
+ if elapsedTime.Seconds() >= (c.Timeout.Seconds() * 0.8) {
|
||||
+ logrus.Warnf("elapsed %s, more than 80%% of the timeout %s, ContainerID: %s", elapsedTime, c.Timeout, s.ID)
|
||||
+ }
|
||||
+ } else {
|
||||
+ if elapsedTime.Seconds() >= warnTime {
|
||||
+ logrus.Warnf("elapsed %s, more than 80%% of the default timeout 120s, ContainerID: %s", elapsedTime, s.ID)
|
||||
+ }
|
||||
+ }
|
||||
errC <- err
|
||||
}()
|
||||
- var timerCh <-chan time.Time
|
||||
if c.Timeout != nil {
|
||||
timer := time.NewTimer(*c.Timeout)
|
||||
defer timer.Stop()
|
||||
timerCh = timer.C
|
||||
+ warnTime = float64(*c.Timeout) * 0.8
|
||||
}
|
||||
- select {
|
||||
- case err := <-errC:
|
||||
- return err
|
||||
- case <-timerCh:
|
||||
- cmd.Process.Kill()
|
||||
- cmd.Wait()
|
||||
- return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
|
||||
+ for {
|
||||
+ select {
|
||||
+ case err := <-errC:
|
||||
+ return err
|
||||
+ case <-timerCh:
|
||||
+ cmd.Process.Kill()
|
||||
+ cmd.Wait()
|
||||
+ return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
|
||||
+ case <-time.After(time.Duration(warnTime) * time.Second):
|
||||
+ logrus.Warnf("hook ran more than 80%% of the default timeout, ContainerID: %s", s.ID)
|
||||
+ }
|
||||
}
|
||||
}
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 502a274..ba5dcd6 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -68,9 +68,9 @@ type State struct {
|
||||
}
|
||||
|
||||
// CompatState
|
||||
-type CompatState struct{
|
||||
- State
|
||||
- Config configs.CompatConfig `json:"config"`
|
||||
+type CompatState struct {
|
||||
+ State
|
||||
+ Config configs.CompatConfig `json:"config"`
|
||||
}
|
||||
|
||||
// Container is a libcontainer container object.
|
||||
@@ -345,13 +345,13 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
Root: c.config.Rootfs,
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Poststart {
|
||||
- logrus.Infof("run poststart hook %d:%s", i, hook.Info())
|
||||
+ logrus.Infof("run poststart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
logrus.Errorf("running poststart hook(%d:%s) failed: %s", i, hook.Info(), err)
|
||||
if err := parent.terminate(); err != nil {
|
||||
- logrus.Warn(err)
|
||||
+ logrus.Warnf("run poststart hook failed: %s, ContainerID: %s", err, s.ID)
|
||||
}
|
||||
- return newSystemErrorWithCausef(err, "running poststart hook %d:%s", i, hook.Info())
|
||||
+ return newSystemErrorWithCausef(err, "running poststart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
logrus.Infof("poststart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
@@ -1319,9 +1319,9 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
|
||||
Root: c.config.Rootfs,
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Prestart {
|
||||
- logrus.Infof("run prestart hook: %d:%s", i, hook.Info())
|
||||
+ logrus.Infof("run prestart hook: %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
- return newSystemErrorWithCausef(err, "running prestart hook %d", i)
|
||||
+ return newSystemErrorWithCausef(err, "running prestart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
logrus.Infof("prestart hook: %d:%s done", i, hook.Info())
|
||||
}
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index 70e93de..79b1c4e 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -6,18 +6,17 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
+ "github.com/opencontainers/runc/libcontainer/configs"
|
||||
+ "github.com/opencontainers/runc/libcontainer/system"
|
||||
+ "github.com/opencontainers/runc/libcontainer/utils"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"syscall"
|
||||
-
|
||||
- "github.com/Sirupsen/logrus"
|
||||
- "github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
- "github.com/opencontainers/runc/libcontainer/configs"
|
||||
- "github.com/opencontainers/runc/libcontainer/system"
|
||||
- "github.com/opencontainers/runc/libcontainer/utils"
|
||||
)
|
||||
|
||||
type parentProcess interface {
|
||||
@@ -309,9 +308,9 @@ func (p *initProcess) start() error {
|
||||
Root: p.config.Config.Rootfs,
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
- logrus.Infof("run prestart hook %d:%s", i, hook.Info())
|
||||
+ logrus.Infof("run prestart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
- return newSystemErrorWithCausef(err, "running prestart hook %d:%s", i, hook.Info())
|
||||
+ return newSystemErrorWithCausef(err, "running prestart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
logrus.Infof("prestart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
@@ -338,9 +337,9 @@ func (p *initProcess) start() error {
|
||||
Root: p.config.Config.Rootfs,
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
- logrus.Infof("run prestart hook %d:%s", i, hook.Info())
|
||||
+ logrus.Infof("run prestart hook %d:%s, ContainerID :%s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
- return newSystemErrorWithCausef(err, "running prestart hook %d:%s", i, hook.Info())
|
||||
+ return newSystemErrorWithCausef(err, "running prestart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
logrus.Infof("prestart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go
|
||||
index b8d2a87..26e091b 100644
|
||||
--- a/libcontainer/state_linux.go
|
||||
+++ b/libcontainer/state_linux.go
|
||||
@@ -66,10 +66,10 @@ func runPoststopHooks(c *linuxContainer) error {
|
||||
Root: c.config.Rootfs,
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Poststop {
|
||||
- logrus.Infof("run poststop hook %d:%s", i, hook.Info())
|
||||
+ logrus.Infof("run poststop hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
logrus.Errorf("running poststop hook %d: %s failed: %s", i, hook.Info(), err)
|
||||
- return newSystemErrorWithCausef(err, "running poststop hook %d:%s", i, hook.Info())
|
||||
+ return newSystemErrorWithCausef(err, "running poststop hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
logrus.Infof("poststop hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
diff --git a/main.go b/main.go
|
||||
index 1cb8f4d..f15a4ac 100644
|
||||
--- a/main.go
|
||||
+++ b/main.go
|
||||
@@ -2,13 +2,14 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
- "io"
|
||||
- "os"
|
||||
- "strings"
|
||||
-
|
||||
"github.com/Sirupsen/logrus"
|
||||
+ "github.com/Sirupsen/logrus/hooks/syslog"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/urfave/cli"
|
||||
+ "io"
|
||||
+ "log/syslog"
|
||||
+ "os"
|
||||
+ "strings"
|
||||
)
|
||||
|
||||
// version will be populated by the Makefile, read from
|
||||
@@ -76,6 +77,10 @@ func main() {
|
||||
Usage: "set the format used by logs ('text' (default), or 'json')",
|
||||
},
|
||||
cli.StringFlag{
|
||||
+ Name: "log-level",
|
||||
+ Usage: "Set the logging level [debug, info, warn, error, fatal, panic]",
|
||||
+ },
|
||||
+ cli.StringFlag{
|
||||
Name: "root",
|
||||
Value: "/run/runc",
|
||||
Usage: "root directory for storage of container state (this should be located in tmpfs)",
|
||||
@@ -110,15 +115,17 @@ func main() {
|
||||
updateCommand,
|
||||
}
|
||||
app.Before = func(context *cli.Context) error {
|
||||
- if context.GlobalBool("debug") {
|
||||
- logrus.SetLevel(logrus.DebugLevel)
|
||||
- }
|
||||
if path := context.GlobalString("log"); path != "" {
|
||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.SetOutput(f)
|
||||
+ hook, serr := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO|syslog.LOG_USER, "docker-runc")
|
||||
+ if serr != nil {
|
||||
+ fmt.Fprint(f, fmt.Sprintf("Leo: new syslog hook get %s", serr))
|
||||
+ }
|
||||
+ logrus.AddHook(hook)
|
||||
}
|
||||
switch context.GlobalString("log-format") {
|
||||
case "text":
|
||||
@@ -128,6 +135,18 @@ func main() {
|
||||
default:
|
||||
return fmt.Errorf("unknown log-format %q", context.GlobalString("log-format"))
|
||||
}
|
||||
+ if logLevel := context.GlobalString("log-level"); logLevel != "" {
|
||||
+ lvl, err := logrus.ParseLevel(logLevel)
|
||||
+ if err != nil {
|
||||
+ fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", logLevel)
|
||||
+ os.Exit(1)
|
||||
+ }
|
||||
+ logrus.SetLevel(lvl)
|
||||
+ }
|
||||
+
|
||||
+ if context.GlobalBool("debug") {
|
||||
+ logrus.SetLevel(logrus.DebugLevel)
|
||||
+ }
|
||||
return nil
|
||||
}
|
||||
// If the command returns an error, cli takes upon itself to print
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index c3db7c9..5318ec2 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 2%{?dist}
|
||||
+Release: 3%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/Checklist b/vendor/github.com/Sirupsen/logrus/Checklist
|
||||
new file mode 100644
|
||||
index 0000000..7117b24
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/Checklist
|
||||
@@ -0,0 +1 @@
|
||||
+imported from runc v1.0.0-Release Candidate 2: Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go b/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
|
||||
new file mode 100644
|
||||
index 0000000..b0502c3
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
|
||||
@@ -0,0 +1,54 @@
|
||||
+package airbrake
|
||||
+
|
||||
+import (
|
||||
+ "errors"
|
||||
+ "fmt"
|
||||
+
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "github.com/tobi/airbrake-go"
|
||||
+)
|
||||
+
|
||||
+// AirbrakeHook to send exceptions to an exception-tracking service compatible
|
||||
+// with the Airbrake API.
|
||||
+type airbrakeHook struct {
|
||||
+ APIKey string
|
||||
+ Endpoint string
|
||||
+ Environment string
|
||||
+}
|
||||
+
|
||||
+func NewHook(endpoint, apiKey, env string) *airbrakeHook {
|
||||
+ return &airbrakeHook{
|
||||
+ APIKey: apiKey,
|
||||
+ Endpoint: endpoint,
|
||||
+ Environment: env,
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func (hook *airbrakeHook) Fire(entry *logrus.Entry) error {
|
||||
+ airbrake.ApiKey = hook.APIKey
|
||||
+ airbrake.Endpoint = hook.Endpoint
|
||||
+ airbrake.Environment = hook.Environment
|
||||
+
|
||||
+ var notifyErr error
|
||||
+ err, ok := entry.Data["error"].(error)
|
||||
+ if ok {
|
||||
+ notifyErr = err
|
||||
+ } else {
|
||||
+ notifyErr = errors.New(entry.Message)
|
||||
+ }
|
||||
+
|
||||
+ airErr := airbrake.Notify(notifyErr)
|
||||
+ if airErr != nil {
|
||||
+ return fmt.Errorf("Failed to send error to Airbrake: %s", airErr)
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+func (hook *airbrakeHook) Levels() []logrus.Level {
|
||||
+ return []logrus.Level{
|
||||
+ logrus.ErrorLevel,
|
||||
+ logrus.FatalLevel,
|
||||
+ logrus.PanicLevel,
|
||||
+ }
|
||||
+}
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go b/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go
|
||||
new file mode 100644
|
||||
index 0000000..d20a0f5
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go
|
||||
@@ -0,0 +1,68 @@
|
||||
+package logrus_bugsnag
|
||||
+
|
||||
+import (
|
||||
+ "errors"
|
||||
+
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "github.com/bugsnag/bugsnag-go"
|
||||
+)
|
||||
+
|
||||
+type bugsnagHook struct{}
|
||||
+
|
||||
+// ErrBugsnagUnconfigured is returned if NewBugsnagHook is called before
|
||||
+// bugsnag.Configure. Bugsnag must be configured before the hook.
|
||||
+var ErrBugsnagUnconfigured = errors.New("bugsnag must be configured before installing this logrus hook")
|
||||
+
|
||||
+// ErrBugsnagSendFailed indicates that the hook failed to submit an error to
|
||||
+// bugsnag. The error was successfully generated, but `bugsnag.Notify()`
|
||||
+// failed.
|
||||
+type ErrBugsnagSendFailed struct {
|
||||
+ err error
|
||||
+}
|
||||
+
|
||||
+func (e ErrBugsnagSendFailed) Error() string {
|
||||
+ return "failed to send error to Bugsnag: " + e.err.Error()
|
||||
+}
|
||||
+
|
||||
+// NewBugsnagHook initializes a logrus hook which sends exceptions to an
|
||||
+// exception-tracking service compatible with the Bugsnag API. Before using
|
||||
+// this hook, you must call bugsnag.Configure(). The returned object should be
|
||||
+// registered with a log via `AddHook()`
|
||||
+//
|
||||
+// Entries that trigger an Error, Fatal or Panic should now include an "error"
|
||||
+// field to send to Bugsnag.
|
||||
+func NewBugsnagHook() (*bugsnagHook, error) {
|
||||
+ if bugsnag.Config.APIKey == "" {
|
||||
+ return nil, ErrBugsnagUnconfigured
|
||||
+ }
|
||||
+ return &bugsnagHook{}, nil
|
||||
+}
|
||||
+
|
||||
+// Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the
|
||||
+// "error" field (or the Message if the error isn't present) and sends it off.
|
||||
+func (hook *bugsnagHook) Fire(entry *logrus.Entry) error {
|
||||
+ var notifyErr error
|
||||
+ err, ok := entry.Data["error"].(error)
|
||||
+ if ok {
|
||||
+ notifyErr = err
|
||||
+ } else {
|
||||
+ notifyErr = errors.New(entry.Message)
|
||||
+ }
|
||||
+
|
||||
+ bugsnagErr := bugsnag.Notify(notifyErr)
|
||||
+ if bugsnagErr != nil {
|
||||
+ return ErrBugsnagSendFailed{bugsnagErr}
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+// Levels enumerates the log levels on which the error should be forwarded to
|
||||
+// bugsnag: everything at or above the "Error" level.
|
||||
+func (hook *bugsnagHook) Levels() []logrus.Level {
|
||||
+ return []logrus.Level{
|
||||
+ logrus.ErrorLevel,
|
||||
+ logrus.FatalLevel,
|
||||
+ logrus.PanicLevel,
|
||||
+ }
|
||||
+}
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md b/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md
|
||||
new file mode 100644
|
||||
index 0000000..ae61e92
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md
|
||||
@@ -0,0 +1,28 @@
|
||||
+# Papertrail Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" />
|
||||
+
|
||||
+[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts).
|
||||
+
|
||||
+In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible.
|
||||
+
|
||||
+## Usage
|
||||
+
|
||||
+You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`.
|
||||
+
|
||||
+For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs.
|
||||
+
|
||||
+```go
|
||||
+import (
|
||||
+ "log/syslog"
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "github.com/Sirupsen/logrus/hooks/papertrail"
|
||||
+)
|
||||
+
|
||||
+func main() {
|
||||
+ log := logrus.New()
|
||||
+ hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME)
|
||||
+
|
||||
+ if err == nil {
|
||||
+ log.Hooks.Add(hook)
|
||||
+ }
|
||||
+}
|
||||
+```
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go b/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
|
||||
new file mode 100644
|
||||
index 0000000..c0f10c1
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
|
||||
@@ -0,0 +1,55 @@
|
||||
+package logrus_papertrail
|
||||
+
|
||||
+import (
|
||||
+ "fmt"
|
||||
+ "net"
|
||||
+ "os"
|
||||
+ "time"
|
||||
+
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+)
|
||||
+
|
||||
+const (
|
||||
+ format = "Jan 2 15:04:05"
|
||||
+)
|
||||
+
|
||||
+// PapertrailHook to send logs to a logging service compatible with the Papertrail API.
|
||||
+type PapertrailHook struct {
|
||||
+ Host string
|
||||
+ Port int
|
||||
+ AppName string
|
||||
+ UDPConn net.Conn
|
||||
+}
|
||||
+
|
||||
+// NewPapertrailHook creates a hook to be added to an instance of logger.
|
||||
+func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) {
|
||||
+ conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port))
|
||||
+ return &PapertrailHook{host, port, appName, conn}, err
|
||||
+}
|
||||
+
|
||||
+// Fire is called when a log event is fired.
|
||||
+func (hook *PapertrailHook) Fire(entry *logrus.Entry) error {
|
||||
+ date := time.Now().Format(format)
|
||||
+ msg, _ := entry.String()
|
||||
+ payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg)
|
||||
+
|
||||
+ bytesWritten, err := hook.UDPConn.Write([]byte(payload))
|
||||
+ if err != nil {
|
||||
+ fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err)
|
||||
+ return err
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+// Levels returns the available logging levels.
|
||||
+func (hook *PapertrailHook) Levels() []logrus.Level {
|
||||
+ return []logrus.Level{
|
||||
+ logrus.PanicLevel,
|
||||
+ logrus.FatalLevel,
|
||||
+ logrus.ErrorLevel,
|
||||
+ logrus.WarnLevel,
|
||||
+ logrus.InfoLevel,
|
||||
+ logrus.DebugLevel,
|
||||
+ }
|
||||
+}
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md b/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md
|
||||
new file mode 100644
|
||||
index 0000000..19e58bb
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md
|
||||
@@ -0,0 +1,61 @@
|
||||
+# Sentry Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" />
|
||||
+
|
||||
+[Sentry](https://getsentry.com) provides both self-hosted and hosted
|
||||
+solutions for exception tracking.
|
||||
+Both client and server are
|
||||
+[open source](https://github.com/getsentry/sentry).
|
||||
+
|
||||
+## Usage
|
||||
+
|
||||
+Every sentry application defined on the server gets a different
|
||||
+[DSN](https://www.getsentry.com/docs/). In the example below replace
|
||||
+`YOUR_DSN` with the one created for your application.
|
||||
+
|
||||
+```go
|
||||
+import (
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "github.com/Sirupsen/logrus/hooks/sentry"
|
||||
+)
|
||||
+
|
||||
+func main() {
|
||||
+ log := logrus.New()
|
||||
+ hook, err := logrus_sentry.NewSentryHook(YOUR_DSN, []logrus.Level{
|
||||
+ logrus.PanicLevel,
|
||||
+ logrus.FatalLevel,
|
||||
+ logrus.ErrorLevel,
|
||||
+ })
|
||||
+
|
||||
+ if err == nil {
|
||||
+ log.Hooks.Add(hook)
|
||||
+ }
|
||||
+}
|
||||
+```
|
||||
+
|
||||
+## Special fields
|
||||
+
|
||||
+Some logrus fields have a special meaning in this hook,
|
||||
+these are server_name and logger.
|
||||
+When logs are sent to sentry these fields are treated differently.
|
||||
+- server_name (also known as hostname) is the name of the server which
|
||||
+is logging the event (hostname.example.com)
|
||||
+- logger is the part of the application which is logging the event.
|
||||
+In go this usually means setting it to the name of the package.
|
||||
+
|
||||
+## Timeout
|
||||
+
|
||||
+`Timeout` is the time the sentry hook will wait for a response
|
||||
+from the sentry server.
|
||||
+
|
||||
+If this time elapses with no response from
|
||||
+the server an error will be returned.
|
||||
+
|
||||
+If `Timeout` is set to 0 the SentryHook will not wait for a reply
|
||||
+and will assume a correct delivery.
|
||||
+
|
||||
+The SentryHook has a default timeout of `100 milliseconds` when created
|
||||
+with a call to `NewSentryHook`. This can be changed by assigning a value to the `Timeout` field:
|
||||
+
|
||||
+```go
|
||||
+hook, _ := logrus_sentry.NewSentryHook(...)
|
||||
+hook.Timeout = 20*time.Second
|
||||
+```
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go b/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
|
||||
new file mode 100644
|
||||
index 0000000..379f281
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
|
||||
@@ -0,0 +1,100 @@
|
||||
+package logrus_sentry
|
||||
+
|
||||
+import (
|
||||
+ "fmt"
|
||||
+ "time"
|
||||
+
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "github.com/getsentry/raven-go"
|
||||
+)
|
||||
+
|
||||
+var (
|
||||
+ severityMap = map[logrus.Level]raven.Severity{
|
||||
+ logrus.DebugLevel: raven.DEBUG,
|
||||
+ logrus.InfoLevel: raven.INFO,
|
||||
+ logrus.WarnLevel: raven.WARNING,
|
||||
+ logrus.ErrorLevel: raven.ERROR,
|
||||
+ logrus.FatalLevel: raven.FATAL,
|
||||
+ logrus.PanicLevel: raven.FATAL,
|
||||
+ }
|
||||
+)
|
||||
+
|
||||
+func getAndDel(d logrus.Fields, key string) (string, bool) {
|
||||
+ var (
|
||||
+ ok bool
|
||||
+ v interface{}
|
||||
+ val string
|
||||
+ )
|
||||
+ if v, ok = d[key]; !ok {
|
||||
+ return "", false
|
||||
+ }
|
||||
+
|
||||
+ if val, ok = v.(string); !ok {
|
||||
+ return "", false
|
||||
+ }
|
||||
+ delete(d, key)
|
||||
+ return val, true
|
||||
+}
|
||||
+
|
||||
+// SentryHook delivers logs to a sentry server.
|
||||
+type SentryHook struct {
|
||||
+ // Timeout sets the time to wait for a delivery error from the sentry server.
|
||||
+ // If this is set to zero the server will not wait for any response and will
|
||||
+ // consider the message correctly sent
|
||||
+ Timeout time.Duration
|
||||
+
|
||||
+ client *raven.Client
|
||||
+ levels []logrus.Level
|
||||
+}
|
||||
+
|
||||
+// NewSentryHook creates a hook to be added to an instance of logger
|
||||
+// and initializes the raven client.
|
||||
+// This method sets the timeout to 100 milliseconds.
|
||||
+func NewSentryHook(DSN string, levels []logrus.Level) (*SentryHook, error) {
|
||||
+ client, err := raven.NewClient(DSN, nil)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ return &SentryHook{100 * time.Millisecond, client, levels}, nil
|
||||
+}
|
||||
+
|
||||
+// Called when an event should be sent to sentry
|
||||
+// Special fields that sentry uses to give more information to the server
|
||||
+// are extracted from entry.Data (if they are found)
|
||||
+// These fields are: logger and server_name
|
||||
+func (hook *SentryHook) Fire(entry *logrus.Entry) error {
|
||||
+ packet := &raven.Packet{
|
||||
+ Message: entry.Message,
|
||||
+ Timestamp: raven.Timestamp(entry.Time),
|
||||
+ Level: severityMap[entry.Level],
|
||||
+ Platform: "go",
|
||||
+ }
|
||||
+
|
||||
+ d := entry.Data
|
||||
+
|
||||
+ if logger, ok := getAndDel(d, "logger"); ok {
|
||||
+ packet.Logger = logger
|
||||
+ }
|
||||
+ if serverName, ok := getAndDel(d, "server_name"); ok {
|
||||
+ packet.ServerName = serverName
|
||||
+ }
|
||||
+ packet.Extra = map[string]interface{}(d)
|
||||
+
|
||||
+ _, errCh := hook.client.Capture(packet, nil)
|
||||
+ timeout := hook.Timeout
|
||||
+ if timeout != 0 {
|
||||
+ timeoutCh := time.After(timeout)
|
||||
+ select {
|
||||
+ case err := <-errCh:
|
||||
+ return err
|
||||
+ case <-timeoutCh:
|
||||
+ return fmt.Errorf("no response from sentry server in %s", timeout)
|
||||
+ }
|
||||
+ }
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+// Levels returns the available logging levels.
|
||||
+func (hook *SentryHook) Levels() []logrus.Level {
|
||||
+ return hook.levels
|
||||
+}
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md b/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
|
||||
new file mode 100644
|
||||
index 0000000..4dbb8e7
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md
|
||||
@@ -0,0 +1,20 @@
|
||||
+# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
|
||||
+
|
||||
+## Usage
|
||||
+
|
||||
+```go
|
||||
+import (
|
||||
+ "log/syslog"
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
|
||||
+)
|
||||
+
|
||||
+func main() {
|
||||
+ log := logrus.New()
|
||||
+ hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
+
|
||||
+ if err == nil {
|
||||
+ log.Hooks.Add(hook)
|
||||
+ }
|
||||
+}
|
||||
+```
|
||||
diff --git a/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go b/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
|
||||
new file mode 100644
|
||||
index 0000000..b6fa374
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
|
||||
@@ -0,0 +1,59 @@
|
||||
+package logrus_syslog
|
||||
+
|
||||
+import (
|
||||
+ "fmt"
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "log/syslog"
|
||||
+ "os"
|
||||
+)
|
||||
+
|
||||
+// SyslogHook to send logs via syslog.
|
||||
+type SyslogHook struct {
|
||||
+ Writer *syslog.Writer
|
||||
+ SyslogNetwork string
|
||||
+ SyslogRaddr string
|
||||
+}
|
||||
+
|
||||
+// Creates a hook to be added to an instance of logger. This is called with
|
||||
+// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
||||
+// `if err == nil { log.Hooks.Add(hook) }`
|
||||
+func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
||||
+ w, err := syslog.Dial(network, raddr, priority, tag)
|
||||
+ return &SyslogHook{w, network, raddr}, err
|
||||
+}
|
||||
+
|
||||
+func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
||||
+ line, err := entry.String()
|
||||
+ if err != nil {
|
||||
+ fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||
+ return err
|
||||
+ }
|
||||
+
|
||||
+ switch entry.Level {
|
||||
+ case logrus.PanicLevel:
|
||||
+ return hook.Writer.Crit(line)
|
||||
+ case logrus.FatalLevel:
|
||||
+ return hook.Writer.Crit(line)
|
||||
+ case logrus.ErrorLevel:
|
||||
+ return hook.Writer.Err(line)
|
||||
+ case logrus.WarnLevel:
|
||||
+ return hook.Writer.Warning(line)
|
||||
+ case logrus.InfoLevel:
|
||||
+ return hook.Writer.Info(line)
|
||||
+ case logrus.DebugLevel:
|
||||
+ return hook.Writer.Debug(line)
|
||||
+ default:
|
||||
+ return nil
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func (hook *SyslogHook) Levels() []logrus.Level {
|
||||
+ return []logrus.Level{
|
||||
+ logrus.PanicLevel,
|
||||
+ logrus.FatalLevel,
|
||||
+ logrus.ErrorLevel,
|
||||
+ logrus.WarnLevel,
|
||||
+ logrus.InfoLevel,
|
||||
+ logrus.DebugLevel,
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
From 6e457e14dcf0960926109c2f89766e893f79b5da Mon Sep 17 00:00:00 2001
|
||||
From: caihaomin <caihaomin@huawei.com>
|
||||
Date: Wed, 24 Oct 2018 14:56:01 +0800
|
||||
Subject: [PATCH 61/94] runc-17: change golang build version to make
|
||||
obs happy
|
||||
|
||||
reason:change golang build version to make obs happy
|
||||
|
||||
Change-Id: Ie4b210056b34611bfb37aa6ea8510540f2c79305
|
||||
Signed-off-by: caihaomin <caihaomin@huawei.com>
|
||||
---
|
||||
script/runc-euleros.spec | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 5318ec2..048ea86 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 3%{?dist}
|
||||
+Release: 4%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
@@ -12,7 +12,7 @@ URL: https://www.opencontainers.org/
|
||||
Vendor: OCI
|
||||
Packager: OCI
|
||||
|
||||
-BuildRequires: golang == 1.8.3
|
||||
+BuildRequires: golang >= 1.8.3
|
||||
BuildRequires: glibc-static
|
||||
BuildRequires: make
|
||||
BuildRequires: libseccomp-devel
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
From ccd2660d85f36695032ed075f8f669ccad17bfc3 Mon Sep 17 00:00:00 2001
|
||||
From: panwenxiang <panwenxiang@huawei.com>
|
||||
Date: Tue, 23 Oct 2018 16:43:20 +0800
|
||||
Subject: [PATCH 62/94] runc: Check the hook timeout in case overflow
|
||||
|
||||
reason:the hook timeout is meaningless when more than 120s
|
||||
|
||||
Change-Id: Ibabf059bd9ba5e68b10189ae4e813d47dcec7ec5
|
||||
---
|
||||
libcontainer/configs/config.go | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go
|
||||
index d6bc603..9049924 100644
|
||||
--- a/libcontainer/configs/config.go
|
||||
+++ b/libcontainer/configs/config.go
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
const (
|
||||
minHookTimeOut = 1 * time.Second
|
||||
defaultHookTimeOut = 5 * time.Second
|
||||
+ maxHookTimeOut = 120 * time.Second
|
||||
//the runc default timeout is 120s, so set the defaultWarnTime to 80% of the default timeout.
|
||||
defaultWarnTime = 96 * time.Second
|
||||
)
|
||||
@@ -355,6 +356,10 @@ func (c Command) Run(s HookState) error {
|
||||
if c.Timeout != nil && *c.Timeout < minHookTimeOut {
|
||||
*c.Timeout = defaultHookTimeOut
|
||||
}
|
||||
+ if c.Timeout != nil && *c.Timeout > maxHookTimeOut {
|
||||
+ logrus.Warnf("hook timeout: %s is too long, ContainerID: %s", *c.Timeout, s.ID)
|
||||
+ *c.Timeout = maxHookTimeOut
|
||||
+ }
|
||||
errC := make(chan error, 1)
|
||||
var (
|
||||
timerCh <-chan time.Time
|
||||
@@ -382,7 +387,7 @@ func (c Command) Run(s HookState) error {
|
||||
timer := time.NewTimer(*c.Timeout)
|
||||
defer timer.Stop()
|
||||
timerCh = timer.C
|
||||
- warnTime = float64(*c.Timeout) * 0.8
|
||||
+ warnTime = (*c.Timeout).Seconds() * 0.8
|
||||
}
|
||||
for {
|
||||
select {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
From 256b247e9fa9844c8e0760679411427d43b661c9 Mon Sep 17 00:00:00 2001
|
||||
From: wangfengtu <wangfengtu@huawei.com>
|
||||
Date: Wed, 5 Sep 2018 15:16:28 +0800
|
||||
Subject: [PATCH 63/94] docker: close openchan immediately to avoid
|
||||
error
|
||||
|
||||
reason: close openchan immediately to avoid error
|
||||
|
||||
Change-Id: I20664570518ea424088a4eb6a5aac3d38ac08449
|
||||
Signed-off-by: wangfengtu <wangfengtu@huawei.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index ba5dcd6..61ffb76 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -245,8 +245,7 @@ func (c *linuxContainer) exec() error {
|
||||
select {
|
||||
case <-awaitProcessExit(c.initProcess.pid(), fifoOpen):
|
||||
return errors.New("container process is already dead")
|
||||
- case result := <-awaitFifoOpen(path):
|
||||
- close(fifoOpen)
|
||||
+ case result := <-awaitFifoOpen(path, fifoOpen):
|
||||
if result.err != nil {
|
||||
return result.err
|
||||
}
|
||||
@@ -283,7 +282,12 @@ func awaitProcessExit(pid int, exit <-chan struct{}) <-chan struct{} {
|
||||
case <-time.After(time.Millisecond * 100):
|
||||
stat, err := system.GetProcessState(pid)
|
||||
if err != nil || stat == system.Zombie {
|
||||
- close(isDead)
|
||||
+ select {
|
||||
+ case <-exit:
|
||||
+ return
|
||||
+ default:
|
||||
+ close(isDead)
|
||||
+ }
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -292,10 +296,11 @@ func awaitProcessExit(pid int, exit <-chan struct{}) <-chan struct{} {
|
||||
return isDead
|
||||
}
|
||||
|
||||
-func awaitFifoOpen(path string) <-chan openResult {
|
||||
+func awaitFifoOpen(path string, fifoOpen chan struct{}) <-chan openResult {
|
||||
fifoOpened := make(chan openResult)
|
||||
go func() {
|
||||
f, err := os.OpenFile(path, os.O_RDONLY, 0)
|
||||
+ close(fifoOpen)
|
||||
if err != nil {
|
||||
fifoOpened <- openResult{err: newSystemErrorWithCause(err, "open exec fifo for reading")}
|
||||
return
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From f7c4eae61c9d532ff9ea77aba147976d05235dba Mon Sep 17 00:00:00 2001
|
||||
From: lujingxiao <lujingxiao@huawei.com>
|
||||
Date: Tue, 30 Oct 2018 15:24:47 +0800
|
||||
Subject: [PATCH 64/94] runc: bump to v1.0.0.rc3.4 after normalization
|
||||
|
||||
reason:bump version to v1.0.0.rc3.4 after making runc and
|
||||
runc-17 into one project
|
||||
|
||||
Change-Id: I9045945c81f9b21aff53659dac98b4461dea4199
|
||||
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||||
---
|
||||
script/runc-euleros.spec | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 048ea86..0ba07be 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 4%{?dist}
|
||||
+Release: 5%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,94 @@
|
||||
From c5f152a9dc851e0297f63a73c3e59890da135352 Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Fri, 19 Oct 2018 10:53:33 +0800
|
||||
Subject: [PATCH 65/94] runc: support namespaced kernel params can be
|
||||
changed in system container
|
||||
|
||||
reason:support namespaced kernel files can be written in container,
|
||||
when docker run a system container specify '--ns-change-opt' param,
|
||||
net or ipc namespaced kernel params can be changed in this container.
|
||||
|
||||
Conflicts:
|
||||
libcontainer/rootfs_linux.go
|
||||
script/runc-euleros.spec
|
||||
|
||||
Change-Id: I051b274117abd9745a27577e14a23c906ff7cca3
|
||||
Signed-off-by: jingrui <jingrui@huawei.com>
|
||||
---
|
||||
libcontainer/rootfs_linux.go | 26 ++++++++++++++++++++++++++
|
||||
libcontainer/standard_init_linux.go | 8 ++++++++
|
||||
2 files changed, 34 insertions(+)
|
||||
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index 7cf5edd..38bdd1b 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -160,6 +160,9 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
|
||||
|
||||
switch m.Device {
|
||||
case "proc", "sysfs":
|
||||
+ if strings.HasPrefix(m.Destination, "/proc/sys/") {
|
||||
+ return nil
|
||||
+ }
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -729,6 +732,29 @@ func readonlyPath(path string) error {
|
||||
return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "")
|
||||
}
|
||||
|
||||
+// remountReadWrite will bind over the top of an existing path and ensure that it is read-write.
|
||||
+func remountReadWrite(path string) error {
|
||||
+ for i := 0; i < 5; i++ {
|
||||
+ if err := syscall.Mount("", path, "", syscall.MS_REMOUNT, ""); err != nil && !os.IsNotExist(err) {
|
||||
+ switch err {
|
||||
+ case syscall.EINVAL:
|
||||
+ // Probably not a mountpoint, use bind-mount
|
||||
+ if err := syscall.Mount(path, path, "", syscall.MS_BIND, ""); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_REC|defaultMountFlags, "")
|
||||
+ case syscall.EBUSY:
|
||||
+ time.Sleep(100 * time.Millisecond)
|
||||
+ continue
|
||||
+ default:
|
||||
+ return err
|
||||
+ }
|
||||
+ }
|
||||
+ return nil
|
||||
+ }
|
||||
+ return fmt.Errorf("unable to mount %s as readwrite max retries reached", path)
|
||||
+}
|
||||
+
|
||||
// remountReadonly will remount an existing mount point and ensure that it is read-only.
|
||||
func remountReadonly(m *configs.Mount) error {
|
||||
var (
|
||||
diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go
|
||||
index 484ba42..18506af 100644
|
||||
--- a/libcontainer/standard_init_linux.go
|
||||
+++ b/libcontainer/standard_init_linux.go
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
+ "strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -117,6 +118,13 @@ func (l *linuxStandardInit) Init() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
+ for _, m := range l.config.Config.Mounts {
|
||||
+ if m.Flags&syscall.MS_RDONLY == 0 && m.Device == "proc" && strings.HasPrefix(m.Destination, "/proc/sys/") {
|
||||
+ if err := remountReadWrite(m.Destination); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
for _, path := range l.config.Config.MaskPaths {
|
||||
if err := maskPath(path); err != nil {
|
||||
return err
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
29
patch/0066-runc-bump-to-v1.0.0.rc3.6.patch
Normal file
29
patch/0066-runc-bump-to-v1.0.0.rc3.6.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From c8e1e988fa6509070411c7dbab50edb40092aaf9 Mon Sep 17 00:00:00 2001
|
||||
From: jingrui <jingrui@huawei.com>
|
||||
Date: Sat, 23 Feb 2019 14:13:49 +0800
|
||||
Subject: [PATCH 66/94] runc: bump to v1.0.0.rc3.6
|
||||
|
||||
reason:bump version to v1.0.0.rc3.6
|
||||
|
||||
Change-Id: I79890c41c7934f96ee6e1d676450d7832cc90f73
|
||||
Signed-off-by: jingrui <jingrui@huawei.com>
|
||||
---
|
||||
script/runc-euleros.spec | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 0ba07be..08fceee 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 5%{?dist}
|
||||
+Release: 6%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
137
patch/0067-runc-make-the-runc-log-more-useful.patch
Normal file
137
patch/0067-runc-make-the-runc-log-more-useful.patch
Normal file
@ -0,0 +1,137 @@
|
||||
From 6bc094ef27ebb55f22c5a1b63ab40a66bf73cc35 Mon Sep 17 00:00:00 2001
|
||||
From: panwenxiang <panwenxiang@huawei.com>
|
||||
Date: Sat, 3 Nov 2018 12:42:49 +0800
|
||||
Subject: [PATCH 67/94] runc: make the runc log more useful.
|
||||
|
||||
reason:changed some log infomation.
|
||||
|
||||
Change-Id: Ib6cda4b8a0ef3a441c45f6c435fe11430f8eada8
|
||||
Signed-off-by: panwenxiang <panwenxiang@huawei.com>
|
||||
---
|
||||
libcontainer/configs/config.go | 13 +++++++++----
|
||||
libcontainer/container_linux.go | 1 -
|
||||
libcontainer/process_linux.go | 4 +---
|
||||
libcontainer/state_linux.go | 1 -
|
||||
main.go | 2 +-
|
||||
script/runc-euleros.spec | 2 +-
|
||||
6 files changed, 12 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go
|
||||
index 9049924..f8f9d05 100644
|
||||
--- a/libcontainer/configs/config.go
|
||||
+++ b/libcontainer/configs/config.go
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
- minHookTimeOut = 1 * time.Second
|
||||
+ minHookTimeOut = 0
|
||||
defaultHookTimeOut = 5 * time.Second
|
||||
maxHookTimeOut = 120 * time.Second
|
||||
//the runc default timeout is 120s, so set the defaultWarnTime to 80% of the default timeout.
|
||||
@@ -353,11 +353,12 @@ func (c Command) Run(s HookState) error {
|
||||
if err := cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
- if c.Timeout != nil && *c.Timeout < minHookTimeOut {
|
||||
+ if c.Timeout != nil && *c.Timeout <= minHookTimeOut {
|
||||
*c.Timeout = defaultHookTimeOut
|
||||
+ logrus.Warnf("hook timeout should not be negative or zero, set hook timeout as 5s")
|
||||
}
|
||||
if c.Timeout != nil && *c.Timeout > maxHookTimeOut {
|
||||
- logrus.Warnf("hook timeout: %s is too long, ContainerID: %s", *c.Timeout, s.ID)
|
||||
+ logrus.Warnf("hook timeout: %s is too long, use 120s as timeout. ContainerID: %s", *c.Timeout, s.ID)
|
||||
*c.Timeout = maxHookTimeOut
|
||||
}
|
||||
errC := make(chan error, 1)
|
||||
@@ -398,7 +399,11 @@ func (c Command) Run(s HookState) error {
|
||||
cmd.Wait()
|
||||
return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
|
||||
case <-time.After(time.Duration(warnTime) * time.Second):
|
||||
- logrus.Warnf("hook ran more than 80%% of the default timeout, ContainerID: %s", s.ID)
|
||||
+ if c.Timeout != nil {
|
||||
+ logrus.Warnf("hook ran more than 80%% of the timeout %s, ContainerID: %s", *c.Timeout, s.ID)
|
||||
+ } else {
|
||||
+ logrus.Warnf("hook ran more than 80%% of the default timeout 120s, ContainerID: %s", s.ID)
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 61ffb76..8e0ad12 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -358,7 +358,6 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
}
|
||||
return newSystemErrorWithCausef(err, "running poststart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
- logrus.Infof("poststart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
|
||||
index 79b1c4e..4a7321c 100644
|
||||
--- a/libcontainer/process_linux.go
|
||||
+++ b/libcontainer/process_linux.go
|
||||
@@ -312,7 +312,6 @@ func (p *initProcess) start() error {
|
||||
if err := hook.Run(s); err != nil {
|
||||
return newSystemErrorWithCausef(err, "running prestart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
- logrus.Infof("prestart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,11 +336,10 @@ func (p *initProcess) start() error {
|
||||
Root: p.config.Config.Rootfs,
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
- logrus.Infof("run prestart hook %d:%s, ContainerID :%s", i, hook.Info(), s.ID)
|
||||
+ logrus.Infof("run prestart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
return newSystemErrorWithCausef(err, "running prestart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
- logrus.Infof("prestart hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
// Sync with child.
|
||||
diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go
|
||||
index 26e091b..6fa62c0 100644
|
||||
--- a/libcontainer/state_linux.go
|
||||
+++ b/libcontainer/state_linux.go
|
||||
@@ -71,7 +71,6 @@ func runPoststopHooks(c *linuxContainer) error {
|
||||
logrus.Errorf("running poststop hook %d: %s failed: %s", i, hook.Info(), err)
|
||||
return newSystemErrorWithCausef(err, "running poststop hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
- logrus.Infof("poststop hook %d:%s done", i, hook.Info())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
diff --git a/main.go b/main.go
|
||||
index f15a4ac..e55ff82 100644
|
||||
--- a/main.go
|
||||
+++ b/main.go
|
||||
@@ -78,7 +78,7 @@ func main() {
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "log-level",
|
||||
- Usage: "Set the logging level [debug, info, warn, error, fatal, panic]",
|
||||
+ Usage: "set the logging level [debug, info, warn, error, fatal, panic]",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "root",
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 08fceee..e829cb9 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 6%{?dist}
|
||||
+Release: 7%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
From 940d7088701fbfe6c2d636251490a1d28f90dbdc Mon Sep 17 00:00:00 2001
|
||||
From: panwenxiang <panwenxiang@huawei.com>
|
||||
Date: Thu, 8 Nov 2018 10:19:23 +0800
|
||||
Subject: [PATCH 68/94] runc: reduced the same log when the hook
|
||||
exected long time.
|
||||
|
||||
reason:runc would print a lot of same logs when the hook executed long time
|
||||
|
||||
Change-Id: I7d0b07cca68590c560580967f8d70143764f53d9
|
||||
Signed-off-by: panwenxiang <panwenxiang@huawei.com>
|
||||
---
|
||||
libcontainer/configs/config.go | 3 ++-
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go
|
||||
index f8f9d05..78a7d1d 100644
|
||||
--- a/libcontainer/configs/config.go
|
||||
+++ b/libcontainer/configs/config.go
|
||||
@@ -390,6 +390,7 @@ func (c Command) Run(s HookState) error {
|
||||
timerCh = timer.C
|
||||
warnTime = (*c.Timeout).Seconds() * 0.8
|
||||
}
|
||||
+ timeAfter := time.After(time.Duration(warnTime) * time.Second)
|
||||
for {
|
||||
select {
|
||||
case err := <-errC:
|
||||
@@ -398,7 +399,7 @@ func (c Command) Run(s HookState) error {
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
|
||||
- case <-time.After(time.Duration(warnTime) * time.Second):
|
||||
+ case <-timeAfter:
|
||||
if c.Timeout != nil {
|
||||
logrus.Warnf("hook ran more than 80%% of the timeout %s, ContainerID: %s", *c.Timeout, s.ID)
|
||||
} else {
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index e829cb9..025b621 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 7%{?dist}
|
||||
+Release: 8%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
From 4b8a7b69792c22c1ee3abf3bee88af3590b144cb Mon Sep 17 00:00:00 2001
|
||||
From: lujingxiao <lujingxiao@huawei.com>
|
||||
Date: Thu, 8 Nov 2018 11:14:01 +0800
|
||||
Subject: [PATCH 69/94] runc: Change Files to LinuxFiles for
|
||||
--file-limit
|
||||
|
||||
reason: after runc-1.0.0.rc3, struct Files should be renamed
|
||||
to LinuxFiles.
|
||||
|
||||
--file-limit related commits:
|
||||
- 0c540de runc: change read value of cgroup files.limit into string
|
||||
- fb2de87 runc: Modify max files.limit to max because of the
|
||||
change of kernel.
|
||||
- 5fc9474 Add file fds limit
|
||||
all are already merged.
|
||||
|
||||
Change-Id: Ida75dd6a7ccd225f6ac851bf4a28ef77d5a3944f
|
||||
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||||
---
|
||||
libcontainer/specconv/spec_linux.go | 4 ++--
|
||||
script/runc-euleros.spec | 2 +-
|
||||
vendor/github.com/opencontainers/runtime-spec/Checklist | 1 +
|
||||
.../github.com/opencontainers/runtime-spec/specs-go/config.go | 10 +++++-----
|
||||
4 files changed, 9 insertions(+), 8 deletions(-)
|
||||
create mode 100644 vendor/github.com/opencontainers/runtime-spec/Checklist
|
||||
|
||||
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
|
||||
index a8cf114..8ef9574 100644
|
||||
--- a/libcontainer/specconv/spec_linux.go
|
||||
+++ b/libcontainer/specconv/spec_linux.go
|
||||
@@ -408,8 +408,8 @@ func createCgroupConfig(opts *CreateOpts) (*configs.Cgroup, error) {
|
||||
if r.Pids != nil {
|
||||
c.Resources.PidsLimit = r.Pids.Limit
|
||||
}
|
||||
- if r.Files != nil && r.Files.Limit != nil {
|
||||
- c.Resources.FilesLimit = *r.Files.Limit
|
||||
+ if r.Files != nil {
|
||||
+ c.Resources.FilesLimit = r.Files.Limit
|
||||
}
|
||||
if r.BlockIO != nil {
|
||||
if r.BlockIO.Weight != nil {
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 025b621..19cdc42 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 8%{?dist}
|
||||
+Release: 9%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
diff --git a/vendor/github.com/opencontainers/runtime-spec/Checklist b/vendor/github.com/opencontainers/runtime-spec/Checklist
|
||||
new file mode 100644
|
||||
index 0000000..be85bc8
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/opencontainers/runtime-spec/Checklist
|
||||
@@ -0,0 +1 @@
|
||||
+Add struct LinuxFiles to vendor/src/github.com/opencontainers/runtime-spec/specs-go/config.go for supporting --files-limit
|
||||
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
index 603ecf4..fe3c5b6 100644
|
||||
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
@@ -318,10 +318,10 @@ type LinuxPids struct {
|
||||
Limit int64 `json:"limit"`
|
||||
}
|
||||
|
||||
-// Files for Linux cgroup 'files' resource management (https://lwn.net/Articles/604129/)
|
||||
-type Files struct {
|
||||
- // Maximum number of open files".
|
||||
- Limit *int64 `json:"limit,omitempty"`
|
||||
+// LinuxFiles for Linux cgroup 'files' resource management (https://lwn.net/Articles/604129/)
|
||||
+type LinuxFiles struct {
|
||||
+ // Maximum number of open files. Default is "no limit".
|
||||
+ Limit int64 `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxNetwork identification and priority configuration
|
||||
@@ -347,7 +347,7 @@ type LinuxResources struct {
|
||||
// Task resource restriction configuration.
|
||||
Pids *LinuxPids `json:"pids,omitempty"`
|
||||
// Files resource restriction configuration.
|
||||
- Files *Files `json:"files,omitempty"`
|
||||
+ Files *LinuxFiles `json:"files,omitempty"`
|
||||
// BlockIO restriction configuration
|
||||
BlockIO *LinuxBlockIO `json:"blockIO,omitempty"`
|
||||
// Hugetlb limit (in bytes)
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
48
patch/0070-runc-not-print-no-such-file-when-cli-err.patch
Normal file
48
patch/0070-runc-not-print-no-such-file-when-cli-err.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From e0f78c86d05f7af62aef49c8c495f417d1bf7beb Mon Sep 17 00:00:00 2001
|
||||
From: lujingxiao <lujingxiao@huawei.com>
|
||||
Date: Fri, 9 Nov 2018 15:01:27 +0800
|
||||
Subject: [PATCH 70/94] runc: not print "no such file" when cli err
|
||||
|
||||
reason: when container does not exists, runc will cannot find
|
||||
state.json, so "state.json: no such file or directory" is expected.
|
||||
but user may call runc command anytime, so we should not print such
|
||||
log to syslog. Just return it with stderr is ok.
|
||||
|
||||
Change-Id: Ia26824d0339f69d8db3ef86c0f8344f60963a177
|
||||
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||||
---
|
||||
main.go | 5 ++++-
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/main.go b/main.go
|
||||
index e55ff82..be3fba6 100644
|
||||
--- a/main.go
|
||||
+++ b/main.go
|
||||
@@ -163,6 +163,9 @@ type FatalWriter struct {
|
||||
}
|
||||
|
||||
func (f *FatalWriter) Write(p []byte) (n int, err error) {
|
||||
- logrus.Error(string(p))
|
||||
+ errStr := string(p)
|
||||
+ if !strings.Contains(errStr, "state.json: no such file or directory") {
|
||||
+ logrus.Error(errStr)
|
||||
+ }
|
||||
return f.cliErrWriter.Write(p)
|
||||
}
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 19cdc42..acadd9e 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 9%{?dist}
|
||||
+Release: 10%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
From a667acd5325633858ae671f27075d58345b12619 Mon Sep 17 00:00:00 2001
|
||||
From: leizhongkai <leizhongkai@huawei.com>
|
||||
Date: Fri, 9 Nov 2018 20:06:31 +0800
|
||||
Subject: [PATCH 71/94] runc: [revert]Change Files to LinuxFiles for
|
||||
--file-limit
|
||||
|
||||
reason:This reverts commit 1695b25310c490fe5038cf5a49e4c17ffc85af0e.
|
||||
|
||||
Signed-off-by: leizhongkai <leizhongkai@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
script/runc-euleros.spec
|
||||
|
||||
Change-Id: Iddbcc7eca095b4b8e5d062e06f2f332a2c07caf8
|
||||
---
|
||||
libcontainer/specconv/spec_linux.go | 4 ++--
|
||||
script/runc-euleros.spec | 2 +-
|
||||
vendor/github.com/opencontainers/runtime-spec/Checklist | 1 -
|
||||
.../github.com/opencontainers/runtime-spec/specs-go/config.go | 10 +++++-----
|
||||
4 files changed, 8 insertions(+), 9 deletions(-)
|
||||
delete mode 100644 vendor/github.com/opencontainers/runtime-spec/Checklist
|
||||
|
||||
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
|
||||
index 8ef9574..a8cf114 100644
|
||||
--- a/libcontainer/specconv/spec_linux.go
|
||||
+++ b/libcontainer/specconv/spec_linux.go
|
||||
@@ -408,8 +408,8 @@ func createCgroupConfig(opts *CreateOpts) (*configs.Cgroup, error) {
|
||||
if r.Pids != nil {
|
||||
c.Resources.PidsLimit = r.Pids.Limit
|
||||
}
|
||||
- if r.Files != nil {
|
||||
- c.Resources.FilesLimit = r.Files.Limit
|
||||
+ if r.Files != nil && r.Files.Limit != nil {
|
||||
+ c.Resources.FilesLimit = *r.Files.Limit
|
||||
}
|
||||
if r.BlockIO != nil {
|
||||
if r.BlockIO.Weight != nil {
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index acadd9e..16fb43c 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 10%{?dist}
|
||||
+Release: 11%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
diff --git a/vendor/github.com/opencontainers/runtime-spec/Checklist b/vendor/github.com/opencontainers/runtime-spec/Checklist
|
||||
deleted file mode 100644
|
||||
index be85bc8..0000000
|
||||
--- a/vendor/github.com/opencontainers/runtime-spec/Checklist
|
||||
+++ /dev/null
|
||||
@@ -1 +0,0 @@
|
||||
-Add struct LinuxFiles to vendor/src/github.com/opencontainers/runtime-spec/specs-go/config.go for supporting --files-limit
|
||||
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
index fe3c5b6..603ecf4 100644
|
||||
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
@@ -318,10 +318,10 @@ type LinuxPids struct {
|
||||
Limit int64 `json:"limit"`
|
||||
}
|
||||
|
||||
-// LinuxFiles for Linux cgroup 'files' resource management (https://lwn.net/Articles/604129/)
|
||||
-type LinuxFiles struct {
|
||||
- // Maximum number of open files. Default is "no limit".
|
||||
- Limit int64 `json:"limit,omitempty"`
|
||||
+// Files for Linux cgroup 'files' resource management (https://lwn.net/Articles/604129/)
|
||||
+type Files struct {
|
||||
+ // Maximum number of open files".
|
||||
+ Limit *int64 `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxNetwork identification and priority configuration
|
||||
@@ -347,7 +347,7 @@ type LinuxResources struct {
|
||||
// Task resource restriction configuration.
|
||||
Pids *LinuxPids `json:"pids,omitempty"`
|
||||
// Files resource restriction configuration.
|
||||
- Files *LinuxFiles `json:"files,omitempty"`
|
||||
+ Files *Files `json:"files,omitempty"`
|
||||
// BlockIO restriction configuration
|
||||
BlockIO *LinuxBlockIO `json:"blockIO,omitempty"`
|
||||
// Hugetlb limit (in bytes)
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
From b736c8d450f52150db3b8f7a6a247338028b57bf Mon Sep 17 00:00:00 2001
|
||||
From: jingrui <jingrui@huawei.com>
|
||||
Date: Tue, 13 Nov 2018 17:21:19 +0800
|
||||
Subject: [PATCH 72/94] Revert "runc: not print "no such file" when cli
|
||||
err"
|
||||
|
||||
reason: This reverts commit 21c62a431c2795f59a82312dd9b8a437a1b2ca28.
|
||||
|
||||
Change-Id: Ice19acd48ef916a3d992d9f4d06cf056361565e5
|
||||
Signed-off-by: jingrui <jingrui@huawei.com>
|
||||
---
|
||||
main.go | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/main.go b/main.go
|
||||
index be3fba6..e55ff82 100644
|
||||
--- a/main.go
|
||||
+++ b/main.go
|
||||
@@ -163,9 +163,6 @@ type FatalWriter struct {
|
||||
}
|
||||
|
||||
func (f *FatalWriter) Write(p []byte) (n int, err error) {
|
||||
- errStr := string(p)
|
||||
- if !strings.Contains(errStr, "state.json: no such file or directory") {
|
||||
- logrus.Error(errStr)
|
||||
- }
|
||||
+ logrus.Error(string(p))
|
||||
return f.cliErrWriter.Write(p)
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
From 3c0c0adf121e44ee00b7191a2693575676eb90be Mon Sep 17 00:00:00 2001
|
||||
From: jingrui <jingrui@huawei.com>
|
||||
Date: Tue, 13 Nov 2018 15:38:05 +0800
|
||||
Subject: [PATCH 73/94] runc: fix state.json: no such file or directory
|
||||
|
||||
reason: fix 8c14d652 * runc-17: add compatibility for docker-1.11.2
|
||||
|
||||
Change-Id: I8ff0b3ae90611dfb6e1f5fbd1b8170c460d9ea2d
|
||||
Signed-off-by: jingrui <jingrui@huawei.com>
|
||||
---
|
||||
libcontainer/factory_linux.go | 14 +++++++-------
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go
|
||||
index b533346..fe9ce24 100644
|
||||
--- a/libcontainer/factory_linux.go
|
||||
+++ b/libcontainer/factory_linux.go
|
||||
@@ -368,11 +368,11 @@ func (l *LinuxFactory) updateStateCapabilites(compatState *CompatState, configPa
|
||||
return errors.New("updateStateCapabilites unexpected format for capabilities")
|
||||
}
|
||||
|
||||
-func (l *LinuxFactory) loadOriginState(configPath string) (*State, error) {
|
||||
+func (l *LinuxFactory) loadOriginState(configPath, id string) (*State, error) {
|
||||
f, err := os.Open(configPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
- return nil, newGenericError(err, ContainerNotExists)
|
||||
+ return nil, newGenericError(fmt.Errorf("container %q does not exist", id), ContainerNotExists)
|
||||
}
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
@@ -384,11 +384,11 @@ func (l *LinuxFactory) loadOriginState(configPath string) (*State, error) {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
-func (l *LinuxFactory) loadCompatState(configPath string) (*State, error) {
|
||||
+func (l *LinuxFactory) loadCompatState(configPath, id string) (*State, error) {
|
||||
dt, err := ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
- return nil, newGenericError(err, ContainerNotExists)
|
||||
+ return nil, newGenericError(fmt.Errorf("container %q does not exist", id), ContainerNotExists)
|
||||
}
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
@@ -403,14 +403,14 @@ func (l *LinuxFactory) loadCompatState(configPath string) (*State, error) {
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
|
||||
- return l.loadOriginState(configPath)
|
||||
+ return l.loadOriginState(configPath, id)
|
||||
}
|
||||
|
||||
func (l *LinuxFactory) loadState(root, id string) (*State, error) {
|
||||
configPath := filepath.Join(root, stateFilename)
|
||||
- state, err := l.loadOriginState(configPath)
|
||||
+ state, err := l.loadOriginState(configPath, id)
|
||||
if err != nil {
|
||||
- return l.loadCompatState(configPath)
|
||||
+ return l.loadCompatState(configPath, id)
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 16fb43c..536678d 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 11%{?dist}
|
||||
+Release: 12%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
78
patch/0074-runc-fix-check-sysctl-in-host-network-mode.patch
Normal file
78
patch/0074-runc-fix-check-sysctl-in-host-network-mode.patch
Normal file
@ -0,0 +1,78 @@
|
||||
From 0a760e4753e743a0fe874471584d378b81a02d07 Mon Sep 17 00:00:00 2001
|
||||
From: zhangyuyun <zhangyuyun@huawei.com>
|
||||
Date: Thu, 15 Nov 2018 01:10:44 -0500
|
||||
Subject: [PATCH 74/94] runc: fix check sysctl in host network mode
|
||||
|
||||
reason:it's found failed in runc to check if the container is in
|
||||
the host namespace,which introduced by
|
||||
https://github.com/opencontainers/runc/pull/1138
|
||||
https://github.com/opencontainers/runc/pull/1221
|
||||
|
||||
Change-Id: If1374c081cea93c700d627b40d2ca1ad58b5fb83
|
||||
---
|
||||
libcontainer/configs/validate/validator.go | 27 ++++++++++++++++++---------
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 19 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/validate/validator.go b/libcontainer/configs/validate/validator.go
|
||||
index 8284345..5cb50fb 100644
|
||||
--- a/libcontainer/configs/validate/validator.go
|
||||
+++ b/libcontainer/configs/validate/validator.go
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
+ "syscall"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
selinux "github.com/opencontainers/selinux/go-selinux"
|
||||
@@ -177,16 +178,24 @@ func checkHostNs(sysctlConfig string, path string) error {
|
||||
return fmt.Errorf("could not check that %q is a symlink: %v", path, err)
|
||||
}
|
||||
|
||||
+ var destOfContainer string
|
||||
if symLink == false {
|
||||
- // The provided namespace is not a symbolic link,
|
||||
- // it is not the host namespace.
|
||||
- return nil
|
||||
- }
|
||||
-
|
||||
- // readlink on the path provided in the struct
|
||||
- destOfContainer, err := os.Readlink(path)
|
||||
- if err != nil {
|
||||
- return fmt.Errorf("read soft link %q error", path)
|
||||
+ // try getting inode number for comparsion
|
||||
+ f, err := os.Stat(path)
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ stat, ok := f.Sys().(*syscall.Stat_t)
|
||||
+ if !ok {
|
||||
+ return fmt.Errorf("cannot convert stat value of %q to syscall.Stat_t", path)
|
||||
+ }
|
||||
+ destOfContainer = fmt.Sprintf("net:[%d]", stat.Ino)
|
||||
+ } else {
|
||||
+ // readlink on the path provided in the struct
|
||||
+ destOfContainer, err = os.Readlink(path)
|
||||
+ if err != nil {
|
||||
+ return fmt.Errorf("read soft link %q error", path)
|
||||
+ }
|
||||
}
|
||||
if destOfContainer == destOfCurrentProcess {
|
||||
return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", sysctlConfig)
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 536678d..0e92bf0 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 12%{?dist}
|
||||
+Release: 13%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
From b35de14c25e51f98c3e61636ed79ba91e6259596 Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Thu, 6 Dec 2018 19:44:58 +0800
|
||||
Subject: [PATCH 75/94] runc: Fix systemd-journald service dependency
|
||||
|
||||
reason:runc logs forwarding to syslog only when systemd-journald service
|
||||
status is active and running.
|
||||
|
||||
Change-Id: Ib95f0269c6905642050be1c4d195e95919245159
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
main.go | 12 ++++++++----
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/main.go b/main.go
|
||||
index e55ff82..dcc2925 100644
|
||||
--- a/main.go
|
||||
+++ b/main.go
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/urfave/cli"
|
||||
"io"
|
||||
"log/syslog"
|
||||
+ "net"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
@@ -121,11 +122,14 @@ func main() {
|
||||
return err
|
||||
}
|
||||
logrus.SetOutput(f)
|
||||
- hook, serr := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO|syslog.LOG_USER, "docker-runc")
|
||||
- if serr != nil {
|
||||
- fmt.Fprint(f, fmt.Sprintf("Leo: new syslog hook get %s", serr))
|
||||
+ if conn, err := net.Dial("unixgram", "/run/systemd/journal/socket"); err == nil {
|
||||
+ defer conn.Close()
|
||||
+ hook, serr := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO|syslog.LOG_USER, "docker-runc")
|
||||
+ if serr != nil {
|
||||
+ fmt.Fprint(f, fmt.Sprintf("new syslog hook get %s", serr))
|
||||
+ }
|
||||
+ logrus.AddHook(hook)
|
||||
}
|
||||
- logrus.AddHook(hook)
|
||||
}
|
||||
switch context.GlobalString("log-format") {
|
||||
case "text":
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 0e92bf0..354bb24 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 13%{?dist}
|
||||
+Release: 14%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
60
patch/0076-runc-Fix-syslog-hook-bug.patch
Normal file
60
patch/0076-runc-Fix-syslog-hook-bug.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From e42b9955244945b3571aad2e2a612b827f6cafa2 Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Thu, 6 Dec 2018 21:41:59 +0800
|
||||
Subject: [PATCH 76/94] runc: Fix syslog hook bug
|
||||
|
||||
reason:If NewSyslogHook() function returns error, it indicates that
|
||||
systemd-journald service is not running, do not add this hook.
|
||||
|
||||
Change-Id: Ifd6c9a79a4055da275a8c4c867195f220b0cdffd
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
main.go | 11 ++++-------
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 5 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/main.go b/main.go
|
||||
index dcc2925..5f0ec91 100644
|
||||
--- a/main.go
|
||||
+++ b/main.go
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"github.com/urfave/cli"
|
||||
"io"
|
||||
"log/syslog"
|
||||
- "net"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
@@ -122,12 +121,10 @@ func main() {
|
||||
return err
|
||||
}
|
||||
logrus.SetOutput(f)
|
||||
- if conn, err := net.Dial("unixgram", "/run/systemd/journal/socket"); err == nil {
|
||||
- defer conn.Close()
|
||||
- hook, serr := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO|syslog.LOG_USER, "docker-runc")
|
||||
- if serr != nil {
|
||||
- fmt.Fprint(f, fmt.Sprintf("new syslog hook get %s", serr))
|
||||
- }
|
||||
+ hook, serr := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO|syslog.LOG_USER, "docker-runc")
|
||||
+ if serr != nil {
|
||||
+ fmt.Fprint(f, fmt.Sprintf("new syslog hook get %s", serr))
|
||||
+ } else {
|
||||
logrus.AddHook(hook)
|
||||
}
|
||||
}
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 354bb24..34f9d22 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 14%{?dist}
|
||||
+Release: 15%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
From 2f064ca54d3e1fcc41bc8f97c3ac8a354de34fff Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Wed, 12 Dec 2018 18:53:48 +0800
|
||||
Subject: [PATCH 77/94] runc: Require libseccomp-static lib for
|
||||
upgrade
|
||||
|
||||
reason:Require libseccomp-static lib for upgrade
|
||||
|
||||
Change-Id: Ie80603197c95ab36ce23c11c8b0807b43d0fb916
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
script/runc-euleros.spec | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 34f9d22..f21ac08 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 15%{?dist}
|
||||
+Release: 16%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
@@ -18,6 +18,7 @@ BuildRequires: make
|
||||
BuildRequires: libseccomp-devel
|
||||
BuildRequires: libselinux-devel
|
||||
|
||||
+BuildRequires: libseccomp-static
|
||||
|
||||
%description
|
||||
runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
499
patch/0078-runc-Fix-race-in-runc-exec.patch
Normal file
499
patch/0078-runc-Fix-race-in-runc-exec.patch
Normal file
@ -0,0 +1,499 @@
|
||||
From 7bef8ad8bbe3fed26c02b070b6ba09d484ec514b Mon Sep 17 00:00:00 2001
|
||||
From: wangfengtu <wangfengtu@huawei.com>
|
||||
Date: Fri, 1 Jun 2018 12:56:13 -0700
|
||||
Subject: [PATCH 78/94] runc: Fix race in runc exec
|
||||
|
||||
reason:There is a race in runc exec when the init process stops just before
|
||||
the check for the container status. It is then wrongly assumed that
|
||||
we are trying to start an init process instead of an exec process.
|
||||
|
||||
This commit add an Init field to libcontainer Process to distinguish
|
||||
between init and exec processes to prevent this race.
|
||||
|
||||
cherry-picked from upstream https://github.com/opencontainers/runc/pull/1812
|
||||
|
||||
conflicts:
|
||||
exec.go
|
||||
libcontainer/container_linux.go
|
||||
utils_linux.go
|
||||
|
||||
Change-Id: I945a5f663914e652cc117aa33885d687f70a51e4
|
||||
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
|
||||
Signed-off-by: wangfengtu <wangfengtu@huawei.com>
|
||||
---
|
||||
exec.go | 1 +
|
||||
libcontainer/container_linux.go | 29 +++++++++--------------------
|
||||
libcontainer/integration/checkpoint_test.go | 2 ++
|
||||
libcontainer/integration/exec_test.go | 19 +++++++++++++++++++
|
||||
libcontainer/integration/execin_test.go | 11 +++++++++++
|
||||
libcontainer/integration/seccomp_test.go | 3 +++
|
||||
libcontainer/integration/utils_test.go | 1 +
|
||||
libcontainer/process.go | 3 +++
|
||||
utils_linux.go | 7 +++++--
|
||||
9 files changed, 54 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/exec.go b/exec.go
|
||||
index 22f2689..9ed90ea 100644
|
||||
--- a/exec.go
|
||||
+++ b/exec.go
|
||||
@@ -135,6 +135,7 @@ func execProcess(context *cli.Context) (int, error) {
|
||||
consoleSocket: context.String("console-socket"),
|
||||
detach: detach,
|
||||
pidFile: context.String("pid-file"),
|
||||
+ init: false,
|
||||
}
|
||||
return r.run(p)
|
||||
}
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 8e0ad12..8100aca 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -197,17 +197,13 @@ func (c *linuxContainer) Set(config configs.Config) error {
|
||||
func (c *linuxContainer) Start(process *Process) error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
- status, err := c.currentStatus()
|
||||
- if err != nil {
|
||||
- return err
|
||||
- }
|
||||
- if status == Stopped {
|
||||
+ if process.Init {
|
||||
if err := c.createExecFifo(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
- if err := c.start(process, status == Stopped); err != nil {
|
||||
- if status == Stopped {
|
||||
+ if err := c.start(process); err != nil {
|
||||
+ if process.Init {
|
||||
c.deleteExecFifo()
|
||||
}
|
||||
return err
|
||||
@@ -216,17 +212,10 @@ func (c *linuxContainer) Start(process *Process) error {
|
||||
}
|
||||
|
||||
func (c *linuxContainer) Run(process *Process) error {
|
||||
- c.m.Lock()
|
||||
- status, err := c.currentStatus()
|
||||
- if err != nil {
|
||||
- c.m.Unlock()
|
||||
- return err
|
||||
- }
|
||||
- c.m.Unlock()
|
||||
if err := c.Start(process); err != nil {
|
||||
return err
|
||||
}
|
||||
- if status == Stopped {
|
||||
+ if process.Init {
|
||||
return c.exec()
|
||||
}
|
||||
return nil
|
||||
@@ -315,8 +304,8 @@ type openResult struct {
|
||||
err error
|
||||
}
|
||||
|
||||
-func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
- parent, err := c.newParentProcess(process, isInit)
|
||||
+func (c *linuxContainer) start(process *Process) error {
|
||||
+ parent, err := c.newParentProcess(process)
|
||||
if err != nil {
|
||||
return newSystemErrorWithCause(err, "creating new parent process")
|
||||
}
|
||||
@@ -329,7 +318,7 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
||||
}
|
||||
// generate a timestamp indicating when the container was started
|
||||
c.created = time.Now().UTC()
|
||||
- if isInit {
|
||||
+ if process.Init {
|
||||
c.state = &createdState{
|
||||
c: c,
|
||||
}
|
||||
@@ -409,7 +398,7 @@ func (c *linuxContainer) deleteExecFifo() {
|
||||
os.Remove(fifoName)
|
||||
}
|
||||
|
||||
-func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProcess, error) {
|
||||
+func (c *linuxContainer) newParentProcess(p *Process) (parentProcess, error) {
|
||||
parentPipe, childPipe, err := utils.NewSockPair("init")
|
||||
if err != nil {
|
||||
return nil, newSystemErrorWithCause(err, "creating new init pipe")
|
||||
@@ -418,7 +407,7 @@ func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProces
|
||||
if err != nil {
|
||||
return nil, newSystemErrorWithCause(err, "creating new command template")
|
||||
}
|
||||
- if !doInit {
|
||||
+ if !p.Init {
|
||||
return c.newSetnsProcess(p, cmd, parentPipe, childPipe)
|
||||
}
|
||||
|
||||
diff --git a/libcontainer/integration/checkpoint_test.go b/libcontainer/integration/checkpoint_test.go
|
||||
index bc5b0a3..b4d55e0 100644
|
||||
--- a/libcontainer/integration/checkpoint_test.go
|
||||
+++ b/libcontainer/integration/checkpoint_test.go
|
||||
@@ -87,6 +87,7 @@ func TestCheckpoint(t *testing.T) {
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
|
||||
err = container.Run(&pconfig)
|
||||
@@ -182,6 +183,7 @@ func TestCheckpoint(t *testing.T) {
|
||||
Cwd: "/",
|
||||
Stdin: restoreStdinR,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
|
||||
err = container.Restore(restoreProcessConfig, checkpointOpts)
|
||||
diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go
|
||||
index f3dd72a..583b04a 100644
|
||||
--- a/libcontainer/integration/exec_test.go
|
||||
+++ b/libcontainer/integration/exec_test.go
|
||||
@@ -230,6 +230,7 @@ func TestEnter(t *testing.T) {
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
stdinR.Close()
|
||||
@@ -319,6 +320,7 @@ func TestProcessEnv(t *testing.T) {
|
||||
},
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
ok(t, err)
|
||||
@@ -365,6 +367,7 @@ func TestProcessEmptyCaps(t *testing.T) {
|
||||
Env: standardEnvironment,
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
ok(t, err)
|
||||
@@ -416,6 +419,7 @@ func TestProcessCaps(t *testing.T) {
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
Capabilities: &configs.Capabilities{},
|
||||
+ Init: true,
|
||||
}
|
||||
pconfig.Capabilities.Bounding = append(config.Capabilities.Bounding, "CAP_NET_ADMIN")
|
||||
pconfig.Capabilities.Permitted = append(config.Capabilities.Permitted, "CAP_NET_ADMIN")
|
||||
@@ -490,6 +494,7 @@ func TestAdditionalGroups(t *testing.T) {
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
AdditionalGroups: []string{"plugdev", "audio"},
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
ok(t, err)
|
||||
@@ -550,6 +555,7 @@ func testFreeze(t *testing.T, systemd bool) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(pconfig)
|
||||
stdinR.Close()
|
||||
@@ -761,6 +767,7 @@ func TestContainerState(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(p)
|
||||
if err != nil {
|
||||
@@ -814,6 +821,7 @@ func TestPassExtraFiles(t *testing.T) {
|
||||
ExtraFiles: []*os.File{pipein1, pipein2},
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&process)
|
||||
if err != nil {
|
||||
@@ -895,6 +903,7 @@ func TestMountCmds(t *testing.T) {
|
||||
Cwd: "/",
|
||||
Args: []string{"sh", "-c", "env"},
|
||||
Env: standardEnvironment,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
if err != nil {
|
||||
@@ -944,6 +953,7 @@ func TestSysctl(t *testing.T) {
|
||||
Env: standardEnvironment,
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
ok(t, err)
|
||||
@@ -1084,6 +1094,7 @@ func TestOomScoreAdj(t *testing.T) {
|
||||
Env: standardEnvironment,
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
ok(t, err)
|
||||
@@ -1189,6 +1200,7 @@ func TestHook(t *testing.T) {
|
||||
Env: standardEnvironment,
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
ok(t, err)
|
||||
@@ -1305,6 +1317,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
|
||||
err = container.Run(pconfig)
|
||||
@@ -1422,6 +1435,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
|
||||
err = container.Run(pconfig)
|
||||
@@ -1530,6 +1544,7 @@ func TestInitJoinPID(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR1,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container1.Run(init1)
|
||||
stdinR1.Close()
|
||||
@@ -1556,6 +1571,7 @@ func TestInitJoinPID(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR2,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container2.Run(init2)
|
||||
stdinR2.Close()
|
||||
@@ -1635,6 +1651,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR1,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container1.Run(init1)
|
||||
stdinR1.Close()
|
||||
@@ -1669,6 +1686,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR2,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container2.Run(init2)
|
||||
stdinR2.Close()
|
||||
@@ -1736,6 +1754,7 @@ func TestTmpfsCopyUp(t *testing.T) {
|
||||
Env: standardEnvironment,
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(&pconfig)
|
||||
ok(t, err)
|
||||
diff --git a/libcontainer/integration/execin_test.go b/libcontainer/integration/execin_test.go
|
||||
index f06075e..988b667 100644
|
||||
--- a/libcontainer/integration/execin_test.go
|
||||
+++ b/libcontainer/integration/execin_test.go
|
||||
@@ -36,6 +36,7 @@ func TestExecIn(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
@@ -103,6 +104,7 @@ func testExecInRlimit(t *testing.T, userns bool) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
@@ -121,6 +123,7 @@ func testExecInRlimit(t *testing.T, userns bool) {
|
||||
// increase process rlimit higher than container rlimit to test per-process limit
|
||||
{Type: syscall.RLIMIT_NOFILE, Hard: 1026, Soft: 1026},
|
||||
},
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(ps)
|
||||
ok(t, err)
|
||||
@@ -157,6 +160,7 @@ func TestExecInAdditionalGroups(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
@@ -213,6 +217,7 @@ func TestExecInError(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
@@ -265,6 +270,7 @@ func TestExecInTTY(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
@@ -349,6 +355,7 @@ func TestExecInEnvironment(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
@@ -368,6 +375,7 @@ func TestExecInEnvironment(t *testing.T) {
|
||||
Stdin: buffers.Stdin,
|
||||
Stdout: buffers.Stdout,
|
||||
Stderr: buffers.Stderr,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process2)
|
||||
ok(t, err)
|
||||
@@ -413,6 +421,7 @@ func TestExecinPassExtraFiles(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
@@ -486,6 +495,7 @@ func TestExecInOomScoreAdj(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
@@ -541,6 +551,7 @@ func TestExecInUserns(t *testing.T) {
|
||||
Args: []string{"cat"},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR,
|
||||
+ Init: true,
|
||||
}
|
||||
err = container.Run(process)
|
||||
stdinR.Close()
|
||||
diff --git a/libcontainer/integration/seccomp_test.go b/libcontainer/integration/seccomp_test.go
|
||||
index 055f887..8e2c7cd 100644
|
||||
--- a/libcontainer/integration/seccomp_test.go
|
||||
+++ b/libcontainer/integration/seccomp_test.go
|
||||
@@ -48,6 +48,7 @@ func TestSeccompDenyGetcwd(t *testing.T) {
|
||||
Stdin: buffers.Stdin,
|
||||
Stdout: buffers.Stdout,
|
||||
Stderr: buffers.Stderr,
|
||||
+ Init: true,
|
||||
}
|
||||
|
||||
err = container.Run(pwd)
|
||||
@@ -123,6 +124,7 @@ func TestSeccompPermitWriteConditional(t *testing.T) {
|
||||
Stdin: buffers.Stdin,
|
||||
Stdout: buffers.Stdout,
|
||||
Stderr: buffers.Stderr,
|
||||
+ Init: true,
|
||||
}
|
||||
|
||||
err = container.Run(dmesg)
|
||||
@@ -184,6 +186,7 @@ func TestSeccompDenyWriteConditional(t *testing.T) {
|
||||
Stdin: buffers.Stdin,
|
||||
Stdout: buffers.Stdout,
|
||||
Stderr: buffers.Stderr,
|
||||
+ Init: true,
|
||||
}
|
||||
|
||||
err = container.Run(dmesg)
|
||||
diff --git a/libcontainer/integration/utils_test.go b/libcontainer/integration/utils_test.go
|
||||
index 74d9413..dc6a4d8 100644
|
||||
--- a/libcontainer/integration/utils_test.go
|
||||
+++ b/libcontainer/integration/utils_test.go
|
||||
@@ -148,6 +148,7 @@ func runContainer(config *configs.Config, console string, args ...string) (buffe
|
||||
Stdin: buffers.Stdin,
|
||||
Stdout: buffers.Stdout,
|
||||
Stderr: buffers.Stderr,
|
||||
+ Init: true,
|
||||
}
|
||||
|
||||
err = container.Run(process)
|
||||
diff --git a/libcontainer/process.go b/libcontainer/process.go
|
||||
index f1ad081..150510d 100644
|
||||
--- a/libcontainer/process.go
|
||||
+++ b/libcontainer/process.go
|
||||
@@ -68,6 +68,9 @@ type Process struct {
|
||||
// ConsoleSocket provides the masterfd console.
|
||||
ConsoleSocket *os.File
|
||||
|
||||
+ // Init specifies whether the process is the first process in the container.
|
||||
+ Init bool
|
||||
+
|
||||
ops processOperations
|
||||
}
|
||||
|
||||
diff --git a/utils_linux.go b/utils_linux.go
|
||||
index c6a8c02..df98cf9 100644
|
||||
--- a/utils_linux.go
|
||||
+++ b/utils_linux.go
|
||||
@@ -72,7 +72,7 @@ func getDefaultImagePath(context *cli.Context) string {
|
||||
|
||||
// newProcess returns a new libcontainer Process with the arguments from the
|
||||
// spec and stdio from the current process.
|
||||
-func newProcess(p specs.Process) (*libcontainer.Process, error) {
|
||||
+func newProcess(p specs.Process, init bool) (*libcontainer.Process, error) {
|
||||
lp := &libcontainer.Process{
|
||||
Args: p.Args,
|
||||
Env: p.Env,
|
||||
@@ -82,6 +82,7 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) {
|
||||
Label: p.SelinuxLabel,
|
||||
NoNewPrivileges: &p.NoNewPrivileges,
|
||||
AppArmorProfile: p.ApparmorProfile,
|
||||
+ Init: init,
|
||||
}
|
||||
if p.Capabilities != nil {
|
||||
lp.Capabilities = &configs.Capabilities{}
|
||||
@@ -212,6 +213,7 @@ func createContainer(context *cli.Context, id string, spec *specs.Spec) (libcont
|
||||
}
|
||||
|
||||
type runner struct {
|
||||
+ init bool
|
||||
enableSubreaper bool
|
||||
shouldDestroy bool
|
||||
detach bool
|
||||
@@ -229,7 +231,7 @@ func (r *runner) run(config *specs.Process) (int, error) {
|
||||
r.destroy()
|
||||
return -1, err
|
||||
}
|
||||
- process, err := newProcess(*config)
|
||||
+ process, err := newProcess(*config, r.init)
|
||||
if err != nil {
|
||||
r.destroy()
|
||||
return -1, err
|
||||
@@ -373,6 +375,7 @@ func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, e
|
||||
pidFile: context.String("pid-file"),
|
||||
preserveFDs: context.Int("preserve-fds"),
|
||||
create: create,
|
||||
+ init: true,
|
||||
}
|
||||
return r.run(&spec.Process)
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
29
patch/0079-runc-modify-spec-file-for-upgrade.patch
Normal file
29
patch/0079-runc-modify-spec-file-for-upgrade.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From 912f3b9001459f118fd85f04d7614cbaaa1c351b Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Tue, 25 Dec 2018 19:13:32 +0800
|
||||
Subject: [PATCH 79/94] runc: modify spec file for upgrade
|
||||
|
||||
reason:modify spec file for upgrade
|
||||
|
||||
Change-Id: Ifad62b1e80bf67bb0a043bdd98e5ac03233727f5
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
script/runc-euleros.spec | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index f21ac08..faccbf6 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 16%{?dist}
|
||||
+Release: 17%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
73
patch/0080-runc-support-specify-umask.patch
Normal file
73
patch/0080-runc-support-specify-umask.patch
Normal file
@ -0,0 +1,73 @@
|
||||
From 18f5c5e20e342af002b0edb2295f64ea12632cc4 Mon Sep 17 00:00:00 2001
|
||||
From: wangfengtu <wangfengtu@huawei.com>
|
||||
Date: Fri, 21 Dec 2018 15:02:16 +0800
|
||||
Subject: [PATCH 80/94] runc: support specify umask
|
||||
|
||||
reason:support specify umask.
|
||||
Umask can be 0022 or 0027(default) by specify umask when
|
||||
start container by command `docker create/run` or start
|
||||
daemon by command `dockerd`. For example:
|
||||
$ dockerd --annotation native.umask=normal
|
||||
$ dockerd --annotation native.umask=secure
|
||||
$ docker run --exec-opt native.umask=normal
|
||||
$ docker run --exec-opt native.umask=secure
|
||||
`normal` reparent umask is 0022, `secure`
|
||||
reparent umask is 0027.
|
||||
|
||||
Change-Id: I49166759ad42dca0ac1f9755f85592e93951c249
|
||||
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||||
Signed-off-by: wangfengtu <wangfengtu@huawei.com>
|
||||
---
|
||||
libcontainer/rootfs_linux.go | 7 ++++++-
|
||||
libcontainer/setns_init_linux.go | 10 ++++++++--
|
||||
2 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index 38bdd1b..3dd5113 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -136,7 +136,12 @@ func finalizeRootfs(config *configs.Config) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
- syscall.Umask(0027)
|
||||
+ umask := libcontainerUtils.SearchLabels(config.Labels, "native.umask")
|
||||
+ if umask == "normal" {
|
||||
+ syscall.Umask(0022)
|
||||
+ } else {
|
||||
+ syscall.Umask(0027)
|
||||
+ }
|
||||
return nil
|
||||
}
|
||||
|
||||
diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go
|
||||
index e8e969a..b3fab21 100644
|
||||
--- a/libcontainer/setns_init_linux.go
|
||||
+++ b/libcontainer/setns_init_linux.go
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/keys"
|
||||
"github.com/opencontainers/runc/libcontainer/seccomp"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
+ "github.com/opencontainers/runc/libcontainer/utils"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
@@ -41,8 +42,13 @@ func (l *linuxSetnsInit) Init() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
- // set exec process umask to 0027 according to secure policy
|
||||
- syscall.Umask(0027)
|
||||
+ // set exec process umask to 0027 or 0022 according to container's config
|
||||
+ umask := utils.SearchLabels(l.config.Config.Labels, "native.umask")
|
||||
+ if umask == "normal" {
|
||||
+ syscall.Umask(0022)
|
||||
+ } else {
|
||||
+ syscall.Umask(0027)
|
||||
+ }
|
||||
if l.config.NoNewPrivileges {
|
||||
if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
|
||||
return err
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
151
patch/0081-runc-fix-oom-killer-disable-unhandled-due-t.patch
Normal file
151
patch/0081-runc-fix-oom-killer-disable-unhandled-due-t.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From 1948bc88664ef018f87bd16c004ea2de32be3ec3 Mon Sep 17 00:00:00 2001
|
||||
From: caihaomin <caihaomin@huawei.com>
|
||||
Date: Mon, 21 Jan 2019 13:50:35 +0800
|
||||
Subject: [PATCH 81/94] runc: fix oom-killer-disable unhandled due to
|
||||
the spec
|
||||
|
||||
reason:fix oom-killer-disable unhandled due to the spec
|
||||
|
||||
Change-Id: I646b0420f8c387906afb80536352259ec1482729
|
||||
Signed-off-by: caihaomin <caihaomin@huawei.com>
|
||||
---
|
||||
spec.go | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 83 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/spec.go b/spec.go
|
||||
index a15c84e..b33e44c 100644
|
||||
--- a/spec.go
|
||||
+++ b/spec.go
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
- "runtime"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/specconv"
|
||||
@@ -117,24 +116,101 @@ generate a proper rootless spec file.`,
|
||||
|
||||
func sPtr(s string) *string { return &s }
|
||||
|
||||
+type compatSpec struct {
|
||||
+ specs.Spec
|
||||
+ Linux *linux `json:"linux,omitempty" platform:"linux"`
|
||||
+}
|
||||
+
|
||||
+type linux struct {
|
||||
+ specs.Linux
|
||||
+ Resources *linuxResources `json:"resources,omitempty"`
|
||||
+}
|
||||
+
|
||||
+type linuxResources struct {
|
||||
+ specs.LinuxResources
|
||||
+ Memory *linuxMemory `json:"memory,omitempty"`
|
||||
+}
|
||||
+
|
||||
+type linuxMemory struct {
|
||||
+ // Memory limit (in bytes).
|
||||
+ Limit *int64 `json:"limit,omitempty"`
|
||||
+ // Memory reservation or soft_limit (in bytes).
|
||||
+ Reservation *int64 `json:"reservation,omitempty"`
|
||||
+ // Total memory limit (memory + swap).
|
||||
+ Swap *int64 `json:"swap,omitempty"`
|
||||
+ // Kernel memory limit (in bytes).
|
||||
+ Kernel *int64 `json:"kernel,omitempty"`
|
||||
+ // Kernel memory limit for tcp (in bytes)
|
||||
+ KernelTCP *int64 `json:"kernelTCP,omitempty"`
|
||||
+ // How aggressive the kernel will swap memory pages.
|
||||
+ Swappiness *uint64 `json:"swappiness,omitempty"`
|
||||
+ // DisableOOMKiller disables the OOM killer for out of memory conditions
|
||||
+ DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
|
||||
+}
|
||||
+
|
||||
// loadSpec loads the specification from the provided path.
|
||||
func loadSpec(cPath string) (spec *specs.Spec, err error) {
|
||||
- cf, err := os.Open(cPath)
|
||||
- if err != nil {
|
||||
+ spec, err = loadOriginSpec(cPath)
|
||||
+ if err != nil || spec.Linux.Resources.DisableOOMKiller == nil {
|
||||
+ return loadCompactSpec(cPath)
|
||||
+ }
|
||||
+
|
||||
+ return spec, validateProcessSpec(&spec.Process)
|
||||
+}
|
||||
+
|
||||
+func loadOriginSpec(cPath string) (*specs.Spec, error) {
|
||||
+ var spec specs.Spec
|
||||
+ if _, err := os.Stat(cPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("JSON specification file %s not found", cPath)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
- defer cf.Close()
|
||||
|
||||
- if err = json.NewDecoder(cf).Decode(&spec); err != nil {
|
||||
+ cData, err := ioutil.ReadFile(cPath)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ if err := json.Unmarshal(cData, &spec); err != nil {
|
||||
+ return nil, fmt.Errorf("config.json %q error :%v", cPath, err)
|
||||
+ }
|
||||
+
|
||||
+ return &spec, nil
|
||||
+}
|
||||
+
|
||||
+func loadCompactSpec(cPath string) (*specs.Spec, error) {
|
||||
+ var compatSpec compatSpec
|
||||
+ cData, err := ioutil.ReadFile(cPath)
|
||||
+ if err != nil {
|
||||
+ if os.IsNotExist(err) {
|
||||
+ return nil, fmt.Errorf("JSON specification file %s not found", cPath)
|
||||
+ }
|
||||
return nil, err
|
||||
}
|
||||
- if err = validatePlatform(&spec.Platform); err != nil {
|
||||
+ if err := json.Unmarshal(cData, &compatSpec); err != nil {
|
||||
+ return nil, fmt.Errorf("config.json %q error :%v", cPath, err)
|
||||
+ }
|
||||
+
|
||||
+ var spec *specs.Spec
|
||||
+ if spec, err = updateCompactSpec(&compatSpec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
- return spec, validateProcessSpec(&spec.Process)
|
||||
+
|
||||
+ return spec, nil
|
||||
+
|
||||
+}
|
||||
+
|
||||
+func updateCompactSpec(compatSpec *compatSpec) (*specs.Spec, error) {
|
||||
+ compatjson, _ := json.Marshal(compatSpec)
|
||||
+ var spec specs.Spec
|
||||
+ err := json.Unmarshal(compatjson, &spec)
|
||||
+ if err != nil {
|
||||
+ return nil, fmt.Errorf("update config failed %v", err)
|
||||
+ }
|
||||
+
|
||||
+ spec.Linux.Resources.DisableOOMKiller = compatSpec.Linux.Resources.Memory.DisableOOMKiller
|
||||
+
|
||||
+ return &spec, nil
|
||||
}
|
||||
|
||||
func createLibContainerRlimit(rlimit specs.LinuxRlimit) (configs.Rlimit, error) {
|
||||
@@ -148,13 +224,3 @@ func createLibContainerRlimit(rlimit specs.LinuxRlimit) (configs.Rlimit, error)
|
||||
Soft: rlimit.Soft,
|
||||
}, nil
|
||||
}
|
||||
-
|
||||
-func validatePlatform(platform *specs.Platform) error {
|
||||
- if platform.OS != runtime.GOOS {
|
||||
- return fmt.Errorf("target os %s mismatch with current os %s", platform.OS, runtime.GOOS)
|
||||
- }
|
||||
- if platform.Arch != runtime.GOARCH {
|
||||
- return fmt.Errorf("target arch %s mismatch with current arch %s", platform.Arch, runtime.GOARCH)
|
||||
- }
|
||||
- return nil
|
||||
-}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
118
patch/0082-runc-make-runc-spec-and-docker-18.9-compati.patch
Normal file
118
patch/0082-runc-make-runc-spec-and-docker-18.9-compati.patch
Normal file
@ -0,0 +1,118 @@
|
||||
From e8e1ec218358495648893370e19eec093681766d Mon Sep 17 00:00:00 2001
|
||||
From: leizhongkai <leizhongkai@huawei.com>
|
||||
Date: Thu, 24 Jan 2019 20:18:14 +0800
|
||||
Subject: [PATCH 82/94] runc: make runc spec and docker-18.9
|
||||
compatible
|
||||
|
||||
reason:make runc spec and docker-18.9 compatible
|
||||
|
||||
Change-Id: I794c936579a4decc1d0cd92e3483c6378dba5bfd
|
||||
Signed-off-by: leizhongkai <leizhongkai@huawei.com>
|
||||
---
|
||||
spec.go | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 75 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/spec.go b/spec.go
|
||||
index b33e44c..0bbe967 100644
|
||||
--- a/spec.go
|
||||
+++ b/spec.go
|
||||
@@ -121,6 +121,30 @@ type compatSpec struct {
|
||||
Linux *linux `json:"linux,omitempty" platform:"linux"`
|
||||
}
|
||||
|
||||
+// linuxBlockIODevice holds major:minor format supported in blkio cgroup
|
||||
+type linuxBlockIODevice struct {
|
||||
+ // Major is the device's major number.
|
||||
+ Major int64 `json:"major"`
|
||||
+ // Minor is the device's minor number.
|
||||
+ Minor int64 `json:"minor"`
|
||||
+}
|
||||
+
|
||||
+// LinuxWeightDevice struct holds a `major:minor weight` pair for blkioWeightDevice
|
||||
+type LinuxWeightDevice struct {
|
||||
+ linuxBlockIODevice
|
||||
+ // Weight is the bandwidth rate for the device, range is from 10 to 1000
|
||||
+ Weight *uint16 `json:"weight,omitempty"`
|
||||
+ // LeafWeight is the bandwidth rate for the device while competing with the cgroup's child cgroups, range is from 10 to 1000, CFQ scheduler only
|
||||
+ LeafWeight *uint16 `json:"leafWeight,omitempty"`
|
||||
+}
|
||||
+
|
||||
+// LinuxThrottleDevice struct holds a `major:minor rate_per_second` pair
|
||||
+type LinuxThrottleDevice struct {
|
||||
+ linuxBlockIODevice
|
||||
+ // Rate is the IO rate limit per cgroup per device
|
||||
+ Rate uint64 `json:"rate"`
|
||||
+}
|
||||
+
|
||||
type linux struct {
|
||||
specs.Linux
|
||||
Resources *linuxResources `json:"resources,omitempty"`
|
||||
@@ -128,7 +152,26 @@ type linux struct {
|
||||
|
||||
type linuxResources struct {
|
||||
specs.LinuxResources
|
||||
- Memory *linuxMemory `json:"memory,omitempty"`
|
||||
+ Memory *linuxMemory `json:"memory,omitempty"`
|
||||
+ BlockIO *LinuxBlockIO `json:"blockIO,omitempty"`
|
||||
+}
|
||||
+
|
||||
+// LinuxBlockIO for Linux cgroup 'blkio' resource management
|
||||
+type LinuxBlockIO struct {
|
||||
+ // Specifies per cgroup weight
|
||||
+ Weight *uint16 `json:"weight,omitempty"`
|
||||
+ // Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, CFQ scheduler only
|
||||
+ LeafWeight *uint16 `json:"leafWeight,omitempty"`
|
||||
+ // Weight per cgroup per device, can override BlkioWeight
|
||||
+ WeightDevice []LinuxWeightDevice `json:"weightDevice,omitempty"`
|
||||
+ // IO read rate limit per cgroup per device, bytes per second
|
||||
+ ThrottleReadBpsDevice []LinuxThrottleDevice `json:"throttleReadBpsDevice,omitempty"`
|
||||
+ // IO write rate limit per cgroup per device, bytes per second
|
||||
+ ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"throttleWriteBpsDevice,omitempty"`
|
||||
+ // IO read rate limit per cgroup per device, IO per second
|
||||
+ ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"throttleReadIOPSDevice,omitempty"`
|
||||
+ // IO write rate limit per cgroup per device, IO per second
|
||||
+ ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"throttleWriteIOPSDevice,omitempty"`
|
||||
}
|
||||
|
||||
type linuxMemory struct {
|
||||
@@ -209,6 +252,37 @@ func updateCompactSpec(compatSpec *compatSpec) (*specs.Spec, error) {
|
||||
}
|
||||
|
||||
spec.Linux.Resources.DisableOOMKiller = compatSpec.Linux.Resources.Memory.DisableOOMKiller
|
||||
+ if compatSpec.Linux.Resources.BlockIO != nil {
|
||||
+ spec.Linux.Resources.BlockIO.Weight = compatSpec.Linux.Resources.BlockIO.Weight
|
||||
+ spec.Linux.Resources.BlockIO.LeafWeight = compatSpec.Linux.Resources.BlockIO.LeafWeight
|
||||
+ if compatSpec.Linux.Resources.BlockIO.WeightDevice != nil {
|
||||
+ for _, wd := range compatSpec.Linux.Resources.BlockIO.WeightDevice {
|
||||
+ wdSpec := specs.LinuxWeightDevice{
|
||||
+ Weight: wd.Weight,
|
||||
+ LeafWeight: wd.LeafWeight,
|
||||
+ }
|
||||
+ wdSpec.Major = wd.Major
|
||||
+ wdSpec.Minor = wd.Minor
|
||||
+ spec.Linux.Resources.BlockIO.WeightDevice = append(spec.Linux.Resources.BlockIO.WeightDevice, wdSpec)
|
||||
+ }
|
||||
+ }
|
||||
+ procLinuxThrottleDevice := func(src []LinuxThrottleDevice, dest *[]specs.LinuxThrottleDevice) {
|
||||
+ if src != nil {
|
||||
+ for _, ltd := range src {
|
||||
+ ltdSpec := specs.LinuxThrottleDevice{
|
||||
+ Rate: ltd.Rate,
|
||||
+ }
|
||||
+ ltdSpec.Major = ltd.Major
|
||||
+ ltdSpec.Minor = ltd.Minor
|
||||
+ *dest = append(*dest, ltdSpec)
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ procLinuxThrottleDevice(compatSpec.Linux.Resources.BlockIO.ThrottleReadBpsDevice, &spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice)
|
||||
+ procLinuxThrottleDevice(compatSpec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, &spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice)
|
||||
+ procLinuxThrottleDevice(compatSpec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, &spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice)
|
||||
+ procLinuxThrottleDevice(compatSpec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, &spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice)
|
||||
+ }
|
||||
|
||||
return &spec, nil
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
74
patch/0083-log-fix-runc-log-decode-failed.patch
Normal file
74
patch/0083-log-fix-runc-log-decode-failed.patch
Normal file
@ -0,0 +1,74 @@
|
||||
From 52e08b0e3d4e44d555efde15a4ab698500d060db Mon Sep 17 00:00:00 2001
|
||||
From: jingrui <jingrui@huawei.com>
|
||||
Date: Tue, 15 Jan 2019 15:16:54 +0800
|
||||
Subject: [PATCH 83/94] log: fix runc log decode failed
|
||||
|
||||
reason: plain logs can not parsed by containerd, using json formatted
|
||||
error logs.
|
||||
|
||||
Change-Id: I293454c038c3b4f36a8ac9df07fc3557c51179e1
|
||||
Signed-off-by: jingrui <jingrui@huawei.com>
|
||||
---
|
||||
main.go | 30 +++++++++++++++++++++++++-----
|
||||
1 file changed, 25 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/main.go b/main.go
|
||||
index 5f0ec91..0476242 100644
|
||||
--- a/main.go
|
||||
+++ b/main.go
|
||||
@@ -1,15 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
+ "encoding/json"
|
||||
"fmt"
|
||||
- "github.com/Sirupsen/logrus"
|
||||
- "github.com/Sirupsen/logrus/hooks/syslog"
|
||||
- "github.com/opencontainers/runtime-spec/specs-go"
|
||||
- "github.com/urfave/cli"
|
||||
"io"
|
||||
"log/syslog"
|
||||
"os"
|
||||
"strings"
|
||||
+ "time"
|
||||
+
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
+ "github.com/Sirupsen/logrus/hooks/syslog"
|
||||
+ "github.com/opencontainers/runtime-spec/specs-go"
|
||||
+ "github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// version will be populated by the Makefile, read from
|
||||
@@ -123,7 +126,7 @@ func main() {
|
||||
logrus.SetOutput(f)
|
||||
hook, serr := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO|syslog.LOG_USER, "docker-runc")
|
||||
if serr != nil {
|
||||
- fmt.Fprint(f, fmt.Sprintf("new syslog hook get %s", serr))
|
||||
+ logToFile(f, "error", fmt.Sprintf("new syslog hook get %s", serr))
|
||||
} else {
|
||||
logrus.AddHook(hook)
|
||||
}
|
||||
@@ -167,3 +170,20 @@ func (f *FatalWriter) Write(p []byte) (n int, err error) {
|
||||
logrus.Error(string(p))
|
||||
return f.cliErrWriter.Write(p)
|
||||
}
|
||||
+
|
||||
+func logToFile(f io.Writer, level string, msg string) {
|
||||
+ var (
|
||||
+ log struct {
|
||||
+ Level string
|
||||
+ Msg string
|
||||
+ Time time.Time
|
||||
+ }
|
||||
+ )
|
||||
+ log.Level = level
|
||||
+ log.Msg = msg
|
||||
+ log.Time = time.Now()
|
||||
+ s, err := json.Marshal(log)
|
||||
+ if err != nil {
|
||||
+ fmt.Fprint(f, string(s))
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
108
patch/0084-oci-fix-runc-panic-and-support-oom-score.patch
Normal file
108
patch/0084-oci-fix-runc-panic-and-support-oom-score.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 19106da5ad20c3b46888a75b08c00d0b0b12e13b Mon Sep 17 00:00:00 2001
|
||||
From: jingrui <jingrui@huawei.com>
|
||||
Date: Wed, 23 Jan 2019 22:40:51 +0800
|
||||
Subject: [PATCH 84/94] oci: fix runc panic and support oom score
|
||||
|
||||
reason: see below.
|
||||
|
||||
1. docker plugin using simple spec, should add more check to avoid runc
|
||||
panic.
|
||||
2. add oom-score support.
|
||||
|
||||
Change-Id: I0999c8f61209e8127390508577034446d9ae1b4f
|
||||
Signed-off-by: jingrui <jingrui@huawei.com>
|
||||
---
|
||||
script/runc-euleros.spec | 2 +-
|
||||
spec.go | 39 ++++++++++++++++++++++++++++++++++++---
|
||||
2 files changed, 37 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index faccbf6..bcbcff1 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 17%{?dist}
|
||||
+Release: 18%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
diff --git a/spec.go b/spec.go
|
||||
index 0bbe967..3b90791 100644
|
||||
--- a/spec.go
|
||||
+++ b/spec.go
|
||||
@@ -118,7 +118,8 @@ func sPtr(s string) *string { return &s }
|
||||
|
||||
type compatSpec struct {
|
||||
specs.Spec
|
||||
- Linux *linux `json:"linux,omitempty" platform:"linux"`
|
||||
+ Linux *linux `json:"linux,omitempty" platform:"linux"`
|
||||
+ Process processRc6 `json:"process"`
|
||||
}
|
||||
|
||||
// linuxBlockIODevice holds major:minor format supported in blkio cgroup
|
||||
@@ -150,6 +151,11 @@ type linux struct {
|
||||
Resources *linuxResources `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
+type processRc6 struct {
|
||||
+ specs.Process
|
||||
+ OOMScoreAdj *int `json:"oomScoreAdj,omitempty" platform:"linux"`
|
||||
+}
|
||||
+
|
||||
type linuxResources struct {
|
||||
specs.LinuxResources
|
||||
Memory *linuxMemory `json:"memory,omitempty"`
|
||||
@@ -191,10 +197,26 @@ type linuxMemory struct {
|
||||
DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
|
||||
}
|
||||
|
||||
+func versionRc6Plus(ver string) bool {
|
||||
+ if len(ver) < 5 { // version should be a.b.c[-rcn][x]
|
||||
+ return false
|
||||
+ }
|
||||
+
|
||||
+ // docker-18.09 1.0.1
|
||||
+ if ver[:5] >= "1.0.1" {
|
||||
+ return true
|
||||
+ }
|
||||
+
|
||||
+ // TODO: add more version detect, support ab.cd.ef format.
|
||||
+
|
||||
+ // < 1.0.0-rc6: include 1.0.0-rc5xxx
|
||||
+ return false
|
||||
+}
|
||||
+
|
||||
// loadSpec loads the specification from the provided path.
|
||||
func loadSpec(cPath string) (spec *specs.Spec, err error) {
|
||||
spec, err = loadOriginSpec(cPath)
|
||||
- if err != nil || spec.Linux.Resources.DisableOOMKiller == nil {
|
||||
+ if err != nil || versionRc6Plus(spec.Version) {
|
||||
return loadCompactSpec(cPath)
|
||||
}
|
||||
|
||||
@@ -251,7 +273,18 @@ func updateCompactSpec(compatSpec *compatSpec) (*specs.Spec, error) {
|
||||
return nil, fmt.Errorf("update config failed %v", err)
|
||||
}
|
||||
|
||||
- spec.Linux.Resources.DisableOOMKiller = compatSpec.Linux.Resources.Memory.DisableOOMKiller
|
||||
+ if compatSpec != nil && compatSpec.Linux != nil &&
|
||||
+ compatSpec.Linux.Resources != nil &&
|
||||
+ compatSpec.Linux.Resources.Memory != nil &&
|
||||
+ compatSpec.Linux.Resources.Memory.DisableOOMKiller != nil {
|
||||
+ spec.Linux.Resources.DisableOOMKiller = compatSpec.Linux.Resources.Memory.DisableOOMKiller
|
||||
+ }
|
||||
+
|
||||
+ if compatSpec != nil && compatSpec.Process.OOMScoreAdj != nil &&
|
||||
+ spec.Linux != nil && spec.Linux.Resources != nil {
|
||||
+ spec.Linux.Resources.OOMScoreAdj = compatSpec.Process.OOMScoreAdj
|
||||
+ }
|
||||
+
|
||||
if compatSpec.Linux.Resources.BlockIO != nil {
|
||||
spec.Linux.Resources.BlockIO.Weight = compatSpec.Linux.Resources.BlockIO.Weight
|
||||
spec.Linux.Resources.BlockIO.LeafWeight = compatSpec.Linux.Resources.BlockIO.LeafWeight
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From 9421de9838d904c5eea40f0bd0cd50a00157392f Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Mon, 5 Mar 2018 21:15:15 +0800
|
||||
Subject: [PATCH 85/94] runc: do not setup sysctl in runc when userns
|
||||
enabled
|
||||
|
||||
reason:when userns enabled, runc will run as normal user, it has
|
||||
no rights to setup sysctl even the ipcns sysctl. let docker-hooks do this job.
|
||||
|
||||
Change-Id: Ia77b8c1bf4255973736f04c0962eae722ed9683e
|
||||
Signed-off-by: gus.gao <gus.gao@huawei.com>
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
libcontainer/standard_init_linux.go | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go
|
||||
index 18506af..fd836f3 100644
|
||||
--- a/libcontainer/standard_init_linux.go
|
||||
+++ b/libcontainer/standard_init_linux.go
|
||||
@@ -107,10 +107,12 @@ func (l *linuxStandardInit) Init() error {
|
||||
if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
|
||||
return err
|
||||
}
|
||||
-
|
||||
- for key, value := range l.config.Config.Sysctl {
|
||||
- if err := writeSystemProperty(key, value); err != nil {
|
||||
- return err
|
||||
+ // when userns enabled, write to sysctl will fail, let docker-hooks do this job
|
||||
+ if len(l.config.Config.UidMappings) == 0 && len(l.config.Config.GidMappings) == 0 {
|
||||
+ for key, value := range l.config.Config.Sysctl {
|
||||
+ if err := writeSystemProperty(key, value); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
}
|
||||
}
|
||||
for _, path := range l.config.Config.ReadonlyPaths {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
68
patch/0086-runc-support-set-seccomp-priority.patch
Normal file
68
patch/0086-runc-support-set-seccomp-priority.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From f0cff0f9ff831b2380d6907ac1b640eb998c4d88 Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Wed, 30 Jan 2019 15:33:44 +0800
|
||||
Subject: [PATCH 86/94] runc: support set seccomp priority
|
||||
|
||||
reason:support set seccomp priority
|
||||
|
||||
Change-Id: I73ea0ca4ce5dc7af975c62b56edbae03f9721e76
|
||||
Signed-off-by: gus.gao <gus.gao@huawei.com>
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
libcontainer/configs/config.go | 7 ++++---
|
||||
libcontainer/seccomp/seccomp_linux.go | 2 +-
|
||||
libcontainer/specconv/spec_linux.go | 7 ++++---
|
||||
3 files changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go
|
||||
index 78a7d1d..9074c86 100644
|
||||
--- a/libcontainer/configs/config.go
|
||||
+++ b/libcontainer/configs/config.go
|
||||
@@ -76,9 +76,10 @@ type Arg struct {
|
||||
|
||||
// Syscall is a rule to match a syscall in Seccomp
|
||||
type Syscall struct {
|
||||
- Name string `json:"name"`
|
||||
- Action Action `json:"action"`
|
||||
- Args []*Arg `json:"args"`
|
||||
+ Name string `json:"name"`
|
||||
+ Action Action `json:"action"`
|
||||
+ Priority uint8 `json:"priority,omitempty"`
|
||||
+ Args []*Arg `json:"args"`
|
||||
}
|
||||
|
||||
// TODO Windows. Many of these fields should be factored out into those parts
|
||||
diff --git a/libcontainer/seccomp/seccomp_linux.go b/libcontainer/seccomp/seccomp_linux.go
|
||||
index 518d2c3..db4bb4e 100644
|
||||
--- a/libcontainer/seccomp/seccomp_linux.go
|
||||
+++ b/libcontainer/seccomp/seccomp_linux.go
|
||||
@@ -198,7 +198,7 @@ func matchCall(filter *libseccomp.ScmpFilter, call *configs.Syscall) error {
|
||||
}
|
||||
}
|
||||
|
||||
- return nil
|
||||
+ return filter.SetSyscallPriority(callNum, call.Priority)
|
||||
}
|
||||
|
||||
func parseStatusFile(path string) (map[string]string, error) {
|
||||
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
|
||||
index a8cf114..8c4567c 100644
|
||||
--- a/libcontainer/specconv/spec_linux.go
|
||||
+++ b/libcontainer/specconv/spec_linux.go
|
||||
@@ -757,9 +757,10 @@ func setupSeccomp(config *specs.LinuxSeccomp) (*configs.Seccomp, error) {
|
||||
|
||||
for _, name := range call.Names {
|
||||
newCall := configs.Syscall{
|
||||
- Name: name,
|
||||
- Action: newAction,
|
||||
- Args: []*configs.Arg{},
|
||||
+ Name: name,
|
||||
+ Action: newAction,
|
||||
+ Priority: call.Priority,
|
||||
+ Args: []*configs.Arg{},
|
||||
}
|
||||
// Loop through all the arguments of the syscall and convert them
|
||||
for _, arg := range call.Args {
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
48
patch/0087-runc-fix-spec-LinuxSyscall-struct.patch
Normal file
48
patch/0087-runc-fix-spec-LinuxSyscall-struct.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 23829a0c51a77222c842b0a1d277e4738ad22942 Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Sun, 3 Feb 2019 09:26:44 +0800
|
||||
Subject: [PATCH 87/94] runc: fix spec LinuxSyscall struct
|
||||
|
||||
reason:fix spec LinuxSyscall struct
|
||||
|
||||
Change-Id: Iab6d095b43c062ad72aad8f7f1f9206f46a4f88d
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
script/runc-euleros.spec | 2 +-
|
||||
vendor/github.com/opencontainers/runtime-spec/specs-go/config.go | 9 +++++----
|
||||
2 files changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index bcbcff1..b3db2ab 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 18%{?dist}
|
||||
+Release: 19%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
index 603ecf4..8439744 100644
|
||||
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
|
||||
@@ -554,8 +554,9 @@ type LinuxSeccompArg struct {
|
||||
|
||||
// LinuxSyscall is used to match a syscall in Seccomp
|
||||
type LinuxSyscall struct {
|
||||
- Names []string `json:"names"`
|
||||
- Action LinuxSeccompAction `json:"action"`
|
||||
- Args []LinuxSeccompArg `json:"args"`
|
||||
- Comment string `json:"comment"`
|
||||
+ Names []string `json:"names"`
|
||||
+ Action LinuxSeccompAction `json:"action"`
|
||||
+ Priority uint8 `json:"priority,omitempty"`
|
||||
+ Args []LinuxSeccompArg `json:"args"`
|
||||
+ Comment string `json:"comment"`
|
||||
}
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
306
patch/0088-nsenter-clone-proc-self-exe-to-avoid-exposi.patch
Normal file
306
patch/0088-nsenter-clone-proc-self-exe-to-avoid-exposi.patch
Normal file
@ -0,0 +1,306 @@
|
||||
From 55dc2797a066480f836baf541a9ab858d9999421 Mon Sep 17 00:00:00 2001
|
||||
From: lujingxiao <lujingxiao@huawei.com>
|
||||
Date: Mon, 28 Jan 2019 22:12:18 +0800
|
||||
Subject: [PATCH 88/94] nsenter: clone /proc/self/exe to avoid
|
||||
exposing host binary to container
|
||||
|
||||
reason: There are quite a few circumstances where /proc/self/exe pointing to a
|
||||
pretty important container binary is a _bad_ thing, so to avoid this we
|
||||
have to make a copy (preferably doing self-clean-up and not being
|
||||
writeable).
|
||||
|
||||
As a hotfix we require memfd_create(2), but we can always extend this to
|
||||
use a scratch MNT_DETACH overlayfs or tmpfs. The main downside to this
|
||||
approach is no page-cache sharing for the runc binary (which overlayfs
|
||||
would give us) but this is far less complicated.
|
||||
|
||||
This is only done during nsenter so that it happens transparently to the
|
||||
Go code, and any libcontainer users benefit from it. This also makes
|
||||
ExtraFiles and --preserve-fds handling trivial (because we don't need to
|
||||
worry about it).
|
||||
|
||||
Fixes: CVE-2019-5736
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
|
||||
Change-Id: Id54b4827173affa0f2063eef4159c87343f4d672
|
||||
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||||
---
|
||||
libcontainer/nsenter/cloned_binary.c | 236 +++++++++++++++++++++++++++++++++++
|
||||
libcontainer/nsenter/nsexec.c | 11 ++
|
||||
2 files changed, 247 insertions(+)
|
||||
create mode 100644 libcontainer/nsenter/cloned_binary.c
|
||||
|
||||
diff --git a/libcontainer/nsenter/cloned_binary.c b/libcontainer/nsenter/cloned_binary.c
|
||||
new file mode 100644
|
||||
index 0000000..ec383c1
|
||||
--- /dev/null
|
||||
+++ b/libcontainer/nsenter/cloned_binary.c
|
||||
@@ -0,0 +1,236 @@
|
||||
+#define _GNU_SOURCE
|
||||
+#include <unistd.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <string.h>
|
||||
+#include <limits.h>
|
||||
+#include <fcntl.h>
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <sys/vfs.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <sys/sendfile.h>
|
||||
+#include <sys/syscall.h>
|
||||
+
|
||||
+#include <linux/magic.h>
|
||||
+#include <linux/memfd.h>
|
||||
+
|
||||
+#define MEMFD_COMMENT "runc_cloned:/proc/self/exe"
|
||||
+#define MEMFD_LNKNAME "/memfd:" MEMFD_COMMENT " (deleted)"
|
||||
+
|
||||
+/* Use our own wrapper for memfd_create. */
|
||||
+#if !defined(SYS_memfd_create) && defined(__NR_memfd_create)
|
||||
+# define SYS_memfd_create __NR_memfd_create
|
||||
+#endif
|
||||
+#ifndef SYS_memfd_create
|
||||
+# error "memfd_create(2) syscall not supported by this glibc version"
|
||||
+#endif
|
||||
+int memfd_create(const char *name, unsigned int flags)
|
||||
+{
|
||||
+ return syscall(SYS_memfd_create, name, flags);
|
||||
+}
|
||||
+
|
||||
+/* This comes directly from <linux/fcntl.h>. */
|
||||
+#ifndef F_LINUX_SPECIFIC_BASE
|
||||
+# define F_LINUX_SPECIFIC_BASE 1024
|
||||
+#endif
|
||||
+#ifndef F_ADD_SEALS
|
||||
+# define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
|
||||
+# define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
|
||||
+#endif
|
||||
+#ifndef F_SEAL_SEAL
|
||||
+# define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
|
||||
+# define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
|
||||
+# define F_SEAL_GROW 0x0004 /* prevent file from growing */
|
||||
+# define F_SEAL_WRITE 0x0008 /* prevent writes */
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * Verify whether we are currently in a self-cloned program. It's not really
|
||||
+ * possible to trivially identify a memfd compared to a regular tmpfs file, so
|
||||
+ * the best we can do is to check whether the readlink(2) looks okay and that
|
||||
+ * it is on a tmpfs.
|
||||
+ */
|
||||
+static int is_self_cloned(void)
|
||||
+{
|
||||
+ struct statfs statfsbuf = {0};
|
||||
+ char linkname[PATH_MAX + 1] = {0};
|
||||
+
|
||||
+ if (statfs("/proc/self/exe", &statfsbuf) < 0)
|
||||
+ return -1;
|
||||
+ if (readlink("/proc/self/exe", linkname, PATH_MAX) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ return statfsbuf.f_type == TMPFS_MAGIC &&
|
||||
+ !strncmp(linkname, MEMFD_LNKNAME, PATH_MAX);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Basic wrapper around mmap(2) that gives you the file length so you can
|
||||
+ * safely treat it as an ordinary buffer. Only gives you read access.
|
||||
+ */
|
||||
+static char *read_file(char *path, size_t *length)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char buf[4096], *copy = NULL;
|
||||
+
|
||||
+ if (!length)
|
||||
+ goto err;
|
||||
+ *length = 0;
|
||||
+
|
||||
+ fd = open(path, O_RDONLY|O_CLOEXEC);
|
||||
+ if (fd < 0)
|
||||
+ goto err_free;
|
||||
+
|
||||
+ for (;;) {
|
||||
+ int n;
|
||||
+ char *old = copy;
|
||||
+
|
||||
+ n = read(fd, buf, sizeof(buf));
|
||||
+ if (n < 0)
|
||||
+ goto err_fd;
|
||||
+ if (!n)
|
||||
+ break;
|
||||
+
|
||||
+ do {
|
||||
+ copy = realloc(old, (*length + n) * sizeof(*old));
|
||||
+ } while(!copy);
|
||||
+
|
||||
+ memcpy(copy + *length, buf, n);
|
||||
+ *length += n;
|
||||
+ }
|
||||
+ close(fd);
|
||||
+ return copy;
|
||||
+
|
||||
+err_fd:
|
||||
+ close(fd);
|
||||
+err_free:
|
||||
+ free(copy);
|
||||
+err:
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * A poor-man's version of "xargs -0". Basically parses a given block of
|
||||
+ * NUL-delimited data, within the given length and adds a pointer to each entry
|
||||
+ * to the array of pointers.
|
||||
+ */
|
||||
+static int parse_xargs(char *data, int data_length, char ***output)
|
||||
+{
|
||||
+ int num = 0;
|
||||
+ char *cur = data;
|
||||
+
|
||||
+ if (!data || *output)
|
||||
+ return -1;
|
||||
+
|
||||
+ do {
|
||||
+ *output = malloc(sizeof(**output));
|
||||
+ } while (!*output);
|
||||
+
|
||||
+ while (cur < data + data_length) {
|
||||
+ char **old = *output;
|
||||
+
|
||||
+ num++;
|
||||
+ do {
|
||||
+ *output = realloc(old, (num + 1) * sizeof(*old));
|
||||
+ } while (!*output);
|
||||
+
|
||||
+ (*output)[num - 1] = cur;
|
||||
+ cur += strlen(cur) + 1;
|
||||
+ }
|
||||
+ (*output)[num] = NULL;
|
||||
+ return num;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * "Parse" out argv and envp from /proc/self/cmdline and /proc/self/environ.
|
||||
+ * This is necessary because we are running in a context where we don't have a
|
||||
+ * main() that we can just get the arguments from.
|
||||
+ */
|
||||
+static int fetchve(char ***argv, char ***envp)
|
||||
+{
|
||||
+ char *cmdline, *environ;
|
||||
+ size_t cmdline_size, environ_size;
|
||||
+
|
||||
+ cmdline = read_file("/proc/self/cmdline", &cmdline_size);
|
||||
+ if (!cmdline)
|
||||
+ goto err;
|
||||
+ environ = read_file("/proc/self/environ", &environ_size);
|
||||
+ if (!environ)
|
||||
+ goto err_free;
|
||||
+
|
||||
+ if (parse_xargs(cmdline, cmdline_size, argv) <= 0)
|
||||
+ goto err_free_both;
|
||||
+ if (parse_xargs(environ, environ_size, envp) <= 0)
|
||||
+ goto err_free_both;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_free_both:
|
||||
+ free(environ);
|
||||
+err_free:
|
||||
+ free(cmdline);
|
||||
+err:
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static int clone_binary(void)
|
||||
+{
|
||||
+ int binfd, memfd, err;
|
||||
+ ssize_t sent = 0;
|
||||
+ struct stat statbuf = {0};
|
||||
+
|
||||
+ binfd = open("/proc/self/exe", O_RDONLY|O_CLOEXEC);
|
||||
+ if (binfd < 0)
|
||||
+ goto err;
|
||||
+ if (fstat(binfd, &statbuf) < 0)
|
||||
+ goto err_binfd;
|
||||
+
|
||||
+ memfd = memfd_create(MEMFD_COMMENT, MFD_CLOEXEC|MFD_ALLOW_SEALING);
|
||||
+ if (memfd < 0)
|
||||
+ goto err_binfd;
|
||||
+
|
||||
+ while (sent < statbuf.st_size) {
|
||||
+ ssize_t n = sendfile(memfd, binfd, NULL, statbuf.st_size - sent);
|
||||
+ if (n < 0)
|
||||
+ goto err_memfd;
|
||||
+ sent += n;
|
||||
+ }
|
||||
+
|
||||
+ err = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_SEAL);
|
||||
+ if (err < 0)
|
||||
+ goto err_memfd;
|
||||
+
|
||||
+ close(binfd);
|
||||
+ return memfd;
|
||||
+
|
||||
+err_memfd:
|
||||
+ close(memfd);
|
||||
+err_binfd:
|
||||
+ close(binfd);
|
||||
+err:
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int ensure_cloned_binary(void)
|
||||
+{
|
||||
+ int execfd;
|
||||
+ char **argv = NULL, **envp = NULL;
|
||||
+
|
||||
+ /* Check that we're not self-cloned, and if we are then bail. */
|
||||
+ int cloned = is_self_cloned();
|
||||
+ if (cloned != 0)
|
||||
+ return cloned;
|
||||
+
|
||||
+ if (fetchve(&argv, &envp) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ execfd = clone_binary();
|
||||
+ if (execfd < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ fexecve(execfd, argv, envp);
|
||||
+ return -1;
|
||||
+}
|
||||
diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c
|
||||
index 0ad6883..75211c8 100644
|
||||
--- a/libcontainer/nsenter/nsexec.c
|
||||
+++ b/libcontainer/nsenter/nsexec.c
|
||||
@@ -432,6 +432,9 @@ void join_namespaces(char *nslist)
|
||||
free(namespaces);
|
||||
}
|
||||
|
||||
+/* Defined in cloned_binary.c. */
|
||||
+int ensure_cloned_binary(void);
|
||||
+
|
||||
void nsexec(void)
|
||||
{
|
||||
int pipenum;
|
||||
@@ -447,6 +450,14 @@ void nsexec(void)
|
||||
if (pipenum == -1)
|
||||
return;
|
||||
|
||||
+ /*
|
||||
+ * We need to re-exec if we are not in a cloned binary. This is necessary
|
||||
+ * to ensure that containers won't be able to access the host binary
|
||||
+ * through /proc/self/exe. See CVE-2019-5736.
|
||||
+ */
|
||||
+ if (ensure_cloned_binary() < 0)
|
||||
+ bail("could not ensure we are a cloned binary");
|
||||
+
|
||||
/* Parse all of the netlink configuration. */
|
||||
nl_parse(pipenum, &config);
|
||||
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
294
patch/0089-Revert-nsenter-clone-proc-self-exe-to-avoid.patch
Normal file
294
patch/0089-Revert-nsenter-clone-proc-self-exe-to-avoid.patch
Normal file
@ -0,0 +1,294 @@
|
||||
From eb6c73cc11d6f8da5f19ef6d0794c41374dbfae4 Mon Sep 17 00:00:00 2001
|
||||
From: lujingxiao <lujingxiao@huawei.com>
|
||||
Date: Tue, 12 Feb 2019 19:07:09 +0800
|
||||
Subject: [PATCH 89/94] Revert "nsenter: clone /proc/self/exe to
|
||||
avoid exposing host binary to container"
|
||||
|
||||
reason: This reverts commit 275c8d34e6a6fa915ea4a4e47c45ce4c246a2410.
|
||||
The origin patch is from discussion email, it is the early version,
|
||||
which is different with the upstream:
|
||||
https://github.com/opencontainers/runc/commit/0a8e4117e7f715d5fbeef398405813ce8e88558b
|
||||
So revert this patch, and recommit with newer patch
|
||||
|
||||
Change-Id: Idb9250ce6dc86bd1a7640015b746c7afe8b03f49
|
||||
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||||
---
|
||||
libcontainer/nsenter/cloned_binary.c | 236 -----------------------------------
|
||||
libcontainer/nsenter/nsexec.c | 11 --
|
||||
2 files changed, 247 deletions(-)
|
||||
delete mode 100644 libcontainer/nsenter/cloned_binary.c
|
||||
|
||||
diff --git a/libcontainer/nsenter/cloned_binary.c b/libcontainer/nsenter/cloned_binary.c
|
||||
deleted file mode 100644
|
||||
index ec383c1..0000000
|
||||
--- a/libcontainer/nsenter/cloned_binary.c
|
||||
+++ /dev/null
|
||||
@@ -1,236 +0,0 @@
|
||||
-#define _GNU_SOURCE
|
||||
-#include <unistd.h>
|
||||
-#include <stdio.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <stdbool.h>
|
||||
-#include <string.h>
|
||||
-#include <limits.h>
|
||||
-#include <fcntl.h>
|
||||
-
|
||||
-#include <sys/types.h>
|
||||
-#include <sys/stat.h>
|
||||
-#include <sys/vfs.h>
|
||||
-#include <sys/mman.h>
|
||||
-#include <sys/sendfile.h>
|
||||
-#include <sys/syscall.h>
|
||||
-
|
||||
-#include <linux/magic.h>
|
||||
-#include <linux/memfd.h>
|
||||
-
|
||||
-#define MEMFD_COMMENT "runc_cloned:/proc/self/exe"
|
||||
-#define MEMFD_LNKNAME "/memfd:" MEMFD_COMMENT " (deleted)"
|
||||
-
|
||||
-/* Use our own wrapper for memfd_create. */
|
||||
-#if !defined(SYS_memfd_create) && defined(__NR_memfd_create)
|
||||
-# define SYS_memfd_create __NR_memfd_create
|
||||
-#endif
|
||||
-#ifndef SYS_memfd_create
|
||||
-# error "memfd_create(2) syscall not supported by this glibc version"
|
||||
-#endif
|
||||
-int memfd_create(const char *name, unsigned int flags)
|
||||
-{
|
||||
- return syscall(SYS_memfd_create, name, flags);
|
||||
-}
|
||||
-
|
||||
-/* This comes directly from <linux/fcntl.h>. */
|
||||
-#ifndef F_LINUX_SPECIFIC_BASE
|
||||
-# define F_LINUX_SPECIFIC_BASE 1024
|
||||
-#endif
|
||||
-#ifndef F_ADD_SEALS
|
||||
-# define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
|
||||
-# define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
|
||||
-#endif
|
||||
-#ifndef F_SEAL_SEAL
|
||||
-# define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
|
||||
-# define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
|
||||
-# define F_SEAL_GROW 0x0004 /* prevent file from growing */
|
||||
-# define F_SEAL_WRITE 0x0008 /* prevent writes */
|
||||
-#endif
|
||||
-
|
||||
-/*
|
||||
- * Verify whether we are currently in a self-cloned program. It's not really
|
||||
- * possible to trivially identify a memfd compared to a regular tmpfs file, so
|
||||
- * the best we can do is to check whether the readlink(2) looks okay and that
|
||||
- * it is on a tmpfs.
|
||||
- */
|
||||
-static int is_self_cloned(void)
|
||||
-{
|
||||
- struct statfs statfsbuf = {0};
|
||||
- char linkname[PATH_MAX + 1] = {0};
|
||||
-
|
||||
- if (statfs("/proc/self/exe", &statfsbuf) < 0)
|
||||
- return -1;
|
||||
- if (readlink("/proc/self/exe", linkname, PATH_MAX) < 0)
|
||||
- return -1;
|
||||
-
|
||||
- return statfsbuf.f_type == TMPFS_MAGIC &&
|
||||
- !strncmp(linkname, MEMFD_LNKNAME, PATH_MAX);
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * Basic wrapper around mmap(2) that gives you the file length so you can
|
||||
- * safely treat it as an ordinary buffer. Only gives you read access.
|
||||
- */
|
||||
-static char *read_file(char *path, size_t *length)
|
||||
-{
|
||||
- int fd;
|
||||
- char buf[4096], *copy = NULL;
|
||||
-
|
||||
- if (!length)
|
||||
- goto err;
|
||||
- *length = 0;
|
||||
-
|
||||
- fd = open(path, O_RDONLY|O_CLOEXEC);
|
||||
- if (fd < 0)
|
||||
- goto err_free;
|
||||
-
|
||||
- for (;;) {
|
||||
- int n;
|
||||
- char *old = copy;
|
||||
-
|
||||
- n = read(fd, buf, sizeof(buf));
|
||||
- if (n < 0)
|
||||
- goto err_fd;
|
||||
- if (!n)
|
||||
- break;
|
||||
-
|
||||
- do {
|
||||
- copy = realloc(old, (*length + n) * sizeof(*old));
|
||||
- } while(!copy);
|
||||
-
|
||||
- memcpy(copy + *length, buf, n);
|
||||
- *length += n;
|
||||
- }
|
||||
- close(fd);
|
||||
- return copy;
|
||||
-
|
||||
-err_fd:
|
||||
- close(fd);
|
||||
-err_free:
|
||||
- free(copy);
|
||||
-err:
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * A poor-man's version of "xargs -0". Basically parses a given block of
|
||||
- * NUL-delimited data, within the given length and adds a pointer to each entry
|
||||
- * to the array of pointers.
|
||||
- */
|
||||
-static int parse_xargs(char *data, int data_length, char ***output)
|
||||
-{
|
||||
- int num = 0;
|
||||
- char *cur = data;
|
||||
-
|
||||
- if (!data || *output)
|
||||
- return -1;
|
||||
-
|
||||
- do {
|
||||
- *output = malloc(sizeof(**output));
|
||||
- } while (!*output);
|
||||
-
|
||||
- while (cur < data + data_length) {
|
||||
- char **old = *output;
|
||||
-
|
||||
- num++;
|
||||
- do {
|
||||
- *output = realloc(old, (num + 1) * sizeof(*old));
|
||||
- } while (!*output);
|
||||
-
|
||||
- (*output)[num - 1] = cur;
|
||||
- cur += strlen(cur) + 1;
|
||||
- }
|
||||
- (*output)[num] = NULL;
|
||||
- return num;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * "Parse" out argv and envp from /proc/self/cmdline and /proc/self/environ.
|
||||
- * This is necessary because we are running in a context where we don't have a
|
||||
- * main() that we can just get the arguments from.
|
||||
- */
|
||||
-static int fetchve(char ***argv, char ***envp)
|
||||
-{
|
||||
- char *cmdline, *environ;
|
||||
- size_t cmdline_size, environ_size;
|
||||
-
|
||||
- cmdline = read_file("/proc/self/cmdline", &cmdline_size);
|
||||
- if (!cmdline)
|
||||
- goto err;
|
||||
- environ = read_file("/proc/self/environ", &environ_size);
|
||||
- if (!environ)
|
||||
- goto err_free;
|
||||
-
|
||||
- if (parse_xargs(cmdline, cmdline_size, argv) <= 0)
|
||||
- goto err_free_both;
|
||||
- if (parse_xargs(environ, environ_size, envp) <= 0)
|
||||
- goto err_free_both;
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
-err_free_both:
|
||||
- free(environ);
|
||||
-err_free:
|
||||
- free(cmdline);
|
||||
-err:
|
||||
- return -1;
|
||||
-}
|
||||
-
|
||||
-static int clone_binary(void)
|
||||
-{
|
||||
- int binfd, memfd, err;
|
||||
- ssize_t sent = 0;
|
||||
- struct stat statbuf = {0};
|
||||
-
|
||||
- binfd = open("/proc/self/exe", O_RDONLY|O_CLOEXEC);
|
||||
- if (binfd < 0)
|
||||
- goto err;
|
||||
- if (fstat(binfd, &statbuf) < 0)
|
||||
- goto err_binfd;
|
||||
-
|
||||
- memfd = memfd_create(MEMFD_COMMENT, MFD_CLOEXEC|MFD_ALLOW_SEALING);
|
||||
- if (memfd < 0)
|
||||
- goto err_binfd;
|
||||
-
|
||||
- while (sent < statbuf.st_size) {
|
||||
- ssize_t n = sendfile(memfd, binfd, NULL, statbuf.st_size - sent);
|
||||
- if (n < 0)
|
||||
- goto err_memfd;
|
||||
- sent += n;
|
||||
- }
|
||||
-
|
||||
- err = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_SEAL);
|
||||
- if (err < 0)
|
||||
- goto err_memfd;
|
||||
-
|
||||
- close(binfd);
|
||||
- return memfd;
|
||||
-
|
||||
-err_memfd:
|
||||
- close(memfd);
|
||||
-err_binfd:
|
||||
- close(binfd);
|
||||
-err:
|
||||
- return -1;
|
||||
-}
|
||||
-
|
||||
-int ensure_cloned_binary(void)
|
||||
-{
|
||||
- int execfd;
|
||||
- char **argv = NULL, **envp = NULL;
|
||||
-
|
||||
- /* Check that we're not self-cloned, and if we are then bail. */
|
||||
- int cloned = is_self_cloned();
|
||||
- if (cloned != 0)
|
||||
- return cloned;
|
||||
-
|
||||
- if (fetchve(&argv, &envp) < 0)
|
||||
- return -1;
|
||||
-
|
||||
- execfd = clone_binary();
|
||||
- if (execfd < 0)
|
||||
- return -1;
|
||||
-
|
||||
- fexecve(execfd, argv, envp);
|
||||
- return -1;
|
||||
-}
|
||||
diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c
|
||||
index 75211c8..0ad6883 100644
|
||||
--- a/libcontainer/nsenter/nsexec.c
|
||||
+++ b/libcontainer/nsenter/nsexec.c
|
||||
@@ -432,9 +432,6 @@ void join_namespaces(char *nslist)
|
||||
free(namespaces);
|
||||
}
|
||||
|
||||
-/* Defined in cloned_binary.c. */
|
||||
-int ensure_cloned_binary(void);
|
||||
-
|
||||
void nsexec(void)
|
||||
{
|
||||
int pipenum;
|
||||
@@ -450,14 +447,6 @@ void nsexec(void)
|
||||
if (pipenum == -1)
|
||||
return;
|
||||
|
||||
- /*
|
||||
- * We need to re-exec if we are not in a cloned binary. This is necessary
|
||||
- * to ensure that containers won't be able to access the host binary
|
||||
- * through /proc/self/exe. See CVE-2019-5736.
|
||||
- */
|
||||
- if (ensure_cloned_binary() < 0)
|
||||
- bail("could not ensure we are a cloned binary");
|
||||
-
|
||||
/* Parse all of the netlink configuration. */
|
||||
nl_parse(pipenum, &config);
|
||||
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
357
patch/0090-nsenter-clone-proc-self-exe-to-avoid-exposi.patch
Normal file
357
patch/0090-nsenter-clone-proc-self-exe-to-avoid-exposi.patch
Normal file
@ -0,0 +1,357 @@
|
||||
From 2f3550fa67d6e2eb21276775e05ba145f8b5768b Mon Sep 17 00:00:00 2001
|
||||
From: lujingxiao <lujingxiao@huawei.com>
|
||||
Date: Tue, 12 Feb 2019 19:15:11 +0800
|
||||
Subject: [PATCH 90/94] nsenter: clone /proc/self/exe to avoid
|
||||
exposing host binary to container
|
||||
|
||||
reason: There are quite a few circumstances where /proc/self/exe pointing to a
|
||||
pretty important container binary is a _bad_ thing, so to avoid this we
|
||||
have to make a copy (preferably doing self-clean-up and not being
|
||||
writeable).
|
||||
|
||||
We require memfd_create(2) -- though there is an O_TMPFILE fallback --
|
||||
but we can always extend this to use a scratch MNT_DETACH overlayfs or
|
||||
tmpfs. The main downside to this approach is no page-cache sharing for
|
||||
the runc binary (which overlayfs would give us) but this is far less
|
||||
complicated.
|
||||
|
||||
This is only done during nsenter so that it happens transparently to the
|
||||
Go code, and any libcontainer users benefit from it. This also makes
|
||||
ExtraFiles and --preserve-fds handling trivial (because we don't need to
|
||||
worry about it).
|
||||
|
||||
Fixes: CVE-2019-5736
|
||||
Co-developed-by: Christian Brauner <christian.brauner@ubuntu.com>
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
|
||||
Recommit this patch with the upstream one:
|
||||
https://github.com/opencontainers/runc/commit/0a8e4117e7f715d5fbeef398405813ce8e88558b
|
||||
|
||||
Change-Id: I4d4d87d480c12a7844b9ef6bd955457cb152ba51
|
||||
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||||
---
|
||||
libcontainer/nsenter/cloned_binary.c | 268 +++++++++++++++++++++++++++++++++++
|
||||
libcontainer/nsenter/nsexec.c | 11 ++
|
||||
script/runc-euleros.spec | 2 +-
|
||||
3 files changed, 280 insertions(+), 1 deletion(-)
|
||||
create mode 100644 libcontainer/nsenter/cloned_binary.c
|
||||
|
||||
diff --git a/libcontainer/nsenter/cloned_binary.c b/libcontainer/nsenter/cloned_binary.c
|
||||
new file mode 100644
|
||||
index 0000000..c8a42c2
|
||||
--- /dev/null
|
||||
+++ b/libcontainer/nsenter/cloned_binary.c
|
||||
@@ -0,0 +1,268 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2019 Aleksa Sarai <cyphar@cyphar.com>
|
||||
+ * Copyright (C) 2019 SUSE LLC
|
||||
+ *
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+#define _GNU_SOURCE
|
||||
+#include <unistd.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <string.h>
|
||||
+#include <limits.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <sys/vfs.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <sys/sendfile.h>
|
||||
+#include <sys/syscall.h>
|
||||
+
|
||||
+/* Use our own wrapper for memfd_create. */
|
||||
+#if !defined(SYS_memfd_create) && defined(__NR_memfd_create)
|
||||
+# define SYS_memfd_create __NR_memfd_create
|
||||
+#endif
|
||||
+#ifdef SYS_memfd_create
|
||||
+# define HAVE_MEMFD_CREATE
|
||||
+/* memfd_create(2) flags -- copied from <linux/memfd.h>. */
|
||||
+# ifndef MFD_CLOEXEC
|
||||
+# define MFD_CLOEXEC 0x0001U
|
||||
+# define MFD_ALLOW_SEALING 0x0002U
|
||||
+# endif
|
||||
+int memfd_create(const char *name, unsigned int flags)
|
||||
+{
|
||||
+ return syscall(SYS_memfd_create, name, flags);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+/* This comes directly from <linux/fcntl.h>. */
|
||||
+#ifndef F_LINUX_SPECIFIC_BASE
|
||||
+# define F_LINUX_SPECIFIC_BASE 1024
|
||||
+#endif
|
||||
+#ifndef F_ADD_SEALS
|
||||
+# define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
|
||||
+# define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
|
||||
+#endif
|
||||
+#ifndef F_SEAL_SEAL
|
||||
+# define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
|
||||
+# define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
|
||||
+# define F_SEAL_GROW 0x0004 /* prevent file from growing */
|
||||
+# define F_SEAL_WRITE 0x0008 /* prevent writes */
|
||||
+#endif
|
||||
+
|
||||
+#define RUNC_SENDFILE_MAX 0x7FFFF000 /* sendfile(2) is limited to 2GB. */
|
||||
+#ifdef HAVE_MEMFD_CREATE
|
||||
+# define RUNC_MEMFD_COMMENT "runc_cloned:/proc/self/exe"
|
||||
+# define RUNC_MEMFD_SEALS \
|
||||
+ (F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)
|
||||
+#endif
|
||||
+
|
||||
+static void *must_realloc(void *ptr, size_t size)
|
||||
+{
|
||||
+ void *old = ptr;
|
||||
+ do {
|
||||
+ ptr = realloc(old, size);
|
||||
+ } while(!ptr);
|
||||
+ return ptr;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Verify whether we are currently in a self-cloned program (namely, is
|
||||
+ * /proc/self/exe a memfd). F_GET_SEALS will only succeed for memfds (or rather
|
||||
+ * for shmem files), and we want to be sure it's actually sealed.
|
||||
+ */
|
||||
+static int is_self_cloned(void)
|
||||
+{
|
||||
+ int fd, ret, is_cloned = 0;
|
||||
+
|
||||
+ fd = open("/proc/self/exe", O_RDONLY|O_CLOEXEC);
|
||||
+ if (fd < 0)
|
||||
+ return -ENOTRECOVERABLE;
|
||||
+
|
||||
+#ifdef HAVE_MEMFD_CREATE
|
||||
+ ret = fcntl(fd, F_GET_SEALS);
|
||||
+ is_cloned = (ret == RUNC_MEMFD_SEALS);
|
||||
+#else
|
||||
+ struct stat statbuf = {0};
|
||||
+ ret = fstat(fd, &statbuf);
|
||||
+ if (ret >= 0)
|
||||
+ is_cloned = (statbuf.st_nlink == 0);
|
||||
+#endif
|
||||
+ close(fd);
|
||||
+ return is_cloned;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Basic wrapper around mmap(2) that gives you the file length so you can
|
||||
+ * safely treat it as an ordinary buffer. Only gives you read access.
|
||||
+ */
|
||||
+static char *read_file(char *path, size_t *length)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char buf[4096], *copy = NULL;
|
||||
+
|
||||
+ if (!length)
|
||||
+ return NULL;
|
||||
+
|
||||
+ fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
+ if (fd < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ *length = 0;
|
||||
+ for (;;) {
|
||||
+ int n;
|
||||
+
|
||||
+ n = read(fd, buf, sizeof(buf));
|
||||
+ if (n < 0)
|
||||
+ goto error;
|
||||
+ if (!n)
|
||||
+ break;
|
||||
+
|
||||
+ copy = must_realloc(copy, (*length + n) * sizeof(*copy));
|
||||
+ memcpy(copy + *length, buf, n);
|
||||
+ *length += n;
|
||||
+ }
|
||||
+ close(fd);
|
||||
+ return copy;
|
||||
+
|
||||
+error:
|
||||
+ close(fd);
|
||||
+ free(copy);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * A poor-man's version of "xargs -0". Basically parses a given block of
|
||||
+ * NUL-delimited data, within the given length and adds a pointer to each entry
|
||||
+ * to the array of pointers.
|
||||
+ */
|
||||
+static int parse_xargs(char *data, int data_length, char ***output)
|
||||
+{
|
||||
+ int num = 0;
|
||||
+ char *cur = data;
|
||||
+
|
||||
+ if (!data || *output != NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ while (cur < data + data_length) {
|
||||
+ num++;
|
||||
+ *output = must_realloc(*output, (num + 1) * sizeof(**output));
|
||||
+ (*output)[num - 1] = cur;
|
||||
+ cur += strlen(cur) + 1;
|
||||
+ }
|
||||
+ (*output)[num] = NULL;
|
||||
+ return num;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * "Parse" out argv and envp from /proc/self/cmdline and /proc/self/environ.
|
||||
+ * This is necessary because we are running in a context where we don't have a
|
||||
+ * main() that we can just get the arguments from.
|
||||
+ */
|
||||
+static int fetchve(char ***argv, char ***envp)
|
||||
+{
|
||||
+ char *cmdline = NULL, *environ = NULL;
|
||||
+ size_t cmdline_size, environ_size;
|
||||
+
|
||||
+ cmdline = read_file("/proc/self/cmdline", &cmdline_size);
|
||||
+ if (!cmdline)
|
||||
+ goto error;
|
||||
+ environ = read_file("/proc/self/environ", &environ_size);
|
||||
+ if (!environ)
|
||||
+ goto error;
|
||||
+
|
||||
+ if (parse_xargs(cmdline, cmdline_size, argv) <= 0)
|
||||
+ goto error;
|
||||
+ if (parse_xargs(environ, environ_size, envp) <= 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+error:
|
||||
+ free(environ);
|
||||
+ free(cmdline);
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int clone_binary(void)
|
||||
+{
|
||||
+ int binfd, memfd;
|
||||
+ ssize_t sent = 0;
|
||||
+
|
||||
+#ifdef HAVE_MEMFD_CREATE
|
||||
+ memfd = memfd_create(RUNC_MEMFD_COMMENT, MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
+#else
|
||||
+ memfd = open("/tmp", O_TMPFILE | O_EXCL | O_RDWR | O_CLOEXEC, 0711);
|
||||
+#endif
|
||||
+ if (memfd < 0)
|
||||
+ return -ENOTRECOVERABLE;
|
||||
+
|
||||
+ binfd = open("/proc/self/exe", O_RDONLY | O_CLOEXEC);
|
||||
+ if (binfd < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ sent = sendfile(memfd, binfd, NULL, RUNC_SENDFILE_MAX);
|
||||
+ close(binfd);
|
||||
+ if (sent < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+#ifdef HAVE_MEMFD_CREATE
|
||||
+ int err = fcntl(memfd, F_ADD_SEALS, RUNC_MEMFD_SEALS);
|
||||
+ if (err < 0)
|
||||
+ goto error;
|
||||
+#else
|
||||
+ /* Need to re-open "memfd" as read-only to avoid execve(2) giving -EXTBUSY. */
|
||||
+ int newfd;
|
||||
+ char *fdpath = NULL;
|
||||
+
|
||||
+ if (asprintf(&fdpath, "/proc/self/fd/%d", memfd) < 0)
|
||||
+ goto error;
|
||||
+ newfd = open(fdpath, O_RDONLY | O_CLOEXEC);
|
||||
+ free(fdpath);
|
||||
+ if (newfd < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ close(memfd);
|
||||
+ memfd = newfd;
|
||||
+#endif
|
||||
+ return memfd;
|
||||
+
|
||||
+error:
|
||||
+ close(memfd);
|
||||
+ return -EIO;
|
||||
+}
|
||||
+
|
||||
+int ensure_cloned_binary(void)
|
||||
+{
|
||||
+ int execfd;
|
||||
+ char **argv = NULL, **envp = NULL;
|
||||
+
|
||||
+ /* Check that we're not self-cloned, and if we are then bail. */
|
||||
+ int cloned = is_self_cloned();
|
||||
+ if (cloned > 0 || cloned == -ENOTRECOVERABLE)
|
||||
+ return cloned;
|
||||
+
|
||||
+ if (fetchve(&argv, &envp) < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ execfd = clone_binary();
|
||||
+ if (execfd < 0)
|
||||
+ return -EIO;
|
||||
+
|
||||
+ fexecve(execfd, argv, envp);
|
||||
+ return -ENOEXEC;
|
||||
+}
|
||||
diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c
|
||||
index 0ad6883..64ed76f 100644
|
||||
--- a/libcontainer/nsenter/nsexec.c
|
||||
+++ b/libcontainer/nsenter/nsexec.c
|
||||
@@ -432,6 +432,9 @@ void join_namespaces(char *nslist)
|
||||
free(namespaces);
|
||||
}
|
||||
|
||||
+/* Defined in cloned_binary.c. */
|
||||
+extern int ensure_cloned_binary(void);
|
||||
+
|
||||
void nsexec(void)
|
||||
{
|
||||
int pipenum;
|
||||
@@ -447,6 +450,14 @@ void nsexec(void)
|
||||
if (pipenum == -1)
|
||||
return;
|
||||
|
||||
+ /*
|
||||
+ * We need to re-exec if we are not in a cloned binary. This is necessary
|
||||
+ * to ensure that containers won't be able to access the host binary
|
||||
+ * through /proc/self/exe. See CVE-2019-5736.
|
||||
+ */
|
||||
+ if (ensure_cloned_binary() < 0)
|
||||
+ bail("could not ensure we are a cloned binary");
|
||||
+
|
||||
/* Parse all of the netlink configuration. */
|
||||
nl_parse(pipenum, &config);
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index b3db2ab..2448078 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 19%{?dist}
|
||||
+Release: 20%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
207
patch/0091-runc-cve-2019-5736-workaround-if-memfd_create.patch
Normal file
207
patch/0091-runc-cve-2019-5736-workaround-if-memfd_create.patch
Normal file
@ -0,0 +1,207 @@
|
||||
From 621c01059536ec167da8c9d5571e8bf860b4dadb Mon Sep 17 00:00:00 2001
|
||||
From: wangfengtu <wangfengtu@huawei.com>
|
||||
Date: Wed, 13 Feb 2019 05:26:38 -0500
|
||||
Subject: [PATCH 91/94] runc: cve-2019-5736: workaround if
|
||||
memfd_create and O_TMPFILE not work
|
||||
|
||||
[Changelog]: create tmpfile using mkostemp when memfd_create and
|
||||
O_TMPFILE not work
|
||||
[Author]: git
|
||||
|
||||
Change-Id: I785295b19759487ddaa5e0dcb5c11e4aa9ace838
|
||||
Signed-off-by: sdu.liu <sdu.liu@huawei.com>
|
||||
Signed-off-by: wangfengtu <wangfengtu@huawei.com>
|
||||
---
|
||||
libcontainer/nsenter/cloned_binary.c | 117 +++++++++++++++++++++++++----------
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 87 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/nsenter/cloned_binary.c b/libcontainer/nsenter/cloned_binary.c
|
||||
index c8a42c2..e59d434 100644
|
||||
--- a/libcontainer/nsenter/cloned_binary.c
|
||||
+++ b/libcontainer/nsenter/cloned_binary.c
|
||||
@@ -71,6 +71,14 @@ int memfd_create(const char *name, unsigned int flags)
|
||||
(F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)
|
||||
#endif
|
||||
|
||||
+enum clone_type
|
||||
+{
|
||||
+ USING_MEMFD = 0,
|
||||
+ USING_UNAMED_FILE,
|
||||
+ USING_TMPFILE,
|
||||
+};
|
||||
+
|
||||
+
|
||||
static void *must_realloc(void *ptr, size_t size)
|
||||
{
|
||||
void *old = ptr;
|
||||
@@ -80,6 +88,23 @@ static void *must_realloc(void *ptr, size_t size)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
+static int get_clone_type()
|
||||
+{
|
||||
+ int memfd = 0;
|
||||
+#ifdef HAVE_MEMFD_CREATE
|
||||
+ memfd = memfd_create(RUNC_MEMFD_COMMENT, MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
+ if (memfd > 0 || memfd == 0) {
|
||||
+ close(memfd);
|
||||
+ return USING_MEMFD;
|
||||
+ }
|
||||
+#else
|
||||
+#ifdef O_TMPFILE
|
||||
+ return USING_UNAMED_FILE;
|
||||
+#endif
|
||||
+#endif
|
||||
+ return USING_TMPFILE;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Verify whether we are currently in a self-cloned program (namely, is
|
||||
* /proc/self/exe a memfd). F_GET_SEALS will only succeed for memfds (or rather
|
||||
@@ -87,21 +112,23 @@ static void *must_realloc(void *ptr, size_t size)
|
||||
*/
|
||||
static int is_self_cloned(void)
|
||||
{
|
||||
- int fd, ret, is_cloned = 0;
|
||||
+ int fd, ret, type, is_cloned = 0;
|
||||
|
||||
fd = open("/proc/self/exe", O_RDONLY|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return -ENOTRECOVERABLE;
|
||||
+ type = get_clone_type();
|
||||
+
|
||||
+ if (type == USING_MEMFD) {
|
||||
+ ret = fcntl(fd, F_GET_SEALS);
|
||||
+ is_cloned = (ret == RUNC_MEMFD_SEALS);
|
||||
+ } else {
|
||||
+ struct stat statbuf = {0};
|
||||
+ ret = fstat(fd, &statbuf);
|
||||
+ if (ret >= 0)
|
||||
+ is_cloned = (statbuf.st_nlink == 0);
|
||||
+ }
|
||||
|
||||
-#ifdef HAVE_MEMFD_CREATE
|
||||
- ret = fcntl(fd, F_GET_SEALS);
|
||||
- is_cloned = (ret == RUNC_MEMFD_SEALS);
|
||||
-#else
|
||||
- struct stat statbuf = {0};
|
||||
- ret = fstat(fd, &statbuf);
|
||||
- if (ret >= 0)
|
||||
- is_cloned = (statbuf.st_nlink == 0);
|
||||
-#endif
|
||||
close(fd);
|
||||
return is_cloned;
|
||||
}
|
||||
@@ -198,16 +225,37 @@ error:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+
|
||||
static int clone_binary(void)
|
||||
{
|
||||
int binfd, memfd;
|
||||
ssize_t sent = 0;
|
||||
+ char template[] = "/tmp/runc.XXXXXX";
|
||||
+ int type = 0;
|
||||
+ char *tmpfile = NULL;
|
||||
+
|
||||
+ type = get_clone_type();
|
||||
+ switch (type) {
|
||||
+ case USING_MEMFD:
|
||||
+ memfd = memfd_create(RUNC_MEMFD_COMMENT, MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
+ break;
|
||||
+ case USING_UNAMED_FILE:
|
||||
+ memfd = open("/tmp", O_TMPFILE | O_EXCL | O_RDWR | O_CLOEXEC, 0711);
|
||||
+ break;
|
||||
+ case USING_TMPFILE:
|
||||
+ memfd = mkostemp(template,O_EXCL | O_RDWR | O_CLOEXEC);
|
||||
+ if (memfd < 0) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+ tmpfile = template;
|
||||
+ if (fchmod(memfd, 0711)) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -ENOTRECOVERABLE;
|
||||
+ }
|
||||
|
||||
-#ifdef HAVE_MEMFD_CREATE
|
||||
- memfd = memfd_create(RUNC_MEMFD_COMMENT, MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
-#else
|
||||
- memfd = open("/tmp", O_TMPFILE | O_EXCL | O_RDWR | O_CLOEXEC, 0711);
|
||||
-#endif
|
||||
if (memfd < 0)
|
||||
return -ENOTRECOVERABLE;
|
||||
|
||||
@@ -220,29 +268,36 @@ static int clone_binary(void)
|
||||
if (sent < 0)
|
||||
goto error;
|
||||
|
||||
-#ifdef HAVE_MEMFD_CREATE
|
||||
- int err = fcntl(memfd, F_ADD_SEALS, RUNC_MEMFD_SEALS);
|
||||
- if (err < 0)
|
||||
- goto error;
|
||||
-#else
|
||||
+ if (type == USING_MEMFD) {
|
||||
+ int err = fcntl(memfd, F_ADD_SEALS, RUNC_MEMFD_SEALS);
|
||||
+ if (err < 0)
|
||||
+ goto error;
|
||||
+ } else {
|
||||
/* Need to re-open "memfd" as read-only to avoid execve(2) giving -EXTBUSY. */
|
||||
- int newfd;
|
||||
- char *fdpath = NULL;
|
||||
+ int newfd;
|
||||
+ char *fdpath = NULL;
|
||||
|
||||
- if (asprintf(&fdpath, "/proc/self/fd/%d", memfd) < 0)
|
||||
- goto error;
|
||||
- newfd = open(fdpath, O_RDONLY | O_CLOEXEC);
|
||||
- free(fdpath);
|
||||
- if (newfd < 0)
|
||||
- goto error;
|
||||
+ if (asprintf(&fdpath, "/proc/self/fd/%d", memfd) < 0)
|
||||
+ goto error;
|
||||
+ newfd = open(fdpath, O_RDONLY | O_CLOEXEC);
|
||||
+ free(fdpath);
|
||||
+ if (newfd < 0)
|
||||
+ goto error;
|
||||
+ close(memfd);
|
||||
|
||||
- close(memfd);
|
||||
- memfd = newfd;
|
||||
-#endif
|
||||
+ memfd = newfd;
|
||||
+ }
|
||||
+
|
||||
+ if(tmpfile) {
|
||||
+ remove(tmpfile);
|
||||
+ }
|
||||
return memfd;
|
||||
|
||||
error:
|
||||
close(memfd);
|
||||
+ if(tmpfile) {
|
||||
+ remove(tmpfile);
|
||||
+ }
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 2448078..b577d1a 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 20%{?dist}
|
||||
+Release: 21%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
47
patch/0092-runc-cve-2019-5736-fix-build-failure.patch
Normal file
47
patch/0092-runc-cve-2019-5736-fix-build-failure.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From 096172d15e1d29ba177a39d8ded3ca6b5b1c0ac4 Mon Sep 17 00:00:00 2001
|
||||
From: wangfengtu <wangfengtu@huawei.com>
|
||||
Date: Thu, 14 Feb 2019 00:08:01 +0800
|
||||
Subject: [PATCH 92/94] runc: cve-2019-5736 fix build failure
|
||||
|
||||
[Changelog]: fix build failure
|
||||
[Author]: git
|
||||
|
||||
Change-Id: Ie422758618726d9e98a7f9ec9a14e34d4479251f
|
||||
Signed-off-by: wangfengtu <wangfengtu@huawei.com>
|
||||
---
|
||||
libcontainer/nsenter/cloned_binary.c | 2 ++
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/nsenter/cloned_binary.c b/libcontainer/nsenter/cloned_binary.c
|
||||
index e59d434..ff7ecb0 100644
|
||||
--- a/libcontainer/nsenter/cloned_binary.c
|
||||
+++ b/libcontainer/nsenter/cloned_binary.c
|
||||
@@ -239,9 +239,11 @@ static int clone_binary(void)
|
||||
case USING_MEMFD:
|
||||
memfd = memfd_create(RUNC_MEMFD_COMMENT, MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
break;
|
||||
+#ifdef O_TMPFILE
|
||||
case USING_UNAMED_FILE:
|
||||
memfd = open("/tmp", O_TMPFILE | O_EXCL | O_RDWR | O_CLOEXEC, 0711);
|
||||
break;
|
||||
+#endif
|
||||
case USING_TMPFILE:
|
||||
memfd = mkostemp(template,O_EXCL | O_RDWR | O_CLOEXEC);
|
||||
if (memfd < 0) {
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index b577d1a..6e96326 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 21%{?dist}
|
||||
+Release: 22%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
46
patch/0093-runc-fix-error-when-check-the-init-process.patch
Normal file
46
patch/0093-runc-fix-error-when-check-the-init-process.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 20ce68df5145a8c56a53322fcf8c6a149d9df535 Mon Sep 17 00:00:00 2001
|
||||
From: zhangyu235 <zhangyu235@huawei.com>
|
||||
Date: Sun, 24 Feb 2019 17:49:09 +0800
|
||||
Subject: [PATCH 93/94] runc: fix error when check the init process
|
||||
|
||||
reason:We shoule ensure the porcess is still the original init process
|
||||
using doesInitProcessExist(). But it could happen when the process exited
|
||||
just when we call function doesInitProcessExist(). Due to this reason,
|
||||
we shoule not return error in this case.
|
||||
|
||||
Change-Id: If515af5beed73adf19b2c31eae919c5a39911a18
|
||||
Signed-off-by: zhangyu235 <zhangyu235@huawei.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 2 +-
|
||||
script/runc-euleros.spec | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 8100aca..5a3705e 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -1411,7 +1411,7 @@ func (c *linuxContainer) refreshState() error {
|
||||
func (c *linuxContainer) doesInitProcessExist(initPid int) (bool, error) {
|
||||
startTime, err := system.GetProcessStartTime(initPid)
|
||||
if err != nil {
|
||||
- return false, newSystemErrorWithCausef(err, "getting init process %d start time", initPid)
|
||||
+ return false, nil
|
||||
}
|
||||
if c.initProcessStartTime != startTime {
|
||||
return false, nil
|
||||
diff --git a/script/runc-euleros.spec b/script/runc-euleros.spec
|
||||
index 6e96326..09be036 100644
|
||||
--- a/script/runc-euleros.spec
|
||||
+++ b/script/runc-euleros.spec
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
-Release: 22%{?dist}
|
||||
+Release: 23%{?dist}
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCF specification
|
||||
|
||||
License: ASL 2.0
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From 662893f67295028a128885544d4a0ee25491da95 Mon Sep 17 00:00:00 2001
|
||||
From: wangfengtu <wangfengtu@huawei.com>
|
||||
Date: Sat, 2 Mar 2019 19:51:08 +0800
|
||||
Subject: [PATCH 94/94] runc: If /tmp is mounted by option
|
||||
noexec,docker run will fail
|
||||
|
||||
reason: Change /tmp to /run for storage temporary runc
|
||||
|
||||
Change-Id: Ia442b489dc1b57c6e4fd720b98b5061f83a88214
|
||||
Signed-off-by: wangfengtu <wangfengtu@huawei.com>
|
||||
---
|
||||
libcontainer/nsenter/cloned_binary.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/nsenter/cloned_binary.c b/libcontainer/nsenter/cloned_binary.c
|
||||
index ff7ecb0..8e8b70e 100644
|
||||
--- a/libcontainer/nsenter/cloned_binary.c
|
||||
+++ b/libcontainer/nsenter/cloned_binary.c
|
||||
@@ -230,7 +230,7 @@ static int clone_binary(void)
|
||||
{
|
||||
int binfd, memfd;
|
||||
ssize_t sent = 0;
|
||||
- char template[] = "/tmp/runc.XXXXXX";
|
||||
+ char template[] = "/run/runc.XXXXXX";
|
||||
int type = 0;
|
||||
char *tmpfile = NULL;
|
||||
|
||||
--
|
||||
2.7.4.3
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
From a854b14193b62c93bd62ccddebca29a77c8c07a2 Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Fri, 8 Mar 2019 14:32:39 +0800
|
||||
Subject: [PATCH] runc: just warning when poststart and poststop
|
||||
failed
|
||||
|
||||
reason:just warning when poststart and poststop failed.
|
||||
|
||||
Change-Id: I65e816c344506bbf9ea2f8c5ff4dc2d47cc0a35e
|
||||
Signed-off-by: mashimiao <mashimiao@huawei.com>
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 3 +--
|
||||
libcontainer/state_linux.go | 3 +--
|
||||
2 files changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 5a3705e..1f587c7 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -341,11 +341,10 @@ func (c *linuxContainer) start(process *Process) error {
|
||||
for i, hook := range c.config.Hooks.Poststart {
|
||||
logrus.Infof("run poststart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
- logrus.Errorf("running poststart hook(%d:%s) failed: %s", i, hook.Info(), err)
|
||||
+ logrus.Warnf("running poststart hook %d:%s failed: %s, ContainerId: %s", i, hook.Info(), err, s.ID)
|
||||
if err := parent.terminate(); err != nil {
|
||||
logrus.Warnf("run poststart hook failed: %s, ContainerID: %s", err, s.ID)
|
||||
}
|
||||
- return newSystemErrorWithCausef(err, "running poststart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go
|
||||
index 6fa62c0..b570a24 100644
|
||||
--- a/libcontainer/state_linux.go
|
||||
+++ b/libcontainer/state_linux.go
|
||||
@@ -68,8 +68,7 @@ func runPoststopHooks(c *linuxContainer) error {
|
||||
for i, hook := range c.config.Hooks.Poststop {
|
||||
logrus.Infof("run poststop hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
- logrus.Errorf("running poststop hook %d: %s failed: %s", i, hook.Info(), err)
|
||||
- return newSystemErrorWithCausef(err, "running poststop hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
+ logrus.Warnf("running poststop hook %d:%s failed: %s, ContainerID: %s", i, hook.Info(), err, s.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
From 5a4335581b0ccf28342f3e48639ba38b611a02fe Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Wed, 13 Mar 2019 15:40:12 +0800
|
||||
Subject: [PATCH] runc: do not kill container if poststart hooks
|
||||
execute failed
|
||||
|
||||
reason:do not kill container if poststart hooks execute failed.
|
||||
|
||||
Change-Id: Ieb1e1e7eeefe4bbd3cdb38fbba5a2a003297a5b3
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
libcontainer/container_linux.go | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 1f587c7..914da7f 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -342,9 +342,6 @@ func (c *linuxContainer) start(process *Process) error {
|
||||
logrus.Infof("run poststart hook %d:%s, ContainerID: %s", i, hook.Info(), s.ID)
|
||||
if err := hook.Run(s); err != nil {
|
||||
logrus.Warnf("running poststart hook %d:%s failed: %s, ContainerId: %s", i, hook.Info(), err, s.ID)
|
||||
- if err := parent.terminate(); err != nil {
|
||||
- logrus.Warnf("run poststart hook failed: %s, ContainerID: %s", err, s.ID)
|
||||
- }
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
120
patch/0097-runc-Fix-mountpoint-leak-and-pivot_root-error.patch
Normal file
120
patch/0097-runc-Fix-mountpoint-leak-and-pivot_root-error.patch
Normal file
@ -0,0 +1,120 @@
|
||||
From 0b0bb50e4ecdebfb2646adb57e53972663947320 Mon Sep 17 00:00:00 2001
|
||||
From: wangfengtu <wangfengtu@huawei.com>
|
||||
Date: Wed, 27 Mar 2019 15:28:03 +0800
|
||||
Subject: [PATCH] runc: Fix mountpoint leak and pivot_root error
|
||||
|
||||
reason:We have no way to get exact /proc/self/mountinfo infomation
|
||||
because it can change if other process mount/umount mountpoint. So
|
||||
runc sometimes cannot get container's mountpoint when runc try to
|
||||
make mountpoint private. This can cause mountpoint leak and pivot_root
|
||||
error, runc error out like this:
|
||||
```
|
||||
Handler for POST
|
||||
/v1.23/containers/1d265651cb1d5475bcb7d5db21679757d5527d44a41c102c6aa4bddaa518c547/start
|
||||
returned error: oci runtime error: container_linux.go:317: starting
|
||||
container process caused \"process_linux.go:358: container init caused
|
||||
\\\"rootfs_linux.go:105: jailing process inside rootfs caused
|
||||
\\\\\\\"pivot_root invalid argument\\\\\\\"\\\"\"\n
|
||||
```
|
||||
|
||||
Change-Id: Icde1638af6ad45c762c11fc8a2b8a969b6306ca5
|
||||
Signed-off-by: wangfengtu <wangfengtu@huawei.com>
|
||||
---
|
||||
libcontainer/rootfs_linux.go | 32 ++++++++++++----------
|
||||
.../docker/docker/pkg/mount/mountinfo_linux.go | 7 +++--
|
||||
2 files changed, 21 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index 3dd5113..53797e9 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -24,7 +24,10 @@ import (
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
-const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
|
||||
+const (
|
||||
+ defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
|
||||
+ maxRetryTimes = 5
|
||||
+)
|
||||
|
||||
// needsSetupDev returns true if /dev needs to be set up.
|
||||
func needsSetupDev(config *configs.Config) bool {
|
||||
@@ -545,23 +548,16 @@ func getMountInfo(mountinfo []*mount.Info, dir string) *mount.Info {
|
||||
// Get the parent mount point of directory passed in as argument. Also return
|
||||
// optional fields.
|
||||
func getParentMount(rootfs string) (string, string, error) {
|
||||
- var path string
|
||||
-
|
||||
- mountinfos, err := mount.GetMounts()
|
||||
- if err != nil {
|
||||
- return "", "", err
|
||||
- }
|
||||
-
|
||||
- mountinfo := getMountInfo(mountinfos, rootfs)
|
||||
- if mountinfo != nil {
|
||||
- return rootfs, mountinfo.Optional, nil
|
||||
- }
|
||||
+ retryTimes := maxRetryTimes
|
||||
+ path := rootfs
|
||||
|
||||
- path = rootfs
|
||||
for {
|
||||
- path = filepath.Dir(path)
|
||||
+ mountinfos, err := mount.GetMounts()
|
||||
+ if err != nil {
|
||||
+ return "", "", err
|
||||
+ }
|
||||
|
||||
- mountinfo = getMountInfo(mountinfos, path)
|
||||
+ mountinfo := getMountInfo(mountinfos, path)
|
||||
if mountinfo != nil {
|
||||
return path, mountinfo.Optional, nil
|
||||
}
|
||||
@@ -569,6 +565,12 @@ func getParentMount(rootfs string) (string, string, error) {
|
||||
if path == "/" {
|
||||
break
|
||||
}
|
||||
+
|
||||
+ retryTimes--
|
||||
+ if retryTimes == 0 {
|
||||
+ retryTimes = maxRetryTimes
|
||||
+ path = filepath.Dir(path)
|
||||
+ }
|
||||
}
|
||||
|
||||
// If we are here, we did not find parent mount. Something is wrong.
|
||||
diff --git a/vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go b/vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go
|
||||
index be69fee..b74773f 100644
|
||||
--- a/vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go
|
||||
+++ b/vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go
|
||||
@@ -4,8 +4,10 @@ package mount
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
+ "bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
+ "io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
@@ -31,13 +33,12 @@ const (
|
||||
// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
|
||||
// bind mounts
|
||||
func parseMountTable() ([]*Info, error) {
|
||||
- f, err := os.Open("/proc/self/mountinfo")
|
||||
+ content, err := ioutil.ReadFile("/proc/self/mountinfo")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
- defer f.Close()
|
||||
|
||||
- return parseInfoFile(f)
|
||||
+ return parseInfoFile(bytes.NewReader(content))
|
||||
}
|
||||
|
||||
func parseInfoFile(r io.Reader) ([]*Info, error) {
|
||||
--
|
||||
2.7.4
|
||||
|
||||
40
patch/0098-runc-fix-read-only-containers-under-userns-.patch
Normal file
40
patch/0098-runc-fix-read-only-containers-under-userns-.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 6e35f145221347264ea5d4814308ab0624725024 Mon Sep 17 00:00:00 2001
|
||||
From: zhangsong34 <zhangsong34@huawei.com>
|
||||
Date: Tue, 2 Apr 2019 10:00:20 +0800
|
||||
Subject: [PATCH] runc: fix --read-only containers under
|
||||
--userns-remap
|
||||
|
||||
reason:fix --read-only containers under --userns-remap
|
||||
cherry-pick from:
|
||||
https://github.com/opencontainers/runc/pull/1572
|
||||
|
||||
Change-Id: I0f823caf1e72e4d61df9abe5f97fa5605425fd2c
|
||||
Signed-off-by: Tycho Andersen <tycho@docker.com>
|
||||
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||||
---
|
||||
libcontainer/rootfs_linux.go | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index 53797e9..18a25f2 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -769,7 +769,14 @@ func remountReadonly(m *configs.Mount) error {
|
||||
flags = m.Flags
|
||||
)
|
||||
for i := 0; i < 5; i++ {
|
||||
- if err := syscall.Mount("", dest, "", uintptr(flags|syscall.MS_REMOUNT|syscall.MS_RDONLY), ""); err != nil {
|
||||
+ // There is a special case in the kernel for
|
||||
+ // MS_REMOUNT | MS_BIND, which allows us to change only the
|
||||
+ // flags even as an unprivileged user (i.e. user namespace)
|
||||
+ // assuming we don't drop any security related flags (nodev,
|
||||
+ // nosuid, etc.). So, let's use that case so that we can do
|
||||
+ // this re-mount without failing in a userns.
|
||||
+ flags |= syscall.MS_REMOUNT | syscall.MS_BIND | syscall.MS_RDONLY
|
||||
+ if err := syscall.Mount("", dest, "", uintptr(flags), ""); err != nil {
|
||||
switch err {
|
||||
case syscall.EBUSY:
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
49
patch/0099-runc-enable-bep-ldflags.patch
Normal file
49
patch/0099-runc-enable-bep-ldflags.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From e2d3a9925386b07e15db79ceee1e5430eed13c26 Mon Sep 17 00:00:00 2001
|
||||
From: jingrui <jingrui@huawei.com>
|
||||
Date: Thu, 11 Apr 2019 23:32:01 +0800
|
||||
Subject: [PATCH] runc: enable bep ldflags
|
||||
|
||||
Change-Id: I9221cb54e470b6c511f7962294bf405de00549c7
|
||||
Signed-off-by: jingrui <jingrui@huawei.com>
|
||||
---
|
||||
Makefile | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index f043d0bc..76423d83 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -24,21 +24,26 @@ VERSION := ${shell cat ./VERSION}
|
||||
|
||||
SHELL := $(shell command -v bash 2>/dev/null)
|
||||
|
||||
+BEP_DIR := "/tmp/runc-build-bep"
|
||||
+BEP_FLAG := "-tmpdir=${BEP_DIR}"
|
||||
+
|
||||
.DEFAULT: runc
|
||||
|
||||
runc: $(SOURCES)
|
||||
- go build -i -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o runc .
|
||||
+ mkdir -p ${BEP_DIR}
|
||||
+ go build -i -ldflags " ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o runc .
|
||||
|
||||
all: runc recvtty
|
||||
|
||||
recvtty: contrib/cmd/recvtty/recvtty
|
||||
|
||||
contrib/cmd/recvtty/recvtty: $(SOURCES)
|
||||
- go build -i -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
+ go build -i -ldflags " ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
static: $(SOURCES)
|
||||
- CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o runc .
|
||||
- CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
+ mkdir -p ${BEP_DIR}
|
||||
+ CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o runc .
|
||||
+ CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
release:
|
||||
@flag_list=(seccomp selinux apparmor static); \
|
||||
--
|
||||
2.17.1
|
||||
|
||||
44
patch/0100-runc-set-makefile-buildid.patch
Normal file
44
patch/0100-runc-set-makefile-buildid.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 0a64bd10e05937427255dada4b6e1b12f31265f0 Mon Sep 17 00:00:00 2001
|
||||
From: xiadanni1 <xiadanni1@huawei.com>
|
||||
Date: Tue, 23 Apr 2019 22:35:45 +0800
|
||||
Subject: [PATCH] runc: set makefile buildid
|
||||
|
||||
reason: set makefile buildid
|
||||
|
||||
Change-Id: Ia547dbc383bffe6532168881a7376df1d990fd30
|
||||
Signed-off-by: xiadanni1 <xiadanni1@huawei.com>
|
||||
---
|
||||
Makefile | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 76423d8..0352e40 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -31,19 +31,19 @@ BEP_FLAG := "-tmpdir=${BEP_DIR}"
|
||||
|
||||
runc: $(SOURCES)
|
||||
mkdir -p ${BEP_DIR}
|
||||
- go build -i -ldflags " ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o runc .
|
||||
+ go build -i -ldflags " -buildid=IdByIsula ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o runc .
|
||||
|
||||
all: runc recvtty
|
||||
|
||||
recvtty: contrib/cmd/recvtty/recvtty
|
||||
|
||||
contrib/cmd/recvtty/recvtty: $(SOURCES)
|
||||
- go build -i -ldflags " ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
+ go build -i -ldflags " -buildid=IdByIsula ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
static: $(SOURCES)
|
||||
mkdir -p ${BEP_DIR}
|
||||
- CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o runc .
|
||||
- CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
+ CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -buildid=IdByIsula -extldflags -static ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o runc .
|
||||
+ CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -buildid=IdByIsula -extldflags -static ${BEP_FLAG} -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
release:
|
||||
@flag_list=(seccomp selinux apparmor static); \
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
From 574f88a1801656869b69408cf2eb0f32c6c0e4aa Mon Sep 17 00:00:00 2001
|
||||
From: xiadanni1 <xiadanni1@huawei.com>
|
||||
Date: Mon, 6 May 2019 02:49:36 +0800
|
||||
Subject: [PATCH] runc: print memory info when syscall.Exec failed
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
reason: print system and cgroup memory info when syscall.Exec failed.
|
||||
|
||||
Change-Id: I4aef0ea3da16849ab82adf45db5a828c758b33ea
|
||||
Signed-off-by: xiadanni1 <xiadanni1@huawei.com>
|
||||
---
|
||||
libcontainer/standard_init_linux.go | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go
|
||||
index fd836f3..b25669f 100644
|
||||
--- a/libcontainer/standard_init_linux.go
|
||||
+++ b/libcontainer/standard_init_linux.go
|
||||
@@ -4,12 +4,14 @@ package libcontainer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
+ "io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
+ "github.com/Sirupsen/logrus"
|
||||
"github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/keys"
|
||||
@@ -212,7 +214,24 @@ func (l *linuxStandardInit) Init() error {
|
||||
// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
|
||||
syscall.Close(l.stateDirFD)
|
||||
if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
|
||||
+ printMemoryInfo()
|
||||
return newSystemErrorWithCause(err, "exec user process")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+
|
||||
+func printMemoryInfo() {
|
||||
+ output, err := ioutil.ReadFile("/proc/meminfo")
|
||||
+ if err != nil {
|
||||
+ logrus.Errorf("Failed to read /proc/meminfo, %v", err)
|
||||
+ } else {
|
||||
+ logrus.Infof("print memory info (/proc/meminfo): %s", string(output))
|
||||
+ }
|
||||
+
|
||||
+ output, err = ioutil.ReadFile("/sys/fs/cgroup/memory/memory.stat")
|
||||
+ if err != nil {
|
||||
+ logrus.Errorf("Failed to read /sys/fs/cgroup/memory/memory.stat, %v", err)
|
||||
+ } else {
|
||||
+ logrus.Infof("print memory info (cgroup memory.stat): %s", string(output))
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user