Add the ability to select a cloud provider

This adds two packages:

        mu/pkg/compiler/clouds
        mu/pkg/compiler/schedulers

And introduces enums for the cloud targets we expect to support.

It also adds the ability at the command line to specify a provider;
for example:

        $ mu build --target=aws         # AWS native
        $ mu build --target=aws:ecs     # AWS ECS
        $ mu build -t=gcp:kubernetes    # Kube on GCP
This commit is contained in:
joeduffy 2016-11-17 07:00:52 -08:00
parent 54148c67e4
commit 8a7fbf019c
6 changed files with 110 additions and 5 deletions

View file

@ -3,10 +3,15 @@
package cmd
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/golang/glog"
"github.com/marapongo/mu/pkg/compiler"
"github.com/marapongo/mu/pkg/compiler/clouds"
"github.com/marapongo/mu/pkg/compiler/schedulers"
"github.com/spf13/cobra"
)
@ -18,6 +23,7 @@ const defaultOutp = ".mu"
func newBuildCmd() *cobra.Command {
var outp string
var target string
var cmd = &cobra.Command{
Use: "build [source]",
Short: "Compile a Mu Stack",
@ -32,15 +38,56 @@ func newBuildCmd() *cobra.Command {
glog.Fatal(err)
}
mup := compiler.NewCompiler(compiler.DefaultOpts(abs))
opts := compiler.DefaultOpts(abs)
setCloudTargetOptions(target, &opts)
mup := compiler.NewCompiler(opts)
mup.Build(abs, outp)
},
}
cmd.PersistentFlags().StringVar(
&outp, "out", defaultOutp,
"The directory in which to place build artifacts",
)
"The directory in which to place build artifacts")
cmd.PersistentFlags().StringVarP(
&target, "target", "t", "",
"Generate output for the given target (format: \"cloud[:scheduler]\")")
return cmd
}
func setCloudTargetOptions(target string, opts *compiler.Options) {
// If a target was specified, parse the pieces and set the options. A target isn't required because stacks
// and workspaces can have default targets. This simply overrides it or provides one where none exists.
if target != "" {
// The format is "cloud[:scheduler]"; parse out the pieces.
var cloud string
var cloudScheduler string
if delim := strings.IndexRune(target, ':'); delim != -1 {
cloud = target[:delim]
cloudScheduler = target[delim+1:]
} else {
cloud = target
}
cloudTarget, ok := clouds.TargetMap[cloud]
if !ok {
fmt.Fprintf(os.Stderr, "Unrecognized cloud target '%v'\n", cloud)
os.Exit(-1)
}
var cloudSchedulerTarget schedulers.Target
if cloudScheduler != "" {
cloudSchedulerTarget, ok = schedulers.TargetMap[cloudScheduler]
if !ok {
fmt.Fprintf(os.Stderr, "Unrecognized cloud scheduler target '%v'\n", cloudScheduler)
os.Exit(-1)
}
}
opts.Target = compiler.Target{
Cloud: cloudTarget,
Scheduler: cloudSchedulerTarget,
}
}
}

View file

@ -19,7 +19,7 @@ func main() {
defer glog.Flush()
if err := cmd.NewMuCmd().Execute(); err != nil {
fmt.Println(err)
fmt.Fprintf(os.Stderr, "An error occurred: %v\n", err)
os.Exit(-1)
}
}

View file

@ -0,0 +1,21 @@
// Copyright 2016 Marapongo, Inc. All rights reserved.
package clouds
// Target selects a cloud infrastructure to target when compiling.
type Target int
const (
AWSTarget Target = iota // Amazon Web Services
GCPTarget // Google Cloud Platform
AzureTarget // Microsoft Azure
VMWareTarget // VMWare vSphere, etc.
)
// TargetMap maps human-friendly names to the Targets for those names.
var TargetMap = map[string]Target{
"aws": AWSTarget,
"gcp": GCPTarget,
"azure": AzureTarget,
"vmware": VMWareTarget,
}

View file

@ -103,6 +103,7 @@ func (c *compiler) Build(inp string, outp string) {
}
// TODO: perform semantic analysis on the bound tree.
// TODO: select a target backend (including reading in a Muclusters file if needed).
// TODO: lower the ASTs to the target backend's representation, emit it.
// TODO: delta generation, deployment, etc.

View file

@ -3,12 +3,15 @@
package compiler
import (
"github.com/marapongo/mu/pkg/compiler/clouds"
"github.com/marapongo/mu/pkg/compiler/schedulers"
"github.com/marapongo/mu/pkg/diag"
)
// Options contains all of the settings a user can use to control the compiler's behavior.
type Options struct {
Diag diag.Sink
Diag diag.Sink
Target Target
}
// DefaultOpts returns the default set of compiler options.
@ -17,3 +20,9 @@ func DefaultOpts(pwd string) Options {
Diag: diag.DefaultSink(pwd),
}
}
// Target is the target "architecture" we are compiling against.
type Target struct {
Cloud clouds.Target
Scheduler schedulers.Target
}

View file

@ -0,0 +1,27 @@
// Copyright 2016 Marapongo, Inc. All rights reserved.
package schedulers
// Target selects a cloud scheduler to target when compiling.
type Target int
const (
NativeTarget Target = iota // no scheduler, just use native VMs.
SwarmTarget // Docker Swarm
KubernetesTarget // Kubernetes
MesosTarget // Apache Mesos
ECSTarget // Amazon Elastic Container Service (only valid for AWS)
GKETarget // Google Container Engine (only valid for GCP)
ACSTarget // Microsoft Azure Container Service (only valid for Azure)
)
// TargetMap maps human-friendly names to the Targets for those names.
var TargetMap = map[string]Target{
"": NativeTarget,
"swarm": SwarmTarget,
"kubernetes": KubernetesTarget,
"mesos": MesosTarget,
"ecs": ECSTarget,
"gke": GKETarget,
"acs": ACSTarget,
}