Merge branch 'dev'
Add latest manifest to goreleaser
12 files · +90 -35
M .goreleaser.yaml +12 -0
| @@ -3,8 +3,10 @@ version: 2 | |||
| 3 | 3 | before: | |
| 4 | 4 | hooks: | |
| 5 | 5 | - go mod tidy | |
| 6 | + | ||
| 6 | 7 | release: | |
| 7 | 8 | draft: true | |
| 9 | + | ||
| 8 | 10 | builds: | |
| 9 | 11 | - id: "gordon" | |
| 10 | 12 | main: ./cmd/cli/main.go | |
| @@ -50,6 +52,16 @@ dockers: | |||
| 50 | 52 | - "--label=org.opencontainers.image.version={{.Version}}" | |
| 51 | 53 | - "--label=org.opencontainers.image.source=https://github.com/bnema/gordon" | |
| 52 | 54 | ||
| 55 | + | docker_manifests: | |
| 56 | + | - name_template: ghcr.io/bnema/gordon:{{ .Tag }} | |
| 57 | + | image_templates: | |
| 58 | + | - ghcr.io/bnema/gordon:{{ .Tag }}-amd64 | |
| 59 | + | - ghcr.io/bnema/gordon:{{ .Tag }}-arm64 | |
| 60 | + | - name_template: ghcr.io/bnema/gordon:latest | |
| 61 | + | image_templates: | |
| 62 | + | - ghcr.io/bnema/gordon:{{ .Tag }}-amd64 | |
| 63 | + | - ghcr.io/bnema/gordon:{{ .Tag }}-arm64 | |
| 64 | + | ||
| 53 | 65 | archives: | |
| 54 | 66 | - format: zip | |
| 55 | 67 | name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" | |
| @@ -3,8 +3,10 @@ version: 2 | |||||
| 3 | before: | 3 | before: | ||
| 4 | hooks: | 4 | hooks: | ||
| 5 | - go mod tidy | 5 | - go mod tidy | ||
| 6 | + | ||||
| 6 | release: | 7 | release: | ||
| 7 | draft: true | 8 | draft: true | ||
| 9 | + | ||||
| 8 | builds: | 10 | builds: | ||
| 9 | - id: "gordon" | 11 | - id: "gordon" | ||
| 10 | main: ./cmd/cli/main.go | 12 | main: ./cmd/cli/main.go | ||
| @@ -50,6 +52,16 @@ dockers: | |||||
| 50 | - "--label=org.opencontainers.image.version={{.Version}}" | 52 | - "--label=org.opencontainers.image.version={{.Version}}" | ||
| 51 | - "--label=org.opencontainers.image.source=https://github.com/bnema/gordon" | 53 | - "--label=org.opencontainers.image.source=https://github.com/bnema/gordon" | ||
| 52 | 54 | ||||
| 55 | + | docker_manifests: | |||
| 56 | + | - name_template: ghcr.io/bnema/gordon:{{ .Tag }} | |||
| 57 | + | image_templates: | |||
| 58 | + | - ghcr.io/bnema/gordon:{{ .Tag }}-amd64 | |||
| 59 | + | - ghcr.io/bnema/gordon:{{ .Tag }}-arm64 | |||
| 60 | + | - name_template: ghcr.io/bnema/gordon:latest | |||
| 61 | + | image_templates: | |||
| 62 | + | - ghcr.io/bnema/gordon:{{ .Tag }}-amd64 | |||
| 63 | + | - ghcr.io/bnema/gordon:{{ .Tag }}-arm64 | |||
| 64 | + | ||||
| 53 | archives: | 65 | archives: | ||
| 54 | - format: zip | 66 | - format: zip | ||
| 55 | name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" | 67 | name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" | ||
M build-dev.sh +2 -0
| @@ -16,3 +16,5 @@ rm -f $DIST_DIR/* | |||
| 16 | 16 | echo "Building Go binaries..." | |
| 17 | 17 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $DIST_DIR/gordon-linux-amd64 ./cmd/cli | |
| 18 | 18 | CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o $DIST_DIR/gordon-linux-arm64 ./cmd/cli | |
| 19 | + | ||
| 20 | + | echo "Successfully built Go binaries" | |
| @@ -16,3 +16,5 @@ rm -f $DIST_DIR/* | |||||
| 16 | echo "Building Go binaries..." | 16 | echo "Building Go binaries..." | ||
| 17 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $DIST_DIR/gordon-linux-amd64 ./cmd/cli | 17 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $DIST_DIR/gordon-linux-amd64 ./cmd/cli | ||
| 18 | CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o $DIST_DIR/gordon-linux-arm64 ./cmd/cli | 18 | CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o $DIST_DIR/gordon-linux-arm64 ./cmd/cli | ||
| 19 | + | ||||
| 20 | + | echo "Successfully built Go binaries" | |||
M buildpush-dev.sh +11 -3
| @@ -29,13 +29,21 @@ $ENGINE image prune -f | |||
| 29 | 29 | ||
| 30 | 30 | # Build Docker images for each architecture | |
| 31 | 31 | echo "Building Docker images..." | |
| 32 | - | $ENGINE build -t $REPO:${TAG}-amd64 --build-arg ARCH=amd64 -f Dockerfile . | |
| 33 | - | $ENGINE build -t $REPO:${TAG}-arm64v8 --build-arg ARCH=arm64 -f Dockerfile . | |
| 32 | + | for ARCH in amd64 arm64; do | |
| 33 | + | # Copy the appropriate binary to the root directory and rename it to 'gordon' | |
| 34 | + | cp $DIST_DIR/gordon-linux-$ARCH gordon | |
| 35 | + | ||
| 36 | + | # Build the Docker image | |
| 37 | + | $ENGINE build -t $REPO:${TAG}-$ARCH . | |
| 38 | + | ||
| 39 | + | # Remove the temporary 'gordon' file | |
| 40 | + | rm gordon | |
| 41 | + | done | |
| 34 | 42 | ||
| 35 | 43 | # Push images | |
| 36 | 44 | echo "Pushing Docker images..." | |
| 37 | 45 | $ENGINE push $REPO:${TAG}-amd64 | |
| 38 | - | $ENGINE push $REPO:${TAG}-arm64v8 | |
| 46 | + | $ENGINE push $REPO:${TAG}-arm64 | |
| 39 | 47 | ||
| 40 | 48 | # Remove existing manifest if it exists | |
| 41 | 49 | echo "Removing existing manifest..." | |
| @@ -29,13 +29,21 @@ $ENGINE image prune -f | |||||
| 29 | 29 | ||||
| 30 | # Build Docker images for each architecture | 30 | # Build Docker images for each architecture | ||
| 31 | echo "Building Docker images..." | 31 | echo "Building Docker images..." | ||
| 32 | - | $ENGINE build -t $REPO:${TAG}-amd64 --build-arg ARCH=amd64 -f Dockerfile . | 32 | + | for ARCH in amd64 arm64; do |
| 33 | - | $ENGINE build -t $REPO:${TAG}-arm64v8 --build-arg ARCH=arm64 -f Dockerfile . | 33 | + | # Copy the appropriate binary to the root directory and rename it to 'gordon' |
| 34 | + | cp $DIST_DIR/gordon-linux-$ARCH gordon | |||
| 35 | + | ||||
| 36 | + | # Build the Docker image | |||
| 37 | + | $ENGINE build -t $REPO:${TAG}-$ARCH . | |||
| 38 | + | ||||
| 39 | + | # Remove the temporary 'gordon' file | |||
| 40 | + | rm gordon | |||
| 41 | + | done | |||
| 34 | 42 | ||||
| 35 | # Push images | 43 | # Push images | ||
| 36 | echo "Pushing Docker images..." | 44 | echo "Pushing Docker images..." | ||
| 37 | $ENGINE push $REPO:${TAG}-amd64 | 45 | $ENGINE push $REPO:${TAG}-amd64 | ||
| 38 | - | $ENGINE push $REPO:${TAG}-arm64v8 | 46 | + | $ENGINE push $REPO:${TAG}-arm64 |
| 39 | 47 | ||||
| 40 | # Remove existing manifest if it exists | 48 | # Remove existing manifest if it exists | ||
| 41 | echo "Removing existing manifest..." | 49 | echo "Removing existing manifest..." | ||
M internal/cli/cmd/deploy.go +6 -3
| @@ -77,10 +77,13 @@ func validateInputs(imageName, port, targetDomain string) error { | |||
| 77 | 77 | if err := handler.ValidateImageName(imageName); err != nil { | |
| 78 | 78 | return err | |
| 79 | 79 | } | |
| 80 | + | ||
| 80 | 81 | handler.EnsureImageTag(&imageName) | |
| 81 | - | if err := handler.ValidatePortMapping(port); err != nil { | |
| 82 | - | return err | |
| 82 | + | ||
| 83 | + | if port == "" { | |
| 84 | + | return fmt.Errorf("port is required") | |
| 83 | 85 | } | |
| 86 | + | ||
| 84 | 87 | return handler.ValidateTargetDomain(targetDomain) | |
| 85 | 88 | } | |
| 86 | 89 | ||
| @@ -117,7 +120,7 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str | |||
| 117 | 120 | reqPayload := common.RequestPayload{ | |
| 118 | 121 | Type: "deploy", | |
| 119 | 122 | Payload: common.DeployPayload{ | |
| 120 | - | Ports: port, | |
| 123 | + | Port: port, | |
| 121 | 124 | TargetDomain: targetDomain, | |
| 122 | 125 | ImageName: imageName, | |
| 123 | 126 | Data: io.NopCloser(reader), | |
| @@ -77,10 +77,13 @@ func validateInputs(imageName, port, targetDomain string) error { | |||||
| 77 | if err := handler.ValidateImageName(imageName); err != nil { | 77 | if err := handler.ValidateImageName(imageName); err != nil { | ||
| 78 | return err | 78 | return err | ||
| 79 | } | 79 | } | ||
| 80 | + | ||||
| 80 | handler.EnsureImageTag(&imageName) | 81 | handler.EnsureImageTag(&imageName) | ||
| 81 | - | if err := handler.ValidatePortMapping(port); err != nil { | 82 | + | |
| 82 | - | return err | 83 | + | if port == "" { |
| 84 | + | return fmt.Errorf("port is required") | |||
| 83 | } | 85 | } | ||
| 86 | + | ||||
| 84 | return handler.ValidateTargetDomain(targetDomain) | 87 | return handler.ValidateTargetDomain(targetDomain) | ||
| 85 | } | 88 | } | ||
| 86 | 89 | ||||
| @@ -117,7 +120,7 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str | |||||
| 117 | reqPayload := common.RequestPayload{ | 120 | reqPayload := common.RequestPayload{ | ||
| 118 | Type: "deploy", | 121 | Type: "deploy", | ||
| 119 | Payload: common.DeployPayload{ | 122 | Payload: common.DeployPayload{ | ||
| 120 | - | Ports: port, | 123 | + | Port: port, |
| 121 | TargetDomain: targetDomain, | 124 | TargetDomain: targetDomain, | ||
| 122 | ImageName: imageName, | 125 | ImageName: imageName, | ||
| 123 | Data: io.NopCloser(reader), | 126 | Data: io.NopCloser(reader), | ||
M internal/cli/cmd/push.go +2 -8
| @@ -29,7 +29,7 @@ func NewPushCommand(a *cli.App) *cobra.Command { | |||
| 29 | 29 | imageName := args[0] | |
| 30 | 30 | log.Info("Pushing image", "image", imageName) | |
| 31 | 31 | ||
| 32 | - | if err := pushImage(a, imageName, port); err != nil { | |
| 32 | + | if err := pushImage(a, imageName); err != nil { | |
| 33 | 33 | log.Error("Push failed", "error", err) | |
| 34 | 34 | os.Exit(1) | |
| 35 | 35 | } | |
| @@ -41,19 +41,13 @@ func NewPushCommand(a *cli.App) *cobra.Command { | |||
| 41 | 41 | return pushCmd | |
| 42 | 42 | } | |
| 43 | 43 | ||
| 44 | - | func pushImage(a *cli.App, imageName, port string) error { | |
| 44 | + | func pushImage(a *cli.App, imageName string) error { | |
| 45 | 45 | if err := handler.ValidateImageName(imageName); err != nil { | |
| 46 | 46 | return fmt.Errorf("invalid image name: %w", err) | |
| 47 | 47 | } | |
| 48 | 48 | ||
| 49 | 49 | handler.EnsureImageTag(&imageName) | |
| 50 | 50 | ||
| 51 | - | if port != "" { | |
| 52 | - | if err := handler.ValidatePortMapping(port); err != nil { | |
| 53 | - | return fmt.Errorf("invalid port mapping: %w", err) | |
| 54 | - | } | |
| 55 | - | } | |
| 56 | - | ||
| 57 | 51 | reader, actualSize, err := exportDockerImage(imageName) | |
| 58 | 52 | if err != nil { | |
| 59 | 53 | return fmt.Errorf("error exporting image: %w", err) | |
| @@ -29,7 +29,7 @@ func NewPushCommand(a *cli.App) *cobra.Command { | |||||
| 29 | imageName := args[0] | 29 | imageName := args[0] | ||
| 30 | log.Info("Pushing image", "image", imageName) | 30 | log.Info("Pushing image", "image", imageName) | ||
| 31 | 31 | ||||
| 32 | - | if err := pushImage(a, imageName, port); err != nil { | 32 | + | if err := pushImage(a, imageName); err != nil { |
| 33 | log.Error("Push failed", "error", err) | 33 | log.Error("Push failed", "error", err) | ||
| 34 | os.Exit(1) | 34 | os.Exit(1) | ||
| 35 | } | 35 | } | ||
| @@ -41,19 +41,13 @@ func NewPushCommand(a *cli.App) *cobra.Command { | |||||
| 41 | return pushCmd | 41 | return pushCmd | ||
| 42 | } | 42 | } | ||
| 43 | 43 | ||||
| 44 | - | func pushImage(a *cli.App, imageName, port string) error { | 44 | + | func pushImage(a *cli.App, imageName string) error { |
| 45 | if err := handler.ValidateImageName(imageName); err != nil { | 45 | if err := handler.ValidateImageName(imageName); err != nil { | ||
| 46 | return fmt.Errorf("invalid image name: %w", err) | 46 | return fmt.Errorf("invalid image name: %w", err) | ||
| 47 | } | 47 | } | ||
| 48 | 48 | ||||
| 49 | handler.EnsureImageTag(&imageName) | 49 | handler.EnsureImageTag(&imageName) | ||
| 50 | 50 | ||||
| 51 | - | if port != "" { | |||
| 52 | - | if err := handler.ValidatePortMapping(port); err != nil { | |||
| 53 | - | return fmt.Errorf("invalid port mapping: %w", err) | |||
| 54 | - | } | |||
| 55 | - | } | |||
| 56 | - | ||||
| 57 | reader, actualSize, err := exportDockerImage(imageName) | 51 | reader, actualSize, err := exportDockerImage(imageName) | ||
| 58 | if err != nil { | 52 | if err != nil { | ||
| 59 | return fmt.Errorf("error exporting image: %w", err) | 53 | return fmt.Errorf("error exporting image: %w", err) | ||
M internal/cli/handler/http.go +1 -1
| @@ -62,7 +62,7 @@ func SendHTTPRequest(a *cli.App, rp *common.RequestPayload, method string, endpo | |||
| 62 | 62 | ||
| 63 | 63 | setAuthRequestHeaders(req, token) | |
| 64 | 64 | req.Header.Set("Content-Type", "application/octet-stream") | |
| 65 | - | req.Header.Set("X-Ports", deployPayload.Ports) | |
| 65 | + | req.Header.Set("X-Ports", deployPayload.Port) | |
| 66 | 66 | req.Header.Set("X-Target-Domain", deployPayload.TargetDomain) | |
| 67 | 67 | req.Header.Set("X-Image-Name", deployPayload.ImageName) | |
| 68 | 68 | ||
| @@ -62,7 +62,7 @@ func SendHTTPRequest(a *cli.App, rp *common.RequestPayload, method string, endpo | |||||
| 62 | 62 | ||||
| 63 | setAuthRequestHeaders(req, token) | 63 | setAuthRequestHeaders(req, token) | ||
| 64 | req.Header.Set("Content-Type", "application/octet-stream") | 64 | req.Header.Set("Content-Type", "application/octet-stream") | ||
| 65 | - | req.Header.Set("X-Ports", deployPayload.Ports) | 65 | + | req.Header.Set("X-Ports", deployPayload.Port) |
| 66 | req.Header.Set("X-Target-Domain", deployPayload.TargetDomain) | 66 | req.Header.Set("X-Target-Domain", deployPayload.TargetDomain) | ||
| 67 | req.Header.Set("X-Image-Name", deployPayload.ImageName) | 67 | req.Header.Set("X-Image-Name", deployPayload.ImageName) | ||
| 68 | 68 | ||||
M internal/common/initconfig.go +17 -2
| @@ -17,6 +17,7 @@ type Config struct { | |||
| 17 | 17 | Http HttpConfig `yaml:"Http"` | |
| 18 | 18 | Admin AdminConfig `yaml:"Admin"` | |
| 19 | 19 | ContainerEngine ContainerEngineConfig `yaml:"ContainerEngine"` | |
| 20 | + | Traefik TraefikConfig `yaml:"Traefik"` | |
| 20 | 21 | Build BuildConfig `yaml:"-"` | |
| 21 | 22 | } | |
| 22 | 23 | ||
| @@ -51,10 +52,19 @@ type ContainerEngineConfig struct { | |||
| 51 | 52 | Network string `yaml:"network"` | |
| 52 | 53 | } | |
| 53 | 54 | ||
| 55 | + | type TraefikConfig struct { | |
| 56 | + | EntryPoint string `yaml:"entryPoint"` | |
| 57 | + | SecureEntryPoint string `yaml:"secureEntryPoint"` | |
| 58 | + | Resolver string `yaml:"resolver"` | |
| 59 | + | } | |
| 60 | + | ||
| 54 | 61 | // Default values | |
| 55 | 62 | var ( | |
| 56 | - | sock = "/var/run/docker.sock" | |
| 57 | - | podmansock = "/run/user/1000/podman/podman.sock" | |
| 63 | + | sock = "/var/run/docker.sock" | |
| 64 | + | podmansock = "/run/user/1000/podman/podman.sock" | |
| 65 | + | entryPoint = "web" | |
| 66 | + | entryPointSecure = "websecure" | |
| 67 | + | resolver = "myresolver" | |
| 58 | 68 | ) | |
| 59 | 69 | ||
| 60 | 70 | func getConfigDir() (string, error) { | |
| @@ -111,6 +121,11 @@ func (config *Config) LoadConfig() (*Config, error) { | |||
| 111 | 121 | PodmanSock: podmansock, | |
| 112 | 122 | Podman: ReadUserInput("Are you using podman ? (y/n)") == "y", | |
| 113 | 123 | }, | |
| 124 | + | Traefik: TraefikConfig{ | |
| 125 | + | EntryPoint: entryPoint, | |
| 126 | + | SecureEntryPoint: entryPointSecure, | |
| 127 | + | Resolver: resolver, | |
| 128 | + | }, | |
| 114 | 129 | } | |
| 115 | 130 | ||
| 116 | 131 | err = config.SaveConfig() | |
| @@ -17,6 +17,7 @@ type Config struct { | |||||
| 17 | Http HttpConfig `yaml:"Http"` | 17 | Http HttpConfig `yaml:"Http"` | ||
| 18 | Admin AdminConfig `yaml:"Admin"` | 18 | Admin AdminConfig `yaml:"Admin"` | ||
| 19 | ContainerEngine ContainerEngineConfig `yaml:"ContainerEngine"` | 19 | ContainerEngine ContainerEngineConfig `yaml:"ContainerEngine"` | ||
| 20 | + | Traefik TraefikConfig `yaml:"Traefik"` | |||
| 20 | Build BuildConfig `yaml:"-"` | 21 | Build BuildConfig `yaml:"-"` | ||
| 21 | } | 22 | } | ||
| 22 | 23 | ||||
| @@ -51,10 +52,19 @@ type ContainerEngineConfig struct { | |||||
| 51 | Network string `yaml:"network"` | 52 | Network string `yaml:"network"` | ||
| 52 | } | 53 | } | ||
| 53 | 54 | ||||
| 55 | + | type TraefikConfig struct { | |||
| 56 | + | EntryPoint string `yaml:"entryPoint"` | |||
| 57 | + | SecureEntryPoint string `yaml:"secureEntryPoint"` | |||
| 58 | + | Resolver string `yaml:"resolver"` | |||
| 59 | + | } | |||
| 60 | + | ||||
| 54 | // Default values | 61 | // Default values | ||
| 55 | var ( | 62 | var ( | ||
| 56 | - | sock = "/var/run/docker.sock" | 63 | + | sock = "/var/run/docker.sock" |
| 57 | - | podmansock = "/run/user/1000/podman/podman.sock" | 64 | + | podmansock = "/run/user/1000/podman/podman.sock" |
| 65 | + | entryPoint = "web" | |||
| 66 | + | entryPointSecure = "websecure" | |||
| 67 | + | resolver = "myresolver" | |||
| 58 | ) | 68 | ) | ||
| 59 | 69 | ||||
| 60 | func getConfigDir() (string, error) { | 70 | func getConfigDir() (string, error) { | ||
| @@ -111,6 +121,11 @@ func (config *Config) LoadConfig() (*Config, error) { | |||||
| 111 | PodmanSock: podmansock, | 121 | PodmanSock: podmansock, | ||
| 112 | Podman: ReadUserInput("Are you using podman ? (y/n)") == "y", | 122 | Podman: ReadUserInput("Are you using podman ? (y/n)") == "y", | ||
| 113 | }, | 123 | }, | ||
| 124 | + | Traefik: TraefikConfig{ | |||
| 125 | + | EntryPoint: entryPoint, | |||
| 126 | + | SecureEntryPoint: entryPointSecure, | |||
| 127 | + | Resolver: resolver, | |||
| 128 | + | }, | |||
| 114 | } | 129 | } | ||
| 115 | 130 | ||||
| 116 | err = config.SaveConfig() | 131 | err = config.SaveConfig() | ||
M internal/common/payload.go +1 -1
| @@ -38,7 +38,7 @@ func (e *DeploymentError) Error() string { | |||
| 38 | 38 | } | |
| 39 | 39 | ||
| 40 | 40 | type DeployPayload struct { | |
| 41 | - | Ports string `json:"ports"` | |
| 41 | + | Port string `json:"port"` | |
| 42 | 42 | TargetDomain string `json:"targetdomain"` | |
| 43 | 43 | ImageName string `json:"imagename"` | |
| 44 | 44 | ImageID string `json:"imageid"` | |
| @@ -38,7 +38,7 @@ func (e *DeploymentError) Error() string { | |||||
| 38 | } | 38 | } | ||
| 39 | 39 | ||||
| 40 | type DeployPayload struct { | 40 | type DeployPayload struct { | ||
| 41 | - | Ports string `json:"ports"` | 41 | + | Port string `json:"port"` |
| 42 | TargetDomain string `json:"targetdomain"` | 42 | TargetDomain string `json:"targetdomain"` | ||
| 43 | ImageName string `json:"imagename"` | 43 | ImageName string `json:"imagename"` | ||
| 44 | ImageID string `json:"imageid"` | 44 | ImageID string `json:"imageid"` | ||
M internal/httpserve/handler/cli-endpoints.go +3 -3
| @@ -130,7 +130,7 @@ func PostPush(c echo.Context, a *server.App) error { | |||
| 130 | 130 | func PostDeploy(c echo.Context, a *server.App) error { | |
| 131 | 131 | // Initialize pushPayload object | |
| 132 | 132 | payload := &common.DeployPayload{ | |
| 133 | - | Ports: c.Request().Header.Get("X-Ports"), | |
| 133 | + | Port: c.Request().Header.Get("X-Ports"), | |
| 134 | 134 | ImageName: c.Request().Header.Get("X-Image-Name"), | |
| 135 | 135 | TargetDomain: c.Request().Header.Get("X-Target-Domain"), | |
| 136 | 136 | } | |
| @@ -149,8 +149,8 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||
| 149 | 149 | imageFileName = imageFileName + ".tar" | |
| 150 | 150 | ||
| 151 | 151 | // Check the ports struct, if there is no /tcp, or /udp, add /tcp | |
| 152 | - | if !regexp.MustCompile(`\/(tcp|udp)$`).MatchString(payload.Ports) { | |
| 153 | - | payload.Ports = payload.Ports + "/tcp" | |
| 152 | + | if !regexp.MustCompile(`\/(tcp|udp)$`).MatchString(payload.Port) { | |
| 153 | + | payload.Port = payload.Port + "/tcp" | |
| 154 | 154 | } | |
| 155 | 155 | ||
| 156 | 156 | // Check the target domain, if there is no https:// or http://, add https:// | |
| @@ -130,7 +130,7 @@ func PostPush(c echo.Context, a *server.App) error { | |||||
| 130 | func PostDeploy(c echo.Context, a *server.App) error { | 130 | func PostDeploy(c echo.Context, a *server.App) error { | ||
| 131 | // Initialize pushPayload object | 131 | // Initialize pushPayload object | ||
| 132 | payload := &common.DeployPayload{ | 132 | payload := &common.DeployPayload{ | ||
| 133 | - | Ports: c.Request().Header.Get("X-Ports"), | 133 | + | Port: c.Request().Header.Get("X-Ports"), |
| 134 | ImageName: c.Request().Header.Get("X-Image-Name"), | 134 | ImageName: c.Request().Header.Get("X-Image-Name"), | ||
| 135 | TargetDomain: c.Request().Header.Get("X-Target-Domain"), | 135 | TargetDomain: c.Request().Header.Get("X-Target-Domain"), | ||
| 136 | } | 136 | } | ||
| @@ -149,8 +149,8 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||||
| 149 | imageFileName = imageFileName + ".tar" | 149 | imageFileName = imageFileName + ".tar" | ||
| 150 | 150 | ||||
| 151 | // Check the ports struct, if there is no /tcp, or /udp, add /tcp | 151 | // Check the ports struct, if there is no /tcp, or /udp, add /tcp | ||
| 152 | - | if !regexp.MustCompile(`\/(tcp|udp)$`).MatchString(payload.Ports) { | 152 | + | if !regexp.MustCompile(`\/(tcp|udp)$`).MatchString(payload.Port) { |
| 153 | - | payload.Ports = payload.Ports + "/tcp" | 153 | + | payload.Port = payload.Port + "/tcp" |
| 154 | } | 154 | } | ||
| 155 | 155 | ||||
| 156 | // Check the target domain, if there is no https:// or http://, add https:// | 156 | // Check the target domain, if there is no https:// or http://, add https:// | ||
M internal/templating/cmdparams/fromcli.go +4 -7
| @@ -18,11 +18,6 @@ func FromPayloadStructToCmdParams(ppl *common.DeployPayload, a *server.App, imag | |||
| 18 | 18 | ||
| 19 | 19 | environmentSlice := ParseEnvironmentSlice("") | |
| 20 | 20 | ||
| 21 | - | portMappings, err := ParsePortMappingsSlice(ppl.Ports) | |
| 22 | - | if err != nil { | |
| 23 | - | return docker.ContainerCommandParams{}, err | |
| 24 | - | } | |
| 25 | - | ||
| 26 | 21 | // from ppl.TargetDomain, (eg. "https://test.example.com") get container_name (eg. "test"), get container_subdomain (eg. "test"), get container_domain (eg. "example.com") and get container_protocol (eg. "https") | |
| 27 | 22 | // Parse TargetDomain to get the various components | |
| 28 | 23 | parsedURL, err := url.Parse(ppl.TargetDomain) | |
| @@ -52,10 +47,12 @@ func FromPayloadStructToCmdParams(ppl *common.DeployPayload, a *server.App, imag | |||
| 52 | 47 | Volumes: volumeSlice, | |
| 53 | 48 | Environment: environmentSlice, | |
| 54 | 49 | Network: a.Config.ContainerEngine.Network, | |
| 55 | - | PortMappings: portMappings, | |
| 56 | 50 | } | |
| 57 | 51 | ||
| 58 | - | CreateTraefikLabels(¶ms) | |
| 52 | + | err = CreateTraefikLabels(¶ms, ppl.Port, a) | |
| 53 | + | if err != nil { | |
| 54 | + | return docker.ContainerCommandParams{}, fmt.Errorf("error creating Traefik labels: %w", err) | |
| 55 | + | } | |
| 59 | 56 | ||
| 60 | 57 | return params, nil | |
| 61 | 58 | } | |
| @@ -18,11 +18,6 @@ func FromPayloadStructToCmdParams(ppl *common.DeployPayload, a *server.App, imag | |||||
| 18 | 18 | ||||
| 19 | environmentSlice := ParseEnvironmentSlice("") | 19 | environmentSlice := ParseEnvironmentSlice("") | ||
| 20 | 20 | ||||
| 21 | - | portMappings, err := ParsePortMappingsSlice(ppl.Ports) | |||
| 22 | - | if err != nil { | |||
| 23 | - | return docker.ContainerCommandParams{}, err | |||
| 24 | - | } | |||
| 25 | - | ||||
| 26 | // from ppl.TargetDomain, (eg. "https://test.example.com") get container_name (eg. "test"), get container_subdomain (eg. "test"), get container_domain (eg. "example.com") and get container_protocol (eg. "https") | 21 | // from ppl.TargetDomain, (eg. "https://test.example.com") get container_name (eg. "test"), get container_subdomain (eg. "test"), get container_domain (eg. "example.com") and get container_protocol (eg. "https") | ||
| 27 | // Parse TargetDomain to get the various components | 22 | // Parse TargetDomain to get the various components | ||
| 28 | parsedURL, err := url.Parse(ppl.TargetDomain) | 23 | parsedURL, err := url.Parse(ppl.TargetDomain) | ||
| @@ -52,10 +47,12 @@ func FromPayloadStructToCmdParams(ppl *common.DeployPayload, a *server.App, imag | |||||
| 52 | Volumes: volumeSlice, | 47 | Volumes: volumeSlice, | ||
| 53 | Environment: environmentSlice, | 48 | Environment: environmentSlice, | ||
| 54 | Network: a.Config.ContainerEngine.Network, | 49 | Network: a.Config.ContainerEngine.Network, | ||
| 55 | - | PortMappings: portMappings, | |||
| 56 | } | 50 | } | ||
| 57 | 51 | ||||
| 58 | - | CreateTraefikLabels(¶ms) | 52 | + | err = CreateTraefikLabels(¶ms, ppl.Port, a) |
| 53 | + | if err != nil { | |||
| 54 | + | return docker.ContainerCommandParams{}, fmt.Errorf("error creating Traefik labels: %w", err) | |||
| 55 | + | } | |||
| 59 | 56 | ||||
| 60 | return params, nil | 57 | return params, nil | ||
| 61 | } | 58 | } | ||
M internal/templating/cmdparams/frominputs.go +17 -1
| @@ -1,6 +1,8 @@ | |||
| 1 | 1 | package cmdparams | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | + | "fmt" | |
| 5 | + | ||
| 4 | 6 | "github.com/bnema/gordon/internal/server" | |
| 5 | 7 | "github.com/bnema/gordon/pkg/docker" | |
| 6 | 8 | ) | |
| @@ -10,6 +12,10 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont | |||
| 10 | 12 | volumeSlice := ParseVolumeSlice(inputs["volumes"]) | |
| 11 | 13 | environmentSlice := ParseEnvironmentSlice(inputs["environment_variables"]) | |
| 12 | 14 | portMappings, err := ParsePortMappingsSlice(inputs["ports"]) | |
| 15 | + | ||
| 16 | + | // Extract the container port (right side of the mapping) | |
| 17 | + | containerPort := extractContainerPort(portMappings) | |
| 18 | + | ||
| 13 | 19 | if err != nil { | |
| 14 | 20 | return docker.ContainerCommandParams{}, err | |
| 15 | 21 | } | |
| @@ -28,7 +34,17 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont | |||
| 28 | 34 | PortMappings: portMappings, | |
| 29 | 35 | } | |
| 30 | 36 | ||
| 31 | - | CreateTraefikLabels(¶ms) | |
| 37 | + | err = CreateTraefikLabels(¶ms, containerPort, a) | |
| 38 | + | if err != nil { | |
| 39 | + | return docker.ContainerCommandParams{}, fmt.Errorf("error creating Traefik labels: %w", err) | |
| 40 | + | } | |
| 32 | 41 | ||
| 33 | 42 | return params, nil | |
| 34 | 43 | } | |
| 44 | + | ||
| 45 | + | func extractContainerPort(portMappings []docker.PortMapping) string { | |
| 46 | + | if len(portMappings) > 0 { | |
| 47 | + | return portMappings[0].ContainerPort | |
| 48 | + | } | |
| 49 | + | return "" | |
| 50 | + | } | |
| @@ -1,6 +1,8 @@ | |||||
| 1 | package cmdparams | 1 | package cmdparams | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | + | "fmt" | |||
| 5 | + | ||||
| 4 | "github.com/bnema/gordon/internal/server" | 6 | "github.com/bnema/gordon/internal/server" | ||
| 5 | "github.com/bnema/gordon/pkg/docker" | 7 | "github.com/bnema/gordon/pkg/docker" | ||
| 6 | ) | 8 | ) | ||
| @@ -10,6 +12,10 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont | |||||
| 10 | volumeSlice := ParseVolumeSlice(inputs["volumes"]) | 12 | volumeSlice := ParseVolumeSlice(inputs["volumes"]) | ||
| 11 | environmentSlice := ParseEnvironmentSlice(inputs["environment_variables"]) | 13 | environmentSlice := ParseEnvironmentSlice(inputs["environment_variables"]) | ||
| 12 | portMappings, err := ParsePortMappingsSlice(inputs["ports"]) | 14 | portMappings, err := ParsePortMappingsSlice(inputs["ports"]) | ||
| 15 | + | ||||
| 16 | + | // Extract the container port (right side of the mapping) | |||
| 17 | + | containerPort := extractContainerPort(portMappings) | |||
| 18 | + | ||||
| 13 | if err != nil { | 19 | if err != nil { | ||
| 14 | return docker.ContainerCommandParams{}, err | 20 | return docker.ContainerCommandParams{}, err | ||
| 15 | } | 21 | } | ||
| @@ -28,7 +34,17 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont | |||||
| 28 | PortMappings: portMappings, | 34 | PortMappings: portMappings, | ||
| 29 | } | 35 | } | ||
| 30 | 36 | ||||
| 31 | - | CreateTraefikLabels(¶ms) | 37 | + | err = CreateTraefikLabels(¶ms, containerPort, a) |
| 38 | + | if err != nil { | |||
| 39 | + | return docker.ContainerCommandParams{}, fmt.Errorf("error creating Traefik labels: %w", err) | |||
| 40 | + | } | |||
| 32 | 41 | ||||
| 33 | return params, nil | 42 | return params, nil | ||
| 34 | } | 43 | } | ||
| 44 | + | ||||
| 45 | + | func extractContainerPort(portMappings []docker.PortMapping) string { | |||
| 46 | + | if len(portMappings) > 0 { | |||
| 47 | + | return portMappings[0].ContainerPort | |||
| 48 | + | } | |||
| 49 | + | return "" | |||
| 50 | + | } | |||
M internal/templating/cmdparams/traefik.go +14 -6
| @@ -3,27 +3,35 @@ package cmdparams | |||
| 3 | 3 | import ( | |
| 4 | 4 | "fmt" | |
| 5 | 5 | ||
| 6 | + | "github.com/bnema/gordon/internal/server" | |
| 6 | 7 | "github.com/bnema/gordon/pkg/docker" | |
| 7 | 8 | ) | |
| 8 | 9 | ||
| 9 | 10 | // CreateTraefikLabels creates Traefik labels based on the provided parameters. | |
| 10 | - | func CreateTraefikLabels(params *docker.ContainerCommandParams) { | |
| 11 | - | entryPoint := "web" | |
| 11 | + | func CreateTraefikLabels(params *docker.ContainerCommandParams, portEntryPoint string, a *server.App) error { | |
| 12 | + | entryPoint := a.Config.Traefik.EntryPoint | |
| 12 | 13 | if params.IsSSL { | |
| 13 | - | entryPoint = "websecure" | |
| 14 | + | entryPoint = a.Config.Traefik.SecureEntryPoint | |
| 14 | 15 | } | |
| 16 | + | ||
| 15 | 17 | baseRouter := "traefik.http.routers." + params.ContainerName | |
| 16 | 18 | baseService := "traefik.http.services." + params.ContainerName | |
| 17 | - | exposedPort := params.PortMappings[0].ContainerPort | |
| 18 | 19 | ||
| 19 | 20 | params.Labels = []string{ | |
| 20 | 21 | "traefik.enable=true", | |
| 21 | 22 | fmt.Sprintf("%s.rule=Host(`%s.%s`)", baseRouter, params.ServiceName, params.Domain), | |
| 22 | 23 | fmt.Sprintf("%s.entrypoints=%s", baseRouter, entryPoint), | |
| 23 | - | fmt.Sprintf("%s.loadbalancer.server.port=%s", baseService, exposedPort), | |
| 24 | + | fmt.Sprintf("%s.loadbalancer.server.port=%s", baseService, portEntryPoint), | |
| 25 | + | } | |
| 26 | + | ||
| 27 | + | resolver := a.Config.Traefik.Resolver | |
| 28 | + | if resolver == "" { | |
| 29 | + | fmt.Errorf("resolver not set in config") | |
| 24 | 30 | } | |
| 25 | 31 | ||
| 26 | 32 | if params.IsSSL { | |
| 27 | - | params.Labels = append(params.Labels, fmt.Sprintf("%s.tls.certresolver=myresolver", baseRouter)) | |
| 33 | + | params.Labels = append(params.Labels, fmt.Sprintf("%s.tls.certresolver=%s", baseRouter, resolver)) | |
| 28 | 34 | } | |
| 35 | + | ||
| 36 | + | return nil | |
| 29 | 37 | } | |
| @@ -3,27 +3,35 @@ package cmdparams | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "fmt" | 4 | "fmt" | ||
| 5 | 5 | ||||
| 6 | + | "github.com/bnema/gordon/internal/server" | |||
| 6 | "github.com/bnema/gordon/pkg/docker" | 7 | "github.com/bnema/gordon/pkg/docker" | ||
| 7 | ) | 8 | ) | ||
| 8 | 9 | ||||
| 9 | // CreateTraefikLabels creates Traefik labels based on the provided parameters. | 10 | // CreateTraefikLabels creates Traefik labels based on the provided parameters. | ||
| 10 | - | func CreateTraefikLabels(params *docker.ContainerCommandParams) { | 11 | + | func CreateTraefikLabels(params *docker.ContainerCommandParams, portEntryPoint string, a *server.App) error { |
| 11 | - | entryPoint := "web" | 12 | + | entryPoint := a.Config.Traefik.EntryPoint |
| 12 | if params.IsSSL { | 13 | if params.IsSSL { | ||
| 13 | - | entryPoint = "websecure" | 14 | + | entryPoint = a.Config.Traefik.SecureEntryPoint |
| 14 | } | 15 | } | ||
| 16 | + | ||||
| 15 | baseRouter := "traefik.http.routers." + params.ContainerName | 17 | baseRouter := "traefik.http.routers." + params.ContainerName | ||
| 16 | baseService := "traefik.http.services." + params.ContainerName | 18 | baseService := "traefik.http.services." + params.ContainerName | ||
| 17 | - | exposedPort := params.PortMappings[0].ContainerPort | |||
| 18 | 19 | ||||
| 19 | params.Labels = []string{ | 20 | params.Labels = []string{ | ||
| 20 | "traefik.enable=true", | 21 | "traefik.enable=true", | ||
| 21 | fmt.Sprintf("%s.rule=Host(`%s.%s`)", baseRouter, params.ServiceName, params.Domain), | 22 | fmt.Sprintf("%s.rule=Host(`%s.%s`)", baseRouter, params.ServiceName, params.Domain), | ||
| 22 | fmt.Sprintf("%s.entrypoints=%s", baseRouter, entryPoint), | 23 | fmt.Sprintf("%s.entrypoints=%s", baseRouter, entryPoint), | ||
| 23 | - | fmt.Sprintf("%s.loadbalancer.server.port=%s", baseService, exposedPort), | 24 | + | fmt.Sprintf("%s.loadbalancer.server.port=%s", baseService, portEntryPoint), |
| 25 | + | } | |||
| 26 | + | ||||
| 27 | + | resolver := a.Config.Traefik.Resolver | |||
| 28 | + | if resolver == "" { | |||
| 29 | + | fmt.Errorf("resolver not set in config") | |||
| 24 | } | 30 | } | ||
| 25 | 31 | ||||
| 26 | if params.IsSSL { | 32 | if params.IsSSL { | ||
| 27 | - | params.Labels = append(params.Labels, fmt.Sprintf("%s.tls.certresolver=myresolver", baseRouter)) | 33 | + | params.Labels = append(params.Labels, fmt.Sprintf("%s.tls.certresolver=%s", baseRouter, resolver)) |
| 28 | } | 34 | } | ||
| 35 | + | ||||
| 36 | + | return nil | |||
| 29 | } | 37 | } | ||