Refactor gRPC-based image functions
Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
@@ -4,8 +4,6 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/warewulf/warewulf/internal/pkg/util"
|
||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
@@ -17,7 +15,7 @@ func Build(name string, buildForce bool) error {
|
||||
imagePath := ImageFile(name)
|
||||
|
||||
if !ValidSource(name) {
|
||||
return errors.Errorf("Image does not exist: %s", name)
|
||||
return fmt.Errorf("Image does not exist: %s", name)
|
||||
}
|
||||
|
||||
if !buildForce {
|
||||
|
||||
78
internal/pkg/image/delete.go
Normal file
78
internal/pkg/image/delete.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/warewulf/warewulf/internal/pkg/node"
|
||||
"github.com/warewulf/warewulf/internal/pkg/util"
|
||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
func Delete(name string) error {
|
||||
// validate image names
|
||||
if !ValidSource(name) {
|
||||
return fmt.Errorf("image name is not valid source: %s", name)
|
||||
}
|
||||
|
||||
nodeDB, err := node.New()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not open nodeDB: %s", err)
|
||||
}
|
||||
|
||||
// check if the deleted images are not used by nodes
|
||||
for nodeName, node := range nodeDB.Nodes {
|
||||
if node.ImageName == name {
|
||||
return fmt.Errorf("image %s is in use by node %s, cannot delete", node.ImageName, nodeName)
|
||||
}
|
||||
}
|
||||
|
||||
// check if the deleted images are not used by profiles
|
||||
for profileName, profile := range nodeDB.NodeProfiles {
|
||||
if profile.ImageName == name {
|
||||
return fmt.Errorf("image %s is in use by profile %s, cannot delete", profile.ImageName, profileName)
|
||||
}
|
||||
}
|
||||
|
||||
// delete images
|
||||
if err := DeleteSource(name); err != nil {
|
||||
return fmt.Errorf("could not remove image source %s: %w", name, err)
|
||||
}
|
||||
if err := DeleteImage(name); err != nil {
|
||||
return fmt.Errorf("could not remove image file %s: %w", name, err)
|
||||
}
|
||||
wwlog.Info("Deleted image %q", name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
Delete the chroot of an image
|
||||
*/
|
||||
func DeleteSource(name string) error {
|
||||
fullPath := SourceDir(name)
|
||||
|
||||
wwlog.Verbose("Removing path: %s", fullPath)
|
||||
return os.RemoveAll(fullPath)
|
||||
}
|
||||
|
||||
/*
|
||||
Delete the image of an image
|
||||
*/
|
||||
func DeleteImage(name string) error {
|
||||
imageFile := ImageFile(name)
|
||||
if util.IsFile(imageFile) {
|
||||
wwlog.Verbose("removing %s for image %s", imageFile, name)
|
||||
errImg := os.Remove(imageFile)
|
||||
wwlog.Verbose("removing %s for image %s", imageFile+".gz", name)
|
||||
errGz := os.Remove(imageFile + ".gz")
|
||||
if errImg != nil {
|
||||
return fmt.Errorf("Problems delete %s for image %s: %s", imageFile, name, errImg)
|
||||
}
|
||||
if errGz != nil {
|
||||
return fmt.Errorf("Problems delete %s for image %s: %s", imageFile+".gz", name, errGz)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Image %s of image %s doesn't exist", imageFile, name)
|
||||
}
|
||||
@@ -2,8 +2,10 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage/drivers/copy"
|
||||
@@ -74,3 +76,48 @@ func ImportDirectory(uri string, name string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// create the system context and reading out environment variables
|
||||
func GetSystemContext(noHttps bool, username string, password string, platform string) (sCtx *types.SystemContext, err error) {
|
||||
sCtx = &types.SystemContext{}
|
||||
// only check env if noHttps wasn't set
|
||||
if !noHttps {
|
||||
val, ok := os.LookupEnv("WAREWULF_OCI_NOHTTPS")
|
||||
if ok {
|
||||
|
||||
noHttps, err = strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while parsing insecure http option: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
// only set this if we want to disable, otherwise leave as undefined
|
||||
if noHttps {
|
||||
sCtx.DockerInsecureSkipTLSVerify = types.NewOptionalBool(true)
|
||||
}
|
||||
sCtx.OCIInsecureSkipTLSVerify = noHttps
|
||||
}
|
||||
if username == "" {
|
||||
username, _ = os.LookupEnv("WAREWULF_OCI_USERNAME")
|
||||
}
|
||||
if password == "" {
|
||||
password, _ = os.LookupEnv("WAREWULF_OCI_PASSWORD")
|
||||
}
|
||||
if username != "" || password != "" {
|
||||
if username != "" && password != "" {
|
||||
sCtx.DockerAuthConfig = &types.DockerAuthConfig{
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("oci username and password env vars must be specified together")
|
||||
}
|
||||
}
|
||||
if platform == "" {
|
||||
platform, _ = os.LookupEnv("WAREWULF_OCI_PLATFORM")
|
||||
}
|
||||
if platform != "" {
|
||||
sCtx.ArchitectureChoice = platform
|
||||
}
|
||||
return sCtx, nil
|
||||
}
|
||||
|
||||
60
internal/pkg/image/rename.go
Normal file
60
internal/pkg/image/rename.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/warewulf/warewulf/internal/pkg/node"
|
||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
func Rename(name string, targetName string, build bool) error {
|
||||
if !ValidSource(name) {
|
||||
return fmt.Errorf("image source does not exist: %s", name)
|
||||
}
|
||||
if !ValidName(targetName) {
|
||||
return fmt.Errorf("invalid image name: %s", targetName)
|
||||
}
|
||||
|
||||
// rename the image source folder
|
||||
sourceDir := SourceDir(name)
|
||||
destDir := SourceDir(targetName)
|
||||
err := os.Rename(sourceDir, destDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = DeleteImage(name)
|
||||
if err != nil {
|
||||
wwlog.Warn("Could not remove image files for %s: %s", name, err)
|
||||
}
|
||||
|
||||
if build {
|
||||
err = Build(targetName, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// update the nodes profiles image name
|
||||
nodeDB, err := node.New()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for nodeId, node := range nodeDB.Nodes {
|
||||
if node.ImageName == name {
|
||||
wwlog.Debug("updating node %s image to %s", nodeId, targetName)
|
||||
nodeDB.Nodes[nodeId].ImageName = targetName
|
||||
}
|
||||
}
|
||||
|
||||
for profileId, profile := range nodeDB.NodeProfiles {
|
||||
if profile.ImageName == name {
|
||||
wwlog.Debug("updating profile %s image to %s", profileId, targetName)
|
||||
nodeDB.NodeProfiles[profileId].ImageName = targetName
|
||||
}
|
||||
}
|
||||
|
||||
return nodeDB.Persist()
|
||||
}
|
||||
@@ -68,16 +68,6 @@ func ValidSource(name string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
Delete the chroot of an image
|
||||
*/
|
||||
func DeleteSource(name string) error {
|
||||
fullPath := SourceDir(name)
|
||||
|
||||
wwlog.Verbose("Removing path: %s", fullPath)
|
||||
return os.RemoveAll(fullPath)
|
||||
}
|
||||
|
||||
func Duplicate(name string, destination string) error {
|
||||
fullPathImageSource := RootFsDir(name)
|
||||
|
||||
@@ -91,27 +81,6 @@ func Duplicate(name string, destination string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
Delete the image of an image
|
||||
*/
|
||||
func DeleteImage(name string) error {
|
||||
imageFile := ImageFile(name)
|
||||
if util.IsFile(imageFile) {
|
||||
wwlog.Verbose("removing %s for image %s", imageFile, name)
|
||||
errImg := os.Remove(imageFile)
|
||||
wwlog.Verbose("removing %s for image %s", imageFile+".gz", name)
|
||||
errGz := os.Remove(imageFile + ".gz")
|
||||
if errImg != nil {
|
||||
return errors.Errorf("Problems delete %s for image %s: %s\n", imageFile, name, errImg)
|
||||
}
|
||||
if errGz != nil {
|
||||
return errors.Errorf("Problems delete %s for image %s: %s\n", imageFile+".gz", name, errGz)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("Image %s of image %s doesn't exist\n", imageFile, name)
|
||||
}
|
||||
|
||||
func IsWriteAble(name string) bool {
|
||||
return !util.IsFile(filepath.Join(SourceDir(name), "readonly"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user