From 598d0ccbd5ae4f637bc58bb047cceeaca036359e Mon Sep 17 00:00:00 2001 From: Kiichiro YUKAWA Date: Tue, 11 Aug 2020 15:20:16 +0900 Subject: [PATCH 01/10] :white_check_mark: add internal/compress/lz4_option test (#619) * :white_check_mark: add internal/compress/lz4_option test Signed-off-by: vankichi * :white_check_mark: fix Signed-off-by: vankichi * :white_check_mark: fix Signed-off-by: vankichi * :white_check_mark: revert Signed-off-by: vankichi --- internal/compress/lz4_option.go | 7 +- internal/compress/lz4_option_test.go | 256 ++++++++++----------------- 2 files changed, 96 insertions(+), 167 deletions(-) diff --git a/internal/compress/lz4_option.go b/internal/compress/lz4_option.go index cf69bc60906..e6ace1c2a4d 100644 --- a/internal/compress/lz4_option.go +++ b/internal/compress/lz4_option.go @@ -17,8 +17,11 @@ // Package compress provides compress functions package compress -import "github.com/vdaas/vald/internal/errors" +import ( + "github.com/vdaas/vald/internal/errors" +) +// LZ4Option represents the functional option for lz4Compressor. type LZ4Option func(c *lz4Compressor) error var ( @@ -28,6 +31,7 @@ var ( } ) +// WithLZ4Gob returns the option to set gobc for lz4Compressor. func WithLZ4Gob(opts ...GobOption) LZ4Option { return func(c *lz4Compressor) error { gobc, err := NewGob(opts...) @@ -39,6 +43,7 @@ func WithLZ4Gob(opts ...GobOption) LZ4Option { } } +// WithLZ4CompressionLevel returns the option to set compressionLevel for lz4Compressor. func WithLZ4CompressionLevel(level int) LZ4Option { return func(c *lz4Compressor) error { if level > 0 { diff --git a/internal/compress/lz4_option_test.go b/internal/compress/lz4_option_test.go index 1225835de1c..aad0fea787e 100644 --- a/internal/compress/lz4_option_test.go +++ b/internal/compress/lz4_option_test.go @@ -18,196 +18,136 @@ package compress import ( + "reflect" "testing" + "github.com/vdaas/vald/internal/errors" "go.uber.org/goleak" ) func TestWithLZ4Gob(t *testing.T) { - type T = interface{} + type T = lz4Compressor type args struct { opts []GobOption } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - opts: nil, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - opts: nil, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + func() test { + gobc, _ := NewGob() + return test{ + name: "set success when opts is not nil.", + args: args{ + opts: nil, + }, + want: want{ + obj: &T{ + gobc: gobc, + }, + }, + } + }(), } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc(test.args) } if test.afterFunc != nil { defer test.afterFunc(test.args) } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithLZ4Gob(test.args.opts...) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithLZ4Gob(test.args.opts...) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + got := WithLZ4Gob(test.args.opts...) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithLZ4CompressionLevel(t *testing.T) { - type T = interface{} + type T = lz4Compressor type args struct { level int } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - level: 0, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - level: 0, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when level is less than 0.", + args: args{ + level: -1, + }, + want: want{ + obj: &T{ + compressionLevel: -1, + }, + }, + }, + { + name: "set success when level is nil.", + want: want{ + obj: new(T), + }, + }, + { + name: "return error when level is more than 1.", + args: args{ + level: 1, + }, + want: want{ + obj: new(T), + err: errors.ErrInvalidCompressionLevel(1), + }, + }, } for _, test := range tests { @@ -220,31 +160,15 @@ func TestWithLZ4CompressionLevel(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithLZ4CompressionLevel(test.args.level) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithLZ4CompressionLevel(test.args.level) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + got := WithLZ4CompressionLevel(test.args.level) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } From 4a499fbb69834d27f8db0866b94b089074cc394b Mon Sep 17 00:00:00 2001 From: Kevin Diu Date: Tue, 11 Aug 2020 15:42:25 +0900 Subject: [PATCH 02/10] :pencil: Coding guideline: Add error checking section (#614) * add error checking section * fix grammar * fix comments --- docs/contributing/coding-style.md | 72 +++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/docs/contributing/coding-style.md b/docs/contributing/coding-style.md index f5418b43b27..fd54e2d35db 100644 --- a/docs/contributing/coding-style.md +++ b/docs/contributing/coding-style.md @@ -221,7 +221,7 @@ ErrInvalidCacherType = New("invalid cacher type") ### Methods -The method name should be named as: +In this section, rules also apply to the `function` (without receiver). The method name should be named as: - Use MixedCaps. @@ -236,6 +236,7 @@ func (s *something) some_method() {} func (s *something) someMethod() {} ``` +- Avoid using long function name. - Do not use short form unless the function name is too long. ```go @@ -269,10 +270,10 @@ func (s *something) SetSignedTok(st string) { An unused variable may increase the complexity of the source code, it may confuse the developer hence introduce a new bug. So please delete the unused variable. -Generally, the unused variable should be reported during compilation, but in some cases, the compiler may not report an error. +Generally, the unused variable should be reported during compilation, but in some cases, the compiler may not report an error. This is an example of the unused variable declaration that does not cause a compilation error. -```golang +```go // In this case, this example are not using `port` field, but dose not cause a compilation error. // So please delete `port` field of `server`. @@ -297,6 +298,51 @@ All errors should define in [internal/errors package](https://github.com/vdaas/v Please use [internal/errgroup](https://github.com/vdaas/vald/blob/master/internal/errgroup) for synchronized error handling on multi-goroutine processing. +### Error checking + +All functions return `error` if the function can fail. It is very important to ensure the error checking is performed. +To reduce human mistake that missing the error checking, please check the error using the following style: + +```go +// good +if err := fn(); err != nil { + // handle error +} +``` + +Instead of this style. + +```go +// bad +err := fn() +if err != nil { + // handle error +} +``` + +If you need the value outside the if statement, please use the following style: + +```go +// good +conn, err := net.Dial("tcp", "localhost:80") +if err != nil { + // handle error +} + +// use the conn +``` + +Instead of this style. + +```go +// bad +if conn, err := net.Dial("tcp", "localhost:80"); err != nil { + // handle error +} else { + // use the conn +} +``` + ### Logging We define our own logging interface in [internal/log package](https://github.com/vdaas/vald/blob/master/internal/log). By default we use [glg](https://github.com/kpango/glg) to do the logging internally. @@ -567,7 +613,7 @@ We do not suggest to modify the generated code other than the `tests` variable, For example, Vald uses [glg](https://github.com/kpango/glg) library for logging by default, if the logger is not initialized before the test, the nil pointer error may be thrown during the test is running. You may need to implement `init()` function like: - ```golang + ```go func init() { log.Init() } @@ -581,7 +627,7 @@ We do not suggest to modify the generated code other than the `tests` variable, Sometimes you may want to skip the detection, for example, Vald uses [fastime](https://github.com/kpango/fastime) library but the internal Goroutine is not closed due to the needs of the library. To skip the goleak detection we need to create the following variable to store the ignore function. - ```golang + ```go var ( // Goroutine leak is detected by `fastime`, but it should be ignored in the test because it is an external package. goleakIgnoreOptions = []goleak.Option{ @@ -592,7 +638,7 @@ We do not suggest to modify the generated code other than the `tests` variable, And modify the generated test code. - ```golang + ```go // before for _, test := range tests { t.Run(test.name, func(tt *testing.T) { @@ -612,7 +658,7 @@ We do not suggest to modify the generated code other than the `tests` variable, For example: - ```golang + ```go for _, test := range tests { t.Run(test.name, func(tt *testing.T) { defer goleak.VerifyNone(tt, goleakIgnoreOptions...) @@ -633,11 +679,11 @@ We do not suggest to modify the generated code other than the `tests` variable, 1. Unused fields - By default, the template provides `fields` structure to initialize object of the test target. + By default, the template provides `fields` structure to initialize object of the test target. But in some cases, not all `fields` are needed, so please delete the unnecessary fields. For example, the following struct and the corresponding function: - - ```golang + + ```go type server struct { addr string port int @@ -648,7 +694,8 @@ We do not suggest to modify the generated code other than the `tests` variable, ``` And the generated test code is: - ```golang + + ```go func Test_server_Addr(t *testing.T) { type fields struct { addr string @@ -659,7 +706,8 @@ We do not suggest to modify the generated code other than the `tests` variable, ``` Since the `port` variable is not used in this test case, you can delete the `port` definition in the test case. - ```golang + + ```go func Test_server_Addr(t *testing.T) { type fields struct { addr string From 57d657e0358081ca7dfb96f0c628fdff139cd4f4 Mon Sep 17 00:00:00 2001 From: Rintaro Okamura Date: Tue, 11 Aug 2020 18:50:53 +0900 Subject: [PATCH 03/10] use distroless for base image (#605) * :whale: :recycle: use distroless for agent-ngt image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for agent-sidecar image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for discoverer-k8s image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for gateway-vald image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for meta-redis image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for meta-cassandra image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for manager-backup-mysql image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for manager-backup-cassandra image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for manager-compressor image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for manager-index image Signed-off-by: Rintaro Okamura * :recycle: add UPX_OPTIONS Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless for manager-replication-* image Signed-off-by: Rintaro Okamura * :whale: :recycle: use distroless/static:nonroot image Signed-off-by: Rintaro Okamura * :whale: :green_heart: add daily trivy scan Signed-off-by: Rintaro Okamura * :whale: :green_heart: add release-time trivy scan Signed-off-by: Rintaro Okamura * :green_heart: build binaries and publish them to release page Signed-off-by: Rintaro Okamura * :wrench: show version ad 'pr-xxx' when pr builds Signed-off-by: Rintaro Okamura * Revert ":wrench: show version ad 'pr-xxx' when pr builds" This reverts commit 4cd9f3b81b950aa06acd38e7891f1be9ef684b71. * :wrench: show version as 'pr-xxx' when PR builds Signed-off-by: Rintaro Okamura * :wrench: fix info.BuildTime Signed-off-by: Rintaro Okamura * :wrench: update go.mod.default Signed-off-by: Rintaro Okamura --- .github/workflows/build-binaries.yml | 74 ++++ .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/dockers-agent-ngt-image.yml | 30 ++ .../workflows/dockers-agent-sidecar-image.yml | 30 ++ ...dockers-backup-manager-cassandra-image.yml | 30 ++ .../dockers-backup-manager-mysql-image.yml | 30 ++ .../dockers-discoverer-k8s-image.yml | 30 ++ .../workflows/dockers-gateway-vald-image.yml | 30 ++ .../workflows/dockers-helm-operator-image.yml | 25 ++ .github/workflows/dockers-image-scan.yml | 378 +++++++++++++++++ .github/workflows/dockers-loadtest-image.yml | 30 ++ .../dockers-manager-compressor-image.yml | 30 ++ .../workflows/dockers-manager-index-image.yml | 30 ++ .../dockers-meta-cassandra-image.yml | 30 ++ .../workflows/dockers-meta-redis-image.yml | 30 ++ Makefile | 33 +- Makefile.d/build.mk | 390 ++++++++++++++++++ Makefile.d/docker.mk | 70 +++- Makefile.d/proto.mk | 148 +++++-- dockers/agent/core/ngt/Dockerfile | 71 +--- dockers/agent/sidecar/Dockerfile | 58 +-- dockers/ci/base/Dockerfile | 1 + dockers/discoverer/k8s/Dockerfile | 58 +-- dockers/gateway/vald/Dockerfile | 57 +-- dockers/manager/backup/cassandra/Dockerfile | 69 ++-- dockers/manager/backup/mysql/Dockerfile | 69 ++-- dockers/manager/compressor/Dockerfile | 59 +-- dockers/manager/index/Dockerfile | 59 +-- dockers/manager/replication/agent/Dockerfile | 59 +-- .../manager/replication/controller/Dockerfile | 59 +-- dockers/meta/cassandra/Dockerfile | 57 +-- dockers/meta/redis/Dockerfile | 57 +-- go.mod | 1 + hack/go.mod.default | 1 + internal/info/info.go | 3 +- 35 files changed, 1660 insertions(+), 528 deletions(-) create mode 100644 .github/workflows/build-binaries.yml create mode 100644 .github/workflows/dockers-image-scan.yml create mode 100644 Makefile.d/build.mk diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries.yml new file mode 100644 index 00000000000..b6b2eb4b39c --- /dev/null +++ b/.github/workflows/build-binaries.yml @@ -0,0 +1,74 @@ +name: 'Upload artifacts to release' +on: + release: + types: + - created + +jobs: + build-linux: + runs-on: ubuntu-latest + container: + image: vdaas/vald-ci-container:nightly + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 10 + - name: Fetch golang version + run: | + GO_VERSION=`make version/go` + echo "::set-output name=version::${GO_VERSION}" + id: golang_version + - uses: actions/setup-go@v1 + with: + go-version: ${{ steps.golang_version.outputs.version }} + - name: Build and zip + run: | + make binary/build/zip + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: artifacts-linux + path: ./artifacts/ + # build-macos: ## or using cross-compiler? + # runs-on: macos-latest + # steps: + # - uses: actions/checkout@v2 + # with: + # fetch-depth: 10 + # - name: Fetch golang version + # run: | + # GO_VERSION=`make version/go` + # echo "::set-output name=version::${GO_VERSION}" + # id: golang_version + # - uses: actions/setup-go@v1 + # with: + # go-version: ${{ steps.golang_version.outputs.version }} + # - name: Build and zip + # run: | + # export PATH=$PATH:$(go env GOPATH)/bin + # brew install llvm libomp protobuf ngt + # make CXXFLAGS="-I/usr/local/opt/llvm/include -mno-avx512f -mno-avx512dq -mno-avx512cd -mno-avx512bw -mno-avx512vl" binary/build/zip + # - name: Upload artifact + # uses: actions/upload-artifact@v2 + # with: + # name: artifacts-macos + # path: ./artifacts + publish: + runs-on: ubuntu-latest + needs: + - build-linux + # - build-macos + # - build-windows + steps: + - uses: actions/download-artifact@v2 + with: + name: artifacts-linux + path: tmp/linux + # - uses: actions/download-artifact@v2 + # with: + # name: artifacts-macos + # path: tmp/macos + - uses: shogo82148/actions-upload-release-asset@v1 + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: tmp/linux/vald-*.zip diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index aaff1324b29..9f794dd0d48 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -14,7 +14,7 @@ on: - '.github/workflows/codeql-analysis.yml' - '**.go' schedule: - - cron: '0 1 * * 2' + - cron: '0 1 * * *' jobs: CodeQL-Build: diff --git a/.github/workflows/dockers-agent-ngt-image.yml b/.github/workflows/dockers-agent-ngt-image.yml index d5b1c073b61..0a2b9e8d5ac 100755 --- a/.github/workflows/dockers-agent-ngt-image.yml +++ b/.github/workflows/dockers-agent-ngt-image.yml @@ -41,6 +41,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/agent-ngt @@ -65,6 +70,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/agent-ngt` docker push ${imagename}:latest @@ -73,6 +79,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-agent-sidecar-image.yml b/.github/workflows/dockers-agent-sidecar-image.yml index 4372138d7d8..ed511c5661f 100644 --- a/.github/workflows/dockers-agent-sidecar-image.yml +++ b/.github/workflows/dockers-agent-sidecar-image.yml @@ -41,6 +41,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/agent-sidecar @@ -65,6 +70,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/agent-sidecar` docker push ${imagename}:latest @@ -73,6 +79,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-backup-manager-cassandra-image.yml b/.github/workflows/dockers-backup-manager-cassandra-image.yml index b1658e88679..5eaf5ea652c 100644 --- a/.github/workflows/dockers-backup-manager-cassandra-image.yml +++ b/.github/workflows/dockers-backup-manager-cassandra-image.yml @@ -43,6 +43,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/backup-manager-cassandra @@ -67,6 +72,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/backup-manager-cassandra` docker push ${imagename}:latest @@ -75,6 +81,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-backup-manager-mysql-image.yml b/.github/workflows/dockers-backup-manager-mysql-image.yml index b90129b7ed1..1b5e5e06d8c 100644 --- a/.github/workflows/dockers-backup-manager-mysql-image.yml +++ b/.github/workflows/dockers-backup-manager-mysql-image.yml @@ -41,6 +41,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/backup-manager-mysql @@ -65,6 +70,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/backup-manager-mysql` docker push ${imagename}:latest @@ -73,6 +79,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-discoverer-k8s-image.yml b/.github/workflows/dockers-discoverer-k8s-image.yml index d9024dcee9b..4842a650e35 100755 --- a/.github/workflows/dockers-discoverer-k8s-image.yml +++ b/.github/workflows/dockers-discoverer-k8s-image.yml @@ -37,6 +37,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/discoverer-k8s @@ -61,6 +66,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/discoverer-k8s` docker push ${imagename}:latest @@ -69,6 +75,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-gateway-vald-image.yml b/.github/workflows/dockers-gateway-vald-image.yml index 62d11d73220..23880086948 100755 --- a/.github/workflows/dockers-gateway-vald-image.yml +++ b/.github/workflows/dockers-gateway-vald-image.yml @@ -39,6 +39,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/gateway-vald @@ -63,6 +68,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/gateway-vald` docker push ${imagename}:latest @@ -71,6 +77,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-helm-operator-image.yml b/.github/workflows/dockers-helm-operator-image.yml index 41d147e6720..2bee039531f 100755 --- a/.github/workflows/dockers-helm-operator-image.yml +++ b/.github/workflows/dockers-helm-operator-image.yml @@ -57,6 +57,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/operator/helm` docker push ${imagename}:latest @@ -65,6 +66,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-image-scan.yml b/.github/workflows/dockers-image-scan.yml new file mode 100644 index 00000000000..3968e7bd6f3 --- /dev/null +++ b/.github/workflows/dockers-image-scan.yml @@ -0,0 +1,378 @@ +name: 'Docker image scanning' +on: + schedule: + - cron: '0 1 * * *' + +jobs: + agent-ngt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/agent-ngt + imagename=`make docker/name/agent-ngt` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + agent-sidecar: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/agent-sidecar + imagename=`make docker/name/agent-sidecar` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + discoverer-k8s: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/discoverer-k8s + imagename=`make docker/name/discoverer-k8s` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + gateway-vald: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/gateway-vald + imagename=`make docker/name/gateway-vald` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + meta-redis: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/meta-redis + imagename=`make docker/name/meta-redis` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + meta-cassandra: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/meta-cassandra + imagename=`make docker/name/meta-cassandra` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + backup-manager-mysql: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/backup-manager-mysql + imagename=`make docker/name/backup-manager-mysql` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + backup-manager-cassandra: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/backup-manager-cassandra + imagename=`make docker/name/backup-manager-cassandra` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + compressor: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/manager-compressor + imagename=`make docker/name/manager-compressor` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + manager-index: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/manager-index + imagename=`make docker/name/manager-index` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + operator-helm: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/operator/helm + imagename=`make docker/name/operator/helm` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' + loadtest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: Build the Docker image + id: build_image + run: | + make docker/build/loadtest + imagename=`make docker/name/loadtest` + docker tag ${imagename} ${imagename}:${{ github.sha }} + echo "::set-output name=IMAGE_NAME::${imagename}" + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'table' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' diff --git a/.github/workflows/dockers-loadtest-image.yml b/.github/workflows/dockers-loadtest-image.yml index 670c885963a..9cab8a1d67b 100755 --- a/.github/workflows/dockers-loadtest-image.yml +++ b/.github/workflows/dockers-loadtest-image.yml @@ -39,6 +39,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/loadtest @@ -63,6 +68,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/loadtest` docker push ${imagename}:latest @@ -71,6 +77,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-manager-compressor-image.yml b/.github/workflows/dockers-manager-compressor-image.yml index 2b1fe961413..dc6799b2203 100644 --- a/.github/workflows/dockers-manager-compressor-image.yml +++ b/.github/workflows/dockers-manager-compressor-image.yml @@ -39,6 +39,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/manager-compressor @@ -63,6 +68,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/manager-compressor` docker push ${imagename}:latest @@ -71,6 +77,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-manager-index-image.yml b/.github/workflows/dockers-manager-index-image.yml index 7946a8fc21b..ce7ed593abd 100644 --- a/.github/workflows/dockers-manager-index-image.yml +++ b/.github/workflows/dockers-manager-index-image.yml @@ -39,6 +39,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/manager-index @@ -63,6 +68,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/manager-index` docker push ${imagename}:latest @@ -71,6 +77,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-meta-cassandra-image.yml b/.github/workflows/dockers-meta-cassandra-image.yml index a36a93d3dd8..16dafa9de21 100644 --- a/.github/workflows/dockers-meta-cassandra-image.yml +++ b/.github/workflows/dockers-meta-cassandra-image.yml @@ -41,6 +41,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/meta-cassandra @@ -65,6 +70,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/meta-cassandra` docker push ${imagename}:latest @@ -73,6 +79,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/.github/workflows/dockers-meta-redis-image.yml b/.github/workflows/dockers-meta-redis-image.yml index 712479ec04e..2eb03aa12f1 100755 --- a/.github/workflows/dockers-meta-redis-image.yml +++ b/.github/workflows/dockers-meta-redis-image.yml @@ -41,6 +41,11 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 10 + - name: Overwrite version name + if: github.event_name == 'pull_request' + run: | + pr_num=`cat $GITHUB_EVENT_PATH | jq -r ".number"` + echo "PR-${pr_num}" > versions/VALD_VERSION - name: Build the Docker image run: | make docker/build/meta-redis @@ -65,6 +70,7 @@ jobs: docker push ${imagename}:pr-${pr_num} - name: push to DockerHub (tags) if: startsWith( github.ref, 'refs/tags/') + id: push_to_dockerhub_tags run: | imagename=`make docker/name/meta-redis` docker push ${imagename}:latest @@ -73,6 +79,30 @@ jobs: docker push ${imagename}:${tag_name} docker tag ${imagename} ${imagename}:nightly docker push ${imagename}:nightly + echo "::set-output name=IMAGE_NAME::${imagename}" + echo "::set-output name=TAG_NAME::${tag_name}" + - name: Initialize CodeQL + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/init@v1 + - name: Run vulnerability scanner (table) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'table' + - name: Run vulnerability scanner (sarif) + if: startsWith( github.ref, 'refs/tags/') + uses: aquasecurity/trivy-action@master + with: + image-ref: "${{ steps.push_to_dockerhub_tags.outputs.IMAGE_NAME }}:${{ steps.push_to_dockerhub_tags.outputs.TAG_NAME }}" + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + - name: Upload Trivy scan results to Security tab + if: startsWith( github.ref, 'refs/tags/') + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' slack: name: Slack notification needs: build diff --git a/Makefile b/Makefile index 26264c1cdab..049d71d2186 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ REPO ?= vdaas NAME = vald GOPKG = github.com/$(REPO)/$(NAME) +DATETIME = $(eval DATETIME := $(shell date -u +%Y/%m/%d_%H:%M:%S%z))$(DATETIME) TAG = $(eval TAG := $(shell date -u +%Y%m%d-%H%M%S))$(TAG) BASE_IMAGE = $(NAME)-base AGENT_IMAGE = $(NAME)-agent-ngt @@ -39,6 +40,8 @@ NGT_VERSION := $(eval NGT_VERSION := $(shell cat versions/NGT_VERSION))$(NGT_VER NGT_REPO = github.com/yahoojapan/NGT GO_VERSION := $(eval GO_VERSION := $(shell cat versions/GO_VERSION))$(GO_VERSION) +GOOS := $(eval GOOS := $(shell go env GOOS))$(GOOS) +GOARCH := $(eval GOARCH := $(shell go env GOARCH))$(GOARCH) GOPATH := $(eval GOPATH := $(shell go env GOPATH))$(GOPATH) GOCACHE := $(eval GOCACHE := $(shell go env GOCACHE))$(GOCACHE) @@ -47,9 +50,9 @@ TENSORFLOW_C_VERSION := $(eval TENSORFLOW_C_VERSION := $(shell cat versions/TENS OPERATOR_SDK_VERSION := $(eval OPERATOR_SDK_VERSION := $(shell cat versions/OPERATOR_SDK_VERSION))$(OPERATOR_SDK_VERSION) KIND_VERSION ?= v0.8.1 -HELM_VERSION ?= v3.2.1 +HELM_VERSION ?= v3.2.4 HELM_DOCS_VERSION ?= 0.13.0 -VALDCLI_VERSION ?= v0.0.38 +VALDCLI_VERSION ?= v0.0.50 TELEPRESENCE_VERSION ?= 0.105 SWAP_DEPLOYMENT_TYPE ?= deployment @@ -59,16 +62,13 @@ SWAP_TAG ?= latest BINDIR ?= /usr/local/bin UNAME := $(eval UNAME := $(shell uname))$(UNAME) +CPU_INFO_FLAGS := $(eval CPU_INFO_FLAGS := $(shell cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1))$(CPU_INFO_FLAGS) +GIT_COMMIT := $(eval GIT_COMMIT := $(shell git rev-list -1 HEAD))$(GIT_COMMIT) MAKELISTS := Makefile $(shell find Makefile.d -type f -regex ".*\.mk") ROOTDIR = $(eval ROOTDIR := $(shell git rev-parse --show-toplevel))$(ROOTDIR) PROTODIRS := $(eval PROTODIRS := $(shell find apis/proto -type d | sed -e "s%apis/proto/%%g" | grep -v "apis/proto"))$(PROTODIRS) -PBGODIRS = $(PROTODIRS:%=apis/grpc/%) -SWAGGERDIRS = $(PROTODIRS:%=apis/swagger/%) -GRAPHQLDIRS = $(PROTODIRS:%=apis/graphql/%) -PBDOCDIRS = $(PROTODIRS:%=apis/docs/%) - BENCH_DATASET_BASE_DIR = hack/benchmark/assets BENCH_DATASET_MD5_DIR_NAME = checksum BENCH_DATASET_HDF5_DIR_NAME = dataset @@ -82,6 +82,9 @@ GRAPHQLS = $(PROTOS:apis/proto/%.proto=apis/graphql/%.pb.graphqls) GQLCODES = $(GRAPHQLS:apis/graphql/%.pb.graphqls=apis/graphql/%.generated.go) PBDOCS = $(PROTOS:apis/proto/%.proto=apis/docs/%.md) +CFLAGS ?= -mno-avx512f -mno-avx512dq -mno-avx512cd -mno-avx512bw -mno-avx512vl +CXXFLAGS ?= $(CFLAGS) + BENCH_DATASET_MD5S := $(eval BENCH_DATASET_MD5S := $(shell find $(BENCH_DATASET_MD5_DIR) -type f -regex ".*\.md5"))$(BENCH_DATASET_MD5S) BENCH_DATASETS = $(BENCH_DATASET_MD5S:$(BENCH_DATASET_MD5_DIR)/%.md5=$(BENCH_DATASET_HDF5_DIR)/%.hdf5) @@ -143,9 +146,21 @@ GO_OPTION_SOURCES = $(eval GO_OPTION_SOURCES := $(shell find \ -regex '.*options?\.go' \ -not -name '*_test.go' \ -not -name 'doc.go'))$(GO_OPTION_SOURCES) + +GO_SOURCES_INTERNAL = $(eval GO_SOURCES_INTERNAL := $(shell find \ + ./internal \ + -type f \ + -name '*.go' \ + -not -name '*_test.go' \ + -not -name 'doc.go'))$(GO_SOURCES_INTERNAL) + GO_TEST_SOURCES = $(GO_SOURCES:%.go=%_test.go) GO_OPTION_TEST_SOURCES = $(GO_OPTION_SOURCES:%.go=%_test.go) +DISTROLESS_IMAGE ?= gcr.io/distroless/static +DISTROLESS_IMAGE_TAG ?= nonroot +UPX_OPTIONS ?= -9 + COMMA := , SHELL = bash @@ -248,7 +263,7 @@ format/yaml: deps: \ proto/deps \ goimports/install \ - prettier/install \ + prettier/install go mod tidy .PHONY: goimports/install @@ -302,6 +317,7 @@ ngt/install: /usr/local/include/NGT/Capi.h make install -C /tmp/NGT-$(NGT_VERSION) rm -rf v$(NGT_VERSION).tar.gz rm -rf /tmp/NGT-$(NGT_VERSION) + ldconfig .PHONY: tensorflow/install ## install TensorFlow for C @@ -335,6 +351,7 @@ changelog/next/print: @echo "$$BODY" include Makefile.d/bench.mk +include Makefile.d/build.mk include Makefile.d/docker.mk include Makefile.d/git.mk include Makefile.d/helm.mk diff --git a/Makefile.d/build.mk b/Makefile.d/build.mk new file mode 100644 index 00000000000..80a6be0cbef --- /dev/null +++ b/Makefile.d/build.mk @@ -0,0 +1,390 @@ +# +# Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +# +# 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 +# +# https://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. +# + +.PHONY: binary/build +## build all binaries +binary/build: \ + cmd/agent/core/ngt/ngt \ + cmd/agent/sidecar/sidecar \ + cmd/discoverer/k8s/discoverer \ + cmd/gateway/vald/vald \ + cmd/meta/redis/meta \ + cmd/meta/cassandra/meta \ + cmd/manager/backup/mysql/backup \ + cmd/manager/backup/cassandra/backup \ + cmd/manager/compressor/compressor \ + cmd/manager/index/index + +cmd/agent/core/ngt/ngt: \ + ngt/install \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/agent/core/ngt -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/agent/core/ngt ./pkg/agent/internal -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CFLAGS="$(CFLAGS)" \ + && export CXXFLAGS="$(CXXFLAGS)" \ + && export CGO_ENABLED=1 \ + && export CGO_CXXFLAGS="-g -Ofast -march=native" \ + && export CGO_FFLAGS="-g -Ofast -march=native" \ + && export CGO_LDFLAGS="-g -Ofast -march=native" \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static -fPIC -m64 -pthread -fopenmp -std=c++17 -lstdc++ -lm' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.NGTVersion=$(NGT_VERSION)' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags "cgo netgo" \ + -trimpath \ + -installsuffix "cgo netgo" \ + -o $@ \ + $(dir $@)main.go + +cmd/agent/sidecar/sidecar: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/agent/sidecar -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/agent/sidecar ./pkg/agent/internal -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -trimpath \ + -installsuffix netgo \ + -o $@ \ + $(dir $@)main.go + +cmd/discoverer/k8s/discoverer: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/discoverer/k8s -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/discoverer/k8s -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -installsuffix netgo \ + -trimpath \ + -o $@ \ + $(dir $@)main.go + +cmd/gateway/vald/vald: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/gateway/vald -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/gateway/vald -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -installsuffix netgo \ + -trimpath \ + -o $@ \ + $(dir $@)main.go + +cmd/meta/redis/meta: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/meta/redis -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/meta/redis -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -installsuffix netgo \ + -trimpath \ + -o $@ \ + $(dir $@)main.go + +cmd/meta/cassandra/meta: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/meta/cassandra -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/meta/cassandra -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -installsuffix netgo \ + -trimpath \ + -o $@ \ + $(dir $@)main.go + +cmd/manager/backup/mysql/backup: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/manager/backup/mysql -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/manager/backup/mysql -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -installsuffix netgo \ + -trimpath \ + -o $@ \ + $(dir $@)main.go + +cmd/manager/backup/cassandra/backup: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/manager/backup/cassandra -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/manager/backup/cassandra -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -installsuffix netgo \ + -trimpath \ + -o $@ \ + $(dir $@)main.go + +cmd/manager/compressor/compressor: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/manager/compressor -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/manager/compressor -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -trimpath \ + -installsuffix netgo \ + -o $@ \ + $(dir $@)main.go + +cmd/manager/index/index: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/manager/index -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/manager/index -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -trimpath \ + -installsuffix netgo \ + -o $@ \ + $(dir $@)main.go + +cmd/manager/replication/agent/agent: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/manager/replication/agent -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/manager/replication/agent -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -trimpath \ + -installsuffix netgo \ + -o $@ \ + $(dir $@)main.go + +cmd/manager/replication/controller/controller: \ + $(GO_SOURCES_INTERNAL) \ + $(PBGOS) \ + $(shell find ./cmd/manager/replication/controller -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') \ + $(shell find ./pkg/manager/replication/controller -type f -name '*.go' -not -name '*_test.go' -not -name 'doc.go') + export CGO_ENABLED=1 \ + && export GO111MODULE=on \ + && go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X '$(GOPKG)/internal/info.Version=$(VERSION)' \ + -X '$(GOPKG)/internal/info.GitCommit=$(GIT_COMMIT)' \ + -X '$(GOPKG)/internal/info.BuildTime=$(DATETIME)' \ + -X '$(GOPKG)/internal/info.GoVersion=$(GO_VERSION)' \ + -X '$(GOPKG)/internal/info.GoOS=$(GOOS)' \ + -X '$(GOPKG)/internal/info.GoArch=$(GOARCH)' \ + -X '$(GOPKG)/internal/info.CGOEnabled=$${CGO_ENABLED}' \ + -X '$(GOPKG)/internal/info.BuildCPUInfoFlags=$(CPU_INFO_FLAGS)'" \ + -a \ + -tags netgo \ + -trimpath \ + -installsuffix netgo \ + -o $@ \ + $(dir $@)main.go + +.PHONY: binary/build/zip +## build all binaries and zip them +binary/build/zip: \ + artifacts/vald-agent-ngt-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-agent-sidecar-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-discoverer-k8s-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-gateway-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-meta-redis-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-meta-cassandra-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-manager-backup-mysql-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-manager-backup-cassandra-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-manager-compressor-$(GOOS)-$(GOARCH).zip \ + artifacts/vald-manager-index-$(GOOS)-$(GOARCH).zip + +artifacts/vald-agent-ngt-$(GOOS)-$(GOARCH).zip: cmd/agent/core/ngt/ngt + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-agent-sidecar-$(GOOS)-$(GOARCH).zip: cmd/agent/sidecar/sidecar + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-discoverer-k8s-$(GOOS)-$(GOARCH).zip: cmd/discoverer/k8s/discoverer + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-gateway-$(GOOS)-$(GOARCH).zip: cmd/gateway/vald/vald + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-meta-redis-$(GOOS)-$(GOARCH).zip: cmd/meta/redis/meta + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-meta-cassandra-$(GOOS)-$(GOARCH).zip: cmd/meta/cassandra/meta + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-manager-backup-mysql-$(GOOS)-$(GOARCH).zip: cmd/manager/backup/mysql/backup + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-manager-backup-cassandra-$(GOOS)-$(GOARCH).zip: cmd/manager/backup/cassandra/backup + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-manager-compressor-$(GOOS)-$(GOARCH).zip: cmd/manager/compressor/compressor + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< + +artifacts/vald-manager-index-$(GOOS)-$(GOARCH).zip: cmd/manager/index/index + $(call mkdir, $(dir $@)) + zip --junk-paths $@ $< diff --git a/Makefile.d/docker.mk b/Makefile.d/docker.mk index 208b1eea003..5c1d02b7d61 100644 --- a/Makefile.d/docker.mk +++ b/Makefile.d/docker.mk @@ -45,7 +45,12 @@ docker/name/agent-ngt: .PHONY: docker/build/agent-ngt ## build agent-ngt image docker/build/agent-ngt: docker/build/base - docker build -f dockers/agent/core/ngt/Dockerfile -t $(REPO)/$(AGENT_IMAGE) . + docker build \ + -f dockers/agent/core/ngt/Dockerfile \ + -t $(REPO)/$(AGENT_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/agent-sidecar docker/name/agent-sidecar: @@ -54,7 +59,12 @@ docker/name/agent-sidecar: .PHONY: docker/build/agent-sidecar ## build agent-sidecar image docker/build/agent-sidecar: docker/build/base - docker build -f dockers/agent/sidecar/Dockerfile -t $(REPO)/$(AGENT_SIDECAR_IMAGE) . + docker build \ + -f dockers/agent/sidecar/Dockerfile \ + -t $(REPO)/$(AGENT_SIDECAR_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/discoverer-k8s docker/name/discoverer-k8s: @@ -63,7 +73,12 @@ docker/name/discoverer-k8s: .PHONY: docker/build/discoverer-k8s ## build discoverer-k8s image docker/build/discoverer-k8s: docker/build/base - docker build -f dockers/discoverer/k8s/Dockerfile -t $(REPO)/$(DISCOVERER_IMAGE) . + docker build \ + -f dockers/discoverer/k8s/Dockerfile \ + -t $(REPO)/$(DISCOVERER_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/gateway-vald docker/name/gateway-vald: @@ -72,7 +87,12 @@ docker/name/gateway-vald: .PHONY: docker/build/gateway-vald ## build gateway-vald image docker/build/gateway-vald: docker/build/base - docker build -f dockers/gateway/vald/Dockerfile -t $(REPO)/$(GATEWAY_IMAGE) . + docker build \ + -f dockers/gateway/vald/Dockerfile \ + -t $(REPO)/$(GATEWAY_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/meta-redis docker/name/meta-redis: @@ -81,7 +101,12 @@ docker/name/meta-redis: .PHONY: docker/build/meta-redis ## build meta-redis image docker/build/meta-redis: docker/build/base - docker build -f dockers/meta/redis/Dockerfile -t $(REPO)/$(META_REDIS_IMAGE) . + docker build \ + -f dockers/meta/redis/Dockerfile \ + -t $(REPO)/$(META_REDIS_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/meta-cassandra docker/name/meta-cassandra: @@ -90,7 +115,12 @@ docker/name/meta-cassandra: .PHONY: docker/build/meta-cassandra ## build meta-cassandra image docker/build/meta-cassandra: docker/build/base - docker build -f dockers/meta/cassandra/Dockerfile -t $(REPO)/$(META_CASSANDRA_IMAGE) . + docker build \ + -f dockers/meta/cassandra/Dockerfile \ + -t $(REPO)/$(META_CASSANDRA_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/backup-manager-mysql docker/name/backup-manager-mysql: @@ -99,7 +129,12 @@ docker/name/backup-manager-mysql: .PHONY: docker/build/backup-manager-mysql ## build backup-manager-mysql image docker/build/backup-manager-mysql: docker/build/base - docker build -f dockers/manager/backup/mysql/Dockerfile -t $(REPO)/$(MANAGER_BACKUP_MYSQL_IMAGE) . + docker build \ + -f dockers/manager/backup/mysql/Dockerfile \ + -t $(REPO)/$(MANAGER_BACKUP_MYSQL_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/backup-manager-cassandra docker/name/backup-manager-cassandra: @@ -108,7 +143,12 @@ docker/name/backup-manager-cassandra: .PHONY: docker/build/backup-manager-cassandra ## build backup-manager-cassandra image docker/build/backup-manager-cassandra: docker/build/base - docker build -f dockers/manager/backup/cassandra/Dockerfile -t $(REPO)/$(MANAGER_BACKUP_CASSANDRA_IMAGE) . + docker build \ + -f dockers/manager/backup/cassandra/Dockerfile \ + -t $(REPO)/$(MANAGER_BACKUP_CASSANDRA_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/manager-compressor docker/name/manager-compressor: @@ -117,7 +157,12 @@ docker/name/manager-compressor: .PHONY: docker/build/manager-compressor ## build manager-compressor image docker/build/manager-compressor: docker/build/base - docker build -f dockers/manager/compressor/Dockerfile -t $(REPO)/$(MANAGER_COMPRESSOR_IMAGE) . + docker build \ + -f dockers/manager/compressor/Dockerfile \ + -t $(REPO)/$(MANAGER_COMPRESSOR_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/manager-index docker/name/manager-index: @@ -126,7 +171,12 @@ docker/name/manager-index: .PHONY: docker/build/manager-index ## build manager-index image docker/build/manager-index: docker/build/base - docker build -f dockers/manager/index/Dockerfile -t $(REPO)/$(MANAGER_INDEX_IMAGE) . + docker build \ + -f dockers/manager/index/Dockerfile \ + -t $(REPO)/$(MANAGER_INDEX_IMAGE) . \ + --build-arg DISTROLESS_IMAGE=$(DISTROLESS_IMAGE) \ + --build-arg DISTROLESS_IMAGE_TAG=$(DISTROLESS_IMAGE_TAG) \ + --build-arg UPX_OPTIONS=$(UPX_OPTIONS) .PHONY: docker/name/ci-container docker/name/ci-container: diff --git a/Makefile.d/proto.mk b/Makefile.d/proto.mk index a44a372510f..129648244d1 100644 --- a/Makefile.d/proto.mk +++ b/Makefile.d/proto.mk @@ -68,7 +68,8 @@ proto/deps: \ $(GOPATH)/bin/swagger \ $(GOPATH)/src/google.golang.org/genproto \ $(GOPATH)/src/github.com/protocolbuffers/protobuf \ - $(GOPATH)/src/github.com/googleapis/googleapis + $(GOPATH)/src/github.com/googleapis/googleapis \ + $(GOPATH)/src/github.com/envoyproxy/protoc-gen-validate $(GOPATH)/src/github.com/protocolbuffers/protobuf: git clone \ @@ -82,6 +83,12 @@ $(GOPATH)/src/github.com/googleapis/googleapis: https://github.com/googleapis/googleapis \ $(GOPATH)/src/github.com/googleapis/googleapis +$(GOPATH)/src/github.com/envoyproxy/protoc-gen-validate: + git clone \ + --depth 1 \ + https://github.com/envoyproxy/protoc-gen-validate \ + $(GOPATH)/src/github.com/envoyproxy/protoc-gen-validate + $(GOPATH)/src/google.golang.org/genproto: $(call go-get, google.golang.org/genproto/...) @@ -119,7 +126,7 @@ $(GOPATH)/bin/protoc-gen-gqlgencfg: $(call go-get-no-mod, github.com/danielvladco/go-proto-gql/protoc-gen-gqlgencfg) $(GOPATH)/bin/protoc-gen-validate: - $(call go-get-no-mod, github.com/envoyproxy/protoc-gen-validate) + $(call go-get, github.com/envoyproxy/protoc-gen-validate) $(GOPATH)/bin/prototool: $(call go-get, github.com/uber/prototool/cmd/prototool) @@ -128,49 +135,134 @@ $(GOPATH)/bin/protoc-gen-doc: $(call go-get, github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc) $(GOPATH)/bin/swagger: - $(call go-get-no-mod, github.com/go-swagger/go-swagger/cmd/swagger) + $(call go-get, github.com/go-swagger/go-swagger/cmd/swagger) $(GOPATH)/bin/gqlgen: $(call go-get, github.com/99designs/gqlgen) -$(PBGODIRS): - $(call mkdir, $@) - $(call rm, -rf, $@/*) - -$(SWAGGERDIRS): - $(call mkdir, $@) - $(call rm, -rf, $@/*) - -$(GRAPHQLDIRS): - $(call mkdir, $@) - $(call rm, -rf, $@/*) - -$(PBDOCDIRS): - $(call mkdir, $@) - $(call rm, -rf, $@/*) - -$(PBPYDIRS): - $(call mkdir, $@) - $(call rm, -rf, $@/*) - -$(PBGOS): proto/deps $(PBGODIRS) +$(PBGOS): \ + $(PROTOS) \ + $(GOPATH)/bin/gqlgen \ + $(GOPATH)/bin/protoc-gen-doc \ + $(GOPATH)/bin/protoc-gen-go \ + $(GOPATH)/bin/protoc-gen-gogo \ + $(GOPATH)/bin/protoc-gen-gofast \ + $(GOPATH)/bin/protoc-gen-gogofast \ + $(GOPATH)/bin/protoc-gen-gogofaster \ + $(GOPATH)/bin/protoc-gen-gogoslick \ + $(GOPATH)/bin/protoc-gen-gogqlgen \ + $(GOPATH)/bin/protoc-gen-gql \ + $(GOPATH)/bin/protoc-gen-gqlgencfg \ + $(GOPATH)/bin/protoc-gen-grpc-gateway \ + $(GOPATH)/bin/protoc-gen-swagger \ + $(GOPATH)/bin/protoc-gen-validate \ + $(GOPATH)/bin/swagger \ + $(GOPATH)/src/google.golang.org/genproto \ + $(GOPATH)/src/github.com/protocolbuffers/protobuf \ + $(GOPATH)/src/github.com/googleapis/googleapis \ + $(GOPATH)/src/github.com/envoyproxy/protoc-gen-validate @$(call green, "generating pb.go files...") + $(call mkdir, $(dir $@)) $(call protoc-gen, $(patsubst apis/grpc/%.pb.go,apis/proto/%.proto,$@), --gogofast_out=plugins=grpc:$(GOPATH)/src) # we have to enable validate after https://github.com/envoyproxy/protoc-gen-validate/pull/257 is merged # $(call protoc-gen, $(patsubst apis/grpc/%.pb.go,apis/proto/%.proto,$@), --gogofast_out=plugins=grpc:$(GOPATH)/src --validate_out=lang=gogo:$(GOPATH)/src) -$(SWAGGERS): proto/deps $(SWAGGERDIRS) +$(SWAGGERS): \ + $(PROTOS) \ + $(GOPATH)/bin/gqlgen \ + $(GOPATH)/bin/protoc-gen-doc \ + $(GOPATH)/bin/protoc-gen-go \ + $(GOPATH)/bin/protoc-gen-gogo \ + $(GOPATH)/bin/protoc-gen-gofast \ + $(GOPATH)/bin/protoc-gen-gogofast \ + $(GOPATH)/bin/protoc-gen-gogofaster \ + $(GOPATH)/bin/protoc-gen-gogoslick \ + $(GOPATH)/bin/protoc-gen-gogqlgen \ + $(GOPATH)/bin/protoc-gen-gql \ + $(GOPATH)/bin/protoc-gen-gqlgencfg \ + $(GOPATH)/bin/protoc-gen-grpc-gateway \ + $(GOPATH)/bin/protoc-gen-swagger \ + $(GOPATH)/bin/protoc-gen-validate \ + $(GOPATH)/bin/swagger \ + $(GOPATH)/src/google.golang.org/genproto \ + $(GOPATH)/src/github.com/protocolbuffers/protobuf \ + $(GOPATH)/src/github.com/googleapis/googleapis \ + $(GOPATH)/src/github.com/envoyproxy/protoc-gen-validate @$(call green, "generating swagger.json files...") + $(call mkdir, $(dir $@)) $(call protoc-gen, $(patsubst apis/swagger/%.swagger.json,apis/proto/%.proto,$@), --swagger_out=json_names_for_fields=true:$(dir $@)) -$(GRAPHQLS): proto/deps $(GRAPHQLDIRS) +$(GRAPHQLS): \ + $(PROTOS) \ + $(GOPATH)/bin/gqlgen \ + $(GOPATH)/bin/protoc-gen-doc \ + $(GOPATH)/bin/protoc-gen-go \ + $(GOPATH)/bin/protoc-gen-gogo \ + $(GOPATH)/bin/protoc-gen-gofast \ + $(GOPATH)/bin/protoc-gen-gogofast \ + $(GOPATH)/bin/protoc-gen-gogofaster \ + $(GOPATH)/bin/protoc-gen-gogoslick \ + $(GOPATH)/bin/protoc-gen-gogqlgen \ + $(GOPATH)/bin/protoc-gen-gql \ + $(GOPATH)/bin/protoc-gen-gqlgencfg \ + $(GOPATH)/bin/protoc-gen-grpc-gateway \ + $(GOPATH)/bin/protoc-gen-swagger \ + $(GOPATH)/bin/protoc-gen-validate \ + $(GOPATH)/bin/swagger \ + $(GOPATH)/src/google.golang.org/genproto \ + $(GOPATH)/src/github.com/protocolbuffers/protobuf \ + $(GOPATH)/src/github.com/googleapis/googleapis \ + $(GOPATH)/src/github.com/envoyproxy/protoc-gen-validate @$(call green, "generating pb.graphqls files...") + $(call mkdir, $(dir $@)) $(call protoc-gen, $(patsubst apis/graphql/%.pb.graphqls,apis/proto/%.proto,$@), --gql_out=paths=source_relative:$(dir $@)) -$(GQLCODES): proto/deps $(GRAPHQLS) +$(GQLCODES): \ + $(PROTOS) \ + $(GOPATH)/bin/gqlgen \ + $(GOPATH)/bin/protoc-gen-doc \ + $(GOPATH)/bin/protoc-gen-go \ + $(GOPATH)/bin/protoc-gen-gogo \ + $(GOPATH)/bin/protoc-gen-gofast \ + $(GOPATH)/bin/protoc-gen-gogofast \ + $(GOPATH)/bin/protoc-gen-gogofaster \ + $(GOPATH)/bin/protoc-gen-gogoslick \ + $(GOPATH)/bin/protoc-gen-gogqlgen \ + $(GOPATH)/bin/protoc-gen-gql \ + $(GOPATH)/bin/protoc-gen-gqlgencfg \ + $(GOPATH)/bin/protoc-gen-grpc-gateway \ + $(GOPATH)/bin/protoc-gen-swagger \ + $(GOPATH)/bin/protoc-gen-validate \ + $(GOPATH)/bin/swagger \ + $(GOPATH)/src/google.golang.org/genproto \ + $(GOPATH)/src/github.com/protocolbuffers/protobuf \ + $(GOPATH)/src/github.com/googleapis/googleapis \ + $(GOPATH)/src/github.com/envoyproxy/protoc-gen-validate @$(call green, "generating graphql generated.go files...") + $(call mkdir, $(dir $@)) sh hack/graphql/gqlgen.sh $(dir $@) $(patsubst apis/graphql/%.generated.go,apis/graphql/%.pb.graphqls,$@) $@ -$(PBDOCS): proto/deps $(PBDOCDIRS) +$(PBDOCS): \ + $(PROTOS) \ + $(GOPATH)/bin/gqlgen \ + $(GOPATH)/bin/protoc-gen-doc \ + $(GOPATH)/bin/protoc-gen-go \ + $(GOPATH)/bin/protoc-gen-gogo \ + $(GOPATH)/bin/protoc-gen-gofast \ + $(GOPATH)/bin/protoc-gen-gogofast \ + $(GOPATH)/bin/protoc-gen-gogofaster \ + $(GOPATH)/bin/protoc-gen-gogoslick \ + $(GOPATH)/bin/protoc-gen-gogqlgen \ + $(GOPATH)/bin/protoc-gen-gql \ + $(GOPATH)/bin/protoc-gen-gqlgencfg \ + $(GOPATH)/bin/protoc-gen-grpc-gateway \ + $(GOPATH)/bin/protoc-gen-swagger \ + $(GOPATH)/bin/protoc-gen-validate \ + $(GOPATH)/bin/swagger \ + $(GOPATH)/src/google.golang.org/genproto \ + $(GOPATH)/src/github.com/protocolbuffers/protobuf \ + $(GOPATH)/src/github.com/googleapis/googleapis \ + $(GOPATH)/src/github.com/envoyproxy/protoc-gen-validate @$(call green, "generating documents...") + $(call mkdir, $(dir $@)) $(call protoc-gen, $(patsubst apis/docs/%.md,apis/proto/%.proto,$@), --plugin=protoc-gen-doc=$(GOPATH)/bin/protoc-gen-doc --doc_opt=markdown$(COMMA)docs.md --doc_out=$(dir $@)) diff --git a/dockers/agent/core/ngt/Dockerfile b/dockers/agent/core/ngt/Dockerfile index f09b7abf849..fe5050d1a29 100644 --- a/dockers/agent/core/ngt/Dockerfile +++ b/dockers/agent/core/ngt/Dockerfile @@ -14,7 +14,12 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald @@ -37,72 +42,30 @@ COPY pkg/${PKG_INTERNAL} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . -ENV CFLAGS "-mno-avx512f -mno-avx512dq -mno-avx512cd -mno-avx512bw -mno-avx512vl" -ENV CXXFLAGS ${CFLAGS} +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . -WORKDIR /tmp -COPY versions/NGT_VERSION . -RUN export NGT_VERSION="$(cat NGT_VERSION)" \ - && curl -LO "https://github.com/yahoojapan/NGT/archive/v${NGT_VERSION}.tar.gz" \ - && tar zxf "v${NGT_VERSION}.tar.gz" -C /tmp \ - && cd "/tmp/NGT-${NGT_VERSION}" \ - && cmake . \ - && make -j -C "/tmp/NGT-${NGT_VERSION}" \ - && make install -C "/tmp/NGT-${NGT_VERSION}" +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . -COPY versions/NGT_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && NGT_VERSION="$(cat NGT_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=1 \ - && CGO_CXXFLAGS="-g -Ofast -march=native" \ - CGO_FFLAGS="-g -Ofast -march=native" \ - CGO_LDFLAGS="-g -Ofast -march=native" \ - GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static -fPIC -m64 -pthread -fopenmp -std=c++17 -lstdc++ -lm' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.NGTVersion=${NGT_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags "cgo netgo" \ - -trimpath \ - -installsuffix "cgo netgo" \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} RUN cp sample.yaml /tmp/config.yaml -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest -LABEL maintainer "kpango " +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME ngt -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} COPY --from=builder /tmp/config.yaml /etc/server/config.yaml +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/ngt"] diff --git a/dockers/agent/sidecar/Dockerfile b/dockers/agent/sidecar/Dockerfile index f72d93b8fef..373460da1f4 100644 --- a/dockers/agent/sidecar/Dockerfile +++ b/dockers/agent/sidecar/Dockerfile @@ -14,7 +14,12 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald @@ -37,49 +42,26 @@ COPY pkg/${PKG_INTERNAL} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -trimpath \ - -installsuffix netgo \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest -LABEL maintainer "kpango " + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME sidecar -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/sidecar"] diff --git a/dockers/ci/base/Dockerfile b/dockers/ci/base/Dockerfile index b1bc4709e91..6708722ef44 100644 --- a/dockers/ci/base/Dockerfile +++ b/dockers/ci/base/Dockerfile @@ -35,6 +35,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ npm \ jq \ sed \ + zip \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/dockers/discoverer/k8s/Dockerfile b/dockers/discoverer/k8s/Dockerfile index 4c55e78194e..48297e9cb79 100644 --- a/dockers/discoverer/k8s/Dockerfile +++ b/dockers/discoverer/k8s/Dockerfile @@ -14,7 +14,12 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald @@ -33,49 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -installsuffix netgo \ - -trimpath \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest -LABEL maintainer "kpango " + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME discoverer -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/discoverer"] diff --git a/dockers/gateway/vald/Dockerfile b/dockers/gateway/vald/Dockerfile index 3420066d580..d45c873d866 100644 --- a/dockers/gateway/vald/Dockerfile +++ b/dockers/gateway/vald/Dockerfile @@ -14,7 +14,12 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -installsuffix netgo \ - -trimpath \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME vald -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/vald"] diff --git a/dockers/manager/backup/cassandra/Dockerfile b/dockers/manager/backup/cassandra/Dockerfile index 599c5deae06..d5a907f36f4 100644 --- a/dockers/manager/backup/cassandra/Dockerfile +++ b/dockers/manager/backup/cassandra/Dockerfile @@ -14,12 +14,17 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald -ENV APP_NAME cassandra -ENV PKG manager/backup/${APP_NAME} +ENV PKG manager/backup/cassandra +ENV APP_NAME backup WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/internal COPY internal . @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -installsuffix netgo \ - -trimpath \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest - -ENV APP_NAME cassandra - -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " + +ENV APP_NAME backup + COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} -ENTRYPOINT ["/go/bin/cassandra"] +USER nonroot:nonroot + +ENTRYPOINT ["/go/bin/backup"] diff --git a/dockers/manager/backup/mysql/Dockerfile b/dockers/manager/backup/mysql/Dockerfile index cf012b700c6..bcacf04bfda 100644 --- a/dockers/manager/backup/mysql/Dockerfile +++ b/dockers/manager/backup/mysql/Dockerfile @@ -14,12 +14,17 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald -ENV APP_NAME mysql -ENV PKG manager/backup/${APP_NAME} +ENV PKG manager/backup/mysql +ENV APP_NAME backup WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/internal COPY internal . @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -installsuffix netgo \ - -trimpath \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest - -ENV APP_NAME mysql - -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " + +ENV APP_NAME backup + COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} -ENTRYPOINT ["/go/bin/mysql"] +USER nonroot:nonroot + +ENTRYPOINT ["/go/bin/backup"] diff --git a/dockers/manager/compressor/Dockerfile b/dockers/manager/compressor/Dockerfile index 91e6a56d9ca..a7223bb05bd 100644 --- a/dockers/manager/compressor/Dockerfile +++ b/dockers/manager/compressor/Dockerfile @@ -14,12 +14,17 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald +ENV PKG manager/compressor ENV APP_NAME compressor -ENV PKG manager/${APP_NAME} WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/internal COPY internal . @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -trimpath \ - -installsuffix netgo \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME compressor -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/compressor"] diff --git a/dockers/manager/index/Dockerfile b/dockers/manager/index/Dockerfile index 8bfed6fdbf5..4603697227e 100644 --- a/dockers/manager/index/Dockerfile +++ b/dockers/manager/index/Dockerfile @@ -14,12 +14,17 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald +ENV PKG manager/index ENV APP_NAME index -ENV PKG manager/${APP_NAME} WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/internal COPY internal . @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -trimpath \ - -installsuffix netgo \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME index -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/index"] diff --git a/dockers/manager/replication/agent/Dockerfile b/dockers/manager/replication/agent/Dockerfile index 505169b5fdd..499cb1337c3 100644 --- a/dockers/manager/replication/agent/Dockerfile +++ b/dockers/manager/replication/agent/Dockerfile @@ -14,12 +14,17 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald +ENV PKG manager/replication/agent ENV APP_NAME agent -ENV PKG manager/replication/${APP_NAME} WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/internal COPY internal . @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -trimpath \ - -installsuffix netgo \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME agent -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/agent"] diff --git a/dockers/manager/replication/controller/Dockerfile b/dockers/manager/replication/controller/Dockerfile index 36f00997332..85b1baf00f9 100644 --- a/dockers/manager/replication/controller/Dockerfile +++ b/dockers/manager/replication/controller/Dockerfile @@ -14,12 +14,17 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald +ENV PKG manager/replication/controller ENV APP_NAME controller -ENV PKG manager/replication/${APP_NAME} WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/internal COPY internal . @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -trimpath \ - -installsuffix netgo \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME controller -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/controller"] diff --git a/dockers/meta/cassandra/Dockerfile b/dockers/meta/cassandra/Dockerfile index 4a0694df688..6134e24553f 100644 --- a/dockers/meta/cassandra/Dockerfile +++ b/dockers/meta/cassandra/Dockerfile @@ -14,7 +14,12 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -installsuffix netgo \ - -trimpath \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME meta -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/meta"] diff --git a/dockers/meta/redis/Dockerfile b/dockers/meta/redis/Dockerfile index b037b957882..1cff3b90f25 100644 --- a/dockers/meta/redis/Dockerfile +++ b/dockers/meta/redis/Dockerfile @@ -14,7 +14,12 @@ # limitations under the License. # +ARG DISTROLESS_IMAGE=gcr.io/distroless/static +ARG DISTROLESS_IMAGE_TAG=nonroot +ARG UPX_OPTIONS=-9 + FROM vdaas/vald-base:latest AS builder +ARG UPX_OPTIONS ENV ORG vdaas ENV REPO vald @@ -33,48 +38,26 @@ COPY pkg/${PKG} . WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} COPY cmd/${PKG} . +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/versions +COPY versions . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/Makefile.d +COPY Makefile.d . + WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} -COPY versions/GO_VERSION . -COPY versions/VALD_VERSION . +COPY Makefile . COPY .git . -RUN GO_VERSION="$(cat GO_VERSION)" \ - && VALD_VERSION="$(cat VALD_VERSION)" \ - && GIT_COMMIT="$(git rev-list -1 HEAD)" \ - && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ - && GOOS="$(go env GOOS)" \ - && GOARCH="$(go env GOARCH)" \ - && CGO_ENABLED=0 \ - && GO111MODULE=on \ - go build \ - --ldflags "-s -w -linkmode 'external' \ - -extldflags '-static' \ - -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ - -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ - -a \ - -tags netgo \ - -installsuffix netgo \ - -trimpath \ - -o "${APP_NAME}" \ - "cmd/${PKG}/main.go" \ - && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" - -# Start From Scratch For Running Environment -FROM scratch -# Start From Alpine For Debug Environment -# FROM alpine:latest + +RUN make REPO=${ORG} NAME=${REPO} cmd/${PKG}/${APP_NAME} \ + && upx ${UPX_OPTIONS} -o "/usr/bin/${APP_NAME}" "cmd/${PKG}/${APP_NAME}" + +FROM ${DISTROLESS_IMAGE}:${DISTROLESS_IMAGE_TAG} +LABEL maintainer "Vald team " ENV APP_NAME meta -# Copy certificates for SSL/TLS -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -# Copy permissions -COPY --from=builder /etc/passwd /etc/passwd -# Copy our static executable COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +USER nonroot:nonroot + ENTRYPOINT ["/go/bin/meta"] diff --git a/go.mod b/go.mod index 1c1173f93e7..a9447eab19f 100755 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.14 replace ( github.com/Azure/go-autorest => github.com/Azure/go-autorest v14.2.0+incompatible + github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v1.33.21 github.com/boltdb/bolt => github.com/boltdb/bolt v1.3.1 github.com/cockroachdb/errors => github.com/cockroachdb/errors v1.5.1-0.20200617111016-cc0024f9c4d3 github.com/coreos/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200425165423-262c93980547 diff --git a/hack/go.mod.default b/hack/go.mod.default index d2c6575f854..2bcce5dd684 100755 --- a/hack/go.mod.default +++ b/hack/go.mod.default @@ -4,6 +4,7 @@ go 1.14 replace ( github.com/Azure/go-autorest => github.com/Azure/go-autorest v14.2.0 + github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v1.33.21 github.com/boltdb/bolt => github.com/boltdb/bolt v1.3.1 github.com/cockroachdb/errors => github.com/cockroachdb/errors master github.com/coreos/etcd => go.etcd.io/etcd master diff --git a/internal/info/info.go b/internal/info/info.go index e80142cd393..5cd3d18f520 100644 --- a/internal/info/info.go +++ b/internal/info/info.go @@ -25,7 +25,6 @@ import ( "strconv" "strings" "sync" - "time" "github.com/vdaas/vald/internal/log" ) @@ -59,7 +58,7 @@ var ( GitCommit = "master" Organization = "vdaas" Repository = "vald" - BuildTime = time.Now().Format(time.RFC1123) + BuildTime = "" GoVersion string GoOS string From 54110b5d5761e6a98aa5dfa1a005fba73a61582d Mon Sep 17 00:00:00 2001 From: Kevin Diu Date: Wed, 12 Aug 2020 15:35:31 +0900 Subject: [PATCH 04/10] :white_check_mark: Add internal/compress/zstd_option test (#621) * add zstd option * apply suggestion --- internal/compress/zstd_option.go | 3 + internal/compress/zstd_option_test.go | 257 +++++++++----------------- 2 files changed, 91 insertions(+), 169 deletions(-) diff --git a/internal/compress/zstd_option.go b/internal/compress/zstd_option.go index 633a8a65eef..8578b3a471d 100644 --- a/internal/compress/zstd_option.go +++ b/internal/compress/zstd_option.go @@ -21,6 +21,7 @@ import ( "github.com/klauspost/compress/zstd" ) +// ZstdOption represents the functional option for zstdCompressor type ZstdOption func(c *zstdCompressor) error var ( @@ -30,6 +31,7 @@ var ( } ) +// WithZstdGob represents the option to set the GobOption to initialize Gob. func WithZstdGob(opts ...GobOption) ZstdOption { return func(c *zstdCompressor) error { gobc, err := NewGob(opts...) @@ -41,6 +43,7 @@ func WithZstdGob(opts ...GobOption) ZstdOption { } } +// WithZstdCompressionLevel represents the option to set the compress level for zstd. func WithZstdCompressionLevel(level int) ZstdOption { return func(c *zstdCompressor) error { c.eoptions = append(c.eoptions, zstd.WithEncoderLevel(zstd.EncoderLevelFromZstd(level))) diff --git a/internal/compress/zstd_option_test.go b/internal/compress/zstd_option_test.go index 1af3685d765..fb5c4d8bad1 100644 --- a/internal/compress/zstd_option_test.go +++ b/internal/compress/zstd_option_test.go @@ -18,88 +18,60 @@ package compress import ( + "reflect" "testing" + "github.com/klauspost/compress/zstd" + "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/test/comparator" "go.uber.org/goleak" ) func TestWithZstdGob(t *testing.T) { - type T = interface{} + type T = zstdCompressor type args struct { opts []GobOption } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - opts: nil, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - opts: nil, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set zdtd gob option success", + args: args{ + opts: nil, + }, + want: want{ + obj: &T{ + gobc: new(gobCompressor), + }, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -107,112 +79,75 @@ func TestWithZstdGob(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithZstdGob(test.args.opts...) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithZstdGob(test.args.opts...) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithZstdGob(test.args.opts...) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithZstdCompressionLevel(t *testing.T) { - type T = interface{} + type T = zstdCompressor type args struct { level int } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + + zstdComparator := []comparator.Option{ + comparator.AllowUnexported(*obj), + comparator.Comparer(func(x, y zstd.EOption) bool { + return !(x == nil && y != nil) || !(x != nil && y == nil) + }), + } + + if diff := comparator.Diff(w.obj, obj, zstdComparator...); diff != "" { + return errors.New(diff) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - level: 0, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - level: 0, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set compression level success", + args: args{ + level: 1, + }, + want: want{ + obj: func() *zstdCompressor { + c := new(zstdCompressor) + c.eoptions = []zstd.EOption{ + zstd.WithEncoderLevel(zstd.SpeedFastest), + } + return c + }(), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -220,31 +155,15 @@ func TestWithZstdCompressionLevel(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithZstdCompressionLevel(test.args.level) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithZstdCompressionLevel(test.args.level) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithZstdCompressionLevel(test.args.level) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } From 29f8ce48445da49c969c06dbfa3329c7d80f86a6 Mon Sep 17 00:00:00 2001 From: Kiichiro YUKAWA Date: Thu, 13 Aug 2020 14:31:46 +0900 Subject: [PATCH 05/10] :pencil: change showing image method (#624) Signed-off-by: vankichi --- docs/usecase/usage-example.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/usecase/usage-example.md b/docs/usecase/usage-example.md index a389eb6f1a9..0de40d874be 100644 --- a/docs/usecase/usage-example.md +++ b/docs/usecase/usage-example.md @@ -11,7 +11,7 @@ ## Image and video processing - ![Image and video processing](../../assets/docs/usecase_image.png) + You can use Vald as the image/video processing engine to search the similar image/video or analyze the image/video for your use case. @@ -27,7 +27,7 @@ ## Audio processing - ![Audio processing](../../assets/docs/usecase_audio.png) + Audio processing is important for personal assistant implementation. @@ -41,7 +41,7 @@ ## Text processing - ![Text processing](../../assets/docs/usecase_text.png) + Using a text vectorizing model like BERT, you can process your text data in Vald. @@ -54,7 +54,7 @@ ## Data analysis - ![Data analysis](../../assets/docs/usecase_data.png) + Vald can process the vector data, you can analyze every data you can vectorize. From 13c5365c116eb75e73c547d17797254eb49bd23c Mon Sep 17 00:00:00 2001 From: Hiroto Funakoshi Date: Thu, 13 Aug 2020 16:46:01 +0900 Subject: [PATCH 06/10] :white_check_mark: Add test for gzip_option (#625) * feat: add test for gzip_option Signed-off-by: hlts2 * feat: add comment Signed-off-by: hlts2 --- internal/compress/gzip_option.go | 3 + internal/compress/gzip_option_test.go | 250 +++++++++----------------- 2 files changed, 87 insertions(+), 166 deletions(-) diff --git a/internal/compress/gzip_option.go b/internal/compress/gzip_option.go index bbfaa4578dd..7cdfdcd68c2 100644 --- a/internal/compress/gzip_option.go +++ b/internal/compress/gzip_option.go @@ -23,6 +23,7 @@ import ( "github.com/vdaas/vald/internal/errors" ) +// GzipOption represents the functional option for gzipCompressor. type GzipOption func(c *gzipCompressor) error var ( @@ -32,6 +33,7 @@ var ( } ) +// WithGzipGob represents the option to set the GobOption to initialize Gob. func WithGzipGob(opts ...GobOption) GzipOption { return func(c *gzipCompressor) error { gobc, err := NewGob(opts...) @@ -43,6 +45,7 @@ func WithGzipGob(opts ...GobOption) GzipOption { } } +// WithGzipCompressionLevel represents the option to set the compress level for gzip. func WithGzipCompressionLevel(level int) GzipOption { return func(c *gzipCompressor) error { if level < gzip.HuffmanOnly || level > gzip.BestCompression { diff --git a/internal/compress/gzip_option_test.go b/internal/compress/gzip_option_test.go index 4c6a22d7f48..f094323fe5a 100644 --- a/internal/compress/gzip_option_test.go +++ b/internal/compress/gzip_option_test.go @@ -18,83 +18,53 @@ package compress import ( + "reflect" "testing" + "github.com/vdaas/vald/internal/errors" "go.uber.org/goleak" ) func TestWithGzipGob(t *testing.T) { - type T = interface{} + type T = gzipCompressor type args struct { opts []GobOption } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - opts: nil, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - opts: nil, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set zdtd gob option success", + args: args{ + opts: nil, + }, + want: want{ + obj: &T{ + gobc: new(gobCompressor), + }, + }, + }, } for _, test := range tests { @@ -107,107 +77,71 @@ func TestWithGzipGob(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithGzipGob(test.args.opts...) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithGzipGob(test.args.opts...) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithGzipGob(test.args.opts...) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithGzipCompressionLevel(t *testing.T) { - type T = interface{} + type T = gzipCompressor type args struct { level int } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - level: 0, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - level: 0, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when level is 0", + args: args{ + level: 0, + }, + want: want{ + obj: &T{ + compressionLevel: 0, + }, + err: nil, + }, + }, + + { + name: "set nothing when level is `-10000`", + args: args{ + level: -10000, + }, + want: want{ + obj: new(T), + err: errors.ErrInvalidCompressionLevel(-10000), + }, + }, } for _, test := range tests { @@ -220,31 +154,15 @@ func TestWithGzipCompressionLevel(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithGzipCompressionLevel(test.args.level) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithGzipCompressionLevel(test.args.level) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithGzipCompressionLevel(test.args.level) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } From aca45eaafa606138a2811a4dacf989f4fe392654 Mon Sep 17 00:00:00 2001 From: Kevin Diu Date: Thu, 13 Aug 2020 19:04:20 +0900 Subject: [PATCH 07/10] Add internal/net test (#615) * refactor and add net test * fix * revert changes * add comments * fix type * fix * fix deepsource * add comment * fix CI --- internal/errors/net.go | 5 + internal/net/net.go | 72 +++- internal/net/net_test.go | 697 ++++++++++++++++++++++++++------------- 3 files changed, 537 insertions(+), 237 deletions(-) diff --git a/internal/errors/net.go b/internal/errors/net.go index 786ac1a0919..433b10b2c4b 100644 --- a/internal/errors/net.go +++ b/internal/errors/net.go @@ -28,4 +28,9 @@ var ( ErrInvalidDNSConfig = func(dnsRefreshDur, dnsCacheExp time.Duration) error { return Errorf("dnsRefreshDuration > dnsCacheExp, %s, %s", dnsRefreshDur, dnsCacheExp) } + + // net + + // ErrNoPortAvailiable defines no port available error + ErrNoPortAvailable = New("no port available") ) diff --git a/internal/net/net.go b/internal/net/net.go index 01c4278b29b..d02ef63f38b 100644 --- a/internal/net/net.go +++ b/internal/net/net.go @@ -27,6 +27,8 @@ import ( "syscall" "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/log" ) const ( @@ -36,30 +38,48 @@ const ( defaultPort = 80 ) -type Conn = net.Conn -type Dialer = net.Dialer -type ListenConfig = net.ListenConfig -type Listener = net.Listener -type Resolver = net.Resolver +type ( + // Conn is an alias of net.Conn + Conn = net.Conn + + // Dialer is an alias of net.Dialer + Dialer = net.Dialer + + // ListenConfig is an alias of net.ListenConfig + ListenConfig = net.ListenConfig + + // Listener is an alias of net.Listener + Listener = net.Listener + + // Resolver is an alias of net.Resolver + Resolver = net.Resolver +) var ( + // DefaultResolver is an alias of net.DefaultResolver DefaultResolver = net.DefaultResolver ) +// Listen is a wrapper function of the net.Listen function. func Listen(network, address string) (Listener, error) { return net.Listen(network, address) } +// IsLocal returns if the host is the localhost address. func IsLocal(host string) bool { return host == localHost || host == localIPv4 || host == localIPv6 } -func Dial(network string, addr string) (conn Conn, err error) { +// Dial is a wrapper function of the net.Dial function. +func Dial(network, addr string) (conn Conn, err error) { return net.Dial(network, addr) } +// Parse parses the hostname, IPv4 or IPv6 address and return the hostname/IP, port number, +// whether the address is IP, and any parsing error occurred. +// The address should contains the port number, otherwise an error will return. func Parse(addr string) (host string, port uint16, isIP bool, err error) { host, port, err = SplitHostPort(addr) isIP = IsIPv6(host) || IsIPv4(host) @@ -69,18 +89,27 @@ func Parse(addr string) (host string, port uint16, isIP bool, err error) { return host, port, isIP, err } +// IsIPv6 returns weather the address is IPv6 address. func IsIPv6(addr string) bool { return net.ParseIP(addr) != nil && strings.Count(addr, ":") >= 2 } +// IsIPv4 returns weather the address is IPv4 address. func IsIPv4(addr string) bool { return net.ParseIP(addr) != nil && strings.Count(addr, ":") < 2 } +// SplitHostPort splits the address, and return the host/IP address and the port number, +// and any error occurred. +// If it is the loopback address, it will return the loopback address and corresponding port number. +// IPv6 loopback address is not supported yet. +// For more information, please read https://github.com/vdaas/vald/projects/3#card-43504189 func SplitHostPort(hostport string) (host string, port uint16, err error) { switch { + /* TODO: IPv6 loopback address support case strings.HasPrefix(hostport, "::"): hostport = localIPv6 + hostport + */ case strings.HasPrefix(hostport, ":"): hostport = localIPv4 + hostport } @@ -98,16 +127,23 @@ func SplitHostPort(hostport string) (host string, port uint16, err error) { return host, port, err } +// ScanPorts scans the given range of port numbers from the host (inclusively), +// and return the list of ports that can be connected through TCP, or any error occurred. func ScanPorts(ctx context.Context, start, end uint16, host string) (ports []uint16, err error) { + if start > end { + start, end = end, start + } + var rl syscall.Rlimit - err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rl) - if err != nil { + if err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rl); err != nil { return nil, err } eg, egctx := errgroup.New(ctx) eg.Limitation(int(rl.Max) / 2) + var mu sync.Mutex - for i := start; i <= end; i++ { + + for i := start; i >= start && i <= end; i++ { port := i eg.Go(func() error { select { @@ -116,19 +152,29 @@ func ScanPorts(ctx context.Context, start, end uint16, host string) (ports []uin default: conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", host, port)) if err != nil { - return err + log.Warn(err) + return nil } + mu.Lock() ports = append(ports, port) mu.Unlock() - return conn.Close() + + if err = conn.Close(); err != nil { + log.Warn(err) + } + return nil } }) } - err = eg.Wait() - if err != nil { + + if err = eg.Wait(); err != nil { return nil, err } + if len(ports) == 0 { + return nil, errors.ErrNoPortAvailable + } + return ports, nil } diff --git a/internal/net/net_test.go b/internal/net/net_test.go index a6219ca5611..d2822a6031e 100644 --- a/internal/net/net_test.go +++ b/internal/net/net_test.go @@ -19,13 +19,35 @@ package net import ( "context" + "fmt" + "io/ioutil" + "math" + "net/http" + "net/http/httptest" + "os" "reflect" + "strconv" + "strings" "testing" "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/log" "go.uber.org/goleak" ) +var ( + // Goroutine leak is detected by `fastime`, but it should be ignored in the test because it is an external package. + goleakIgnoreOptions = []goleak.Option{ + goleak.IgnoreTopFunction("github.com/kpango/fastime.(*Fastime).StartTimerD.func1"), + goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), + } +) + +func TestMain(m *testing.M) { + log.Init() + os.Exit(m.Run()) +} + func TestListen(t *testing.T) { type args struct { network string @@ -53,38 +75,25 @@ func TestListen(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - network: "", - address: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - network: "", - address: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "listener is created successfully", + args: args{ + network: "tcp", + address: ":0", + }, + checkFunc: func(w want, got Listener, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + + return got.Close() + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -126,36 +135,56 @@ func TestIsLocal(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - host: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - host: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "return true if it is host is `localhost`", + args: args{ + host: "localhost", + }, + want: want{ + want: true, + }, + }, + { + name: "return true if it is host is local IPv4 address", + args: args{ + host: "127.0.0.1", + }, + want: want{ + want: true, + }, + }, + { + name: "return true if it is host is local IPv6 address", + args: args{ + host: "::1", + }, + want: want{ + want: true, + }, + }, + { + name: "return false if the host is not an address", + args: args{ + host: "dummy", + }, + want: want{ + want: false, + }, + }, + { + name: "return false if the host is empty", + args: args{ + host: "", + }, + want: want{ + want: false, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -202,38 +231,46 @@ func TestDial(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - network: "", - addr: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - network: "", - addr: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + func() test { + srvContent := "test" + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, srvContent) + w.WriteHeader(200) + }) + testSrv := httptest.NewServer(handler) + + return test{ + name: "dial return server content", + args: args{ + network: "tcp", + addr: testSrv.URL[len("http://"):], + }, + checkFunc: func(w want, gotConn Conn, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + + // read the output from the server and check if it is equals to the count + fmt.Fprintf(gotConn, "GET / HTTP/1.0\r\n\r\n") + buf, _ := ioutil.ReadAll(gotConn) + content := strings.Split(string(buf), "\n")[5] // skip HTTP header + if content != srvContent { + return errors.Errorf("invalid content, got: %v, want: %v", content, srvContent) + } + + return nil + }, + afterFunc: func(args) { + testSrv.CloseClientConnections() + testSrv.Close() + }, + } + }(), } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -272,7 +309,7 @@ func TestParse(t *testing.T) { afterFunc func(args) } defaultCheckFunc := func(w want, gotHost string, gotPort uint16, gotIsIP bool, err error) error { - if !errors.Is(err, w.err) { + if (w.err == nil && err != nil) || (w.err != nil && err == nil) || (err != nil && err.Error() != w.err.Error()) { return errors.Errorf("got error = %v, want %v", err, w.err) } if !reflect.DeepEqual(gotHost, w.wantHost) { @@ -287,36 +324,91 @@ func TestParse(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - addr: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - addr: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "parse success with IPv4 address", + args: args{ + addr: "192.168.1.1:8080", + }, + want: want{ + wantHost: "192.168.1.1", + wantPort: uint16(8080), + wantIsIP: true, + }, + }, + { + name: "parse success with IPv6 address", + args: args{ + addr: "[2001:db8::1]:8080", + }, + want: want{ + wantHost: "2001:db8::1", + wantPort: uint16(8080), + wantIsIP: true, + }, + }, + { + name: "parse success with hostname", + args: args{ + addr: "google.com:8080", + }, + want: want{ + wantHost: "google.com", + wantPort: uint16(8080), + wantIsIP: false, + }, + }, + { + name: "return default port when parse failed if it is not an address", + args: args{ + addr: "dummy", + }, + want: want{ + wantHost: "dummy", + wantPort: uint16(80), + err: &strconv.NumError{ + Func: "Atoi", + Num: "", + Err: strconv.ErrSyntax, + }, + }, + }, + { + name: "return default port when parse failed if port number missing in IPv4 address", + args: args{ + addr: "192.168.1.1", + }, + want: want{ + wantHost: "192.168.1.1", + wantPort: uint16(80), + wantIsIP: true, + err: &strconv.NumError{ + Func: "Atoi", + Num: "", + Err: strconv.ErrSyntax, + }, + }, + }, + { + name: "return default port when parse failed if port number missing in IPv6 address", + args: args{ + addr: "2001:db8::1", + }, + want: want{ + wantHost: "2001:db8::1", + wantPort: uint16(80), + wantIsIP: true, + err: &strconv.NumError{ + Func: "Atoi", + Num: "", + Err: strconv.ErrSyntax, + }, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -358,36 +450,29 @@ func TestIsIPv6(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - addr: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - addr: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "return true if it is IPv6 address", + args: args{ + addr: "2001:db8::1", + }, + want: want{ + want: true, + }, + }, + { + name: "return false if it is not IPv6 address", + args: args{ + addr: "localhost", + }, + want: want{ + want: false, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -429,36 +514,29 @@ func TestIsIPv4(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - addr: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - addr: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "return true if it is IPv4 address", + args: args{ + addr: "192.168.1.1", + }, + want: want{ + want: true, + }, + }, + { + name: "return false if it is not IPv4 address", + args: args{ + addr: "localhost", + }, + want: want{ + want: false, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -496,7 +574,7 @@ func TestSplitHostPort(t *testing.T) { afterFunc func(args) } defaultCheckFunc := func(w want, gotHost string, gotPort uint16, err error) error { - if !errors.Is(err, w.err) { + if (w.err == nil && err != nil) || (w.err != nil && err == nil) || (err != nil && err.Error() != w.err.Error()) { return errors.Errorf("got error = %v, want %v", err, w.err) } if !reflect.DeepEqual(gotHost, w.wantHost) { @@ -508,36 +586,84 @@ func TestSplitHostPort(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - hostport: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - hostport: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "parse success with IPv4 address", + args: args{ + hostport: "192.168.1.1:8080", + }, + want: want{ + wantHost: "192.168.1.1", + wantPort: uint16(8080), + }, + }, + { + name: "parse success with IPv6 address", + args: args{ + hostport: "[2001:db8::1]:8080", + }, + want: want{ + wantHost: "2001:db8::1", + wantPort: uint16(8080), + }, + }, + { + name: "parse success with hostname", + args: args{ + hostport: "google.com:8080", + }, + want: want{ + wantHost: "google.com", + wantPort: uint16(8080), + }, + }, + { + name: "return default port when parse failed if it is not an address", + args: args{ + hostport: "dummy", + }, + want: want{ + wantHost: "dummy", + wantPort: uint16(80), + err: &strconv.NumError{"Atoi", "", strconv.ErrSyntax}, + }, + }, + { + name: "return default port when parse failed if port number missing in IPv4 address", + args: args{ + hostport: "192.168.1.1", + }, + want: want{ + wantHost: "192.168.1.1", + wantPort: uint16(80), + err: &strconv.NumError{"Atoi", "", strconv.ErrSyntax}, + }, + }, + { + name: "return default port when parse failed if port number missing in IPv6 address", + args: args{ + hostport: "2001:db8::1", + }, + want: want{ + wantHost: "2001:db8::1", + wantPort: uint16(80), + err: &strconv.NumError{"Atoi", "", strconv.ErrSyntax}, + }, + }, + { + name: "parse success with default IPv4 address", + args: args{ + hostport: ":8080", + }, + want: want{ + wantHost: "127.0.0.1", + wantPort: uint16(8080), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -580,54 +706,174 @@ func TestScanPorts(t *testing.T) { if !errors.Is(err, w.err) { return errors.Errorf("got error = %v, want %v", err, w.err) } - if !reflect.DeepEqual(gotPorts, w.wantPorts) { + + // count how want want ports exists in got ports + cnt := 0 + for _, wp := range w.wantPorts { + for _, gp := range gotPorts { + if wp == gp { + cnt++ + break + } + } + } + + if cnt != len(w.wantPorts) { return errors.Errorf("got = %v, want %v", gotPorts, w.wantPorts) } return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - ctx: nil, - start: 0, - end: 0, - host: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - ctx: nil, - start: 0, - end: 0, - host: "", - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + func() test { + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + }) + testSrv := httptest.NewServer(handler) + + s := strings.Split(testSrv.URL, ":") + p, _ := strconv.Atoi(s[len(s)-1]) + srvPort := uint16(p) + + return test{ + name: "return test server port number in given range", + args: args{ + ctx: context.Background(), + host: "localhost", + start: srvPort - 5, + end: srvPort + 5, + }, + want: want{ + wantPorts: []uint16{ + srvPort, + }, + }, + afterFunc: func(args) { + testSrv.Close() + }, + } + }(), + func() test { + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + }) + testSrv := httptest.NewServer(handler) + + s := strings.Split(testSrv.URL, ":") + p, _ := strconv.Atoi(s[len(s)-1]) + srvPort := uint16(p) + + return test{ + name: "return test server port number when start = end", + args: args{ + ctx: context.Background(), + host: "localhost", + start: srvPort, + end: srvPort, + }, + want: want{ + wantPorts: []uint16{ + srvPort, + }, + }, + afterFunc: func(args) { + testSrv.Close() + }, + } + }(), + func() test { + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + }) + testSrv := httptest.NewServer(handler) + + s := strings.Split(testSrv.URL, ":") + p, _ := strconv.Atoi(s[len(s)-1]) + srvPort := uint16(p) + + return test{ + name: "return test server port number when start > end", + args: args{ + ctx: context.Background(), + host: "localhost", + start: srvPort + 10, + end: srvPort - 10, + }, + want: want{ + wantPorts: []uint16{ + srvPort, + }, + }, + afterFunc: func(args) { + testSrv.Close() + }, + } + }(), + func() test { + srvNum := 20 + + srvs := make([]*httptest.Server, 0, srvNum) + ports := make([]uint16, 0, srvNum) + minPort := uint16(math.MaxUint16) + maxPort := uint16(0) + + for i := 0; i < srvNum; i++ { + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + }) + srv := httptest.NewServer(handler) + srvs = append(srvs, srv) + + s := strings.Split(srv.URL, ":") + p, _ := strconv.Atoi(s[len(s)-1]) + port := uint16(p) + ports = append(ports, port) + + if port < minPort { + minPort = port + } + if port > maxPort { + maxPort = port + } + } + + return test{ + name: "return multiple test server port number", + args: args{ + ctx: context.Background(), + host: "localhost", + start: minPort - 5, + end: maxPort + 5, + }, + want: want{ + wantPorts: ports, + }, + afterFunc: func(args) { + for _, s := range srvs { + s.Close() + } + }, + } + }(), + { + name: "return no port available if no port is scanned", + args: args{ + ctx: context.Background(), + host: "localhost", + start: 65534, + end: 65535, + }, + want: want{ + err: errors.ErrNoPortAvailable, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } - if test.afterFunc != nil { - defer test.afterFunc(test.args) - } if test.checkFunc == nil { test.checkFunc = defaultCheckFunc } @@ -637,6 +883,9 @@ func TestScanPorts(t *testing.T) { tt.Errorf("error = %v", err) } + if test.afterFunc != nil { + test.afterFunc(test.args) + } }) } } From 00645e132f47a1cad71bd8e1e486883bfe0c3182 Mon Sep 17 00:00:00 2001 From: Kiichiro YUKAWA Date: Fri, 14 Aug 2020 11:20:22 +0900 Subject: [PATCH 08/10] :white_check_mark: add internal/db/rdb/mysql/option test (#626) * :white_check_mark: add internal/db/rdb/mysql/option test Signed-off-by: vankichi * Update internal/db/rdb/mysql/option_test.go Co-authored-by: Kevin Diu * Update internal/db/rdb/mysql/option_test.go Co-authored-by: Kevin Diu * Update internal/db/rdb/mysql/option_test.go Co-authored-by: Kevin Diu * :robot: Update license headers / Format go codes and yaml files Signed-off-by: vdaas-ci Co-authored-by: Kevin Diu Co-authored-by: vdaas-ci --- internal/db/rdb/mysql/option.go | 20 + internal/db/rdb/mysql/option_test.go | 1947 +++++++++----------------- 2 files changed, 707 insertions(+), 1260 deletions(-) diff --git a/internal/db/rdb/mysql/option.go b/internal/db/rdb/mysql/option.go index b1c03a1d2a3..bb6efb6f24c 100644 --- a/internal/db/rdb/mysql/option.go +++ b/internal/db/rdb/mysql/option.go @@ -25,6 +25,7 @@ import ( "github.com/vdaas/vald/internal/timeutil" ) +// Option represents the functional option for mySQLClient. type Option func(*mySQLClient) error var ( @@ -39,6 +40,7 @@ var ( } ) +// WithTimezone returns the option to set the timezone. func WithTimezone(tz string) Option { return func(m *mySQLClient) error { if tz != "" { @@ -48,6 +50,7 @@ func WithTimezone(tz string) Option { } } +// WithCharset returns the option to set the charset. func WithCharset(cs string) Option { return func(m *mySQLClient) error { if cs != "" { @@ -57,6 +60,7 @@ func WithCharset(cs string) Option { } } +// WithDB returns the option to set the db. func WithDB(db string) Option { return func(m *mySQLClient) error { if db != "" { @@ -66,6 +70,7 @@ func WithDB(db string) Option { } } +// WithHost returns the option to set the host. func WithHost(host string) Option { return func(m *mySQLClient) error { if host != "" { @@ -75,6 +80,7 @@ func WithHost(host string) Option { } } +// WithPort returns the option to set the port. func WithPort(port int) Option { return func(m *mySQLClient) error { m.port = port @@ -82,6 +88,7 @@ func WithPort(port int) Option { } } +// WithUser returns the option to set the user. func WithUser(user string) Option { return func(m *mySQLClient) error { if user != "" { @@ -91,6 +98,7 @@ func WithUser(user string) Option { } } +// WithPass returns the option to set the pass. func WithPass(pass string) Option { return func(m *mySQLClient) error { if pass != "" { @@ -100,6 +108,7 @@ func WithPass(pass string) Option { } } +// WithName returns the option to sst the name. func WithName(name string) Option { return func(m *mySQLClient) error { if name != "" { @@ -109,6 +118,7 @@ func WithName(name string) Option { } } +// WithInitialPingTimeLimit returns the option to set the initialPingTimeLimit. func WithInitialPingTimeLimit(lim string) Option { return func(m *mySQLClient) error { if lim == "" { @@ -123,6 +133,7 @@ func WithInitialPingTimeLimit(lim string) Option { } } +// WithInitialPingDuration returns the option to set the initialPingDuration. func WithInitialPingDuration(dur string) Option { return func(m *mySQLClient) error { if dur == "" { @@ -137,6 +148,7 @@ func WithInitialPingDuration(dur string) Option { } } +// WithConnectionLifeTimeLimit returns the option to set the connMaxLifeTime. func WithConnectionLifeTimeLimit(dur string) Option { return func(m *mySQLClient) error { if dur == "" { @@ -151,6 +163,9 @@ func WithConnectionLifeTimeLimit(dur string) Option { } } +// WithMaxIdleConns returns the option to set the maxIdleConns. +// If conns is negative numner, no idle connections are retained. +// ref: https://golang.org/src/database/sql/sql.go?s=24983:25019#L879 func WithMaxIdleConns(conns int) Option { return func(m *mySQLClient) error { if conns != 0 { @@ -160,6 +175,9 @@ func WithMaxIdleConns(conns int) Option { } } +// WithMaxOpenConns returns the option to set the maxOpenConns. +// If conns is negative numner, no limit on the number of open connections. +// ref: https://golang.org/src/database/sql/sql.go?s=24983:25019#L923 func WithMaxOpenConns(conns int) Option { return func(m *mySQLClient) error { if conns != 0 { @@ -169,6 +187,7 @@ func WithMaxOpenConns(conns int) Option { } } +// WithTLSConfig returns the option to set the tlsConfig. func WithTLSConfig(cfg *tls.Config) Option { return func(m *mySQLClient) error { if cfg != nil { @@ -178,6 +197,7 @@ func WithTLSConfig(cfg *tls.Config) Option { } } +// WithDialer returns the option to set the dialer. func WithDialer(der func(ctx context.Context, addr, port string) (net.Conn, error)) Option { return func(m *mySQLClient) error { if der != nil { diff --git a/internal/db/rdb/mysql/option_test.go b/internal/db/rdb/mysql/option_test.go index 111b5680eb3..303a7bccd1f 100644 --- a/internal/db/rdb/mysql/option_test.go +++ b/internal/db/rdb/mysql/option_test.go @@ -19,203 +19,144 @@ package mysql import ( "context" "crypto/tls" + "reflect" "testing" + "time" + "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/net" "go.uber.org/goleak" ) +var ( + // Goroutine leak is detected by `fastime`, but it should be ignored in the test because it is an external package. + goleakIgnoreOptions = []goleak.Option{ + goleak.IgnoreTopFunction("github.com/kpango/fastime.(*Fastime).StartTimerD.func1"), + } +) + func TestWithTimezone(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { tz string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - tz: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - tz: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when tz is not nil", + args: args{ + tz: "Asia/Tokyo", + }, + want: want{ + obj: &T{ + timezone: "Asia/Tokyo", + }, + }, + }, + { + name: "set success when tz is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } if test.afterFunc != nil { defer test.afterFunc(test.args) } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithTimezone(test.args.tz) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithTimezone(test.args.tz) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + got := WithTimezone(test.args.tz) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithCharset(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { cs string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - cs: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - cs: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when cs is not nil", + args: args{ + cs: "utf-8", + }, + want: want{ + obj: &T{ + charset: "utf-8", + }, + }, + }, + { + name: "set success when cs is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -223,112 +164,70 @@ func TestWithCharset(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithCharset(test.args.cs) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithCharset(test.args.cs) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithCharset(test.args.cs) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithDB(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { db string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - db: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - db: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when db is not nil", + args: args{ + db: "mysql", + }, + want: want{ + obj: &T{ + db: "mysql", + }, + }, + }, + { + name: "set success when db is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -336,112 +235,70 @@ func TestWithDB(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithDB(test.args.db) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithDB(test.args.db) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithDB(test.args.db) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithHost(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { host string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - host: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - host: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when host is not nil", + args: args{ + host: "vald.mysql.db.com", + }, + want: want{ + obj: &T{ + host: "vald.mysql.db.com", + }, + }, + }, + { + name: "set success when host is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -449,112 +306,70 @@ func TestWithHost(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithHost(test.args.host) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithHost(test.args.host) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithHost(test.args.host) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithPort(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { port int } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - port: 0, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - port: 0, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when port is not nil", + args: args{ + port: 3306, + }, + want: want{ + obj: &T{ + port: 3306, + }, + }, + }, + { + name: "set success when port is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -562,112 +377,73 @@ func TestWithPort(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithPort(test.args.port) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithPort(test.args.port) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithPort(test.args.port) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithUser(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { user string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - user: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - user: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when user is not nil", + args: args{ + user: "vdaas", + }, + want: want{ + obj: &T{ + user: "vdaas", + }, + }, + }, + { + name: "set success when user is nil", + args: args{ + user: "", + }, + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -675,112 +451,70 @@ func TestWithUser(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithUser(test.args.user) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithUser(test.args.user) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithUser(test.args.user) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithPass(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { pass string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - pass: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - pass: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when pass is not nil", + args: args{ + pass: "valddb", + }, + want: want{ + obj: &T{ + pass: "valddb", + }, + }, + }, + { + name: "set success when pass is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -788,112 +522,70 @@ func TestWithPass(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithPass(test.args.pass) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithPass(test.args.pass) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithPass(test.args.pass) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithName(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { name string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - name: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - name: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when name is not nil", + args: args{ + name: "valdmysql", + }, + want: want{ + obj: &T{ + name: "valdmysql", + }, + }, + }, + { + name: "set success when name is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -901,112 +593,81 @@ func TestWithName(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithName(test.args.name) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithName(test.args.name) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithName(test.args.name) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithInitialPingTimeLimit(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { lim string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - lim: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - lim: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when lim is valid", + args: args{ + lim: "10s", + }, + want: want{ + obj: &T{ + initialPingTimeLimit: 10 * time.Second, + }, + }, + }, + { + name: "set success with default value when lim is invalid", + args: args{ + lim: "invalid", + }, + want: want{ + obj: &T{ + initialPingTimeLimit: 30 * time.Second, + }, + }, + }, + { + name: "set success when lim is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1014,112 +675,81 @@ func TestWithInitialPingTimeLimit(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithInitialPingTimeLimit(test.args.lim) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithInitialPingTimeLimit(test.args.lim) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithInitialPingTimeLimit(test.args.lim) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithInitialPingDuration(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { dur string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - dur: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - dur: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when dur is valid", + args: args{ + dur: "100ms", + }, + want: want{ + obj: &T{ + initialPingDuration: 100 * time.Millisecond, + }, + }, + }, + { + name: "set success with default value when dur is invalid", + args: args{ + dur: "invalid", + }, + want: want{ + obj: &T{ + initialPingDuration: 50 * time.Millisecond, + }, + }, + }, + { + name: "set success when dur is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1127,112 +757,81 @@ func TestWithInitialPingDuration(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithInitialPingDuration(test.args.dur) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithInitialPingDuration(test.args.dur) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithInitialPingDuration(test.args.dur) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithConnectionLifeTimeLimit(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { dur string } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - dur: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - dur: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when dur is valid", + args: args{ + dur: "60s", + }, + want: want{ + obj: &T{ + connMaxLifeTime: 60 * time.Second, + }, + }, + }, + { + name: "set success with default value when dur is invalid", + args: args{ + dur: "invalid", + }, + want: want{ + obj: &T{ + connMaxLifeTime: 30 * time.Second, + }, + }, + }, + { + name: "set success when dur is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1240,112 +839,70 @@ func TestWithConnectionLifeTimeLimit(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithConnectionLifeTimeLimit(test.args.dur) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithConnectionLifeTimeLimit(test.args.dur) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithConnectionLifeTimeLimit(test.args.dur) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithMaxIdleConns(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { conns int } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - conns: 0, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - conns: 0, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when conns is not 0", + args: args{ + conns: 5, + }, + want: want{ + obj: &T{ + maxIdleConns: 5, + }, + }, + }, + { + name: "set success when conns is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1353,112 +910,70 @@ func TestWithMaxIdleConns(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithMaxIdleConns(test.args.conns) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithMaxIdleConns(test.args.conns) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithMaxIdleConns(test.args.conns) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithMaxOpenConns(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { conns int } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - conns: 0, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - conns: 0, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + { + name: "set success when conns is not 0", + args: args{ + conns: 100, + }, + want: want{ + obj: &T{ + maxOpenConns: 100, + }, + }, + }, + { + name: "set success when conns is nil", + want: want{ + obj: new(T), + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1466,112 +981,75 @@ func TestWithMaxOpenConns(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithMaxOpenConns(test.args.conns) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithMaxOpenConns(test.args.conns) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithMaxOpenConns(test.args.conns) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithTLSConfig(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { cfg *tls.Config } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - cfg: nil, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - cfg: nil, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + func() test { + cfg := new(tls.Config) + return test{ + name: "set success when cfg is not nil", + args: args{ + cfg: cfg, + }, + want: want{ + obj: &T{ + tlsConfig: cfg, + }, + }, + } + }(), + func() test { + return test{ + name: "set success when cfg is nil", + want: want{ + obj: new(T), + }, + } + }(), } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1579,112 +1057,77 @@ func TestWithTLSConfig(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithTLSConfig(test.args.cfg) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithTLSConfig(test.args.cfg) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithTLSConfig(test.args.cfg) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } func TestWithDialer(t *testing.T) { - type T = interface{} + type T = mySQLClient type args struct { der func(ctx context.Context, addr, port string) (net.Conn, error) } type want struct { obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error + err error } type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error + name string + args args + want want + checkFunc func(want, *T, error) error beforeFunc func(args) afterFunc func(args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if reflect.ValueOf(w.obj.dialer).Pointer() != reflect.ValueOf(obj.dialer).Pointer() { + return errors.Errorf("got dialer = %p, want %p", obj.dialer, w.obj.dialer) + } + return nil + } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - der: nil, - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - der: nil, - }, - want: want { - obj: new(T), - }, - } - }(), - */ + func() test { + der := func(ctx context.Context, addr, port string) (net.Conn, error) { + return nil, nil + } + return test{ + name: "set success when der is not nil", + args: args{ + der: der, + }, + want: want{ + obj: &T{ + dialer: der, + }, + }, + } + }(), + func() test { + return test{ + name: "set success when der is nil", + want: want{ + obj: new(T), + }, + } + }(), } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -1692,31 +1135,15 @@ func TestWithDialer(t *testing.T) { defer test.afterFunc(test.args) } - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithDialer(test.args.der) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithDialer(test.args.der) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithDialer(test.args.der) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } }) } } From 95fb5c5ddc157c5c4c041f25f857a655ead8fa38 Mon Sep 17 00:00:00 2001 From: Rintaro Okamura Date: Tue, 18 Aug 2020 12:11:12 +0900 Subject: [PATCH 09/10] :wrench: upload sarif only for HIGH or CRITICAL (#629) Signed-off-by: Rintaro Okamura --- .github/workflows/dockers-image-scan.yml | 36 ++++++++---------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/.github/workflows/dockers-image-scan.yml b/.github/workflows/dockers-image-scan.yml index 3968e7bd6f3..fdf702209eb 100644 --- a/.github/workflows/dockers-image-scan.yml +++ b/.github/workflows/dockers-image-scan.yml @@ -22,8 +22,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -31,6 +29,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -53,8 +52,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -62,6 +59,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -84,8 +82,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -93,6 +89,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -115,8 +112,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -124,6 +119,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -146,8 +142,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -155,6 +149,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -177,8 +172,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -186,6 +179,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -208,8 +202,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -217,6 +209,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -239,8 +232,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -248,6 +239,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -270,8 +262,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -279,6 +269,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -301,8 +292,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -310,6 +299,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -332,8 +322,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -341,6 +329,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: @@ -363,8 +352,6 @@ jobs: with: image-ref: "${{ steps.build_image.outputs.IMAGE_NAME }}:${{ github.sha }}" format: 'table' - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - name: Run vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -372,6 +359,7 @@ jobs: format: 'template' template: '@/contrib/sarif.tpl' output: 'trivy-results.sarif' + severity: 'HIGH,CRITICAL' - name: Upload Trivy scan results to Security tab uses: github/codeql-action/upload-sarif@v1 with: From cd8be5b3de55000d15b502660e5fe3ddf1cc4e37 Mon Sep 17 00:00:00 2001 From: Kiichiro YUKAWA Date: Tue, 18 Aug 2020 22:05:59 +0900 Subject: [PATCH 10/10] :white_check_mark: add internal/db/rdb/mysql/model test (#628) * :white_check_mark: add internal/db/rdb/mysql/model test Signed-off-by: vankichi * :white_check_mark: fix Signed-off-by: vankichi * Update internal/db/rdb/mysql/model_test.go Co-authored-by: Hiroto Funakoshi * Update internal/db/rdb/mysql/model_test.go Co-authored-by: Hiroto Funakoshi * Update internal/db/rdb/mysql/model_test.go Co-authored-by: Hiroto Funakoshi * Update internal/db/rdb/mysql/model_test.go Co-authored-by: Hiroto Funakoshi * Update internal/db/rdb/mysql/model_test.go Co-authored-by: Hiroto Funakoshi * Update internal/db/rdb/mysql/model_test.go Co-authored-by: Hiroto Funakoshi * Update internal/db/rdb/mysql/model_test.go Co-authored-by: Hiroto Funakoshi * Update internal/db/rdb/mysql/model_test.go Co-authored-by: Hiroto Funakoshi * :robot: Update license headers / Format go codes and yaml files Signed-off-by: vdaas-ci Co-authored-by: Hiroto Funakoshi Co-authored-by: vdaas-ci --- internal/db/rdb/mysql/model.go | 12 +- internal/db/rdb/mysql/model_test.go | 228 +++++++++++++--------------- 2 files changed, 116 insertions(+), 124 deletions(-) diff --git a/internal/db/rdb/mysql/model.go b/internal/db/rdb/mysql/model.go index 6a2a1b9a8e3..7e75065c32f 100644 --- a/internal/db/rdb/mysql/model.go +++ b/internal/db/rdb/mysql/model.go @@ -20,6 +20,7 @@ import ( dbr "github.com/gocraft/dbr/v2" ) +// MetaVector is an interface to handle metadata keep in MySQL. type MetaVector interface { GetUUID() string GetVector() []byte @@ -44,9 +45,16 @@ type podIP struct { IP string `db:"ip"` } -func (m *metaVector) GetUUID() string { return m.meta.UUID } +// GetUUID returns UUID of metaVector. +func (m *metaVector) GetUUID() string { return m.meta.UUID } + +// GetVector returns Vector of metaVector. func (m *metaVector) GetVector() []byte { return m.meta.Vector } -func (m *metaVector) GetMeta() string { return m.meta.Meta.String } + +// GetMeta returns meta.String of metaVector. +func (m *metaVector) GetMeta() string { return m.meta.Meta.String } + +// GetIPs returns all podIPs which are Vald Agent Pods' IP indexed meta's vector. func (m *metaVector) GetIPs() []string { ips := make([]string, 0, len(m.podIPs)) diff --git a/internal/db/rdb/mysql/model_test.go b/internal/db/rdb/mysql/model_test.go index 68476d362b6..39f05ed1863 100644 --- a/internal/db/rdb/mysql/model_test.go +++ b/internal/db/rdb/mysql/model_test.go @@ -17,16 +17,18 @@ package mysql import ( + "database/sql" "reflect" "testing" + dbr "github.com/gocraft/dbr/v2" "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" ) func Test_metaVector_GetUUID(t *testing.T) { type fields struct { - meta meta - podIPs []podIP + meta meta } type want struct { want string @@ -46,37 +48,33 @@ func Test_metaVector_GetUUID(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - fields: fields { - meta: meta{}, - podIPs: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - fields: fields { - meta: meta{}, - podIPs: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "returns UUID when UUID of meta is not empty", + fields: fields{ + meta: meta{ + UUID: "vald-vector-01", + }, + }, + want: want{ + want: "vald-vector-01", + }, + }, + { + name: "returns UUID when UUID of meta is empty string", + fields: fields{ + meta: meta{ + UUID: "", + }, + }, + want: want{ + want: "", + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc() } @@ -87,8 +85,7 @@ func Test_metaVector_GetUUID(t *testing.T) { test.checkFunc = defaultCheckFunc } m := &metaVector{ - meta: test.fields.meta, - podIPs: test.fields.podIPs, + meta: test.fields.meta, } got := m.GetUUID() @@ -102,8 +99,7 @@ func Test_metaVector_GetUUID(t *testing.T) { func Test_metaVector_GetVector(t *testing.T) { type fields struct { - meta meta - podIPs []podIP + meta meta } type want struct { want []byte @@ -123,37 +119,33 @@ func Test_metaVector_GetVector(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - fields: fields { - meta: meta{}, - podIPs: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - fields: fields { - meta: meta{}, - podIPs: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + func() test { + v := []byte("vdaas/vald") + return test{ + name: "returns Vector when Vector of meta is not empty", + fields: fields{ + meta: meta{ + Vector: v, + }, + }, + want: want{ + want: v, + }, + } + }(), + func() test { + return test{ + name: "returns Vector when Vector of meta is empty", + want: want{ + want: nil, + }, + } + }(), } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc() } @@ -164,8 +156,7 @@ func Test_metaVector_GetVector(t *testing.T) { test.checkFunc = defaultCheckFunc } m := &metaVector{ - meta: test.fields.meta, - podIPs: test.fields.podIPs, + meta: test.fields.meta, } got := m.GetVector() @@ -179,8 +170,7 @@ func Test_metaVector_GetVector(t *testing.T) { func Test_metaVector_GetMeta(t *testing.T) { type fields struct { - meta meta - podIPs []podIP + meta meta } type want struct { want string @@ -200,37 +190,33 @@ func Test_metaVector_GetMeta(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - fields: fields { - meta: meta{}, - podIPs: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - fields: fields { - meta: meta{}, - podIPs: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "returns MetaString when MetaString is not empty", + fields: fields{ + meta: meta{ + Meta: dbr.NullString{ + sql.NullString{ + String: "vdaas/vald", + Valid: false, + }, + }, + }, + }, + want: want{ + want: "vdaas/vald", + }, + }, + { + name: "returns MetaString when MetaString is empty", + want: want{ + want: "", + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc() } @@ -241,8 +227,7 @@ func Test_metaVector_GetMeta(t *testing.T) { test.checkFunc = defaultCheckFunc } m := &metaVector{ - meta: test.fields.meta, - podIPs: test.fields.podIPs, + meta: test.fields.meta, } got := m.GetMeta() @@ -256,7 +241,6 @@ func Test_metaVector_GetMeta(t *testing.T) { func Test_metaVector_GetIPs(t *testing.T) { type fields struct { - meta meta podIPs []podIP } type want struct { @@ -277,37 +261,38 @@ func Test_metaVector_GetIPs(t *testing.T) { return nil } tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - fields: fields { - meta: meta{}, - podIPs: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - fields: fields { - meta: meta{}, - podIPs: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + { + name: "returns ips when podIP is not nil", + fields: fields{ + podIPs: []podIP{ + { + ID: 1, + IP: "192.168.1.1", + }, + { + ID: 2, + IP: "192.168.1.2", + }, + }, + }, + want: want{ + want: []string{ + "192.168.1.1", + "192.168.1.2", + }, + }, + }, + { + name: "returns empty array when podIP is nil", + want: want{ + want: []string{}, + }, + }, } for _, test := range tests { t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt, goleakIgnoreOptions...) if test.beforeFunc != nil { test.beforeFunc() } @@ -318,7 +303,6 @@ func Test_metaVector_GetIPs(t *testing.T) { test.checkFunc = defaultCheckFunc } m := &metaVector{ - meta: test.fields.meta, podIPs: test.fields.podIPs, }