From a486f325e5bcc7e0449dacfeb69c5b8b0f9a7369 Mon Sep 17 00:00:00 2001 From: Doug Simmons Date: Thu, 10 Mar 2022 02:22:26 -0800 Subject: [PATCH] Add support for an environ (V2) endpoint Add the ability to configure a DRONE_ENV_PLUGIN_ENDPOINT with the runner Bump drone-go to v1.6.0 Bump runner-go to 1.7.0 tidy via `go mod tidy` --- command/compile.go | 15 ++- command/exec.go | 15 ++- daemon/config.go | 6 ++ daemon/daemon.go | 30 ++++-- engine/compiler/compiler.go | 161 +++++++++++++++---------------- engine/compiler/compiler_test.go | 57 ++++++----- engine/spec.go | 4 +- go.mod | 6 +- go.sum | 20 ++-- runtime/execer.go | 4 +- runtime/runner.go | 24 ++--- runtime/type.go | 65 +++++++++++++ 12 files changed, 254 insertions(+), 153 deletions(-) create mode 100644 runtime/type.go diff --git a/command/compile.go b/command/compile.go index 3c3189b..c053968 100644 --- a/command/compile.go +++ b/command/compile.go @@ -14,8 +14,11 @@ import ( "github.com/drone-runners/drone-runner-exec/command/internal" "github.com/drone-runners/drone-runner-exec/engine/compiler" "github.com/drone-runners/drone-runner-exec/engine/resource" + "github.com/drone-runners/drone-runner-exec/runtime" + "github.com/drone/envsubst" "github.com/drone/runner-go/environ" + "github.com/drone/runner-go/environ/provider" "github.com/drone/runner-go/manifest" "github.com/drone/runner-go/secret" @@ -80,6 +83,12 @@ func (c *compileCommand) run(*kingpin.ParseContext) error { // compile the pipeline to an intermediate representation. comp := &compiler.Compiler{ + Environ: provider.Static(c.Environ), + Secret: secret.StaticVars(c.Secrets), + Root: c.Root, + } + + args := runtime.CompilerArgs{ Pipeline: resource, Manifest: manifest, Build: c.Build, @@ -87,11 +96,9 @@ func (c *compileCommand) run(*kingpin.ParseContext) error { Repo: c.Repo, Stage: c.Stage, System: c.System, - Environ: c.Environ, - Secret: secret.StaticVars(c.Secrets), - Root: c.Root, } - spec := comp.Compile(nocontext) + + spec := comp.Compile(nocontext, args) // encode the pipeline in json format and print to the // console for inspection. diff --git a/command/exec.go b/command/exec.go index 722277b..6091bd1 100644 --- a/command/exec.go +++ b/command/exec.go @@ -17,12 +17,14 @@ import ( "github.com/drone-runners/drone-runner-exec/engine/compiler" "github.com/drone-runners/drone-runner-exec/engine/resource" "github.com/drone-runners/drone-runner-exec/runtime" + "github.com/drone/drone-go/drone" "github.com/drone/envsubst" "github.com/drone/runner-go/environ" + "github.com/drone/runner-go/environ/provider" "github.com/drone/runner-go/manifest" "github.com/drone/runner-go/pipeline" - "github.com/drone/runner-go/pipeline/console" + "github.com/drone/runner-go/pipeline/streamer/console" "github.com/drone/runner-go/secret" "github.com/drone/signal" @@ -90,6 +92,12 @@ func (c *execCommand) run(*kingpin.ParseContext) error { // compile the pipeline to an intermediate representation. comp := &compiler.Compiler{ + Environ: provider.Static(c.Environ), + Secret: secret.StaticVars(c.Secrets), + Root: c.Root, + } + + args := runtime.CompilerArgs{ Pipeline: resource, Manifest: manifest, Build: c.Build, @@ -97,11 +105,8 @@ func (c *execCommand) run(*kingpin.ParseContext) error { Repo: c.Repo, Stage: c.Stage, System: c.System, - Environ: c.Environ, - Secret: secret.StaticVars(c.Secrets), - Root: c.Root, } - spec := comp.Compile(nocontext) + spec := comp.Compile(nocontext, args) // create a step object for each pipeline step. for _, step := range spec.Steps { diff --git a/daemon/config.go b/daemon/config.go index 1cfad84..9eb2ea6 100644 --- a/daemon/config.go +++ b/daemon/config.go @@ -76,6 +76,12 @@ type Config struct { Trusted bool `envconfig:"DRONE_LIMIT_TRUSTED"` } + Environ struct { + Endpoint string `envconfig:"DRONE_ENV_PLUGIN_ENDPOINT"` + Token string `envconfig:"DRONE_ENV_PLUGIN_TOKEN"` + SkipVerify bool `envconfig:"DRONE_ENV_PLUGIN_SKIP_VERIFY"` + } + Secret struct { Endpoint string `envconfig:"DRONE_SECRET_PLUGIN_ENDPOINT"` Token string `envconfig:"DRONE_SECRET_PLUGIN_TOKEN"` diff --git a/daemon/daemon.go b/daemon/daemon.go index dfadb34..f4cdee6 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -11,16 +11,18 @@ import ( "time" "github.com/drone-runners/drone-runner-exec/engine" + "github.com/drone-runners/drone-runner-exec/engine/compiler" "github.com/drone-runners/drone-runner-exec/engine/resource" "github.com/drone-runners/drone-runner-exec/internal/match" "github.com/drone-runners/drone-runner-exec/runtime" "github.com/drone/runner-go/client" + "github.com/drone/runner-go/environ/provider" "github.com/drone/runner-go/handler/router" "github.com/drone/runner-go/logger" loghistory "github.com/drone/runner-go/logger/history" - "github.com/drone/runner-go/pipeline/history" - "github.com/drone/runner-go/pipeline/remote" + "github.com/drone/runner-go/pipeline/reporter/history" + "github.com/drone/runner-go/pipeline/reporter/remote" "github.com/drone/runner-go/secret" "github.com/drone/runner-go/server" @@ -61,19 +63,29 @@ func Run(ctx context.Context, config Config) error { Client: cli, Environ: config.Runner.Environ, Machine: config.Runner.Name, - Root: config.Runner.Root, - Symlinks: config.Runner.Symlinks, Reporter: tracer, Match: match.Func( config.Limit.Repos, config.Limit.Events, config.Limit.Trusted, ), - Secret: secret.External( - config.Secret.Endpoint, - config.Secret.Token, - config.Secret.SkipVerify, - ), + Compiler: &compiler.Compiler{ + Environ: provider.Combine( + provider.Static(config.Runner.Environ), + provider.External( + config.Environ.Endpoint, + config.Environ.Token, + config.Environ.SkipVerify, + ), + ), + Secret: secret.External( + config.Secret.Endpoint, + config.Secret.Token, + config.Secret.SkipVerify, + ), + Root: config.Runner.Root, + Symlinks: config.Runner.Symlinks, + }, Execer: runtime.NewExecer( tracer, remote, diff --git a/engine/compiler/compiler.go b/engine/compiler/compiler.go index 1150350..8b62db7 100644 --- a/engine/compiler/compiler.go +++ b/engine/compiler/compiler.go @@ -12,11 +12,11 @@ import ( "strings" "github.com/drone-runners/drone-runner-exec/engine" - "github.com/drone-runners/drone-runner-exec/engine/resource" + "github.com/drone-runners/drone-runner-exec/runtime" - "github.com/drone/drone-go/drone" "github.com/drone/runner-go/clone" "github.com/drone/runner-go/environ" + "github.com/drone/runner-go/environ/provider" "github.com/drone/runner-go/manifest" "github.com/drone/runner-go/secret" "github.com/drone/runner-go/shell" @@ -34,43 +34,9 @@ var tempdir = os.TempDir // Compiler compiles the Yaml configuration file to an // intermediate representation optimized for simple execution. type Compiler struct { - // Manifest provides the parsed manifest. - Manifest *manifest.Manifest - - // Pipeline provides the parsed pipeline. This pipeline is - // the compiler source and is converted to the intermediate - // representation by the Compile method. - Pipeline *resource.Pipeline - - // Build provides the compiler with stage information that - // is converted to environment variable format and passed to - // each pipeline step. It is also used to clone the commit. - Build *drone.Build - - // Stage provides the compiler with stage information that - // is converted to environment variable format and passed to - // each pipeline step. - Stage *drone.Stage - - // Repo provides the compiler with repo information. This - // repo information is converted to environment variable - // format and passed to each pipeline step. It is also used - // to clone the repository. - Repo *drone.Repo - - // System provides the compiler with system information that - // is converted to environment variable format and passed to - // each pipeline step. - System *drone.System - - // Environ provides a set of environment varaibles that + // Environ provides a set of environment variables that // should be added to each pipeline step by default. - Environ map[string]string - - // Netrc provides netrc parameters that can be used by the - // default clone step to authenticate to the remote - // repository. - Netrc *drone.Netrc + Environ provider.Provider // Secret returns a named secret value that can be injected // into the pipeline step. @@ -86,7 +52,7 @@ type Compiler struct { } // Compile compiles the configuration file. -func (c *Compiler) Compile(ctx context.Context) *engine.Spec { +func (c *Compiler) Compile(ctx context.Context, args runtime.CompilerArgs) *engine.Spec { spec := new(engine.Spec) if c.Root != "" { @@ -101,10 +67,11 @@ func (c *Compiler) Compile(ctx context.Context) *engine.Spec { ) } - spec.Platform.OS = c.Pipeline.Platform.OS - spec.Platform.Arch = c.Pipeline.Platform.Arch - spec.Platform.Variant = c.Pipeline.Platform.Variant - spec.Platform.Version = c.Pipeline.Platform.Version + pipeline := args.Pipeline + spec.Platform.OS = pipeline.Platform.OS + spec.Platform.Arch = pipeline.Platform.Arch + spec.Platform.Variant = pipeline.Platform.Variant + spec.Platform.Version = pipeline.Platform.Version // creates a home directory in the root. homedir := filepath.Join(spec.Root, "home", "drone") @@ -130,13 +97,13 @@ func (c *Compiler) Compile(ctx context.Context) *engine.Spec { }) // creates the netrc file - if c.Netrc != nil { + if args.Netrc != nil { netrcpath := filepath.Join(homedir, netrc) netrcdata := fmt.Sprintf( "machine %s login %s password %s", - c.Netrc.Machine, - c.Netrc.Login, - c.Netrc.Password, + args.Netrc.Machine, + args.Netrc.Login, + args.Netrc.Password, ) spec.Files = append(spec.Files, &engine.File{ Path: netrcpath, @@ -153,23 +120,31 @@ func (c *Compiler) Compile(ctx context.Context) *engine.Spec { }) } + // list the global environment variables + globals, _ := c.Environ.List(ctx, &provider.Request{ + Build: args.Build, + Repo: args.Repo, + }) + // create the default environment variables. envs := environ.Combine( hostEnviron(), - c.Environ, - c.Build.Params, + provider.ToMap( + provider.FilterUnmasked(globals), + ), + args.Build.Params, environ.Proxy(), - environ.System(c.System), - environ.Repo(c.Repo), - environ.Build(c.Build), - environ.Stage(c.Stage), - environ.Link(c.Repo, c.Build, c.System), + environ.System(args.System), + environ.Repo(args.Repo), + environ.Build(args.Build), + environ.Stage(args.Stage), + environ.Link(args.Repo, args.Build, args.System), clone.Environ(clone.Config{ - SkipVerify: c.Pipeline.Clone.SkipVerify, - Trace: c.Pipeline.Clone.Trace, + SkipVerify: pipeline.Clone.SkipVerify, + Trace: pipeline.Clone.Trace, User: clone.User{ - Name: c.Build.AuthorName, - Email: c.Build.AuthorEmail, + Name: args.Build.AuthorName, + Email: args.Build.AuthorEmail, }, }), // TODO(bradrydzewski) windows variable HOMEDRIVE @@ -185,18 +160,18 @@ func (c *Compiler) Compile(ctx context.Context) *engine.Spec { ) // create clone step, maybe - if c.Pipeline.Clone.Disable == false { + if pipeline.Clone.Disable == false { clonepath := filepath.Join(spec.Root, "opt", "clone"+shell.Suffix) - repoUrl := c.Repo.HTTPURL - if repoUrl == "" && c.Repo.SSHURL != "" { - repoUrl = c.Repo.SSHURL + repoUrl := args.Repo.HTTPURL + if repoUrl == "" && args.Repo.SSHURL != "" { + repoUrl = args.Repo.SSHURL } clonefile := shell.Script( clone.Commands( clone.Args{ - Branch: c.Build.Target, - Commit: c.Build.After, - Ref: c.Build.Ref, + Branch: args.Build.Target, + Commit: args.Build.After, + Ref: args.Build.Ref, Remote: repoUrl, }, ), @@ -222,15 +197,15 @@ func (c *Compiler) Compile(ctx context.Context) *engine.Spec { } // create steps - for _, src := range c.Pipeline.Steps { + for _, src := range pipeline.Steps { buildslug := slug.Make(src.Name) buildpath := filepath.Join(spec.Root, "opt", buildslug+shell.Suffix) buildfile := shell.Script(src.Commands) - cmd, args := shell.Command() + cmd, cmdArgs := shell.Command() dst := &engine.Step{ Name: src.Name, - Args: append(args, buildpath), + Args: append(cmdArgs, buildpath), Command: cmd, Detach: src.Detach, DependsOn: src.DependsOn, @@ -267,14 +242,14 @@ func (c *Compiler) Compile(ctx context.Context) *engine.Spec { // if the pipeline step has unmet conditions the step is // automatically skipped. if !src.When.Match(manifest.Match{ - Action: c.Build.Action, - Cron: c.Build.Cron, - Ref: c.Build.Ref, - Repo: c.Repo.Slug, - Instance: c.System.Host, - Target: c.Build.Deploy, - Event: c.Build.Event, - Branch: c.Build.Target, + Action: args.Build.Action, + Cron: args.Build.Cron, + Ref: args.Build.Ref, + Repo: args.Repo.Slug, + Instance: args.System.Host, + Target: args.Build.Deploy, + Event: args.Build.Event, + Branch: args.Build.Target, }) { dst.RunPolicy = engine.RunNever } @@ -282,19 +257,41 @@ func (c *Compiler) Compile(ctx context.Context) *engine.Spec { if isGraph(spec) == false { configureSerial(spec) - } else if c.Pipeline.Clone.Disable == false { + } else if pipeline.Clone.Disable == false { configureCloneDeps(spec) - } else if c.Pipeline.Clone.Disable == true { + } else if pipeline.Clone.Disable == true { removeCloneDeps(spec) } + // HACK: append masked global variables to secrets + // this ensures the environment variable values are + // masked when printed to the console. + masked := provider.FilterMasked(globals) + for _, step := range spec.Steps { + for _, g := range masked { + step.Secrets = append(step.Secrets, &engine.Secret{ + Name: g.Name, + Data: []byte(g.Data), + Mask: g.Mask, + Env: g.Name, + }) + } + } + for _, step := range spec.Steps { for _, s := range step.Secrets { - found, _ := c.Secret.Find(ctx, &secret.Request{ + // source secrets from the global secret provider + // and the repository secret provider. + provider := secret.Combine( + args.Secret, + c.Secret, + ) + + found, _ := provider.Find(ctx, &secret.Request{ Name: s.Name, - Build: c.Build, - Repo: c.Repo, - Conf: c.Manifest, + Build: args.Build, + Repo: args.Repo, + Conf: args.Manifest, }) if found != nil { s.Data = []byte(found.Data) diff --git a/engine/compiler/compiler_test.go b/engine/compiler/compiler_test.go index 9ba2e32..cb0d135 100644 --- a/engine/compiler/compiler_test.go +++ b/engine/compiler/compiler_test.go @@ -13,13 +13,16 @@ import ( "os" "testing" - "github.com/dchest/uniuri" "github.com/drone-runners/drone-runner-exec/engine" "github.com/drone-runners/drone-runner-exec/engine/resource" + "github.com/drone-runners/drone-runner-exec/runtime" + "github.com/drone/drone-go/drone" + "github.com/drone/runner-go/environ/provider" "github.com/drone/runner-go/manifest" "github.com/drone/runner-go/secret" + "github.com/dchest/uniuri" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" ) @@ -94,18 +97,23 @@ func TestCompile_RunFaiure(t *testing.T) { // at compile time. func TestCompile_Secrets(t *testing.T) { manifest, _ := manifest.ParseFile("testdata/secret.yml") - compiler := Compiler{} - compiler.Build = &drone.Build{} - compiler.Repo = &drone.Repo{} - compiler.Stage = &drone.Stage{} - compiler.System = &drone.System{} - compiler.Netrc = &drone.Netrc{} - compiler.Manifest = manifest - compiler.Pipeline = manifest.Resources[0].(*resource.Pipeline) - compiler.Secret = secret.StaticVars(map[string]string{ - "my_username": "octocat", - }) - ir := compiler.Compile(nocontext) + compiler := Compiler{ + Environ: provider.Static(nil), + Secret: secret.StaticVars(map[string]string{ + "my_username": "octocat", + }), + } + args := runtime.CompilerArgs{ + Repo: &drone.Repo{}, + Build: &drone.Build{}, + Stage: &drone.Stage{}, + System: &drone.System{}, + Netrc: &drone.Netrc{}, + Manifest: manifest, + Pipeline: manifest.Resources[0].(*resource.Pipeline), + Secret: secret.Static(nil), + } + ir := compiler.Compile(nocontext, args) got := ir.Steps[0].Secrets want := []*engine.Secret{ { @@ -153,15 +161,20 @@ func testCompile(t *testing.T, source, golden string) *engine.Spec { return nil } - compiler := Compiler{} - compiler.Build = &drone.Build{Target: "master"} - compiler.Repo = &drone.Repo{} - compiler.Stage = &drone.Stage{} - compiler.System = &drone.System{} - compiler.Netrc = &drone.Netrc{Machine: "github.com", Login: "octocat", Password: "correct-horse-battery-staple"} - compiler.Manifest = manifest - compiler.Pipeline = manifest.Resources[0].(*resource.Pipeline) - got := compiler.Compile(nocontext) + compiler := Compiler{ + Environ: provider.Static(nil), + Secret: secret.Static(nil), + } + args := runtime.CompilerArgs{ + Manifest: manifest, + Pipeline: manifest.Resources[0].(*resource.Pipeline), + Build: &drone.Build{Target: "master"}, + Stage: &drone.Stage{}, + Repo: &drone.Repo{}, + System: &drone.System{}, + Netrc: &drone.Netrc{Machine: "github.com", Login: "octocat", Password: "correct-horse-battery-staple"}, + } + got := compiler.Compile(nocontext, args) raw, err := ioutil.ReadFile(golden) if err != nil { diff --git a/engine/spec.go b/engine/spec.go index f285039..deb86cf 100644 --- a/engine/spec.go +++ b/engine/spec.go @@ -6,7 +6,7 @@ package engine type ( // Spec provides the pipeline spec. This provides the - // required instructions for reproducable pipeline + // required instructions for reproducible pipeline // execution. Spec struct { // Metadata Metadata `json:"metadata,omitempty"` @@ -28,7 +28,7 @@ type ( IgnoreErr bool `json:"ignore_err,omitempty"` IgnoreStdout bool `json:"ignore_stderr,omitempty"` IgnoreStderr bool `json:"ignore_stdout,omitempty"` - Name string `json:"name,omitempt"` + Name string `json:"name,omitempty"` RunPolicy RunPolicy `json:"run_policy,omitempty"` Secrets []*Secret `json:"secrets,omitempty"` WorkingDir string `json:"working_dir,omitempty"` diff --git a/go.mod b/go.mod index 93ca677..a4dbe46 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.17 require ( github.com/buildkite/yaml v2.1.0+incompatible github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9 - github.com/drone/drone-go v1.0.5-0.20190504210458-4d6116b897ba + github.com/drone/drone-go v1.6.0 github.com/drone/envsubst v1.0.2 - github.com/drone/runner-go v1.3.1 + github.com/drone/runner-go v1.7.0 github.com/drone/signal v1.0.0 github.com/golang/mock v1.3.1 github.com/google/go-cmp v0.3.0 @@ -39,5 +39,7 @@ require ( golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 // indirect golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect golang.org/x/text v0.3.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index a846320..a0067fc 100644 --- a/go.sum +++ b/go.sum @@ -20,12 +20,12 @@ github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9 h1:74lLNRzvsdIlkTgfD github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/drone/drone-go v1.0.5-0.20190504210458-4d6116b897ba h1:GKiT4UPBligLXJAP1zRllHvTUygAAlgS3t9LM9aasp0= -github.com/drone/drone-go v1.0.5-0.20190504210458-4d6116b897ba/go.mod h1:GxyeGClYohaKNYJv/ZpsmVHtMJ7WhoT+uDaJNcDIrk4= +github.com/drone/drone-go v1.6.0 h1:HJXienGtXlUKLe8z0iDsX6012CE9/2of5pQpUiD+zSA= +github.com/drone/drone-go v1.6.0/go.mod h1:fxCf9jAnXDZV1yDr0ckTuWd1intvcQwfJmTRpTZ1mXg= github.com/drone/envsubst v1.0.2 h1:dpYLMAspQHW0a8dZpLRKe9jCNvIGZPhCPrycZzIHdqo= github.com/drone/envsubst v1.0.2/go.mod h1:bkZbnc/2vh1M12Ecn7EYScpI4YGYU0etwLJICOWi8Z0= -github.com/drone/runner-go v1.3.1 h1:RNLOQOH0EZD0vMT1SDQUPReVOnh1Wbx1D9gQyKH1McI= -github.com/drone/runner-go v1.3.1/go.mod h1:61VgQWhZbNPXp01lBuR7PAztTMySGLnMzK/4oYE3D9Y= +github.com/drone/runner-go v1.7.0 h1:bxvopa3zJJnEqjTsW/a7tn0syfvo0X9B0VBm+7IQLEU= +github.com/drone/runner-go v1.7.0/go.mod h1:rKn98jQVmPzrXYX8kPCupAn3QwxyhmR0lX9hvFiJJI8= github.com/drone/signal v1.0.0 h1:NrnM2M/4yAuU/tXs6RP1a1ZfxnaHwYkd0kJurA1p6uI= github.com/drone/signal v1.0.0/go.mod h1:S8t92eFT0g4WUgEc/LxG+LCuiskpMNsG0ajAMGnyZpc= github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= @@ -46,6 +46,11 @@ github.com/kardianos/service v1.0.0/go.mod h1:8CzDhVuCuugtsHyZoTvsOBuvonN/UDBvl0 github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/natessilva/dag v0.0.0-20180124060714-7194b8dcc5c4 h1:dnMxwus89s86tI8rcGVp2HwZzlz7c5o92VOy7dSckBQ= @@ -83,9 +88,10 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/runtime/execer.go b/runtime/execer.go index acbb7ae..4d7fc6e 100644 --- a/runtime/execer.go +++ b/runtime/execer.go @@ -133,9 +133,9 @@ func (e *execer) exec(ctx context.Context, state *pipeline.State, spec *engine.S } switch { - case state.Skipped(): - return nil case state.Cancelled(): + // skip if the pipeline was cancelled, either by the + // end user or due to timeout. return nil case step.RunPolicy == engine.RunNever: return nil diff --git a/runtime/runner.go b/runtime/runner.go index 340e597..2f62750 100644 --- a/runtime/runner.go +++ b/runtime/runner.go @@ -14,7 +14,6 @@ import ( "time" "github.com/drone-runners/drone-runner-exec/engine" - "github.com/drone-runners/drone-runner-exec/engine/compiler" "github.com/drone-runners/drone-runner-exec/engine/resource" "github.com/drone/drone-go/drone" @@ -33,6 +32,10 @@ type Runner struct { // with the central server. Client client.Client + // Compiler is responsible for compiling the pipeline + // configuration to the intermediate representation. + Compiler Compiler + // Execer is responsible for executing intermediate // representation of the pipeline and returns its results. Execer Execer @@ -54,17 +57,6 @@ type Runner struct { // intended as a security measure to prevent a runner from // processing an unwanted pipeline. Match func(*drone.Repo, *drone.Build) bool - - // Secret provides the compiler with secrets. - Secret secret.Provider - - // Root defines the optional build root path, defaults to - // temp directory. - Root string - - // Symlinks provides an optional list of symlinks that are - // created and linked to the pipeline workspace. - Symlinks map[string]string } // Run runs the pipeline stage. @@ -191,26 +183,22 @@ func (s *Runner) Run(ctx context.Context, stage *drone.Stage) error { secrets := secret.Combine( secret.Static(data.Secrets), secret.Encrypted(), - s.Secret, ) // compile the yaml configuration file to an intermediate // representation, and then - comp := &compiler.Compiler{ + args := CompilerArgs{ Pipeline: resource, Manifest: manifest, - Environ: s.Environ, Build: data.Build, Stage: stage, Repo: data.Repo, System: data.System, Netrc: data.Netrc, Secret: secrets, - Root: s.Root, - Symlinks: s.Symlinks, } - spec := comp.Compile(ctx) + spec := s.Compiler.Compile(ctx, args) for _, src := range spec.Steps { // steps that are skipped are ignored and are not stored // in the drone database, nor displayed in the UI. diff --git a/runtime/type.go b/runtime/type.go new file mode 100644 index 0000000..8e12a36 --- /dev/null +++ b/runtime/type.go @@ -0,0 +1,65 @@ +// Copyright 2019 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by the Polyform License +// that can be found in the LICENSE file. + +package runtime + +import ( + "context" + + "github.com/drone-runners/drone-runner-exec/engine" + "github.com/drone-runners/drone-runner-exec/engine/resource" + + "github.com/drone/drone-go/drone" + "github.com/drone/runner-go/manifest" + "github.com/drone/runner-go/secret" +) + +type ( + // CompilerArgs provides compiler arguments. + CompilerArgs struct { + // Manifest provides the parsed manifest. + Manifest *manifest.Manifest + + // Pipeline provides the parsed pipeline. This pipeline is + // the compiler source and is converted to the intermediate + // representation by the Compile method. + Pipeline *resource.Pipeline + + // Build provides the compiler with stage information that + // is converted to environment variable format and passed to + // each pipeline step. It is also used to clone the commit. + Build *drone.Build + + // Stage provides the compiler with stage information that + // is converted to environment variable format and passed to + // each pipeline step. + Stage *drone.Stage + + // Repo provides the compiler with repo information. This + // repo information is converted to environment variable + // format and passed to each pipeline step. It is also used + // to clone the repository. + Repo *drone.Repo + + // System provides the compiler with system information that + // is converted to environment variable format and passed to + // each pipeline step. + System *drone.System + + // Netrc provides netrc parameters that can be used by the + // default clone step to authenticate to the remote + // repository. + Netrc *drone.Netrc + + // Secret returns a named secret value that can be injected + // into the pipeline step. + Secret secret.Provider + } + + // Compiler compiles the Yaml configuration file to an + // intermediate representation optimized for simple execution. + Compiler interface { + Compile(context.Context, CompilerArgs) *engine.Spec + } +)