Merge branch 'main' of github.com:ctrl-cmd/warewulf into main
This commit is contained in:
@@ -1,34 +1,15 @@
|
||||
nodegroups:
|
||||
group_1:
|
||||
comment: This is the group 1
|
||||
vnfs: /var/chroots/centos-7
|
||||
system overlay: default
|
||||
default:
|
||||
comment: This is the default group
|
||||
vnfs: docker://warewulf/centos-8
|
||||
runtime overlay: default
|
||||
domain suffix: group1
|
||||
nodes:
|
||||
n0000:
|
||||
hostname: localtest
|
||||
kernel version: 3.10.0-1127.el7.x86_64
|
||||
kernel args: crashkernel=no quiet
|
||||
system overlay: test
|
||||
netdevs:
|
||||
eth0:
|
||||
hwaddr: xx:xx:xx:xx:aa
|
||||
ipaddr: 192.168.1.1
|
||||
netmask: 255.255.255.0
|
||||
gateway: 192.168.1.1
|
||||
group_2:
|
||||
comment: This is the group 2
|
||||
vnfs: docker://warewulf/centos-7
|
||||
system overlay: default
|
||||
runtime overlay: default
|
||||
domain suffix: group2
|
||||
kernel version: 3.10.0-1127.el7.x86_64
|
||||
domain suffix: default
|
||||
kernel version: ""
|
||||
kernel args: crashkernel=no quiet
|
||||
nodes:
|
||||
n0000:
|
||||
hostname: n0000
|
||||
ipmi ipaddr: x.x.x.x
|
||||
kernel args: crashkernel=no
|
||||
netdevs:
|
||||
eth0:
|
||||
hwaddr: 00:0c:29:23:8b:48
|
||||
@@ -37,21 +18,36 @@ nodegroups:
|
||||
gateway: 192.168.1.1
|
||||
type: ethernet
|
||||
ib0:
|
||||
hwaddr: xx:xx:xx:xx:xx
|
||||
ipaddr: x.x.x.x
|
||||
netmask: x.x.x.x
|
||||
gateway: x.x.x.x
|
||||
hwaddr: aa:bb:cc:dd:ee:a0
|
||||
ipaddr: 192.168.10.100
|
||||
netmask: 255.255.255.0
|
||||
type: infiniband
|
||||
n0001:
|
||||
hostname: n0001
|
||||
ipmi ipaddr: x.x.x.x
|
||||
netdevs:
|
||||
eth0:
|
||||
hwaddr: xx:xx:xx:xx:xx
|
||||
hwaddr: aa:bb:cc:dd:ee:b0
|
||||
ipaddr: 192.168.1.101
|
||||
netmask: 255.255.255.0
|
||||
gateway: 192.168.1.1
|
||||
ib0:
|
||||
hwaddr: xx:xx:xx:xx:xx
|
||||
ipaddr: x.x.x.x
|
||||
netmask: x.x.x.x
|
||||
hwaddr: aa:bb:cc:dd:ee:b1
|
||||
ipaddr: 192.168.10.100
|
||||
netmask: 255.255.255.0
|
||||
group_1:
|
||||
comment: This is the group 1
|
||||
vnfs: /var/chroots/centos-7
|
||||
runtime overlay: default
|
||||
domain suffix: group1
|
||||
nodes:
|
||||
n0000:
|
||||
hostname: localtest
|
||||
kernel version: 3.10.0-1127.el7.x86_64
|
||||
system overlay: test
|
||||
netdevs:
|
||||
eth0:
|
||||
hwaddr: aa:bb:cc:dd:ee:c0
|
||||
ipaddr: 192.168.2.100
|
||||
netmask: 255.255.255.0
|
||||
gateway: 192.168.2.1
|
||||
|
||||
1
go.mod
1
go.mod
@@ -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
13
go.sum
@@ -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=
|
||||
|
||||
@@ -2,8 +2,8 @@ package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -26,13 +26,20 @@ type iPxeTemplate struct {
|
||||
func IpxeSend(w http.ResponseWriter, req *http.Request) {
|
||||
url := strings.Split(req.URL.Path, "/")
|
||||
|
||||
nodes, err := node.New()
|
||||
if err != nil {
|
||||
log.Printf("Could not read node configuration file: %s\n", err)
|
||||
w.WriteHeader(503)
|
||||
return
|
||||
}
|
||||
|
||||
if url[2] == "" {
|
||||
log.Printf("ERROR: Bad iPXE request from %s\n", req.RemoteAddr)
|
||||
return
|
||||
}
|
||||
|
||||
hwaddr := strings.ReplaceAll(url[2], "-", ":")
|
||||
node, err := assets.FindByHwaddr(hwaddr)
|
||||
node, err := nodes.FindByHwaddr(hwaddr)
|
||||
if err != nil {
|
||||
log.Printf("Could not find HW Addr: %s: %s\n", hwaddr, err)
|
||||
w.WriteHeader(404)
|
||||
|
||||
@@ -2,8 +2,8 @@ package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -12,6 +12,12 @@ import (
|
||||
|
||||
func RuntimeOverlaySend(w http.ResponseWriter, req *http.Request) {
|
||||
config := config.New()
|
||||
nodes, err := node.New()
|
||||
if err != nil {
|
||||
log.Printf("Could not read node configuration file: %s\n", err)
|
||||
w.WriteHeader(503)
|
||||
return
|
||||
}
|
||||
|
||||
remote := strings.Split(req.RemoteAddr, ":")
|
||||
port, err := strconv.Atoi(remote[1])
|
||||
@@ -34,7 +40,7 @@ func RuntimeOverlaySend(w http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
node, err := assets.FindByIpaddr(remote[0])
|
||||
node, err := nodes.FindByIpaddr(remote[0])
|
||||
if err != nil {
|
||||
fmt.Printf("Could not find node by IP address: %s\n", remote[0])
|
||||
w.WriteHeader(404)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
"io"
|
||||
"log"
|
||||
@@ -11,23 +12,29 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getSanity(req *http.Request) (assets.NodeInfo, error) {
|
||||
func getSanity(req *http.Request) (node.NodeInfo, error) {
|
||||
url := strings.Split(req.URL.Path, "/")
|
||||
var ret node.NodeInfo
|
||||
|
||||
nodes, err := node.New()
|
||||
if err != nil {
|
||||
return ret, errors.New(fmt.Sprintf("%s", err))
|
||||
}
|
||||
|
||||
hwaddr := strings.ReplaceAll(url[2], "-", ":")
|
||||
node, err := assets.FindByHwaddr(hwaddr)
|
||||
ret, err = nodes.FindByHwaddr(hwaddr)
|
||||
if err != nil {
|
||||
return node, errors.New("Could not find node by HW address")
|
||||
return ret, errors.New("Could not find node by HW address")
|
||||
}
|
||||
|
||||
if node.Fqdn == "" {
|
||||
if ret.Fqdn == "" {
|
||||
log.Printf("UNKNOWN: %15s: %s\n", hwaddr, req.URL.Path)
|
||||
return node, errors.New("Unknown node HW address: " + hwaddr)
|
||||
return ret, errors.New("Unknown node HW address: " + hwaddr)
|
||||
} else {
|
||||
log.Printf("REQ: %15s: %s\n", node.Fqdn, req.URL.Path)
|
||||
log.Printf("REQ: %15s: %s\n", ret.Fqdn, req.URL.Path)
|
||||
}
|
||||
|
||||
return node, nil
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func sendFile(w http.ResponseWriter, filename string, sendto string) error {
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/build/kernel"
|
||||
runtime_overlay "github.com/hpcng/warewulf/internal/app/wwctl/build/runtime-overlay"
|
||||
system_overlay "github.com/hpcng/warewulf/internal/app/wwctl/build/system-overlay"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/build/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
var nodeList []assets.NodeInfo
|
||||
|
||||
if buildAll == true {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Building all components\n")
|
||||
buildVnfs = true
|
||||
buildKernel = true
|
||||
buildSystemOverlay = true;
|
||||
buildRuntimeOverlay = true;
|
||||
}
|
||||
|
||||
if len(args) >= 1 {
|
||||
nodeList, _ = assets.SearchByName(args[0])
|
||||
} else {
|
||||
nodeList, _ = assets.FindAllNodes()
|
||||
}
|
||||
|
||||
if len(nodeList) == 0 {
|
||||
wwlog.Printf(wwlog.ERROR, "No nodes found matching: '%s'\n", args[0])
|
||||
os.Exit(255)
|
||||
} else {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Found matching nodes for build: %d\n", len(nodeList))
|
||||
}
|
||||
|
||||
if buildVnfs == true {
|
||||
// wwlog.Printf(wwlog.INFO, "===============================================================================\n")
|
||||
|
||||
err := vnfs.Build(nodeList, buildForce)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(255)
|
||||
}
|
||||
}
|
||||
|
||||
if buildKernel == true {
|
||||
// wwlog.Printf(wwlog.INFO, "===============================================================================\n")
|
||||
|
||||
err := kernel.Build(nodeList, buildForce)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(255)
|
||||
}
|
||||
}
|
||||
|
||||
if buildSystemOverlay == true {
|
||||
// wwlog.Printf(wwlog.INFO, "===============================================================================\n")
|
||||
err := system_overlay.Build(nodeList, buildForce)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(255)
|
||||
}
|
||||
}
|
||||
|
||||
if buildRuntimeOverlay == true {
|
||||
// wwlog.Printf(wwlog.INFO, "===============================================================================\n")
|
||||
err := runtime_overlay.Build(nodeList, buildForce)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(255)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
)
|
||||
|
||||
func Build(nodeList []assets.NodeInfo, force bool) error {
|
||||
config := config.New()
|
||||
set := make(map[string]int)
|
||||
|
||||
wwlog.Printf(wwlog.INFO, "Importing Kernels:\n")
|
||||
wwlog.SetIndent(4)
|
||||
|
||||
for _, node := range nodeList {
|
||||
if node.KernelVersion != "" {
|
||||
set[node.KernelVersion] ++
|
||||
wwlog.Printf(wwlog.DEBUG, "Node '%s' has KernelVersion '%s'\n", node.Fqdn, node.KernelVersion)
|
||||
}
|
||||
}
|
||||
|
||||
for kernelVersion := range set {
|
||||
kernelImage := "/boot/vmlinuz-"+kernelVersion
|
||||
kernelDrivers := "/lib/modules/"+kernelVersion
|
||||
kernelDestination := config.KernelImage(kernelVersion)
|
||||
driversDestination := config.KmodsImage(kernelVersion)
|
||||
|
||||
// Create the destination paths just in case it doesn't exist
|
||||
os.MkdirAll(path.Dir(kernelDestination), 0755)
|
||||
os.MkdirAll(path.Dir(driversDestination), 0755)
|
||||
|
||||
|
||||
if _, err := os.Stat(kernelImage); err == nil {
|
||||
if util.PathIsNewer(kernelImage, kernelDestination) && force == false {
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Skipping, kernel is current\n", "vmlinuz-"+kernelVersion)
|
||||
|
||||
} else {
|
||||
err := util.CopyFile(kernelImage, kernelDestination)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Failed copying kernel image: %s\n", err)
|
||||
continue
|
||||
}
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Done\n", "vmlinuz-"+kernelVersion)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(kernelDrivers); err == nil {
|
||||
if util.PathIsNewer(kernelDrivers, driversDestination) && force == false {
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Skipping, drivers are current\n", "kmods-"+kernelVersion+".img")
|
||||
|
||||
} else {
|
||||
cmd := fmt.Sprintf("cd /; find .%s | cpio --quiet -o -H newc -F \"%s\"", kernelDrivers, driversDestination)
|
||||
err := exec.Command("/bin/sh", "-c", cmd).Run()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not generate kernel driver overlay: %s\n", err)
|
||||
continue
|
||||
}
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Done\n", "kmods-"+kernelVersion+".img")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wwlog.SetIndent(0)
|
||||
|
||||
return nil
|
||||
}
|
||||
90
internal/app/wwctl/build/main.go
Normal file
90
internal/app/wwctl/build/main.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
var nodes []node.NodeInfo
|
||||
showHelp := true
|
||||
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
var err error
|
||||
nodes, err = n.SearchByName(args[0])
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not find nodes for search term: %s\n", args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
} else {
|
||||
var err error
|
||||
nodes, err = n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not get list of nodes: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if buildVnfs == true || buildAll == true {
|
||||
set := make(map[string]int)
|
||||
showHelp = false
|
||||
|
||||
wwlog.Printf(wwlog.INFO, "Building VNFS images...\n")
|
||||
|
||||
for _, node := range nodes {
|
||||
set[node.Vnfs] ++
|
||||
}
|
||||
for e := range set {
|
||||
vnfs.Build(e, buildForce)
|
||||
}
|
||||
}
|
||||
|
||||
if buildKernel == true || buildAll == true {
|
||||
set := make(map[string]int)
|
||||
showHelp = false
|
||||
|
||||
wwlog.Printf(wwlog.INFO, "Building Kernel images...\n")
|
||||
|
||||
for _, node := range nodes {
|
||||
set[node.KernelVersion] ++
|
||||
}
|
||||
for e := range set {
|
||||
kernel.Build(e)
|
||||
}
|
||||
}
|
||||
|
||||
if buildSystemOverlay == true || buildAll == true {
|
||||
wwlog.Printf(wwlog.INFO, "Building System Overlays...\n")
|
||||
showHelp = false
|
||||
|
||||
overlay.SystemBuild(nodes, buildForce)
|
||||
}
|
||||
|
||||
if buildRuntimeOverlay == true || buildAll == true {
|
||||
wwlog.Printf(wwlog.INFO, "Building Runtime Overlays...n")
|
||||
showHelp = false
|
||||
|
||||
overlay.RuntimeBuild(nodes, buildForce)
|
||||
}
|
||||
|
||||
if showHelp == true {
|
||||
cmd.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -13,6 +13,7 @@ var (
|
||||
"that seems to be needed.",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
|
||||
buildVnfs bool
|
||||
buildKernel bool
|
||||
buildRuntimeOverlay bool
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
package runtime_overlay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func fileInclude(path string) string {
|
||||
wwlog.Printf(wwlog.DEBUG, "Including file into template: %s\n", path)
|
||||
content, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Template include: %s\n", err)
|
||||
}
|
||||
return strings.TrimSuffix(string(content), "\n")
|
||||
}
|
||||
|
||||
func Build(nodeList []assets.NodeInfo, force bool) error {
|
||||
wwlog.Printf(wwlog.INFO, "Building Runtime Overlays:\n")
|
||||
config := config.New()
|
||||
|
||||
wwlog.SetIndent(4)
|
||||
|
||||
for _, node := range nodeList {
|
||||
if node.RuntimeOverlay != "" {
|
||||
OverlayDir := config.RuntimeOverlaySource(node.RuntimeOverlay)
|
||||
OverlayFile := config.RuntimeOverlayImage(node.Fqdn)
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Building Runtime Overlay for: %s\n", node.Fqdn)
|
||||
|
||||
tmpDir, err := ioutil.TempDir(os.TempDir(), ".wwctl-runtime-overlay-")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(OverlayDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.MkdirAll(path.Dir(OverlayFile), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if force == false {
|
||||
wwlog.Printf(wwlog.DEBUG, "Checking if overlay is required\n")
|
||||
}
|
||||
if util.PathIsNewer(OverlayDir, OverlayFile) {
|
||||
if force == false {
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Skipping, overlay is current\n", node.Fqdn)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Changing directory to OverlayDir: %s\n", OverlayDir)
|
||||
err = os.Chdir(OverlayDir)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not chdir() to OverlayDir: %s\n", OverlayDir)
|
||||
continue
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Walking the file system: %s\n", OverlayDir)
|
||||
err = filepath.Walk(".", func(location string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
wwlog.Printf(wwlog.DEBUG, "Found directory: %s\n", location)
|
||||
|
||||
err := os.MkdirAll(path.Join(tmpDir, location), info.Mode())
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
} else if filepath.Ext(location) == ".ww" {
|
||||
wwlog.Printf(wwlog.DEBUG, "Found template file: %s\n", location)
|
||||
|
||||
destFile := strings.TrimSuffix(location, ".ww")
|
||||
|
||||
tmpl, err := template.New(path.Base(location)).Funcs(template.FuncMap{"Include": fileInclude}).ParseGlob(path.Join(OverlayDir, destFile + ".ww*"))
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
w, err := os.OpenFile(path.Join(tmpDir, destFile), os.O_RDWR|os.O_CREATE, info.Mode())
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
err = tmpl.Execute(w, node)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
} else if b, _ := regexp.MatchString(`\.ww[a-zA-Z0-9\-\._]*$`, location); b == true {
|
||||
wwlog.Printf(wwlog.DEBUG, "Ignoring WW template file: %s\n", location)
|
||||
} else {
|
||||
wwlog.Printf(wwlog.DEBUG, "Found file: %s\n", location)
|
||||
|
||||
err := util.CopyFile(path.Join(OverlayDir, location), path.Join(tmpDir, location))
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
wwlog.Printf(wwlog.VERBOSE, "Finished generating overlay directory for: %s\n", node.Fqdn)
|
||||
|
||||
cmd := fmt.Sprintf("cd \"%s\"; find . | cpio --quiet -o -H newc -F \"%s\"", tmpDir, OverlayFile)
|
||||
wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd)
|
||||
err = exec.Command("/bin/sh", "-c", cmd).Run()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not generate runtime image overlay: %s\n", err)
|
||||
continue
|
||||
}
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Done\n", node.Fqdn)
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Removing temporary directory: %s\n", tmpDir)
|
||||
os.RemoveAll(tmpDir)
|
||||
}
|
||||
}
|
||||
|
||||
wwlog.SetIndent(0)
|
||||
return nil
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
package system_overlay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func fileInclude(path string) string {
|
||||
wwlog.Printf(wwlog.DEBUG, "Including file into template: %s\n", path)
|
||||
content, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Template include: %s\n", err)
|
||||
}
|
||||
return strings.TrimSuffix(string(content), "\n")
|
||||
}
|
||||
|
||||
func Build(nodeList []assets.NodeInfo, force bool) error {
|
||||
wwlog.Printf(wwlog.INFO, "Building System Overlays:\n")
|
||||
config := config.New()
|
||||
|
||||
wwlog.SetIndent(4)
|
||||
|
||||
for _, node := range nodeList {
|
||||
if node.SystemOverlay != "" {
|
||||
OverlayDir := config.SystemOverlaySource(node.SystemOverlay)
|
||||
OverlayFile := config.SystemOverlayImage(node.Fqdn)
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Building System Overlay for: %s\n", node.Fqdn)
|
||||
|
||||
tmpDir, err := ioutil.TempDir(os.TempDir(), ".wwctl-system-overlay-")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(OverlayDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.MkdirAll(path.Dir(OverlayFile), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if force == false {
|
||||
wwlog.Printf(wwlog.DEBUG, "Checking if overlay is required\n")
|
||||
}
|
||||
if util.PathIsNewer(OverlayDir, OverlayFile) {
|
||||
if force == false {
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Skipping, overlay is current\n", node.Fqdn)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Changing directory to OverlayDir: %s\n", OverlayDir)
|
||||
err = os.Chdir(OverlayDir)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not chdir() to OverlayDir: %s\n", OverlayDir)
|
||||
continue
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Walking the file system: %s\n", OverlayDir)
|
||||
err = filepath.Walk(".", func(location string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
wwlog.Printf(wwlog.DEBUG, "Found directory: %s\n", location)
|
||||
|
||||
err := os.MkdirAll(path.Join(tmpDir, location), info.Mode())
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
} else if filepath.Ext(location) == ".ww" {
|
||||
wwlog.Printf(wwlog.DEBUG, "Found template file: %s\n", location)
|
||||
|
||||
destFile := strings.TrimSuffix(location, ".ww")
|
||||
|
||||
tmpl, err := template.New(path.Base(location)).Funcs(template.FuncMap{"Include": fileInclude}).ParseGlob(path.Join(OverlayDir, destFile + ".ww*"))
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
w, err := os.OpenFile(path.Join(tmpDir, destFile), os.O_RDWR|os.O_CREATE, info.Mode())
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
err = tmpl.Execute(w, node)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
} else if b, _ := regexp.MatchString(`\.ww[a-zA-Z0-9\-\._]*$`, location); b == true {
|
||||
wwlog.Printf(wwlog.DEBUG, "Ignoring WW template file: %s\n", location)
|
||||
} else {
|
||||
wwlog.Printf(wwlog.DEBUG, "Found file: %s\n", location)
|
||||
|
||||
err := util.CopyFile(path.Join(OverlayDir, location), path.Join(tmpDir, location))
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
wwlog.Printf(wwlog.VERBOSE, "Finished generating overlay directory for: %s\n", node.Fqdn)
|
||||
|
||||
cmd := fmt.Sprintf("cd \"%s\"; find . | cpio --quiet -o -H newc -F \"%s\"", tmpDir, OverlayFile)
|
||||
wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd)
|
||||
err = exec.Command("/bin/sh", "-c", cmd).Run()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not generate system image overlay: %s\n", err)
|
||||
continue
|
||||
}
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Done\n", node.Fqdn)
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Removing temporary directory: %s\n", tmpDir)
|
||||
os.RemoveAll(tmpDir)
|
||||
}
|
||||
}
|
||||
|
||||
wwlog.SetIndent(0)
|
||||
return nil
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package vnfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
func BuildContainerdir(v vnfs.VnfsObject) {
|
||||
config := config.New()
|
||||
|
||||
if _, err := os.Stat(v.Source()); err != nil {
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Skipping (bad path)\n", v.Name())
|
||||
return
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Checking if there have been any updates to the VNFS directory\n")
|
||||
if util.PathIsNewer(v.Source(), config.VnfsImage(v.NameClean())) {
|
||||
if buildForce == false {
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Skipping, VNFS is current\n", v.Name())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Making the directory: %s\n", path.Dir(config.VnfsImage(v.NameClean())))
|
||||
err := os.MkdirAll(path.Dir(config.VnfsImage(v.NameClean())), 0755)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Making the directory: %s\n", path.Dir(config.VnfsChroot(v.NameClean())))
|
||||
err = os.MkdirAll(path.Dir(config.VnfsChroot(v.NameClean())), 0755)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Building VNFS image: '%s' -> '%s'\n", v.Source(), config.VnfsImage(v.NameClean()))
|
||||
err = buildVnfs(v.Source(), config.VnfsImage(v.NameClean()))
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Setup links from OCI rootfs to chroot path
|
||||
_ = os.Remove(config.VnfsChroot(v.NameClean()) + "-link")
|
||||
err = os.Symlink(v.Source(), config.VnfsChroot(v.NameClean())+"-link")
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not create symlink for Chroot: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
err = os.Rename(config.VnfsChroot(v.NameClean())+"-link", config.VnfsChroot(v.NameClean()))
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not rename link: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Done\n", v.Name())
|
||||
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package vnfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/oci"
|
||||
"github.com/hpcng/warewulf/internal/pkg/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
|
||||
func BuildDocker(v vnfs.VnfsObject) {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Building OCI Container: %s\n", v.Source())
|
||||
config := config.New()
|
||||
|
||||
OciCacheDir := config.LocalStateDir + "/oci"
|
||||
VnfsHashDir := config.LocalStateDir + "/oci/vnfs"
|
||||
|
||||
c, err := oci.NewCache(oci.OptSetCachePath(OciCacheDir))
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Downloading OCI container layers\n")
|
||||
sourcePath, err := c.Pull(context.Background(), v.Source(), nil)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
hashDestination := VnfsHashDir + path.Base(sourcePath)
|
||||
|
||||
name, err := os.Readlink(config.VnfsImage(v.NameClean()))
|
||||
if err == nil {
|
||||
if name == hashDestination {
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Skipping, VNFS is current\n", v.Name())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = os.MkdirAll(VnfsHashDir, 0755)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
return
|
||||
}
|
||||
err = os.MkdirAll(path.Dir(config.VnfsImage(v.NameClean())), 0755)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
return
|
||||
}
|
||||
err = os.MkdirAll(path.Dir(config.VnfsChroot(v.NameClean())), 0755)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Building bootable VNFS image\n")
|
||||
|
||||
err = buildVnfs(sourcePath, hashDestination)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Finalizing Build\n")
|
||||
|
||||
// Setup links from OCI image to provision path
|
||||
_ = os.Remove(config.VnfsImage(v.NameClean()) + "-link")
|
||||
err = os.Symlink(hashDestination, config.VnfsImage(v.NameClean())+"-link")
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not create symlink for Image: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
err = os.Rename(config.VnfsImage(v.NameClean())+"-link", config.VnfsImage(v.NameClean()))
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not rename link: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Setup links from OCI rootfs to chroot path
|
||||
_ = os.Remove(config.VnfsChroot(v.NameClean()) + "-link")
|
||||
err = os.Symlink(sourcePath, config.VnfsChroot(v.NameClean())+"-link")
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not create symlink for Chroot: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
err = os.Rename(config.VnfsChroot(v.NameClean())+"-link", config.VnfsChroot(v.NameClean()))
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not rename link: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
wwlog.Printf(wwlog.INFO, "%-35s: Done\n", v.Name())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package vnfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func buildVnfs(source string, dest string) error {
|
||||
cmd := fmt.Sprintf("cd %s; find . | cpio --quiet -o -H newc | gzip -c > \"%s\"", source, dest)
|
||||
|
||||
err := exec.Command("/bin/sh", "-c", cmd).Run()
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package vnfs
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
var buildForce bool
|
||||
|
||||
func Build(nodeList []assets.NodeInfo, force bool) error {
|
||||
set := make(map[string]int)
|
||||
|
||||
wwlog.Printf(wwlog.INFO, "Building and Importing VNFS Images:\n")
|
||||
wwlog.SetIndent(4)
|
||||
|
||||
buildForce = force
|
||||
|
||||
for _, node := range nodeList {
|
||||
if node.Vnfs != "" {
|
||||
set[node.Vnfs]++
|
||||
wwlog.Printf(wwlog.DEBUG, "Node '%s' has VNFS '%s'\n", node.Fqdn, node.Vnfs)
|
||||
}
|
||||
}
|
||||
|
||||
for uri := range set {
|
||||
v := vnfs.New(uri)
|
||||
wwlog.Printf(wwlog.VERBOSE, "VNFS found: %s (nodes: %d)\n", uri, set[uri])
|
||||
if strings.HasPrefix(uri, "/") {
|
||||
if strings.HasSuffix(uri, "tar.gz") {
|
||||
//wwlog.Printf(wwlog.WARN, "Building VNFS from local tarball: %s\n", uri)
|
||||
wwlog.Printf(wwlog.WARN, "Building VNFS from local tarball is not supported yet: %s\n", uri)
|
||||
|
||||
} else {
|
||||
BuildContainerdir(v)
|
||||
}
|
||||
} else {
|
||||
BuildDocker(v)
|
||||
}
|
||||
}
|
||||
|
||||
wwlog.SetIndent(0)
|
||||
|
||||
return nil
|
||||
}
|
||||
29
internal/app/wwctl/group/add/main.go
Normal file
29
internal/app/wwctl/group/add/main.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package add
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
nodeDB, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Failed opening node database: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for _, g := range args {
|
||||
err = nodeDB.AddGroup(g)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
nodeDB.Persist()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
25
internal/app/wwctl/group/add/root.go
Normal file
25
internal/app/wwctl/group/add/root.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package add
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add a new node group",
|
||||
Long: "Add a new node group ",
|
||||
RunE: CobraRunE,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
}
|
||||
SetVnfs string
|
||||
SetKernel 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")
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
61
internal/app/wwctl/group/delete/main.go
Normal file
61
internal/app/wwctl/group/delete/main.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package delete
|
||||
|
||||
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
|
||||
}
|
||||
25
internal/app/wwctl/group/delete/root.go
Normal file
25
internal/app/wwctl/group/delete/root.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package delete
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Add a new node group",
|
||||
Long: "Add a new node group ",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
SetVnfs string
|
||||
SetKernel string
|
||||
// SetGroupLevel bool
|
||||
)
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
44
internal/app/wwctl/group/list/main.go
Normal file
44
internal/app/wwctl/group/list/main.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package list
|
||||
|
||||
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 %-16s %-30s %-30s %-16s\n", "GROUP NAME", "DOMAINNAME", "KERNEL VERSION", "VNFS IMAGE", "RUNTIME OVERLAY")
|
||||
for _, g := range groups {
|
||||
fmt.Printf("%-22s %-16s %-30s %-30s %-16s\n", g.GroupName, g.DomainName, g.KernelVersion, g.Vnfs, g.RuntimeOverlay)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
23
internal/app/wwctl/group/list/root.go
Normal file
23
internal/app/wwctl/group/list/root.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package list
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List group configurations",
|
||||
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.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
29
internal/app/wwctl/group/root.go
Normal file
29
internal/app/wwctl/group/root.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/group/add"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/group/delete"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/group/list"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/group/set"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "group",
|
||||
Short: "Group management",
|
||||
Long: "Management of group settings and power management",
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
baseCmd.AddCommand(list.GetCommand())
|
||||
baseCmd.AddCommand(set.GetCommand())
|
||||
baseCmd.AddCommand(add.GetCommand())
|
||||
baseCmd.AddCommand(delete.GetCommand())
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
247
internal/app/wwctl/group/set/main.go
Normal file
247
internal/app/wwctl/group/set/main.go
Normal file
@@ -0,0 +1,247 @@
|
||||
package set
|
||||
|
||||
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 err error
|
||||
var groups []node.GroupInfo
|
||||
|
||||
nodeDB, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
var tmp []node.GroupInfo
|
||||
tmp, err = nodeDB.FindAllGroups()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for _, a := range args {
|
||||
for _, g := range tmp {
|
||||
if g.Id == a {
|
||||
groups = append(groups, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
cmd.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for _, g := range groups {
|
||||
if SetVnfs != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting vnfs to: %s\n", g.Id, SetVnfs)
|
||||
err := nodeDB.SetGroupVal(g.Id, "vnfs", SetVnfs)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "vnfs", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if SetKernel != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting kernel to: %s\n", g.Id, SetVnfs)
|
||||
err := nodeDB.SetGroupVal(g.Id, "kernel", SetKernel)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "kernel", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if SetDomainName != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting domain name to: %s\n", g.Id, SetDomainName)
|
||||
err := nodeDB.SetGroupVal(g.Id, "domain", SetDomainName)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "domain", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if SetIpxe != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting iPXE template to: %s\n", g.Id, SetIpxe)
|
||||
err := nodeDB.SetGroupVal(g.Id, "ipxe", SetIpxe)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "ipxe", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if SetRuntimeOverlay != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting runtime overlay to: %s\n", g.Id, SetRuntimeOverlay)
|
||||
err := nodeDB.SetGroupVal(g.Id, "runtimeoverlay", SetRuntimeOverlay)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "runtimeoverlay", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if SetSystemOverlay != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting system overlay to: %s\n", g.Id, SetSystemOverlay)
|
||||
err := nodeDB.SetGroupVal(g.Id, "systemoverlay", SetSystemOverlay)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "systemoverlay", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
if SetIpmiIpaddr != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting IPMI IP address to: %s\n", g.Id, SetIpmiIpaddr)
|
||||
err := nodeDB.SetGroupVal(g.Id, "ipmiipaddr", SetIpmiIpaddr)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "ipmiipaddr", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
if SetIpmiUsername != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting IPMI IP username to: %s\n", g.Id, SetIpmiUsername)
|
||||
err := nodeDB.SetGroupVal(g.Id, "ipmiusername", SetIpmiUsername)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "ipmiusername", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
if SetIpmiPassword != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting IPMI IP password to: %s\n", g.Id, SetIpmiPassword)
|
||||
err := nodeDB.SetGroupVal(g.Id, "ipmipassword", SetIpmiPassword)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if SetClearNodes == true {
|
||||
nodes, err := nodeDB.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, n := range nodes {
|
||||
_ = nodeDB.SetNodeVal(g.Id, n.Id, "ipmipassword", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if len(groups) > 0 {
|
||||
q := fmt.Sprintf("Are you sure you want to modify %d group(s)", len(groups))
|
||||
|
||||
prompt := promptui.Prompt{
|
||||
Label: q,
|
||||
IsConfirm: true,
|
||||
}
|
||||
|
||||
result, _ := prompt.Run()
|
||||
|
||||
if result == "y" || result == "yes" {
|
||||
nodeDB.Persist()
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Printf("No groups found\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
43
internal/app/wwctl/group/set/root.go
Normal file
43
internal/app/wwctl/group/set/root.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package set
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "Set group configurations",
|
||||
Long: "Set group configurations ",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
SetVnfs string
|
||||
SetKernel string
|
||||
SetDomainName string
|
||||
SetIpxe string
|
||||
SetRuntimeOverlay string
|
||||
SetSystemOverlay string
|
||||
SetHostname string
|
||||
SetClearNodes bool
|
||||
SetIpmiIpaddr string
|
||||
SetIpmiUsername string
|
||||
SetIpmiPassword 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(&SetDomainName, "domain", "D", "", "Set the node's domain name")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay")
|
||||
baseCmd.PersistentFlags().StringVar(&SetIpmiIpaddr, "ipmi", "", "Set the node's IPMI address")
|
||||
baseCmd.PersistentFlags().StringVar(&SetIpmiUsername, "ipmiuser", "", "Set the node's IPMI username")
|
||||
baseCmd.PersistentFlags().StringVar(&SetIpmiPassword, "ipmipass", "", "Set the node's IPMI password")
|
||||
|
||||
baseCmd.PersistentFlags().BoolVarP(&SetClearNodes, "clear", "c", false, "Clear node configurations when setting parent group")
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -1,20 +1,26 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
var nodes []assets.NodeInfo
|
||||
var nodes []node.NodeInfo
|
||||
set := make(map[string]int)
|
||||
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) == 1 && ByNode == true {
|
||||
var err error
|
||||
nodes, err = assets.SearchByName(args[0])
|
||||
nodes, err = n.SearchByName(args[0])
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not find nodes for search term: %s\n", args[0])
|
||||
os.Exit(1)
|
||||
@@ -26,7 +32,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
|
||||
} else if BuildAll == true {
|
||||
var err error
|
||||
nodes, err = assets.FindAllNodes()
|
||||
nodes, err = n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not get list of nodes: %s\n", err)
|
||||
os.Exit(1)
|
||||
|
||||
28
internal/app/wwctl/node/add/main.go
Normal file
28
internal/app/wwctl/node/add/main.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package add
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
nodeDB, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Failed to open node database: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for _, a := range args {
|
||||
err = nodeDB.AddNode(SetGroup, a)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
nodeDB.Persist()
|
||||
|
||||
return nil
|
||||
}
|
||||
23
internal/app/wwctl/node/add/root.go
Normal file
23
internal/app/wwctl/node/add/root.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package add
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add new node",
|
||||
Long: "Add new node ",
|
||||
RunE: CobraRunE,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
}
|
||||
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.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
55
internal/app/wwctl/node/delete/main.go
Normal file
55
internal/app/wwctl/node/delete/main.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package delete
|
||||
|
||||
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 {
|
||||
fmt.Printf("No nodes found\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
25
internal/app/wwctl/node/delete/root.go
Normal file
25
internal/app/wwctl/node/delete/root.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package delete
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Set node configurations",
|
||||
Long: "Set node configurations ",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
SetForce string
|
||||
SetGroup string
|
||||
)
|
||||
|
||||
func init() {
|
||||
baseCmd.PersistentFlags().StringVarP(&SetForce, "force", "f", "", "Force node delete")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetGroup, "group", "g", "default", "Set group to delete nodes from")
|
||||
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
71
internal/app/wwctl/node/list/main.go
Normal file
71
internal/app/wwctl/node/list/main.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package list
|
||||
|
||||
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 {
|
||||
var err error
|
||||
var nodes []node.NodeInfo
|
||||
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
nodes, err = n.SearchByNameList(args)
|
||||
} else {
|
||||
nodes, err = n.FindAllNodes()
|
||||
}
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
for name, dev := range node.NetDevs {
|
||||
fmt.Printf("%-22s %-10s %-20s %-16s %-16s %-16s %s\n", node.Fqdn, name, dev.Hwaddr, dev.Ipaddr, dev.Netmask, dev.Gateway, dev.Type)
|
||||
}
|
||||
}
|
||||
|
||||
} else if ShowIpmi == true {
|
||||
fmt.Printf("%-22s %-16s %-20s %-20s\n", "NODE NAME", "IPMI IPADDR", "IPMI USERNAME", "IPMI PASSWORD")
|
||||
|
||||
for _, node := range nodes {
|
||||
fmt.Printf("%-22s %-16s %-20s %-20s\n", node.Fqdn, node.IpmiIpaddr, node.IpmiUserName, node.IpmiPassword)
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Printf("%-22s %-16s %-30s %-30s %-16s\n", "NODE NAME", "GROUP NAME", "KERNEL VERSION", "VNFS IMAGE", "RUNTIME OVERLAY")
|
||||
|
||||
for _, node := range nodes {
|
||||
fmt.Printf("%-22s %-16s %-30s %-30s %-16s\n", node.Fqdn, node.GroupName, node.KernelVersion, node.Vnfs, node.RuntimeOverlay)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
26
internal/app/wwctl/node/list/root.go
Normal file
26
internal/app/wwctl/node/list/root.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package list
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List all nodes",
|
||||
Long: "List all nodes",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
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.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package poweroff
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/power"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -9,14 +9,17 @@ import (
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
|
||||
var returnErr error = nil
|
||||
var nodeList []node.NodeInfo
|
||||
|
||||
var nodeList []assets.NodeInfo
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) >= 1 {
|
||||
//nodeList, _ = assets.SearchByName(args[0])
|
||||
nodeList, _ = assets.SearchByNameList(args)
|
||||
nodeList, _ = n.SearchByNameList(args)
|
||||
} else {
|
||||
wwlog.Printf(wwlog.ERROR, "No requested nodes\n")
|
||||
os.Exit(255)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package poweron
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/power"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -9,14 +9,17 @@ import (
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
|
||||
var returnErr error = nil
|
||||
var nodeList []node.NodeInfo
|
||||
|
||||
var nodeList []assets.NodeInfo
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) >= 1 {
|
||||
//nodeList, _ = assets.SearchByName(args[0])
|
||||
nodeList, _ = assets.SearchByNameList(args)
|
||||
nodeList, _ = n.SearchByNameList(args)
|
||||
} else {
|
||||
wwlog.Printf(wwlog.ERROR, "No requested nodes\n")
|
||||
os.Exit(255)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package powerstatus
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/power"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -9,14 +9,17 @@ import (
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
|
||||
var returnErr error = nil
|
||||
var nodeList []node.NodeInfo
|
||||
|
||||
var nodeList []assets.NodeInfo
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) >= 1 {
|
||||
//nodeList, _ = assets.SearchByName(args[0])
|
||||
nodeList, _ = assets.SearchByNameList(args)
|
||||
nodeList, _ = n.SearchByNameList(args)
|
||||
} else {
|
||||
wwlog.Printf(wwlog.ERROR, "No requested nodes\n")
|
||||
os.Exit(255)
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/node/add"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/node/delete"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/node/list"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/node/poweron"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/node/poweroff"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/node/powerstatus"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/node/set"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -19,6 +23,10 @@ func init() {
|
||||
baseCmd.AddCommand(poweron.GetCommand())
|
||||
baseCmd.AddCommand(poweroff.GetCommand())
|
||||
baseCmd.AddCommand(powerstatus.GetCommand())
|
||||
baseCmd.AddCommand(list.GetCommand())
|
||||
baseCmd.AddCommand(set.GetCommand())
|
||||
baseCmd.AddCommand(add.GetCommand())
|
||||
baseCmd.AddCommand(delete.GetCommand())
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
|
||||
206
internal/app/wwctl/node/set/main.go
Normal file
206
internal/app/wwctl/node/set/main.go
Normal file
@@ -0,0 +1,206 @@
|
||||
package set
|
||||
|
||||
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 err error
|
||||
var nodes []node.NodeInfo
|
||||
|
||||
nodeDB, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
nodes, err = nodeDB.SearchByNameList(args)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
} else {
|
||||
cmd.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for _, n := range nodes {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Evaluating node: %s\n", n.Fqdn)
|
||||
if SetVnfs != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting vnfs to: %s\n", n.Fqdn, SetVnfs)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "vnfs", SetVnfs)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetKernel != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel to: %s\n", n.Fqdn, SetVnfs)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "kernel", SetKernel)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetDomainName != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting domain name to: %s\n", n.Fqdn, SetDomainName)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "domain", SetDomainName)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetIpxe != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting iPXE template to: %s\n", n.Fqdn, SetIpxe)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "ipxe", SetIpxe)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetRuntimeOverlay != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting runtime overlay to: %s\n", n.Fqdn, SetRuntimeOverlay)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "runtimeoverlay", SetRuntimeOverlay)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetSystemOverlay != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting system overlay to: %s\n", n.Fqdn, SetSystemOverlay)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "systemoverlay", SetSystemOverlay)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetHostname != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting hostname to: %s\n", n.Fqdn, SetHostname)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "hostname", SetHostname)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetIpmiIpaddr != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP address to: %s\n", n.Fqdn, SetIpmiIpaddr)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "ipmiipaddr", SetIpmiIpaddr)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetIpmiUsername != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP username to: %s\n", n.Fqdn, SetIpmiUsername)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "ipmiusername", SetIpmiUsername)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetIpmiPassword != "" {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP password to: %s\n", n.Fqdn, SetIpmiPassword)
|
||||
err := nodeDB.SetNodeVal(n.Gid, n.Id, "ipmipassword", SetIpmiPassword)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if SetNetDevDel == true {
|
||||
if SetNetDev == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Deleting network device: %s\n", n.Fqdn, SetNetDev)
|
||||
err := nodeDB.DelNodeNet(n.Gid, n.Id, SetNetDev)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
if SetIpaddr != "" {
|
||||
if SetNetDev == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Ipaddr to: %s\n", n.Fqdn, SetNetDev, SetIpaddr)
|
||||
err := nodeDB.SetNodeNet(n.Gid, n.Id, SetNetDev, "ipaddr", SetIpaddr)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetNetmask != "" {
|
||||
if SetNetDev == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting netmask to: %s\n", n.Fqdn, SetNetDev, SetNetmask)
|
||||
err := nodeDB.SetNodeNet(n.Gid, n.Id, SetNetDev, "netmask", SetNetmask)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetGateway != "" {
|
||||
if SetNetDev == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting gateway to: %s\n", n.Fqdn, SetNetDev, SetGateway)
|
||||
err := nodeDB.SetNodeNet(n.Gid, n.Id, SetNetDev, "gateway", SetGateway)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if SetHwaddr != "" {
|
||||
if SetNetDev == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting HW address to: %s\n", n.Fqdn, SetNetDev, SetHwaddr)
|
||||
err := nodeDB.SetNodeNet(n.Gid, n.Id, SetNetDev, "hwaddr", SetHwaddr)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(nodes) > 0 {
|
||||
q := fmt.Sprintf("Are you sure you want to modify %d nodes(s)", len(nodes))
|
||||
|
||||
prompt := promptui.Prompt{
|
||||
Label: q,
|
||||
IsConfirm: true,
|
||||
}
|
||||
|
||||
result, _ := prompt.Run()
|
||||
|
||||
if result == "y" || result == "yes" {
|
||||
nodeDB.Persist()
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Printf("No nodes found\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
55
internal/app/wwctl/node/set/root.go
Normal file
55
internal/app/wwctl/node/set/root.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package set
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "Set node configurations",
|
||||
Long: "Set node configurations ",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
SetVnfs string
|
||||
SetKernel string
|
||||
SetNetDev string
|
||||
SetIpaddr string
|
||||
SetNetmask string
|
||||
SetGateway string
|
||||
SetHwaddr string
|
||||
SetNetDevDel bool
|
||||
SetDomainName string
|
||||
SetIpxe string
|
||||
SetRuntimeOverlay string
|
||||
SetSystemOverlay string
|
||||
SetHostname string
|
||||
SetIpmiIpaddr string
|
||||
SetIpmiUsername string
|
||||
SetIpmiPassword 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(&SetDomainName, "domain", "D", "", "Set the node's domain name")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetHostname, "hostname", "H", "", "Set the node's hostname")
|
||||
baseCmd.PersistentFlags().StringVar(&SetIpmiIpaddr, "ipmi", "", "Set the node's IPMI address")
|
||||
baseCmd.PersistentFlags().StringVar(&SetIpmiUsername, "ipmiuser", "", "Set the node's IPMI username")
|
||||
baseCmd.PersistentFlags().StringVar(&SetIpmiPassword, "ipmipass", "", "Set the node's IPMI password")
|
||||
|
||||
baseCmd.PersistentFlags().StringVarP(&SetNetDev, "netdev", "n", "", "Define the network device to configure")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetIpaddr, "ipaddr", "I", "", "Set the node's network device IP address")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetNetmask, "netmask", "M", "", "Set the node's network device netmask")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetGateway, "gateway", "G", "", "Set the node's network device gateway")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetHwaddr, "hwaddr", "N", "", "Set the node's network device HW address")
|
||||
baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "delete", false, "Delete the node's network device")
|
||||
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -9,10 +9,16 @@ import (
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
var updateNodes []assets.NodeInfo
|
||||
var updateNodes []node.NodeInfo
|
||||
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) > 0 && BuildAll == false {
|
||||
nodes, err := assets.FindAllNodes()
|
||||
nodes, err := n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
@@ -27,7 +33,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
updateNodes, err = assets.FindAllNodes()
|
||||
updateNodes, err = n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package chmod
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
@@ -49,13 +49,19 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if NoOverlayUpdate == false {
|
||||
nodes, err := assets.FindAllNodes()
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
nodes, err := n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var updateNodes []assets.NodeInfo
|
||||
var updateNodes []node.NodeInfo
|
||||
|
||||
for _, node := range nodes {
|
||||
if SystemOverlay == true && node.SystemOverlay == overlayName {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package create
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if len(args) < 1 {
|
||||
cmd.Help()
|
||||
os.Exit(1)
|
||||
@@ -34,13 +33,19 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if NoOverlayUpdate == false {
|
||||
nodes, err := assets.FindAllNodes()
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
nodes, err := n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var updateNodes []assets.NodeInfo
|
||||
var updateNodes []node.NodeInfo
|
||||
|
||||
for _, node := range nodes {
|
||||
if SystemOverlay == true && node.SystemOverlay == args[0] {
|
||||
|
||||
@@ -2,8 +2,8 @@ package delete
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
@@ -95,13 +95,19 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if NoOverlayUpdate == false {
|
||||
nodes, err := assets.FindAllNodes()
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
nodes, err := n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var updateNodes []assets.NodeInfo
|
||||
var updateNodes []node.NodeInfo
|
||||
|
||||
for _, node := range nodes {
|
||||
if SystemOverlay == true && node.SystemOverlay == args[0] {
|
||||
|
||||
@@ -2,8 +2,8 @@ package edit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
@@ -93,13 +93,19 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if NoOverlayUpdate == false {
|
||||
nodes, err := assets.FindAllNodes()
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
nodes, err := n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var updateNodes []assets.NodeInfo
|
||||
var updateNodes []node.NodeInfo
|
||||
|
||||
for _, node := range nodes {
|
||||
if SystemOverlay == true && node.SystemOverlay == args[0] {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package imprt
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
@@ -45,13 +45,19 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if NoOverlayUpdate == false {
|
||||
nodes, err := assets.FindAllNodes()
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
nodes, err := n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var updateNodes []assets.NodeInfo
|
||||
var updateNodes []node.NodeInfo
|
||||
|
||||
for _, node := range nodes {
|
||||
if SystemOverlay == true && node.SystemOverlay == overlayName {
|
||||
|
||||
@@ -2,8 +2,8 @@ package list
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
@@ -17,7 +17,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
set := make(map[string]int)
|
||||
var o []string
|
||||
var err error
|
||||
var nodeList []assets.NodeInfo
|
||||
var nodeList []node.NodeInfo
|
||||
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if SystemOverlay == true {
|
||||
if ListLong == false {
|
||||
@@ -39,7 +45,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
nodeList, err = assets.FindAllNodes()
|
||||
nodeList, err = n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not get node configuration: %s\n", err)
|
||||
return err
|
||||
|
||||
@@ -2,8 +2,8 @@ package mkdir
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
@@ -42,13 +42,19 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("Created directory within overlay: %s:%s\n", args[0], args[1])
|
||||
|
||||
if NoOverlayUpdate == false {
|
||||
nodes, err := assets.FindAllNodes()
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
nodes, err := n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var updateNodes []assets.NodeInfo
|
||||
var updateNodes []node.NodeInfo
|
||||
|
||||
for _, node := range nodes {
|
||||
if SystemOverlay == true && node.SystemOverlay == args[0] {
|
||||
|
||||
47
internal/app/wwctl/overlay/show/main.go
Normal file
47
internal/app/wwctl/overlay/show/main.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package show
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
config := config.New()
|
||||
var overlaySourceDir string
|
||||
overlayName := args[0]
|
||||
fileName := args[1]
|
||||
|
||||
if SystemOverlay == true {
|
||||
overlaySourceDir = config.SystemOverlaySource(overlayName)
|
||||
} else {
|
||||
overlaySourceDir = config.RuntimeOverlaySource(overlayName)
|
||||
}
|
||||
|
||||
if util.IsDir(overlaySourceDir) == false {
|
||||
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
overlayFile := path.Join(overlaySourceDir, fileName)
|
||||
|
||||
if util.IsFile(overlayFile) == false {
|
||||
wwlog.Printf(wwlog.ERROR, "File does not exist within overlay: %s:%s\n", overlayName, fileName)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
f, err := ioutil.ReadFile(overlayFile)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not read file: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Print(string(f))
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package show
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -11,21 +10,17 @@ var (
|
||||
Short: "Show Warewulf Overlay objects",
|
||||
Long: "Warewulf show overlay objects",
|
||||
RunE: CobraRunE,
|
||||
Aliases: []string{"cat"},
|
||||
Args: cobra.ExactArgs(2),
|
||||
}
|
||||
|
||||
SystemOverlay bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
baseCmd.PersistentFlags().BoolVarP(&SystemOverlay, "system", "s", false, "Show System Overlays as well")
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("Show: Hello World\n")
|
||||
return nil
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package wwctl
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/build"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/group"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/kernel"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/node"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/overlay"
|
||||
@@ -30,6 +31,8 @@ func init() {
|
||||
rootCmd.AddCommand(vnfs.GetCommand())
|
||||
rootCmd.AddCommand(node.GetCommand())
|
||||
rootCmd.AddCommand(kernel.GetCommand())
|
||||
rootCmd.AddCommand(group.GetCommand())
|
||||
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
|
||||
@@ -2,7 +2,7 @@ package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -10,12 +10,18 @@ import (
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
var nodes []assets.NodeInfo
|
||||
var nodes []node.NodeInfo
|
||||
set := make(map[string]int)
|
||||
|
||||
n, err := node.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(args) == 1 && ByNode == true {
|
||||
var err error
|
||||
nodes, err = assets.SearchByName(args[0])
|
||||
nodes, err = n.SearchByName(args[0])
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not find nodes for search term: %s\n", args[0])
|
||||
os.Exit(1)
|
||||
@@ -27,7 +33,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
|
||||
} else if BuildAll == true {
|
||||
var err error
|
||||
nodes, err = assets.FindAllNodes()
|
||||
nodes, err = n.FindAllNodes()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not get list of nodes: %s\n", err)
|
||||
os.Exit(1)
|
||||
|
||||
27
internal/app/wwctl/vnfs/list/main.go
Normal file
27
internal/app/wwctl/vnfs/list/main.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
config := config.New()
|
||||
|
||||
files, err := ioutil.ReadDir(config.VnfsImageParentDir())
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
fmt.Println(f.Name())
|
||||
}
|
||||
|
||||
fmt.Printf("VNFS LIST: work in progress: %s\n", config.VnfsImageParentDir())
|
||||
return nil
|
||||
}
|
||||
25
internal/app/wwctl/vnfs/list/root.go
Normal file
25
internal/app/wwctl/vnfs/list/root.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package list
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List VNFS images",
|
||||
Long: "List VNFS images ",
|
||||
RunE: CobraRunE,
|
||||
}
|
||||
SystemOverlay bool
|
||||
BuildAll bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
baseCmd.PersistentFlags().BoolVarP(&SystemOverlay, "system", "s", false, "Show System Overlays as well")
|
||||
baseCmd.PersistentFlags().BoolVarP(&BuildAll, "all", "a", false, "Build all overlays (runtime and system)")
|
||||
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
return baseCmd
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package vnfs
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/vnfs/build"
|
||||
"github.com/hpcng/warewulf/internal/app/wwctl/vnfs/list"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -16,7 +17,7 @@ var (
|
||||
|
||||
func init() {
|
||||
baseCmd.AddCommand(build.GetCommand())
|
||||
|
||||
baseCmd.AddCommand(list.GetCommand())
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
|
||||
@@ -1,337 +0,0 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
// "os"
|
||||
|
||||
// "os"
|
||||
"regexp"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
)
|
||||
|
||||
const ConfigFile = "/etc/warewulf/nodes.conf"
|
||||
const LocalStateDir = "/var/warewulf"
|
||||
|
||||
func init() {
|
||||
//TODO: Check to make sure nodes.conf is found
|
||||
|
||||
}
|
||||
|
||||
type nodeYaml struct {
|
||||
NodeGroups map[string]nodeGroup //`yaml:"nodegroups"`
|
||||
}
|
||||
|
||||
type nodeGroup struct {
|
||||
Comment string
|
||||
Vnfs string
|
||||
Ipxe string `yaml:"ipxe template"`
|
||||
SystemOverlay string `yaml:"system overlay""`
|
||||
RuntimeOverlay string `yaml:"runtime overlay""`
|
||||
DomainSuffix string `yaml:"domain suffix"`
|
||||
KernelVersion string `yaml:"kernel version"`
|
||||
KernelArgs string `yaml:"kernel args"`
|
||||
Nodes map[string]nodeEntry
|
||||
}
|
||||
|
||||
type nodeEntry struct {
|
||||
Hostname string
|
||||
Vnfs string
|
||||
Ipxe string `yaml:"ipxe template"`
|
||||
SystemOverlay string `yaml:"system overlay"`
|
||||
RuntimeOverlay string `yaml:"runtime overlay"`
|
||||
DomainSuffix string `yaml:"domain suffix"`
|
||||
KernelVersion string `yaml:"kernel version"`
|
||||
KernelArgs string `yaml:"kernel args"`
|
||||
IpmiIpaddr string `yaml:"ipmi ipaddr"`
|
||||
NetDevs map[string]netDevs
|
||||
}
|
||||
|
||||
type netDevs struct {
|
||||
Type string
|
||||
Hwaddr string
|
||||
Ipaddr string
|
||||
Netmask string
|
||||
Gateway string
|
||||
}
|
||||
|
||||
type NodeInfo struct {
|
||||
GroupName string
|
||||
HostName string
|
||||
DomainName string
|
||||
Fqdn string
|
||||
Vnfs string
|
||||
VnfsDir string
|
||||
Ipxe string
|
||||
SystemOverlay string
|
||||
RuntimeOverlay string
|
||||
KernelVersion string
|
||||
KernelArgs string
|
||||
IpmiIpaddr string
|
||||
NetDevs map[string]netDevs
|
||||
}
|
||||
|
||||
func FindAllNodes() ([]NodeInfo, error) {
|
||||
var c nodeYaml
|
||||
var ret []NodeInfo
|
||||
config := config.New()
|
||||
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Opening configuration file: %s\n", ConfigFile)
|
||||
data, err := ioutil.ReadFile(ConfigFile)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading node configuration file\n")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(data, &c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for groupname, group := range c.NodeGroups {
|
||||
for _, node := range group.Nodes {
|
||||
var n NodeInfo
|
||||
|
||||
n.GroupName = groupname
|
||||
n.HostName = node.Hostname
|
||||
n.IpmiIpaddr = node.IpmiIpaddr
|
||||
|
||||
n.Vnfs = group.Vnfs
|
||||
n.SystemOverlay = group.SystemOverlay
|
||||
n.RuntimeOverlay = group.RuntimeOverlay
|
||||
n.KernelVersion = group.KernelVersion
|
||||
n.KernelArgs = group.KernelArgs
|
||||
n.DomainName = group.DomainSuffix
|
||||
n.Ipxe = group.Ipxe
|
||||
n.NetDevs = node.NetDevs
|
||||
|
||||
if node.KernelVersion != "" {
|
||||
n.KernelVersion = node.KernelVersion
|
||||
}
|
||||
if node.Vnfs != "" {
|
||||
n.Vnfs = node.Vnfs
|
||||
}
|
||||
if node.SystemOverlay != "" {
|
||||
n.SystemOverlay = node.SystemOverlay
|
||||
}
|
||||
if node.RuntimeOverlay != "" {
|
||||
n.RuntimeOverlay = node.RuntimeOverlay
|
||||
}
|
||||
if node.DomainSuffix != "" {
|
||||
n.DomainName = node.DomainSuffix
|
||||
}
|
||||
if node.Ipxe != "" {
|
||||
n.Ipxe = node.Ipxe
|
||||
}
|
||||
if node.KernelArgs != "" {
|
||||
n.KernelArgs = node.KernelArgs
|
||||
}
|
||||
|
||||
if n.RuntimeOverlay == "" {
|
||||
n.RuntimeOverlay = "default"
|
||||
}
|
||||
if n.SystemOverlay == "" {
|
||||
n.SystemOverlay = "default"
|
||||
}
|
||||
if n.Ipxe == "" {
|
||||
n.Ipxe = "default"
|
||||
}
|
||||
|
||||
if n.DomainName != "" {
|
||||
n.Fqdn = node.Hostname + "." + n.DomainName
|
||||
} else {
|
||||
n.Fqdn = node.Hostname
|
||||
}
|
||||
|
||||
util.ValidateOrDie(n.Fqdn, "group name", n.GroupName, "^[a-zA-Z0-9-._]+$")
|
||||
util.ValidateOrDie(n.Fqdn, "vnfs", n.Vnfs, "^[a-zA-Z0-9-._:/]+$")
|
||||
util.ValidateOrDie(n.Fqdn, "system overlay", n.SystemOverlay, "^[a-zA-Z0-9-._]+$")
|
||||
util.ValidateOrDie(n.Fqdn, "runtime overlay", n.RuntimeOverlay, "^[a-zA-Z0-9-._]+$")
|
||||
util.ValidateOrDie(n.Fqdn, "domain suffix", n.DomainName, "^[a-zA-Z0-9-._]+$")
|
||||
util.ValidateOrDie(n.Fqdn, "hostname", n.HostName, "^[a-zA-Z0-9-_]+$")
|
||||
util.ValidateOrDie(n.Fqdn, "kernel version", n.KernelVersion, "^[a-zA-Z0-9-._]+$")
|
||||
|
||||
v := vnfs.New(n.Vnfs)
|
||||
n.VnfsDir = config.VnfsChroot(v.NameClean())
|
||||
|
||||
ret = append(ret, n)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
||||
func FindByHwaddr(hwa string) (NodeInfo, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
nodeList, err := FindAllNodes()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, node := range nodeList {
|
||||
for _, dev := range node.NetDevs {
|
||||
if dev.Hwaddr == hwa {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, errors.New("No nodes found with HW Addr: " + hwa)
|
||||
}
|
||||
|
||||
func FindByIpaddr(ipaddr string) (NodeInfo, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
nodeList, err := FindAllNodes()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, node := range nodeList {
|
||||
for _, dev := range node.NetDevs {
|
||||
if dev.Ipaddr == ipaddr {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, errors.New("No nodes found with IP Addr: " + ipaddr)
|
||||
}
|
||||
|
||||
func SearchByName(search string) ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
nodeList, err := FindAllNodes()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, node := range nodeList {
|
||||
b, _ := regexp.MatchString(search, node.Fqdn)
|
||||
if b == true {
|
||||
ret = append(ret, node)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func SearchByNameList(searchList []string) ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
nodeList, err := FindAllNodes()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, search := range searchList {
|
||||
for _, node := range nodeList {
|
||||
b, _ := regexp.MatchString(search, node.Fqdn)
|
||||
if b == true {
|
||||
ret = append(ret, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
/*
|
||||
func FindAllVnfs() ([]string, error) {
|
||||
var ret []string
|
||||
set := make(map[string]bool)
|
||||
|
||||
nodeList, err := FindAllNodes()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, node := range nodeList {
|
||||
if node.Vnfs != "" {
|
||||
set[node.Vnfs] = true
|
||||
}
|
||||
}
|
||||
|
||||
for entry := range set {
|
||||
ret = append(ret, entry)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func FindAllKernels() ([]string, error) {
|
||||
var ret []string
|
||||
set := make(map[string]bool)
|
||||
|
||||
nodeList, err := FindAllNodes()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, node := range nodeList {
|
||||
if node.KernelVersion != "" {
|
||||
set[node.KernelVersion] = true
|
||||
}
|
||||
}
|
||||
|
||||
for entry := range set {
|
||||
ret = append(ret, entry)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func ListSystemOverlays() ([]string, error) {
|
||||
var ret []string
|
||||
set := make(map[string]bool)
|
||||
|
||||
nodeList, err := FindAllNodes()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, node := range nodeList {
|
||||
if node.SystemOverlay != "" {
|
||||
set[node.SystemOverlay] = true
|
||||
}
|
||||
}
|
||||
|
||||
for entry := range set {
|
||||
ret = append(ret, entry)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func ListRuntimeOverlays() ([]string, error) {
|
||||
var ret []string
|
||||
set := make(map[string]bool)
|
||||
|
||||
nodeList, err := FindAllNodes()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, node := range nodeList {
|
||||
if node.RuntimeOverlay != "" {
|
||||
set[node.RuntimeOverlay] = true
|
||||
}
|
||||
}
|
||||
|
||||
for entry := range set {
|
||||
ret = append(ret, entry)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -57,10 +57,10 @@ func init() {
|
||||
c.Editor = "vi"
|
||||
}
|
||||
|
||||
util.ValidateOrDie("warewulf.conf", "warewulfd ipaddr", c.Ipaddr, "^[0-9]+.[0-9]+.[0-9]+.[0-9]+$")
|
||||
util.ValidateOrDie("warewulf.conf", "system config dir", c.SysConfDir, "^[a-zA-Z0-9-._:/]+$")
|
||||
util.ValidateOrDie("warewulf.conf", "local state dir", c.LocalStateDir, "^[a-zA-Z0-9-._:/]+$")
|
||||
util.ValidateOrDie("warewulf.conf", "default editor", c.LocalStateDir, "^[a-zA-Z0-9-._:/]+$")
|
||||
util.ValidateOrDie("warewulfd ipaddr", c.Ipaddr, "^[0-9]+.[0-9]+.[0-9]+.[0-9]+$")
|
||||
util.ValidateOrDie("system config dir", c.SysConfDir, "^[a-zA-Z0-9-._:/]+$")
|
||||
util.ValidateOrDie("local state dir", c.LocalStateDir, "^[a-zA-Z0-9-._:/]+$")
|
||||
util.ValidateOrDie("default editor", c.LocalStateDir, "^[a-zA-Z0-9-._:/]+$")
|
||||
|
||||
}
|
||||
|
||||
@@ -84,6 +84,14 @@ func (self *Config) RuntimeOverlayDir() string {
|
||||
return path.Join(self.OverlayDir(), "/runtime")
|
||||
}
|
||||
|
||||
func (self *Config) VnfsImageParentDir() string {
|
||||
return fmt.Sprintf("%s/provision/vnfs/", self.LocalStateDir)
|
||||
}
|
||||
|
||||
func (self *Config) VnfsChrootParentDir() string {
|
||||
return fmt.Sprintf("%s/chroot/", self.LocalStateDir)
|
||||
}
|
||||
|
||||
func (self *Config) SystemOverlaySource(overlayName string) string {
|
||||
if overlayName == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "System overlay name is not defined\n")
|
||||
@@ -141,20 +149,6 @@ func (self *Config) KmodsImage(kernelVersion string) string {
|
||||
return fmt.Sprintf("%s/provision/kernel/kmods-%s.img", self.LocalStateDir, kernelVersion)
|
||||
}
|
||||
|
||||
func (self *Config) VnfsImage(vnfsNameClean string) string {
|
||||
if vnfsNameClean == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "VNFS name is not defined\n")
|
||||
return ""
|
||||
}
|
||||
|
||||
if util.TaintCheck(vnfsNameClean, "^[a-zA-Z0-9-._:]+$") == false {
|
||||
wwlog.Printf(wwlog.ERROR, "Runtime overlay name contains illegal characters: %s\n", vnfsNameClean)
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/provision/vnfs/%s.img.gz", self.LocalStateDir, vnfsNameClean)
|
||||
}
|
||||
|
||||
func (self *Config) SystemOverlayImage(nodeName string) string {
|
||||
if nodeName == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "Node name is not defined\n")
|
||||
@@ -183,6 +177,21 @@ func (self *Config) RuntimeOverlayImage(nodeName string) string {
|
||||
return fmt.Sprintf("%s/provision/overlays/runtime/%s.img", self.LocalStateDir, nodeName)
|
||||
}
|
||||
|
||||
|
||||
func (self *Config) VnfsImage(vnfsNameClean string) string {
|
||||
if vnfsNameClean == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "VNFS name is not defined\n")
|
||||
return ""
|
||||
}
|
||||
|
||||
if util.TaintCheck(vnfsNameClean, "^[a-zA-Z0-9-._:]+$") == false {
|
||||
wwlog.Printf(wwlog.ERROR, "Runtime overlay name contains illegal characters: %s\n", vnfsNameClean)
|
||||
return ""
|
||||
}
|
||||
|
||||
return path.Join(self.VnfsImageParentDir(), vnfsNameClean)
|
||||
}
|
||||
|
||||
func (self *Config) VnfsChroot(vnfsNameClean string) string {
|
||||
if vnfsNameClean == "" {
|
||||
wwlog.Printf(wwlog.ERROR, "VNFS name is not defined\n")
|
||||
@@ -194,6 +203,6 @@ func (self *Config) VnfsChroot(vnfsNameClean string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/chroot/%s.img", self.LocalStateDir, vnfsNameClean)
|
||||
return path.Join(self.VnfsChrootParentDir(), vnfsNameClean)
|
||||
}
|
||||
|
||||
|
||||
530
internal/pkg/node/node.go
Normal file
530
internal/pkg/node/node.go
Normal file
@@ -0,0 +1,530 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const ConfigFile = "/etc/warewulf/nodes.conf"
|
||||
const LocalStateDir = "/var/warewulf"
|
||||
|
||||
func init() {
|
||||
//TODO: Check to make sure nodes.conf is found
|
||||
|
||||
}
|
||||
|
||||
type nodeYaml struct {
|
||||
NodeGroups map[string]*nodeGroup //`yaml:"nodegroups"`
|
||||
}
|
||||
|
||||
type nodeGroup struct {
|
||||
Comment string
|
||||
Vnfs string `yaml:"vnfs"`
|
||||
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
|
||||
}
|
||||
|
||||
type nodeEntry struct {
|
||||
Hostname string `yaml:"hostname,omitempty"`
|
||||
Vnfs string `yaml:"vnfs,omitempty"`
|
||||
Ipxe string `yaml:"ipxe template,omitempty"`
|
||||
SystemOverlay string `yaml:"system overlay,omitempty"`
|
||||
RuntimeOverlay string `yaml:"runtime overlay,omitempty"`
|
||||
DomainSuffix string `yaml:"domain suffix,omitempty"`
|
||||
KernelVersion string `yaml:"kernel version,omitempty"`
|
||||
KernelArgs string `yaml:"kernel args,omitempty"`
|
||||
IpmiIpaddr string `yaml:"ipmi ipaddr,omitempty"`
|
||||
IpmiUserName string `yaml:"ipmi username,omitempty"`
|
||||
IpmiPassword string `yaml:"ipmi password,omitempty"`
|
||||
NetDevs map[string]*netDevs
|
||||
}
|
||||
|
||||
type netDevs struct {
|
||||
Type string `yaml:"type,omitempty"`
|
||||
Hwaddr string
|
||||
Ipaddr string
|
||||
Netmask string
|
||||
Gateway string`yaml:"gateway,omitempty"`
|
||||
}
|
||||
|
||||
type NodeInfo struct {
|
||||
Id string
|
||||
Gid string
|
||||
Uid string
|
||||
GroupName string
|
||||
HostName string
|
||||
DomainName string
|
||||
Fqdn string
|
||||
Vnfs string
|
||||
Ipxe string
|
||||
SystemOverlay string
|
||||
RuntimeOverlay string
|
||||
KernelVersion string
|
||||
KernelArgs string
|
||||
IpmiIpaddr string
|
||||
IpmiUserName string
|
||||
IpmiPassword string
|
||||
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
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Opening node configuration file: %s\n", ConfigFile)
|
||||
data, err := ioutil.ReadFile(ConfigFile)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading node configuration file\n")
|
||||
return ret, err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(data, &ret)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) AddGroup(groupID string) error {
|
||||
var group nodeGroup
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
return errors.New("Group name already exists: " + groupID)
|
||||
}
|
||||
|
||||
self.NodeGroups[groupID] = &group
|
||||
self.NodeGroups[groupID].DomainSuffix = groupID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) AddNode(groupID string, nodeID string) error {
|
||||
var node nodeEntry
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Adding new node: %s/%s\n", groupID, nodeID)
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
return errors.New("Nodename already exists in group: " + nodeID)
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group does not exist: "+groupID)
|
||||
}
|
||||
|
||||
self.NodeGroups[groupID].Nodes[nodeID] = &node
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Hostname = nodeID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) DelNode(groupID string, nodeID string) error {
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
delete(self.NodeGroups[groupID].Nodes, nodeID)
|
||||
wwlog.Printf(wwlog.VERBOSE, "Deleting node: %s/%s\n", groupID, nodeID)
|
||||
} else {
|
||||
return errors.New("Node '"+nodeID+"' was not found in group '"+groupID+"'")
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group '"+groupID+"' was not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) DelNodeNet(groupID string, nodeID string, netDev string) error {
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev]; ok {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Deleting node network device: %s/%s:%s\n", groupID, nodeID, netDev)
|
||||
delete(self.NodeGroups[groupID].Nodes[nodeID].NetDevs, netDev)
|
||||
} else {
|
||||
return errors.New("Network device '"+netDev+"' was not found in node '"+groupID+"/"+nodeID+"'")
|
||||
}
|
||||
} else {
|
||||
return errors.New("Node '"+nodeID+"' was not found in group '"+groupID+"'")
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group '"+groupID+"' 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) error {
|
||||
if strings.ToUpper(value) == "UNDEF" || strings.ToUpper(value) == "NIL" || strings.ToUpper(value) == "DEL" {
|
||||
value = ""
|
||||
}
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Setting group %s to: %s = '%s'\n", groupID, entry, value )
|
||||
|
||||
switch strings.ToUpper(entry) {
|
||||
case "VNFS":
|
||||
util.ValidateOrDie("VNFS", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Vnfs = value
|
||||
case "KERNEL":
|
||||
util.ValidateOrDie("Kernel Version", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].KernelVersion = value
|
||||
case "DOMAINSUFFIX":
|
||||
util.ValidateOrDie("Domain", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].DomainSuffix = value
|
||||
case "IPXE":
|
||||
util.ValidateOrDie("iPXE Template", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Ipxe = value
|
||||
case "SYSTEMOVERLAY":
|
||||
util.ValidateOrDie("System Overlay", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].SystemOverlay = value
|
||||
case "RUNTIMEOVERLAY":
|
||||
util.ValidateOrDie("Runtime Overlay", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].RuntimeOverlay = value
|
||||
case "IPMIUSERNAME":
|
||||
util.ValidateOrDie("IPMI Username", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].IpmiUserName = value
|
||||
case "IPMIPASSWORD":
|
||||
util.ValidateOrDie("IPMI Password", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].IpmiPassword = value
|
||||
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group does not exist: " +groupID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) SetNodeVal(groupID string, nodeID string, entry string, value string) error {
|
||||
if strings.ToUpper(value) == "UNDEF" || strings.ToUpper(value) == "NIL" || strings.ToUpper(value) == "DEL" {
|
||||
value = ""
|
||||
}
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Setting node %s/%s to: %s = '%s'\n", groupID, nodeID, entry, value )
|
||||
|
||||
switch strings.ToUpper(entry) {
|
||||
case "VNFS":
|
||||
util.ValidateOrDie("VNFS", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Vnfs = value
|
||||
case "KERNEL":
|
||||
util.ValidateOrDie("Kernel Version", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].KernelVersion = value
|
||||
case "DOMAINSUFFIX":
|
||||
util.ValidateOrDie("Domain", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].DomainSuffix = value
|
||||
case "IPXE":
|
||||
util.ValidateOrDie("iPXE Template", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Ipxe = value
|
||||
case "SYSTEMOVERLAY":
|
||||
util.ValidateOrDie("System Overlay", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].SystemOverlay = value
|
||||
case "RUNTIMEOVERLAY":
|
||||
util.ValidateOrDie("Runtime Overlay", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].RuntimeOverlay = value
|
||||
case "HOSTNAME":
|
||||
util.ValidateOrDie("Hostname", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Hostname = value
|
||||
case "IPMIIPADDR":
|
||||
util.ValidateOrDie("IPMI IP Address", entry, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiIpaddr = value
|
||||
case "IPMIUSERNAME":
|
||||
util.ValidateOrDie("IPMI Username", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiUserName = value
|
||||
case "IPMIPASSWORD":
|
||||
util.ValidateOrDie("IPMI Password", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiPassword = value
|
||||
|
||||
}
|
||||
} else {
|
||||
return errors.New("Node does not exist: " +groupID+ "/" +nodeID)
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group does not exist: " +groupID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) SetNodeNet(groupID string, nodeID string, netDev string, entry string, value string) error {
|
||||
if strings.ToUpper(value) == "UNDEF" || strings.ToUpper(value) == "NIL" || strings.ToUpper(value) == "DEL" {
|
||||
value = ""
|
||||
}
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev]; ok {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Editing existing node NetDev entry for node: %s/%s\n", groupID, nodeID)
|
||||
} else {
|
||||
var nd netDevs
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev] = &nd
|
||||
}
|
||||
} else {
|
||||
return errors.New("Node does not exist: "+groupID+"/"+nodeID)
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group does not exist: "+groupID)
|
||||
}
|
||||
|
||||
switch strings.ToUpper(entry) {
|
||||
case "IPADDR":
|
||||
util.ValidateOrDie("IP address", value, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Ipaddr = value
|
||||
case "NETMASK":
|
||||
util.ValidateOrDie("Netmask", value, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Netmask = value
|
||||
case "GATEWAY":
|
||||
util.ValidateOrDie("Gateway", value, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Gateway = value
|
||||
case "TYPE":
|
||||
util.ValidateOrDie("Network device type", value, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Type = value
|
||||
case "HWADDR":
|
||||
util.ValidateOrDie("HW address", value, "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Hwaddr = value
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) Persist() error {
|
||||
|
||||
out, err := yaml.Marshal(self)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(ConfigFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.WriteString(string(out))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
for groupname, group := range self.NodeGroups {
|
||||
for nodename, node := range group.Nodes {
|
||||
var n NodeInfo
|
||||
|
||||
n.Id = nodename
|
||||
n.Gid = groupname
|
||||
// n.Uid = groupname + ":" + nodename
|
||||
n.GroupName = groupname
|
||||
n.HostName = node.Hostname
|
||||
n.IpmiIpaddr = node.IpmiIpaddr
|
||||
|
||||
n.Vnfs = group.Vnfs
|
||||
n.SystemOverlay = group.SystemOverlay
|
||||
n.RuntimeOverlay = group.RuntimeOverlay
|
||||
n.KernelVersion = group.KernelVersion
|
||||
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
|
||||
}
|
||||
if node.Vnfs != "" {
|
||||
n.Vnfs = node.Vnfs
|
||||
}
|
||||
if node.SystemOverlay != "" {
|
||||
n.SystemOverlay = node.SystemOverlay
|
||||
}
|
||||
if node.RuntimeOverlay != "" {
|
||||
n.RuntimeOverlay = node.RuntimeOverlay
|
||||
}
|
||||
if node.DomainSuffix != "" {
|
||||
n.DomainName = node.DomainSuffix
|
||||
}
|
||||
if node.Ipxe != "" {
|
||||
n.Ipxe = node.Ipxe
|
||||
}
|
||||
if node.KernelArgs != "" {
|
||||
n.KernelArgs = node.KernelArgs
|
||||
}
|
||||
|
||||
if n.RuntimeOverlay == "" {
|
||||
n.RuntimeOverlay = "default"
|
||||
}
|
||||
if n.SystemOverlay == "" {
|
||||
n.SystemOverlay = "default"
|
||||
}
|
||||
if n.Ipxe == "" {
|
||||
n.Ipxe = "default"
|
||||
}
|
||||
if n.HostName == "" {
|
||||
n.HostName = nodename
|
||||
}
|
||||
|
||||
if n.DomainName != "" {
|
||||
n.Fqdn = node.Hostname + "." + n.DomainName
|
||||
} else {
|
||||
n.Fqdn = node.Hostname
|
||||
}
|
||||
|
||||
util.ValidateOrDie(n.Fqdn +":group name", n.GroupName, "^[a-zA-Z0-9-._]*$")
|
||||
util.ValidateOrDie(n.Fqdn +":vnfs", n.Vnfs, "^[a-zA-Z0-9-._:/]*$")
|
||||
util.ValidateOrDie(n.Fqdn +":system overlay", n.SystemOverlay, "^[a-zA-Z0-9-._]*$")
|
||||
util.ValidateOrDie(n.Fqdn +":runtime overlay", n.RuntimeOverlay, "^[a-zA-Z0-9-._]*$")
|
||||
util.ValidateOrDie(n.Fqdn +":domain suffix", n.DomainName, "^[a-zA-Z0-9-._]*$")
|
||||
util.ValidateOrDie(n.Fqdn +":hostname", n.HostName, "^[a-zA-Z0-9-_]*$")
|
||||
util.ValidateOrDie(n.Fqdn +":kernel version", n.KernelVersion, "^[a-zA-Z0-9-._]*$")
|
||||
|
||||
ret = append(ret, n)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (nodes *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
n, _ := nodes.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
for _, dev := range node.NetDevs {
|
||||
if dev.Hwaddr == hwa {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, errors.New("No nodes found with HW Addr: " + hwa)
|
||||
}
|
||||
|
||||
func (nodes *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
n, _ := nodes.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
for _, dev := range node.NetDevs {
|
||||
if dev.Ipaddr == ipaddr {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, errors.New("No nodes found with IP Addr: " + ipaddr)
|
||||
}
|
||||
|
||||
func (nodes *nodeYaml) SearchByName(search string) ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
n, _ := nodes.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
b, _ := regexp.MatchString(search, node.Fqdn)
|
||||
if b == true {
|
||||
ret = append(ret, node)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (nodes *nodeYaml) SearchByNameList(searchList []string) ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
n, _ := nodes.FindAllNodes()
|
||||
|
||||
for _, search := range searchList {
|
||||
for _, node := range n {
|
||||
b, _ := regexp.MatchString(search, node.Fqdn)
|
||||
if b == true {
|
||||
ret = append(ret, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
@@ -3,14 +3,13 @@ package overlay
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/hpcng/warewulf/internal/pkg/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
||||
func templateFileInclude(path string) string {
|
||||
wwlog.Printf(wwlog.DEBUG, "Including file into template: %s\n", path)
|
||||
content, err := ioutil.ReadFile(path)
|
||||
|
||||
@@ -2,10 +2,11 @@ package overlay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"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"
|
||||
@@ -53,7 +54,7 @@ func RuntimeOverlayInit(name string) error {
|
||||
}
|
||||
|
||||
|
||||
func RuntimeBuild(nodeList []assets.NodeInfo, force bool) error {
|
||||
func RuntimeBuild(nodeList []node.NodeInfo, force bool) error {
|
||||
config := config.New()
|
||||
|
||||
wwlog.SetIndent(4)
|
||||
@@ -62,6 +63,9 @@ func RuntimeBuild(nodeList []assets.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)
|
||||
|
||||
@@ -71,11 +75,11 @@ func RuntimeBuild(nodeList []assets.NodeInfo, force bool) error {
|
||||
}
|
||||
|
||||
if util.IsDir(OverlayDir) == false {
|
||||
wwlog.Printf(wwlog.WARN, "%-35s: Skipped (unknown runtime overlay)\n", node.Fqdn)
|
||||
wwlog.Printf(wwlog.WARN, "%-35s: Skipped (runtime overlay template not found)\n", node.Fqdn)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ package overlay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"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"
|
||||
@@ -53,7 +54,7 @@ func SystemOverlayInit(name string) error {
|
||||
}
|
||||
|
||||
|
||||
func SystemBuild(nodeList []assets.NodeInfo, force bool) error {
|
||||
func SystemBuild(nodeList []node.NodeInfo, force bool) error {
|
||||
config := config.New()
|
||||
|
||||
wwlog.SetIndent(4)
|
||||
@@ -62,6 +63,9 @@ func SystemBuild(nodeList []assets.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)
|
||||
|
||||
@@ -71,11 +75,11 @@ func SystemBuild(nodeList []assets.NodeInfo, force bool) error {
|
||||
}
|
||||
|
||||
if util.IsDir(OverlayDir) == false {
|
||||
wwlog.Printf(wwlog.WARN, "%-35s: Skipped (unknown system overlay)\n", node.Fqdn)
|
||||
wwlog.Printf(wwlog.WARN, "%-35s: Skipped (system overlay template not found)\n", node.Fqdn)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -111,9 +111,9 @@ func TaintCheck(pattern string, expr string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func ValidateOrDie(hostname string, name string, pattern string, expr string) {
|
||||
func ValidateOrDie(message string, pattern string, expr string) {
|
||||
if TaintCheck(pattern, expr) == false {
|
||||
wwlog.Printf(wwlog.ERROR, "Entry '%s:%s' contains illegal characters: '%s'\n", hostname, name, pattern)
|
||||
wwlog.Printf(wwlog.ERROR, "%s does not validate: '%s'\n", message, pattern)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user