diff --git a/cmd/otf-agent/main.go b/cmd/otf-agent/main.go index 310e513d3..0cfd258be 100644 --- a/cmd/otf-agent/main.go +++ b/cmd/otf-agent/main.go @@ -7,8 +7,8 @@ import ( cmdutil "github.com/leg100/otf/cmd" "github.com/leg100/otf/internal" - "github.com/leg100/otf/internal/agent" "github.com/leg100/otf/internal/logr" + "github.com/leg100/otf/internal/remoteops" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -27,7 +27,7 @@ func main() { func run(ctx context.Context, args []string) error { var ( loggerCfg *logr.Config - cfg *agent.ExternalConfig + cfg *remoteops.AgentConfig ) cmd := &cobra.Command{ @@ -41,7 +41,7 @@ func run(ctx context.Context, args []string) error { return err } - agent, err := agent.NewExternalAgent(cmd.Context(), logger, *cfg) + agent, err := remoteops.NewAgent(cmd.Context(), logger, *cfg) if err != nil { return fmt.Errorf("unable to start agent: %w", err) } @@ -54,7 +54,7 @@ func run(ctx context.Context, args []string) error { cmd.SetArgs(args) loggerCfg = logr.NewConfigFromFlags(cmd.Flags()) - cfg = agent.NewExternalConfigFromFlags(cmd.Flags()) + cfg = remoteops.NewAgentConfigFromFlags(cmd.Flags()) if err := cmdutil.SetFlagsFromEnvVariables(cmd.Flags()); err != nil { return errors.Wrap(err, "failed to populate config from environment vars") diff --git a/cmd/otfd/main.go b/cmd/otfd/main.go index 1ba5864b5..732df8149 100644 --- a/cmd/otfd/main.go +++ b/cmd/otfd/main.go @@ -7,12 +7,12 @@ import ( cmdutil "github.com/leg100/otf/cmd" "github.com/leg100/otf/internal" - "github.com/leg100/otf/internal/agent" "github.com/leg100/otf/internal/authenticator" "github.com/leg100/otf/internal/daemon" "github.com/leg100/otf/internal/github" "github.com/leg100/otf/internal/gitlab" "github.com/leg100/otf/internal/logr" + "github.com/leg100/otf/internal/remoteops" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -103,7 +103,7 @@ func parseFlags(ctx context.Context, args []string, out io.Writer) error { cmd.Flags().StringVar(&cfg.GoogleIAPConfig.Audience, "google-jwt-audience", "", "The Google JWT audience claim for validation. If unspecified then validation is skipped") loggerConfig = logr.NewConfigFromFlags(cmd.Flags()) - cfg.AgentConfig = agent.NewConfigFromFlags(cmd.Flags()) + cfg.RemoteOpsConfig = remoteops.NewConfigFromFlags(cmd.Flags()) if err := cmdutil.SetFlagsFromEnvVariables(cmd.Flags()); err != nil { return errors.Wrap(err, "failed to populate config from environment vars") diff --git a/internal/agent/agent_test.go b/internal/agent/agent_test.go deleted file mode 100644 index 6b1f92b2b..000000000 --- a/internal/agent/agent_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package agent - -import ( - "testing" - - "github.com/go-logr/logr" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestNewAgent_SetDefaultConcurrency(t *testing.T) { - agent, err := NewAgent(logr.Discard(), nil, Config{}) - require.NoError(t, err) - assert.Equal(t, 5, agent.Concurrency) -} diff --git a/internal/daemon/config.go b/internal/daemon/config.go index df9456314..0cd26e809 100644 --- a/internal/daemon/config.go +++ b/internal/daemon/config.go @@ -4,10 +4,10 @@ import ( "errors" "github.com/leg100/otf/internal" - "github.com/leg100/otf/internal/agent" "github.com/leg100/otf/internal/authenticator" "github.com/leg100/otf/internal/configversion" "github.com/leg100/otf/internal/inmem" + "github.com/leg100/otf/internal/remoteops" "github.com/leg100/otf/internal/tokens" ) @@ -16,7 +16,7 @@ var ErrInvalidSecretLength = errors.New("secret must be 16 bytes in size") // Config configures the otfd daemon. Descriptions of each field can be found in // the flag definitions in ./cmd/otfd type Config struct { - AgentConfig *agent.Config + RemoteOpsConfig *remoteops.Config CacheConfig *inmem.CacheConfig GithubHostname string GithubClientID string @@ -46,9 +46,9 @@ type Config struct { } func ApplyDefaults(cfg *Config) { - if cfg.AgentConfig == nil { - cfg.AgentConfig = &agent.Config{ - Concurrency: agent.DefaultConcurrency, + if cfg.RemoteOpsConfig == nil { + cfg.RemoteOpsConfig = &remoteops.Config{ + Concurrency: remoteops.DefaultConcurrency, } } if cfg.CacheConfig == nil { diff --git a/internal/daemon/daemon.go b/internal/daemon/daemon.go index babaeff7a..c4501e458 100644 --- a/internal/daemon/daemon.go +++ b/internal/daemon/daemon.go @@ -10,7 +10,6 @@ import ( "github.com/go-logr/logr" "github.com/gorilla/mux" "github.com/leg100/otf/internal" - "github.com/leg100/otf/internal/agent" "github.com/leg100/otf/internal/api" "github.com/leg100/otf/internal/auth" "github.com/leg100/otf/internal/authenticator" @@ -30,6 +29,7 @@ import ( "github.com/leg100/otf/internal/organization" "github.com/leg100/otf/internal/pubsub" "github.com/leg100/otf/internal/releases" + "github.com/leg100/otf/internal/remoteops" "github.com/leg100/otf/internal/repohooks" "github.com/leg100/otf/internal/run" "github.com/leg100/otf/internal/scheduler" @@ -71,7 +71,7 @@ type ( Handlers []internal.Handlers - agent process + opsDaemon process } process interface { @@ -277,9 +277,9 @@ func New(ctx context.Context, logger logr.Logger, cfg Config) (*Daemon, error) { RunService: runService, }) - agent, err := agent.NewAgent( - logger.WithValues("component", "agent"), - agent.LocalClient{ + remoteopsDaemon, err := remoteops.NewDaemon( + logger.WithValues("component", "remoteops"), + remoteops.InProcClient{ TokensService: tokensService, WorkspaceService: workspaceService, VariableService: variableService, @@ -289,7 +289,7 @@ func New(ctx context.Context, logger logr.Logger, cfg Config) (*Daemon, error) { RunService: runService, LogsService: logsService, }, - *cfg.AgentConfig, + *cfg.RemoteOpsConfig, ) if err != nil { return nil, err @@ -400,7 +400,7 @@ func New(ctx context.Context, logger logr.Logger, cfg Config) (*Daemon, error) { ConnectionService: connectionService, Broker: broker, DB: db, - agent: agent, + opsDaemon: remoteopsDaemon, }, nil } @@ -511,12 +511,12 @@ func (d *Daemon) Start(ctx context.Context, started chan struct{}) error { case <-d.Broker.Started(): } - // Run local agent in background + // Run remote ops daemon in background g.Go(func() error { - // give local agent unlimited access to services - agentCtx := internal.AddSubjectToContext(ctx, &internal.Superuser{Username: "local-agent"}) - if err := d.agent.Start(agentCtx); err != nil { - return fmt.Errorf("agent terminated: %w", err) + // give daemon unlimited access to services + daemonCtx := internal.AddSubjectToContext(ctx, &internal.Superuser{Username: "remoteops-daemon"}) + if err := d.opsDaemon.Start(daemonCtx); err != nil { + return fmt.Errorf("remote ops daemon terminated: %w", err) } return nil }) diff --git a/internal/integration/cluster_test.go b/internal/integration/cluster_test.go index 2d92cbe05..b095a637f 100644 --- a/internal/integration/cluster_test.go +++ b/internal/integration/cluster_test.go @@ -3,8 +3,8 @@ package integration import ( "testing" - "github.com/leg100/otf/internal/agent" "github.com/leg100/otf/internal/daemon" + "github.com/leg100/otf/internal/remoteops" "github.com/leg100/otf/internal/sql" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -30,7 +30,7 @@ func TestCluster(t *testing.T) { // start agent, instructing it to connect to otfd2, // add --debug flag, which dumps info that this test relies upon - otfd2.startAgent(t, ctx, org.Name, agent.ExternalConfig{Config: agent.Config{Debug: true}}) + otfd2.startAgent(t, ctx, org.Name, remoteops.AgentConfig{Config: remoteops.Config{Debug: true}}) // create root module, setting otfd1 as hostname root := newRootModule(t, otfd1.Hostname(), org.Name, "dev") diff --git a/internal/integration/daemon_helpers_test.go b/internal/integration/daemon_helpers_test.go index 8943dba85..375cc3b33 100644 --- a/internal/integration/daemon_helpers_test.go +++ b/internal/integration/daemon_helpers_test.go @@ -11,7 +11,6 @@ import ( "github.com/google/uuid" "github.com/leg100/otf/internal" - "github.com/leg100/otf/internal/agent" "github.com/leg100/otf/internal/auth" "github.com/leg100/otf/internal/cli" "github.com/leg100/otf/internal/configversion" @@ -23,6 +22,7 @@ import ( "github.com/leg100/otf/internal/organization" "github.com/leg100/otf/internal/pubsub" "github.com/leg100/otf/internal/releases" + "github.com/leg100/otf/internal/remoteops" "github.com/leg100/otf/internal/run" "github.com/leg100/otf/internal/sql" "github.com/leg100/otf/internal/state" @@ -419,7 +419,7 @@ func (s *testDaemon) createAgentToken(t *testing.T, ctx context.Context, organiz // startAgent starts an external agent, configuring it with the given // organization and configuring it to connect to the daemon. -func (s *testDaemon) startAgent(t *testing.T, ctx context.Context, organization string, cfg agent.ExternalConfig) { +func (s *testDaemon) startAgent(t *testing.T, ctx context.Context, organization string, cfg remoteops.AgentConfig) { t.Helper() // Configure logger; discard logs by default @@ -436,7 +436,7 @@ func (s *testDaemon) startAgent(t *testing.T, ctx context.Context, organization cfg.APIConfig.Token = string(token) cfg.APIConfig.Address = s.Hostname() - agent, err := agent.NewExternalAgent(ctx, logger, cfg) + agent, err := remoteops.NewAgent(ctx, logger, cfg) require.NoError(t, err) ctx, cancel := context.WithCancel(ctx) diff --git a/internal/integration/run_cancel_test.go b/internal/integration/run_cancel_test.go index 4d5934254..c9c7d17bc 100644 --- a/internal/integration/run_cancel_test.go +++ b/internal/integration/run_cancel_test.go @@ -8,8 +8,8 @@ import ( "testing" "github.com/leg100/otf/internal" - "github.com/leg100/otf/internal/agent" "github.com/leg100/otf/internal/releases" + "github.com/leg100/otf/internal/remoteops" "github.com/leg100/otf/internal/variable" "github.com/leg100/otf/internal/workspace" "github.com/stretchr/testify/require" @@ -49,8 +49,8 @@ func TestIntegration_RunCancel(t *testing.T) { // start an external agent (it's the only way to specify a separate bin // directory currently). - daemon.startAgent(t, ctx, org.Name, agent.ExternalConfig{ - Config: agent.Config{TerraformBinDir: bins}, + daemon.startAgent(t, ctx, org.Name, remoteops.AgentConfig{ + Config: remoteops.Config{TerraformBinDir: bins}, }) // create workspace specifying that it use an external agent. diff --git a/internal/integration/run_error_test.go b/internal/integration/run_error_test.go index 56c22777e..74f39d487 100644 --- a/internal/integration/run_error_test.go +++ b/internal/integration/run_error_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/leg100/otf/internal" - "github.com/leg100/otf/internal/agent" + "github.com/leg100/otf/internal/remoteops" "github.com/leg100/otf/internal/run" "github.com/leg100/otf/internal/workspace" "github.com/stretchr/testify/require" @@ -24,7 +24,7 @@ func TestRunError(t *testing.T) { // create a daemon and start an agent daemon, org, ctx := setup(t, nil) - daemon.startAgent(t, ctx, org.Name, agent.ExternalConfig{}) + daemon.startAgent(t, ctx, org.Name, remoteops.AgentConfig{}) // two tests: one run on the daemon, one via the agent. tests := []struct { diff --git a/internal/integration/sandbox_test.go b/internal/integration/sandbox_test.go index 7a228f210..02cbda7d4 100644 --- a/internal/integration/sandbox_test.go +++ b/internal/integration/sandbox_test.go @@ -5,8 +5,8 @@ import ( "os/exec" "testing" - "github.com/leg100/otf/internal/agent" "github.com/leg100/otf/internal/daemon" + "github.com/leg100/otf/internal/remoteops" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -23,7 +23,7 @@ func TestSandbox(t *testing.T) { require.NoError(t, err) daemon, org, ctx := setup(t, &config{Config: daemon.Config{ - AgentConfig: &agent.Config{ + RemoteOpsConfig: &remoteops.Config{ Sandbox: true, Debug: true, }, diff --git a/internal/logs/api.go b/internal/logs/api.go index f5d5365dd..2cc12d576 100644 --- a/internal/logs/api.go +++ b/internal/logs/api.go @@ -24,7 +24,7 @@ func (a *api) addHandlers(r *mux.Router) { signed.Use(internal.VerifySignedURL(a.Verifier)) signed.HandleFunc("/runs/{run_id}/logs/{phase}", a.getLogs).Methods("GET") - // client is typically an external agent + // client is typically otf-agent r = r.PathPrefix(otfapi.DefaultBasePath).Subrouter() r.HandleFunc("/runs/{run_id}/logs/{phase}", a.putLogs).Methods("PUT") } diff --git a/internal/agent/client.go b/internal/remoteops/client.go similarity index 85% rename from internal/agent/client.go rename to internal/remoteops/client.go index 23f09afda..b2895c45e 100644 --- a/internal/agent/client.go +++ b/internal/remoteops/client.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "context" @@ -17,12 +17,12 @@ import ( ) var ( - _ client = (*LocalClient)(nil) - _ client = (*remoteClient)(nil) + _ client = (*InProcClient)(nil) + _ client = (*rpcClient)(nil) ) type ( - // client allows the agent to communicate with the server endpoints. + // client allows the daemon to communicate with the server endpoints. client interface { GetWorkspace(ctx context.Context, workspaceID string) (*workspace.Workspace, error) ListEffectiveVariables(ctx context.Context, runID string) ([]*variable.Variable, error) @@ -43,8 +43,8 @@ type ( internal.PutChunkService } - // LocalClient is the client for an internal agent. - LocalClient struct { + // InProcClient is a client for in-process communication with the server. + InProcClient struct { tokens.TokensService variable.VariableService state.StateService @@ -55,8 +55,8 @@ type ( logs.LogsService } - // remoteClient is the client for an external agent. - remoteClient struct { + // rpcClient is a client for communication via RPC with the server. + rpcClient struct { *otfapi.Client otfapi.Config @@ -78,15 +78,13 @@ type ( logsClient = logs.Client ) -// New constructs a client that uses http to remotely invoke OTF -// services. -func newClient(config ExternalConfig) (*remoteClient, error) { +// New constructs a client that uses RPC to remotely invoke OTF services. +func newClient(config AgentConfig) (*rpcClient, error) { api, err := otfapi.NewClient(config.APIConfig) if err != nil { return nil, err } - - return &remoteClient{ + return &rpcClient{ Client: api, stateClient: &stateClient{Client: api}, configClient: &configClient{Client: api}, diff --git a/internal/agent/config.go b/internal/remoteops/config.go similarity index 72% rename from internal/agent/config.go rename to internal/remoteops/config.go index cc555dc0f..6048508e0 100644 --- a/internal/agent/config.go +++ b/internal/remoteops/config.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "github.com/leg100/otf/internal/api" @@ -6,18 +6,20 @@ import ( ) type ( - // Config is configuration for an agent. + // Config is configuration for a remote operations daemon. Config struct { - Organization *string // only process runs belonging to org - External bool // dedicated agent (true) or integrated into otfd (false) + Organization *string // only perform operations for a particular org Concurrency int // number of workers Sandbox bool // isolate privileged ops within sandbox Debug bool // toggle debug mode PluginCache bool // toggle use of terraform's shared plugin cache TerraformBinDir string // destination directory for terraform binaries + + isAgent bool // external agent process (true) or integrated into otfd (false) } - // ExternalConfig is configuration for an external agent - ExternalConfig struct { + // AgentConfig is configuration for an agent, i.e. a remote operations + // daemon that communicates with the server via RPC. + AgentConfig struct { APIConfig api.Config Config @@ -33,8 +35,8 @@ func NewConfigFromFlags(flags *pflag.FlagSet) *Config { return &cfg } -func NewExternalConfigFromFlags(flags *pflag.FlagSet) *ExternalConfig { - cfg := ExternalConfig{ +func NewAgentConfigFromFlags(flags *pflag.FlagSet) *AgentConfig { + cfg := AgentConfig{ Config: *NewConfigFromFlags(flags), } flags.StringVar(&cfg.APIConfig.Address, "address", api.DefaultAddress, "Address of OTF server") diff --git a/internal/agent/agent.go b/internal/remoteops/daemon.go similarity index 70% rename from internal/agent/agent.go rename to internal/remoteops/daemon.go index 5fda95bdc..5edbb69b4 100644 --- a/internal/agent/agent.go +++ b/internal/remoteops/daemon.go @@ -1,7 +1,4 @@ -/* -Package agent provides a daemon capable of running remote operations on behalf of a user. -*/ -package agent +package remoteops import ( "context" @@ -30,8 +27,8 @@ var ( } ) -// agent processes runs. -type agent struct { +// daemon performs remote operations +type daemon struct { Config logr.Logger releases.Downloader @@ -43,13 +40,15 @@ type agent struct { envs []string // terraform environment variables } -// NewAgent is the constructor for an agent -func NewAgent(logger logr.Logger, app client, cfg Config) (*agent, error) { +// NewDaemon constructs a remote operations daemon, which is either in-process, +// part of otfd, or an external process, otf-agent, communicating with the +// server via RPC. +func NewDaemon(logger logr.Logger, app client, cfg Config) (*daemon, error) { if cfg.Concurrency == 0 { cfg.Concurrency = DefaultConcurrency } - if cfg.External && cfg.Organization == nil { - return nil, fmt.Errorf("external agent requires organization to be specified") + if cfg.isAgent && cfg.Organization == nil { + return nil, fmt.Errorf("an agent requires a specific organization to be specified") } if cfg.Sandbox { if _, err := exec.LookPath("bwrap"); errors.Is(err, exec.ErrNotFound) { @@ -60,8 +59,7 @@ func NewAgent(logger logr.Logger, app client, cfg Config) (*agent, error) { if cfg.Debug { logger.V(0).Info("enabled debug mode") } - - agent := &agent{ + dmon := &daemon{ client: app, Config: cfg, Logger: logger, @@ -70,21 +68,19 @@ func NewAgent(logger logr.Logger, app client, cfg Config) (*agent, error) { spooler: newSpooler(app, logger, cfg), terminator: newTerminator(), } - if cfg.PluginCache { if err := os.MkdirAll(PluginCacheDir, 0o755); err != nil { return nil, fmt.Errorf("creating plugin cache directory: %w", err) } - agent.envs = append(agent.envs, "TF_PLUGIN_CACHE_DIR="+PluginCacheDir) + dmon.envs = append(dmon.envs, "TF_PLUGIN_CACHE_DIR="+PluginCacheDir) logger.V(0).Info("enabled plugin cache", "path", PluginCacheDir) } - - return agent, nil + return dmon, nil } -// NewExternalAgent constructs an external agent, which communicates with otfd -// via http -func NewExternalAgent(ctx context.Context, logger logr.Logger, cfg ExternalConfig) (*agent, error) { +// NewAgent constructs a remote operations daemon that communicates with the +// server via RPC. It is typically invoked as a separate process, `otf-agent`. +func NewAgent(ctx context.Context, logger logr.Logger, cfg AgentConfig) (*daemon, error) { // Sends unauthenticated ping to server app, err := newClient(cfg) if err != nil { @@ -100,16 +96,15 @@ func NewExternalAgent(ctx context.Context, logger logr.Logger, cfg ExternalConfi // Ensure agent only processes runs for this org cfg.Organization = internal.String(at.Organization) - // Mark agent as external. - cfg.External = true + // This is an agent. + cfg.isAgent = true - return NewAgent(logger, app, cfg.Config) + return NewDaemon(logger, app, cfg.Config) } -// Start starts the agent daemon and its workers -func (a *agent) Start(ctx context.Context) error { +// Start starts the daemon and its workers +func (a *daemon) Start(ctx context.Context) error { g, ctx := errgroup.WithContext(ctx) - g.Go(func() error { if err := a.spooler.start(ctx); err != nil { // only report error if context has not been canceled @@ -119,7 +114,6 @@ func (a *agent) Start(ctx context.Context) error { } return nil }) - g.Go(func() error { for i := 0; i < a.Concurrency; i++ { w := &worker{a} @@ -135,6 +129,5 @@ func (a *agent) Start(ctx context.Context) error { } } }) - return g.Wait() } diff --git a/internal/remoteops/daemon_test.go b/internal/remoteops/daemon_test.go new file mode 100644 index 000000000..134640c74 --- /dev/null +++ b/internal/remoteops/daemon_test.go @@ -0,0 +1,15 @@ +package remoteops + +import ( + "testing" + + "github.com/go-logr/logr" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewDaemon_SetDefaultConcurrency(t *testing.T) { + daemon, err := NewDaemon(logr.Discard(), nil, Config{}) + require.NoError(t, err) + assert.Equal(t, 5, daemon.Concurrency) +} diff --git a/internal/agent/environment.go b/internal/remoteops/environment.go similarity index 86% rename from internal/agent/environment.go rename to internal/remoteops/environment.go index 81f79032b..8069cf695 100644 --- a/internal/agent/environment.go +++ b/internal/remoteops/environment.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "context" @@ -19,9 +19,6 @@ import ( // environment provides an execution environment for a run, providing a working // directory, services, capturing logs etc. -// -// TODO: this is a pointless abstraction; refactor it out into worker's -// handle() func. type environment struct { client logr.Logger @@ -41,10 +38,10 @@ type environment struct { func newEnvironment( ctx context.Context, logger logr.Logger, - agent *agent, + dmon *daemon, run *run.Run, ) (*environment, error) { - ws, err := agent.GetWorkspace(ctx, run.WorkspaceID) + ws, err := dmon.GetWorkspace(ctx, run.WorkspaceID) if err != nil { return nil, errors.Wrap(err, "retrieving workspace") } @@ -59,17 +56,17 @@ func newEnvironment( // via an environment variable. // // NOTE: environment variable support is only available in terraform >= 1.2.0 - token, err := agent.CreateRunToken(ctx, tokens.CreateRunTokenOptions{ + token, err := dmon.CreateRunToken(ctx, tokens.CreateRunTokenOptions{ Organization: &ws.Organization, RunID: &run.ID, }) if err != nil { return nil, errors.Wrap(err, "creating run token") } - envs := internal.SafeAppend(agent.envs, internal.CredentialEnv(agent.Hostname(), token)) + envs := internal.SafeAppend(dmon.envs, internal.CredentialEnv(dmon.Hostname(), token)) // retrieve variables and add them to the environment - variables, err := agent.ListEffectiveVariables(ctx, run.ID) + variables, err := dmon.ListEffectiveVariables(ctx, run.ID) if err != nil { return nil, fmt.Errorf("retrieving workspace variables: %w", err) } @@ -83,20 +80,20 @@ func newEnvironment( writer := logs.NewPhaseWriter(ctx, logs.PhaseWriterOptions{ RunID: run.ID, Phase: run.Phase(), - Writer: agent, + Writer: dmon, }) env := &environment{ Logger: logger, - Downloader: agent.Downloader, - client: agent, + Downloader: dmon.Downloader, + client: dmon, out: writer, workdir: wd, variables: variables, ctx: ctx, runner: &runner{out: writer}, executor: &executor{ - Config: agent.Config, + Config: dmon.Config, version: run.TerraformVersion, out: writer, envs: envs, @@ -124,7 +121,7 @@ func (e *environment) execute() (err error) { fmt.Fprintln(e.out, "Debug mode enabled") fmt.Fprintln(e.out, "------------------") fmt.Fprintf(e.out, "Hostname: %s\n", hostname) - fmt.Fprintf(e.out, "External agent: %t\n", e.External) + fmt.Fprintf(e.out, "External agent: %t\n", e.isAgent) fmt.Fprintf(e.out, "Sandbox mode: %t\n", e.Sandbox) fmt.Fprintln(e.out, "------------------") fmt.Fprintln(e.out) diff --git a/internal/agent/executor.go b/internal/remoteops/executor.go similarity index 97% rename from internal/agent/executor.go rename to internal/remoteops/executor.go index 354be9c64..73a68fa20 100644 --- a/internal/agent/executor.go +++ b/internal/remoteops/executor.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "bytes" @@ -45,7 +45,7 @@ type ( executionOption func(*execution) ) -// sandboxIfEnabled sandboxes the execution process *if* the agent is configured +// sandboxIfEnabled sandboxes the execution process *if* the daemon is configured // with a sandbox. func sandboxIfEnabled() executionOption { return func(e *execution) { diff --git a/internal/agent/executor_test.go b/internal/remoteops/executor_test.go similarity index 99% rename from internal/agent/executor_test.go rename to internal/remoteops/executor_test.go index fcbfb24d8..21f7e5f3c 100644 --- a/internal/agent/executor_test.go +++ b/internal/remoteops/executor_test.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "bytes" diff --git a/internal/remoteops/remoteops.go b/internal/remoteops/remoteops.go new file mode 100644 index 000000000..8b9479c2d --- /dev/null +++ b/internal/remoteops/remoteops.go @@ -0,0 +1,2 @@ +// Package remoteops performs remote operations, i.e. terraform plan, apply, etc. +package remoteops diff --git a/internal/agent/spooler.go b/internal/remoteops/spooler.go similarity index 92% rename from internal/agent/spooler.go rename to internal/remoteops/spooler.go index c4d18b73c..d63bd5677 100644 --- a/internal/agent/spooler.go +++ b/internal/remoteops/spooler.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "context" @@ -130,12 +130,12 @@ func (s *spoolerDaemon) handleEvent(ev pubsub.Event) error { } func (s *spoolerDaemon) handleRun(event pubsub.EventType, run *otfrun.Run) { - // (a) external agents only handle runs with agent execution mode - // (b) internal agents only handle runs with remote execution mode + // (a) agents only handle runs with agent execution mode + // (b) non-agents only handle runs with remote execution mode // (c) if neither (a) nor (b) then skip run - if s.External && run.ExecutionMode != workspace.AgentExecutionMode { + if s.isAgent && run.ExecutionMode != workspace.AgentExecutionMode { return - } else if !s.External && run.ExecutionMode != workspace.RemoteExecutionMode { + } else if !s.isAgent && run.ExecutionMode != workspace.RemoteExecutionMode { return } diff --git a/internal/agent/spooler_test.go b/internal/remoteops/spooler_test.go similarity index 95% rename from internal/agent/spooler_test.go rename to internal/remoteops/spooler_test.go index d28295c35..0450da106 100644 --- a/internal/agent/spooler_test.go +++ b/internal/remoteops/spooler_test.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "context" @@ -66,8 +66,8 @@ func TestSpooler_handleEvent(t *testing.T) { wantRun: true, }, { - name: "internal agents skip agent-mode runs", - config: Config{External: false}, + name: "non-agent daemon skip agent-mode runs", + config: Config{isAgent: false}, event: pubsub.Event{ Payload: &run.Run{ ExecutionMode: workspace.AgentExecutionMode, @@ -76,8 +76,8 @@ func TestSpooler_handleEvent(t *testing.T) { wantRun: false, }, { - name: "external agents handle agent-mode runs", - config: Config{External: true}, + name: "agent daemon handle agent-mode runs", + config: Config{isAgent: true}, event: pubsub.Event{ Payload: &run.Run{ ExecutionMode: workspace.AgentExecutionMode, diff --git a/internal/agent/spooler_test_helper.go b/internal/remoteops/spooler_test_helper.go similarity index 97% rename from internal/agent/spooler_test_helper.go rename to internal/remoteops/spooler_test_helper.go index db5a1a71e..0aeacb924 100644 --- a/internal/agent/spooler_test_helper.go +++ b/internal/remoteops/spooler_test_helper.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "context" diff --git a/internal/agent/steps.go b/internal/remoteops/steps.go similarity index 99% rename from internal/agent/steps.go rename to internal/remoteops/steps.go index 618b081fc..f6d52a52c 100644 --- a/internal/agent/steps.go +++ b/internal/remoteops/steps.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "bytes" diff --git a/internal/agent/terminator.go b/internal/remoteops/terminator.go similarity index 97% rename from internal/agent/terminator.go rename to internal/remoteops/terminator.go index 08b6d2e9b..6cd08cd88 100644 --- a/internal/agent/terminator.go +++ b/internal/remoteops/terminator.go @@ -1,4 +1,4 @@ -package agent +package remoteops import "sync" diff --git a/internal/agent/testdata/badexe b/internal/remoteops/testdata/badexe similarity index 100% rename from internal/agent/testdata/badexe rename to internal/remoteops/testdata/badexe diff --git a/internal/agent/testdata/dir/file b/internal/remoteops/testdata/dir/file similarity index 100% rename from internal/agent/testdata/dir/file rename to internal/remoteops/testdata/dir/file diff --git a/internal/agent/testdata/dir/symlink b/internal/remoteops/testdata/dir/symlink similarity index 100% rename from internal/agent/testdata/dir/symlink rename to internal/remoteops/testdata/dir/symlink diff --git a/internal/agent/testdata/exe b/internal/remoteops/testdata/exe similarity index 100% rename from internal/agent/testdata/exe rename to internal/remoteops/testdata/exe diff --git a/internal/agent/testdata/file b/internal/remoteops/testdata/file similarity index 100% rename from internal/agent/testdata/file rename to internal/remoteops/testdata/file diff --git a/internal/agent/testdata/init.log b/internal/remoteops/testdata/init.log similarity index 100% rename from internal/agent/testdata/init.log rename to internal/remoteops/testdata/init.log diff --git a/internal/agent/testdata/killme b/internal/remoteops/testdata/killme similarity index 100% rename from internal/agent/testdata/killme rename to internal/remoteops/testdata/killme diff --git a/internal/agent/testdata/main.tf b/internal/remoteops/testdata/main.tf similarity index 100% rename from internal/agent/testdata/main.tf rename to internal/remoteops/testdata/main.tf diff --git a/internal/agent/testdata/staticbin b/internal/remoteops/testdata/staticbin similarity index 100% rename from internal/agent/testdata/staticbin rename to internal/remoteops/testdata/staticbin diff --git a/internal/agent/testdata/terraform.tfstate b/internal/remoteops/testdata/terraform.tfstate similarity index 100% rename from internal/agent/testdata/terraform.tfstate rename to internal/remoteops/testdata/terraform.tfstate diff --git a/internal/agent/workdir.go b/internal/remoteops/workdir.go similarity index 98% rename from internal/agent/workdir.go rename to internal/remoteops/workdir.go index e11446963..b16cb4d1d 100644 --- a/internal/agent/workdir.go +++ b/internal/remoteops/workdir.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "os" diff --git a/internal/agent/worker.go b/internal/remoteops/worker.go similarity index 97% rename from internal/agent/worker.go rename to internal/remoteops/worker.go index 6b6f8f29b..b98381ec0 100644 --- a/internal/agent/worker.go +++ b/internal/remoteops/worker.go @@ -1,4 +1,4 @@ -package agent +package remoteops import ( "context" @@ -10,7 +10,7 @@ import ( // worker sequentially executes runs. type worker struct { - *agent + *daemon } // Start starts the worker which waits for runs to execute. @@ -42,7 +42,7 @@ func (w *worker) handle(ctx context.Context, r *run.Run) { env, err := newEnvironment( ctx, log, - w.agent, + w.daemon, r, ) if err != nil {