Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Display the runner type during CLI operations #2795

Merged
merged 10 commits into from
Dec 13, 2021
Merged
4 changes: 4 additions & 0 deletions .changelog/2795.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:improvement
cli: Report where each operation runs (locally vs remotely)
```

14 changes: 13 additions & 1 deletion internal/cli/runner_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ type RunnerAgentCommand struct {
// is made available to the plugins so they can alter their behavior for
// this unique context.
flagODR bool

// If this is an ODR runner, this should be the ODR profile that it was created
// from.
flagOdrProfileId string
}

// This is how long a runner in ODR mode will wait for its job assignment before
Expand Down Expand Up @@ -133,7 +137,7 @@ func (c *RunnerAgentCommand) Run(args []string) int {

if c.flagODR {
options = append(options,
runnerpkg.WithODR(),
runnerpkg.WithODR(c.flagOdrProfileId),
runnerpkg.ByIdOnly(),
runnerpkg.WithAcceptTimeout(defaultRunnerODRAcceptTimeout),
)
Expand Down Expand Up @@ -272,6 +276,14 @@ func (c *RunnerAgentCommand) Flags() *flag.Sets {
Name: "odr",
Target: &c.flagODR,
Usage: "Indicates to the runner it's operating as an on-demand runner.",
Hidden: true,
})

f.StringVar(&flag.StringVar{
Name: "odr-profile-id",
Target: &c.flagOdrProfileId,
Usage: "The ID of the odr profile used to create the task that is running this runner.",
Hidden: true,
izaaklauer marked this conversation as resolved.
Show resolved Hide resolved
})
})
}
Expand Down
38 changes: 38 additions & 0 deletions internal/client/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ func (c *Project) queueAndStreamJob(
}()
}

var assignedRunner *pb.Ref_RunnerId

for {
resp, err := stream.Recv()
if err != nil {
Expand All @@ -244,6 +246,7 @@ func (c *Project) queueAndStreamJob(
}

switch event := resp.Event.(type) {

case *pb.GetJobStreamResponse_Complete_:
completed = true

Expand Down Expand Up @@ -383,6 +386,41 @@ func (c *Project) queueAndStreamJob(
stateEventTimer = nil
}

// Check if this job has been assigned a runner for the first time
if event.State != nil &&
event.State.Job != nil &&
event.State.Job.AssignedRunner != nil &&
assignedRunner == nil {

assignedRunner = event.State.Job.AssignedRunner

runner, err := c.client.GetRunner(ctx, &pb.GetRunnerRequest{RunnerId: assignedRunner.Id})
if err != nil {
ui.Output("Failed to inspect the runner (id %q) assigned for this operation: %s", assignedRunner.Id, err, terminal.WithErrorStyle())
break
}
switch runnerType := runner.Kind.(type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this because it's like self-documenting of the different runners in our runner system.

case *pb.Runner_Local_:
ui.Output("Performing operation locally", terminal.WithInfoStyle())
case *pb.Runner_Remote_:
ui.Output("Performing this operation on a remote runner with id %q", runner.Id, terminal.WithInfoStyle())
case *pb.Runner_Odr:
log.Debug("Executing operation on an on-demand runner from profile with ID %q", runnerType.Odr.ProfileId)
profile, err := c.client.GetOnDemandRunnerConfig(
ctx, &pb.GetOnDemandRunnerConfigRequest{
Config: &pb.Ref_OnDemandRunnerConfig{
Id: runnerType.Odr.ProfileId,
},
})
if err != nil {
ui.Output("Performing operation on an on-demand runner from profile with ID %q", runnerType.Odr.ProfileId, terminal.WithInfoStyle())
ui.Output("Failed inspecting runner profile with id %q: %s", runnerType.Odr.GetProfileId(), err, terminal.WithErrorStyle())
} else {
ui.Output("Performing operation on %q with runner profile %q", profile.Config.PluginType, profile.Config.Name, terminal.WithInfoStyle())
}
}
}

// For certain states, we do a quality of life UI message if
// the wait time ends up being long.
switch event.State.Current {
Expand Down
2 changes: 1 addition & 1 deletion internal/client/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func remoteOpPreferred(ctx context.Context, client pb.WaypointClient, project *p
}
hasRemoteRunner := false
for _, runner := range runnersResp.Runners {
if !runner.Odr {
if _, ok := runner.Kind.(*pb.Runner_Remote_); ok {
// NOTE(izaak): There is currently no way to distinguish between a remote runner and a CLI runner.
// So if some other waypoint client is performing an operation at this moment, we will interpret
// that as a remote runner, and this will return a false positive.
Expand Down
4 changes: 3 additions & 1 deletion internal/client/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ func Test_remoteOpPreferred(t *testing.T) {
}

// Register a remote runner
_, remoteRunnerClose := singleprocess.TestRunner(t, client, &pb.Runner{Odr: false})
_, remoteRunnerClose := singleprocess.TestRunner(t, client, &pb.Runner{
Kind: &pb.Runner_Remote_{Remote: &pb.Runner_Remote{}},
})
defer remoteRunnerClose()

// Register a non-default runner profile
Expand Down
28 changes: 24 additions & 4 deletions internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,25 @@ func New(opts ...Option) (*Runner, error) {
runner.runner = &pb.Runner{
Id: runner.id,
ByIdOnly: cfg.byIdOnly,
Odr: cfg.odr,
}

// Determine what kind of remote runner we are
if cfg.odr {
runner.runner.Kind = &pb.Runner_Odr{
Odr: &pb.Runner_ODR{
ProfileId: cfg.odrProfileId,
},
}
} else if runner.local {
runner.runner.Kind = &pb.Runner_Local_{
Local: &pb.Runner_Local{},
}
} else {
// If this runner isn't ODR or Local, by process of elimination it must be a "static" remote runner.
// We don't currently have a method to indicate this explicitly.
runner.runner.Kind = &pb.Runner_Remote_{
Remote: &pb.Runner_Remote{},
}
}

// Setup our runner components list
Expand Down Expand Up @@ -267,8 +285,9 @@ func (r *Runner) setState(state *bool, v bool) {
}

type config struct {
byIdOnly bool
odr bool
byIdOnly bool
odr bool
odrProfileId string
}

type Option func(*Runner, *config) error
Expand Down Expand Up @@ -323,9 +342,10 @@ func ByIdOnly() Option {

// WithODR configures this runner to be an on-demand runner. This
// will flag this to the server on registration.
func WithODR() Option {
func WithODR(profileId string) Option {
return func(r *Runner, cfg *config) error {
cfg.odr = true
cfg.odrProfileId = profileId
return nil
}
}
Expand Down
15 changes: 15 additions & 0 deletions internal/server/gen/mocks/is_runner__kind.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions internal/server/gen/mocks/is_runner__type.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading