From 7156fcdb9569019269853b611f42de8e4cb30a78 Mon Sep 17 00:00:00 2001 From: Spencer Date: Tue, 20 Feb 2024 09:18:53 +0000 Subject: [PATCH 01/15] Added supervisor.d --- scripts/docker/nginx-oss/deb/Dockerfile | 2 ++ scripts/docker/supervisor.d/agent.conf | 8 ++++++++ scripts/docker/supervisor.d/nginx.conf | 8 ++++++++ 3 files changed, 18 insertions(+) create mode 100644 scripts/docker/supervisor.d/agent.conf create mode 100644 scripts/docker/supervisor.d/nginx.conf diff --git a/scripts/docker/nginx-oss/deb/Dockerfile b/scripts/docker/nginx-oss/deb/Dockerfile index 988cbfe13d..0dfc5eb772 100644 --- a/scripts/docker/nginx-oss/deb/Dockerfile +++ b/scripts/docker/nginx-oss/deb/Dockerfile @@ -7,6 +7,8 @@ ARG ENTRY_POINT ARG PACKAGE_NAME ARG PACKAGES_REPO +COPY ./scripts/docker/supervisor.d/*.conf etc/supervisor.d/ + WORKDIR /agent COPY ./build /agent/build COPY $ENTRY_POINT /agent/entrypoint.sh diff --git a/scripts/docker/supervisor.d/agent.conf b/scripts/docker/supervisor.d/agent.conf new file mode 100644 index 0000000000..ccc170cc0c --- /dev/null +++ b/scripts/docker/supervisor.d/agent.conf @@ -0,0 +1,8 @@ +[program:nginx-agent] +command=/usr/bin/nginx-agent +stopsignal=QUIT +stopwaitseconds=60 +stdout_logfile=/dev/stdout +stderr_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile_maxbytes=0 \ No newline at end of file diff --git a/scripts/docker/supervisor.d/nginx.conf b/scripts/docker/supervisor.d/nginx.conf new file mode 100644 index 0000000000..fd8e91034c --- /dev/null +++ b/scripts/docker/supervisor.d/nginx.conf @@ -0,0 +1,8 @@ +[program:nginx] +command=/usr/sbin/nginx -g 'daemon off;' +stopsignal=QUIT +stopwaitseconds=60 +stdout_logfile=/dev/stdout +stderr_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile_maxbytes=0 \ No newline at end of file From 317da66aca9256c7da48d2ff009727c22270cd5c Mon Sep 17 00:00:00 2001 From: Spencer Date: Tue, 20 Feb 2024 15:01:28 +0000 Subject: [PATCH 02/15] Installed supervisor into the Docker Image --- scripts/docker/nginx-oss/deb/Dockerfile | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/docker/nginx-oss/deb/Dockerfile b/scripts/docker/nginx-oss/deb/Dockerfile index 0dfc5eb772..95ab8f7aa6 100644 --- a/scripts/docker/nginx-oss/deb/Dockerfile +++ b/scripts/docker/nginx-oss/deb/Dockerfile @@ -7,11 +7,10 @@ ARG ENTRY_POINT ARG PACKAGE_NAME ARG PACKAGES_REPO -COPY ./scripts/docker/supervisor.d/*.conf etc/supervisor.d/ +COPY ./scripts/docker/supervisor.d/*.conf etc/supervisor/conf.d/ WORKDIR /agent COPY ./build /agent/build -COPY $ENTRY_POINT /agent/entrypoint.sh RUN set -x \ && addgroup --system --gid 101 nginx \ @@ -24,18 +23,18 @@ RUN set -x \ curl \ lsb-release \ procps \ - nginx + nginx \ + supervisor # Setup nginx agent repository RUN curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \ && printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://${PACKAGES_REPO}/nginx-agent/ubuntu/ `lsb_release -cs` agent\n" > /etc/apt/sources.list.d/nginx-agent.list -RUN chmod +x /agent/entrypoint.sh -STOPSIGNAL SIGTERM +STOPSIGNAL SIGQUIT EXPOSE 80 443 -ENTRYPOINT ["/agent/entrypoint.sh"] +CMD ["/usr/bin/supervisord", "-c","/etc/supervisor/supervisord.conf"] FROM install-nginx as install-agent-local From fe59ae914bf3da8c31f66f1e56068fdeeeff7b0d Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 7 Mar 2024 11:18:08 +0000 Subject: [PATCH 03/15] changes to registration.go to make it continuously search for NGINX --- scripts/docker/nginx-oss/deb/Dockerfile | 6 ++--- scripts/docker/supervisor.d/agent.conf | 8 ------ scripts/docker/supervisor.d/nginx.conf | 11 +++++++- src/plugins/registration.go | 34 +++++++++++++++---------- 4 files changed, 34 insertions(+), 25 deletions(-) delete mode 100644 scripts/docker/supervisor.d/agent.conf diff --git a/scripts/docker/nginx-oss/deb/Dockerfile b/scripts/docker/nginx-oss/deb/Dockerfile index 95ab8f7aa6..76a4bfa4fb 100644 --- a/scripts/docker/nginx-oss/deb/Dockerfile +++ b/scripts/docker/nginx-oss/deb/Dockerfile @@ -7,7 +7,7 @@ ARG ENTRY_POINT ARG PACKAGE_NAME ARG PACKAGES_REPO -COPY ./scripts/docker/supervisor.d/*.conf etc/supervisor/conf.d/ +COPY ./scripts/docker/supervisor.d/nginx.conf etc/supervisor/conf.d/ WORKDIR /agent COPY ./build /agent/build @@ -24,7 +24,7 @@ RUN set -x \ lsb-release \ procps \ nginx \ - supervisor + supervisor # Setup nginx agent repository RUN curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \ @@ -34,7 +34,7 @@ STOPSIGNAL SIGQUIT EXPOSE 80 443 -CMD ["/usr/bin/supervisord", "-c","/etc/supervisor/supervisord.conf"] +ENTRYPOINT ["/usr/bin/supervisord", "-c","/etc/supervisor/supervisord.conf", "-u", "root", "--nodaemon", "--logfile", "/dev/stdout", "--logfile_maxbytes", "0" ] FROM install-nginx as install-agent-local diff --git a/scripts/docker/supervisor.d/agent.conf b/scripts/docker/supervisor.d/agent.conf deleted file mode 100644 index ccc170cc0c..0000000000 --- a/scripts/docker/supervisor.d/agent.conf +++ /dev/null @@ -1,8 +0,0 @@ -[program:nginx-agent] -command=/usr/bin/nginx-agent -stopsignal=QUIT -stopwaitseconds=60 -stdout_logfile=/dev/stdout -stderr_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile_maxbytes=0 \ No newline at end of file diff --git a/scripts/docker/supervisor.d/nginx.conf b/scripts/docker/supervisor.d/nginx.conf index fd8e91034c..cc18d49bce 100644 --- a/scripts/docker/supervisor.d/nginx.conf +++ b/scripts/docker/supervisor.d/nginx.conf @@ -1,5 +1,14 @@ [program:nginx] -command=/usr/sbin/nginx -g 'daemon off;' +command=bash -c "sleep 30 && echo 'running nginx' && /usr/sbin/nginx -g 'daemon off;'" +stopsignal=QUIT +stopwaitseconds=60 +stdout_logfile=/dev/stdout +stderr_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile_maxbytes=0 + +[program:nginx-agent] +command=/usr/bin/nginx-agent stopsignal=QUIT stopwaitseconds=60 stdout_logfile=/dev/stdout diff --git a/src/plugins/registration.go b/src/plugins/registration.go index 535e01fee8..addd60eb15 100644 --- a/src/plugins/registration.go +++ b/src/plugins/registration.go @@ -93,6 +93,8 @@ func (r *OneTimeRegistration) Process(msg *core.Message) { defer r.dataplaneSoftwareDetailsMutex.Unlock() r.dataplaneSoftwareDetails[data.GetPluginName()] = data.GetDataplaneSoftwareDetails() } + case msg.Exact(core.NginxDetailProcUpdate): + r.processes = msg.Data().([]*core.Process) } } @@ -100,6 +102,7 @@ func (r *OneTimeRegistration) Subscriptions() []string { return []string{ core.RegistrationCompletedTopic, core.DataplaneSoftwareDetailsUpdated, + core.NginxDetailProcUpdate, } } @@ -153,22 +156,27 @@ func (r *OneTimeRegistration) areDataplaneSoftwareDetailsReady() error { func (r *OneTimeRegistration) registerAgent() { var details []*proto.NginxDetails - for _, proc := range r.processes { - // only need master process for registration - if proc.IsMaster { - nginxDetails := r.binary.GetNginxDetailsFromProcess(proc) - details = append(details, nginxDetails) - // Reading nginx config during registration to populate nginx fields like access/error logs, etc. - _, err := r.binary.ReadConfig(nginxDetails.GetConfPath(), nginxDetails.NginxId, r.env.GetSystemUUID()) - if err != nil { - log.Warnf("Unable to read config for NGINX instance %s, %v", nginxDetails.NginxId, err) + findMaster := func() { + for _, proc := range r.processes { + // only need master process for registration + if proc.IsMaster { + nginxDetails := r.binary.GetNginxDetailsFromProcess(proc) + details = append(details, nginxDetails) + // Reading nginx config during registration to populate nginx fields like access/error logs, etc. + _, err := r.binary.ReadConfig(nginxDetails.GetConfPath(), nginxDetails.NginxId, r.env.GetSystemUUID()) + if err != nil { + log.Warnf("Unable to read config for NGINX instance %s, %v", nginxDetails.NginxId, err) + } + } else { + log.Tracef("NGINX non-master process: %d", proc.Pid) } - } else { - log.Tracef("NGINX non-master process: %d", proc.Pid) } } - if len(details) == 0 { - log.Info("No master process found") + findMaster() + for len(details) == 0 { + log.Info("No master process found, waiting 10 seconds and searching again") + time.Sleep(10 * time.Second) + findMaster() } updated, err := types.TimestampProto(r.config.Updated) if err != nil { From 1b8b468474c1e6332e28fca7dacec6c0a62345a4 Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 7 Mar 2024 11:22:48 +0000 Subject: [PATCH 04/15] changes to registration.go to make it continuously search for NGINX --- .../agent/v2/src/plugins/registration.go | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go index 535e01fee8..addd60eb15 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go @@ -93,6 +93,8 @@ func (r *OneTimeRegistration) Process(msg *core.Message) { defer r.dataplaneSoftwareDetailsMutex.Unlock() r.dataplaneSoftwareDetails[data.GetPluginName()] = data.GetDataplaneSoftwareDetails() } + case msg.Exact(core.NginxDetailProcUpdate): + r.processes = msg.Data().([]*core.Process) } } @@ -100,6 +102,7 @@ func (r *OneTimeRegistration) Subscriptions() []string { return []string{ core.RegistrationCompletedTopic, core.DataplaneSoftwareDetailsUpdated, + core.NginxDetailProcUpdate, } } @@ -153,22 +156,27 @@ func (r *OneTimeRegistration) areDataplaneSoftwareDetailsReady() error { func (r *OneTimeRegistration) registerAgent() { var details []*proto.NginxDetails - for _, proc := range r.processes { - // only need master process for registration - if proc.IsMaster { - nginxDetails := r.binary.GetNginxDetailsFromProcess(proc) - details = append(details, nginxDetails) - // Reading nginx config during registration to populate nginx fields like access/error logs, etc. - _, err := r.binary.ReadConfig(nginxDetails.GetConfPath(), nginxDetails.NginxId, r.env.GetSystemUUID()) - if err != nil { - log.Warnf("Unable to read config for NGINX instance %s, %v", nginxDetails.NginxId, err) + findMaster := func() { + for _, proc := range r.processes { + // only need master process for registration + if proc.IsMaster { + nginxDetails := r.binary.GetNginxDetailsFromProcess(proc) + details = append(details, nginxDetails) + // Reading nginx config during registration to populate nginx fields like access/error logs, etc. + _, err := r.binary.ReadConfig(nginxDetails.GetConfPath(), nginxDetails.NginxId, r.env.GetSystemUUID()) + if err != nil { + log.Warnf("Unable to read config for NGINX instance %s, %v", nginxDetails.NginxId, err) + } + } else { + log.Tracef("NGINX non-master process: %d", proc.Pid) } - } else { - log.Tracef("NGINX non-master process: %d", proc.Pid) } } - if len(details) == 0 { - log.Info("No master process found") + findMaster() + for len(details) == 0 { + log.Info("No master process found, waiting 10 seconds and searching again") + time.Sleep(10 * time.Second) + findMaster() } updated, err := types.TimestampProto(r.config.Updated) if err != nil { From 21819a343a30bf8933b55425503ab8590af17238 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 11 Mar 2024 16:51:01 +0000 Subject: [PATCH 05/15] Used backoff instead of sleep --- src/plugins/registration.go | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/plugins/registration.go b/src/plugins/registration.go index addd60eb15..6512fd4e45 100644 --- a/src/plugins/registration.go +++ b/src/plugins/registration.go @@ -29,6 +29,7 @@ const ( dataplaneSoftwareDetailsMaxWaitTime = time.Duration(5 * time.Second) // Time between attempts to gather DataplaneSoftwareDetails softwareDetailsOperationInterval = time.Duration(1 * time.Second) + nginxStartMaxWaitTime = 0 ) type OneTimeRegistration struct { @@ -139,7 +140,6 @@ func (r *OneTimeRegistration) areDataplaneSoftwareDetailsReady() error { log.Trace("No extension plugins to register") return nil } - r.dataplaneSoftwareDetailsMutex.Lock() defer r.dataplaneSoftwareDetailsMutex.Unlock() @@ -156,28 +156,43 @@ func (r *OneTimeRegistration) areDataplaneSoftwareDetailsReady() error { func (r *OneTimeRegistration) registerAgent() { var details []*proto.NginxDetails - findMaster := func() { + backoffSetting := backoff.BackoffSettings{ + InitialInterval: softwareDetailsOperationInterval, + MaxInterval: softwareDetailsOperationInterval, + MaxElapsedTime: nginxStartMaxWaitTime, + Jitter: backoff.BACKOFF_JITTER, + Multiplier: backoff.BACKOFF_MULTIPLIER, + } + + findMaster := func() error { for _, proc := range r.processes { // only need master process for registration if proc.IsMaster { nginxDetails := r.binary.GetNginxDetailsFromProcess(proc) details = append(details, nginxDetails) - // Reading nginx config during registration to populate nginx fields like access/error logs, etc. - _, err := r.binary.ReadConfig(nginxDetails.GetConfPath(), nginxDetails.NginxId, r.env.GetSystemUUID()) - if err != nil { - log.Warnf("Unable to read config for NGINX instance %s, %v", nginxDetails.NginxId, err) + if len(details) > 0 { + // Reading nginx config during registration to populate nginx fields like access/error logs, etc. + _, err := r.binary.ReadConfig(nginxDetails.GetConfPath(), nginxDetails.NginxId, r.env.GetSystemUUID()) + if err != nil { + log.Warnf("Unable to read config for NGINX instance %s, %v", nginxDetails.NginxId, err) + } + log.Info("Master process has been found") + return nil } } else { log.Tracef("NGINX non-master process: %d", proc.Pid) + return nil } } + return fmt.Errorf("No master process found, waiting...") } - findMaster() - for len(details) == 0 { - log.Info("No master process found, waiting 10 seconds and searching again") - time.Sleep(10 * time.Second) - findMaster() + err2 := backoff.WaitUntil( + context.Background(), backoffSetting, findMaster, + ) + if err2 != nil { + log.Warn(err2.Error()) } + updated, err := types.TimestampProto(r.config.Updated) if err != nil { log.Warnf("failed to parse proto timestamp %s: %s, assuming now", r.config.Updated, err) From 1936f204015146a9fcdefc0596afc89befc10945 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 11 Mar 2024 16:53:47 +0000 Subject: [PATCH 06/15] Used backoff instead of sleep --- .../agent/v2/src/plugins/registration.go | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go index addd60eb15..6512fd4e45 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go @@ -29,6 +29,7 @@ const ( dataplaneSoftwareDetailsMaxWaitTime = time.Duration(5 * time.Second) // Time between attempts to gather DataplaneSoftwareDetails softwareDetailsOperationInterval = time.Duration(1 * time.Second) + nginxStartMaxWaitTime = 0 ) type OneTimeRegistration struct { @@ -139,7 +140,6 @@ func (r *OneTimeRegistration) areDataplaneSoftwareDetailsReady() error { log.Trace("No extension plugins to register") return nil } - r.dataplaneSoftwareDetailsMutex.Lock() defer r.dataplaneSoftwareDetailsMutex.Unlock() @@ -156,28 +156,43 @@ func (r *OneTimeRegistration) areDataplaneSoftwareDetailsReady() error { func (r *OneTimeRegistration) registerAgent() { var details []*proto.NginxDetails - findMaster := func() { + backoffSetting := backoff.BackoffSettings{ + InitialInterval: softwareDetailsOperationInterval, + MaxInterval: softwareDetailsOperationInterval, + MaxElapsedTime: nginxStartMaxWaitTime, + Jitter: backoff.BACKOFF_JITTER, + Multiplier: backoff.BACKOFF_MULTIPLIER, + } + + findMaster := func() error { for _, proc := range r.processes { // only need master process for registration if proc.IsMaster { nginxDetails := r.binary.GetNginxDetailsFromProcess(proc) details = append(details, nginxDetails) - // Reading nginx config during registration to populate nginx fields like access/error logs, etc. - _, err := r.binary.ReadConfig(nginxDetails.GetConfPath(), nginxDetails.NginxId, r.env.GetSystemUUID()) - if err != nil { - log.Warnf("Unable to read config for NGINX instance %s, %v", nginxDetails.NginxId, err) + if len(details) > 0 { + // Reading nginx config during registration to populate nginx fields like access/error logs, etc. + _, err := r.binary.ReadConfig(nginxDetails.GetConfPath(), nginxDetails.NginxId, r.env.GetSystemUUID()) + if err != nil { + log.Warnf("Unable to read config for NGINX instance %s, %v", nginxDetails.NginxId, err) + } + log.Info("Master process has been found") + return nil } } else { log.Tracef("NGINX non-master process: %d", proc.Pid) + return nil } } + return fmt.Errorf("No master process found, waiting...") } - findMaster() - for len(details) == 0 { - log.Info("No master process found, waiting 10 seconds and searching again") - time.Sleep(10 * time.Second) - findMaster() + err2 := backoff.WaitUntil( + context.Background(), backoffSetting, findMaster, + ) + if err2 != nil { + log.Warn(err2.Error()) } + updated, err := types.TimestampProto(r.config.Updated) if err != nil { log.Warnf("failed to parse proto timestamp %s: %s, assuming now", r.config.Updated, err) From 7f979558006388b03054db82b811fae61a9a3438 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 25 Mar 2024 14:50:53 +0000 Subject: [PATCH 07/15] Added unit test for registerAgent() --- src/plugins/registration_test.go | 50 +++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/plugins/registration_test.go b/src/plugins/registration_test.go index 18ad5d6cd3..bb0a92a909 100644 --- a/src/plugins/registration_test.go +++ b/src/plugins/registration_test.go @@ -64,7 +64,55 @@ func TestRegistration_Process(t *testing.T) { messages := messagePipe.GetMessages() assert.Equal(tt, messages[0].Topic(), core.CommRegister) - // host info checked elsewhere + assert.NotNil(tt, messages[0].Data()) + + assert.Equal(tt, messages[1].Topic(), core.RegistrationCompletedTopic) + assert.Nil(tt, messages[1].Data()) + }) + } +} + +func TestRegistration_registerAgent(t *testing.T) { + tests := []struct { + name string + expectedMessageCount int + }{ + { + name: "test registration", + expectedMessageCount: 2, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(tt *testing.T) { + binary := tutils.GetMockNginxBinary() + binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) + env := tutils.GetMockEnvWithHostAndProcess() + + cfg := &config.Config{ + Extensions: []string{agent_config.NginxAppProtectExtensionPlugin}, + } + + oneTimeReg := NewOneTimeRegistration(cfg, binary, env, &proto.Metadata{}, tutils.GetProcesses()) + + messagePipe := core.SetupMockMessagePipe(t, context.TODO(), []core.Plugin{oneTimeReg}, []core.ExtensionPlugin{}) + + oneTimeReg.pipeline = messagePipe + oneTimeReg.registerAgent() + defer oneTimeReg.Close() + messagePipe.Run() + + assert.Eventually( + tt, + func() bool { return len(messagePipe.GetMessages()) == test.expectedMessageCount }, + time.Duration(5*time.Second), + 3*time.Millisecond, + ) + + messages := messagePipe.GetMessages() + + assert.Equal(tt, messages[0].Topic(), core.CommRegister) assert.NotNil(tt, messages[0].Data()) assert.Equal(tt, messages[1].Topic(), core.RegistrationCompletedTopic) From 9f3714778b2557343717f4845d12726f852e5421 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 25 Mar 2024 15:52:29 +0000 Subject: [PATCH 08/15] Prep for PR --- scripts/docker/nginx-oss/deb/Dockerfile | 13 +++---- scripts/docker/supervisor.d/nginx.conf | 17 --------- src/plugins/registration.go | 6 +-- src/plugins/registration_test.go | 51 +------------------------ 4 files changed, 10 insertions(+), 77 deletions(-) delete mode 100644 scripts/docker/supervisor.d/nginx.conf diff --git a/scripts/docker/nginx-oss/deb/Dockerfile b/scripts/docker/nginx-oss/deb/Dockerfile index 76a4bfa4fb..836532f345 100644 --- a/scripts/docker/nginx-oss/deb/Dockerfile +++ b/scripts/docker/nginx-oss/deb/Dockerfile @@ -7,10 +7,9 @@ ARG ENTRY_POINT ARG PACKAGE_NAME ARG PACKAGES_REPO -COPY ./scripts/docker/supervisor.d/nginx.conf etc/supervisor/conf.d/ - WORKDIR /agent COPY ./build /agent/build +COPY $ENTRY_POINT /agent/entrypoint.sh RUN set -x \ && addgroup --system --gid 101 nginx \ @@ -23,18 +22,18 @@ RUN set -x \ curl \ lsb-release \ procps \ - nginx \ - supervisor + nginx # Setup nginx agent repository RUN curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \ && printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://${PACKAGES_REPO}/nginx-agent/ubuntu/ `lsb_release -cs` agent\n" > /etc/apt/sources.list.d/nginx-agent.list -STOPSIGNAL SIGQUIT +RUN chmod +x /agent/entrypoint.sh +STOPSIGNAL SIGTERM EXPOSE 80 443 -ENTRYPOINT ["/usr/bin/supervisord", "-c","/etc/supervisor/supervisord.conf", "-u", "root", "--nodaemon", "--logfile", "/dev/stdout", "--logfile_maxbytes", "0" ] +ENTRYPOINT ["/agent/entrypoint.sh"] FROM install-nginx as install-agent-local @@ -44,4 +43,4 @@ RUN apt install -y /agent/build/$PACKAGE_NAME.deb FROM install-nginx as install-agent-repo -RUN apt-get update && apt-get install -y nginx-agent +RUN apt-get update && apt-get install -y nginx-agent \ No newline at end of file diff --git a/scripts/docker/supervisor.d/nginx.conf b/scripts/docker/supervisor.d/nginx.conf deleted file mode 100644 index cc18d49bce..0000000000 --- a/scripts/docker/supervisor.d/nginx.conf +++ /dev/null @@ -1,17 +0,0 @@ -[program:nginx] -command=bash -c "sleep 30 && echo 'running nginx' && /usr/sbin/nginx -g 'daemon off;'" -stopsignal=QUIT -stopwaitseconds=60 -stdout_logfile=/dev/stdout -stderr_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile_maxbytes=0 - -[program:nginx-agent] -command=/usr/bin/nginx-agent -stopsignal=QUIT -stopwaitseconds=60 -stdout_logfile=/dev/stdout -stderr_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile_maxbytes=0 \ No newline at end of file diff --git a/src/plugins/registration.go b/src/plugins/registration.go index 6512fd4e45..17f64a2062 100644 --- a/src/plugins/registration.go +++ b/src/plugins/registration.go @@ -186,11 +186,11 @@ func (r *OneTimeRegistration) registerAgent() { } return fmt.Errorf("No master process found, waiting...") } - err2 := backoff.WaitUntil( + err := backoff.WaitUntil( context.Background(), backoffSetting, findMaster, ) - if err2 != nil { - log.Warn(err2.Error()) + if err != nil { + log.Warn(err.Error()) } updated, err := types.TimestampProto(r.config.Updated) diff --git a/src/plugins/registration_test.go b/src/plugins/registration_test.go index bb0a92a909..5bd69043c5 100644 --- a/src/plugins/registration_test.go +++ b/src/plugins/registration_test.go @@ -23,7 +23,7 @@ import ( tutils "github.com/nginx/agent/v2/test/utils" ) -func TestRegistration_Process(t *testing.T) { +func TestRegistration_startRegistration(t *testing.T) { tests := []struct { name string expectedMessageCount int @@ -72,55 +72,6 @@ func TestRegistration_Process(t *testing.T) { } } -func TestRegistration_registerAgent(t *testing.T) { - tests := []struct { - name string - expectedMessageCount int - }{ - { - name: "test registration", - expectedMessageCount: 2, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(tt *testing.T) { - binary := tutils.GetMockNginxBinary() - binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) - env := tutils.GetMockEnvWithHostAndProcess() - - cfg := &config.Config{ - Extensions: []string{agent_config.NginxAppProtectExtensionPlugin}, - } - - oneTimeReg := NewOneTimeRegistration(cfg, binary, env, &proto.Metadata{}, tutils.GetProcesses()) - - messagePipe := core.SetupMockMessagePipe(t, context.TODO(), []core.Plugin{oneTimeReg}, []core.ExtensionPlugin{}) - - oneTimeReg.pipeline = messagePipe - oneTimeReg.registerAgent() - defer oneTimeReg.Close() - messagePipe.Run() - - assert.Eventually( - tt, - func() bool { return len(messagePipe.GetMessages()) == test.expectedMessageCount }, - time.Duration(5*time.Second), - 3*time.Millisecond, - ) - - messages := messagePipe.GetMessages() - - assert.Equal(tt, messages[0].Topic(), core.CommRegister) - assert.NotNil(tt, messages[0].Data()) - - assert.Equal(tt, messages[1].Topic(), core.RegistrationCompletedTopic) - assert.Nil(tt, messages[1].Data()) - }) - } -} - func TestRegistration_areDataplaneSoftwareDetailsReady(t *testing.T) { conf := tutils.GetMockAgentConfig() conf.Extensions = []string{agent_config.NginxAppProtectExtensionPlugin} From b89cf0e9042aa7e3410c0ac65e6f1c0f8a3798f9 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 25 Mar 2024 16:07:52 +0000 Subject: [PATCH 09/15] Prep for PR --- .../github.com/nginx/agent/v2/src/plugins/registration.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go index 6512fd4e45..17f64a2062 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go @@ -186,11 +186,11 @@ func (r *OneTimeRegistration) registerAgent() { } return fmt.Errorf("No master process found, waiting...") } - err2 := backoff.WaitUntil( + err := backoff.WaitUntil( context.Background(), backoffSetting, findMaster, ) - if err2 != nil { - log.Warn(err2.Error()) + if err != nil { + log.Warn(err.Error()) } updated, err := types.TimestampProto(r.config.Updated) From 794ff64a8ef2073e4d452e5ed932985f3e87b068 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 25 Mar 2024 17:11:42 +0000 Subject: [PATCH 10/15] Updated subscription test --- src/plugins/registration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/registration_test.go b/src/plugins/registration_test.go index 5bd69043c5..4c5435a837 100644 --- a/src/plugins/registration_test.go +++ b/src/plugins/registration_test.go @@ -87,7 +87,7 @@ func TestRegistration_areDataplaneSoftwareDetailsReady(t *testing.T) { func TestRegistration_Subscriptions(t *testing.T) { pluginUnderTest := NewOneTimeRegistration(tutils.GetMockAgentConfig(), nil, tutils.GetMockEnv(), nil, tutils.GetProcesses()) - assert.Equal(t, []string{core.RegistrationCompletedTopic, core.DataplaneSoftwareDetailsUpdated}, pluginUnderTest.Subscriptions()) + assert.Equal(t, []string{core.RegistrationCompletedTopic, core.DataplaneSoftwareDetailsUpdated,core.NginxDetailProcUpdate}, pluginUnderTest.Subscriptions()) } func TestRegistration_Info(t *testing.T) { From ac725e2d0305f27b90b3496c8c1671aeab334e27 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 25 Mar 2024 17:14:24 +0000 Subject: [PATCH 11/15] Updated subscription test --- src/plugins/registration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/registration_test.go b/src/plugins/registration_test.go index 4c5435a837..64016e6df8 100644 --- a/src/plugins/registration_test.go +++ b/src/plugins/registration_test.go @@ -87,7 +87,7 @@ func TestRegistration_areDataplaneSoftwareDetailsReady(t *testing.T) { func TestRegistration_Subscriptions(t *testing.T) { pluginUnderTest := NewOneTimeRegistration(tutils.GetMockAgentConfig(), nil, tutils.GetMockEnv(), nil, tutils.GetProcesses()) - assert.Equal(t, []string{core.RegistrationCompletedTopic, core.DataplaneSoftwareDetailsUpdated,core.NginxDetailProcUpdate}, pluginUnderTest.Subscriptions()) + assert.Equal(t, []string{core.RegistrationCompletedTopic, core.DataplaneSoftwareDetailsUpdated, core.NginxDetailProcUpdate}, pluginUnderTest.Subscriptions()) } func TestRegistration_Info(t *testing.T) { From cff923cbfa0e3d873ab54e0aa53458db482a9f5a Mon Sep 17 00:00:00 2001 From: Spencer Date: Tue, 26 Mar 2024 13:31:22 +0000 Subject: [PATCH 12/15] type check for core.NginxDetailProcUpdate --- src/plugins/registration.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/registration.go b/src/plugins/registration.go index 17f64a2062..cc7f39865f 100644 --- a/src/plugins/registration.go +++ b/src/plugins/registration.go @@ -29,7 +29,8 @@ const ( dataplaneSoftwareDetailsMaxWaitTime = time.Duration(5 * time.Second) // Time between attempts to gather DataplaneSoftwareDetails softwareDetailsOperationInterval = time.Duration(1 * time.Second) - nginxStartMaxWaitTime = 0 + // Timeout for master process search (will not stop searching until master process is found) + nginxStartMaxWaitTime = 0 ) type OneTimeRegistration struct { @@ -95,7 +96,9 @@ func (r *OneTimeRegistration) Process(msg *core.Message) { r.dataplaneSoftwareDetails[data.GetPluginName()] = data.GetDataplaneSoftwareDetails() } case msg.Exact(core.NginxDetailProcUpdate): - r.processes = msg.Data().([]*core.Process) + if processes, ok := msg.Data().([]*core.Process); ok { + r.processes = processes + } } } @@ -181,7 +184,6 @@ func (r *OneTimeRegistration) registerAgent() { } } else { log.Tracef("NGINX non-master process: %d", proc.Pid) - return nil } } return fmt.Errorf("No master process found, waiting...") From a3506c50ee368e7e2b0ee8b2ad96b48a70dec4df Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 27 Mar 2024 08:56:29 +0000 Subject: [PATCH 13/15] type check for core.NginxDetailProcUpdate --- .../github.com/nginx/agent/v2/src/plugins/registration.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go index 17f64a2062..cc7f39865f 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go @@ -29,7 +29,8 @@ const ( dataplaneSoftwareDetailsMaxWaitTime = time.Duration(5 * time.Second) // Time between attempts to gather DataplaneSoftwareDetails softwareDetailsOperationInterval = time.Duration(1 * time.Second) - nginxStartMaxWaitTime = 0 + // Timeout for master process search (will not stop searching until master process is found) + nginxStartMaxWaitTime = 0 ) type OneTimeRegistration struct { @@ -95,7 +96,9 @@ func (r *OneTimeRegistration) Process(msg *core.Message) { r.dataplaneSoftwareDetails[data.GetPluginName()] = data.GetDataplaneSoftwareDetails() } case msg.Exact(core.NginxDetailProcUpdate): - r.processes = msg.Data().([]*core.Process) + if processes, ok := msg.Data().([]*core.Process); ok { + r.processes = processes + } } } @@ -181,7 +184,6 @@ func (r *OneTimeRegistration) registerAgent() { } } else { log.Tracef("NGINX non-master process: %d", proc.Pid) - return nil } } return fmt.Errorf("No master process found, waiting...") From 799bfd7ea17e1a4babfa4ff343b08c980808ad1e Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 27 Mar 2024 10:55:54 +0000 Subject: [PATCH 14/15] Logging an error when master nginx process is not found --- src/plugins/registration.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/registration.go b/src/plugins/registration.go index cc7f39865f..c7ef07cb81 100644 --- a/src/plugins/registration.go +++ b/src/plugins/registration.go @@ -167,7 +167,7 @@ func (r *OneTimeRegistration) registerAgent() { Multiplier: backoff.BACKOFF_MULTIPLIER, } - findMaster := func() error { + findNginxMasterProcess := func() error { for _, proc := range r.processes { // only need master process for registration if proc.IsMaster { @@ -186,13 +186,13 @@ func (r *OneTimeRegistration) registerAgent() { log.Tracef("NGINX non-master process: %d", proc.Pid) } } - return fmt.Errorf("No master process found, waiting...") + return fmt.Errorf("waiting for NGINX master process... ") } err := backoff.WaitUntil( - context.Background(), backoffSetting, findMaster, + context.Background(), backoffSetting, findNginxMasterProcess, ) if err != nil { - log.Warn(err.Error()) + log.Errorf("Unable to find NGINX master processes, %v", err) } updated, err := types.TimestampProto(r.config.Updated) From f72e5cae85d8be0f97cc76a95e167180f8fe28bc Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 27 Mar 2024 10:56:58 +0000 Subject: [PATCH 15/15] Logging an error when master nginx process is not found --- .../github.com/nginx/agent/v2/src/plugins/registration.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go index cc7f39865f..c7ef07cb81 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go @@ -167,7 +167,7 @@ func (r *OneTimeRegistration) registerAgent() { Multiplier: backoff.BACKOFF_MULTIPLIER, } - findMaster := func() error { + findNginxMasterProcess := func() error { for _, proc := range r.processes { // only need master process for registration if proc.IsMaster { @@ -186,13 +186,13 @@ func (r *OneTimeRegistration) registerAgent() { log.Tracef("NGINX non-master process: %d", proc.Pid) } } - return fmt.Errorf("No master process found, waiting...") + return fmt.Errorf("waiting for NGINX master process... ") } err := backoff.WaitUntil( - context.Background(), backoffSetting, findMaster, + context.Background(), backoffSetting, findNginxMasterProcess, ) if err != nil { - log.Warn(err.Error()) + log.Errorf("Unable to find NGINX master processes, %v", err) } updated, err := types.TimestampProto(r.config.Updated)