From c8817cc5c413a357b0e88227736ebfc6da5d6d64 Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Wed, 17 Jul 2024 12:09:14 +0000 Subject: [PATCH] TEST: build "portal" separately --- v2.10.2/nginx-photon/rockcraft.yaml | 53 -- v2.10.2/portal/rockcraft.yaml | 1 - v2.10.2/redis-photon/rockcraft.yaml | 64 -- v2.10.2/registry-photon/redis.patch | 883 -------------------- v2.10.2/registry-photon/rockcraft.yaml | 84 -- v2.10.2/trivy-adapter-photon/rockcraft.yaml | 94 --- 6 files changed, 1179 deletions(-) delete mode 100644 v2.10.2/nginx-photon/rockcraft.yaml delete mode 100644 v2.10.2/redis-photon/rockcraft.yaml delete mode 100644 v2.10.2/registry-photon/redis.patch delete mode 100644 v2.10.2/registry-photon/rockcraft.yaml delete mode 100644 v2.10.2/trivy-adapter-photon/rockcraft.yaml diff --git a/v2.10.2/nginx-photon/rockcraft.yaml b/v2.10.2/nginx-photon/rockcraft.yaml deleted file mode 100644 index 3e64a61..0000000 --- a/v2.10.2/nginx-photon/rockcraft.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: nginx -summary: Rock replacement for the Harbor Nginx image. -description: > - This rock is a drop in replacement for the - docker.io/goharbor/nginx-photon:v2.10.2 image. -# Based on the following: -# https://github.com/goharbor/harbor/tree/v2.10.2/make/photon/nginx -version: v2.10.2 -license: Apache-2.0 - -base: ubuntu@22.04 -build-base: ubuntu@22.04 -platforms: - amd64: - arm64: - -services: - nginx: - command: nginx -g daemon off - override: replace - startup: enabled - user: nginx - group: nginx - -parts: - nginx-user: - plugin: nil - overlay-script: | - groupadd -R $CRAFT_OVERLAY -g 10000 nginx - useradd -R $CRAFT_OVERLAY -u 10000 -g 10000 \ - -d /home/nginx -s /bin/bash -m nginx - - nginx: - after: [nginx-user] - plugin: nil - stage-packages: [nginx] - override-build: | - chown -R 10000:10000 $CRAFT_PART_INSTALL/etc/nginx - - mkdir -p $CRAFT_PART_INSTALL/var/log/nginx - chown -R 10000:10000 $CRAFT_PART_INSTALL/var/log/nginx - - # The reference image creates these symlinks, however a volume is expected - # to be mounted at the given location. - # - # Also, the github image builder job fails when having these links: - # https://paste.ubuntu.com/p/zsDHyR2NY4/plain/ - # - # ln -sf /dev/stdout $CRAFT_PART_INSTALL/var/log/nginx/access.log - # ln -sf /dev/stderr $CRAFT_PART_INSTALL/var/log/nginx/error.log - - # TODO: the upstream image defines a healthcheck, stop signal and a volume, - # should/can we do the same? diff --git a/v2.10.2/portal/rockcraft.yaml b/v2.10.2/portal/rockcraft.yaml index 87cc99b..04d454c 100644 --- a/v2.10.2/portal/rockcraft.yaml +++ b/v2.10.2/portal/rockcraft.yaml @@ -72,7 +72,6 @@ parts: export NPM_CONFIG_REGISTRY=https://registry.npmjs.org export PATH="$PATH:$CRAFT_PART_BUILD/src/portal/node_modules/.bin" - npm install ng-swagger-gen npm install --unsafe-perm npm run generate-build-timestamp diff --git a/v2.10.2/redis-photon/rockcraft.yaml b/v2.10.2/redis-photon/rockcraft.yaml deleted file mode 100644 index 56fa402..0000000 --- a/v2.10.2/redis-photon/rockcraft.yaml +++ /dev/null @@ -1,64 +0,0 @@ -name: redis -summary: Rock replacement for the Harbor Redis image. -description: > - This rock is a drop in replacement for the - docker.io/goharbor/redis-photon:v2.10.2 image. -# Based on the following: -# https://github.com/goharbor/harbor/tree/v2.10.2/make/photon/redis -version: v2.10.2 -license: Apache-2.0 - -base: ubuntu@22.04 -build-base: ubuntu@22.04 -platforms: - amd64: - arm64: - -package-repositories: - - type: apt - components: [main] - suites: [jammy] - key-id: 54318FA4052D1E61A6B6F7BB5F4349D6BF53AA0C - url: https://packages.redis.io/deb - priority: always - -services: - redis: - command: redis-server /etc/redis.conf - override: replace - startup: enabled - user: redis - group: redis - # working-dir: /var/lib/redis - -parts: - redis-user: - plugin: nil - overlay-script: | - groupadd -R $CRAFT_OVERLAY -g 999 redis - useradd -R $CRAFT_OVERLAY -u 999 -g 999 -c "Redis Database Server" \ - -d /var/lib/redis -s /sbin/nologin -m redis - - image-prep: - after: [redis-user] - plugin: nil - source-type: git - source: https://github.com/goharbor/harbor - source-tag: v2.10.2 - source-depth: 1 - override-build: | - mkdir -p $CRAFT_PART_INSTALL/usr/bin - mkdir -p $CRAFT_PART_INSTALL/etc - cd $CRAFT_PART_SRC - cp ./make/photon/redis/docker-healthcheck $CRAFT_PART_INSTALL/usr/bin - cp ./make/photon/redis/redis.conf $CRAFT_PART_INSTALL/etc/redis.conf - - chown 999:999 $CRAFT_PART_INSTALL/etc/redis.conf - chmod +x $CRAFT_PART_INSTALL/usr/bin/docker-healthcheck - - redis: - after: [image-prep] - plugin: nil - stage-packages: [redis] - # TODO: the upstream image defines a healthcheck and a volume, - # should/can we do the same? diff --git a/v2.10.2/registry-photon/redis.patch b/v2.10.2/registry-photon/redis.patch deleted file mode 100644 index ab4649c..0000000 --- a/v2.10.2/registry-photon/redis.patch +++ /dev/null @@ -1,883 +0,0 @@ -diff --git a/configuration/configuration.go b/configuration/configuration.go -index 7076df85d4..3e74330321 100644 ---- a/configuration/configuration.go -+++ b/configuration/configuration.go -@@ -168,6 +168,9 @@ type Configuration struct { - // Addr specifies the the redis instance available to the application. - Addr string `yaml:"addr,omitempty"` - -+ // SentinelMasterSet specifies the the redis sentinel master set name. -+ SentinelMasterSet string `yaml:"sentinelMasterSet,omitempty"` -+ - // Password string to use when making a connection. - Password string `yaml:"password,omitempty"` - -diff --git a/registry/handlers/app.go b/registry/handlers/app.go -index bf56cea22a..4a7cee9a2e 100644 ---- a/registry/handlers/app.go -+++ b/registry/handlers/app.go -@@ -3,6 +3,7 @@ package handlers - import ( - "context" - "crypto/rand" -+ "errors" - "expvar" - "fmt" - "math" -@@ -16,6 +17,7 @@ import ( - "strings" - "time" - -+ "github.com/FZambia/sentinel" - "github.com/distribution/reference" - "github.com/docker/distribution" - "github.com/docker/distribution/configuration" -@@ -499,6 +501,45 @@ func (app *App) configureRedis(configuration *configuration.Configuration) { - return - } - -+ var getRedisAddr func() (string, error) -+ var testOnBorrow func(c redis.Conn, t time.Time) error -+ if configuration.Redis.SentinelMasterSet != "" { -+ sntnl := &sentinel.Sentinel{ -+ Addrs: strings.Split(configuration.Redis.Addr, ","), -+ MasterName: configuration.Redis.SentinelMasterSet, -+ Dial: func(addr string) (redis.Conn, error) { -+ c, err := redis.DialTimeout("tcp", addr, -+ configuration.Redis.DialTimeout, -+ configuration.Redis.ReadTimeout, -+ configuration.Redis.WriteTimeout) -+ if err != nil { -+ return nil, err -+ } -+ return c, nil -+ }, -+ } -+ getRedisAddr = func() (string, error) { -+ return sntnl.MasterAddr() -+ } -+ testOnBorrow = func(c redis.Conn, t time.Time) error { -+ if !sentinel.TestRole(c, "master") { -+ return errors.New("role check failed") -+ } -+ return nil -+ } -+ -+ } else { -+ getRedisAddr = func() (string, error) { -+ return configuration.Redis.Addr, nil -+ } -+ testOnBorrow = func(c redis.Conn, t time.Time) error { -+ // TODO(stevvooe): We can probably do something more interesting -+ // here with the health package. -+ _, err := c.Do("PING") -+ return err -+ } -+ } -+ - pool := &redis.Pool{ - Dial: func() (redis.Conn, error) { - // TODO(stevvooe): Yet another use case for contextual timing. -@@ -514,8 +555,11 @@ func (app *App) configureRedis(configuration *configuration.Configuration) { - } - } - -- conn, err := redis.DialTimeout("tcp", -- configuration.Redis.Addr, -+ redisAddr, err := getRedisAddr() -+ if err != nil { -+ return nil, err -+ } -+ conn, err := redis.DialTimeout("tcp", redisAddr, - configuration.Redis.DialTimeout, - configuration.Redis.ReadTimeout, - configuration.Redis.WriteTimeout) -@@ -547,16 +591,11 @@ func (app *App) configureRedis(configuration *configuration.Configuration) { - done(nil) - return conn, nil - }, -- MaxIdle: configuration.Redis.Pool.MaxIdle, -- MaxActive: configuration.Redis.Pool.MaxActive, -- IdleTimeout: configuration.Redis.Pool.IdleTimeout, -- TestOnBorrow: func(c redis.Conn, t time.Time) error { -- // TODO(stevvooe): We can probably do something more interesting -- // here with the health package. -- _, err := c.Do("PING") -- return err -- }, -- Wait: false, // if a connection is not available, proceed without cache. -+ MaxIdle: configuration.Redis.Pool.MaxIdle, -+ MaxActive: configuration.Redis.Pool.MaxActive, -+ IdleTimeout: configuration.Redis.Pool.IdleTimeout, -+ TestOnBorrow: testOnBorrow, -+ Wait: false, // if a connection is not available, proceed without cache. - } - - app.redis = pool -diff --git a/registry/handlers/app_test.go b/registry/handlers/app_test.go -index 60a57e6c15..8a644d83d8 100644 ---- a/registry/handlers/app_test.go -+++ b/registry/handlers/app_test.go -@@ -140,7 +140,29 @@ func TestAppDispatcher(t *testing.T) { - // TestNewApp covers the creation of an application via NewApp with a - // configuration. - func TestNewApp(t *testing.T) { -- ctx := context.Background() -+ -+ config := configuration.Configuration{ -+ Storage: configuration.Storage{ -+ "testdriver": nil, -+ "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ -+ "enabled": false, -+ }}, -+ }, -+ Auth: configuration.Auth{ -+ // For now, we simply test that new auth results in a viable -+ // application. -+ "silly": { -+ "realm": "realm-test", -+ "service": "service-test", -+ }, -+ }, -+ } -+ runAppWithConfig(t, config) -+} -+ -+// TestNewApp covers the creation of an application via NewApp with a -+// configuration(with redis). -+func TestNewAppWithRedis(t *testing.T) { - config := configuration.Configuration{ - Storage: configuration.Storage{ - "testdriver": nil, -@@ -157,7 +179,38 @@ func TestNewApp(t *testing.T) { - }, - }, - } -+ config.Redis.Addr = "127.0.0.1:6379" -+ config.Redis.DB = 0 -+ runAppWithConfig(t, config) -+} - -+// TestNewApp covers the creation of an application via NewApp with a -+// configuration(with redis sentinel cluster). -+func TestNewAppWithRedisSentinelCluster(t *testing.T) { -+ config := configuration.Configuration{ -+ Storage: configuration.Storage{ -+ "testdriver": nil, -+ "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ -+ "enabled": false, -+ }}, -+ }, -+ Auth: configuration.Auth{ -+ // For now, we simply test that new auth results in a viable -+ // application. -+ "silly": { -+ "realm": "realm-test", -+ "service": "service-test", -+ }, -+ }, -+ } -+ config.Redis.Addr = "192.168.0.11:26379,192.168.0.12:26379" -+ config.Redis.DB = 0 -+ config.Redis.SentinelMasterSet = "mymaster" -+ runAppWithConfig(t, config) -+} -+ -+func runAppWithConfig(t *testing.T, config configuration.Configuration) { -+ ctx := context.Background() - // Mostly, with this test, given a sane configuration, we are simply - // ensuring that NewApp doesn't panic. We might want to tweak this - // behavior. -diff --git a/vendor.conf b/vendor.conf -index 33fe616b76..a8d8f58bc6 100644 ---- a/vendor.conf -+++ b/vendor.conf -@@ -51,3 +51,4 @@ gopkg.in/yaml.v2 v2.2.1 - rsc.io/letsencrypt e770c10b0f1a64775ae91d240407ce00d1a5bdeb https://github.com/dmcgowan/letsencrypt.git - github.com/opencontainers/go-digest ea51bea511f75cfa3ef6098cc253c5c3609b037a # v1.0.0 - github.com/opencontainers/image-spec 67d2d5658fe0476ab9bf414cec164077ebff3920 # v1.0.2 -+github.com/FZambia/sentinel 5585739eb4b6478aa30161866ccf9ce0ef5847c7 https://github.com/jeremyxu2010/sentinel.git -diff --git a/vendor/github.com/FZambia/sentinel/LICENSE b/vendor/github.com/FZambia/sentinel/LICENSE -new file mode 100644 -index 0000000000..8dada3edaf ---- /dev/null -+++ b/vendor/github.com/FZambia/sentinel/LICENSE -@@ -0,0 +1,201 @@ -+ Apache License -+ Version 2.0, January 2004 -+ http://www.apache.org/licenses/ -+ -+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -+ -+ 1. Definitions. -+ -+ "License" shall mean the terms and conditions for use, reproduction, -+ and distribution as defined by Sections 1 through 9 of this document. -+ -+ "Licensor" shall mean the copyright owner or entity authorized by -+ the copyright owner that is granting the License. -+ -+ "Legal Entity" shall mean the union of the acting entity and all -+ other entities that control, are controlled by, or are under common -+ control with that entity. For the purposes of this definition, -+ "control" means (i) the power, direct or indirect, to cause the -+ direction or management of such entity, whether by contract or -+ otherwise, or (ii) ownership of fifty percent (50%) or more of the -+ outstanding shares, or (iii) beneficial ownership of such entity. -+ -+ "You" (or "Your") shall mean an individual or Legal Entity -+ exercising permissions granted by this License. -+ -+ "Source" form shall mean the preferred form for making modifications, -+ including but not limited to software source code, documentation -+ source, and configuration files. -+ -+ "Object" form shall mean any form resulting from mechanical -+ transformation or translation of a Source form, including but -+ not limited to compiled object code, generated documentation, -+ and conversions to other media types. -+ -+ "Work" shall mean the work of authorship, whether in Source or -+ Object form, made available under the License, as indicated by a -+ copyright notice that is included in or attached to the work -+ (an example is provided in the Appendix below). -+ -+ "Derivative Works" shall mean any work, whether in Source or Object -+ form, that is based on (or derived from) the Work and for which the -+ editorial revisions, annotations, elaborations, or other modifications -+ represent, as a whole, an original work of authorship. For the purposes -+ of this License, Derivative Works shall not include works that remain -+ separable from, or merely link (or bind by name) to the interfaces of, -+ the Work and Derivative Works thereof. -+ -+ "Contribution" shall mean any work of authorship, including -+ the original version of the Work and any modifications or additions -+ to that Work or Derivative Works thereof, that is intentionally -+ submitted to Licensor for inclusion in the Work by the copyright owner -+ or by an individual or Legal Entity authorized to submit on behalf of -+ the copyright owner. For the purposes of this definition, "submitted" -+ means any form of electronic, verbal, or written communication sent -+ to the Licensor or its representatives, including but not limited to -+ communication on electronic mailing lists, source code control systems, -+ and issue tracking systems that are managed by, or on behalf of, the -+ Licensor for the purpose of discussing and improving the Work, but -+ excluding communication that is conspicuously marked or otherwise -+ designated in writing by the copyright owner as "Not a Contribution." -+ -+ "Contributor" shall mean Licensor and any individual or Legal Entity -+ on behalf of whom a Contribution has been received by Licensor and -+ subsequently incorporated within the Work. -+ -+ 2. Grant of Copyright License. Subject to the terms and conditions of -+ this License, each Contributor hereby grants to You a perpetual, -+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable -+ copyright license to reproduce, prepare Derivative Works of, -+ publicly display, publicly perform, sublicense, and distribute the -+ Work and such Derivative Works in Source or Object form. -+ -+ 3. Grant of Patent License. Subject to the terms and conditions of -+ this License, each Contributor hereby grants to You a perpetual, -+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable -+ (except as stated in this section) patent license to make, have made, -+ use, offer to sell, sell, import, and otherwise transfer the Work, -+ where such license applies only to those patent claims licensable -+ by such Contributor that are necessarily infringed by their -+ Contribution(s) alone or by combination of their Contribution(s) -+ with the Work to which such Contribution(s) was submitted. If You -+ institute patent litigation against any entity (including a -+ cross-claim or counterclaim in a lawsuit) alleging that the Work -+ or a Contribution incorporated within the Work constitutes direct -+ or contributory patent infringement, then any patent licenses -+ granted to You under this License for that Work shall terminate -+ as of the date such litigation is filed. -+ -+ 4. Redistribution. You may reproduce and distribute copies of the -+ Work or Derivative Works thereof in any medium, with or without -+ modifications, and in Source or Object form, provided that You -+ meet the following conditions: -+ -+ (a) You must give any other recipients of the Work or -+ Derivative Works a copy of this License; and -+ -+ (b) You must cause any modified files to carry prominent notices -+ stating that You changed the files; and -+ -+ (c) You must retain, in the Source form of any Derivative Works -+ that You distribute, all copyright, patent, trademark, and -+ attribution notices from the Source form of the Work, -+ excluding those notices that do not pertain to any part of -+ the Derivative Works; and -+ -+ (d) If the Work includes a "NOTICE" text file as part of its -+ distribution, then any Derivative Works that You distribute must -+ include a readable copy of the attribution notices contained -+ within such NOTICE file, excluding those notices that do not -+ pertain to any part of the Derivative Works, in at least one -+ of the following places: within a NOTICE text file distributed -+ as part of the Derivative Works; within the Source form or -+ documentation, if provided along with the Derivative Works; or, -+ within a display generated by the Derivative Works, if and -+ wherever such third-party notices normally appear. The contents -+ of the NOTICE file are for informational purposes only and -+ do not modify the License. You may add Your own attribution -+ notices within Derivative Works that You distribute, alongside -+ or as an addendum to the NOTICE text from the Work, provided -+ that such additional attribution notices cannot be construed -+ as modifying the License. -+ -+ You may add Your own copyright statement to Your modifications and -+ may provide additional or different license terms and conditions -+ for use, reproduction, or distribution of Your modifications, or -+ for any such Derivative Works as a whole, provided Your use, -+ reproduction, and distribution of the Work otherwise complies with -+ the conditions stated in this License. -+ -+ 5. Submission of Contributions. Unless You explicitly state otherwise, -+ any Contribution intentionally submitted for inclusion in the Work -+ by You to the Licensor shall be under the terms and conditions of -+ this License, without any additional terms or conditions. -+ Notwithstanding the above, nothing herein shall supersede or modify -+ the terms of any separate license agreement you may have executed -+ with Licensor regarding such Contributions. -+ -+ 6. Trademarks. This License does not grant permission to use the trade -+ names, trademarks, service marks, or product names of the Licensor, -+ except as required for reasonable and customary use in describing the -+ origin of the Work and reproducing the content of the NOTICE file. -+ -+ 7. Disclaimer of Warranty. Unless required by applicable law or -+ agreed to in writing, Licensor provides the Work (and each -+ Contributor provides its Contributions) on an "AS IS" BASIS, -+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -+ implied, including, without limitation, any warranties or conditions -+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A -+ PARTICULAR PURPOSE. You are solely responsible for determining the -+ appropriateness of using or redistributing the Work and assume any -+ risks associated with Your exercise of permissions under this License. -+ -+ 8. Limitation of Liability. In no event and under no legal theory, -+ whether in tort (including negligence), contract, or otherwise, -+ unless required by applicable law (such as deliberate and grossly -+ negligent acts) or agreed to in writing, shall any Contributor be -+ liable to You for damages, including any direct, indirect, special, -+ incidental, or consequential damages of any character arising as a -+ result of this License or out of the use or inability to use the -+ Work (including but not limited to damages for loss of goodwill, -+ work stoppage, computer failure or malfunction, or any and all -+ other commercial damages or losses), even if such Contributor -+ has been advised of the possibility of such damages. -+ -+ 9. Accepting Warranty or Additional Liability. While redistributing -+ the Work or Derivative Works thereof, You may choose to offer, -+ and charge a fee for, acceptance of support, warranty, indemnity, -+ or other liability obligations and/or rights consistent with this -+ License. However, in accepting such obligations, You may act only -+ on Your own behalf and on Your sole responsibility, not on behalf -+ of any other Contributor, and only if You agree to indemnify, -+ defend, and hold each Contributor harmless for any liability -+ incurred by, or claims asserted against, such Contributor by reason -+ of your accepting any such warranty or additional liability. -+ -+ END OF TERMS AND CONDITIONS -+ -+ APPENDIX: How to apply the Apache License to your work. -+ -+ To apply the Apache License to your work, attach the following -+ boilerplate notice, with the fields enclosed by brackets "{}" -+ replaced with your own identifying information. (Don't include -+ the brackets!) The text should be enclosed in the appropriate -+ comment syntax for the file format. We also recommend that a -+ file or class name and description of purpose be included on the -+ same "printed page" as the copyright notice for easier -+ identification within third-party archives. -+ -+ Copyright {yyyy} {name of copyright owner} -+ -+ 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. -diff --git a/vendor/github.com/FZambia/sentinel/README.md b/vendor/github.com/FZambia/sentinel/README.md -new file mode 100644 -index 0000000000..f544c54ef6 ---- /dev/null -+++ b/vendor/github.com/FZambia/sentinel/README.md -@@ -0,0 +1,39 @@ -+go-sentinel -+=========== -+ -+Redis Sentinel support for [redigo](https://github.com/gomodule/redigo) library. -+ -+Documentation -+------------- -+ -+- [API Reference](http://godoc.org/github.com/FZambia/sentinel) -+ -+Alternative solution -+-------------------- -+ -+You can alternatively configure Haproxy between your application and Redis to proxy requests to Redis master instance if you only need HA: -+ -+``` -+listen redis -+ server redis-01 127.0.0.1:6380 check port 6380 check inter 2s weight 1 inter 2s downinter 5s rise 10 fall 2 -+ server redis-02 127.0.0.1:6381 check port 6381 check inter 2s weight 1 inter 2s downinter 5s rise 10 fall 2 backup -+ bind *:6379 -+ mode tcp -+ option tcpka -+ option tcplog -+ option tcp-check -+ tcp-check send PING\r\n -+ tcp-check expect string +PONG -+ tcp-check send info\ replication\r\n -+ tcp-check expect string role:master -+ tcp-check send QUIT\r\n -+ tcp-check expect string +OK -+ balance roundrobin -+``` -+ -+This way you don't need to use this library. -+ -+License -+------- -+ -+Library is available under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). -diff --git a/vendor/github.com/FZambia/sentinel/sentinel.go b/vendor/github.com/FZambia/sentinel/sentinel.go -new file mode 100644 -index 0000000000..79209e9f0d ---- /dev/null -+++ b/vendor/github.com/FZambia/sentinel/sentinel.go -@@ -0,0 +1,426 @@ -+package sentinel -+ -+import ( -+ "errors" -+ "fmt" -+ "net" -+ "strings" -+ "sync" -+ "time" -+ -+ "github.com/garyburd/redigo/redis" -+) -+ -+// Sentinel provides a way to add high availability (HA) to Redis Pool using -+// preconfigured addresses of Sentinel servers and name of master which Sentinels -+// monitor. It works with Redis >= 2.8.12 (mostly because of ROLE command that -+// was introduced in that version, it's possible though to support old versions -+// using INFO command). -+// -+// Example of the simplest usage to contact master "mymaster": -+// -+// func newSentinelPool() *redis.Pool { -+// sntnl := &sentinel.Sentinel{ -+// Addrs: []string{":26379", ":26380", ":26381"}, -+// MasterName: "mymaster", -+// Dial: func(addr string) (redis.Conn, error) { -+// timeout := 500 * time.Millisecond -+// c, err := redis.DialTimeout("tcp", addr, timeout, timeout, timeout) -+// if err != nil { -+// return nil, err -+// } -+// return c, nil -+// }, -+// } -+// return &redis.Pool{ -+// MaxIdle: 3, -+// MaxActive: 64, -+// Wait: true, -+// IdleTimeout: 240 * time.Second, -+// Dial: func() (redis.Conn, error) { -+// masterAddr, err := sntnl.MasterAddr() -+// if err != nil { -+// return nil, err -+// } -+// c, err := redis.Dial("tcp", masterAddr) -+// if err != nil { -+// return nil, err -+// } -+// return c, nil -+// }, -+// TestOnBorrow: func(c redis.Conn, t time.Time) error { -+// if !sentinel.TestRole(c, "master") { -+// return errors.New("Role check failed") -+// } else { -+// return nil -+// } -+// }, -+// } -+// } -+type Sentinel struct { -+ // Addrs is a slice with known Sentinel addresses. -+ Addrs []string -+ -+ // MasterName is a name of Redis master Sentinel servers monitor. -+ MasterName string -+ -+ // Dial is a user supplied function to connect to Sentinel on given address. This -+ // address will be chosen from Addrs slice. -+ // Note that as per the redis-sentinel client guidelines, a timeout is mandatory -+ // while connecting to Sentinels, and should not be set to 0. -+ Dial func(addr string) (redis.Conn, error) -+ -+ // Pool is a user supplied function returning custom connection pool to Sentinel. -+ // This can be useful to tune options if you are not satisfied with what default -+ // Sentinel pool offers. See defaultPool() method for default pool implementation. -+ // In most cases you only need to provide Dial function and let this be nil. -+ Pool func(addr string) *redis.Pool -+ -+ mu sync.RWMutex -+ pools map[string]*redis.Pool -+ addr string -+} -+ -+// NoSentinelsAvailable is returned when all sentinels in the list are exhausted -+// (or none configured), and contains the last error returned by Dial (which -+// may be nil) -+type NoSentinelsAvailable struct { -+ lastError error -+} -+ -+func (ns NoSentinelsAvailable) Error() string { -+ if ns.lastError != nil { -+ return fmt.Sprintf("redigo: no sentinels available; last error: %s", ns.lastError.Error()) -+ } -+ return fmt.Sprintf("redigo: no sentinels available") -+} -+ -+// putToTop puts Sentinel address to the top of address list - this means -+// that all next requests will use Sentinel on this address first. -+// -+// From Sentinel guidelines: -+// -+// The first Sentinel replying to the client request should be put at the -+// start of the list, so that at the next reconnection, we'll try first -+// the Sentinel that was reachable in the previous connection attempt, -+// minimizing latency. -+// -+// Lock must be held by caller. -+func (s *Sentinel) putToTop(addr string) { -+ addrs := s.Addrs -+ if addrs[0] == addr { -+ // Already on top. -+ return -+ } -+ newAddrs := []string{addr} -+ for _, a := range addrs { -+ if a == addr { -+ continue -+ } -+ newAddrs = append(newAddrs, a) -+ } -+ s.Addrs = newAddrs -+} -+ -+// putToBottom puts Sentinel address to the bottom of address list. -+// We call this method internally when see that some Sentinel failed to answer -+// on application request so next time we start with another one. -+// -+// Lock must be held by caller. -+func (s *Sentinel) putToBottom(addr string) { -+ addrs := s.Addrs -+ if addrs[len(addrs)-1] == addr { -+ // Already on bottom. -+ return -+ } -+ newAddrs := []string{} -+ for _, a := range addrs { -+ if a == addr { -+ continue -+ } -+ newAddrs = append(newAddrs, a) -+ } -+ newAddrs = append(newAddrs, addr) -+ s.Addrs = newAddrs -+} -+ -+// defaultPool returns a connection pool to one Sentinel. This allows -+// us to call concurrent requests to Sentinel using connection Do method. -+func (s *Sentinel) defaultPool(addr string) *redis.Pool { -+ return &redis.Pool{ -+ MaxIdle: 3, -+ MaxActive: 10, -+ Wait: true, -+ IdleTimeout: 240 * time.Second, -+ Dial: func() (redis.Conn, error) { -+ return s.Dial(addr) -+ }, -+ TestOnBorrow: func(c redis.Conn, t time.Time) error { -+ _, err := c.Do("PING") -+ return err -+ }, -+ } -+} -+ -+func (s *Sentinel) get(addr string) redis.Conn { -+ pool := s.poolForAddr(addr) -+ return pool.Get() -+} -+ -+func (s *Sentinel) poolForAddr(addr string) *redis.Pool { -+ s.mu.Lock() -+ if s.pools == nil { -+ s.pools = make(map[string]*redis.Pool) -+ } -+ pool, ok := s.pools[addr] -+ if ok { -+ s.mu.Unlock() -+ return pool -+ } -+ s.mu.Unlock() -+ newPool := s.newPool(addr) -+ s.mu.Lock() -+ p, ok := s.pools[addr] -+ if ok { -+ s.mu.Unlock() -+ return p -+ } -+ s.pools[addr] = newPool -+ s.mu.Unlock() -+ return newPool -+} -+ -+func (s *Sentinel) newPool(addr string) *redis.Pool { -+ if s.Pool != nil { -+ return s.Pool(addr) -+ } -+ return s.defaultPool(addr) -+} -+ -+// close connection pool to Sentinel. -+// Lock must be hold by caller. -+func (s *Sentinel) close() { -+ if s.pools != nil { -+ for _, pool := range s.pools { -+ pool.Close() -+ } -+ } -+ s.pools = nil -+} -+ -+func (s *Sentinel) doUntilSuccess(f func(redis.Conn) (interface{}, error)) (interface{}, error) { -+ s.mu.RLock() -+ addrs := s.Addrs -+ s.mu.RUnlock() -+ -+ var lastErr error -+ -+ for _, addr := range addrs { -+ conn := s.get(addr) -+ reply, err := f(conn) -+ conn.Close() -+ if err != nil { -+ lastErr = err -+ s.mu.Lock() -+ pool, ok := s.pools[addr] -+ if ok { -+ pool.Close() -+ delete(s.pools, addr) -+ } -+ s.putToBottom(addr) -+ s.mu.Unlock() -+ continue -+ } -+ s.putToTop(addr) -+ return reply, nil -+ } -+ -+ return nil, NoSentinelsAvailable{lastError: lastErr} -+} -+ -+// MasterAddr returns an address of current Redis master instance. -+func (s *Sentinel) MasterAddr() (string, error) { -+ res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) { -+ return queryForMaster(c, s.MasterName) -+ }) -+ if err != nil { -+ return "", err -+ } -+ return res.(string), nil -+} -+ -+// SlaveAddrs returns a slice with known slave addresses of current master instance. -+func (s *Sentinel) SlaveAddrs() ([]string, error) { -+ res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) { -+ return queryForSlaveAddrs(c, s.MasterName) -+ }) -+ if err != nil { -+ return nil, err -+ } -+ return res.([]string), nil -+} -+ -+// Slave represents a Redis slave instance which is known by Sentinel. -+type Slave struct { -+ ip string -+ port string -+ flags string -+} -+ -+// Addr returns an address of slave. -+func (s *Slave) Addr() string { -+ return net.JoinHostPort(s.ip, s.port) -+} -+ -+// Available returns if slave is in working state at moment based on information in slave flags. -+func (s *Slave) Available() bool { -+ return !strings.Contains(s.flags, "disconnected") && !strings.Contains(s.flags, "s_down") -+} -+ -+// Slaves returns a slice with known slaves of master instance. -+func (s *Sentinel) Slaves() ([]*Slave, error) { -+ res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) { -+ return queryForSlaves(c, s.MasterName) -+ }) -+ if err != nil { -+ return nil, err -+ } -+ return res.([]*Slave), nil -+} -+ -+// SentinelAddrs returns a slice of known Sentinel addresses Sentinel server aware of. -+func (s *Sentinel) SentinelAddrs() ([]string, error) { -+ res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) { -+ return queryForSentinels(c, s.MasterName) -+ }) -+ if err != nil { -+ return nil, err -+ } -+ return res.([]string), nil -+} -+ -+// Discover allows to update list of known Sentinel addresses. From docs: -+// -+// A client may update its internal list of Sentinel nodes following this procedure: -+// 1) Obtain a list of other Sentinels for this master using the command SENTINEL sentinels . -+// 2) Add every ip:port pair not already existing in our list at the end of the list. -+func (s *Sentinel) Discover() error { -+ addrs, err := s.SentinelAddrs() -+ if err != nil { -+ return err -+ } -+ s.mu.Lock() -+ for _, addr := range addrs { -+ if !stringInSlice(addr, s.Addrs) { -+ s.Addrs = append(s.Addrs, addr) -+ } -+ } -+ s.mu.Unlock() -+ return nil -+} -+ -+// Close closes current connection to Sentinel. -+func (s *Sentinel) Close() error { -+ s.mu.Lock() -+ s.close() -+ s.mu.Unlock() -+ return nil -+} -+ -+// TestRole wraps GetRole in a test to verify if the role matches an expected -+// role string. If there was any error in querying the supplied connection, -+// the function returns false. Works with Redis >= 2.8.12. -+// It's not goroutine safe, but if you call this method on pooled connections -+// then you are OK. -+func TestRole(c redis.Conn, expectedRole string) bool { -+ role, err := getRole(c) -+ if err != nil || role != expectedRole { -+ return false -+ } -+ return true -+} -+ -+// getRole is a convenience function supplied to query an instance (master or -+// slave) for its role. It attempts to use the ROLE command introduced in -+// redis 2.8.12. -+func getRole(c redis.Conn) (string, error) { -+ res, err := c.Do("ROLE") -+ if err != nil { -+ return "", err -+ } -+ rres, ok := res.([]interface{}) -+ if ok { -+ return redis.String(rres[0], nil) -+ } -+ return "", errors.New("redigo: can not transform ROLE reply to string") -+} -+ -+func queryForMaster(conn redis.Conn, masterName string) (string, error) { -+ res, err := redis.Strings(conn.Do("SENTINEL", "get-master-addr-by-name", masterName)) -+ if err != nil { -+ return "", err -+ } -+ if len(res) < 2 { -+ return "", errors.New("redigo: malformed get-master-addr-by-name reply") -+ } -+ masterAddr := net.JoinHostPort(res[0], res[1]) -+ return masterAddr, nil -+} -+ -+func queryForSlaveAddrs(conn redis.Conn, masterName string) ([]string, error) { -+ slaves, err := queryForSlaves(conn, masterName) -+ if err != nil { -+ return nil, err -+ } -+ slaveAddrs := make([]string, 0) -+ for _, slave := range slaves { -+ slaveAddrs = append(slaveAddrs, slave.Addr()) -+ } -+ return slaveAddrs, nil -+} -+ -+func queryForSlaves(conn redis.Conn, masterName string) ([]*Slave, error) { -+ res, err := redis.Values(conn.Do("SENTINEL", "slaves", masterName)) -+ if err != nil { -+ return nil, err -+ } -+ slaves := make([]*Slave, 0) -+ for _, a := range res { -+ sm, err := redis.StringMap(a, err) -+ if err != nil { -+ return slaves, err -+ } -+ slave := &Slave{ -+ ip: sm["ip"], -+ port: sm["port"], -+ flags: sm["flags"], -+ } -+ slaves = append(slaves, slave) -+ } -+ return slaves, nil -+} -+ -+func queryForSentinels(conn redis.Conn, masterName string) ([]string, error) { -+ res, err := redis.Values(conn.Do("SENTINEL", "sentinels", masterName)) -+ if err != nil { -+ return nil, err -+ } -+ sentinels := make([]string, 0) -+ for _, a := range res { -+ sm, err := redis.StringMap(a, err) -+ if err != nil { -+ return sentinels, err -+ } -+ sentinels = append(sentinels, fmt.Sprintf("%s:%s", sm["ip"], sm["port"])) -+ } -+ return sentinels, nil -+} -+ -+func stringInSlice(str string, slice []string) bool { -+ for _, s := range slice { -+ if s == str { -+ return true -+ } -+ } -+ return false -+} diff --git a/v2.10.2/registry-photon/rockcraft.yaml b/v2.10.2/registry-photon/rockcraft.yaml deleted file mode 100644 index a01c3c7..0000000 --- a/v2.10.2/registry-photon/rockcraft.yaml +++ /dev/null @@ -1,84 +0,0 @@ -name: registry -summary: Rock replacement for the Harbor registry image. -description: > - This rock is a drop in replacement for the - docker.io/goharbor/registry-photon:v2.10.2 image. -# Based on the following: -# https://github.com/goharbor/harbor/tree/v2.10.2/make/photon/registry -version: v2.10.2 -license: Apache-2.0 - -base: ubuntu@22.04 -build-base: ubuntu@22.04 -platforms: - amd64: - arm64: - -services: - registry: - command: /home/harbor/entrypoint.sh - override: replace - startup: enabled - user: harbor - group: harbor - working-dir: /home/harbor - -parts: - create-user: - plugin: nil - overlay-script: | - groupadd -R $CRAFT_OVERLAY -r -g 10000 harbor - useradd -R $CRAFT_OVERLAY \ - --no-log-init -r -m -g 10000 -u 10000 harbor - - image-prep: - after: [create-user] - plugin: nil - source-type: git - source: https://github.com/goharbor/harbor - source-tag: v2.10.2 - source-depth: 1 - override-build: | - OUTDIR="$CRAFT_PART_INSTALL/home/harbor" - mkdir -p "$OUTDIR" - cd $CRAFT_PART_SRC - cp ./make/photon/common/install_cert.sh "$OUTDIR/" - cp ./make/photon/registry/entrypoint.sh "$OUTDIR/" - mkdir -p "$CRAFT_PART_INSTALL/etc/pki/tls/certs" - chown -R 10000:10000 "$CRAFT_PART_INSTALL/etc/pki/tls/certs" - chown -R 10000:10000 "$OUTDIR" - chmod u+x "$OUTDIR/entrypoint.sh" - chmod u+x "$OUTDIR/install_cert.sh" - - registry: - after: [image-prep] - build-snaps: - - go/1.21/stable - plugin: go - source-type: git - source: https://github.com/distribution/distribution.git - source-tag: v2.8.3 - source-depth: 1 - override-build: | - git apply --ignore-whitespace $CRAFT_PROJECT_DIR/redis.patch - - # 2.8.3 doesn't have a go.mod definition. - mkdir -p /go/src/github.com/docker - - ln -sf $(pwd) /go/src/github.com/docker/distribution - - pushd /go/src/github.com/docker/distribution - - export GOPATH=/go - export BUILDTAGS=include_oss include_gcs - export GO111MODULE=auto - export CGO_ENABLED=0 - make clean binaries - - mkdir -p $CRAFT_PART_INSTALL/usr/bin - - cp bin/registry $CRAFT_PART_INSTALL/usr/bin/registry_DO_NOT_USE_GC - chown 10000:10000 $CRAFT_PART_INSTALL/usr/bin/registry_DO_NOT_USE_GC - - # TODO: the upstream image defines a healthcheck and a volume, - # should/can we do the same? diff --git a/v2.10.2/trivy-adapter-photon/rockcraft.yaml b/v2.10.2/trivy-adapter-photon/rockcraft.yaml deleted file mode 100644 index d7db7a2..0000000 --- a/v2.10.2/trivy-adapter-photon/rockcraft.yaml +++ /dev/null @@ -1,94 +0,0 @@ -name: trivy-adapter -summary: Rock replacement for the Harbor Trivy adapter image. -description: > - This rock is a drop in replacement for the - docker.io/goharbor/trivy-adapter-photon:v2.10.2 image. -# Based on the following: -# https://github.com/goharbor/harbor/tree/v2.10.2/make/photon/trivy-adapter -version: v2.10.2 -license: Apache-2.0 - -base: ubuntu@22.04 -build-base: ubuntu@22.04 -platforms: - amd64: - arm64: - -services: - scanner: - command: /home/scanner/entrypoint.sh - override: replace - startup: enabled - user: scanner - group: scanner - -parts: - create-user: - plugin: nil - overlay-script: | - groupadd -R $CRAFT_OVERLAY -r -g 10000 scanner - useradd -R $CRAFT_OVERLAY \ - --no-log-init -r -m -g 10000 -u 10000 scanner - - image-prep: - after: [create-user] - plugin: nil - source-type: git - source: https://github.com/goharbor/harbor - source-tag: v2.10.2 - source-depth: 1 - override-build: | - OUTDIR="$CRAFT_PART_INSTALL/home/scanner" - mkdir -p "$OUTDIR" - cd $CRAFT_PART_SRC - cp ./make/photon/common/install_cert.sh "$OUTDIR/" - cp ./make/photon/trivy-adapter/entrypoint.sh "$OUTDIR/" - mkdir -p "$CRAFT_PART_INSTALL/etc/pki/tls/certs" - chown -R 10000:10000 "$CRAFT_PART_INSTALL/etc/pki/tls/certs" - chown -R 10000:10000 "$OUTDIR" - chmod u+x "$OUTDIR/entrypoint.sh" - chmod u+x "$OUTDIR/install_cert.sh" - - trivy: - after: [image-prep] - build-snaps: - - go/1.21/stable - plugin: go - source-type: git - source: https://github.com/aquasecurity/trivy - source-tag: v0.50.1 - source-depth: 1 - override-build: | - export GOOS=linux - export GO111MODULE=on - export CGO_ENABLED=0 - go build -o trivy cmd/trivy/main.go - - mkdir -p $CRAFT_PART_INSTALL/usr/local/bin - cp trivy $CRAFT_PART_INSTALL/usr/local/bin/trivy - chown 10000:10000 $CRAFT_PART_INSTALL/usr/local/bin/trivy - - # TODO: the upstream image defines a healthcheck, - # should/can we do the same? - - trivy-adapter: - after: [image-prep] - build-snaps: - - go/1.21/stable - plugin: go - source-type: git - source: https://github.com/aquasecurity/harbor-scanner-trivy - source-tag: v0.30.23 - source-depth: 1 - override-build: | - export GOOS=linux - export GO111MODULE=on - export CGO_ENABLED=0 - go build -o scanner-trivy cmd/scanner-trivy/main.go - - mkdir -p $CRAFT_PART_INSTALL/home/scanner/bin - cp scanner-trivy $CRAFT_PART_INSTALL/home/scanner/bin/scanner-trivy - chown 10000:10000 $CRAFT_PART_INSTALL/home/scanner/bin/scanner-trivy - - # TODO: the upstream image defines a healthcheck, - # should/can we do the same?