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

Commit

Permalink
Merge pull request #3145 from hashicorp/target_runner_labels_server
Browse files Browse the repository at this point in the history
feature: Enable runner targeting by labels specified in runner profile
  • Loading branch information
xiaolin-ninja committed Mar 28, 2022
2 parents 8f04eb3 + b58a875 commit 9d34ba2
Show file tree
Hide file tree
Showing 10 changed files with 435 additions and 65 deletions.
8 changes: 8 additions & 0 deletions .changelog/3145.txt
@@ -0,0 +1,8 @@
```release-note:feature
**Targetable Runners with Labels**: Waypoint now supports runner profiles that target specific on-demand runners by labels.
Projects and/or Apps can be configured to use a specific runner profile, identified by name.
The runner profile will target all operations to a specific on-demand runner by ID, or labels on the runner.
```
```release-note:improvement
cli: `runner profile` command set now supports target runner labels
```
8 changes: 6 additions & 2 deletions internal/cli/runner_profile_inspect.go
@@ -1,8 +1,10 @@
package cli

import (
"encoding/json"
"fmt"

"github.com/posener/complete"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/encoding/protojson"
Expand All @@ -11,7 +13,6 @@ import (
"github.com/hashicorp/waypoint/internal/clierrors"
"github.com/hashicorp/waypoint/internal/pkg/flag"
pb "github.com/hashicorp/waypoint/pkg/server/gen"
"github.com/posener/complete"
)

type RunnerProfileInspectCommand struct {
Expand Down Expand Up @@ -84,6 +85,9 @@ func (c *RunnerProfileInspectCommand) Run(args []string) int {
targetRunner = "*"
case *pb.Ref_Runner_Id:
targetRunner = t.Id.Id
case *pb.Ref_Runner_Labels:
s, _ := json.Marshal(t.Labels.Labels)
targetRunner = "labels: " + string(s)
}
}
c.ui.Output("Runner profile:", terminal.WithHeaderStyle())
Expand All @@ -104,7 +108,7 @@ func (c *RunnerProfileInspectCommand) Run(args []string) int {
Name: "Plugin Type", Value: config.PluginType,
},
{
Name: "Target Runner ID", Value: targetRunner,
Name: "Target Runner", Value: targetRunner,
},
{
Name: "Environment Variables", Value: config.EnvironmentVariables,
Expand Down
14 changes: 9 additions & 5 deletions internal/cli/runner_profile_list.go
@@ -1,14 +1,15 @@
package cli

import (
"github.com/hashicorp/waypoint/internal/clierrors"
"github.com/hashicorp/waypoint/internal/pkg/flag"
pb "github.com/hashicorp/waypoint/pkg/server/gen"
"encoding/json"

"github.com/posener/complete"
empty "google.golang.org/protobuf/types/known/emptypb"

"github.com/hashicorp/waypoint-plugin-sdk/terminal"
empty "google.golang.org/protobuf/types/known/emptypb"
"github.com/hashicorp/waypoint/internal/clierrors"
"github.com/hashicorp/waypoint/internal/pkg/flag"
pb "github.com/hashicorp/waypoint/pkg/server/gen"
)

type RunnerProfileListCommand struct {
Expand Down Expand Up @@ -37,7 +38,7 @@ func (c *RunnerProfileListCommand) Run(args []string) int {

c.ui.Output("Runner profiles")

tbl := terminal.NewTable("Name", "Plugin Type", "OCI Url", "Target Runner ID",
tbl := terminal.NewTable("Name", "Plugin Type", "OCI Url", "Target Runner",
"Default")

for _, p := range resp.Configs {
Expand All @@ -53,6 +54,9 @@ func (c *RunnerProfileListCommand) Run(args []string) int {
targetRunner = "*"
case *pb.Ref_Runner_Id:
targetRunner = t.Id.Id
case *pb.Ref_Runner_Labels:
s, _ := json.Marshal(t.Labels.Labels)
targetRunner = "labels: " + string(s)
}
}

Expand Down
49 changes: 33 additions & 16 deletions internal/cli/runner_profile_set.go
Expand Up @@ -5,29 +5,31 @@ import (
"path/filepath"
"strings"

"github.com/posener/complete"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
hcljson "github.com/hashicorp/hcl/v2/json"
"github.com/hashicorp/waypoint-plugin-sdk/terminal"
"github.com/hashicorp/waypoint/internal/clierrors"
"github.com/hashicorp/waypoint/internal/pkg/flag"
pb "github.com/hashicorp/waypoint/pkg/server/gen"
"github.com/posener/complete"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

type RunnerProfileSetCommand struct {
*baseCommand
//TODO(XX): after `-env-vars` as a slice is deprecated, rename flagEnvVar to flagEnvVars
flagName string
flagOCIUrl string
flagEnvVar map[string]string
flagEnvVars []string
flagPluginType string
flagPluginConfig string
flagDefault bool
flagTargetRunnerId string
flagName string
flagOCIUrl string
flagEnvVar map[string]string
flagEnvVars []string
flagPluginType string
flagPluginConfig string
flagDefault bool
flagTargetRunnerId string
flagTargetRunnerLabels map[string]string
}

func (c *RunnerProfileSetCommand) Run(args []string) int {
Expand Down Expand Up @@ -107,6 +109,18 @@ func (c *RunnerProfileSetCommand) Run(args []string) int {
},
},
}
if c.flagTargetRunnerLabels != nil {
c.ui.Output("Both -target-runner-id and -target-runner-label detected, only one can be set at a time. ID takes priority.",
terminal.WithWarningStyle())
}
} else if c.flagTargetRunnerLabels != nil {
od.TargetRunner = &pb.Ref_Runner{
Target: &pb.Ref_Runner_Labels{
Labels: &pb.Ref_RunnerLabels{
Labels: c.flagTargetRunnerLabels,
},
},
}
} else {
od.TargetRunner = &pb.Ref_Runner{Target: &pb.Ref_Runner_Any{}}
}
Expand Down Expand Up @@ -285,7 +299,14 @@ func (c *RunnerProfileSetCommand) Flags() *flag.Sets {
Name: "target-runner-id",
Target: &c.flagTargetRunnerId,
Default: "",
Usage: "ID of the remote runner to target for the profile.",
Usage: "ID of the runner to target for this remote runner profile.",
})

f.StringMapVar(&flag.StringMapVar{
Name: "target-runner-label",
Target: &c.flagTargetRunnerLabels,
Usage: "Labels on the runner to target for this remote runner profile. " +
"e.g. `-target-runner-label=k=v`. Can be specified multiple times.",
})
})
}
Expand All @@ -305,16 +326,12 @@ func (c *RunnerProfileSetCommand) Synopsis() string {
func (c *RunnerProfileSetCommand) Help() string {
return formatHelp(`
Usage: waypoint runner profile set [OPTIONS]
Create or update a runner profile.
This will register a new runner profile with the given options. If
a runner profile with the same id already exists, this will update the
existing runner profile using the fields that are set.
Waypoint will use a runner profile to spawn containers for
various kinds of work as needed on the platform requested during any given
lifecycle operation.
` + c.Flags().Help())
}
15 changes: 5 additions & 10 deletions internal/server/singleprocess/service_job.go
Expand Up @@ -163,8 +163,8 @@ func (s *service) queueJobReqToJob(
}

// If the job has any target runner, it is a remote job.
// We attempt to spawn an on-demand runner for the job, if it doesn't already have an ODR assigned, use a default.
if _, anyTarget := job.TargetRunner.Target.(*pb.Ref_Runner_Any); anyTarget {
// Use a default ODR profile if it doesn't already have one assigned.
if _, ok := job.TargetRunner.Target.(*pb.Ref_Runner_Any); ok {
if job.OndemandRunner == nil {
ods, err := s.state.OnDemandRunnerConfigDefault()
if err != nil {
Expand All @@ -178,7 +178,7 @@ func (s *service) queueJobReqToJob(
job.OndemandRunner = ods[0]
default:
job.OndemandRunner = ods[rand.Intn(len(ods))]
log.Debug("multiple default on-demand runners detected, chose a random one",
log.Debug("multiple default on-demand runner profiles detected, chose a random one",
"runner-config-id", job.OndemandRunner.Id)
}
}
Expand Down Expand Up @@ -241,7 +241,7 @@ func (s *service) wrapJobWithRunner(
return nil, err
}

// Change our source job to require being run on the launched ODR.
// Change our source job to run on the launched ODR.
source.TargetRunner = &pb.Ref_Runner{
Target: &pb.Ref_Runner_Id{
Id: &pb.Ref_RunnerId{
Expand Down Expand Up @@ -311,7 +311,7 @@ func (s *service) onDemandRunnerStartJob(
}

// We generate a new login token for each ondemand-runner used. This will inherit
// the user of the token to be the user that queue'd the original job, which is
// the user of the token to be the user that queued the original job, which is
// the correct behavior.
token, err := s.newToken(60*time.Minute, DefaultKeyId, nil, &pb.Token{
Kind: &pb.Token_Login_{Login: &pb.Token_Login{
Expand Down Expand Up @@ -380,11 +380,6 @@ func (s *service) onDemandRunnerStartJob(

job.ExpireTime = timestamppb.New(time.Now().Add(dur))

if err != nil {
return nil, "", status.Errorf(codes.FailedPrecondition,
"Failed to get on-demand runner config by name %q, id %q: %s",
job.OndemandRunner.Name, job.OndemandRunner.Id, err)
}
// This will be either "Any" or a specific static runner.
job.TargetRunner = od.TargetRunner

Expand Down

0 comments on commit 9d34ba2

Please sign in to comment.