cmd/hub/lifecycle/invoke.go (99 lines of code) (raw):

// Copyright (c) 2022 EPAM Systems, Inc. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. package lifecycle import ( "fmt" "log" "github.com/epam/hubctl/cmd/hub/config" "github.com/epam/hubctl/cmd/hub/manifest" "github.com/epam/hubctl/cmd/hub/parameters" "github.com/epam/hubctl/cmd/hub/state" "github.com/epam/hubctl/cmd/hub/storage" "github.com/epam/hubctl/cmd/hub/util" ) func Invoke(request *Request) { stackManifest, componentsManifests, _, err := manifest.ParseManifest(request.ManifestFilenames) if err != nil { log.Fatalf("Unable to parse: %v", err) } additionalEnvironment, err := util.ParseKvList(request.EnvironmentOverrides) if err != nil { log.Fatalf("Unable to parse additional environment variables `%s`: %v", request.EnvironmentOverrides, err) } osEnv, err := initOsEnv(request.OsEnvironmentMode) if err != nil { log.Fatalf("Unable to parse OS environment setup: %v", err) } stateFiles, errs := storage.Check(request.StateFilenames, "state") if len(errs) > 0 { util.MaybeFatalf("Unable to check state file: %v", util.Errors2(errs...)) } order, err := manifest.GenerateLifecycleOrder(stackManifest) if err != nil { log.Fatal(err) } stackManifest.Lifecycle.Order = order stackBaseDir := util.Basedir(request.ManifestFilenames) componentsBaseDir := request.ComponentsBaseDir if componentsBaseDir == "" { componentsBaseDir = stackBaseDir } manifest.CheckComponentsExist(stackManifest.Components, request.Component) component := manifest.ComponentRefByName(stackManifest.Components, request.Component) componentName := manifest.ComponentQualifiedNameFromRef(component) componentManifest := manifest.ComponentManifestByRef(componentsManifests, component) checkVerbs(request.Component, componentManifest.Lifecycle.Verbs, request.Verb) stackParameters := make(parameters.LockedParameters) outputs := make(parameters.CapturedOutputs) _, err = state.MergeState(stateFiles, request.Component, component.Depends, stackManifest.Lifecycle.Order, false, stackParameters, outputs, nil) if err != nil { util.MaybeFatalf("Unable to load component `%s` state: %v", request.Component, err) } if config.Verbose { log.Printf("Invoke `%s` on `%s` with %v manifest and %v state", request.Verb, request.Component, request.ManifestFilenames, request.StateFilenames) } // should we ask mergeState() to load true component parameters // from state instead of re-evaluating them here? expandedComponentParameters, errs := parameters.ExpandParameters(componentName, componentManifest.Meta.Kind, component.Depends, stackParameters, outputs, manifest.FlattenParameters(componentManifest.Parameters, componentManifest.Meta.Name)) if len(errs) > 0 { util.MaybeFatalf("Component `%s` parameters expansion failed:\n\t%s", componentName, util.Errors("\n\t", errs...)) } componentParameters := parameters.MergeParameters(make(parameters.LockedParameters), expandedComponentParameters) if config.Debug { log.Print("Component parameters:") parameters.PrintLockedParameters(componentParameters) } dir := manifest.ComponentSourceDirFromRef(component, stackBaseDir, componentsBaseDir) if config.Debug { log.Printf("Component `%s` directory: %s", request.Component, dir) } impl, err := findImplementation(dir, request.Verb, componentManifest) if err != nil { log.Fatalf("Failed to %s %s: %v", request.Verb, request.Component, err) } processEnv := mergeOsEnviron( parametersInEnv(component, componentParameters, stackBaseDir), additionalEnvironmentToList(additionalEnvironment)) impl.Env = mergeOsEnviron(osEnv, processEnv) if config.Debug && len(processEnv) > 0 { log.Print("Component environment:") printEnvironment(processEnv) if config.Trace { log.Print("Full process environment:") printEnvironment(impl.Env) } } _, _, err = execImplementation(impl, true, false) if err != nil { util.MaybeFatalf("Failed to %s %s: %v", request.Verb, request.Component, err) } } func additionalEnvironmentToList(env map[string]string) []string { list := make([]string, 0, len(env)) for k, v := range env { list = append(list, fmt.Sprintf("%s=%s", k, v)) } return list }