Updated to 1.0.0-rc9

This commit is contained in:
Алзим 2019-10-12 03:11:07 +03:00
parent 6aa3c0d556
commit 19079a8f19
4 changed files with 334 additions and 57 deletions

View file

@ -1,2 +1,2 @@
sources: sources:
v1.0.0-rc2.tar.gz: e85ee8387c2ce47b6162333efd1898adcb1dca08 runc-d736ef1.tar.gz: 812dbd873389db38f03438166784aee998146d30

1
.gitignore vendored
View file

@ -1 +0,0 @@
src

275
1807.patch Normal file
View file

@ -0,0 +1,275 @@
From a52f7bfdea91550eee25ee5af1efed4bf1def869 Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <gscrivan@redhat.com>
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 <gscrivan@redhat.com>
---
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 := &notifySocket{
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, &notifySocketHostAddr)
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.

113
runc.spec
View file

@ -1,79 +1,82 @@
%define _libexecdir /usr/libexec %define debug_package %{nil}
%define debugcflags %nil
#debuginfo not supported with Go %define import_path github.com/opencontainers/runc
%global debug_package %{nil} %define commit0 d736ef14f0288d6993a1845745d6756cfc9ddd5a
%global import_path github.com/opencontainers/runc %define shortcommit0 %(c=%{commit0}; echo ${c:0:7})
%global go_dir %{_libdir}/go %define pre rc9
%define gosrc %{go_dir}/src/%{import_path}
%define provider github
%define provider_tld com
%define project opencontainers
%define shortcommit 4dc5990
%define pre rc2
Name: runc Summary: CLI for running Open Containers
Version: 1.0.0 Name: runc
# drop me on release Version: 1.0.0
Epoch: 1 Release: 0.%{pre}.1
Release: %{?pre:0.%{pre}.}4 Epoch: 1
Summary: CLI tool for spawning and running containers License: ASL 2.0
License: ASL 2.0 Group: System/Kernel and hardware
Group: System/Base Url: https://github.com/opencontainers/runc
URL: http://www.docker.com Source0: https://github.com/opencontainers/runc/archive/%{commit0}/%{name}-%{shortcommit0}.tar.gz
Source0: https://%{import_path}/archive/v%{version}%{?pre:-%{pre}}.tar.gz Patch0: 1807.patch
BuildRequires: glibc-static-devel
BuildRequires: golang BuildRequires: go-md2man
BuildRequires: pkgconfig(sqlite3) BuildRequires: golang
BuildRequires: git
BuildRequires: glibc-static-devel
BuildRequires: pkgconfig(libseccomp) BuildRequires: pkgconfig(libseccomp)
BuildRequires: go-md2man
BuildRequires: pkgconfig(systemd)
BuildRequires: pkgconfig(devmapper)
BuildRequires: btrfs-devel
Requires: systemd
# need xz to work with ubuntu images # need xz to work with ubuntu images
# https://bugzilla.redhat.com/show_bug.cgi?id=1045220 # https://bugzilla.redhat.com/show_bug.cgi?id=1045220
Requires: xz Requires: xz
# https://bugzilla.redhat.com/show_bug.cgi?id=1034919 # https://bugzilla.redhat.com/show_bug.cgi?id=1034919
# No longer needed in Fedora because of libcontainer # No longer needed in Fedora because of libcontainer
Requires: libcgroup Requires: libcgroup
Requires: e2fsprogs Requires: e2fsprogs
Requires: iptables Requires: iptables
%rename opencontainers-runc %rename opencontainers-runc
%description %description
runc is a CLI tool for spawning and running containers The runc command can be used to start containers which are packaged
according to the OCI specification. 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 %prep
%setup -qn %{name}-%{version}%{?pre:-%{pre}} %setup -qn %{name}-%{commit0}
%apply_patches %patch0 -p1
%build %build
mkdir -p GOPATH mkdir -p GOPATH
pushd GOPATH pushd GOPATH
mkdir -p src/%{provider}.%{provider_tld}/%{project} mkdir -p src/github.com/opencontainers
ln -s $(dirs +1 -l) src/%{import_path} ln -s $(dirs +1 -l) src/%{import_path}
popd popd
pushd GOPATH/src/%{import_path}
export GOPATH=%{gopath}:$(pwd)/GOPATH
mkdir -p bfd pushd GOPATH/src/%{import_path}
ln -s %{_bindir}/ld.bfd bfd/ld export GOPATH=%{_builddir}:$(pwd)/GOPATH
export PATH=$PWD/bfd:$PATH
%make BUILDTAGS="" make BUILDTAGS="seccomp selinux" all
sed -i '/\#\!\/bin\/bash/d' contrib/completions/bash/%{name}
popd
%install %install
# install binary install -d -p %{buildroot}%{_bindir}
install -d %{buildroot}%{_sbindir} install -p -m 755 %{name} %{buildroot}%{_bindir}
install -p -m 755 runc %{buildroot}%{_sbindir}/
ln -s runc %{buildroot}%{_sbindir}/docker-runc
%files # generate man pages
%{_sbindir}/runc man/md2man-all.sh
%{_sbindir}/docker-runc
# 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}