From bcd67bc3f6ff1cbbfd9e88717b8bfdd91cbe52ed Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Thu, 11 May 2023 23:17:46 +0100 Subject: [PATCH] feat: add Work Flow to Flow Platform - Deploy Work Flow (woodpecker) to the Flow Platform. - Enable oauth2 in Code Flow. --- config | 2 +- magefiles/config.go | 22 ++++++++++ templates/compose/docker-compose.yaml.gotmpl | 41 ++++++++++++++++++- templates/forgejo/app.ini.gotmpl | 4 +- templates/woodpecker/Dockerfile.gotmpl | 28 +++++++++++++ templates/woodpecker/entrypoint.sh.gotmpl | 12 ++++++ .../woodpecker/traefik_woodpecker.yaml.gotmpl | 26 ++++++++++++ 7 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 templates/woodpecker/Dockerfile.gotmpl create mode 100644 templates/woodpecker/entrypoint.sh.gotmpl create mode 100644 templates/woodpecker/traefik_woodpecker.yaml.gotmpl diff --git a/config b/config index c7e82ff..e4d0eb1 160000 --- a/config +++ b/config @@ -1 +1 @@ -Subproject commit c7e82ff40b7478a16d11e89b815f83e6c698cfc6 +Subproject commit e4d0eb1388ef090fe38107476c5b5298bed3dbd8 diff --git a/magefiles/config.go b/magefiles/config.go index 233cddc..c5c69ac 100644 --- a/magefiles/config.go +++ b/magefiles/config.go @@ -16,6 +16,7 @@ type config struct { Traefik traefikConfig `json:"traefik"` Forgejo forgejoConfig `json:"forgejo"` GoToSocial gotosocialConfig `json:"gotosocial"` + Woodpecker woodpeckerConfig `json:"woodpecker"` } type traefikConfig struct { @@ -55,6 +56,9 @@ type forgejoConfig struct { SecretKey string `json:"secretKey"` InternalToken string `json:"internalToken"` LfsJwtSecret string `json:"lfsJwtSecret"` + Oauth2Enable bool `json:"oauth2Enable"` + Oauth2JwtSigningAlgo string `json:"oauth2JwtSigningAlgo"` + Oauth2JwtSecret string `json:"oauth2JwtSecret"` } type gotosocialConfig struct { @@ -69,6 +73,24 @@ type gotosocialConfig struct { DataContainerDirectory string `json:"dataContainerDirectory"` } +type woodpeckerConfig struct { + Version string `json:"version"` + LogLevel string `json:"logLevel"` + LinuxUID int32 `json:"linuxUID"` + Subdomain string `json:"subdomain"` + GrpcSubdomain string `json:"grpcSubdomain"` + ContainerIpv4Address string `json:"containerIpv4Address"` + HttpPort int32 `json:"httpPort"` + GrpcPort int32 `json:"grpcPort"` + DataHostDirectory string `json:"dataHostDirectory"` + DataContainerDirectory string `json:"dataContainerDirectory"` + Admin string `json:"admin"` + Open bool `json:"open"` + AgentSecret string `json:"agentSecret"` + ForgejoClientID string `json:"forgejoClientID"` + ForgejoClientSecret string `json:"forgejoClientSecret"` +} + func newConfig(path string) (config, error) { var c config diff --git a/templates/compose/docker-compose.yaml.gotmpl b/templates/compose/docker-compose.yaml.gotmpl index b088190..0c48ac0 100644 --- a/templates/compose/docker-compose.yaml.gotmpl +++ b/templates/compose/docker-compose.yaml.gotmpl @@ -80,7 +80,7 @@ services: - type: "bind" source: "{{ .Forgejo.DataHostDirectory }}" target: "{{ .Forgejo.DataContainerDirectory }}" - # -- Free Flow 2 -- + # -- Free Flow -- gotosocial: container_name: "free-flow" image: "localhost/flow/gotosocial:{{ .GoToSocial.Version }}" @@ -102,3 +102,42 @@ services: - type: "bind" source: "{{ .GoToSocial.DataHostDirectory }}" target: "{{ .GoToSocial.DataContainerDirectory }}" + # -- Work Flow -- + woodpecker: + container_name: "work-flow" + image: "localhost/flow/woodpecker:{{ .Woodpecker.Version }}" + build: + context: "../woodpecker" + environment: + WOODPECKER_LOG_LEVEL: "{{ .Woodpecker.LogLevel }}" + WOODPECKER_HOST: "https://{{ .Woodpecker.Subdomain }}.{{ .RootDomain }}" + WOODPECKER_SERVER_ADDR: "{{ .Woodpecker.ContainerIpv4Address }}:{{ .Woodpecker.HttpPort }}" + WOODPECKER_GRPC_ADDR: "{{ .Woodpecker.ContainerIpv4Address }}:{{ .Woodpecker.GrpcPort }}" + WOODPECKER_LETS_ENCRYPT: "false" + WOODPECKER_ADMIN: "{{ .Woodpecker.Admin }}" + WOODPECKER_OPEN: "{{ .Woodpecker.Open }}" + WOODPECKER_AGENT_SECRET: "{{ .Woodpecker.AgentSecret }}" + WOODPECKER_DATABASE_DRIVER: "sqlite3" + WOODPECKER_DATABASE_DATASOURCE: "{{ .Woodpecker.DataContainerDirectory }}/woodpecker.db" + WOODPECKER_GITEA: "true" + WOODPECKER_GITEA_URL: "https://{{ .Forgejo.Subdomain }}.{{ .RootDomain }}" + WOODPECKER_GITEA_CLIENT: "{{ .Woodpecker.ForgejoClientID }}" + WOODPECKER_GITEA_SECRET: "{{ .Woodpecker.ForgejoClientSecret }}" + WOODPECKER_GITEA_SKIP_VERIFY: "false" + expose: + - "{{ .Woodpecker.HttpPort }}" + - "{{ .Woodpecker.GrpcPort }}" + networks: + flow: + ipv4_address: "{{ .Woodpecker.ContainerIpv4Address }}" + restart: "always" + volumes: + {{- template "defaultVolumes" }} + # Shared volume + - type: "volume" + source: "traefik-shared" + target: "{{ .Traefik.SharedMountPoint }}" + # Woodpecker data volume + - type: "bind" + source: "{{ .Woodpecker.DataHostDirectory }}" + target: "{{ .Woodpecker.DataContainerDirectory }}" diff --git a/templates/forgejo/app.ini.gotmpl b/templates/forgejo/app.ini.gotmpl index 7662011..a267111 100644 --- a/templates/forgejo/app.ini.gotmpl +++ b/templates/forgejo/app.ini.gotmpl @@ -106,7 +106,9 @@ SHOW_FOOTER_VERSION = false SHOW_FOOTER_TEMPLATE_LOAD_TIME = false [oauth2] -ENABLE = false +ENABLE = {{ .Forgejo.Oauth2Enable }} +JWT_SIGNING_ALGORITHM = {{ .Forgejo.Oauth2JwtSigningAlgo }} +JWT_SECRET = {{ .Forgejo.Oauth2JwtSecret }} [federation] ENABLED = true diff --git a/templates/woodpecker/Dockerfile.gotmpl b/templates/woodpecker/Dockerfile.gotmpl new file mode 100644 index 0000000..b9f63e5 --- /dev/null +++ b/templates/woodpecker/Dockerfile.gotmpl @@ -0,0 +1,28 @@ +# syntax=docker/dockerfile:1 +FROM alpine:3.17 + +WORKDIR /tmp + +RUN --mount=type=bind,source=.,target=/packages \ + apk update --no-cache && apk add --no-cache \ + bash \ + ca-certificates \ + && addgroup -g {{ .FlowGID }} flow \ + && adduser -S -H -D -s /bin/bash -u {{ .Woodpecker.LinuxUID }} -G flow workflow \ + && mkdir -p {{ .Woodpecker.DataContainerDirectory }} \ + && chown {{ .Woodpecker.LinuxUID }}:{{ .Woodpecker.LinuxUID }} {{ .Woodpecker.DataContainerDirectory }} \ + && chmod 0700 {{ .Woodpecker.DataContainerDirectory }} \ + && tar xzvf /packages/woodpecker-server-{{ .Woodpecker.Version }}_linux_amd64.tar.gz \ + && mv /tmp/woodpecker-server /usr/local/bin/woodpecker-server \ + && rm -rf /tmp/* + +COPY --chown={{ .Woodpecker.LinuxUID }}:{{ .Woodpecker.LinuxUID }} entrypoint.sh /usr/local/bin/entrypoint +COPY --chown={{ .Woodpecker.LinuxUID }}:{{ .FlowGID }} traefik_woodpecker.yaml /flow/woodpecker/tmp/traefik_woodpecker.yaml + +RUN chmod a+x /usr/local/bin/entrypoint + +ENV GODEBUG=netdns=go + +USER {{ .Woodpecker.LinuxUID }}:{{ .FlowGID }} + +ENTRYPOINT ["entrypoint"] diff --git a/templates/woodpecker/entrypoint.sh.gotmpl b/templates/woodpecker/entrypoint.sh.gotmpl new file mode 100644 index 0000000..d157e00 --- /dev/null +++ b/templates/woodpecker/entrypoint.sh.gotmpl @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +# Move the dynamic traefik config to the shared volume +if [ -f /flow/woodpecker/tmp/traefik_woodpecker.yaml ]; then + mv /flow/woodpecker/tmp/traefik_woodpecker.yaml {{ .Traefik.SharedMountPoint }}/dynamic/traefik_woodpecker.yaml +fi + +exec woodpecker-server diff --git a/templates/woodpecker/traefik_woodpecker.yaml.gotmpl b/templates/woodpecker/traefik_woodpecker.yaml.gotmpl new file mode 100644 index 0000000..d8c1451 --- /dev/null +++ b/templates/woodpecker/traefik_woodpecker.yaml.gotmpl @@ -0,0 +1,26 @@ +--- +http: + routers: + woodpecker: + entryPoints: + - "https" + rule: "Host(`{{ .Woodpecker.Subdomain }}.{{ .RootDomain }}`)" + service: "woodpecker" + tls: + certResolver: resolver + woodpecker-grpc: + entryPoints: + - "https" + rule: "Host(`{{ .Woodpecker.GrpcSubdomain }}.{{ .RootDomain }}`)" + service: "woodpecker-grpc" + tls: + certResolver: resolver + services: + woodpecker: + loadBalancer: + servers: + - url: "http://{{ .Woodpecker.ContainerIpv4Address }}:{{ .Woodpecker.HttpPort }}/" + woodpecker-grpc: + loadBalancer: + servers: + - url: "h2c://{{ .Woodpecker.ContainerIpv4Address }}:{{ .Woodpecker.GrpcPort }}"