added support for mounts.conf for container exec

This commit is contained in:
Christian Goll
2023-01-30 15:36:42 +01:00
parent 71a3867bbe
commit d82314460f
5 changed files with 125 additions and 20 deletions

View File

@@ -97,7 +97,7 @@ export GOPROXY
WW_GO_BUILD_TAGS := containers_image_openpgp containers_image_ostree
# Default target
all: config vendor wwctl wwclient bash_completion.d man_pages config_defaults print_defaults wwapid wwapic wwapird
all: config vendor wwctl wwclient bash_completion.d man_pages config_defaults print_defaults wwapid wwapic wwapird print_mnts
# Validate source and build all packages
build: lint test-it vet all
@@ -248,6 +248,9 @@ config_defaults: vendor cmd/config_defaults/config_defaults.go
print_defaults: vendor cmd/print_defaults/print_defaults.go
cd cmd/print_defaults && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'" -o ../../print_defaults
print_mnts: vendor cmd/print_mnts/print_mnts.go
cd cmd/print_mnts && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'" -o ../../print_mnts
update_configuration: vendor cmd/update_configuration/update_configuration.go
cd cmd/update_configuration && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'\
-X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=./etc/nodes.conf'"\
@@ -309,6 +312,7 @@ clean:
rm -f config_defaults
rm -f update_configuration
rm -f print_defaults
rm -f print_mnts
rm -f etc/wwapi{c,d,rd}.conf
install: files install_wwclient

View File

@@ -0,0 +1,37 @@
package print_mnts
import (
"fmt"
"github.com/hpcng/warewulf/internal/pkg/container"
"gopkg.in/yaml.v2"
)
func main() {
mounts := []container.MntDetails{
container.MntDetails{
Source: "/etc/resolv.conf",
Dest: "/etc/resolv.conf",
ReadOnly: false,
},
container.MntDetails{
Source: "etc/zypp/credentials.d/SCCcredentials",
Dest: "etc/zypp/credentials.d/SCCcredentials",
ReadOnly: false,
},
container.MntDetails{
Source: "/etc/SUSEConnect",
Dest: "/etc/SUSEConnect",
ReadOnly: false,
},
}
var ptrs []*container.MntDetails
for _, m := range mounts {
ptrs = append(ptrs, &m)
}
mountPts := container.MountPoints{
MountPnts: ptrs,
}
data, _ := yaml.Marshal(mountPts)
fmt.Println(data)
}

View File

@@ -32,8 +32,10 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
os.Exit(1)
}
var err error
mountPts := container.DefaultMntPts()
mountPts = append(container.InitMountPnts(binds), mountPts...)
// check for valid mount points
lowerObjects := checkMountPoints(containerName, binds)
lowerObjects := checkMountPoints(containerName, mountPts)
if len(lowerObjects) != 0 {
if tempDir == "" {
tempDir, err = os.MkdirTemp(buildconfig.TMPDIR(), "overlay")
@@ -154,33 +156,22 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
Check if the bind mount points exists in the given container. Returns
the invalid mount points. Directories always have '/' as suffix
*/
func checkMountPoints(containerName string, binds []string) (overlayObjects []string) {
func checkMountPoints(containerName string, binds []container.MntDetails) (overlayObjects []string) {
wwlog.Debug("Checking if container %s has paths: %v", containerName, binds)
overlayObjects = []string{}
for _, b := range binds {
var source string
var dest string
bind := util.SplitValidPaths(b, ":")
source = bind[0]
if len(bind) == 1 {
dest = source
} else {
dest = bind[1]
}
err, _ := os.Stat(source)
err, _ := os.Stat(b.Source)
if err == nil {
// no need to create a mount location if source doesn't exist
continue
}
if _, err := os.Stat(path.Join(container.RootFsDir(containerName), dest)); err != nil {
if _, err := os.Stat(path.Join(container.RootFsDir(containerName), b.Dest)); err != nil {
if os.IsNotExist(err) {
if util.IsDir(dest) && !strings.HasSuffix(dest, "/") {
dest += "/"
if util.IsDir(b.Dest) && !strings.HasSuffix(b.Dest, "/") {
b.Dest += "/"
}
overlayObjects = append(overlayObjects, source)
wwlog.Debug("Container %s, needs following path: %s", containerName, dest)
overlayObjects = append(overlayObjects, b.Dest)
wwlog.Debug("Container %s, needs following path: %s", containerName, b.Dest)
}
}
}

View File

@@ -0,0 +1,73 @@
package container
import (
"io/ioutil"
"path"
"strings"
"github.com/hpcng/warewulf/internal/pkg/buildconfig"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"gopkg.in/yaml.v2"
)
/*
Describe a mount point for a container exec
*/
type MntDetails struct {
Dest string `yaml:"Dest"`
Source string `yaml:"Source,omitempty"`
ReadOnly bool `yaml:"Readonly,omitempty" default:"false"`
Options string `yaml:"Options,omitempty"` // ignored at the moment
}
/*
Holds the containers, so that they can be marshalled
*/
type MountPoints struct {
MountPnts []*MntDetails `yaml:"Mount Points"`
}
/*
Create a slice iof MntDetails from a string slice with following
format "source:[:destination][:readonly]" if destination is not
given, the source is used as destination
*/
func InitMountPnts(binds []string) (mounts []MntDetails) {
for _, b := range binds {
bind := strings.Split(b, ":")
dest := bind[0]
if len(bind) >= 2 {
dest = bind[1]
}
readonly := false
if len(bind) >= 3 && bind[2] == "ro" {
readonly = true
}
mntPnt := MntDetails{
Source: bind[0],
Dest: dest,
ReadOnly: readonly,
}
mounts = append(mounts, mntPnt)
}
return mounts
}
/*
Read in the default bind mounts from the configuration file
warewulf/mounts.conf
*/
func DefaultMntPts() (mounts []MntDetails) {
data, err := ioutil.ReadFile(path.Join(buildconfig.SYSCONFDIR(), "warewulf/mounts.conf"))
if err != nil {
wwlog.Verbose("No default bind mounts for containers: %s", err)
return mounts
}
wwlog.Debug("Unmarshaling the mounts configuration")
err = yaml.Unmarshal(data, &mounts)
if err != nil {
wwlog.Verbose("Couldn't unmarshall default bind mounts for containers: %s", err)
}
return mounts
}

BIN
print_mnts Executable file

Binary file not shown.