Files
airshipctl/pkg/bootstrap/isogen/command.go
Kostiantyn Kalynovskyi ca0ecbd3ab Change document labeling
Now document labeling would allow to have same document to be deployed
to different clusters, ephemeral or target at the same type.

Change-Id: Ia1bb618c322c19c4db3c47b3d19c630b61125f5c
2020-02-19 20:51:21 +00:00

154 lines
4.1 KiB
Go

package isogen
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"opendev.org/airship/airshipctl/pkg/bootstrap/cloudinit"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/container"
"opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/log"
"opendev.org/airship/airshipctl/pkg/util"
"sigs.k8s.io/kustomize/v3/pkg/fs"
)
const (
builderConfigFileName = "builder-conf.yaml"
)
// GenerateBootstrapIso will generate data for cloud init and start ISO builder container
func GenerateBootstrapIso(settings *environment.AirshipCTLSettings, args []string) error {
ctx := context.Background()
globalConf := settings.Config()
if err := globalConf.EnsureComplete(); err != nil {
return err
}
cfg, err := globalConf.CurrentContextBootstrapInfo()
if err != nil {
return err
}
var manifest *config.Manifest
manifest, err = globalConf.CurrentContextManifest()
if err != nil {
return err
}
if err = verifyInputs(cfg); err != nil {
return err
}
// TODO (dukov) replace with the appropriate function once it's available
// in document module
docBundle, err := document.NewBundle(fs.MakeRealFS(), manifest.TargetPath, "")
if err != nil {
return err
}
log.Print("Creating ISO builder container")
builder, err := container.NewContainer(
&ctx, cfg.Container.ContainerRuntime,
cfg.Container.Image)
if err != nil {
return err
}
err = generateBootstrapIso(docBundle, builder, cfg, settings.Debug)
if err != nil {
return err
}
log.Print("Checking artifacts")
return verifyArtifacts(cfg)
}
func verifyInputs(cfg *config.Bootstrap) error {
if cfg.Container.Volume == "" {
log.Print("Specify volume bind for ISO builder container")
return config.ErrWrongConfig{}
}
if (cfg.Builder.UserDataFileName == "") || (cfg.Builder.NetworkConfigFileName == "") {
log.Print("UserDataFileName or NetworkConfigFileName are not specified in ISO builder config")
return config.ErrWrongConfig{}
}
vols := strings.Split(cfg.Container.Volume, ":")
switch {
case len(vols) == 1:
cfg.Container.Volume = fmt.Sprintf("%s:%s", vols[0], vols[0])
case len(vols) > 2:
log.Print("Bad container volume format. Use hostPath:contPath")
return config.ErrWrongConfig{}
}
return nil
}
func getContainerCfg(cfg *config.Bootstrap, userData []byte, netConf []byte) map[string][]byte {
hostVol := strings.Split(cfg.Container.Volume, ":")[0]
fls := make(map[string][]byte)
fls[filepath.Join(hostVol, cfg.Builder.UserDataFileName)] = userData
fls[filepath.Join(hostVol, cfg.Builder.NetworkConfigFileName)] = netConf
// TODO (dukov) Get rid of this ugly conversion byte -> string -> byte
builderData := []byte(cfg.String())
fls[filepath.Join(hostVol, builderConfigFileName)] = builderData
return fls
}
func verifyArtifacts(cfg *config.Bootstrap) error {
hostVol := strings.Split(cfg.Container.Volume, ":")[0]
metadataPath := filepath.Join(hostVol, cfg.Builder.OutputMetadataFileName)
_, err := os.Stat(metadataPath)
return err
}
func generateBootstrapIso(
docBundle document.Bundle,
builder container.Container,
cfg *config.Bootstrap,
debug bool,
) error {
cntVol := strings.Split(cfg.Container.Volume, ":")[1]
log.Print("Creating cloud-init for ephemeral K8s")
label := document.EphemeralClusterSelector
userData, netConf, err := cloudinit.GetCloudData(docBundle, label)
if err != nil {
return err
}
fls := getContainerCfg(cfg, userData, netConf)
if err = util.WriteFiles(fls, 0600); err != nil {
return err
}
vols := []string{cfg.Container.Volume}
builderCfgLocation := filepath.Join(cntVol, builderConfigFileName)
log.Printf("Running default container command. Mounted dir: %s", vols)
if err := builder.RunCommand(
[]string{},
nil,
vols,
[]string{fmt.Sprintf("BUILDER_CONFIG=%s", builderCfgLocation)},
debug,
); err != nil {
return err
}
log.Print("ISO successfully built.")
if !debug {
log.Print("Removing container.")
return builder.RmContainer()
}
log.Debugf("Debug flag is set. Container %s stopped but not deleted.", builder.GetId())
return nil
}