Skip to content

Commit 387ed7a

Browse files
committed
feat(build): add darwin and windows support in goreleaser config
1 parent c09bc72 commit 387ed7a

File tree

12 files changed

+306
-272
lines changed

12 files changed

+306
-272
lines changed

.goreleaser.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ builds:
1818
- CGO_ENABLED=0
1919
goos:
2020
- linux
21+
- darwin
22+
- windows
2123
goarch:
2224
- amd64
2325
- arm64
24-
main: ./cmd/dockersync
26+
main: ./cmd/docker-sync
2527
binary: docker-sync
2628
tags:
2729
- containers_image_docker_daemon_stub

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
all:
22
mkdir dist 2>/dev/null || true
3-
cd cmd/dockersync && go build -o ../../dist/dockersync
4-
echo "Binary is in dist/dockersync"
3+
cd cmd/docker-sync && go build -o ../../dist/docker-sync
4+
echo "Binary is in dist/docker-sync"

README.md

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -25,63 +25,64 @@ Build the project:
2525
```console
2626
make
2727
```
28-
To run a one-off synchronization, you can run `dist/dockersync sync`.
2928

30-
``` sh
31-
dist/dockersync --source docker.io/library/ubuntu --targets r2:blablabla:docker-sync-test:ubuntu --url1 docker.io --username1 foo --password1 bar --url2 r2:blablabla:docker-sync-test --username2 foo --password2 bar
29+
To run a one-off synchronization, you can run `dist/docker-sync sync`.
30+
31+
```sh
32+
dist/docker-sync --source docker.io/library/ubuntu --target r2:blablabla:docker-sync-test:ubuntu --source-username foo --source-password bar --target-username foo --target-password bar
3233
```
3334

34-
Run `dist/dockersync sync --help` for more configuration options.
35+
Run `dist/docker-sync sync --help` for more configuration options.
3536

3637
## Configuration
3738

3839
Write the default config file:
3940

4041
```console
41-
dist/dockersync writeConfig -o config.yaml`
42+
dist/docker-sync writeConfig -o config.yaml`
4243
```
4344

4445
Edit the config file accordingly, then run:
4546

4647
```console
47-
dist/dockersync
48+
dist/docker-sync
4849
```
4950

50-
The default configuration looks like this:
51+
The default configuration looks like this:
5152

5253
```yaml
5354
ecr:
54-
region: us-east-1
55+
region: us-east-1
5556
logging:
56-
colors: true
57-
format: text
58-
level: INFO
59-
output: stdout
60-
timeformat: "15:04:05"
57+
colors: true
58+
format: text
59+
level: INFO
60+
output: stdout
61+
timeformat: "15:04:05"
6162
sync:
62-
images:
63-
- source: docker.io/library/ubuntu
64-
targets:
65-
- docker.io/kamushadenes/ubuntu
66-
interval: 5m
67-
maxerrors: 5
68-
registries:
69-
- auth:
70-
helper: ""
71-
password: ""
72-
token: ""
73-
username: ""
74-
name: Docker Hub
75-
url: docker.io
63+
images:
64+
- source: docker.io/library/ubuntu
65+
targets:
66+
- docker.io/kamushadenes/ubuntu
67+
interval: 5m
68+
maxerrors: 5
69+
registries:
70+
- auth:
71+
helper: ""
72+
password: ""
73+
token: ""
74+
username: ""
75+
name: Docker Hub
76+
url: docker.io
7677
telemetry:
77-
enabled: false
78-
metrics:
79-
exporter: prometheus
80-
prometheus:
81-
address: 127.0.0.1:9090
82-
path: /metrics
83-
stdout:
84-
interval: 5s
78+
enabled: false
79+
metrics:
80+
exporter: prometheus
81+
prometheus:
82+
address: 127.0.0.1:9090
83+
path: /metrics
84+
stdout:
85+
interval: 5s
8586
```
8687
8788
The `sync` section is where you define the images you want to keep in sync. The `interval` is the time between syncs, and `maxerrors` is the maximum number of errors before the sync is stopped and the program exits.
@@ -92,14 +93,14 @@ To provide authentication for registries, put them under `sync.registries` in th
9293

9394
```yaml
9495
sync:
95-
registries:
96-
- auth:
97-
helper: ""
98-
password: ""
99-
token: ""
100-
username: ""
101-
name: Docker Hub
102-
url: docker.io
96+
registries:
97+
- auth:
98+
helper: ""
99+
password: ""
100+
token: ""
101+
username: ""
102+
name: Docker Hub
103+
url: docker.io
103104
```
104105

105106
#### ECR
@@ -108,14 +109,14 @@ To authenticate against ECR, you can leave `password`, `token` and `username` em
108109

109110
```yaml
110111
sync:
111-
registries:
112-
- auth:
113-
helper: ecr
114-
password: ""
115-
token: ""
116-
username: ""
117-
name: ECR
118-
url: 123456789012.dkr.ecr.us-east-1.amazonaws.com
112+
registries:
113+
- auth:
114+
helper: ecr
115+
password: ""
116+
token: ""
117+
username: ""
118+
name: ECR
119+
url: 123456789012.dkr.ecr.us-east-1.amazonaws.com
119120
```
120121

121122
The same applies to ecr-public, since it uses the url prefix to differentiate between the two.
@@ -170,7 +171,7 @@ sync:
170171
- r2:f6934f56ce237241104dbe9302cee786:docker-sync-test:ubuntu # r2:<endpoint>:<bucket>:<image>
171172
registries:
172173
- auth:
173-
helper: ""
174+
helper: ""
174175
password: "SECRET_ACCES_KEY"
175176
token: ""
176177
username: "ACCESS_KEY_ID"
@@ -224,7 +225,7 @@ sync:
224225
- r3:us-east-1:docker-sync-test:ubuntu # s3:<region>:<bucket>:<image>
225226
registries:
226227
- auth:
227-
helper: ""
228+
helper: ""
228229
password: "SECRET_ACCES_KEY"
229230
token: ""
230231
username: "ACCESS_KEY_ID"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
var cfgFile string
1818

1919
var rootCmd = &cobra.Command{
20-
Use: "dockersync",
20+
Use: "docker-sync",
2121
Short: "Keep your Docker images in sync",
2222
PreRun: func(cmd *cobra.Command, args []string) {
2323
cmd.Annotations = make(map[string]string)

cmd/docker-sync/cmd/sync.go

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"os"
6+
"os/signal"
7+
"path/filepath"
8+
"syscall"
9+
"time"
10+
11+
dockersync "github.com/Altinity/docker-sync"
12+
"github.com/Altinity/docker-sync/config"
13+
"github.com/Altinity/docker-sync/logging"
14+
"github.com/Altinity/docker-sync/structs"
15+
"github.com/rs/zerolog/log"
16+
"github.com/spf13/cobra"
17+
"gopkg.in/yaml.v3"
18+
)
19+
20+
type syncImage struct {
21+
Source string `yaml:"source"`
22+
Targets []string `yaml:"targets"`
23+
MutableTags []string `yaml:"mutableTags"`
24+
IgnoredTags []string `yaml:"ignoredTags"`
25+
}
26+
27+
type syncAuth struct {
28+
Username string `yaml:"username"`
29+
Password string `yaml:"password"`
30+
Token string `yaml:"token"`
31+
Helper string `yaml:"helper"`
32+
}
33+
34+
type syncRegistry struct {
35+
Auth syncAuth `yaml:"auth"`
36+
Name string `yaml:"name"`
37+
URL string `yaml:"url"`
38+
}
39+
40+
type syncConfig struct {
41+
Ecr struct {
42+
Region string `yaml:"region"`
43+
} `yaml:"ecr"`
44+
Sync struct {
45+
Images []syncImage `yaml:"images"`
46+
Registries []syncRegistry `yaml:"registries"`
47+
} `yaml:"sync"`
48+
}
49+
50+
var syncCmd = &cobra.Command{
51+
Use: "sync",
52+
Short: "Sync a single image",
53+
Run: func(cmd *cobra.Command, args []string) {
54+
ctx, cancel := context.WithCancel(context.Background())
55+
defer cancel()
56+
57+
c := make(chan os.Signal, 1)
58+
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
59+
go func() {
60+
<-c
61+
cancel()
62+
time.Sleep(1 * time.Second)
63+
os.Exit(0)
64+
}()
65+
66+
logging.ReloadGlobalLogger()
67+
68+
log.Info().Msg("Starting Docker Sync")
69+
70+
cnf := syncConfig{}
71+
cnf.Ecr.Region, _ = cmd.Flags().GetString("ecr-region")
72+
73+
source, _ := cmd.Flags().GetString("source")
74+
target, _ := cmd.Flags().GetString("target")
75+
mutableTags, _ := cmd.Flags().GetStringSlice("mutableTags")
76+
ignoredTags, _ := cmd.Flags().GetStringSlice("ignoredTags")
77+
78+
cnf.Sync.Images = append(cnf.Sync.Images, syncImage{
79+
Source: source,
80+
Targets: []string{target},
81+
MutableTags: mutableTags,
82+
IgnoredTags: ignoredTags,
83+
})
84+
85+
var registries []syncRegistry
86+
87+
sourceHelper, _ := cmd.Flags().GetString("source-helper")
88+
sourcePassword, _ := cmd.Flags().GetString("source-password")
89+
sourceToken, _ := cmd.Flags().GetString("source-token")
90+
sourceUsername, _ := cmd.Flags().GetString("source-username")
91+
92+
targetHelper, _ := cmd.Flags().GetString("target-helper")
93+
targetPassword, _ := cmd.Flags().GetString("target-password")
94+
targetToken, _ := cmd.Flags().GetString("target-token")
95+
targetUsername, _ := cmd.Flags().GetString("target-username")
96+
97+
imgHelper := structs.Image{}
98+
99+
sourceUrl := imgHelper.GetRegistry(source)
100+
targetUrl := imgHelper.GetRegistry(target)
101+
102+
if sourceUrl != "" && (sourceUsername != "" || sourcePassword != "" || sourceToken != "" || sourceHelper != "") {
103+
registries = append(registries, syncRegistry{
104+
Auth: syncAuth{
105+
Username: sourceUsername,
106+
Password: sourcePassword,
107+
Token: sourceToken,
108+
Helper: sourceHelper,
109+
},
110+
Name: "source",
111+
URL: sourceUrl,
112+
})
113+
}
114+
115+
if targetUrl != "" && (targetUsername != "" || targetPassword != "" || targetToken != "" || targetHelper != "") {
116+
registries = append(registries, syncRegistry{
117+
Auth: syncAuth{
118+
Username: targetUsername,
119+
Password: targetPassword,
120+
Token: targetToken,
121+
Helper: targetHelper,
122+
},
123+
Name: "target",
124+
URL: targetUrl,
125+
})
126+
}
127+
128+
cnf.Sync.Registries = registries
129+
130+
tmpDir, err := os.MkdirTemp(os.TempDir(), "docker-sync")
131+
if err != nil {
132+
log.Fatal().Err(err).Msg("Failed to create temporary directory")
133+
}
134+
defer os.RemoveAll(tmpDir)
135+
136+
b, err := yaml.Marshal(cnf)
137+
if err != nil {
138+
log.Fatal().Err(err).Msg("Failed to marshal configuration")
139+
}
140+
141+
if err := os.WriteFile(filepath.Join(tmpDir, "config.yaml"), b, 0644); err != nil {
142+
log.Fatal().Err(err).Msg("Failed to write configuration")
143+
}
144+
145+
if err := config.InitConfig(filepath.Join(tmpDir, "config.yaml")); err != nil {
146+
log.Fatal().Err(err).Msg("Failed to initialize config")
147+
}
148+
149+
dockersync.Reload()
150+
151+
images := config.SyncImages.Images()
152+
153+
if err := dockersync.RunOnce(ctx, images); err != nil {
154+
cmd.Annotations["error"] = err.Error()
155+
log.Error().
156+
Stack().
157+
Err(err).
158+
Msg("Error running Docker Sync")
159+
}
160+
161+
log.Info().Msg("Shutting down Docker Sync")
162+
},
163+
}
164+
165+
func init() {
166+
rootCmd.AddCommand(syncCmd)
167+
168+
syncCmd.Flags().StringP("source", "s", "", "Source image")
169+
syncCmd.Flags().StringP("target", "t", "", "Target images")
170+
171+
syncCmd.MarkFlagRequired("source")
172+
syncCmd.MarkFlagRequired("target")
173+
174+
syncCmd.Flags().StringSliceP("mutable-tags", "m", []string{}, "Mutable tags")
175+
syncCmd.Flags().StringSliceP("ignored-tags", "i", []string{}, "Ignored tags")
176+
177+
syncCmd.Flags().StringP("ecr-region", "", os.Getenv("AWS_REGION"), "AWS region for ECR")
178+
179+
syncCmd.Flags().StringP("source-helper", "", os.Getenv("DOCKER_SYNC_SOURCE_HELPER"), "Source registry helper")
180+
syncCmd.Flags().StringP("source-password", "", os.Getenv("DOCKER_SYNC_SOURCE_PASSWORD"), "Source registry password")
181+
syncCmd.Flags().StringP("source-token", "", os.Getenv("DOCKER_SYNC_SOURCE_TOKEN"), "Source registry token")
182+
syncCmd.Flags().StringP("source-username", os.Getenv("DOCKER_SYNC_SOURCE_USERNAME"), "", "Source registry username")
183+
184+
syncCmd.Flags().StringP("target-helper", "", os.Getenv("DOCKER_SYNC_TARGET_HELPER"), "target registry helper")
185+
syncCmd.Flags().StringP("target-password", "", os.Getenv("DOCKER_SYNC_TARGET_PASSWORD"), "target registry password")
186+
syncCmd.Flags().StringP("target-token", "", os.Getenv("DOCKER_SYNC_TARGET_TOKEN"), "target registry token")
187+
syncCmd.Flags().StringP("target-username", os.Getenv("DOCKER_SYNC_TARGET_USERNAME"), "", "target registry username")
188+
189+
// For more registries and advanced options, please use a configuration file
190+
}

0 commit comments

Comments
 (0)