diff --git a/Makefile b/Makefile index 310d38b5..81b75681 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/cmd/print_mnts/print_mnts.go b/cmd/print_mnts/print_mnts.go new file mode 100644 index 00000000..b119b192 --- /dev/null +++ b/cmd/print_mnts/print_mnts.go @@ -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) +} diff --git a/internal/app/wwctl/container/exec/child/main.go b/internal/app/wwctl/container/exec/child/main.go index dc34fc72..52be2676 100644 --- a/internal/app/wwctl/container/exec/child/main.go +++ b/internal/app/wwctl/container/exec/child/main.go @@ -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) } } } diff --git a/internal/pkg/container/mountpoints.go b/internal/pkg/container/mountpoints.go new file mode 100644 index 00000000..1d12b3eb --- /dev/null +++ b/internal/pkg/container/mountpoints.go @@ -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 +} diff --git a/print_mnts b/print_mnts new file mode 100755 index 00000000..3fe2e35d Binary files /dev/null and b/print_mnts differ