harness-drone/cmd/drone-agent/config/config.go
2019-02-27 23:07:13 -08:00

208 lines
5.7 KiB
Go

// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Drone Non-Commercial License
// that can be found in the LICENSE file.
// +build !oss
package config
import (
"fmt"
"net/url"
"os"
"strings"
"github.com/dustin/go-humanize"
"github.com/kelseyhightower/envconfig"
)
// IMPORTANT please do not add new configuration parameters unless it has
// been discussed on the mailing list. We are attempting to reduce the
// number of configuration parameters, and may reject pull requests that
// introduce new parameters. (mailing list https://discourse.drone.io)
// default runner hostname.
var hostname string
func init() {
hostname, _ = os.Hostname()
if hostname == "" {
hostname = "localhost"
}
}
type (
// Config provides the system configuration.
Config struct {
Docker Docker
Logging Logging
Registries Registries
Runner Runner
RPC RPC
Server Server
Secrets Secrets
}
// Docker provides docker configuration
Docker struct {
Config string `envconfig:"DRONE_DOCKER_CONFIG"`
}
// Logging provides the logging configuration.
Logging struct {
Debug bool `envconfig:"DRONE_LOGS_DEBUG"`
Trace bool `envconfig:"DRONE_LOGS_TRACE"`
Color bool `envconfig:"DRONE_LOGS_COLOR"`
Pretty bool `envconfig:"DRONE_LOGS_PRETTY"`
Text bool `envconfig:"DRONE_LOGS_TEXT"`
}
// Registries provides the registry configuration.
Registries struct {
Endpoint string `envconfig:"DRONE_REGISTRY_ENDPOINT"`
Password string `envconfig:"DRONE_REGISTRY_SECRET"`
SkipVerify bool `envconfig:"DRONE_REGISTRY_SKIP_VERIFY"`
}
// Secrets provides the secret configuration.
Secrets struct {
Endpoint string `envconfig:"DRONE_SECRET_ENDPOINT"`
Password string `envconfig:"DRONE_SECRET_SECRET"`
SkipVerify bool `envconfig:"DRONE_SECRET_SKIP_VERIFY"`
}
// RPC provides the rpc configuration.
RPC struct {
Server string `envconfig:"DRONE_RPC_SERVER"`
Secret string `envconfig:"DRONE_RPC_SECRET"`
Debug bool `envconfig:"DRONE_RPC_DEBUG"`
Host string `envconfig:"DRONE_RPC_HOST"`
Proto string `envconfig:"DRONE_RPC_PROTO"`
// Hosts map[string]string `envconfig:"DRONE_RPC_EXTRA_HOSTS"`
}
// Runner provides the runner configuration.
Runner struct {
Platform string `envconfig:"DRONE_RUNNER_PLATFORM" default:"linux/amd64"`
OS string `envconfig:"DRONE_RUNNER_OS"`
Arch string `envconfig:"DRONE_RUNNER_ARCH"`
Kernel string `envconfig:"DRONE_RUNNER_KERNEL"`
Variant string `envconfig:"DRONE_RUNNER_VARIANT"`
Machine string `envconfig:"DRONE_RUNNER_NAME"`
Capacity int `envconfig:"DRONE_RUNNER_CAPACITY" default:"2"`
Labels map[string]string `envconfig:"DRONE_RUNNER_LABELS"`
Volumes []string `envconfig:"DRONE_RUNNER_VOLUMES"`
Networks []string `envconfig:"DRONE_RUNNER_NETWORKS"`
Devices []string `envconfig:"DRONE_RUNNER_DEVICES"`
Privileged []string `envconfig:"DRONE_RUNNER_PRIVILEGED_IMAGES"`
Environ map[string]string `envconfig:"DRONE_RUNNER_ENVIRON"`
Limits struct {
MemSwapLimit Bytes `envconfig:"DRONE_LIMIT_MEM_SWAP"`
MemLimit Bytes `envconfig:"DRONE_LIMIT_MEM"`
ShmSize Bytes `envconfig:"DRONE_LIMIT_SHM_SIZE"`
CPUQuota int64 `envconfig:"DRONE_LIMIT_CPU_QUOTA"`
CPUShares int64 `envconfig:"DRONE_LIMIT_CPU_SHARES"`
CPUSet string `envconfig:"DRONE_LIMIT_CPU_SET"`
}
}
// Server provides the server configuration.
Server struct {
Addr string `envconfig:"-"`
Host string `envconfig:"DRONE_SERVER_HOST" default:"localhost:8080"`
Proto string `envconfig:"DRONE_SERVER_PROTO" default:"http"`
}
)
// Environ returns the settings from the environment.
func Environ() (Config, error) {
cfg := Config{}
err := envconfig.Process("", &cfg)
defaultRunner(&cfg)
defaultCallback(&cfg)
return cfg, err
}
func defaultRunner(c *Config) {
if c.Runner.Machine == "" {
c.Runner.Machine = hostname
}
parts := strings.Split(c.Runner.Platform, "/")
if len(parts) == 2 && c.Runner.OS == "" {
c.Runner.OS = parts[0]
}
if len(parts) == 2 && c.Runner.Arch == "" {
c.Runner.Arch = parts[1]
}
}
func defaultCallback(c *Config) {
// this is legacy, remove in a future release
if c.RPC.Server != "" {
uri, err := url.Parse(c.RPC.Server)
if err == nil {
c.RPC.Host = uri.Host
c.RPC.Proto = uri.Scheme
}
}
if c.RPC.Host == "" {
c.RPC.Host = c.Server.Host
}
if c.RPC.Proto == "" {
c.RPC.Proto = c.Server.Proto
}
}
// Bytes stores number bytes (e.g. megabytes)
type Bytes int64
// Decode implements a decoder that parses a string representation
// of bytes into the number of bytes it represents.
func (b *Bytes) Decode(value string) error {
v, err := humanize.ParseBytes(value)
*b = Bytes(v)
return err
}
// Int64 returns the int64 value of the Byte.
func (b *Bytes) Int64() int64 {
return int64(*b)
}
// String returns the string value of the Byte.
func (b *Bytes) String() string {
return fmt.Sprint(*b)
}
// UserCreate stores account information used to bootstrap
// the admin user account when the system initializes.
type UserCreate struct {
Username string
Machine bool
Admin bool
Token string
}
// Decode implements a decoder that extracts user information
// from the environment variable string.
func (u *UserCreate) Decode(value string) error {
for _, param := range strings.Split(value, ",") {
parts := strings.Split(param, ":")
if len(parts) != 2 {
continue
}
key := parts[0]
val := parts[1]
switch key {
case "username":
u.Username = val
case "token":
u.Token = val
case "machine":
u.Machine = val == "true"
case "admin":
u.Admin = val == "true"
}
}
return nil
}