Major refactor for Cobra and new pkg/app structure for wwctl

This commit is contained in:
Gregory Kurtzer
2020-11-10 21:28:39 -08:00
parent 0c369270ef
commit 189618a111
24 changed files with 658 additions and 130 deletions

View File

@@ -0,0 +1,50 @@
package vnfs
import (
"fmt"
"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) {
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(), v.Image()) {
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(v.Image()))
err := os.MkdirAll(path.Dir(v.Image()), 0755)
if err != nil {
fmt.Printf("ERROR: %s\n", err)
return
}
wwlog.Printf(wwlog.DEBUG, "Building VNFS image: '%s' -> '%s'\n", v.Source(), v.Image())
err = buildVnfs(v.Source(), v.Image())
if err != nil {
fmt.Printf("ERROR: %s\n", err)
os.Exit(1)
}
wwlog.Printf(wwlog.DEBUG, "Building links for Warewulf access to chroot\n")
err = buildLinks(v, v.Source())
if err != nil {
fmt.Printf("ERROR: %s\n", err)
os.Exit(1)
}
wwlog.Printf(wwlog.INFO, "%-35s: Done\n", v.Name())
}

View File

@@ -0,0 +1,89 @@
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"
)
const (
OciCacheDir = config.LocalStateDir + "/oci"
VnfsHashDir = config.LocalStateDir + "/oci/vnfs/hash/"
)
func BuildDocker(v vnfs.VnfsObject) {
wwlog.Printf(wwlog.VERBOSE, "Building OCI Container: %s\n", v.Source())
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(v.Image())
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(v.Image()), 0755)
if err != nil {
fmt.Printf("ERROR: %s\n", err)
return
}
err = os.MkdirAll(path.Dir(v.Root()), 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")
_ = os.Remove(v.Image() + "-link")
err = os.Symlink(hashDestination, v.Image()+"-link")
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
err = os.Rename(v.Image()+"-link", v.Image())
err = buildLinks(v, sourcePath)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
wwlog.Printf(wwlog.INFO, "%-35s: Done\n", v.Name())
return
}

View File

@@ -0,0 +1,41 @@
package vnfs
import (
"fmt"
"github.com/hpcng/warewulf/internal/pkg/vnfs"
"os"
"os/exec"
"path"
)
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
}
func buildLinks(v vnfs.VnfsObject, source string) error {
// Just incase the temporary link location is present, remove it if we can
_ = os.Remove(v.Root() + "-link")
// Just incase the directory doesn't exist, make it
_ = os.MkdirAll(path.Dir(v.Root()), 0755)
// Link to a temporary location so we can atomically move the link into place
err := os.Symlink(source, v.Root()+"-link")
if err != nil {
return err
}
// Atomically move the link into place
err = os.Rename(v.Root()+"-link", v.Root())
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,51 @@
package vnfs
import (
"github.com/hpcng/warewulf/internal/pkg/assets"
"github.com/hpcng/warewulf/internal/pkg/vnfs"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"strings"
)
var buildForce bool
func Build(nodeList []assets.NodeInfo, force bool) (error) {
set := make(map[string]int)
wwlog.Printf(wwlog.INFO, "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, "docker://") {
BuildDocker(v)
} else if strings.HasPrefix(uri, "docker-daemon://") {
//wwlog.Printf(wwlog.INFO, "Building VNFS from Docker service: %s\n", uri)
wwlog.Printf(wwlog.INFO, "Building VNFS from Docker service is not supported yet: %s\n", uri)
} else 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)
}
}
}
wwlog.SetIndent(0)
return nil
}