Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
wweir committed Sep 30, 2024
1 parent 01f48ed commit 6a6ba72
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 20 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ build:
-o bin/contatto .
run: build
./bin/contatto proxy --debug -c contatto.toml

install: build
sudo install -m 0755 ./bin/contatto /bin/contatto
clean:
rm -f ./bin/contatto
18 changes: 16 additions & 2 deletions conf/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ func ReadConfig(file string) (*Config, error) {
return nil, fmt.Errorf("mapstructure config: %w", err)
}

return c.Validate()
}

func (c *Config) Validate() (*Config, error) {
if c.Addr == "" {
return nil, fmt.Errorf("addr is required")
}

if c.BaseRule.MirrorRegistry == "" {
return nil, fmt.Errorf("base_rule.mirror_registry is required")
}

for host, registry := range c.Registry {
if registry.registry == "" {
registry.registry = host
Expand Down Expand Up @@ -92,12 +104,14 @@ func ReadConfig(file string) (*Config, error) {
if rule.PathTpl == "" {
rule.pathTpl = c.BaseRule.pathTpl
}
if rule.pathTpl == nil {
return nil, fmt.Errorf(`rule."%s".path_tpl is required`, registry)
}
if rule.OnMissingTpl == "" {
rule.onMissingTpl = c.BaseRule.onMissingTpl
}
}

return &c, nil
return c, nil
}

var envRe = regexp.MustCompile(`\$\{([a-zA-Z0-9_]+)\}`)
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ require (
github.com/containerd/containerd/v2 v2.0.0-rc.4
github.com/go-viper/mapstructure/v2 v2.2.1
github.com/julienschmidt/httprouter v1.3.0
github.com/lmittmann/tint v1.0.5
github.com/pelletier/go-toml/v2 v2.2.3
gopkg.in/yaml.v3 v3.0.1
)
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4d
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/lmittmann/tint v1.0.5 h1:NQclAutOfYsqs2F1Lenue6OoWCajs5wJcP3DfWVpePw=
github.com/lmittmann/tint v1.0.5/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
Expand Down
93 changes: 89 additions & 4 deletions install.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,98 @@
package main

import (
"log/slog"
"encoding/json"
"fmt"
"os"

"github.com/pelletier/go-toml/v2"
"github.com/wweir/contatto/conf"
)

type InstallCmd struct{}
type InstallCmd struct {
Interactive *InstallInteractiveCmd `cmd:"" default:"1" hidden:"" help:"123"`
Docker *InstallDockerCmd `cmd:"" help:"inject proxy as mirror to dockerd config file"`
Containerd *InstallContainerdCmd `cmd:"" help:"inject proxy as puller in containerd config file"`
}

func (c *InstallCmd) Run() error {
slog.Info("install")
type InstallInteractiveCmd struct{}

func (c *InstallInteractiveCmd) Run(config *conf.Config) error {
return nil
}

type InstallDockerCmd struct {
File string `arg:"" required:"" default:"/etc/docker/daemon.json" help:"dockerd config file, default: /etc/docker/daemon.json"`
}

func (c *InstallDockerCmd) Run(config *conf.Config) error {
fmt.Printf("inject mirror http://%s into docker config: %s\n", config.Addr, c.File)

f, err := os.Open(c.File)
if err != nil {
return err
}
defer f.Close()

dockerConfig := map[string]any{}
if err := json.NewDecoder(f).Decode(&dockerConfig); err != nil {
return err
}

if dockerConfig["registry-mirrors"] == nil {
dockerConfig["registry-mirrors"] = []string{}
}

mirrors := dockerConfig["registry-mirrors"].([]any)
proxyAddr := "http://" + config.Addr
for _, mirror := range mirrors {
if mirror.(string) == proxyAddr {
return nil
}
}

dockerConfig["registry-mirrors"] = append([]any{proxyAddr}, mirrors...)

f, err = os.OpenFile(c.File+"_safe", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644)
if err != nil {
return err
}
defer f.Close()

en := json.NewEncoder(f)
en.SetIndent("", " ")
if err := en.Encode(dockerConfig); err != nil {
return err
}

return os.Rename(c.File+"_safe", c.File)
}

type InstallContainerdCmd struct {
File string `arg:"" required:"" default:"/etc/containerd/config.toml" help:"containerd config file, default: /etc/containerd/config.toml"`
}

func (c *InstallContainerdCmd) Run(config *conf.Config) error {
fmt.Printf("inject proxy http://%s into containerd config: %s\n", config.Addr, c.File)

f, err := os.Open(c.File)
if err != nil {
return err
}
defer f.Close()

containerdConfig := map[string]any{}
if err := toml.NewDecoder(f).Decode(&containerdConfig); err != nil {
return err
}

switch containerdConfig["version"].(int64) {
case 2:
return c.installContainerdV2(config, containerdConfig)
default:
return fmt.Errorf("unsupported containerd config version: %d", containerdConfig["version"])
}
}

func (c *InstallContainerdCmd) installContainerdV2(config *conf.Config, containerdConfig map[string]any) error {
}
22 changes: 12 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,40 @@ import (
"fmt"
"log"
"log/slog"
"os"

"github.com/alecthomas/kong"
"github.com/lmittmann/tint"
"github.com/wweir/contatto/conf"
)

var cli struct {
Config string `short:"c" required:"" default:"/etc/contatto.toml"`
Config string `short:"c" default:"/etc/contatto.toml"`
Debug bool `help:"Enable debug logging"`

Install *InstallCmd `cmd:"" help:"install contatto"`
Install *InstallCmd `cmd:"" help:"Install proxy setting."`
Proxy *ProxyCmd `cmd:"" help:"Execute Contatto as a registry proxy."`
}

func main() {
slog.SetDefault(slog.New(tint.NewHandler(os.Stderr, &tint.Options{
AddSource: true,
Level: slog.LevelDebug,
})))
func init() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
}

func main() {
ctx := kong.Parse(&cli,
kong.UsageOnError(),
kong.Description(fmt.Sprintf(
`Contatto %s(%s) is a container registry transparent proxy.`, conf.Version, conf.Date)),
)

if cli.Debug {
slog.SetLogLoggerLevel(slog.LevelDebug)
}

config, err := conf.ReadConfig(cli.Config)
if err != nil {
log.Fatalln("failed to read config:", err)
}

if err := ctx.Run(config); err != nil {
log.Fatalf("run failed: %v\n", err)
log.Fatalln("run failed:", err)
}
}

0 comments on commit 6a6ba72

Please sign in to comment.