Skip to content

Commit

Permalink
Merge pull request #2 from whywaita/feat/add-image-alias
Browse files Browse the repository at this point in the history
Move LXD_MULTI_IMAGE_ALIAS to shoes-provider from server
  • Loading branch information
whywaita authored Dec 8, 2021
2 parents b26d9a2 + ea85594 commit 90a0561
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 84 deletions.
5 changes: 1 addition & 4 deletions server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ Server-side implementation for shoes-lxd-multi
```

### Optional values
- `LXD_MULTI_IMAGE_ALIAS`
- set runner image alias
- default: `ubuntu:bionic`
- e.g.) for remote image server: `https://192.0.2.110:8443/ubuntu-custom`

- `LXD_MULTI_RESOURCE_TYPE_MAPPING`
- mapping `resource_type` and CPU / Memory.
- need JSON format. keys is `resource_type_name`, `cpu`, `memory`.
Expand Down
4 changes: 1 addition & 3 deletions server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ require (
github.com/lxc/lxd v0.0.0-20211202222358-a293da71aeb0
github.com/prometheus/client_golang v1.11.0
github.com/whywaita/myshoes v1.10.4
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211203151606-53728ef694c2
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211208053634-b26d9a26e161
google.golang.org/grpc v1.42.0
)

//replace github.com/flosch/pongo2 => github.com/flosch/pongo2/v4 v4.0.2
2 changes: 2 additions & 0 deletions server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,8 @@ github.com/whywaita/myshoes v1.10.4 h1:4EeoOKnwN2HpCe8KaLRQhQPWDvqYlNSPjIc94z5WC
github.com/whywaita/myshoes v1.10.4/go.mod h1:1HsvGV2VRtOtagjo0S0XhYM9dJdOHzX2+XXJ1yQAG04=
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211203151606-53728ef694c2 h1:bidYeGz7agcdZMjO1yk2GhjhZMuVZmszfu40StCblmc=
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211203151606-53728ef694c2/go.mod h1:xLARbdd13u1aMMBI0xRc8FVv4RRoCFf5f7+E/HaNs7o=
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211208053634-b26d9a26e161 h1:p8niwHC6nWbg0uoX3pd3aI5ZwVxgtHXGDzSKx49zcfg=
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211208053634-b26d9a26e161/go.mod h1:xLARbdd13u1aMMBI0xRc8FVv4RRoCFf5f7+E/HaNs7o=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
Expand Down
4 changes: 2 additions & 2 deletions server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ func main() {
}

func run() error {
hostConfigs, mapping, instanceSource, listenPort, overCommitPercent, err := config.Load()
hostConfigs, mapping, listenPort, overCommitPercent, err := config.Load()
if err != nil {
return fmt.Errorf("failed to create server: %w", err)
}

go serveMetrics(context.Background(), hostConfigs)

server, err := api.New(hostConfigs, mapping, instanceSource, overCommitPercent)
server, err := api.New(hostConfigs, mapping, overCommitPercent)
if err != nil {
return fmt.Errorf("failed to create server: %w", err)
}
Expand Down
6 changes: 1 addition & 5 deletions server/pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"log"
"net"

"github.com/lxc/lxd/shared/api"

pb "github.com/whywaita/shoes-lxd-multi/proto.go"
"github.com/whywaita/shoes-lxd-multi/server/pkg/config"
"github.com/whywaita/shoes-lxd-multi/server/pkg/lxdclient"
Expand All @@ -19,17 +17,15 @@ type ShoesLXDMultiServer struct {

hostConfigs *config.HostConfigMap
resourceMapping map[pb.ResourceType]config.Mapping
instanceSource *api.InstanceSource

overCommitPercent uint64
}

// New create gRPC server
func New(hostConfigs *config.HostConfigMap, mapping map[pb.ResourceType]config.Mapping, instanceSource *api.InstanceSource, overCommitPercent uint64) (*ShoesLXDMultiServer, error) {
func New(hostConfigs *config.HostConfigMap, mapping map[pb.ResourceType]config.Mapping, overCommitPercent uint64) (*ShoesLXDMultiServer, error) {
return &ShoesLXDMultiServer{
hostConfigs: hostConfigs,
resourceMapping: mapping,
instanceSource: instanceSource,
overCommitPercent: overCommitPercent,
}, nil
}
Expand Down
46 changes: 45 additions & 1 deletion server/pkg/api/server_add_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"log"
"math/rand"
"net/url"
"sort"
"strconv"
"strings"
Expand All @@ -26,6 +27,12 @@ func (s *ShoesLXDMultiServer) AddInstance(ctx context.Context, req *pb.AddInstan
return nil, status.Errorf(codes.InvalidArgument, "failed to parse request name: %+v", err)
}
instanceName := req.RunnerName

instanceSource, err := parseAlias(req.ImageAlias)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to parse image alias: %+v", err)
}

targetLXDHosts, err := s.validateTargetHosts(req.TargetHosts)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to validate target hosts: %+v", err)
Expand All @@ -45,7 +52,7 @@ func (s *ShoesLXDMultiServer) AddInstance(ctx context.Context, req *pb.AddInstan
Config: s.getInstanceConfig(req.SetupScript, req.ResourceType),
},
Name: instanceName,
Source: *s.instanceSource,
Source: *instanceSource,
}

client = host.Client
Expand Down Expand Up @@ -161,3 +168,40 @@ func schedule(targets []targetHost, limitOverCommit uint64) (*targetHost, error)
index := rand.Intn(len(schedulableTargets))
return &schedulableTargets[index], nil
}

// parseAlias parse user input
func parseAlias(input string) (*api.InstanceSource, error) {
if strings.EqualFold(input, "") {
// default value is ubuntu:bionic
return &api.InstanceSource{
Type: "image",
Properties: map[string]string{
"os": "ubuntu",
"release": "bionic",
},
}, nil
}

if strings.HasPrefix(input, "http") {
// https://<FQDN or IP>:8443/<alias>
u, err := url.Parse(input)
if err != nil {
return nil, fmt.Errorf("failed to parse alias: %w", err)
}

urlImageServer := fmt.Sprintf("%s://%s", u.Scheme, u.Host)
alias := strings.TrimPrefix(u.Path, "/")

return &api.InstanceSource{
Type: "image",
Mode: "pull",
Server: urlImageServer,
Alias: alias,
}, nil
}

return &api.InstanceSource{
Type: "image",
Alias: input,
}, nil
}
20 changes: 6 additions & 14 deletions server/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ import (

pb "github.com/whywaita/shoes-lxd-multi/proto.go"

"github.com/lxc/lxd/shared/api"
"github.com/whywaita/myshoes/pkg/datastore"
)

const (
// EnvLXDHosts is json of lxd hosts
EnvLXDHosts = "LXD_MULTI_HOSTS"

// EnvLXDImageAlias is alias in lxd
EnvLXDImageAlias = "LXD_MULTI_IMAGE_ALIAS"
// EnvLXDResourceTypeMapping is mapping resource in lxd
EnvLXDResourceTypeMapping = "LXD_MULTI_RESOURCE_TYPE_MAPPING"
// EnvPort will listen port
Expand All @@ -34,34 +31,29 @@ type Mapping struct {
}

// Load load config from Environment values
func Load() (*HostConfigMap, map[pb.ResourceType]Mapping, *api.InstanceSource, int, uint64, error) {
func Load() (*HostConfigMap, map[pb.ResourceType]Mapping, int, uint64, error) {
hostConfigs, err := loadHostConfigs()
if err != nil {
return nil, nil, nil, -1, 0, fmt.Errorf("failed to load host config: %w", err)
return nil, nil, -1, 0, fmt.Errorf("failed to load host config: %w", err)
}

envMappingJSON := os.Getenv(EnvLXDResourceTypeMapping)
var m map[pb.ResourceType]Mapping
if envMappingJSON != "" {
m, err = readResourceTypeMapping(envMappingJSON)
if err != nil {
return nil, nil, nil, -1, 0, fmt.Errorf("failed to read %s: %w", EnvLXDResourceTypeMapping, err)
return nil, nil, -1, 0, fmt.Errorf("failed to read %s: %w", EnvLXDResourceTypeMapping, err)
}
}

alias, err := parseAlias(os.Getenv(EnvLXDImageAlias))
if err != nil {
return nil, nil, nil, -1, 0, fmt.Errorf("failed to parse alias %s: %w", EnvLXDImageAlias, err)
}

envPort := os.Getenv(EnvPort)
var port int
if envPort == "" {
port = 8080
} else {
port, err = strconv.Atoi(envPort)
if err != nil {
return nil, nil, nil, -1, 0, fmt.Errorf("failed to parse %s, need to int: %w", EnvPort, err)
return nil, nil, -1, 0, fmt.Errorf("failed to parse %s, need to int: %w", EnvPort, err)
}
}

Expand All @@ -72,11 +64,11 @@ func Load() (*HostConfigMap, map[pb.ResourceType]Mapping, *api.InstanceSource, i
} else {
overCommitPercent, err = strconv.ParseUint(envOCP, 10, 64)
if err != nil {
return nil, nil, nil, -1, 0, fmt.Errorf("failed to parse %s, need to uint: %w", EnvOverCommit, err)
return nil, nil, -1, 0, fmt.Errorf("failed to parse %s, need to uint: %w", EnvOverCommit, err)
}
}

return hostConfigs, m, alias, port, overCommitPercent, nil
return hostConfigs, m, port, overCommitPercent, nil
}

func readResourceTypeMapping(env string) (map[pb.ResourceType]Mapping, error) {
Expand Down
46 changes: 0 additions & 46 deletions server/pkg/config/config_alias.go

This file was deleted.

9 changes: 8 additions & 1 deletion shoes-lxd-multi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,11 @@ shoes-provider implementation for shoes-lxd-multi
]
```

- `LXD_MULTI_SERVER_ENDPOINT`: Endpoint of Server-side Application
- `LXD_MULTI_SERVER_ENDPOINT`: Endpoint of Server-side Application

### Optional values

- `LXD_MULTI_IMAGE_ALIAS`
- set runner image alias
- default: `ubuntu:bionic`
- e.g.) for remote image server: `https://192.0.2.110:8443/ubuntu-custom`
2 changes: 1 addition & 1 deletion shoes-lxd-multi/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ go 1.16
require (
github.com/hashicorp/go-plugin v1.4.3
github.com/whywaita/myshoes v1.10.4
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211203151606-53728ef694c2
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211208053634-b26d9a26e161
google.golang.org/grpc v1.33.2
)
2 changes: 2 additions & 0 deletions shoes-lxd-multi/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ github.com/whywaita/myshoes v1.10.4 h1:4EeoOKnwN2HpCe8KaLRQhQPWDvqYlNSPjIc94z5WC
github.com/whywaita/myshoes v1.10.4/go.mod h1:1HsvGV2VRtOtagjo0S0XhYM9dJdOHzX2+XXJ1yQAG04=
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211203151606-53728ef694c2 h1:bidYeGz7agcdZMjO1yk2GhjhZMuVZmszfu40StCblmc=
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211203151606-53728ef694c2/go.mod h1:xLARbdd13u1aMMBI0xRc8FVv4RRoCFf5f7+E/HaNs7o=
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211208053634-b26d9a26e161 h1:p8niwHC6nWbg0uoX3pd3aI5ZwVxgtHXGDzSKx49zcfg=
github.com/whywaita/shoes-lxd-multi/proto.go v0.0.0-20211208053634-b26d9a26e161/go.mod h1:xLARbdd13u1aMMBI0xRc8FVv4RRoCFf5f7+E/HaNs7o=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
Expand Down
25 changes: 18 additions & 7 deletions shoes-lxd-multi/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const (
EnvTargetHosts = "LXD_MULTI_TARGET_HOSTS"
// EnvServerEndpoint is endpoint of server
EnvServerEndpoint = "LXD_MULTI_SERVER_ENDPOINT"

// EnvLXDImageAlias is alias in lxd
EnvLXDImageAlias = "LXD_MULTI_IMAGE_ALIAS"
)

func main() {
Expand Down Expand Up @@ -53,24 +56,29 @@ type LXDMultiPlugin struct {
plugin.Plugin
}

func loadConfig() ([]string, string, error) {
func loadConfig() ([]string, string, string, error) {
var targetHosts []string
envTargetHosts := os.Getenv(EnvTargetHosts)
if err := json.Unmarshal([]byte(envTargetHosts), &targetHosts); err != nil {
return nil, "", fmt.Errorf("failed to unmarshal JSON from %s: %w", envTargetHosts, err)
return nil, "", "", fmt.Errorf("failed to unmarshal JSON from %s: %w", envTargetHosts, err)
}

envServerEndpoint := os.Getenv(EnvServerEndpoint)
if envServerEndpoint == "" {
return nil, "", fmt.Errorf("must set %s", EnvServerEndpoint)
return nil, "", "", fmt.Errorf("must set %s", EnvServerEndpoint)
}

alias := os.Getenv(EnvLXDImageAlias)
if alias == "" {
alias = "ubuntu:bionic"
}

return targetHosts, envServerEndpoint, nil
return targetHosts, envServerEndpoint, alias, nil
}

// GRPCServer is implement gRPC Server.
func (l *LXDMultiPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
targetHosts, serverEndpoint, err := loadConfig()
targetHosts, serverEndpoint, imageAlias, err := loadConfig()
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
Expand All @@ -83,7 +91,7 @@ func (l *LXDMultiPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) e
if err != nil {
return fmt.Errorf("failed to dial to server: %w", err)
}
client := NewClient(targetHosts, grpcConn)
client := NewClient(targetHosts, grpcConn, imageAlias)
pb.RegisterShoesServer(s, client)
return nil

Expand All @@ -101,13 +109,15 @@ type Client struct {

targetHosts []string
conn *grpc.ClientConn
imageAlias string
}

// NewClient create Client
func NewClient(targetHosts []string, conn *grpc.ClientConn) *Client {
func NewClient(targetHosts []string, conn *grpc.ClientConn, imageAlias string) *Client {
return &Client{
targetHosts: targetHosts,
conn: conn,
imageAlias: imageAlias,
}
}

Expand All @@ -119,6 +129,7 @@ func (l Client) AddInstance(ctx context.Context, req *pb.AddInstanceRequest) (*p
SetupScript: req.SetupScript,
ResourceType: shoeslxdpb.ResourceTypeToShoesLXDMultiPb(req.ResourceType),
TargetHosts: l.targetHosts,
ImageAlias: l.imageAlias,
}

slResp, err := slClient.AddInstance(ctx, slReq)
Expand Down

0 comments on commit 90a0561

Please sign in to comment.