github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/k8s-spec-set.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc 5 6 import ( 7 "bytes" 8 9 "github.com/juju/cmd/v3" 10 "github.com/juju/errors" 11 "github.com/juju/gnuflag" 12 13 jujucmd "github.com/juju/juju/cmd" 14 ) 15 16 // K8sSpecSetCommand implements the k8s-spec-set command. 17 type K8sSpecSetCommand struct { 18 cmd.CommandBase 19 name string 20 ctx Context 21 22 specFile cmd.FileVar 23 k8sResources cmd.FileVar 24 } 25 26 // NewK8sSpecSetCommand makes a k8s-spec-set command. 27 func NewK8sSpecSetCommand(ctx Context, name string) (cmd.Command, error) { 28 return &K8sSpecSetCommand{ctx: ctx, name: name}, nil 29 } 30 31 func (c *K8sSpecSetCommand) Info() *cmd.Info { 32 doc := ` 33 Sets configuration data to use for k8s resources. 34 The spec applies to all units for the application. 35 ` 36 purpose := "set k8s spec information" 37 if c.name == "pod-spec-set" { 38 purpose += " (deprecated)" 39 } 40 return jujucmd.Info(&cmd.Info{ 41 Name: c.name, 42 Args: "--file <core spec file> [--k8s-resources <k8s spec file>]", 43 Purpose: purpose, 44 Doc: doc, 45 }) 46 } 47 48 func (c *K8sSpecSetCommand) SetFlags(f *gnuflag.FlagSet) { 49 c.specFile.SetStdin() 50 c.specFile.Path = "-" 51 f.Var(&c.specFile, "file", "file containing pod spec") 52 f.Var(&c.k8sResources, "k8s-resources", "file containing k8s specific resources not yet modelled by Juju") 53 } 54 55 func (c *K8sSpecSetCommand) Init(args []string) error { 56 return cmd.CheckEmpty(args) 57 } 58 59 func (c *K8sSpecSetCommand) Run(ctx *cmd.Context) error { 60 specData, err := c.mergePodSpec(ctx) 61 if err != nil { 62 return errors.Trace(err) 63 } 64 return c.ctx.SetPodSpec(specData) 65 } 66 67 func (c *K8sSpecSetCommand) mergePodSpec(ctx *cmd.Context) (string, error) { 68 caasSpecData, err := c.handleSpecFile(ctx) 69 if err != nil { 70 return "", errors.Trace(err) 71 } 72 k8sSpecData, err := c.handleK8sResources(ctx) 73 if err != nil { 74 return "", errors.Trace(err) 75 } 76 return mergeFileContent(caasSpecData, k8sSpecData), nil 77 } 78 79 func mergeFileContent(contents ...string) string { 80 var buffer bytes.Buffer 81 for _, v := range contents { 82 if v == "" { 83 continue 84 } 85 buffer.WriteString(v) 86 } 87 return buffer.String() 88 } 89 90 func (c *K8sSpecSetCommand) handleSpecFile(ctx *cmd.Context) (string, error) { 91 specData, err := c.specFile.Read(ctx) 92 if err != nil { 93 return "", errors.Trace(err) 94 } 95 if len(specData) == 0 { 96 return "", errors.New("no k8s spec specified: pipe k8s spec to command, or specify a file with --file") 97 } 98 return string(specData), nil 99 } 100 101 func (c *K8sSpecSetCommand) handleK8sResources(ctx *cmd.Context) (string, error) { 102 if c.k8sResources.Path == "" { 103 return "", nil 104 } 105 k8sResourcesData, err := c.k8sResources.Read(ctx) 106 if err != nil { 107 return "", errors.Trace(err) 108 } 109 return string(k8sResourcesData), nil 110 }