Skip to content

Commit 6b75a3d

Browse files
feat: improve and simplify targets.json (#125)
Co-authored-by: raphaelcoeffic <[email protected]> Co-authored-by: Peter Feerick <[email protected]>
1 parent 698d6f1 commit 6b75a3d

File tree

12 files changed

+622
-360
lines changed

12 files changed

+622
-360
lines changed

Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ migrate:
77
go run cmd/db/main.go -migrate
88

99
lint:
10-
go install github.com/golangci/golangci-lint/cmd/[email protected]
1110
golangci-lint run ./...
1211

1312
lint-fix:
1413
go mod tidy
15-
go install github.com/golangci/golangci-lint/cmd/[email protected]
1614
golangci-lint run --fix ./...
1715

1816
build:

README.md

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ Linux operating system with:
3232

3333
First clone this repository:
3434

35-
``` shell
35+
```shell
3636
git clone https://github.com/EdgeTX/cloudbuild.git
3737
```
3838

3939
Then you will need to configure some things:
4040

41-
``` shell
41+
```shell
4242
# Create config from template
4343
cp api.env.example api.env
4444
```
@@ -47,7 +47,7 @@ For a quick test, all you need to edit is external URL (as it will be seen by we
4747
and the directory in which the firmwares are stored (which should be shared among all
4848
containers as a volume).
4949

50-
```
50+
```env
5151
EBUILD_STORAGE_PATH=/home/rootless/src/static/firmwares
5252
EBUILD_DOWNLOAD_URL=http://localhost:3000/firmwares
5353
```
@@ -56,7 +56,7 @@ EBUILD_DOWNLOAD_URL=http://localhost:3000/firmwares
5656

5757
The runtime container image can be built with:
5858

59-
``` shell
59+
```shell
6060
docker compose build api
6161
```
6262

@@ -66,19 +66,19 @@ docker compose build api
6666

6767
Start the database first:
6868

69-
``` shell
69+
```shell
7070
docker compose up -d db
7171
```
7272

7373
Then start the API:
7474

75-
``` shell
75+
```shell
7676
docker compose up -d api
7777
```
7878

7979
And setup the database schema with:
8080

81-
``` shell
81+
```shell
8282
docker exec -it cloudbuild-api-1 ./ebuild db migrate
8383
```
8484

@@ -88,7 +88,7 @@ Once the database is setup, proceed to the next step to start the workers as wel
8888

8989
Then the rest of the stack can be run all together:
9090

91-
``` shell
91+
```shell
9292
docker compose up -d --scale worker=2
9393
```
9494

@@ -100,7 +100,7 @@ You can increase the number of workers if you want to build more firmwares in pa
100100
To offload serving the firmware files to a S3 compatible storage, a few configuration
101101
parameters need to be set additionally in the environment file (`api.env`):
102102

103-
```
103+
```env
104104
# Common settings for all provider
105105
EBUILD_STORAGE_TYPE: S3
106106
EBUILD_S3_ACCESS_KEY: myAccessKey
@@ -118,15 +118,49 @@ EBUILD_DOWNLOAD_URL: https://bucket.s3.super-provider.com
118118

119119
To be able to use the administrative UI, a token must be generated for every user:
120120

121-
``` shell
121+
```shell
122122
docker exec -it cloudbuild-api-1 ./ebuild auth create [some name]
123123
AccessKey: [some access key]
124124
SecretKey: [very secret key]
125125
```
126126

127127
The token can be later removed:
128128

129-
``` shell
129+
```shell
130130
docker exec -it cloudbuild-api-1 ./ebuild auth remove [Access Key]
131131
token [Access Key] removed
132132
```
133+
134+
## Using a local Git mirror
135+
136+
To speed up builds, it is possible to use a local mirror by changing
137+
the repository URL:
138+
```env
139+
EBUILD_SRC_REPO=http://local-mirror:8080/EdgeTX/edgetx
140+
```
141+
142+
[cloudbuild-mirror](https://github.com/EdgeTX/cloudbuild-mirror) can be
143+
used as a local mirror. It also supports automatic refreshing of the
144+
targets (see next section).
145+
146+
With this configuration only, the submodules will still be fetched from `http://github.com`,
147+
as the full URL is encoded into the respective `.gitmodules` files. Fortunately, Git offers
148+
a simple to override this with [insteadOf](https://git-scm.com/docs/git-config#Documentation/git-config.txt-urlbaseinsteadOf).
149+
150+
Just mount this file into the workers at `/etc/gitconfig`:
151+
```
152+
[url "http://local-mirror:8080"]
153+
insteadOf = https://github.com
154+
```
155+
156+
## Refresh targets automatically from URL
157+
158+
It is also possible to fetch `targets.json` from a URL instead of a local
159+
file. In that case, the targets are refreshed automatically (defaults to 5 minutes interval).
160+
161+
```env
162+
# Use cloudbuild mirrored repository as the source for targets.json
163+
EBUILD_TARGETS=http://local-mirror:8080/gitweb.cgi?p=EdgeTX/cloudbuild.git;a=blob_plain;f=targets.json;hb=HEAD
164+
# This is the default refresh interval in seconds
165+
EBUILD_TARGETS_REFRESH_INTERVAL=300
166+
```

artifactory/artifactory_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ import (
2828
func init() {
2929
log.SetOutput(os.Stdout)
3030
log.SetLevel(log.DebugLevel)
31-
err := targets.ReadTargetsDefFromBytes([]byte(targetsJSON))
31+
defs, err := targets.ReadTargetsDefFromBytes([]byte(targetsJSON), "")
3232
if err != nil {
3333
panic(err)
3434
}
35+
targets.SetTargets(defs)
3536
request = artifactory.NewBuildRequestWithParams(commitRef, target, flags)
3637
}
3738

cmd/ebuild/run/cmd.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,19 @@ func (s *serverRunner) runAPI(cmd *cobra.Command, args []string) {
4040
fmt.Printf("failed to migrate database: %s", err)
4141
os.Exit(1)
4242
}
43-
if err := targets.ReadTargetsDef("./targets.json"); err != nil {
43+
if defs, err := targets.ReadTargetsDef(
44+
s.opts.TargetsDef,
45+
s.opts.SourceRepository,
46+
); err != nil {
4447
fmt.Printf("failed to read targets: %s", err)
4548
os.Exit(1)
49+
} else {
50+
targets.SetTargets(defs)
4651
}
47-
go targets.Updater(time.Minute * 5)
52+
go targets.Updater(
53+
time.Second*time.Duration(s.opts.TargetsRefreshInterval),
54+
s.opts.SourceRepository,
55+
)
4856
art, err := artifactory.NewFromConfig(s.ctx, s.opts)
4957
if err != nil {
5058
fmt.Printf("failed to create artifactory: %s", err)
@@ -131,7 +139,6 @@ func NewAPICommand(s *serverRunner) *cobra.Command {
131139

132140
func NewWorkerCommand(s *serverRunner) *cobra.Command {
133141
cmd := s.makeCmd("worker", "Run a cloudbuild worker", s.runWorker)
134-
s.opts.BindWorkerOpts(cmd)
135142
return cmd
136143
}
137144

config/options.go

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ func LogLevelDecodeHookFunc() mapstructure.DecodeHookFunc {
5050
return func(
5151
f reflect.Type,
5252
t reflect.Type,
53-
data interface{},
54-
) (interface{}, error) {
53+
data any,
54+
) (any, error) {
5555
if f.Kind() != reflect.String {
5656
return data, nil
5757
}
@@ -85,6 +85,10 @@ type CloudbuildOpts struct {
8585
DatabaseDSN string `mapstructure:"database-dsn"`
8686
DatabaseHost string `mapstructure:"database-host"`
8787

88+
// Targets options:
89+
TargetsDef string `mapstructure:"targets"`
90+
TargetsRefreshInterval uint32 `mapstructure:"targets-refresh-interval"`
91+
8892
// Build options:
8993
BuildImage string `mapstructure:"build-img"`
9094
SourceRepository string `mapstructure:"src-repo"`
@@ -104,14 +108,16 @@ type CloudbuildOpts struct {
104108

105109
func NewOpts(v *viper.Viper) *CloudbuildOpts {
106110
return &CloudbuildOpts{
107-
Viper: v,
108-
LogLevel: InfoLevel,
109-
HTTPBindPort: 3000,
110-
BuildImage: "ghcr.io/edgetx/edgetx-builder",
111-
SourceRepository: "https://github.com/EdgeTX/edgetx.git",
112-
DownloadURL: "http://localhost:3000",
113-
StorageType: "FILE_SYSTEM_STORAGE",
114-
StoragePath: "/tmp",
111+
Viper: v,
112+
LogLevel: InfoLevel,
113+
HTTPBindPort: 3000,
114+
TargetsDef: "file:///targets.json",
115+
TargetsRefreshInterval: 300,
116+
BuildImage: "ghcr.io/edgetx/edgetx-builder",
117+
SourceRepository: "https://github.com/EdgeTX/edgetx.git",
118+
DownloadURL: "http://localhost:3000",
119+
StorageType: "FILE_SYSTEM_STORAGE",
120+
StoragePath: "/tmp",
115121
}
116122
}
117123

@@ -162,18 +168,28 @@ func (o *CloudbuildOpts) BindBuildOpts(c *cobra.Command) {
162168
c.PersistentFlags().StringVar(
163169
&o.BuildImage, "build-img", o.BuildImage, "Build docker image",
164170
)
171+
c.Flags().StringVar(
172+
&o.SourceRepository, "src-repo", o.SourceRepository, "Source repository",
173+
)
165174
}
166175

167176
func (o *CloudbuildOpts) BindAPIOpts(c *cobra.Command) {
168-
c.Flags().Uint16VarP(&o.HTTPBindPort, "port", "p", o.HTTPBindPort, "HTTP listen port")
169-
c.Flags().IPVarP(&o.HTTPBindAddress, "listen-ip", "l", net.IPv4zero, "HTTP listen IP")
170-
c.Flags().StringVarP(
171-
&o.DownloadURL, "download-url", "u", o.DownloadURL, "Artifact download URL")
172-
}
173-
174-
func (o *CloudbuildOpts) BindWorkerOpts(c *cobra.Command) {
177+
c.Flags().Uint16VarP(
178+
&o.HTTPBindPort, "port", "p", o.HTTPBindPort, "HTTP listen port",
179+
)
180+
c.Flags().IPVarP(
181+
&o.HTTPBindAddress, "listen-ip", "l", net.IPv4zero, "HTTP listen IP",
182+
)
175183
c.Flags().StringVar(
176-
&o.SourceRepository, "src-repo", o.SourceRepository, "Source repository")
184+
&o.TargetsDef, "targets", o.TargetsDef, "Targets definition",
185+
)
186+
c.Flags().Uint32Var(
187+
&o.TargetsRefreshInterval, "targets-refresh-interval",
188+
o.TargetsRefreshInterval, "Targets refresh interval",
189+
)
190+
c.Flags().StringVarP(
191+
&o.DownloadURL, "download-url", "u", o.DownloadURL, "Artifact download URL",
192+
)
177193
}
178194

179195
func (o *CloudbuildOpts) Unmarshal() error {

go.mod

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,35 @@ module github.com/edgetx/cloudbuild
33
go 1.24.1
44

55
require (
6+
github.com/Masterminds/semver/v3 v3.4.0
67
github.com/aws/aws-sdk-go-v2 v1.18.0
78
github.com/aws/aws-sdk-go-v2/config v1.18.23
89
github.com/aws/aws-sdk-go-v2/credentials v1.13.22
910
github.com/aws/aws-sdk-go-v2/service/s3 v1.33.1
1011
github.com/gin-contrib/static v0.0.1
1112
github.com/gin-gonic/gin v1.9.1
13+
github.com/go-git/go-git/v6 v6.0.0-20250819122726-39261590f7f3
1214
github.com/ldez/go-git-cmd-wrapper/v2 v2.6.0
1315
github.com/mitchellh/mapstructure v1.5.0
1416
github.com/pkg/errors v0.9.1
1517
github.com/prometheus/client_golang v1.15.0
1618
github.com/satori/go.uuid v1.2.0
17-
github.com/sirupsen/logrus v1.9.0
19+
github.com/sirupsen/logrus v1.9.3
1820
github.com/spf13/cobra v1.7.0
1921
github.com/spf13/viper v1.15.0
20-
github.com/stretchr/testify v1.8.3
22+
github.com/stretchr/testify v1.10.0
2123
github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f
22-
golang.org/x/crypto v0.36.0
23-
golang.org/x/exp v0.0.0-20230519143937-03e91628a987
24+
golang.org/x/crypto v0.41.0
25+
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b
2426
gorm.io/datatypes v1.2.0
2527
gorm.io/driver/postgres v1.5.0
2628
gorm.io/gorm v1.25.0
2729
)
2830

2931
require (
32+
dario.cat/mergo v1.0.1 // indirect
33+
github.com/Microsoft/go-winio v0.6.2 // indirect
34+
github.com/ProtonMail/go-crypto v1.3.0 // indirect
3035
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
3136
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 // indirect
3237
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 // indirect
@@ -45,16 +50,22 @@ require (
4550
github.com/bytedance/sonic v1.9.1 // indirect
4651
github.com/cespare/xxhash/v2 v2.2.0 // indirect
4752
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
53+
github.com/cloudflare/circl v1.6.1 // indirect
54+
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
4855
github.com/davecgh/go-spew v1.1.1 // indirect
56+
github.com/emirpasic/gods v1.18.1 // indirect
4957
github.com/fsnotify/fsnotify v1.6.0 // indirect
5058
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
5159
github.com/gin-contrib/sse v0.1.0 // indirect
60+
github.com/go-git/gcfg/v2 v2.0.2 // indirect
61+
github.com/go-git/go-billy/v6 v6.0.0-20250627091229-31e2a16eef30 // indirect
5262
github.com/go-playground/locales v0.14.1 // indirect
5363
github.com/go-playground/universal-translator v0.18.1 // indirect
5464
github.com/go-playground/validator/v10 v10.14.0 // indirect
5565
github.com/go-sql-driver/mysql v1.7.1 // indirect
5666
github.com/goccy/go-json v0.10.2 // indirect
57-
github.com/golang/protobuf v1.5.3 // indirect
67+
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
68+
github.com/golang/protobuf v1.5.4 // indirect
5869
github.com/hashicorp/hcl v1.0.0 // indirect
5970
github.com/inconshreveable/mousetrap v1.1.0 // indirect
6071
github.com/jackc/pgpassfile v1.0.0 // indirect
@@ -64,6 +75,7 @@ require (
6475
github.com/jinzhu/inflection v1.0.0 // indirect
6576
github.com/jinzhu/now v1.1.5 // indirect
6677
github.com/json-iterator/go v1.1.12 // indirect
78+
github.com/kevinburke/ssh_config v1.2.0 // indirect
6779
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
6880
github.com/leodido/go-urn v1.2.4 // indirect
6981
github.com/magiconair/properties v1.8.7 // indirect
@@ -72,24 +84,25 @@ require (
7284
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
7385
github.com/modern-go/reflect2 v1.0.2 // indirect
7486
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
87+
github.com/pjbgf/sha1cd v0.4.0 // indirect
7588
github.com/pmezard/go-difflib v1.0.0 // indirect
7689
github.com/prometheus/client_model v0.3.0 // indirect
7790
github.com/prometheus/common v0.42.0 // indirect
7891
github.com/prometheus/procfs v0.9.0 // indirect
79-
github.com/rogpeppe/go-internal v1.9.0 // indirect
92+
github.com/sergi/go-diff v1.4.0 // indirect
8093
github.com/spf13/afero v1.9.3 // indirect
8194
github.com/spf13/cast v1.5.0 // indirect
8295
github.com/spf13/jwalterweatherman v1.1.0 // indirect
8396
github.com/spf13/pflag v1.0.5 // indirect
84-
github.com/stretchr/objx v0.5.0 // indirect
97+
github.com/stretchr/objx v0.5.2 // indirect
8598
github.com/subosito/gotenv v1.4.2 // indirect
8699
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
87100
github.com/ugorji/go/codec v1.2.11 // indirect
88101
golang.org/x/arch v0.3.0 // indirect
89-
golang.org/x/net v0.38.0 // indirect
90-
golang.org/x/sync v0.12.0 // indirect
91-
golang.org/x/sys v0.31.0 // indirect
92-
golang.org/x/text v0.23.0 // indirect
102+
golang.org/x/net v0.43.0 // indirect
103+
golang.org/x/sync v0.16.0 // indirect
104+
golang.org/x/sys v0.35.0 // indirect
105+
golang.org/x/text v0.28.0 // indirect
93106
google.golang.org/protobuf v1.33.0 // indirect
94107
gopkg.in/ini.v1 v1.67.0 // indirect
95108
gopkg.in/yaml.v3 v3.0.1 // indirect

0 commit comments

Comments
 (0)