Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ services:

The agents will use `WOODPECKER_GRPC_ADDR` and a token automatically generated by the autoscaler to connect to the server.Therefore the `WOODPECKER_GRPC_ADDR` has to be publicly accessible from the newly created agents. Check for example how you could use [caddy](https://woodpecker-ci.org/docs/administration/configuration/server#caddy) to expose the grpc connection.

### Oracle Cloud

Set `WOODPECKER_PROVIDER=oracle` and provide an OCI config file through the default SDK lookup (`~/.oci/config`) or `WOODPECKER_ORACLE_CONFIG_FILE`. The autoscaler launches instances from an image OCID and tags them with the autoscaler pool so only agents from the configured pool are listed or terminated.

Required Oracle-specific settings:

- `WOODPECKER_ORACLE_COMPARTMENT_ID`
- `WOODPECKER_ORACLE_AVAILABILITY_DOMAIN`
- `WOODPECKER_ORACLE_SUBNET_ID`
- `WOODPECKER_ORACLE_IMAGE_ID`
- `WOODPECKER_ORACLE_SHAPE`
- `WOODPECKER_ORACLE_SSH_AUTHORIZED_KEY`

Optional settings include `WOODPECKER_ORACLE_REGION`, `WOODPECKER_ORACLE_PROFILE`, `WOODPECKER_ORACLE_OCPUS`, `WOODPECKER_ORACLE_MEMORY_GBS`, `WOODPECKER_ORACLE_ASSIGN_PUBLIC_IP`, and `WOODPECKER_ORACLE_FREEFORM_TAGS`.

## Roadmap

- [ ] Add support for multiple providers
Expand All @@ -44,7 +59,7 @@ The agents will use `WOODPECKER_GRPC_ADDR` and a token automatically generated b
- [ ] Azure
- [ ] Digital Ocean
- [x] Linode (temp disabled until the [security issue](https://github.com/woodpecker-ci/autoscaler/issues/91) was addressed)
- [ ] Oracle Cloud
- [x] Oracle Cloud
- [ ] Equinix Metal
- [x] Vultr
- [x] Scaleway
Expand Down
4 changes: 4 additions & 0 deletions cmd/woodpecker-autoscaler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"go.woodpecker-ci.org/autoscaler/engine/types"
"go.woodpecker-ci.org/autoscaler/providers/aws"
"go.woodpecker-ci.org/autoscaler/providers/hetznercloud"
"go.woodpecker-ci.org/autoscaler/providers/oracle"
"go.woodpecker-ci.org/autoscaler/providers/scaleway"
"go.woodpecker-ci.org/autoscaler/providers/vultr"
"go.woodpecker-ci.org/autoscaler/server"
Expand All @@ -33,6 +34,8 @@ func setupProvider(ctx context.Context, cmd *cli.Command, config *config.Config)
// Enable it again when the issue is fixed.
// case "linode":
// return linode.New(ctx, config)
case "oracle":
return oracle.New(ctx, cmd, config)
case "vultr":
return vultr.New(ctx, cmd, config)
case "scaleway":
Expand Down Expand Up @@ -168,6 +171,7 @@ func main() {
// Enable it again when the issue is fixed.
// app.Flags = append(app.Flags, linode.ProviderFlags...)
app.Flags = append(app.Flags, aws.ProviderFlags...)
app.Flags = append(app.Flags, oracle.ProviderFlags...)
app.Flags = append(app.Flags, vultr.ProviderFlags...)

if err := app.Run(context.Background(), os.Args); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/hetznercloud/hcloud-go/v2 v2.40.0
github.com/joho/godotenv v1.5.1
github.com/linode/linodego v1.69.1
github.com/oracle/oci-go-sdk/v65 v65.114.2
github.com/rs/zerolog v1.35.1
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36
github.com/stretchr/testify v1.11.1
Expand Down Expand Up @@ -40,6 +41,7 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/go-resty/resty/v2 v2.17.2 // indirect
github.com/gofrs/flock v0.10.0 // indirect
github.com/google/go-querystring v1.2.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
Expand All @@ -51,8 +53,11 @@ require (
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/sony/gobreaker/v2 v2.4.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/crypto v0.51.0 // indirect
golang.org/x/sys v0.44.0 // indirect
golang.org/x/text v0.37.0 // indirect
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
Expand Down
14 changes: 12 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk=
github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
github.com/gofrs/flock v0.10.0 h1:SHMXenfaB03KbroETaCMtbBg3Yn29v4w1r+tgy4ff4k=
github.com/gofrs/flock v0.10.0/go.mod h1:FirDy1Ing0mI2+kB6wk+vyyAH+e6xiE+EYA0jnzV9jc=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
Expand Down Expand Up @@ -75,6 +77,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/oracle/oci-go-sdk/v65 v65.114.2 h1:7ROvpCkL5v63HTHKGajlL+++zqz3+jAflfJt4wLE+J8=
github.com/oracle/oci-go-sdk/v65 v65.114.2/go.mod h1:oo33NDf2XPqx3/N6oLG4jFlrqJ0xu4Rlt9SfuAbtDFs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -86,12 +90,14 @@ github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9Z
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/rs/zerolog v1.35.1 h1:m7xQeoiLIiV0BCEY4Hs+j2NG4Gp2o2KPKmhnnLiazKI=
github.com/rs/zerolog v1.35.1/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 h1:ObX9hZmK+VmijreZO/8x9pQ8/P/ToHD/bdSb4Eg4tUo=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36/go.mod h1:LEsDu4BubxK7/cWhtlQWfuxwL4rf/2UEpxXz1o1EMtM=
github.com/sony/gobreaker/v2 v2.4.0 h1:g2KJRW1Ubty3+ZOcSEUN7K+REQJdN6yo6XvaML+jptg=
github.com/sony/gobreaker/v2 v2.4.0/go.mod h1:pTyFJgcZ3h2tdQVLZZruK2C0eoFL1fb/G83wK1ZQl+s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand All @@ -106,6 +112,8 @@ github.com/urfave/cli/v3 v3.9.0 h1:AV9lIiPv3ukYnxunaCUsHnEozptYmDN2F0+yWqLMn/c=
github.com/urfave/cli/v3 v3.9.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/vultr/govultr/v3 v3.31.2 h1:2l3/KDvfemG+4azw4LLquJoh9mFOAVEdBXtPPzix3ac=
github.com/vultr/govultr/v3 v3.31.2/go.mod h1:2zyUw9yADQaGwKnwDesmIOlBNLrm7edsCfWHFJpWKf8=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.woodpecker-ci.org/woodpecker/v3 v3.14.1 h1:/HrTfGQOJxVHx5+ReCAf/4BBZe+HoE7s/rYgOzZlRi0=
Expand All @@ -114,6 +122,8 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go=
go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a h1:+3jdDGGB8NGb1Zktc737jlt3/A5f6UlwSzmvqUuufxw=
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw=
golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
Expand Down
99 changes: 99 additions & 0 deletions providers/oracle/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package oracle

import (
"os"

"github.com/urfave/cli/v3"
)

const category = "Oracle Cloud"

//nolint:mnd
var ProviderFlags = []cli.Flag{
&cli.StringFlag{
Name: "oracle-config-file",
Usage: "OCI config file path; defaults to the SDK default config provider",
Sources: cli.EnvVars("WOODPECKER_ORACLE_CONFIG_FILE"),
Category: category,
},
&cli.StringFlag{
Name: "oracle-profile",
Value: "DEFAULT",
Usage: "OCI config profile name",
Sources: cli.EnvVars("WOODPECKER_ORACLE_PROFILE"),
Category: category,
},
&cli.StringFlag{
Name: "oracle-region",
Usage: "OCI region override, e.g. eu-frankfurt-1",
Sources: cli.EnvVars("WOODPECKER_ORACLE_REGION"),
Category: category,
},
&cli.StringFlag{
Name: "oracle-compartment-id",
Usage: "OCI compartment OCID for autoscaler instances",
Sources: cli.EnvVars("WOODPECKER_ORACLE_COMPARTMENT_ID"),
Category: category,
},
&cli.StringFlag{
Name: "oracle-availability-domain",
Usage: "OCI availability domain where agents are launched",
Sources: cli.EnvVars("WOODPECKER_ORACLE_AVAILABILITY_DOMAIN"),
Category: category,
},
&cli.StringFlag{
Name: "oracle-subnet-id",
Usage: "OCI subnet OCID used for agent VNICs",
Sources: cli.EnvVars("WOODPECKER_ORACLE_SUBNET_ID"),
Category: category,
},
&cli.StringFlag{
Name: "oracle-image-id",
Usage: "OCI image OCID used to boot agents",
Sources: cli.EnvVars("WOODPECKER_ORACLE_IMAGE_ID"),
Category: category,
},
&cli.StringFlag{
Name: "oracle-shape",
Value: "VM.Standard.E4.Flex",
Usage: "OCI compute shape",
Sources: cli.EnvVars("WOODPECKER_ORACLE_SHAPE"),
Category: category,
},
&cli.FloatFlag{
Name: "oracle-ocpus",
Value: 1,
Usage: "OCPU count for flex shapes",
Sources: cli.EnvVars("WOODPECKER_ORACLE_OCPUS"),
Category: category,
},
&cli.FloatFlag{
Name: "oracle-memory-gbs",
Value: 6,
Usage: "memory in GB for flex shapes",
Sources: cli.EnvVars("WOODPECKER_ORACLE_MEMORY_GBS"),
Category: category,
},
&cli.StringFlag{
Name: "oracle-ssh-authorized-key",
Usage: "SSH public key added to launched agents",
Sources: cli.NewValueSourceChain(
cli.EnvVar("WOODPECKER_ORACLE_SSH_AUTHORIZED_KEY"),
cli.File(os.Getenv("WOODPECKER_ORACLE_SSH_AUTHORIZED_KEY_FILE")),
),
Category: category,
},
&cli.StringSliceFlag{
Name: "oracle-freeform-tags",
Usage: "additional OCI freeform tags as key=value pairs",
Sources: cli.EnvVars("WOODPECKER_ORACLE_FREEFORM_TAGS"),
Category: category,
},
&cli.BoolFlag{
Name: "oracle-assign-public-ip",
Value: true,
Usage: "assign public IPv4 addresses to agent VNICs",
Sources: cli.EnvVars("WOODPECKER_ORACLE_ASSIGN_PUBLIC_IP"),
Category: category,
},
}
Loading