From 19079a8f19c71880b0ea8460743414c1fabac833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B7=D0=B8=D0=BC?= Date: Sat, 12 Oct 2019 03:11:07 +0300 Subject: [PATCH] Updated to 1.0.0-rc9 --- .abf.yml | 2 +- .gitignore | 1 - 1807.patch | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++++ runc.spec | 113 +++++++++++----------- 4 files changed, 334 insertions(+), 57 deletions(-) delete mode 100644 .gitignore create mode 100644 1807.patch diff --git a/.abf.yml b/.abf.yml index 079340a..1d1a0bd 100644 --- a/.abf.yml +++ b/.abf.yml @@ -1,2 +1,2 @@ sources: - v1.0.0-rc2.tar.gz: e85ee8387c2ce47b6162333efd1898adcb1dca08 + runc-d736ef1.tar.gz: 812dbd873389db38f03438166784aee998146d30 diff --git a/.gitignore b/.gitignore deleted file mode 100644 index e831038..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -src \ No newline at end of file diff --git a/1807.patch b/1807.patch new file mode 100644 index 0000000..69dc019 --- /dev/null +++ b/1807.patch @@ -0,0 +1,275 @@ +From a52f7bfdea91550eee25ee5af1efed4bf1def869 Mon Sep 17 00:00:00 2001 +From: Giuseppe Scrivano +Date: Fri, 25 May 2018 18:04:06 +0200 +Subject: [PATCH] sd-notify: do not hang when NOTIFY_SOCKET is used with create + +if NOTIFY_SOCKET is used, do not block the main runc process waiting +for events on the notify socket. Bind mount the parent directory of +the notify socket, so that "start" can create the socket and it is +still accessible from the container. + +Signed-off-by: Giuseppe Scrivano +--- + notify_socket.go | 113 ++++++++++++++++++++++++++++++++++------------- + signals.go | 4 +- + start.go | 13 +++++- + utils_linux.go | 12 ++++- + 4 files changed, 106 insertions(+), 36 deletions(-) + +diff --git a/notify_socket.go b/notify_socket.go +index b890b5b1c..286ce1ddd 100644 +--- a/notify_socket.go ++++ b/notify_socket.go +@@ -7,11 +7,14 @@ + "fmt" + "net" + "os" ++ "path" + "path/filepath" ++ "strconv" ++ "time" + ++ "github.com/opencontainers/runc/libcontainer" + "github.com/opencontainers/runtime-spec/specs-go" + +- "github.com/sirupsen/logrus" + "github.com/urfave/cli" + ) + +@@ -26,12 +29,12 @@ func newNotifySocket(context *cli.Context, notifySocketHost string, id string) * + } + + root := filepath.Join(context.GlobalString("root"), id) +- path := filepath.Join(root, "notify.sock") ++ socketPath := filepath.Join(root, "notify", "notify.sock") + + notifySocket := ¬ifySocket{ + socket: nil, + host: notifySocketHost, +- socketPath: path, ++ socketPath: socketPath, + } + + return notifySocket +@@ -43,13 +46,19 @@ func (s *notifySocket) Close() error { + + // If systemd is supporting sd_notify protocol, this function will add support + // for sd_notify protocol from within the container. +-func (s *notifySocket) setupSpec(context *cli.Context, spec *specs.Spec) { +- mount := specs.Mount{Destination: s.host, Source: s.socketPath, Options: []string{"bind"}} ++func (s *notifySocket) setupSpec(context *cli.Context, spec *specs.Spec) error { ++ pathInContainer := filepath.Join("/run/notify", path.Base(s.socketPath)) ++ mount := specs.Mount{ ++ Destination: path.Dir(pathInContainer), ++ Source: path.Dir(s.socketPath), ++ Options: []string{"bind", "nosuid", "noexec", "nodev", "ro"}, ++ } + spec.Mounts = append(spec.Mounts, mount) +- spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", s.host)) ++ spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", pathInContainer)) ++ return nil + } + +-func (s *notifySocket) setupSocket() error { ++func (s *notifySocket) bindSocket() error { + addr := net.UnixAddr{ + Name: s.socketPath, + Net: "unixgram", +@@ -64,45 +73,89 @@ func (s *notifySocket) setupSocket() error { + return nil + } + +-// pid1 must be set only with -d, as it is used to set the new process as the main process +-// for the service in systemd +-func (s *notifySocket) run(pid1 int) { +- buf := make([]byte, 512) +- notifySocketHostAddr := net.UnixAddr{Name: s.host, Net: "unixgram"} ++func (s *notifySocket) setupSocketDirectory() error { ++ return os.Mkdir(path.Dir(s.socketPath), 0755) ++} ++ ++func notifySocketStart(context *cli.Context, notifySocketHost, id string) (*notifySocket, error) { ++ notifySocket := newNotifySocket(context, notifySocketHost, id) ++ if notifySocket == nil { ++ return nil, nil ++ } ++ ++ if err := notifySocket.bindSocket(); err != nil { ++ return nil, err ++ } ++ return notifySocket, nil ++} ++ ++func (n *notifySocket) waitForContainer(container libcontainer.Container) error { ++ s, err := container.State() ++ if err != nil { ++ return err ++ } ++ return n.run(s.InitProcessPid) ++} ++ ++func (n *notifySocket) run(pid1 int) error { ++ if n.socket == nil { ++ return nil ++ } ++ notifySocketHostAddr := net.UnixAddr{Name: n.host, Net: "unixgram"} + client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr) + if err != nil { +- logrus.Error(err) +- return ++ return err + } +- for { +- r, err := s.socket.Read(buf) +- if err != nil { +- break ++ ++ ticker := time.NewTicker(time.Millisecond * 100) ++ defer ticker.Stop() ++ ++ fileChan := make(chan []byte) ++ go func() { ++ for { ++ buf := make([]byte, 512) ++ r, err := n.socket.Read(buf) ++ if err != nil { ++ return ++ } ++ got := buf[0:r] ++ if !bytes.HasPrefix(got, []byte("READY=")) { ++ continue ++ } ++ fileChan <- got ++ return + } +- var out bytes.Buffer +- for _, line := range bytes.Split(buf[0:r], []byte{'\n'}) { +- if bytes.HasPrefix(line, []byte("READY=")) { ++ }() ++ ++ for { ++ select { ++ case <-ticker.C: ++ _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid1))) ++ if err != nil { ++ return nil ++ } ++ case b := <-fileChan: ++ for _, line := range bytes.Split(b, []byte{'\n'}) { ++ var out bytes.Buffer + _, err = out.Write(line) + if err != nil { +- return ++ return err + } + + _, err = out.Write([]byte{'\n'}) + if err != nil { +- return ++ return err + } + + _, err = client.Write(out.Bytes()) + if err != nil { +- return ++ return err + } + + // now we can inform systemd to use pid1 as the pid to monitor +- if pid1 > 0 { +- newPid := fmt.Sprintf("MAINPID=%d\n", pid1) +- client.Write([]byte(newPid)) +- } +- return ++ newPid := fmt.Sprintf("MAINPID=%d\n", pid1) ++ client.Write([]byte(newPid)) ++ return nil + } + } + } +diff --git a/signals.go b/signals.go +index b67f65a03..dd25e094c 100644 +--- a/signals.go ++++ b/signals.go +@@ -70,6 +70,7 @@ func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach + h.notifySocket.run(pid1) + return 0, nil + } ++ h.notifySocket.run(os.Getpid()) + go h.notifySocket.run(0) + } + +@@ -97,9 +98,6 @@ func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach + // status because we must ensure that any of the go specific process + // fun such as flushing pipes are complete before we return. + process.Wait() +- if h.notifySocket != nil { +- h.notifySocket.Close() +- } + return e.status, nil + } + } +diff --git a/start.go b/start.go +index 2bb698b20..3a1769a43 100644 +--- a/start.go ++++ b/start.go +@@ -3,6 +3,7 @@ package main + import ( + "errors" + "fmt" ++ "os" + + "github.com/opencontainers/runc/libcontainer" + "github.com/urfave/cli" +@@ -31,7 +32,17 @@ your host.`, + } + switch status { + case libcontainer.Created: +- return container.Exec() ++ notifySocket, err := notifySocketStart(context, os.Getenv("NOTIFY_SOCKET"), container.ID()) ++ if err != nil { ++ return err ++ } ++ if err := container.Exec(); err != nil { ++ return err ++ } ++ if notifySocket != nil { ++ return notifySocket.waitForContainer(container) ++ } ++ return nil + case libcontainer.Stopped: + return errors.New("cannot start a container that has stopped") + case libcontainer.Running: +diff --git a/utils_linux.go b/utils_linux.go +index a37b1c3df..4921bd94b 100644 +--- a/utils_linux.go ++++ b/utils_linux.go +@@ -401,7 +401,9 @@ func startContainer(context *cli.Context, spec *specs.Spec, action CtAct, criuOp + + notifySocket := newNotifySocket(context, os.Getenv("NOTIFY_SOCKET"), id) + if notifySocket != nil { +- notifySocket.setupSpec(context, spec) ++ if err := notifySocket.setupSpec(context, spec); err != nil { ++ return -1, err ++ } + } + + container, err := createContainer(context, id, spec) +@@ -410,10 +412,16 @@ func startContainer(context *cli.Context, spec *specs.Spec, action CtAct, criuOp + } + + if notifySocket != nil { +- err := notifySocket.setupSocket() ++ err := notifySocket.setupSocketDirectory() + if err != nil { + return -1, err + } ++ if action == CT_ACT_RUN { ++ err := notifySocket.bindSocket() ++ if err != nil { ++ return -1, err ++ } ++ } + } + + // Support on-demand socket activation by passing file descriptors into the container init process. diff --git a/runc.spec b/runc.spec index 4640cd6..a28493f 100644 --- a/runc.spec +++ b/runc.spec @@ -1,79 +1,82 @@ -%define _libexecdir /usr/libexec -%define debugcflags %nil +%define debug_package %{nil} -#debuginfo not supported with Go -%global debug_package %{nil} -%global import_path github.com/opencontainers/runc -%global go_dir %{_libdir}/go -%define gosrc %{go_dir}/src/%{import_path} -%define provider github -%define provider_tld com -%define project opencontainers -%define shortcommit 4dc5990 -%define pre rc2 +%define import_path github.com/opencontainers/runc +%define commit0 d736ef14f0288d6993a1845745d6756cfc9ddd5a +%define shortcommit0 %(c=%{commit0}; echo ${c:0:7}) +%define pre rc9 -Name: runc -Version: 1.0.0 -# drop me on release -Epoch: 1 -Release: %{?pre:0.%{pre}.}4 -Summary: CLI tool for spawning and running containers -License: ASL 2.0 -Group: System/Base -URL: http://www.docker.com -Source0: https://%{import_path}/archive/v%{version}%{?pre:-%{pre}}.tar.gz -BuildRequires: glibc-static-devel +Summary: CLI for running Open Containers +Name: runc +Version: 1.0.0 +Release: 0.%{pre}.1 +Epoch: 1 +License: ASL 2.0 +Group: System/Kernel and hardware +Url: https://github.com/opencontainers/runc +Source0: https://github.com/opencontainers/runc/archive/%{commit0}/%{name}-%{shortcommit0}.tar.gz +Patch0: 1807.patch -BuildRequires: golang -BuildRequires: pkgconfig(sqlite3) +BuildRequires: go-md2man +BuildRequires: golang +BuildRequires: git +BuildRequires: glibc-static-devel BuildRequires: pkgconfig(libseccomp) -BuildRequires: go-md2man -BuildRequires: pkgconfig(systemd) -BuildRequires: pkgconfig(devmapper) -BuildRequires: btrfs-devel -Requires: systemd - # need xz to work with ubuntu images # https://bugzilla.redhat.com/show_bug.cgi?id=1045220 -Requires: xz +Requires: xz # https://bugzilla.redhat.com/show_bug.cgi?id=1034919 # No longer needed in Fedora because of libcontainer -Requires: libcgroup -Requires: e2fsprogs -Requires: iptables +Requires: libcgroup +Requires: e2fsprogs +Requires: iptables %rename opencontainers-runc %description -runc is a CLI tool for spawning and running containers -according to the OCI specification. +The runc command can be used to start containers which are packaged +in accordance with the Open Container Initiative's specifications, +and to manage containers running under runc. + +%files +%{_bindir}/%{name} +%{_bindir}/docker-%{name} +%{_mandir}/man8/%{name}* +%{_datadir}/bash-completion/completions/%{name} + +#---------------------------------------------------------------- %prep -%setup -qn %{name}-%{version}%{?pre:-%{pre}} -%apply_patches - +%setup -qn %{name}-%{commit0} +%patch0 -p1 %build mkdir -p GOPATH pushd GOPATH - mkdir -p src/%{provider}.%{provider_tld}/%{project} - ln -s $(dirs +1 -l) src/%{import_path} + mkdir -p src/github.com/opencontainers + ln -s $(dirs +1 -l) src/%{import_path} popd -pushd GOPATH/src/%{import_path} -export GOPATH=%{gopath}:$(pwd)/GOPATH -mkdir -p bfd -ln -s %{_bindir}/ld.bfd bfd/ld -export PATH=$PWD/bfd:$PATH -%make BUILDTAGS="" +pushd GOPATH/src/%{import_path} +export GOPATH=%{_builddir}:$(pwd)/GOPATH + +make BUILDTAGS="seccomp selinux" all + +sed -i '/\#\!\/bin\/bash/d' contrib/completions/bash/%{name} +popd %install -# install binary -install -d %{buildroot}%{_sbindir} -install -p -m 755 runc %{buildroot}%{_sbindir}/ -ln -s runc %{buildroot}%{_sbindir}/docker-runc +install -d -p %{buildroot}%{_bindir} +install -p -m 755 %{name} %{buildroot}%{_bindir} -%files -%{_sbindir}/runc -%{_sbindir}/docker-runc +# generate man pages +man/md2man-all.sh + +# install man pages +install -d -p %{buildroot}%{_mandir}/man8 +install -p -m 0644 man/man8/*.8 %{buildroot}%{_mandir}/man8/. +# install bash completion +install -d -p %{buildroot}%{_datadir}/bash-completion/completions +install -p -m 0644 contrib/completions/bash/%{name} %{buildroot}%{_datadir}/bash-completion/completions + +ln -s %{name} %{buildroot}%{_bindir}/docker-%{name}