This change guts the deployment planning and execution process, a necessary component of pulumi/lumi#90. The major effect of this change is that resources are actually connected to the live objects, instead of being snapshots taken at inopportune moments in time.
138 lines
4.4 KiB
Go
138 lines
4.4 KiB
Go
// Licensed to Pulumi Corporation ("Pulumi") under one or more
|
|
// contributor license agreements. See the NOTICE file distributed with
|
|
// this work for additional information regarding copyright ownership.
|
|
// Pulumi licenses this file to You under the Apache License, Version 2.0
|
|
// (the "License"); you may not use this file except in compliance with
|
|
// the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package main
|
|
|
|
import (
|
|
"github.com/golang/glog"
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/pulumi/lumi/pkg/compiler"
|
|
"github.com/pulumi/lumi/pkg/compiler/core"
|
|
"github.com/pulumi/lumi/pkg/compiler/errors"
|
|
"github.com/pulumi/lumi/pkg/compiler/symbols"
|
|
"github.com/pulumi/lumi/pkg/eval/rt"
|
|
"github.com/pulumi/lumi/pkg/pack"
|
|
"github.com/pulumi/lumi/pkg/resource"
|
|
"github.com/pulumi/lumi/pkg/tokens"
|
|
"github.com/pulumi/lumi/pkg/util/cmdutil"
|
|
)
|
|
|
|
func NewLumiCmd() *cobra.Command {
|
|
var logFlow bool
|
|
var logToStderr bool
|
|
var verbose int
|
|
cmd := &cobra.Command{
|
|
Use: "lumi",
|
|
Short: "Lumi is a framework and toolset for reusable stacks of services",
|
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
|
cmdutil.InitLogging(logToStderr, verbose, logFlow)
|
|
},
|
|
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
|
glog.Flush()
|
|
},
|
|
}
|
|
|
|
cmd.PersistentFlags().BoolVar(&logFlow, "logflow", false, "Flow log settings to child processes (like plugins)")
|
|
cmd.PersistentFlags().BoolVar(&logToStderr, "logtostderr", false, "Log to stderr instead of to files")
|
|
cmd.PersistentFlags().IntVarP(
|
|
&verbose, "verbose", "v", 0, "Enable verbose logging (e.g., v=3); anything >3 is very verbose")
|
|
|
|
cmd.AddCommand(newConfigCmd())
|
|
cmd.AddCommand(newDeployCmd())
|
|
cmd.AddCommand(newDestroyCmd())
|
|
cmd.AddCommand(newEnvCmd())
|
|
cmd.AddCommand(newPackCmd())
|
|
cmd.AddCommand(newPlanCmd())
|
|
cmd.AddCommand(newVersionCmd())
|
|
|
|
return cmd
|
|
}
|
|
|
|
func prepareCompiler(cmd *cobra.Command, args []string) (compiler.Compiler, *pack.Package) {
|
|
// If there's a --, we need to separate out the command args from the stack args.
|
|
flags := cmd.Flags()
|
|
dashdash := flags.ArgsLenAtDash()
|
|
var packArgs []string
|
|
if dashdash != -1 {
|
|
packArgs = args[dashdash:]
|
|
args = args[0:dashdash]
|
|
}
|
|
|
|
// Create a compiler options object and map any flags and arguments to settings on it.
|
|
opts := core.DefaultOptions()
|
|
opts.Args = dashdashArgsToMap(packArgs)
|
|
|
|
// If a package argument is present, try to load that package (either via stdin or a path).
|
|
var pkg *pack.Package
|
|
var root string
|
|
if len(args) > 0 {
|
|
pkg, root = readPackageFromArg(args[0])
|
|
}
|
|
|
|
// Now create a compiler object based on whether we loaded a package or just have a root to deal with.
|
|
var comp compiler.Compiler
|
|
var err error
|
|
if root == "" {
|
|
comp, err = compiler.Newwd(opts)
|
|
} else {
|
|
comp, err = compiler.New(root, opts)
|
|
}
|
|
if err != nil {
|
|
cmdutil.Sink().Errorf(errors.ErrorCantCreateCompiler, err)
|
|
}
|
|
|
|
return comp, pkg
|
|
}
|
|
|
|
// compile just uses the standard logic to parse arguments, options, and to locate/compile a package. It returns the
|
|
// LumiGL graph that is produced, or nil if an error occurred (in which case, we would expect non-0 errors).
|
|
func compile(cmd *cobra.Command, args []string, config resource.ConfigMap) *compileResult {
|
|
// Prepare the compiler info and, provided it succeeds, perform the compilation.
|
|
if comp, pkg := prepareCompiler(cmd, args); comp != nil {
|
|
// Create the preexec hook if the config map is non-nil.
|
|
var preexec compiler.Preexec
|
|
configVars := make(map[tokens.Token]*rt.Object)
|
|
if config != nil {
|
|
preexec = config.ConfigApplier(configVars)
|
|
}
|
|
|
|
// Now perform the compilation and extract the heap snapshot.
|
|
var heap *heapstate.Heap
|
|
var pkgsym *symbols.Package
|
|
if pkg == nil {
|
|
pkgsym, heap = comp.Compile(preexec)
|
|
} else {
|
|
pkgsym, heap = comp.CompilePackage(pkg, preexec)
|
|
}
|
|
|
|
return &compileResult{
|
|
C: comp,
|
|
Pkg: pkgsym,
|
|
Heap: heap,
|
|
ConfigVars: configVars,
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type compileResult struct {
|
|
C compiler.Compiler
|
|
Pkg *symbols.Package
|
|
Heap *heapstate.Heap
|
|
ConfigVars map[tokens.Token]*rt.Object
|
|
}
|