From 639dc9a75f0994c642fba493a91e95c89f41db53 Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Sat, 12 Oct 2024 18:10:30 +0800 Subject: [PATCH 01/10] fix(reaper): forkExec error no such file or directory fix https://github.com/aptible/supercronic/issues/177 --- reaper.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/reaper.go b/reaper.go index a271bbd..17445e6 100644 --- a/reaper.go +++ b/reaper.go @@ -16,6 +16,11 @@ func forkExec() { logrus.Fatalf("Failed to get current working directory: %s", err.Error()) return } + exe, err := os.Executable() + if err != nil { + logrus.Fatalf("Failed to get executable %s", err.Error()) + return + } pattrs := &syscall.ProcAttr{ Dir: pwd, @@ -28,7 +33,7 @@ func forkExec() { } args := make([]string, 0, len(os.Args)+1) // disable reaping for supercronic, avoid no sense warning - args = append(args, os.Args[0], "-no-reap") + args = append(args, exe, "-no-reap") args = append(args, os.Args[1:]...) pid, err := syscall.ForkExec(args[0], args, pattrs) From aa473505de71d1bc80f7d2819126d672ca167d1e Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Sat, 19 Oct 2024 11:34:40 +0800 Subject: [PATCH 02/10] test(reaper): add reaper path error check --- Makefile | 2 +- integration/test.bats | 48 ++++++++++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 7df77ee..57d3b55 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ unit: .PHONY: integration integration: VERSION=v1337 integration: build - bats integration + sudo bats integration .PHONY: test test: unit integration diff --git a/integration/test.bats b/integration/test.bats index 8eb2060..77034bc 100755 --- a/integration/test.bats +++ b/integration/test.bats @@ -7,7 +7,7 @@ function run_supercronic() { "${BATS_TEST_DIRNAME}/../supercronic" ${SUPERCRONIC_ARGS:-} "$crontab" 2>&1 } -setup () { +setup() { WORK_DIR="$(mktemp -d)" export WORK_DIR } @@ -18,7 +18,7 @@ teardown() { wait_for() { for i in $(seq 0 50); do - if "$@" > /dev/null 2>&1; then + if "$@" >/dev/null 2>&1; then return 0 fi sleep 0.1 @@ -28,8 +28,8 @@ wait_for() { } @test "it prints the version" { - run "${BATS_TEST_DIRNAME}/../supercronic" -version - [[ "$output" =~ ^v1337$ ]] + run "${BATS_TEST_DIRNAME}/../supercronic" -version + [[ "$output" =~ ^v1337$ ]] } @test "it starts" { @@ -111,30 +111,44 @@ wait_for() { out="${WORK_DIR}/zombie-crontab-out" # run in new process namespace - sudo timeout 10s unshare --fork --pid --mount-proc \ - ${BATS_TEST_DIRNAME}/../supercronic "${BATS_TEST_DIRNAME}/zombie.crontab" >"$out" 2>&1 & - local pid=$! + timeout 10s unshare --fork --pid --mount-proc \ + ${BATS_TEST_DIRNAME}/../supercronic "${BATS_TEST_DIRNAME}/zombie.crontab" >"$out" 2>&1 & sleep 3 - kill -TERM ${pid} # todo: use other method to detect zombie cleanup - wait_for grep "reaper cleanup: pid=" "$out" + !(grep --ignore-case "unshare" "$out") + wait_for grep "reaper cleanup: pid=" "$out" } - @test "it run as pid 1 and normal crontab no error" { out="${WORK_DIR}/normal-crontab-out" # sleep 30 seconds occur found bug # FIXME: other way to detect - sudo timeout 30s unshare --fork --pid --mount-proc \ - "${BATS_TEST_DIRNAME}/../supercronic" "${BATS_TEST_DIRNAME}/normal.crontab" >"$out" 2>&1 & + timeout 30s unshare --fork --pid --mount-proc \ + "${BATS_TEST_DIRNAME}/../supercronic" "${BATS_TEST_DIRNAME}/normal.crontab" >"$out" 2>&1 & # https://github.com/aptible/supercronic/issues/171 - local pid=$! local foundErr - - sleep 29.5 - kill -TERM ${pid} - grep "waitid: no child processes" "$out" && foundErr=1 + + sleep 30 + !(grep --ignore-case "unshare" "$out") + !(grep --ignore-case "waitid: no child processes" "$out") +} + +@test "it run as pid 1 and no not found error" { + out="${WORK_DIR}/normal-crontab-out2" + export PATH="${BATS_TEST_DIRNAME}/../:$PATH" + ( + cd / + timeout 1s unshare --fork --pid --mount-proc \ + "supercronic" "${BATS_TEST_DIRNAME}/normal.crontab" >"$out" 2>&1 & + # https://github.com/aptible/supercronic/issues/177 + local foundErr + ) + + sleep 1 + !(grep --ignore-case "unshare" "$out") + !(grep --ignore-case "failed" "$out") + !(grep --ignore-case "no such file or directory" "$out") [[ $foundErr != 1 ]] } From 2df5fb626d77b94c0521c6da0ab52685e62b7468 Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Sat, 19 Oct 2024 17:17:38 +0800 Subject: [PATCH 03/10] test: user bats-action & use refute_line assert --- .github/workflows/test.yml | 43 +++++++++++++++++++------------------- integration/test.bats | 27 ++++++++++++++---------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f393d77..5cecb63 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,25 +15,24 @@ jobs: go-version: [1.23.1] steps: - - name: install golang - uses: actions/setup-go@v5 - with: - go-version: ${{ matrix.go-version }} - - - name: install bats - run: | - git clone https://github.com/bats-core/bats-core.git --branch v1.11.0 --depth 1 "${HOME}/bats" - echo "${HOME}/bats/bin" >> $GITHUB_PATH - - - name: install govulncheck - run: | - go install golang.org/x/vuln/cmd/govulncheck@latest - - - name: checkout code - uses: actions/checkout@v4 - - - name: run tests - run: make test - - - name: run vuln check - run: make vulncheck + - name: install golang + uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.go-version }} + + - name: Setup Bats and bats libs + id: setup-bats + uses: bats-core/bats-action@3 + - name: install govulncheck + run: | + go install golang.org/x/vuln/cmd/govulncheck@latest + + - name: checkout code + uses: actions/checkout@v4 + + - name: run tests + run: make test + env: + -BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }} + - name: run vuln check + run: make vulncheck diff --git a/integration/test.bats b/integration/test.bats index 77034bc..037442d 100755 --- a/integration/test.bats +++ b/integration/test.bats @@ -10,6 +10,10 @@ function run_supercronic() { setup() { WORK_DIR="$(mktemp -d)" export WORK_DIR + + export BATS_LIB_PATH=${BATS_LIB_PATH:-"/usr/lib"} + bats_load_library bats-assert + bats_load_library bats-support } teardown() { @@ -29,7 +33,7 @@ wait_for() { @test "it prints the version" { run "${BATS_TEST_DIRNAME}/../supercronic" -version - [[ "$output" =~ ^v1337$ ]] + assert_output 'v1337' } @test "it starts" { @@ -116,7 +120,8 @@ wait_for() { sleep 3 # todo: use other method to detect zombie cleanup - !(grep --ignore-case "unshare" "$out") + run cat $out + refute_line --partial 'unshare' wait_for grep "reaper cleanup: pid=" "$out" } @@ -128,11 +133,12 @@ wait_for() { timeout 30s unshare --fork --pid --mount-proc \ "${BATS_TEST_DIRNAME}/../supercronic" "${BATS_TEST_DIRNAME}/normal.crontab" >"$out" 2>&1 & # https://github.com/aptible/supercronic/issues/171 - local foundErr sleep 30 - !(grep --ignore-case "unshare" "$out") - !(grep --ignore-case "waitid: no child processes" "$out") + run cat $out + + refute_line --partial 'unshare' + refute_line --partial 'waitid: no child processes' } @test "it run as pid 1 and no not found error" { @@ -143,12 +149,11 @@ wait_for() { timeout 1s unshare --fork --pid --mount-proc \ "supercronic" "${BATS_TEST_DIRNAME}/normal.crontab" >"$out" 2>&1 & # https://github.com/aptible/supercronic/issues/177 - local foundErr ) - sleep 1 - !(grep --ignore-case "unshare" "$out") - !(grep --ignore-case "failed" "$out") - !(grep --ignore-case "no such file or directory" "$out") - [[ $foundErr != 1 ]] + run cat $out + + refute_line --partial 'unshare' + refute_line --partial 'failed' + refute_line --partial 'no such file or directory' } From aa24f2a3e0dbc9ff406e08d1794656536955d32a Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Sat, 19 Oct 2024 21:52:39 +0800 Subject: [PATCH 04/10] test: test in docker container --- .dockerignore | 31 ++++++++++++++++++++++++ .github/workflows/test.yml | 8 +++++-- Dockerfile | 48 ++++++++++++++++++++++++++++++++++++++ Makefile | 10 +++++--- integration/test.bats | 47 +++++++++++++------------------------ 5 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f09e0ce --- /dev/null +++ b/.dockerignore @@ -0,0 +1,31 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + +**/.DS_Store +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose.y*ml +**/Dockerfile* +.github +LICENSE.md +README.md +SECURITY.md +Makefile +supercronic diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5cecb63..858f797 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,17 +22,21 @@ jobs: - name: Setup Bats and bats libs id: setup-bats - uses: bats-core/bats-action@3 + uses: bats-core/bats-action@3.0.0 + - name: install govulncheck run: | go install golang.org/x/vuln/cmd/govulncheck@latest + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: checkout code uses: actions/checkout@v4 - name: run tests run: make test env: - -BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }} + BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }} - name: run vuln check run: make vulncheck diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2c8fdae --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +# syntax=docker/dockerfile:1 + +# Create a stage for building the application. +ARG GO_VERSION=1.23.2 +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS build +WORKDIR /src + +RUN --mount=type=cache,target=/go/pkg/mod/ \ + --mount=type=bind,source=go.sum,target=go.sum \ + --mount=type=bind,source=go.mod,target=go.mod \ + go mod download -x + +# This is the architecture you're building for, which is passed in by the builder. +# Placing it here allows the previous steps to be cached across architectures. +ARG TARGETARCH +ARG VERSION="" + +RUN --mount=type=cache,target=/go/pkg/mod/ \ + --mount=type=bind,target=. \ + CGO_ENABLED=0 GOARCH=$TARGETARCH \ + go build -ldflags "-X main.Version=${VERSION}" \ + -o /bin/supercronic . + +################################################################################ +FROM alpine:latest AS final + +RUN --mount=type=cache,target=/var/cache/apk \ + apk --update add \ + ca-certificates \ + tzdata \ + && \ + update-ca-certificates + +# Create a non-privileged user that the app will run under. +# See https://docs.docker.com/go/dockerfile-user-best-practices/ +ARG UID=10001 +RUN adduser \ + --disabled-password \ + --gecos "" \ + --system \ + --no-create-home \ + --uid "${UID}" \ + supercronic +USER supercronic + +COPY --from=build /bin/supercronic /bin/ + +ENTRYPOINT [ "/bin/supercronic" ] diff --git a/Makefile b/Makefile index 57d3b55..8ff9b2c 100644 --- a/Makefile +++ b/Makefile @@ -7,9 +7,13 @@ deps: go mod vendor .PHONY: build -build: $(GOFILES) +build: go build -ldflags "-X main.Version=${VERSION}" +.PHONY: docker-build +docker-build: + docker build -t supercronic:${VERSION} --build-arg VERSION=${VERSION} . + .PHONY: unit unit: go test -v -race $$(go list ./... | grep -v /vendor/) @@ -17,8 +21,8 @@ unit: .PHONY: integration integration: VERSION=v1337 -integration: build - sudo bats integration +integration: build docker-build + bats integration .PHONY: test test: unit integration diff --git a/integration/test.bats b/integration/test.bats index 037442d..f4c0695 100755 --- a/integration/test.bats +++ b/integration/test.bats @@ -14,6 +14,8 @@ setup() { export BATS_LIB_PATH=${BATS_LIB_PATH:-"/usr/lib"} bats_load_library bats-assert bats_load_library bats-support + # mock version + export VERSION=v1337 } teardown() { @@ -33,7 +35,7 @@ wait_for() { @test "it prints the version" { run "${BATS_TEST_DIRNAME}/../supercronic" -version - assert_output 'v1337' + assert_output $VERSION } @test "it starts" { @@ -112,48 +114,31 @@ wait_for() { } @test "it run as pid 1 and reap zombie process" { - out="${WORK_DIR}/zombie-crontab-out" + run timeout 5s docker run \ + -v "${BATS_TEST_DIRNAME}/zombie.crontab":/test.crontab \ + --rm supercronic:${VERSION} /test.crontab - # run in new process namespace - timeout 10s unshare --fork --pid --mount-proc \ - ${BATS_TEST_DIRNAME}/../supercronic "${BATS_TEST_DIRNAME}/zombie.crontab" >"$out" 2>&1 & - sleep 3 + assert_equal $status 124 # timeout exit code # todo: use other method to detect zombie cleanup - run cat $out - refute_line --partial 'unshare' - wait_for grep "reaper cleanup: pid=" "$out" + assert_line --partial 'reaping dead processes' + assert_line --partial "reaper cleanup: pid=" } @test "it run as pid 1 and normal crontab no error" { - out="${WORK_DIR}/normal-crontab-out" - # sleep 30 seconds occur found bug # FIXME: other way to detect - timeout 30s unshare --fork --pid --mount-proc \ - "${BATS_TEST_DIRNAME}/../supercronic" "${BATS_TEST_DIRNAME}/normal.crontab" >"$out" 2>&1 & # https://github.com/aptible/supercronic/issues/171 + run timeout 30s docker run \ + -v "${BATS_TEST_DIRNAME}/normal.crontab":/normal.crontab \ + --rm supercronic:${VERSION} /normal.crontab - sleep 30 - run cat $out + assert_equal $status 124 # timeout exit code - refute_line --partial 'unshare' refute_line --partial 'waitid: no child processes' -} - -@test "it run as pid 1 and no not found error" { - out="${WORK_DIR}/normal-crontab-out2" - export PATH="${BATS_TEST_DIRNAME}/../:$PATH" - ( - cd / - timeout 1s unshare --fork --pid --mount-proc \ - "supercronic" "${BATS_TEST_DIRNAME}/normal.crontab" >"$out" 2>&1 & - # https://github.com/aptible/supercronic/issues/177 - ) - sleep 1 - run cat $out - - refute_line --partial 'unshare' + assert_line --partial 'reaping dead processes' + assert_line --partial 'msg=1' # normal output refute_line --partial 'failed' + # https://github.com/aptible/supercronic/issues/177 refute_line --partial 'no such file or directory' } From 050efc3c1047533bb64705b0addbbc63fb79479b Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Sat, 19 Oct 2024 23:25:59 +0800 Subject: [PATCH 05/10] fix(prometheus): shutdown error & http error handle https://github.com/aptible/supercronic/issues/173 --- main.go | 4 ++-- prometheus_metrics/prommetrics.go | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/main.go b/main.go index 6b4c508..4c06d03 100644 --- a/main.go +++ b/main.go @@ -123,7 +123,7 @@ func main() { forkExec() return } - + logrus.Warn("process reaping disabled, not pid 1") } crontabFileName := flag.Args()[0] @@ -184,7 +184,7 @@ func main() { defer func() { if err := promServerShutdownClosure(); err != nil { - logrus.Fatalf("prometheus http shutdown failed: %s", err.Error()) + logrus.Errorf("prometheus http shutdown failed: %s", err.Error()) } }() } diff --git a/prometheus_metrics/prommetrics.go b/prometheus_metrics/prommetrics.go index c225895..bf51e01 100644 --- a/prometheus_metrics/prommetrics.go +++ b/prometheus_metrics/prommetrics.go @@ -2,6 +2,7 @@ package prometheus_metrics import ( "context" + "errors" "fmt" "net" "net/http" @@ -55,7 +56,7 @@ func NewPrometheusMetrics() PrometheusMetrics { pm.CronsSuccessCounter = *prometheus.NewCounterVec( prometheus.CounterOpts{ Name: genMetricName("successful_executions"), - Help: "count of successul cron executions", + Help: "count of successful cron executions", }, cronLabels, ) @@ -140,17 +141,23 @@ func InitHTTPServer(listenAddr string, shutdownContext context.Context) (func() http.Handle("/metrics", promhttp.Handler()) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(` + _, err := w.Write([]byte(` Supercronic

Supercronic

Metrics

`)) + if err != nil { + logrus.Warnf("failed to write response on '/': %s", err.Error()) + } }) http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`OK`)) + _, err := w.Write([]byte(`OK`)) + if err != nil { + logrus.Warnf("failed to write response on '/health': %s", err.Error()) + } }) shutdownClosure := func() error { @@ -164,7 +171,9 @@ func InitHTTPServer(listenAddr string, shutdownContext context.Context) (func() go func() { if err := promSrv.Serve(listener); err != nil { - logrus.Fatalf("prometheus http serve failed: %s", err.Error()) + if !errors.Is(err, http.ErrServerClosed) { + logrus.Fatalf("prometheus http serve failed: %s", err.Error()) + } } }() From 45b31c30b8f4023df22801ecdfc322a2bf90ba91 Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Sat, 19 Oct 2024 23:33:00 +0800 Subject: [PATCH 06/10] test: make the GitHub test workflow runnable manually --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 858f797..08861a4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,7 @@ on: branches: [master] pull_request: branches: [master] + workflow_dispatch: jobs: build: From 9cd9b36bf5a23df5eb2779dd481270eed4a560d2 Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Sat, 19 Oct 2024 23:39:28 +0800 Subject: [PATCH 07/10] chore: upgrade go to 1.23.2 & deps --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- go.mod | 14 +++++++------- go.sum | 24 ++++++++++++------------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8ab6f9b..7b02085 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: - name: install golang uses: actions/setup-go@v5 with: - go-version: 1.23.1 + go-version: 1.23.2 - name: checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 08861a4..cd21438 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - go-version: [1.23.1] + go-version: [1.23.2] steps: - name: install golang diff --git a/go.mod b/go.mod index 93ea420..2bcea62 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/aptible/supercronic -go 1.23.0 +go 1.23.2 require ( github.com/evalphobia/logrus_sentry v0.8.2 github.com/fsnotify/fsnotify v1.7.0 - github.com/prometheus/client_golang v1.20.2 + github.com/prometheus/client_golang v1.20.5 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 ) @@ -16,16 +16,16 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/getsentry/raven-go v0.2.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/kr/text v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.57.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect - golang.org/x/sys v0.24.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + golang.org/x/sys v0.26.0 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index cb5ebe5..e18707f 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,8 @@ github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JY github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -30,16 +30,16 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= -github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= -github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -47,10 +47,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From 99808b5b7eb18d676e0fe4de56c281b8e55579c9 Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:15:38 +0800 Subject: [PATCH 08/10] chore(reaper): add document about reaping 1. change warn to info. The warning may confuse the user. 2. add document about reaping https://github.com/aptible/supercronic/issues/183 --- README.md | 1 + main.go | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1c7ab16..813dd3b 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ implementations are ill-suited for container environments: - They often try to send their logs to syslog. This conveniently provides centralized logging when a syslog server is running, but with containers, simply logging to `stdout` or `stderr` is preferred. +- Automate reaping [zombie processes](https://en.wikipedia.org/wiki/Zombie_process) when running as PID 1, which may cause them to accumulate in the process table, consuming system resources. Finally, they are often quiet, making these issues difficult to understand and debug! diff --git a/main.go b/main.go index 4c06d03..6ab051e 100644 --- a/main.go +++ b/main.go @@ -123,8 +123,9 @@ func main() { forkExec() return } - - logrus.Warn("process reaping disabled, not pid 1") + // warning may confuse user + // https://github.com/aptible/supercronic/issues/183 + logrus.Info("process reaping disabled, not pid 1.It's safe to ignore") } crontabFileName := flag.Args()[0] From e1f8afccc51d538eb462eae8daee3cd4092f9789 Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:28:26 +0800 Subject: [PATCH 09/10] chore: upgrade go to 1.23.5 & dep --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- Dockerfile | 2 +- cronexpr/cronexpr/go.mod | 4 ++-- go.mod | 12 ++++++------ go.sum | 20 ++++++++++---------- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b02085..3bb5813 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: - name: install golang uses: actions/setup-go@v5 with: - go-version: 1.23.2 + go-version: 1.23.5 - name: checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cd21438..98bdef3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - go-version: [1.23.2] + go-version: [1.23.5] steps: - name: install golang diff --git a/Dockerfile b/Dockerfile index 2c8fdae..c75dc01 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 # Create a stage for building the application. -ARG GO_VERSION=1.23.2 +ARG GO_VERSION=1.23.5 FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS build WORKDIR /src diff --git a/cronexpr/cronexpr/go.mod b/cronexpr/cronexpr/go.mod index 1b1121a..481aeff 100644 --- a/cronexpr/cronexpr/go.mod +++ b/cronexpr/cronexpr/go.mod @@ -1,7 +1,7 @@ module github.com/aptible/supercronic/cronexpr/cronexpr -go 1.18 +go 1.23.5 replace github.com/aptible/supercronic => ../../ -require github.com/aptible/supercronic v0.0.0-00010101000000-000000000000 +require github.com/aptible/supercronic v0.2.33 diff --git a/go.mod b/go.mod index 2bcea62..97fb6cd 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/aptible/supercronic -go 1.23.2 +go 1.23.5 require ( github.com/evalphobia/logrus_sentry v0.8.2 - github.com/fsnotify/fsnotify v1.7.0 + github.com/fsnotify/fsnotify v1.8.0 github.com/prometheus/client_golang v1.20.5 github.com/sirupsen/logrus v1.9.3 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 ) require ( @@ -22,10 +22,10 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.60.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect - golang.org/x/sys v0.26.0 // indirect - google.golang.org/protobuf v1.35.1 // indirect + golang.org/x/sys v0.29.0 // indirect + google.golang.org/protobuf v1.36.4 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e18707f..8c65d38 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/evalphobia/logrus_sentry v0.8.2 h1:dotxHq+YLZsT1Bb45bB5UQbfCh3gM/nFFetyN46VoDQ= github.com/evalphobia/logrus_sentry v0.8.2/go.mod h1:pKcp+vriitUqu9KiWj/VRFbRfFNUwz95/UkgG8a6MNc= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -34,8 +34,8 @@ github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+ github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= -github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= @@ -44,13 +44,13 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From 20f94d4981729a70e0a228be4b08260153e81aaf Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Wed, 11 Jun 2025 18:40:46 +0800 Subject: [PATCH 10/10] chore: upgrade from 1.23.5 to 1.24.4 --- Dockerfile | 2 +- cronexpr/cronexpr/go.mod | 2 +- go.mod | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index c75dc01..3625c14 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 # Create a stage for building the application. -ARG GO_VERSION=1.23.5 +ARG GO_VERSION=1.24.4 FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS build WORKDIR /src diff --git a/cronexpr/cronexpr/go.mod b/cronexpr/cronexpr/go.mod index 481aeff..415f0b1 100644 --- a/cronexpr/cronexpr/go.mod +++ b/cronexpr/cronexpr/go.mod @@ -1,6 +1,6 @@ module github.com/aptible/supercronic/cronexpr/cronexpr -go 1.23.5 +go 1.24.4 replace github.com/aptible/supercronic => ../../ diff --git a/go.mod b/go.mod index d8c84c7..0a76e4c 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/aptible/supercronic -go 1.23.5 +go 1.24.4 require ( github.com/evalphobia/logrus_sentry v0.8.2