diff --git a/cmd/imports/daemon.go b/cmd/imports/daemon.go index 31ac9226..ea62ccb3 100644 --- a/cmd/imports/daemon.go +++ b/cmd/imports/daemon.go @@ -21,4 +21,6 @@ import ( _ "github.com/go-sigma/sigma/pkg/daemon/gc" _ "github.com/go-sigma/sigma/pkg/daemon/sbom" _ "github.com/go-sigma/sigma/pkg/daemon/vulnerability" + _ "github.com/go-sigma/sigma/pkg/workq/database" + _ "github.com/go-sigma/sigma/pkg/workq/kafka" ) diff --git a/cmd/server.go b/cmd/server.go index 6c5ad9f9..f74b0d0a 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -30,7 +30,7 @@ import ( // serverCmd represents the server command var serverCmd = &cobra.Command{ Use: "server", - Short: "Start the XImager server", + Short: "Start the sigma server", PersistentPreRun: func(_ *cobra.Command, _ []string) { initConfig() logger.SetLevel(viper.GetString("log.level")) diff --git a/cmd/version.go b/cmd/version.go index bd448ba4..980a5a0a 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -22,30 +22,32 @@ import ( "github.com/spf13/cobra" ) +// You can copy & paste this ascii graphic and use it e.g. as mail signature +// Font: doh Reflection: no Adjustment: left Stretch: no Width: 280 Text: sigma const banner = ` -XXXXXXX XXXXXXIIIIIIIIII -X:::::X X:::::I::::::::I -X:::::X X:::::I::::::::I -X::::::X X::::::II::::::II -XXX:::::X X:::::XXX I::::I mmmmmmm mmmmmmm aaaaaaaaaaaaa ggggggggg ggggg eeeeeeeeeeee rrrrr rrrrrrrrr - X:::::X X:::::X I::::I mm:::::::m m:::::::mm a::::::::::::a g:::::::::ggg::::g ee::::::::::::ee r::::rrr:::::::::r - X:::::X:::::X I::::I m::::::::::mm::::::::::m aaaaaaaaa:::::ag:::::::::::::::::ge::::::eeeee:::::er:::::::::::::::::r - X:::::::::X I::::I m::::::::::::::::::::::m a::::g::::::ggggg::::::ge::::::e e:::::rr::::::rrrrr::::::r - X:::::::::X I::::I m:::::mmm::::::mmm:::::m aaaaaaa:::::g:::::g g:::::ge:::::::eeeee::::::er:::::r r:::::r - X:::::X:::::X I::::I m::::m m::::m m::::m aa::::::::::::g:::::g g:::::ge:::::::::::::::::e r:::::r rrrrrrr - X:::::X X:::::X I::::I m::::m m::::m m::::ma::::aaaa::::::g:::::g g:::::ge::::::eeeeeeeeeee r:::::r -XXX:::::X X:::::XXX I::::I m::::m m::::m m::::a::::a a:::::g::::::g g:::::ge:::::::e r:::::r -X::::::X X::::::II::::::Im::::m m::::m m::::a::::a a:::::g:::::::ggggg:::::ge::::::::e r:::::r -X:::::X X:::::I::::::::m::::m m::::m m::::a:::::aaaa::::::ag::::::::::::::::g e::::::::eeeeeeee r:::::r -X:::::X X:::::I::::::::m::::m m::::m m::::ma::::::::::aa:::agg::::::::::::::g ee:::::::::::::e r:::::r -XXXXXXX XXXXXXIIIIIIIIImmmmmm mmmmmm mmmmmm aaaaaaaaaa aaaa gggggggg::::::g eeeeeeeeeeeeee rrrrrrr - g:::::g - gggggg g:::::g - g:::::gg gg:::::g - g::::::ggg:::::::g - gg:::::::::::::g - ggg::::::ggg - gggggg` + iiii + i::::i + iiii + + ssssssssss iiiiiii ggggggggg ggggg mmmmmmm mmmmmmm aaaaaaaaaaaaa + ss::::::::::s i:::::i g:::::::::ggg::::g mm:::::::m m:::::::mm a::::::::::::a +ss:::::::::::::s i::::i g:::::::::::::::::gm::::::::::mm::::::::::m aaaaaaaaa:::::a +s::::::ssss:::::s i::::i g::::::ggggg::::::ggm::::::::::::::::::::::m a::::a + s:::::s ssssss i::::i g:::::g g:::::g m:::::mmm::::::mmm:::::m aaaaaaa:::::a + s::::::s i::::i g:::::g g:::::g m::::m m::::m m::::m aa::::::::::::a + s::::::s i::::i g:::::g g:::::g m::::m m::::m m::::m a::::aaaa::::::a +ssssss s:::::s i::::i g::::::g g:::::g m::::m m::::m m::::ma::::a a:::::a +s:::::ssss::::::si::::::ig:::::::ggggg:::::g m::::m m::::m m::::ma::::a a:::::a +s::::::::::::::s i::::::i g::::::::::::::::g m::::m m::::m m::::ma:::::aaaa::::::a + s:::::::::::ss i::::::i gg::::::::::::::g m::::m m::::m m::::m a::::::::::aa:::a + sssssssssss iiiiiiii gggggggg::::::g mmmmmm mmmmmm mmmmmm aaaaaaaaaa aaaa + g:::::g + gggggg g:::::g + g:::::gg gg:::::g + g::::::ggg:::::::g + gg:::::::::::::g + ggg::::::ggg + gggggg` var ( version = "" @@ -56,7 +58,7 @@ var ( // versionCmd represents the worker command var versionCmd = &cobra.Command{ Use: "version", - Short: "Show version of XImager", + Short: "Show version of sigma", Run: func(_ *cobra.Command, _ []string) { color.Cyan(banner) fmt.Printf("Version: %s\n", version) diff --git a/cmd/worker.go b/cmd/worker.go index f45b4b5d..cfc89736 100644 --- a/cmd/worker.go +++ b/cmd/worker.go @@ -29,7 +29,7 @@ import ( // workerCmd represents the worker command var workerCmd = &cobra.Command{ Use: "worker", - Short: "Start the XImager worker", + Short: "Start the sigma worker", PersistentPreRun: func(_ *cobra.Command, _ []string) { initConfig() logger.SetLevel(viper.GetString("log.level")) diff --git a/go.mod b/go.mod index 09be766d..90abe4fb 100644 --- a/go.mod +++ b/go.mod @@ -5,25 +5,26 @@ go 1.20 require ( code.gitea.io/sdk/gitea v0.16.0 github.com/BurntSushi/toml v1.3.2 + github.com/IBM/sarama v1.41.2 github.com/Masterminds/sprig/v3 v3.2.3 github.com/alicebob/miniredis/v2 v2.30.5 github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/anchore/syft v0.90.0 - github.com/aquasecurity/trivy v0.45.0 - github.com/aws/aws-sdk-go v1.45.7 + github.com/aquasecurity/trivy v0.45.1 + github.com/aws/aws-sdk-go v1.45.11 github.com/bytedance/json v0.0.0-20190516032711-0d89175f1949 github.com/caarlos0/env/v9 v9.0.0 github.com/casbin/casbin/v2 v2.77.2 github.com/casbin/gorm-adapter/v3 v3.19.0 github.com/deckarep/golang-set/v2 v2.3.1 - github.com/distribution/distribution/v3 v3.0.0-20230908093250-285b601af99a + github.com/distribution/distribution/v3 v3.0.0-20230915083636-612ad42609c3 github.com/distribution/reference v0.5.0 github.com/docker/cli v24.0.6+incompatible github.com/docker/docker v24.0.6+incompatible github.com/dustin/go-humanize v1.0.1 github.com/fatih/color v1.15.0 github.com/glebarez/sqlite v1.9.0 - github.com/go-git/go-git/v5 v5.8.1 + github.com/go-git/go-git/v5 v5.9.0 github.com/go-playground/validator v9.31.0+incompatible github.com/go-redsync/redsync/v4 v4.9.4 github.com/go-resty/resty/v2 v2.7.0 @@ -55,7 +56,7 @@ require ( github.com/tidwall/gjson v1.16.0 github.com/wagslane/go-password-validator v0.3.0 github.com/xanzy/go-gitlab v0.91.1 - go.uber.org/mock v0.2.0 + go.uber.org/mock v0.3.0 golang.org/x/crypto v0.13.0 golang.org/x/exp v0.0.0-20230905200255-921286631fa9 golang.org/x/oauth2 v0.12.0 @@ -66,22 +67,8 @@ require ( gorm.io/gorm v1.25.4 gorm.io/plugin/dbresolver v1.4.7 gorm.io/plugin/soft_delete v1.2.1 - k8s.io/api v0.28.1 - k8s.io/client-go v0.28.1 -) - -require ( - github.com/adrg/xdg v0.4.0 // indirect - github.com/anchore/clio v0.0.0-20230823172630-c42d666061af // indirect - github.com/anchore/fangs v0.0.0-20230818131516-2186b10924fe // indirect - github.com/felixge/fgprof v0.9.3 // indirect - github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect - github.com/gookit/color v1.5.4 // indirect - github.com/iancoleman/strcase v0.3.0 // indirect - github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/pborman/indent v1.2.1 // indirect - github.com/pkg/profile v1.7.0 // indirect - github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect + k8s.io/api v0.28.2 + k8s.io/client-go v0.28.2 ) require ( @@ -90,10 +77,13 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/acobaugh/osrelease v0.1.0 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect + github.com/adrg/xdg v0.4.0 // indirect github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect + github.com/anchore/clio v0.0.0-20230823172630-c42d666061af // indirect + github.com/anchore/fangs v0.0.0-20230818131516-2186b10924fe // indirect github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a // indirect github.com/anchore/go-struct-converter v0.0.0-20230627203149-c72ef8859ca9 // indirect github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501 // indirect @@ -105,8 +95,9 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/clbanning/mxj v1.8.4 // indirect github.com/cloudflare/circl v1.3.3 // indirect - github.com/containerd/containerd v1.7.3 // indirect + github.com/containerd/containerd v1.7.5 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -115,8 +106,12 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect + github.com/eapache/go-resiliency v1.4.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect + github.com/eapache/queue v1.1.0 // indirect github.com/emicklei/go-restful/v3 v3.10.2 // indirect github.com/facebookincubator/nvdtools v0.1.5 // indirect + github.com/felixge/fgprof v0.9.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/ghodss/yaml v1.0.0 // indirect @@ -124,7 +119,7 @@ require ( github.com/glebarez/go-sqlite v1.21.2 // indirect github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.4.1 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.20.0 // indirect @@ -145,14 +140,18 @@ require ( github.com/google/go-containerregistry v0.16.1 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect + github.com/gookit/color v1.5.4 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.4 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect @@ -164,6 +163,11 @@ require ( github.com/jackc/pgtype v1.14.0 // indirect github.com/jackc/pgx/v5 v5.4.3 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.7.6 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect @@ -181,6 +185,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mholt/archiver/v3 v3.5.1 github.com/microsoft/go-mssqldb v1.5.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -194,13 +199,16 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nwaples/rardecode v1.1.3 // indirect github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/pborman/indent v1.2.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.9 // indirect github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/profile v1.7.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/samber/lo v1.38.1 // indirect github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect @@ -229,6 +237,7 @@ require ( github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 // indirect github.com/wagoodman/go-progress v0.0.0-20230301185719-21920a456ad5 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect + github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect github.com/yuin/gopher-lua v1.1.0 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect @@ -254,7 +263,7 @@ require ( gorm.io/datatypes v1.2.0 // indirect gorm.io/driver/sqlserver v1.5.1 // indirect gorm.io/hints v1.1.2 // indirect - k8s.io/apimachinery v0.28.1 + k8s.io/apimachinery v0.28.2 k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230816210353-14e408962443 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect diff --git a/go.sum b/go.sum index b2c8dbd3..54810de9 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,8 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/IBM/sarama v1.41.2 h1:ZDBZfGPHAD4uuAtSv4U22fRZBgst0eEwGFzLj0fb85c= +github.com/IBM/sarama v1.41.2/go.mod h1:xdpu7sd6OE1uxNdjYTSKUfY8FaKkJES9/+EyjSgiGQk= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= @@ -77,8 +79,8 @@ github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBa github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE= github.com/acobaugh/osrelease v0.1.0/go.mod h1:4bFEs0MtgHNHBrmHCt67gNisnabCRAlzdVasCEGHTWY= @@ -119,8 +121,8 @@ github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aquasecurity/trivy v0.45.0 h1:Pwla4x6G2U2xrcsfsrdeZmLUmnrFPlUhg23xcNTzJX8= -github.com/aquasecurity/trivy v0.45.0/go.mod h1:nqruwuHFYfEDw4UGeg0oAzgAHYAtMpUR/PNfVDTidF4= +github.com/aquasecurity/trivy v0.45.1 h1:JjkrawgNpVUV6mxtFX635I3MhzDqmGkze46SnygkYN0= +github.com/aquasecurity/trivy v0.45.1/go.mod h1:3cawI6q9o32pPGXhuGEIWWwUCSMAzRk/FhsEdA4eW1k= github.com/aquasecurity/trivy-db v0.0.0-20230831170347-f732860d4917 h1:MQd7h7yUyA8UlUzhjNMzpUX0NpD7jfxmRfSKwp/Ji3E= github.com/aquasecurity/trivy-db v0.0.0-20230831170347-f732860d4917/go.mod h1:WJ5Qnk5ZNGWvks07GOZe2IOsuXrPfSC5c8hYGOGfrsU= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -128,8 +130,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.45.7 h1:k4QsvWZhm8409TYeRuTV1P6+j3lLKoe+giFA/j3VAps= -github.com/aws/aws-sdk-go v1.45.7/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.45.11 h1:8qiSrA12+NRr+2MVpMApi3JxtiFFjDVU1NeWe+80bYg= +github.com/aws/aws-sdk-go v1.45.11/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA= github.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -182,8 +184,8 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= -github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= +github.com/containerd/containerd v1.7.5 h1:i9T9XpAWMe11BHMN7pu1BZqOGjXaKTPyz2v+KYOZgkY= +github.com/containerd/containerd v1.7.5/go.mod h1:ieJNCSzASw2shSGYLHx8NAE7WsZ/gEigo5fQ78W5Zvw= github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -195,6 +197,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -206,8 +210,8 @@ github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dhui/dktest v0.3.16 h1:i6gq2YQEtcrjKbeJpBkWjE8MmLZPYllcjOFbTZuPDnw= -github.com/distribution/distribution/v3 v3.0.0-20230908093250-285b601af99a h1:UCizW/swHK+zxiZfXcrKybLRhm0pou8gJFNXeH7Xb5Y= -github.com/distribution/distribution/v3 v3.0.0-20230908093250-285b601af99a/go.mod h1:kwpPDTHXOnL7Ei4I8QaP0rOH/KP9SYIuXABAvv5jw0c= +github.com/distribution/distribution/v3 v3.0.0-20230915083636-612ad42609c3 h1:NNbaD3nHlCm6c6trUVsYrQqDTsR8sDPaZKJOgZ6PFn8= +github.com/distribution/distribution/v3 v3.0.0-20230915083636-612ad42609c3/go.mod h1:kwpPDTHXOnL7Ei4I8QaP0rOH/KP9SYIuXABAvv5jw0c= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= @@ -229,6 +233,12 @@ github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj6 github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/eapache/go-resiliency v1.4.0 h1:3OK9bWpPk5q6pbFAaYSEwD9CLUSHG8bnZuqX2yMt3B0= +github.com/eapache/go-resiliency v1.4.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -254,6 +264,7 @@ github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -274,11 +285,11 @@ github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= -github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= -github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= -github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= +github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY= +github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -495,6 +506,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= @@ -582,11 +594,17 @@ github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= @@ -775,7 +793,7 @@ github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2 github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/opencontainers/distribution-spec/specs-go v0.0.0-20230727214836-6bc87156eacf h1:UyoZ/WziSy7+CIWLfn68zhJkJqIin10U0wkL2FUNRCM= github.com/opencontainers/distribution-spec/specs-go v0.0.0-20230727214836-6bc87156eacf/go.mod h1:Va0IMqkjv62YSEytL4sgxrkiD9IzU0T0bX/ZZEtMnSQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -825,6 +843,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY= @@ -1013,8 +1033,8 @@ go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0 go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= -go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1631,12 +1651,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.28.1 h1:i+0O8k2NPBCPYaMB+uCkseEbawEt/eFaiRqUx8aB108= -k8s.io/api v0.28.1/go.mod h1:uBYwID+66wiL28Kn2tBjBYQdEU0Xk0z5qF8bIBqk/Dg= -k8s.io/apimachinery v0.28.1 h1:EJD40og3GizBSV3mkIoXQBsws32okPOy+MkRyzh6nPY= -k8s.io/apimachinery v0.28.1/go.mod h1:X0xh/chESs2hP9koe+SdIAcXWcQ+RM5hy0ZynB+yEvw= -k8s.io/client-go v0.28.1 h1:pRhMzB8HyLfVwpngWKE8hDcXRqifh1ga2Z/PU9SXVK8= -k8s.io/client-go v0.28.1/go.mod h1:pEZA3FqOsVkCc07pFVzK076R+P/eXqsgx5zuuRWukNE= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230816210353-14e408962443 h1:CAIciCnJnSOQxPd0xvpV6JU3D4AJvnYbImPpFpO9Hnw= diff --git a/pkg/dal/cmd/gen.go b/pkg/dal/cmd/gen.go index 1ba7bd03..f99ecf72 100644 --- a/pkg/dal/cmd/gen.go +++ b/pkg/dal/cmd/gen.go @@ -50,6 +50,7 @@ func main() { models.WebhookLog{}, models.Builder{}, models.BuilderRunner{}, + models.WorkQueue{}, ) g.Execute() diff --git a/pkg/dal/dao/builder.go b/pkg/dal/dao/builder.go index 5a5658e0..77d77115 100644 --- a/pkg/dal/dao/builder.go +++ b/pkg/dal/dao/builder.go @@ -22,6 +22,10 @@ import ( "github.com/go-sigma/sigma/pkg/dal/models" "github.com/go-sigma/sigma/pkg/dal/query" + "github.com/go-sigma/sigma/pkg/types" + "github.com/go-sigma/sigma/pkg/types/enums" + "github.com/go-sigma/sigma/pkg/utils" + "github.com/go-sigma/sigma/pkg/utils/ptr" ) //go:generate mockgen -destination=mocks/builder.go -package=mocks github.com/go-sigma/sigma/pkg/dal/dao BuilderService @@ -43,6 +47,8 @@ type BuilderService interface { CreateRunner(ctx context.Context, log *models.BuilderRunner) error // GetRunner get runner from object storage or database GetRunner(ctx context.Context, id int64) (*models.BuilderRunner, error) + // ListRunners list builder runners + ListRunners(ctx context.Context, id int64, pagination types.Pagination, sort types.Sortable) ([]*models.BuilderRunner, int64, error) // UpdateRunner update builder runner UpdateRunner(ctx context.Context, builderID, runnerID int64, updates map[string]interface{}) error // GetByNextTrigger get by next trigger @@ -133,6 +139,26 @@ func (s builderService) GetRunner(ctx context.Context, id int64) (*models.Builde return s.tx.BuilderRunner.WithContext(ctx).Where(s.tx.BuilderRunner.BuilderID.Eq(id)).First() } +// ListRunners list builder runners +func (s builderService) ListRunners(ctx context.Context, id int64, pagination types.Pagination, sort types.Sortable) ([]*models.BuilderRunner, int64, error) { + pagination = utils.NormalizePagination(pagination) + query := s.tx.BuilderRunner.WithContext(ctx).Where(s.tx.BuilderRunner.BuilderID.Eq(id)) + field, ok := s.tx.BuilderRunner.GetFieldByName(ptr.To(sort.Sort)) + if ok { + switch ptr.To(sort.Method) { + case enums.SortMethodDesc: + query = query.Order(field.Desc()) + case enums.SortMethodAsc: + query = query.Order(field) + default: + query = query.Order(s.tx.BuilderRunner.UpdatedAt.Desc()) + } + } else { + query = query.Order(s.tx.BuilderRunner.UpdatedAt.Desc()) + } + return query.FindByPage(ptr.To(pagination.Limit)*(ptr.To(pagination.Page)-1), ptr.To(pagination.Limit)) +} + // UpdateRunner update builder runner func (s builderService) UpdateRunner(ctx context.Context, builderID, runnerID int64, updates map[string]interface{}) error { matched, err := s.tx.BuilderRunner.WithContext(ctx).Where(s.tx.BuilderRunner.BuilderID.Eq(builderID), s.tx.BuilderRunner.ID.Eq(runnerID)).Updates(updates) diff --git a/pkg/dal/dao/code_repository.go b/pkg/dal/dao/code_repository.go index 3a6b79c2..8e3a58b5 100644 --- a/pkg/dal/dao/code_repository.go +++ b/pkg/dal/dao/code_repository.go @@ -50,6 +50,8 @@ type CodeRepositoryService interface { DeleteBranchesInBatches(ctx context.Context, ids []int64) error // ListAll lists all code repository records in the database ListAll(ctx context.Context, user3rdPartyID int64) ([]*models.CodeRepository, error) + // Get get code repository record by id + Get(ctx context.Context, id int64) (*models.CodeRepository, error) // ListOwnersAll lists all code repository owners records in the database ListOwnersAll(ctx context.Context, user3rdPartyID int64) ([]*models.CodeRepositoryOwner, error) // ListWithPagination list code repositories with pagination @@ -176,6 +178,11 @@ func (s *codeRepositoryService) ListAll(ctx context.Context, user3rdPartyID int6 return s.tx.CodeRepository.WithContext(ctx).Where(s.tx.CodeRepository.User3rdPartyID.Eq(user3rdPartyID)).Find() } +// Get get code repository record by id +func (s *codeRepositoryService) Get(ctx context.Context, id int64) (*models.CodeRepository, error) { + return s.tx.CodeRepository.WithContext(ctx).Where(s.tx.CodeRepository.ID.Eq(id)).Preload(s.tx.CodeRepository.User3rdParty).First() +} + // ListOwnersAll lists all code repository owners records in the database func (s *codeRepositoryService) ListOwnersAll(ctx context.Context, user3rdPartyID int64) ([]*models.CodeRepositoryOwner, error) { return s.tx.CodeRepositoryOwner.WithContext(ctx).Where(s.tx.CodeRepositoryOwner.User3rdPartyID.Eq(user3rdPartyID)).Find() diff --git a/pkg/dal/dao/mocks/builder.go b/pkg/dal/dao/mocks/builder.go index 3eb40324..27ab637e 100644 --- a/pkg/dal/dao/mocks/builder.go +++ b/pkg/dal/dao/mocks/builder.go @@ -64,6 +64,21 @@ func (mr *MockBuilderServiceMockRecorder) CreateRunner(arg0, arg1 interface{}) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRunner", reflect.TypeOf((*MockBuilderService)(nil).CreateRunner), arg0, arg1) } +// Get mocks base method. +func (m *MockBuilderService) Get(arg0 context.Context, arg1 int64) (*models.Builder, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(*models.Builder) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockBuilderServiceMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockBuilderService)(nil).Get), arg0, arg1) +} + // GetByNextTrigger mocks base method. func (m *MockBuilderService) GetByNextTrigger(arg0 context.Context, arg1 time.Time, arg2 int) ([]*models.Builder, error) { m.ctrl.T.Helper() @@ -94,6 +109,21 @@ func (mr *MockBuilderServiceMockRecorder) GetByRepositoryID(arg0, arg1 interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByRepositoryID", reflect.TypeOf((*MockBuilderService)(nil).GetByRepositoryID), arg0, arg1) } +// GetByRepositoryIDs mocks base method. +func (m *MockBuilderService) GetByRepositoryIDs(arg0 context.Context, arg1 []int64) (map[int64]*models.Builder, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetByRepositoryIDs", arg0, arg1) + ret0, _ := ret[0].(map[int64]*models.Builder) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetByRepositoryIDs indicates an expected call of GetByRepositoryIDs. +func (mr *MockBuilderServiceMockRecorder) GetByRepositoryIDs(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByRepositoryIDs", reflect.TypeOf((*MockBuilderService)(nil).GetByRepositoryIDs), arg0, arg1) +} + // GetRunner mocks base method. func (m *MockBuilderService) GetRunner(arg0 context.Context, arg1 int64) (*models.BuilderRunner, error) { m.ctrl.T.Helper() @@ -109,6 +139,20 @@ func (mr *MockBuilderServiceMockRecorder) GetRunner(arg0, arg1 interface{}) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRunner", reflect.TypeOf((*MockBuilderService)(nil).GetRunner), arg0, arg1) } +// Update mocks base method. +func (m *MockBuilderService) Update(arg0 context.Context, arg1 int64, arg2 map[string]interface{}) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// Update indicates an expected call of Update. +func (mr *MockBuilderServiceMockRecorder) Update(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockBuilderService)(nil).Update), arg0, arg1, arg2) +} + // UpdateNextTrigger mocks base method. func (m *MockBuilderService) UpdateNextTrigger(arg0 context.Context, arg1 int64, arg2 time.Time) error { m.ctrl.T.Helper() diff --git a/pkg/dal/dao/mocks/code_repository.go b/pkg/dal/dao/mocks/code_repository.go index 72b797bc..08a6e858 100644 --- a/pkg/dal/dao/mocks/code_repository.go +++ b/pkg/dal/dao/mocks/code_repository.go @@ -121,6 +121,21 @@ func (mr *MockCodeRepositoryServiceMockRecorder) DeleteOwnerInBatches(arg0, arg1 return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteOwnerInBatches", reflect.TypeOf((*MockCodeRepositoryService)(nil).DeleteOwnerInBatches), arg0, arg1) } +// Get mocks base method. +func (m *MockCodeRepositoryService) Get(arg0 context.Context, arg1 int64) (*models.CodeRepository, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(*models.CodeRepository) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockCodeRepositoryServiceMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockCodeRepositoryService)(nil).Get), arg0, arg1) +} + // ListAll mocks base method. func (m *MockCodeRepositoryService) ListAll(arg0 context.Context, arg1 int64) ([]*models.CodeRepository, error) { m.ctrl.T.Helper() diff --git a/pkg/dal/dao/mocks/workq.go b/pkg/dal/dao/mocks/workq.go new file mode 100644 index 00000000..a970c0cd --- /dev/null +++ b/pkg/dal/dao/mocks/workq.go @@ -0,0 +1,80 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/go-sigma/sigma/pkg/dal/dao (interfaces: WorkQueueService) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + models "github.com/go-sigma/sigma/pkg/dal/models" + enums "github.com/go-sigma/sigma/pkg/types/enums" + gomock "go.uber.org/mock/gomock" +) + +// MockWorkQueueService is a mock of WorkQueueService interface. +type MockWorkQueueService struct { + ctrl *gomock.Controller + recorder *MockWorkQueueServiceMockRecorder +} + +// MockWorkQueueServiceMockRecorder is the mock recorder for MockWorkQueueService. +type MockWorkQueueServiceMockRecorder struct { + mock *MockWorkQueueService +} + +// NewMockWorkQueueService creates a new mock instance. +func NewMockWorkQueueService(ctrl *gomock.Controller) *MockWorkQueueService { + mock := &MockWorkQueueService{ctrl: ctrl} + mock.recorder = &MockWorkQueueServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockWorkQueueService) EXPECT() *MockWorkQueueServiceMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockWorkQueueService) Create(arg0 context.Context, arg1 *models.WorkQueue) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Create indicates an expected call of Create. +func (mr *MockWorkQueueServiceMockRecorder) Create(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockWorkQueueService)(nil).Create), arg0, arg1) +} + +// Get mocks base method. +func (m *MockWorkQueueService) Get(arg0 context.Context) (*models.WorkQueue, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0) + ret0, _ := ret[0].(*models.WorkQueue) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockWorkQueueServiceMockRecorder) Get(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockWorkQueueService)(nil).Get), arg0) +} + +// UpdateStatus mocks base method. +func (m *MockWorkQueueService) UpdateStatus(arg0 context.Context, arg1 int64, arg2 string, arg3 enums.TaskCommonStatus) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStatus", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateStatus indicates an expected call of UpdateStatus. +func (mr *MockWorkQueueServiceMockRecorder) UpdateStatus(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStatus", reflect.TypeOf((*MockWorkQueueService)(nil).UpdateStatus), arg0, arg1, arg2, arg3) +} diff --git a/pkg/dal/dao/mocks/workq_factory.go b/pkg/dal/dao/mocks/workq_factory.go new file mode 100644 index 00000000..3680bed8 --- /dev/null +++ b/pkg/dal/dao/mocks/workq_factory.go @@ -0,0 +1,54 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/go-sigma/sigma/pkg/dal/dao (interfaces: WorkQueueServiceFactory) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + dao "github.com/go-sigma/sigma/pkg/dal/dao" + query "github.com/go-sigma/sigma/pkg/dal/query" + gomock "go.uber.org/mock/gomock" +) + +// MockWorkQueueServiceFactory is a mock of WorkQueueServiceFactory interface. +type MockWorkQueueServiceFactory struct { + ctrl *gomock.Controller + recorder *MockWorkQueueServiceFactoryMockRecorder +} + +// MockWorkQueueServiceFactoryMockRecorder is the mock recorder for MockWorkQueueServiceFactory. +type MockWorkQueueServiceFactoryMockRecorder struct { + mock *MockWorkQueueServiceFactory +} + +// NewMockWorkQueueServiceFactory creates a new mock instance. +func NewMockWorkQueueServiceFactory(ctrl *gomock.Controller) *MockWorkQueueServiceFactory { + mock := &MockWorkQueueServiceFactory{ctrl: ctrl} + mock.recorder = &MockWorkQueueServiceFactoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockWorkQueueServiceFactory) EXPECT() *MockWorkQueueServiceFactoryMockRecorder { + return m.recorder +} + +// New mocks base method. +func (m *MockWorkQueueServiceFactory) New(arg0 ...*query.Query) dao.WorkQueueService { + m.ctrl.T.Helper() + varargs := []interface{}{} + for _, a := range arg0 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "New", varargs...) + ret0, _ := ret[0].(dao.WorkQueueService) + return ret0 +} + +// New indicates an expected call of New. +func (mr *MockWorkQueueServiceFactoryMockRecorder) New(arg0 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "New", reflect.TypeOf((*MockWorkQueueServiceFactory)(nil).New), arg0...) +} diff --git a/pkg/dal/dao/workq.go b/pkg/dal/dao/workq.go new file mode 100644 index 00000000..e47e1800 --- /dev/null +++ b/pkg/dal/dao/workq.go @@ -0,0 +1,93 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dao + +import ( + "context" + + "gorm.io/gorm" + + "github.com/go-sigma/sigma/pkg/dal/models" + "github.com/go-sigma/sigma/pkg/dal/query" + "github.com/go-sigma/sigma/pkg/types/enums" +) + +//go:generate mockgen -destination=mocks/workq.go -package=mocks github.com/go-sigma/sigma/pkg/dal/dao WorkQueueService +//go:generate mockgen -destination=mocks/workq_factory.go -package=mocks github.com/go-sigma/sigma/pkg/dal/dao WorkQueueServiceFactory + +// WorkQueueService is the interface that provides methods to operate on work queue model +type WorkQueueService interface { + // Create creates a new work queue record in the database + Create(ctx context.Context, builder *models.WorkQueue) error + // Get get a work queue record + Get(ctx context.Context) (*models.WorkQueue, error) + // UpdateStatus update a work queue record status + UpdateStatus(ctx context.Context, id int64, version, newVersion string, status enums.TaskCommonStatus) error +} + +type workQueueService struct { + tx *query.Query +} + +// WorkQueueServiceFactory is the interface that provides the work queue service factory methods. +type WorkQueueServiceFactory interface { + New(txs ...*query.Query) WorkQueueService +} + +type workQueueServiceFactory struct{} + +// NewWorkQueueServiceFactory creates a new work queue service factory. +func NewWorkQueueServiceFactory() WorkQueueServiceFactory { + return &workQueueServiceFactory{} +} + +func (f *workQueueServiceFactory) New(txs ...*query.Query) WorkQueueService { + tx := query.Q + if len(txs) > 0 { + tx = txs[0] + } + return &workQueueService{ + tx: tx, + } +} + +// Create creates a new work queue record in the database +func (s workQueueService) Create(ctx context.Context, wq *models.WorkQueue) error { + return s.tx.WorkQueue.WithContext(ctx).Create(wq) +} + +// Get get a work queue record +func (s workQueueService) Get(ctx context.Context) (*models.WorkQueue, error) { + return s.tx.WorkQueue.WithContext(ctx).Where(s.tx.WorkQueue.Status.Eq(enums.TaskCommonStatusPending)).Order(s.tx.WorkQueue.UpdatedAt).First() +} + +// Update update a work queue record +func (s workQueueService) UpdateStatus(ctx context.Context, id int64, version, newVersion string, status enums.TaskCommonStatus) error { + value := map[string]any{ + query.WorkQueue.Status.ColumnName().String(): status, + query.WorkQueue.Version.ColumnName().String(): newVersion, + } + result, err := s.tx.WorkQueue.WithContext(ctx).Where( + s.tx.WorkQueue.ID.Eq(id), + s.tx.WorkQueue.Version.Eq(version), + ).UpdateColumns(value) + if err != nil { + return err + } + if result.RowsAffected == 0 { + return gorm.ErrRecordNotFound + } + return nil +} diff --git a/pkg/dal/migrations/mysql/0001_initialize.up.sql b/pkg/dal/migrations/mysql/0001_initialize.up.sql index 5303473a..d1999d73 100644 --- a/pkg/dal/migrations/mysql/0001_initialize.up.sql +++ b/pkg/dal/migrations/mysql/0001_initialize.up.sql @@ -405,7 +405,9 @@ CREATE TABLE IF NOT EXISTS `work_queue` ( `id` bigint AUTO_INCREMENT PRIMARY KEY, `topic` varchar(30) NOT NULL, `payload` BLOB NOT NULL, + `times` MEDIUMINT NOT NULL DEFAULT 0, `version` varchar(30) NOT NULL, + `status` ENUM ('Success', 'Failed', 'Pending', 'Doing') NOT NULL DEFAULT 'Pending', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleted_at` bigint NOT NULL DEFAULT 0 diff --git a/pkg/dal/migrations/postgresql/0001_initialize.up.sql b/pkg/dal/migrations/postgresql/0001_initialize.up.sql index 3fbb1de0..1f5fc9dc 100644 --- a/pkg/dal/migrations/postgresql/0001_initialize.up.sql +++ b/pkg/dal/migrations/postgresql/0001_initialize.up.sql @@ -474,7 +474,9 @@ CREATE TABLE IF NOT EXISTS "work_queue" ( "id" bigserial PRIMARY KEY, "topic" varchar(30) NOT NULL, "payload" bytea NOT NULL, + "times" smallint NOT NULL DEFAULT 0, "version" varchar(30) NOT NULL, + "status" daemon_status NOT NULL DEFAULT 'Pending', "created_at" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, "deleted_at" bigint NOT NULL DEFAULT 0 diff --git a/pkg/dal/migrations/sqlite3/0001_initialize.up.sql b/pkg/dal/migrations/sqlite3/0001_initialize.up.sql index 530f7523..b3ec90c1 100644 --- a/pkg/dal/migrations/sqlite3/0001_initialize.up.sql +++ b/pkg/dal/migrations/sqlite3/0001_initialize.up.sql @@ -403,7 +403,9 @@ CREATE TABLE IF NOT EXISTS `work_queue` ( `id` integer PRIMARY KEY AUTOINCREMENT, `topic` varchar(30) NOT NULL, `payload` BLOB NOT NULL, + `times` integer NOT NULL DEFAULT 0, `version` varchar(30) NOT NULL, + `status` text CHECK (`status` IN ('Success', 'Failed', 'Pending', 'Scheduling', 'Building')) NOT NULL DEFAULT 'Pending', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleted_at` bigint NOT NULL DEFAULT 0 diff --git a/pkg/dal/models/workq.go b/pkg/dal/models/workq.go new file mode 100644 index 00000000..f8eab60a --- /dev/null +++ b/pkg/dal/models/workq.go @@ -0,0 +1,37 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package models + +import ( + "time" + + "gorm.io/plugin/soft_delete" + + "github.com/go-sigma/sigma/pkg/types/enums" +) + +// WorkQueue ... +type WorkQueue struct { + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt soft_delete.DeletedAt `gorm:"softDelete:milli"` + ID int64 `gorm:"primaryKey"` + + Topic string + Payload []byte + Times int + Version string + Status enums.TaskCommonStatus `gorm:"default:Pending"` +} diff --git a/pkg/dal/query/gen.go b/pkg/dal/query/gen.go index bf97281a..f3df83fd 100644 --- a/pkg/dal/query/gen.go +++ b/pkg/dal/query/gen.go @@ -39,6 +39,7 @@ var ( UserRecoverCode *userRecoverCode Webhook *webhook WebhookLog *webhookLog + WorkQueue *workQueue ) func SetDefault(db *gorm.DB, opts ...gen.DOOption) { @@ -65,6 +66,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) { UserRecoverCode = &Q.UserRecoverCode Webhook = &Q.Webhook WebhookLog = &Q.WebhookLog + WorkQueue = &Q.WorkQueue } func Use(db *gorm.DB, opts ...gen.DOOption) *Query { @@ -92,6 +94,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query { UserRecoverCode: newUserRecoverCode(db, opts...), Webhook: newWebhook(db, opts...), WebhookLog: newWebhookLog(db, opts...), + WorkQueue: newWorkQueue(db, opts...), } } @@ -120,6 +123,7 @@ type Query struct { UserRecoverCode userRecoverCode Webhook webhook WebhookLog webhookLog + WorkQueue workQueue } func (q *Query) Available() bool { return q.db != nil } @@ -149,6 +153,7 @@ func (q *Query) clone(db *gorm.DB) *Query { UserRecoverCode: q.UserRecoverCode.clone(db), Webhook: q.Webhook.clone(db), WebhookLog: q.WebhookLog.clone(db), + WorkQueue: q.WorkQueue.clone(db), } } @@ -185,6 +190,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query { UserRecoverCode: q.UserRecoverCode.replaceDB(db), Webhook: q.Webhook.replaceDB(db), WebhookLog: q.WebhookLog.replaceDB(db), + WorkQueue: q.WorkQueue.replaceDB(db), } } @@ -211,6 +217,7 @@ type queryCtx struct { UserRecoverCode *userRecoverCodeDo Webhook *webhookDo WebhookLog *webhookLogDo + WorkQueue *workQueueDo } func (q *Query) WithContext(ctx context.Context) *queryCtx { @@ -237,6 +244,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx { UserRecoverCode: q.UserRecoverCode.WithContext(ctx), Webhook: q.Webhook.WithContext(ctx), WebhookLog: q.WebhookLog.WithContext(ctx), + WorkQueue: q.WorkQueue.WithContext(ctx), } } diff --git a/pkg/dal/query/work_queues.gen.go b/pkg/dal/query/work_queues.gen.go new file mode 100644 index 00000000..f84d7519 --- /dev/null +++ b/pkg/dal/query/work_queues.gen.go @@ -0,0 +1,357 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "github.com/go-sigma/sigma/pkg/dal/models" +) + +func newWorkQueue(db *gorm.DB, opts ...gen.DOOption) workQueue { + _workQueue := workQueue{} + + _workQueue.workQueueDo.UseDB(db, opts...) + _workQueue.workQueueDo.UseModel(&models.WorkQueue{}) + + tableName := _workQueue.workQueueDo.TableName() + _workQueue.ALL = field.NewAsterisk(tableName) + _workQueue.CreatedAt = field.NewTime(tableName, "created_at") + _workQueue.UpdatedAt = field.NewTime(tableName, "updated_at") + _workQueue.DeletedAt = field.NewUint(tableName, "deleted_at") + _workQueue.ID = field.NewInt64(tableName, "id") + _workQueue.Topic = field.NewString(tableName, "topic") + _workQueue.Payload = field.NewBytes(tableName, "payload") + _workQueue.Version = field.NewString(tableName, "version") + _workQueue.Status = field.NewField(tableName, "status") + + _workQueue.fillFieldMap() + + return _workQueue +} + +type workQueue struct { + workQueueDo workQueueDo + + ALL field.Asterisk + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Uint + ID field.Int64 + Topic field.String + Payload field.Bytes + Version field.String + Status field.Field + + fieldMap map[string]field.Expr +} + +func (w workQueue) Table(newTableName string) *workQueue { + w.workQueueDo.UseTable(newTableName) + return w.updateTableName(newTableName) +} + +func (w workQueue) As(alias string) *workQueue { + w.workQueueDo.DO = *(w.workQueueDo.As(alias).(*gen.DO)) + return w.updateTableName(alias) +} + +func (w *workQueue) updateTableName(table string) *workQueue { + w.ALL = field.NewAsterisk(table) + w.CreatedAt = field.NewTime(table, "created_at") + w.UpdatedAt = field.NewTime(table, "updated_at") + w.DeletedAt = field.NewUint(table, "deleted_at") + w.ID = field.NewInt64(table, "id") + w.Topic = field.NewString(table, "topic") + w.Payload = field.NewBytes(table, "payload") + w.Version = field.NewString(table, "version") + w.Status = field.NewField(table, "status") + + w.fillFieldMap() + + return w +} + +func (w *workQueue) WithContext(ctx context.Context) *workQueueDo { + return w.workQueueDo.WithContext(ctx) +} + +func (w workQueue) TableName() string { return w.workQueueDo.TableName() } + +func (w workQueue) Alias() string { return w.workQueueDo.Alias() } + +func (w workQueue) Columns(cols ...field.Expr) gen.Columns { return w.workQueueDo.Columns(cols...) } + +func (w *workQueue) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := w.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (w *workQueue) fillFieldMap() { + w.fieldMap = make(map[string]field.Expr, 8) + w.fieldMap["created_at"] = w.CreatedAt + w.fieldMap["updated_at"] = w.UpdatedAt + w.fieldMap["deleted_at"] = w.DeletedAt + w.fieldMap["id"] = w.ID + w.fieldMap["topic"] = w.Topic + w.fieldMap["payload"] = w.Payload + w.fieldMap["version"] = w.Version + w.fieldMap["status"] = w.Status +} + +func (w workQueue) clone(db *gorm.DB) workQueue { + w.workQueueDo.ReplaceConnPool(db.Statement.ConnPool) + return w +} + +func (w workQueue) replaceDB(db *gorm.DB) workQueue { + w.workQueueDo.ReplaceDB(db) + return w +} + +type workQueueDo struct{ gen.DO } + +func (w workQueueDo) Debug() *workQueueDo { + return w.withDO(w.DO.Debug()) +} + +func (w workQueueDo) WithContext(ctx context.Context) *workQueueDo { + return w.withDO(w.DO.WithContext(ctx)) +} + +func (w workQueueDo) ReadDB() *workQueueDo { + return w.Clauses(dbresolver.Read) +} + +func (w workQueueDo) WriteDB() *workQueueDo { + return w.Clauses(dbresolver.Write) +} + +func (w workQueueDo) Session(config *gorm.Session) *workQueueDo { + return w.withDO(w.DO.Session(config)) +} + +func (w workQueueDo) Clauses(conds ...clause.Expression) *workQueueDo { + return w.withDO(w.DO.Clauses(conds...)) +} + +func (w workQueueDo) Returning(value interface{}, columns ...string) *workQueueDo { + return w.withDO(w.DO.Returning(value, columns...)) +} + +func (w workQueueDo) Not(conds ...gen.Condition) *workQueueDo { + return w.withDO(w.DO.Not(conds...)) +} + +func (w workQueueDo) Or(conds ...gen.Condition) *workQueueDo { + return w.withDO(w.DO.Or(conds...)) +} + +func (w workQueueDo) Select(conds ...field.Expr) *workQueueDo { + return w.withDO(w.DO.Select(conds...)) +} + +func (w workQueueDo) Where(conds ...gen.Condition) *workQueueDo { + return w.withDO(w.DO.Where(conds...)) +} + +func (w workQueueDo) Order(conds ...field.Expr) *workQueueDo { + return w.withDO(w.DO.Order(conds...)) +} + +func (w workQueueDo) Distinct(cols ...field.Expr) *workQueueDo { + return w.withDO(w.DO.Distinct(cols...)) +} + +func (w workQueueDo) Omit(cols ...field.Expr) *workQueueDo { + return w.withDO(w.DO.Omit(cols...)) +} + +func (w workQueueDo) Join(table schema.Tabler, on ...field.Expr) *workQueueDo { + return w.withDO(w.DO.Join(table, on...)) +} + +func (w workQueueDo) LeftJoin(table schema.Tabler, on ...field.Expr) *workQueueDo { + return w.withDO(w.DO.LeftJoin(table, on...)) +} + +func (w workQueueDo) RightJoin(table schema.Tabler, on ...field.Expr) *workQueueDo { + return w.withDO(w.DO.RightJoin(table, on...)) +} + +func (w workQueueDo) Group(cols ...field.Expr) *workQueueDo { + return w.withDO(w.DO.Group(cols...)) +} + +func (w workQueueDo) Having(conds ...gen.Condition) *workQueueDo { + return w.withDO(w.DO.Having(conds...)) +} + +func (w workQueueDo) Limit(limit int) *workQueueDo { + return w.withDO(w.DO.Limit(limit)) +} + +func (w workQueueDo) Offset(offset int) *workQueueDo { + return w.withDO(w.DO.Offset(offset)) +} + +func (w workQueueDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *workQueueDo { + return w.withDO(w.DO.Scopes(funcs...)) +} + +func (w workQueueDo) Unscoped() *workQueueDo { + return w.withDO(w.DO.Unscoped()) +} + +func (w workQueueDo) Create(values ...*models.WorkQueue) error { + if len(values) == 0 { + return nil + } + return w.DO.Create(values) +} + +func (w workQueueDo) CreateInBatches(values []*models.WorkQueue, batchSize int) error { + return w.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (w workQueueDo) Save(values ...*models.WorkQueue) error { + if len(values) == 0 { + return nil + } + return w.DO.Save(values) +} + +func (w workQueueDo) First() (*models.WorkQueue, error) { + if result, err := w.DO.First(); err != nil { + return nil, err + } else { + return result.(*models.WorkQueue), nil + } +} + +func (w workQueueDo) Take() (*models.WorkQueue, error) { + if result, err := w.DO.Take(); err != nil { + return nil, err + } else { + return result.(*models.WorkQueue), nil + } +} + +func (w workQueueDo) Last() (*models.WorkQueue, error) { + if result, err := w.DO.Last(); err != nil { + return nil, err + } else { + return result.(*models.WorkQueue), nil + } +} + +func (w workQueueDo) Find() ([]*models.WorkQueue, error) { + result, err := w.DO.Find() + return result.([]*models.WorkQueue), err +} + +func (w workQueueDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.WorkQueue, err error) { + buf := make([]*models.WorkQueue, 0, batchSize) + err = w.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (w workQueueDo) FindInBatches(result *[]*models.WorkQueue, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return w.DO.FindInBatches(result, batchSize, fc) +} + +func (w workQueueDo) Attrs(attrs ...field.AssignExpr) *workQueueDo { + return w.withDO(w.DO.Attrs(attrs...)) +} + +func (w workQueueDo) Assign(attrs ...field.AssignExpr) *workQueueDo { + return w.withDO(w.DO.Assign(attrs...)) +} + +func (w workQueueDo) Joins(fields ...field.RelationField) *workQueueDo { + for _, _f := range fields { + w = *w.withDO(w.DO.Joins(_f)) + } + return &w +} + +func (w workQueueDo) Preload(fields ...field.RelationField) *workQueueDo { + for _, _f := range fields { + w = *w.withDO(w.DO.Preload(_f)) + } + return &w +} + +func (w workQueueDo) FirstOrInit() (*models.WorkQueue, error) { + if result, err := w.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*models.WorkQueue), nil + } +} + +func (w workQueueDo) FirstOrCreate() (*models.WorkQueue, error) { + if result, err := w.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*models.WorkQueue), nil + } +} + +func (w workQueueDo) FindByPage(offset int, limit int) (result []*models.WorkQueue, count int64, err error) { + result, err = w.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = w.Offset(-1).Limit(-1).Count() + return +} + +func (w workQueueDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = w.Count() + if err != nil { + return + } + + err = w.Offset(offset).Limit(limit).Scan(result) + return +} + +func (w workQueueDo) Scan(result interface{}) (err error) { + return w.DO.Scan(result) +} + +func (w workQueueDo) Delete(models ...*models.WorkQueue) (result gen.ResultInfo, err error) { + return w.DO.Delete(models) +} + +func (w *workQueueDo) withDO(do gen.Dao) *workQueueDo { + w.DO = *do.(*gen.DO) + return w +} diff --git a/pkg/handlers/apidocs/docs.go b/pkg/handlers/apidocs/docs.go index a4854025..5091ab3d 100644 --- a/pkg/handlers/apidocs/docs.go +++ b/pkg/handlers/apidocs/docs.go @@ -299,6 +299,55 @@ const docTemplate = `{ } } }, + "/coderepos/{provider}/repos/{id}": { + "get": { + "security": [ + { + "BasicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CodeRepository" + ], + "summary": "Get code repository by id", + "parameters": [ + { + "type": "string", + "description": "search code repository with provider", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "code repository id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/types.CodeRepositoryItem" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/xerrors.ErrCode" + } + } + } + } + }, "/coderepos/{provider}/resync": { "get": { "security": [ @@ -3170,6 +3219,7 @@ const docTemplate = `{ ], "properties": { "buildkit_build_args": { + "description": "TODO: validate", "type": "string", "example": "a=b,c=d" }, @@ -3214,6 +3264,7 @@ const docTemplate = `{ "example": "main" }, "cron_rule": { + "description": "TODO: validate", "type": "string", "example": "* * * * *" }, @@ -3290,6 +3341,7 @@ const docTemplate = `{ "example": "{.Ref}" }, "webhook_tag_tag_template": { + "description": "TODO: validate", "type": "string", "example": "{.Ref}" } @@ -3495,6 +3547,7 @@ const docTemplate = `{ ], "properties": { "buildkit_build_args": { + "description": "TODO: validate", "type": "string", "example": "a=b,c=d" }, @@ -3539,6 +3592,7 @@ const docTemplate = `{ "example": "main" }, "cron_rule": { + "description": "TODO: validate", "type": "string", "example": "* * * * *" }, @@ -3615,6 +3669,7 @@ const docTemplate = `{ "example": "{.Ref}" }, "webhook_tag_tag_template": { + "description": "TODO: validate", "type": "string", "example": "{.Ref}" } diff --git a/pkg/handlers/apidocs/swagger.json b/pkg/handlers/apidocs/swagger.json index 288d93db..7a42dfa0 100644 --- a/pkg/handlers/apidocs/swagger.json +++ b/pkg/handlers/apidocs/swagger.json @@ -290,6 +290,55 @@ } } }, + "/coderepos/{provider}/repos/{id}": { + "get": { + "security": [ + { + "BasicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CodeRepository" + ], + "summary": "Get code repository by id", + "parameters": [ + { + "type": "string", + "description": "search code repository with provider", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "code repository id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/types.CodeRepositoryItem" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/xerrors.ErrCode" + } + } + } + } + }, "/coderepos/{provider}/resync": { "get": { "security": [ @@ -3161,6 +3210,7 @@ ], "properties": { "buildkit_build_args": { + "description": "TODO: validate", "type": "string", "example": "a=b,c=d" }, @@ -3205,6 +3255,7 @@ "example": "main" }, "cron_rule": { + "description": "TODO: validate", "type": "string", "example": "* * * * *" }, @@ -3281,6 +3332,7 @@ "example": "{.Ref}" }, "webhook_tag_tag_template": { + "description": "TODO: validate", "type": "string", "example": "{.Ref}" } @@ -3486,6 +3538,7 @@ ], "properties": { "buildkit_build_args": { + "description": "TODO: validate", "type": "string", "example": "a=b,c=d" }, @@ -3530,6 +3583,7 @@ "example": "main" }, "cron_rule": { + "description": "TODO: validate", "type": "string", "example": "* * * * *" }, @@ -3606,6 +3660,7 @@ "example": "{.Ref}" }, "webhook_tag_tag_template": { + "description": "TODO: validate", "type": "string", "example": "{.Ref}" } diff --git a/pkg/handlers/apidocs/swagger.yaml b/pkg/handlers/apidocs/swagger.yaml index bcf6cb15..46bfe606 100644 --- a/pkg/handlers/apidocs/swagger.yaml +++ b/pkg/handlers/apidocs/swagger.yaml @@ -516,6 +516,7 @@ definitions: types.PostBuilderRequestSwagger: properties: buildkit_build_args: + description: 'TODO: validate' example: a=b,c=d type: string buildkit_context: @@ -549,6 +550,7 @@ definitions: example: main type: string cron_rule: + description: 'TODO: validate' example: '* * * * *' type: string cron_tag_template: @@ -603,6 +605,7 @@ definitions: example: '{.Ref}' type: string webhook_tag_tag_template: + description: 'TODO: validate' example: '{.Ref}' type: string required: @@ -748,6 +751,7 @@ definitions: types.PutBuilderRequestSwagger: properties: buildkit_build_args: + description: 'TODO: validate' example: a=b,c=d type: string buildkit_context: @@ -781,6 +785,7 @@ definitions: example: main type: string cron_rule: + description: 'TODO: validate' example: '* * * * *' type: string cron_tag_template: @@ -835,6 +840,7 @@ definitions: example: '{.Ref}' type: string webhook_tag_tag_template: + description: 'TODO: validate' example: '{.Ref}' type: string required: @@ -1270,6 +1276,37 @@ paths: summary: List code repository owners tags: - CodeRepository + /coderepos/{provider}/repos/{id}: + get: + consumes: + - application/json + parameters: + - description: search code repository with provider + in: path + name: provider + required: true + type: string + - description: code repository id + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/types.CodeRepositoryItem' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/xerrors.ErrCode' + security: + - BasicAuth: [] + summary: Get code repository by id + tags: + - CodeRepository /coderepos/{provider}/resync: get: consumes: diff --git a/pkg/handlers/builders/builders_get.go b/pkg/handlers/builders/builders_get.go index c2e47849..dd6290f1 100644 --- a/pkg/handlers/builders/builders_get.go +++ b/pkg/handlers/builders/builders_get.go @@ -57,15 +57,15 @@ func (h *handlers) GetBuilder(c echo.Context) error { builderObj, err := builderService.Get(ctx, req.ID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - log.Error().Err(err).Int64("repositoryID", req.ID).Int64("id", req.ID).Msg("Builder not found") + log.Error().Err(err).Int64("repositoryID", req.RepositoryID).Int64("id", req.ID).Msg("Builder not found") return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeNotFound, fmt.Sprintf("Builder(%d) not found: %s", req.ID, err)) } - log.Error().Err(err).Int64("repositoryID", req.ID).Int64("id", req.ID).Msg("Get builder failed") + log.Error().Err(err).Int64("repositoryID", req.RepositoryID).Int64("id", req.ID).Msg("Get builder failed") return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("Builder(%d) not found: %s", req.ID, err)) } if builderObj.RepositoryID != req.RepositoryID { - log.Error().Int64("repositoryID", req.ID).Int64("id", req.ID).Msg("Builder not found") + log.Error().Int64("repositoryID", req.RepositoryID).Int64("id", req.ID).Msg("Builder not found") return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeNotFound, fmt.Sprintf("Builder(%d) not found", req.ID)) } diff --git a/pkg/handlers/builders/builders_runners_list.go b/pkg/handlers/builders/builders_runners_list.go new file mode 100644 index 00000000..c77f2534 --- /dev/null +++ b/pkg/handlers/builders/builders_runners_list.go @@ -0,0 +1,75 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package builders + +import ( + "errors" + "fmt" + "net/http" + "strings" + + "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" + "gorm.io/gorm" + + "github.com/go-sigma/sigma/pkg/consts" + "github.com/go-sigma/sigma/pkg/types" + "github.com/go-sigma/sigma/pkg/types/enums" + "github.com/go-sigma/sigma/pkg/utils" + "github.com/go-sigma/sigma/pkg/xerrors" +) + +// ListRunners handles the list builder runners request +func (h *handlers) ListRunners(c echo.Context) error { + ctx := log.Logger.WithContext(c.Request().Context()) + + var req types.ListBuilderRunnersRequest + err := utils.BindValidate(c, &req) + if err != nil { + log.Error().Err(err).Msg("Bind and validate request body failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeBadRequest, fmt.Sprintf("Bind and validate request body failed: %v", err)) + } + req.Pagination = utils.NormalizePagination(req.Pagination) + + builderService := h.builderServiceFactory.New() + _, err = builderService.GetByRepositoryID(ctx, req.RepositoryID) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + log.Error().Err(err).Int64("id", req.RepositoryID).Msg("Get builder by repository id failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("Get builder by repository id failed: %v", err)) + } + runnerObjs, total, err := builderService.ListRunners(ctx, req.ID, req.Pagination, req.Sortable) + if err != nil { + log.Error().Err(err).Msg("List builder runners failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("List builder runners failed: %v", err)) + } + var resp = make([]any, 0, len(runnerObjs)) + for _, runner := range runnerObjs { + platforms := []enums.OciPlatform{} + for _, p := range strings.Split(runner.BuildkitPlatforms, ",") { + platforms = append(platforms, enums.OciPlatform(p)) + } + resp = append(resp, types.BuilderRunnerItem{ + ID: runner.ID, + BuilderID: runner.BuilderID, + Log: runner.Log, + Status: runner.Status, + Tag: runner.Tag, + BuildkitPlatforms: platforms, + CreatedAt: runner.CreatedAt.Format(consts.DefaultTimePattern), + UpdatedAt: runner.UpdatedAt.Format(consts.DefaultTimePattern), + }) + } + return c.JSON(http.StatusOK, types.CommonList{Total: total, Items: resp}) +} diff --git a/pkg/handlers/builders/handler.go b/pkg/handlers/builders/handler.go index 3eee3563..1c905e4c 100644 --- a/pkg/handlers/builders/handler.go +++ b/pkg/handlers/builders/handler.go @@ -35,6 +35,8 @@ type Handlers interface { GetBuilder(c echo.Context) error // PutBuilder handles the put builder request PutBuilder(c echo.Context) error + // ListRunners handles the list builder runners request + ListRunners(c echo.Context) error } var _ Handlers = &handlers{} @@ -95,10 +97,11 @@ type factory struct{} func (f factory) Initialize(e *echo.Echo) error { builderGroup := e.Group(consts.APIV1+"/repositories/:repository_id/builders", middlewares.AuthWithConfig(middlewares.AuthConfig{})) - webhookHandler := handlerNew() - builderGroup.POST("/", webhookHandler.PostBuilder) - builderGroup.GET("/:id", webhookHandler.GetBuilder) - builderGroup.PUT("/:id", webhookHandler.PutBuilder) + handler := handlerNew() + builderGroup.POST("/", handler.PostBuilder) + builderGroup.GET("/:id", handler.GetBuilder) + builderGroup.PUT("/:id", handler.PutBuilder) + builderGroup.GET("/:id/runners/", handler.GetBuilder) return nil } diff --git a/pkg/handlers/coderepos/coderepos_get.go b/pkg/handlers/coderepos/coderepos_get.go new file mode 100644 index 00000000..0506b01a --- /dev/null +++ b/pkg/handlers/coderepos/coderepos_get.go @@ -0,0 +1,80 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package coderepos + +import ( + "errors" + "fmt" + "net/http" + + "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" + "gorm.io/gorm" + + "github.com/go-sigma/sigma/pkg/consts" + "github.com/go-sigma/sigma/pkg/types" + "github.com/go-sigma/sigma/pkg/utils" + "github.com/go-sigma/sigma/pkg/xerrors" +) + +// Get get code repository by id +// @Summary Get code repository by id +// @security BasicAuth +// @Tags CodeRepository +// @Accept json +// @Produce json +// @Router /coderepos/{provider}/repos/{id} [get] +// @Param provider path string true "search code repository with provider" +// @Param id path string true "code repository id" +// @Success 200 {object} types.CodeRepositoryItem +// @Failure 500 {object} xerrors.ErrCode +func (h *handlers) Get(c echo.Context) error { + ctx := log.Logger.WithContext(c.Request().Context()) + + var req types.GetCodeRepositoryRequest + err := utils.BindValidate(c, &req) + if err != nil { + log.Error().Err(err).Msg("Bind and validate request body failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeBadRequest, fmt.Sprintf("Bind and validate request body failed: %v", err)) + } + codeRepositoryService := h.codeRepositoryServiceFactory.New() + codeRepositoryObj, err := codeRepositoryService.Get(ctx, req.ID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + log.Error().Err(err).Str("provider", req.Provider.String()).Int64("id", req.ID).Msg("Code repository not found") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeNotFound, fmt.Sprintf("Code repository(%d) not found: %s", req.ID, err)) + } + log.Error().Err(err).Int64("repositoryID", req.ID).Int64("id", req.ID).Msg("Get code repository failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("Code repository(%d) not found: %s", req.ID, err)) + } + if codeRepositoryObj.User3rdParty.Provider != req.Provider { + log.Error().Err(err).Str("provider", req.Provider.String()).Int64("id", req.ID).Msg("Code repository not found") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeNotFound, fmt.Sprintf("Code repository(%d) not found", req.ID)) + } + + return c.JSON(http.StatusOK, types.CodeRepositoryItem{ + ID: codeRepositoryObj.ID, + RepositoryID: codeRepositoryObj.RepositoryID, + Name: codeRepositoryObj.Name, + OwnerID: codeRepositoryObj.OwnerID, + Owner: codeRepositoryObj.Owner, + IsOrg: codeRepositoryObj.IsOrg, + CloneUrl: codeRepositoryObj.CloneUrl, + SshUrl: codeRepositoryObj.SshUrl, + OciRepoCount: codeRepositoryObj.OciRepoCount, + CreatedAt: codeRepositoryObj.CreatedAt.Format(consts.DefaultTimePattern), + UpdatedAt: codeRepositoryObj.UpdatedAt.Format(consts.DefaultTimePattern), + }) +} diff --git a/pkg/handlers/coderepos/handler.go b/pkg/handlers/coderepos/handler.go index 310051ac..376560f2 100644 --- a/pkg/handlers/coderepos/handler.go +++ b/pkg/handlers/coderepos/handler.go @@ -31,6 +31,8 @@ import ( type Handlers interface { // List list all of the code repositories List(c echo.Context) error + // Get get code repository by id + Get(c echo.Context) error // ListOwner list all of the code repository owner ListOwners(c echo.Context) error // ListBranches ... @@ -111,6 +113,7 @@ func (f factory) Initialize(e *echo.Echo) error { codeRepositoryHandler := handlerNew() codereposGroup.GET("/providers", codeRepositoryHandler.Providers) codereposGroup.GET("/:provider", codeRepositoryHandler.List) + codereposGroup.GET("/:provider/repos/:id", codeRepositoryHandler.Get) codereposGroup.GET("/:provider/user3rdparty", codeRepositoryHandler.User3rdParty) codereposGroup.GET("/:provider/resync", codeRepositoryHandler.Resync) codereposGroup.GET("/:provider/owners", codeRepositoryHandler.ListOwners) diff --git a/pkg/types/builder.go b/pkg/types/builder.go index 5b9dbffd..96fc17cd 100644 --- a/pkg/types/builder.go +++ b/pkg/types/builder.go @@ -153,3 +153,27 @@ type PutBuilderRequest struct { type PutBuilderRequestSwagger struct { PostOrPutBuilderRequest } + +// ListBuilderRunnersRequest ... +type ListBuilderRunnersRequest struct { + Pagination + Sortable + + ID int64 `json:"id" param:"id" validate:"required,number"` + RepositoryID int64 `json:"repository_id" param:"repository_id" example:"10"` +} + +// BuilderRunnerItem ... +type BuilderRunnerItem struct { + ID int64 `json:"id" example:"10"` + BuilderID int64 + Log []byte + Status enums.BuildStatus + + Tag string + ScmBranch string + BuildkitPlatforms []enums.OciPlatform `json:"buildkit_platforms" example:"linux/amd64"` + + CreatedAt string `json:"created_at" example:"2006-01-02 15:04:05"` + UpdatedAt string `json:"updated_at" example:"2006-01-02 15:04:05"` +} diff --git a/pkg/types/coderepos.go b/pkg/types/coderepos.go index a4cf4482..ee2e5fd2 100644 --- a/pkg/types/coderepos.go +++ b/pkg/types/coderepos.go @@ -51,6 +51,12 @@ type ListCodeRepositoryRequest struct { Name *string `json:"name,omitempty" query:"name" validate:"omitempty,min=1"` } +// GetCodeRepositoryRequest ... +type GetCodeRepositoryRequest struct { + Provider enums.Provider `json:"provider" param:"provider" validate:"required,is_valid_provider"` + ID int64 `json:"id" param:"id" validate:"required,number"` +} + // ListCodeRepositoryOwnerRequest .... type ListCodeRepositoryOwnerRequest struct { Provider enums.Provider `json:"provider" param:"provider" validate:"required,is_valid_provider"` diff --git a/pkg/types/enums/enums.go b/pkg/types/enums/enums.go index a1c60b43..b9cea36d 100644 --- a/pkg/types/enums/enums.go +++ b/pkg/types/enums/enums.go @@ -71,6 +71,8 @@ type CacheType string // CacheKey x ENUM( // redis, +// kafka, +// database, // ) type WorkQueueType string diff --git a/pkg/types/enums/enums_enum.go b/pkg/types/enums/enums_enum.go index 3f45e101..bbe8afc3 100644 --- a/pkg/types/enums/enums_enum.go +++ b/pkg/types/enums/enums_enum.go @@ -2003,6 +2003,10 @@ func (x WebhookResourceType) Value() (driver.Value, error) { const ( // WorkQueueTypeRedis is a WorkQueueType of type redis. WorkQueueTypeRedis WorkQueueType = "redis" + // WorkQueueTypeKafka is a WorkQueueType of type kafka. + WorkQueueTypeKafka WorkQueueType = "kafka" + // WorkQueueTypeDatabase is a WorkQueueType of type database. + WorkQueueTypeDatabase WorkQueueType = "database" ) var ErrInvalidWorkQueueType = errors.New("not a valid WorkQueueType") @@ -2020,7 +2024,9 @@ func (x WorkQueueType) IsValid() bool { } var _WorkQueueTypeValue = map[string]WorkQueueType{ - "redis": WorkQueueTypeRedis, + "redis": WorkQueueTypeRedis, + "kafka": WorkQueueTypeKafka, + "database": WorkQueueTypeDatabase, } // ParseWorkQueueType attempts to convert a string to a WorkQueueType. diff --git a/pkg/workq/database/consumer.go b/pkg/workq/database/consumer.go new file mode 100644 index 00000000..f58a7783 --- /dev/null +++ b/pkg/workq/database/consumer.go @@ -0,0 +1,95 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package database + +import ( + "context" + "path" + "reflect" + + "github.com/google/uuid" + "github.com/rs/zerolog/log" + + "github.com/go-sigma/sigma/pkg/configs" + "github.com/go-sigma/sigma/pkg/dal/dao" + "github.com/go-sigma/sigma/pkg/types/enums" + "github.com/go-sigma/sigma/pkg/workq" +) + +func init() { + workq.ConsumerClientFactories[path.Base(reflect.TypeOf(consumerFactory{}).PkgPath())] = &consumerFactory{} +} + +type consumerFactory struct{} + +// NewWorkQueueConsumer ... +func (f consumerFactory) New(_ configs.Configuration) error { + for topic, c := range workq.TopicConsumers { + go func(consumer workq.Consumer, topic string) { + handler := &consumerHandler{ + processingSemaphore: make(chan struct{}, consumer.Concurrency), + consumer: consumer, + } + handler.Consume(topic) + }(c, topic) + } + return nil +} + +type consumerHandler struct { + processingSemaphore chan struct{} + consumer workq.Consumer +} + +func (h *consumerHandler) Consume(topic string) { + for { + err := h.consume() + if err != nil { + log.Error().Err(err).Msg("Consume topic failed") + } + } +} + +func (h *consumerHandler) consume() error { + h.processingSemaphore <- struct{}{} + defer func() { + <-h.processingSemaphore + }() + workQueueService := dao.NewWorkQueueServiceFactory().New() + daoCtx := log.Logger.WithContext(context.Background()) + wq, err := workQueueService.Get(daoCtx) + if err != nil { + return err + } + newVersion := uuid.New().String() + err = workQueueService.UpdateStatus(daoCtx, wq.ID, wq.Version, newVersion, enums.TaskCommonStatusDoing) + if err != nil { + return err + } + ctx := context.Background() + if h.consumer.Timeout != 0 { + var ctxCancel context.CancelFunc + ctx, ctxCancel = context.WithTimeout(ctx, h.consumer.Timeout) + defer ctxCancel() + } + err = h.consumer.Handler(ctx, wq.Payload) + if err != nil { + wq.Times++ + if wq.Times < h.consumer.MaxRetry { + return workQueueService.UpdateStatus(daoCtx, wq.ID, newVersion, uuid.New().String(), enums.TaskCommonStatusPending) + } + } + return nil +} diff --git a/pkg/workq/database/producer.go b/pkg/workq/database/producer.go new file mode 100644 index 00000000..dcae1ed5 --- /dev/null +++ b/pkg/workq/database/producer.go @@ -0,0 +1,58 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package database + +import ( + "context" + "path" + "reflect" + + "github.com/google/uuid" + + "github.com/go-sigma/sigma/pkg/configs" + "github.com/go-sigma/sigma/pkg/dal/dao" + "github.com/go-sigma/sigma/pkg/dal/models" + "github.com/go-sigma/sigma/pkg/utils" + "github.com/go-sigma/sigma/pkg/workq" +) + +func init() { + workq.ProducerClientFactories[path.Base(reflect.TypeOf(producerFactory{}).PkgPath())] = &producerFactory{} +} + +type producer struct { + workQueueServiceFactory dao.WorkQueueServiceFactory +} + +type producerFactory struct{} + +// NewWorkQueueProducer ... +func (f producerFactory) New(_ configs.Configuration) (workq.WorkQueueProducer, error) { + p := &producer{ + workQueueServiceFactory: dao.NewWorkQueueServiceFactory(), + } + return p, nil +} + +// Produce ... +func (p *producer) Produce(ctx context.Context, topic string, payload any) error { + wq := &models.WorkQueue{ + Topic: topic, + Payload: utils.MustMarshal(payload), + Version: uuid.New().String(), + } + workQueueService := p.workQueueServiceFactory.New() + return workQueueService.Create(ctx, wq) +} diff --git a/pkg/workq/kafka/config.go b/pkg/workq/kafka/config.go new file mode 100644 index 00000000..787d05ab --- /dev/null +++ b/pkg/workq/kafka/config.go @@ -0,0 +1,34 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kafka + +import ( + "time" + + "github.com/IBM/sarama" + + "github.com/go-sigma/sigma/pkg/configs" +) + +// Config ... +func Config(cfg configs.Configuration) *sarama.Config { + config := sarama.NewConfig() + config.Producer.Return.Successes = true + config.Producer.RequiredAcks = sarama.WaitForAll + config.Producer.Retry.Max = 5 + config.Consumer.Group.Session.Timeout = 10 * time.Second + config.Consumer.Group.Heartbeat.Interval = 3 * time.Second + return config +} diff --git a/pkg/workq/kafka/consumer.go b/pkg/workq/kafka/consumer.go new file mode 100644 index 00000000..a07744cf --- /dev/null +++ b/pkg/workq/kafka/consumer.go @@ -0,0 +1,148 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kafka + +import ( + "context" + "encoding/json" + "fmt" + "path" + "reflect" + "time" + + "github.com/IBM/sarama" + "github.com/rs/zerolog/log" + + "github.com/go-sigma/sigma/pkg/configs" + "github.com/go-sigma/sigma/pkg/consts" + "github.com/go-sigma/sigma/pkg/utils" + "github.com/go-sigma/sigma/pkg/workq" +) + +// ConsumerGroupHandler ... +type ConsumerGroupHandler struct { + processingSemaphore chan struct{} + consumer workq.Consumer + producer sarama.SyncProducer +} + +// Setup ... +func (h *ConsumerGroupHandler) Setup(session sarama.ConsumerGroupSession) error { + return nil +} + +// Cleanup ... +func (h *ConsumerGroupHandler) Cleanup(session sarama.ConsumerGroupSession) error { + return nil +} + +// ConsumeClaim ... +func (h *ConsumerGroupHandler) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { + for { + h.processingSemaphore <- struct{}{} + select { + case message := <-claim.Messages(): + go func() { + defer func() { + <-h.processingSemaphore + }() + var msg MessageWrapper + err := json.Unmarshal(message.Value, &msg) + if err != nil { + log.Error().Err(err).Str("message", string(message.Value)).Msg("Unmarshal message failed") + return + } + ctx := session.Context() + if h.consumer.Timeout != 0 { + var ctxCancel context.CancelFunc + ctx, ctxCancel = context.WithTimeout(session.Context(), h.consumer.Timeout) + defer ctxCancel() + } + err = h.consumer.Handler(ctx, message.Value) + if err != nil { + msg.Times++ + if msg.Times < h.consumer.MaxRetry { + _, _, err := h.producer.SendMessage(&sarama.ProducerMessage{ + Topic: message.Topic, + Value: sarama.ByteEncoder(utils.MustMarshal(msg)), + }) + if err != nil { + log.Error().Err(err).Str("topic", message.Topic).Str("payload", string(utils.MustMarshal(msg))).Msg("Resend message failed") + return + } + } + } + }() + case <-session.Context().Done(): + return nil + } + } +} + +// MessageWrapper ... +type MessageWrapper struct { + Times int + Payload []byte +} + +func init() { + workq.ConsumerClientFactories[path.Base(reflect.TypeOf(consumerFactory{}).PkgPath())] = &consumerFactory{} +} + +type consumerFactory struct{} + +// NewWorkQueueConsumer ... +func (f consumerFactory) New(_ configs.Configuration) error { + config := sarama.NewConfig() + config.Producer.Return.Successes = true + config.Producer.RequiredAcks = sarama.WaitForAll + config.Producer.Retry.Max = 5 + config.Consumer.Group.Session.Timeout = 10 * time.Second + config.Consumer.Group.Heartbeat.Interval = 3 * time.Second + config.Consumer.Group.Rebalance.Strategy = sarama.NewBalanceStrategyRoundRobin() + + client, err := sarama.NewClient([]string{}, config) + if err != nil { + return err + } + + producer, err := sarama.NewSyncProducerFromClient(client) + if err != nil { + log.Error().Err(err).Msg("Create producer failed") + } + + for topic, c := range workq.TopicConsumers { + consumerGroup, err := sarama.NewConsumerGroupFromClient(fmt.Sprintf("%s-%s", consts.AppName, topic), client) + if err != nil { + return err + } + go func(consumer workq.Consumer, topic string) { + for { + handler := &ConsumerGroupHandler{ + processingSemaphore: make(chan struct{}, consumer.Concurrency), + consumer: consumer, + producer: producer, + } + err := consumerGroup.Consume(context.Background(), []string{topic}, handler) + if err != nil { + log.Error().Err(err).Str("topic", topic).Msg("Consume topics failed") + return + } + } + }(c, topic) + } + + return nil +} diff --git a/pkg/workq/kafka/producer.go b/pkg/workq/kafka/producer.go new file mode 100644 index 00000000..2dfa8952 --- /dev/null +++ b/pkg/workq/kafka/producer.go @@ -0,0 +1,71 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kafka + +import ( + "context" + "path" + "reflect" + + "github.com/IBM/sarama" + "github.com/rs/zerolog/log" + + "github.com/go-sigma/sigma/pkg/configs" + "github.com/go-sigma/sigma/pkg/utils" + "github.com/go-sigma/sigma/pkg/workq" +) + +func init() { + workq.ProducerClientFactories[path.Base(reflect.TypeOf(producerFactory{}).PkgPath())] = &producerFactory{} +} + +type producerFactory struct{} + +// NewWorkQueueProducer ... +func (f producerFactory) New(_ configs.Configuration) (workq.WorkQueueProducer, error) { + config := sarama.NewConfig() + config.Producer.Return.Successes = true + config.Producer.RequiredAcks = sarama.WaitForAll + config.Producer.Retry.Max = 5 + client, err := sarama.NewClient([]string{}, config) + if err != nil { + return nil, err + } + + p, err := sarama.NewSyncProducerFromClient(client) + if err != nil { + log.Error().Err(err).Msg("Create producer failed") + return nil, err + } + return &producer{ + producer: p, + }, nil +} + +type producer struct { + producer sarama.SyncProducer +} + +func (p *producer) Produce(_ context.Context, topic string, payload any) error { + message := MessageWrapper{ + Times: 0, + Payload: utils.MustMarshal(payload), + } + _, _, err := p.producer.SendMessage(&sarama.ProducerMessage{ + Topic: topic, + Value: sarama.ByteEncoder(utils.MustMarshal(message)), + }) + return err +} diff --git a/pkg/workq/workq.go b/pkg/workq/workq.go new file mode 100644 index 00000000..a7a613ec --- /dev/null +++ b/pkg/workq/workq.go @@ -0,0 +1,92 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package workq + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/go-sigma/sigma/pkg/configs" +) + +// Message ... +type Message struct { + Topic string + Payload []byte +} + +type Consumer struct { + Handler func(ctx context.Context, payload []byte) error + Concurrency int + MaxRetry int + Timeout time.Duration +} + +var TopicConsumers = make(map[string]Consumer) + +// WorkQueueProducer ... +type WorkQueueProducer interface { + // Produce ... + Produce(ctx context.Context, topic string, payload any) error +} + +// WorkQueueConsumer ... +type WorkQueueConsumer interface { + // Consume ... + Run(ctx context.Context) +} + +// ConsumerClientFactory ... +type ConsumerClientFactory interface { + New(config configs.Configuration) error +} + +// ProducerClientFactory ... +type ProducerClientFactory interface { + New(config configs.Configuration) (WorkQueueProducer, error) +} + +// ConsumerClientFactories ... +var ConsumerClientFactories = make(map[string]ConsumerClientFactory, 5) + +// ProducerClientFactories ... +var ProducerClientFactories = make(map[string]ProducerClientFactory, 5) + +// Initialize ... +func Initialize(config configs.Configuration) error { + consumerClientFactory, ok := ConsumerClientFactories[strings.ToLower(config.WorkQueue.Type.String())] + if !ok { + return fmt.Errorf("Work queue consumer(%s) not support", config.WorkQueue.Type.String()) + } + err := consumerClientFactory.New(config) + if err != nil { + return err + } + producerClientFactory, ok := ProducerClientFactories[strings.ToLower(config.WorkQueue.Type.String())] + if !ok { + return fmt.Errorf("Work queue producer(%s) not support", config.WorkQueue.Type.String()) + } + producer, err := producerClientFactory.New(config) + if err != nil { + return err + } + ProducerClient = producer + return nil +} + +// ProducerClient ... +var ProducerClient WorkQueueProducer diff --git a/web/src/App.tsx b/web/src/App.tsx index c1a9c074..0f89953c 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -30,6 +30,7 @@ import NamespaceDaemonTasks from "./pages/Namespace/DaemonTask"; import CodeRepositoryHome from './pages/CodeRepository'; import CodeRepositoryList from './pages/CodeRepository/List'; +import BuilderRunner from './pages/CodeRepository/BuilderRunner'; import BuildersSetup from './pages/Builder/Setup'; @@ -70,6 +71,7 @@ export default function App() { } /> } /> } /> + } /> } /> } /> diff --git a/web/src/pages/Builder/Setup.tsx b/web/src/pages/Builder/Setup.tsx index 2cafe3ef..c7971706 100644 --- a/web/src/pages/Builder/Setup.tsx +++ b/web/src/pages/Builder/Setup.tsx @@ -249,6 +249,32 @@ export default function ({ localServer }: { localServer: string }) { const data = response.data as ICodeRepositoryBranchList; setCodeRepositoryBranchList(data.items); setCodeRepositoryBranchFilteredList(data.items); + if (searchParams.get('code_repository_branch_name') !== null) { + for (let i = 0; i < data.total; i++) { + if (data.items[i].name === searchParams.get('code_repository_branch_name')) { + setCodeRepositoryBranchSelected(data.items[i]); + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + code_repository_branch_name: data.items[i].name, + code_repository_branch_id: data.items[i].id.toString(), + }); + break; + } + } + } + if (searchParams.get('cron_branch_name') !== null) { + for (let i = 0; i < data.total; i++) { + if (data.items[i].name === searchParams.get('cron_branch_name')) { + setCodeRepositoryBranchSelected(data.items[i]); + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + cron_branch_name: data.items[i].name, + cron_branch_id: data.items[i].id.toString(), + }); + break; + } + } + } } else { const errorcode = response.data as IHTTPError; Toast({ level: "warning", title: errorcode.title, message: errorcode.description }); @@ -445,6 +471,15 @@ export default function ({ localServer }: { localServer: string }) { builder_source: builderItem.source, cron_enabled: builderItem.cron_rule !== null ? "true" : "false", }); + if (builderItem.scm_branch !== undefined) { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + code_repository_branch_name: builderItem.scm_branch || '', + }); + } + if (builderItem.code_repository_id !== undefined) { + + } let ps = ""; let platforms: { id: number; @@ -475,6 +510,15 @@ export default function ({ localServer }: { localServer: string }) { setCronTagTemplate(builderItem.cron_tag_template || ''); if (builderItem.source === 'SelfCodeRepository') { setCronBranch(builderItem.cron_branch || ''); + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + cron_branch_name: builderItem.cron_branch || '', + }); + } else if (builderItem.source === 'CodeRepository') { + setSearchParams({ + ...Object.fromEntries(searchParams.entries()), + cron_branch_name: builderItem.cron_branch || '', + }); } } } diff --git a/web/src/pages/CodeRepository/BuilderRunner.tsx b/web/src/pages/CodeRepository/BuilderRunner.tsx new file mode 100644 index 00000000..9de2e248 --- /dev/null +++ b/web/src/pages/CodeRepository/BuilderRunner.tsx @@ -0,0 +1,21 @@ +/** + * Copyright 2023 sigma + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default function ({ localServer }: { localServer: string }) { + return ( +
+ ) +}