Working through node and group configuration via CLI

This commit is contained in:
Gregory Kurtzer
2020-11-21 21:51:14 -08:00
parent 8453aecc9d
commit 5181940952
16 changed files with 279 additions and 22 deletions

1
go.mod
View File

@@ -5,6 +5,7 @@ go 1.15
require (
github.com/containers/image/v5 v5.7.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/manifoldco/promptui v0.8.0
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
github.com/opencontainers/umoci v0.4.6
github.com/spf13/cobra v1.1.1

13
go.sum
View File

@@ -46,6 +46,10 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/checkpoint-restore/go-criu/v4 v4.0.2/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
@@ -191,6 +195,8 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
@@ -214,13 +220,19 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw=
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/manifoldco/promptui v0.8.0 h1:R95mMF+McvXZQ7j1g8ucVZE1gLP3Sv6j9vlF9kyRqQo=
github.com/manifoldco/promptui v0.8.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
@@ -468,6 +480,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@@ -15,6 +15,8 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
}
nodeDB.AddGroup(args[0])
nodeDB.Persist()
return nil

View File

@@ -1,8 +1,61 @@
package delete
import "github.com/spf13/cobra"
import (
"fmt"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
"os"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
var count int
var numNodes int
nodeDB, err := node.New()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Failed to open node database: %s\n", err)
os.Exit(1)
}
nodes, err := nodeDB. FindAllNodes()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not load all nodes: %s\n", err)
os.Exit(1)
}
for _, g := range args {
err := nodeDB.DelGroup(g)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
} else {
for _, n := range nodes {
if n.GroupName == g {
numNodes ++
}
}
count ++
}
}
if count > 0 {
q := fmt.Sprintf("Are you sure you want to delete %d group(s) (%d nodes)", count, numNodes)
prompt := promptui.Prompt{
Label: q,
IsConfirm: true,
}
result, _ := prompt.Run()
if result == "y" || result == "yes" {
nodeDB.Persist()
}
} else {
wwlog.Printf(wwlog.INFO, "No groups found\n")
}
return nil
}

View File

@@ -4,7 +4,7 @@ import "github.com/spf13/cobra"
var (
baseCmd = &cobra.Command{
Use: "del",
Use: "delete",
Short: "Add a new node group",
Long: "Add a new node group ",
RunE: CobraRunE,

View File

@@ -1,8 +1,44 @@
package list
import "github.com/spf13/cobra"
import (
"fmt"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"os"
"reflect"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
nodeDB, err := node.New()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
os.Exit(1)
}
groups, err := nodeDB.FindAllGroups()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not find all nodes: %s\n", err)
os.Exit(1)
}
if ShowAll == true {
for _, group := range groups {
v := reflect.ValueOf(group)
typeOfS := v.Type()
fmt.Printf("################################################################################\n")
for i := 0; i< v.NumField(); i++ {
fmt.Printf("%-25s %s = %v\n", group.Id, typeOfS.Field(i).Name, v.Field(i).Interface())
}
}
} else {
fmt.Printf("%-22s %-20s %-30s %-30s %-16s\n", "GROUP NAME", "DOMAINNAME", "KERNEL VERSION", "VNFS IMAGE", "RUNTIME OVERLAY")
for _, g := range groups {
fmt.Printf("%-22s %-20s %-30s %-30s %-16s\n", g.GroupName, g.DomainName, g.KernelVersion, g.Vnfs, g.RuntimeOverlay)
}
}
return nil
}

View File

@@ -9,9 +9,12 @@ var (
Long: "List group configurations ",
RunE: CobraRunE,
}
ShowAll bool
)
func init() {
baseCmd.PersistentFlags().BoolVarP(&ShowAll, "all", "a", false, "Show all node configurations")
}
// GetRootCommand returns the root cobra.Command for the application.

View File

@@ -9,9 +9,11 @@ var (
Long: "Add new node ",
RunE: CobraRunE,
}
SetGroup string
)
func init() {
baseCmd.PersistentFlags().StringVarP(&SetGroup, "group", "g", "default", "Set group to add nodes to")
}
// GetRootCommand returns the root cobra.Command for the application.

View File

@@ -1,8 +1,55 @@
package delete
import "github.com/spf13/cobra"
import (
"fmt"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
"os"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
var count int
nodeDB, err := node.New()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Failed to open node database: %s\n", err)
os.Exit(1)
}
nodeList, err := nodeDB.SearchByNameList(args)
for _, n := range nodeList {
if SetGroup != "" && SetGroup != n.GroupName {
wwlog.Printf(wwlog.DEBUG, "skipping node of different group: %s/%s\n", n.GroupName, n.Id)
continue
}
err := nodeDB.DelNode(n.GroupName, n.Id)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
} else {
count++
}
}
if count > 0 {
q := fmt.Sprintf("Are you sure you want to delete %d nodes(s)", count)
prompt := promptui.Prompt{
Label: q,
IsConfirm: true,
}
result, _ := prompt.Run()
if result == "y" || result == "yes" {
nodeDB.Persist()
}
} else {
wwlog.Printf(wwlog.INFO, "No nodes found\n")
}
return nil
}

View File

@@ -4,19 +4,19 @@ import "github.com/spf13/cobra"
var (
baseCmd = &cobra.Command{
Use: "del",
Use: "delete",
Short: "Set node configurations",
Long: "Set node configurations ",
RunE: CobraRunE,
}
SetVnfs string
SetKernel string
// SetGroupLevel bool
SetForce string
SetGroup string
)
func init() {
baseCmd.PersistentFlags().StringVarP(&SetVnfs, "vnfs", "V", "", "Set node Virtual Node File System (VNFS)")
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes")
baseCmd.PersistentFlags().StringVarP(&SetForce, "force", "f", "", "Force node delete")
baseCmd.PersistentFlags().StringVarP(&SetGroup, "group", "g", "", "Set group to delete nodes from")
}
// GetRootCommand returns the root cobra.Command for the application.

View File

@@ -6,6 +6,7 @@ import (
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"os"
"reflect"
)
@@ -30,7 +31,18 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
os.Exit(1)
}
if ShowNet == true {
if ShowAll == true {
for _, node := range nodes {
v := reflect.ValueOf(node)
typeOfS := v.Type()
fmt.Printf("################################################################################\n")
for i := 0; i< v.NumField(); i++ {
fmt.Printf("%-25s %s = %v\n", node.Fqdn, typeOfS.Field(i).Name, v.Field(i).Interface())
}
}
} else if ShowNet == true {
fmt.Printf("%-22s %-10s %-20s %-16s %-16s %-16s %s\n", "NODE NAME", "DEVICE", "HWADDR", "IPADDR", "NETMASK", "GATEWAY", "TYPE")
for _, node := range nodes {
@@ -47,7 +59,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
}
} else {
fmt.Printf("%-22s %-30s %-30s %-16s %-16s\n", "NODE NAME", "KERNEL NAME", "VNFS IMAGE", "SYSTEM OVERLAY", "RUNTIME OVERLAY")
fmt.Printf("%-22s %-30s %-30s %-16s %-16s\n", "NODE NAME", "KERNEL VERSION", "VNFS IMAGE", "SYSTEM OVERLAY", "RUNTIME OVERLAY")
for _, node := range nodes {
fmt.Printf("%-22s %-30s %-30s %-16s %-16s\n", node.Fqdn, node.KernelVersion, node.Vnfs, node.SystemOverlay, node.RuntimeOverlay)

View File

@@ -11,12 +11,14 @@ var (
}
ShowNet bool
ShowIpmi bool
ShowAll bool
)
func init() {
baseCmd.PersistentFlags().BoolVarP(&ShowNet, "net", "n", false, "Show node network configurations")
baseCmd.PersistentFlags().BoolVarP(&ShowIpmi, "ipmi", "i", false, "Show node IPMI configurations")
baseCmd.PersistentFlags().BoolVarP(&ShowAll, "all", "a", false, "Show all node configurations")
}
// GetRootCommand returns the root cobra.Command for the application.

View File

@@ -25,12 +25,14 @@ type nodeYaml struct {
type nodeGroup struct {
Comment string
Vnfs string `yaml:"vnfs"`
Ipxe string `yaml:"ipxe template"`
SystemOverlay string `yaml:"system overlay""`
Ipxe string `yaml:"ipxe template,omitempty"`
SystemOverlay string `yaml:"system overlay,omitempty""`
RuntimeOverlay string `yaml:"runtime overlay""`
DomainSuffix string `yaml:"domain suffix"`
KernelVersion string `yaml:"kernel version"`
KernelArgs string `yaml:"kernel args"`
IpmiUserName string `yaml:"ipmi username,omitempty"`
IpmiPassword string `yaml:"ipmi password,omitempty"`
Nodes map[string]*nodeEntry
}
@@ -59,12 +61,12 @@ type netDevs struct {
type NodeInfo struct {
Id string
Uid string
GroupName string
HostName string
DomainName string
Fqdn string
Vnfs string
VnfsDir string
Ipxe string
SystemOverlay string
RuntimeOverlay string
@@ -76,6 +78,20 @@ type NodeInfo struct {
NetDevs map[string]netDevs
}
type GroupInfo struct {
Id string
GroupName string
DomainName string
Vnfs string
Ipxe string
SystemOverlay string
RuntimeOverlay string
KernelVersion string
KernelArgs string
IpmiUserName string
IpmiPassword string
}
func New() (nodeYaml, error) {
var ret nodeYaml
@@ -111,6 +127,33 @@ func (self *nodeYaml) AddNode(groupname string, nodename string) error {
return nil
}
func (self *nodeYaml) DelNode(groupname string, nodename string) error {
if _, ok := self.NodeGroups[groupname]; ok {
if _, ok := self.NodeGroups[groupname].Nodes[nodename]; ok {
delete(self.NodeGroups[groupname].Nodes, nodename)
wwlog.Printf(wwlog.VERBOSE, "Deleting node: %s/%s\n", groupname, nodename)
} else {
return errors.New("Node '"+nodename+"' was not found in group '"+groupname+"'")
}
} else {
return errors.New("Group '"+groupname+"' was not found")
}
return nil
}
func (self *nodeYaml) DelGroup(groupname string) error {
if _, ok := self.NodeGroups[groupname]; ok {
delete(self.NodeGroups, groupname)
} else {
return errors.New("Node group undefined: " + groupname)
}
return nil
}
func (self *nodeYaml) SetGroupVal(groupID string, entry string, value string) (int, error) {
var count int
@@ -199,6 +242,33 @@ func (self *nodeYaml) Persist() error {
return nil
}
func (self *nodeYaml) FindAllGroups() ([]GroupInfo, error) {
var ret []GroupInfo
for groupname, group := range self.NodeGroups {
var g GroupInfo
g.Id = groupname
g.GroupName = groupname
g.RuntimeOverlay = group.RuntimeOverlay
g.SystemOverlay = group.SystemOverlay
g.Ipxe = group.Ipxe
g.KernelVersion = group.KernelVersion
g.KernelArgs = group.KernelArgs
g.Vnfs = group.Vnfs
g.IpmiUserName = group.IpmiUserName
g.IpmiPassword = group.IpmiPassword
g.DomainName = group.DomainSuffix
// TODO: Validate or die on all inputs
ret = append(ret, g)
}
return ret, nil
}
func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
var ret []NodeInfo
@@ -206,12 +276,11 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
for nodename, node := range group.Nodes {
var n NodeInfo
n.Id = groupname + ":" + nodename
n.Id = nodename
n.Uid = groupname + ":" + nodename
n.GroupName = groupname
n.HostName = node.Hostname
n.IpmiIpaddr = node.IpmiIpaddr
n.IpmiUserName = node.IpmiUserName
n.IpmiPassword = node.IpmiPassword
n.Vnfs = group.Vnfs
n.SystemOverlay = group.SystemOverlay
@@ -220,8 +289,17 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.KernelArgs = group.KernelArgs
n.DomainName = group.DomainSuffix
n.Ipxe = group.Ipxe
n.IpmiUserName = group.IpmiUserName
n.IpmiPassword = group.IpmiPassword
n.NetDevs = node.NetDevs
if node.IpmiUserName != "" {
n.IpmiUserName = node.IpmiUserName
}
if node.IpmiPassword != "" {
n.IpmiPassword = node.IpmiPassword
}
if node.KernelVersion != "" {
n.KernelVersion = node.KernelVersion
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/hpcng/warewulf/internal/pkg/errors"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/vnfs"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"io/ioutil"
"os"
@@ -62,6 +63,9 @@ func RuntimeBuild(nodeList []node.NodeInfo, force bool) error {
if node.RuntimeOverlay != "" {
OverlayDir := config.RuntimeOverlaySource(node.RuntimeOverlay)
OverlayFile := config.RuntimeOverlayImage(node.Fqdn)
vnfs := vnfs.New(node.Vnfs)
vnfsDir := config.VnfsChroot(vnfs.NameClean())
wwlog.Printf(wwlog.VERBOSE, "Building Runtime Overlay for: %s\n", node.Fqdn)
@@ -75,7 +79,7 @@ func RuntimeBuild(nodeList []node.NodeInfo, force bool) error {
continue
}
if util.IsDir(node.VnfsDir) == false {
if util.IsDir(vnfsDir) == false {
wwlog.Printf(wwlog.WARN, "%-35s: Skipped (VNFS not imported)\n", node.Fqdn)
continue
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/hpcng/warewulf/internal/pkg/errors"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/vnfs"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"io/ioutil"
"os"
@@ -62,6 +63,9 @@ func SystemBuild(nodeList []node.NodeInfo, force bool) error {
if node.SystemOverlay != "" {
OverlayDir := config.SystemOverlaySource(node.SystemOverlay)
OverlayFile := config.SystemOverlayImage(node.Fqdn)
vnfs := vnfs.New(node.Vnfs)
vnfsDir := config.VnfsChroot(vnfs.NameClean())
wwlog.Printf(wwlog.VERBOSE, "Building System Overlay for: %s\n", node.Fqdn)
@@ -75,7 +79,7 @@ func SystemBuild(nodeList []node.NodeInfo, force bool) error {
continue
}
if util.IsDir(node.VnfsDir) == false {
if util.IsDir(vnfsDir) == false {
wwlog.Printf(wwlog.WARN, "%-35s: Skipped (VNFS not imported)\n", node.Fqdn)
continue
}

View File

@@ -181,4 +181,4 @@ func ShaSumFile(file string) (string, error) {
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}
}