From 6c393b0a6a3e6ed2560d9e4d75effd5997e175ea Mon Sep 17 00:00:00 2001 From: Vladimir Lavor Date: Tue, 28 May 2019 09:42:15 +0200 Subject: [PATCH] add vpp-agent-init Signed-off-by: Vladimir Lavor --- Makefile | 3 ++ cmd/vpp-agent-init/main.go | 30 +++++++++++++++ docker/dev/Dockerfile | 10 ++--- docker/dev/init_hook.sh | 17 +++++++++ docker/dev/supervisor.conf | 11 ++++++ docker/dev/supervisord.conf | 26 ------------- docker/dev/supervisord_kill.py | 66 --------------------------------- docker/prod/Dockerfile | 12 +++--- docker/prod/init_hook.sh | 17 +++++++++ docker/prod/supervisor.conf | 11 ++++++ docker/prod/supervisord.conf | 26 ------------- docker/prod/supervisord_kill.py | 66 --------------------------------- 12 files changed, 100 insertions(+), 195 deletions(-) create mode 100644 cmd/vpp-agent-init/main.go create mode 100755 docker/dev/init_hook.sh create mode 100644 docker/dev/supervisor.conf delete mode 100644 docker/dev/supervisord.conf delete mode 100755 docker/dev/supervisord_kill.py create mode 100755 docker/prod/init_hook.sh create mode 100644 docker/prod/supervisor.conf delete mode 100644 docker/prod/supervisord.conf delete mode 100755 docker/prod/supervisord_kill.py diff --git a/Makefile b/Makefile index 495a731fea..a1d5f8209b 100644 --- a/Makefile +++ b/Makefile @@ -39,16 +39,19 @@ agent: install: @echo "=> installing ${VERSION}" go install -ldflags "${LDFLAGS}" -tags="${GO_BUILD_TAGS}" ${GO_BUILD_ARGS} ./cmd/vpp-agent + go install -ldflags "${LDFLAGS}" -tags="${GO_BUILD_TAGS}" ${GO_BUILD_ARGS} ./cmd/vpp-agent-init go install -ldflags "${LDFLAGS}" -tags="${GO_BUILD_TAGS}" ${GO_BUILD_ARGS} ./cmd/agentctl cmd: @echo "=> building ${VERSION}" cd cmd/vpp-agent && go build -ldflags "${LDFLAGS}" -tags="${GO_BUILD_TAGS}" ${GO_BUILD_ARGS} + cd cmd/vpp-agent-init && go build -ldflags "${LDFLAGS}" -tags="${GO_BUILD_TAGS}" ${GO_BUILD_ARGS} cd cmd/agentctl && go build -ldflags "${LDFLAGS}" -tags="${GO_BUILD_TAGS}" ${GO_BUILD_ARGS} clean-cmd: @echo "=> cleaning command binaries" rm -f ./cmd/vpp-agent/vpp-agent + rm -f ./cmd/vpp-agent/vpp-agent-init rm -f ./cmd/agentctl/agentctl examples: diff --git a/cmd/vpp-agent-init/main.go b/cmd/vpp-agent-init/main.go new file mode 100644 index 0000000000..97c5cc9c60 --- /dev/null +++ b/cmd/vpp-agent-init/main.go @@ -0,0 +1,30 @@ +// Copyright (c) 2019 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package vpp-agent-init starts supervisor plugin managing other processes +// (VPP-Agent, VPP, ...) + +package main + +import ( + "github.com/ligato/cn-infra/agent" + sv "github.com/ligato/cn-infra/exec/supervisor" +) + +func main() { + a := agent.NewAgent(agent.AllPlugins(sv.NewPlugin())) + if err := a.Run(); err != nil { + panic(err) + } +} diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 341331e8e7..01e5488817 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -37,9 +37,7 @@ RUN apt-get update \ iputils-ping \ make \ patch \ - python \ sudo \ - supervisor \ unzip \ wget \ && rm -rf /var/lib/apt/lists/* @@ -71,11 +69,11 @@ COPY \ ./docker/dev/etcd.conf \ ./docker/dev/logs.conf \ ./docker/dev/vpp-ifplugin.conf \ + ./docker/dev/supervisor.conf \ /opt/vpp-agent/dev/ COPY ./docker/dev/vpp.conf /etc/vpp/vpp.conf -COPY ./docker/dev/supervisord.conf /etc/supervisord/supervisord.conf -COPY ./docker/dev/supervisord_kill.py /usr/bin/ +COPY ./docker/dev/init_hook.sh /usr/bin/ # Build agent WORKDIR $GOPATH/src/github.com/ligato/vpp-agent @@ -91,6 +89,8 @@ COPY . ./ RUN VERSION=$VERSION COMMIT=$COMMIT DATE=$DATE make install +ENV SUPERVISOR_CONFIG=/opt/vpp-agent/dev/supervisor.conf + # run supervisor as the default executable CMD rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api && \ - exec /usr/bin/supervisord -c /etc/supervisord/supervisord.conf + exec vpp-agent-init diff --git a/docker/dev/init_hook.sh b/docker/dev/init_hook.sh new file mode 100755 index 0000000000..e3b8ede3a8 --- /dev/null +++ b/docker/dev/init_hook.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +terminate_process () { + PID=$(pidof $1) + if [[ ${PID} != "" ]]; then + kill ${PID} + echo "process $1 terminated" + fi +} + +if [[ "${SUPERVISOR_PROCESS_NAME}" = "agent" && "${SUPERVISOR_PROCESS_STATE}" = "terminated" ]]; then + terminate_process vpp-agent-init +fi + +if [[ "${SUPERVISOR_PROCESS_NAME}" = "vpp" && "${SUPERVISOR_PROCESS_STATE}" = "terminated" ]]; then + terminate_process vpp-agent-init +fi \ No newline at end of file diff --git a/docker/dev/supervisor.conf b/docker/dev/supervisor.conf new file mode 100644 index 0000000000..c02946247f --- /dev/null +++ b/docker/dev/supervisor.conf @@ -0,0 +1,11 @@ +programs: + - name: "vpp" + executable-path: "/usr/bin/vpp" + executable-args: ["-c", "/etc/vpp/vpp.conf"] + logfile-path: "/var/log/supervisord.log" + - name: "agent" + executable-path: "/go/bin/vpp-agent" + executable-args: ["--config-dir=/opt/vpp-agent/dev"] + logfile-path: "/var/log/supervisord.log" +hooks: + - cmd: "/usr/bin/init_hook.sh" diff --git a/docker/dev/supervisord.conf b/docker/dev/supervisord.conf deleted file mode 100644 index d768e417e0..0000000000 --- a/docker/dev/supervisord.conf +++ /dev/null @@ -1,26 +0,0 @@ -[supervisord] -logfile=/var/log/supervisord.log -loglevel=debug -nodaemon=true -pidfile=/run/supervisord.pid - -[program:vpp] -command=/usr/bin/vpp -c /etc/vpp/vpp.conf -autorestart=false -redirect_stderr=true -priority=1 - -[program:agent] -command=vpp-agent --config-dir=/opt/vpp-agent/dev -startsecs=0 -autorestart=false -redirect_stderr=true -priority=2 - -; This event listener waits for event of vpp or agent exitting. -; Once received, it kills supervisord process and this makes -; subsequently the exit of docker container. -; You should also set agent's autorestart=false. -[eventlistener:vpp_or_agent_not_running] -command=/usr/bin/supervisord_kill.py -events=PROCESS_STATE_EXITED diff --git a/docker/dev/supervisord_kill.py b/docker/dev/supervisord_kill.py deleted file mode 100755 index debf647cb0..0000000000 --- a/docker/dev/supervisord_kill.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python - -import sys -import os -import signal - - -def write_stdout(msg): - # only eventlistener protocol messages may be sent to stdout - sys.stdout.write(msg) - sys.stdout.flush() - - -def write_stderr(msg): - sys.stderr.write(msg) - sys.stderr.flush() - - -def main(): - while 1: - # transition from ACKNOWLEDGED to READY - write_stdout('READY\n') - - # read header line and print it to stderr - line = sys.stdin.readline() - write_stderr('EVENT: ' + line) - - # read event payload and print it to stderr - headers = dict([x.split(':') for x in line.split()]) - data = sys.stdin.read(int(headers['len'])) - write_stderr('DATA: ' + data + '\n') - - # ignore non vpp events, skipping - parsed_data = dict([x.split(':') for x in data.split()]) - if parsed_data["processname"] not in ["vpp", "agent"]: - write_stderr('Ignoring event from ' + parsed_data["processname"] + '\n') - write_stdout('RESULT 2\nOK') - continue - - # ignore exits with expected exit codes - if parsed_data["expected"] == "1": - write_stderr('Exit state from ' + parsed_data["processname"] + ' was expected\n') - write_stdout('RESULT 2\nOK') - continue - - # do not kill supervisor if retained and exit - if 'RETAIN_SUPERVISOR' in os.environ and os.environ['RETAIN_SUPERVISOR'] != '': - write_stderr('Supervisord is configured to retain after unexpected exits (unset RETAIN_SUPERVISOR to disable it)\n') - write_stdout('RESULT 2\nOK') - continue - - try: - with open('/run/supervisord.pid', 'r') as pidfile: - pid = int(pidfile.readline()) - write_stderr('Killing supervisord with pid: ' + str(pid) + '\n') - os.kill(pid, signal.SIGQUIT) - except Exception as e: - write_stderr('Could not kill supervisor: ' + str(e) + '\n') - - # transition from READY to ACKNOWLEDGED - write_stdout('RESULT 2\nOK') - return - - -if __name__ == '__main__': - main() diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile index 930b63b5b3..6adaabe87a 100644 --- a/docker/prod/Dockerfile +++ b/docker/prod/Dockerfile @@ -18,9 +18,6 @@ RUN apt-get update \ libmbedx509-0 \ libnuma1 \ openssl \ - # other - python \ - supervisor \ && rm -rf /var/lib/apt/lists/* # install vpp @@ -42,15 +39,18 @@ COPY --from=base / / COPY --from=devimg \ /go/bin/agentctl \ /go/bin/vpp-agent \ + /go/bin/vpp-agent-init \ /bin/ # Copy configs COPY etcd.conf /opt/vpp-agent/dev/ +COPY supervisor.conf /opt/vpp-agent/dev/ COPY vpp.conf /etc/vpp/vpp.conf -COPY supervisord.conf /etc/supervisord/supervisord.conf -COPY supervisord_kill.py /usr/bin/ +COPY init_hook.sh /usr/bin/ WORKDIR /root/ +ENV SUPERVISOR_CONFIG=/opt/vpp-agent/dev/supervisor.conf + CMD rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api && \ - exec /usr/bin/supervisord -c /etc/supervisord/supervisord.conf + exec vpp-agent-init diff --git a/docker/prod/init_hook.sh b/docker/prod/init_hook.sh new file mode 100755 index 0000000000..e3b8ede3a8 --- /dev/null +++ b/docker/prod/init_hook.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +terminate_process () { + PID=$(pidof $1) + if [[ ${PID} != "" ]]; then + kill ${PID} + echo "process $1 terminated" + fi +} + +if [[ "${SUPERVISOR_PROCESS_NAME}" = "agent" && "${SUPERVISOR_PROCESS_STATE}" = "terminated" ]]; then + terminate_process vpp-agent-init +fi + +if [[ "${SUPERVISOR_PROCESS_NAME}" = "vpp" && "${SUPERVISOR_PROCESS_STATE}" = "terminated" ]]; then + terminate_process vpp-agent-init +fi \ No newline at end of file diff --git a/docker/prod/supervisor.conf b/docker/prod/supervisor.conf new file mode 100644 index 0000000000..4a7b3b903a --- /dev/null +++ b/docker/prod/supervisor.conf @@ -0,0 +1,11 @@ +programs: + - name: "vpp" + executable-path: "/usr/bin/vpp" + executable-args: ["-c", "/etc/vpp/vpp.conf"] + logfile-path: "/var/log/supervisord.log" + - name: "agent" + executable-path: "/bin/vpp-agent" + executable-args: ["--config-dir=/opt/vpp-agent/dev"] + logfile-path: "/var/log/supervisord.log" +hooks: + - cmd: "/usr/bin/init_hook.sh" diff --git a/docker/prod/supervisord.conf b/docker/prod/supervisord.conf deleted file mode 100644 index d768e417e0..0000000000 --- a/docker/prod/supervisord.conf +++ /dev/null @@ -1,26 +0,0 @@ -[supervisord] -logfile=/var/log/supervisord.log -loglevel=debug -nodaemon=true -pidfile=/run/supervisord.pid - -[program:vpp] -command=/usr/bin/vpp -c /etc/vpp/vpp.conf -autorestart=false -redirect_stderr=true -priority=1 - -[program:agent] -command=vpp-agent --config-dir=/opt/vpp-agent/dev -startsecs=0 -autorestart=false -redirect_stderr=true -priority=2 - -; This event listener waits for event of vpp or agent exitting. -; Once received, it kills supervisord process and this makes -; subsequently the exit of docker container. -; You should also set agent's autorestart=false. -[eventlistener:vpp_or_agent_not_running] -command=/usr/bin/supervisord_kill.py -events=PROCESS_STATE_EXITED diff --git a/docker/prod/supervisord_kill.py b/docker/prod/supervisord_kill.py deleted file mode 100755 index debf647cb0..0000000000 --- a/docker/prod/supervisord_kill.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python - -import sys -import os -import signal - - -def write_stdout(msg): - # only eventlistener protocol messages may be sent to stdout - sys.stdout.write(msg) - sys.stdout.flush() - - -def write_stderr(msg): - sys.stderr.write(msg) - sys.stderr.flush() - - -def main(): - while 1: - # transition from ACKNOWLEDGED to READY - write_stdout('READY\n') - - # read header line and print it to stderr - line = sys.stdin.readline() - write_stderr('EVENT: ' + line) - - # read event payload and print it to stderr - headers = dict([x.split(':') for x in line.split()]) - data = sys.stdin.read(int(headers['len'])) - write_stderr('DATA: ' + data + '\n') - - # ignore non vpp events, skipping - parsed_data = dict([x.split(':') for x in data.split()]) - if parsed_data["processname"] not in ["vpp", "agent"]: - write_stderr('Ignoring event from ' + parsed_data["processname"] + '\n') - write_stdout('RESULT 2\nOK') - continue - - # ignore exits with expected exit codes - if parsed_data["expected"] == "1": - write_stderr('Exit state from ' + parsed_data["processname"] + ' was expected\n') - write_stdout('RESULT 2\nOK') - continue - - # do not kill supervisor if retained and exit - if 'RETAIN_SUPERVISOR' in os.environ and os.environ['RETAIN_SUPERVISOR'] != '': - write_stderr('Supervisord is configured to retain after unexpected exits (unset RETAIN_SUPERVISOR to disable it)\n') - write_stdout('RESULT 2\nOK') - continue - - try: - with open('/run/supervisord.pid', 'r') as pidfile: - pid = int(pidfile.readline()) - write_stderr('Killing supervisord with pid: ' + str(pid) + '\n') - os.kill(pid, signal.SIGQUIT) - except Exception as e: - write_stderr('Could not kill supervisor: ' + str(e) + '\n') - - # transition from READY to ACKNOWLEDGED - write_stdout('RESULT 2\nOK') - return - - -if __name__ == '__main__': - main()