Accepting request 1207972 from network:cluster
without patch (forwarded request 1207971 from mslacken) OBS-URL: https://build.opensuse.org/request/show/1207972 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/warewulf4?expand=0&rev=26
This commit is contained in:
commit
dab5fb20dc
2
_service
2
_service
@ -2,7 +2,7 @@
|
||||
<service name="obs_scm" mode="manual">
|
||||
<param name="url">https://github.com/warewulf/warewulf.git</param>
|
||||
<param name="scm">git</param>
|
||||
<param name="revision">v4.5.6</param>
|
||||
<param name="revision">v4.5.8</param>
|
||||
<param name="versionformat">@PARENT_TAG@</param>
|
||||
<param name="versionrewrite-pattern">v(.*)</param>
|
||||
<param name="changesgenerate">enable</param>
|
||||
|
@ -1,225 +0,0 @@
|
||||
diff --git a/internal/app/wwctl/container/exec/child/main.go b/internal/app/wwctl/container/exec/child/main.go
|
||||
index 253a6ad2..ba9ad9f7 100644
|
||||
--- a/internal/app/wwctl/container/exec/child/main.go
|
||||
+++ b/internal/app/wwctl/container/exec/child/main.go
|
||||
@@ -92,7 +92,7 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
wwlog.Debug("overlay options: %s", options)
|
||||
err = syscall.Mount("overlay", containerPath, "overlay", 0, options)
|
||||
if err != nil {
|
||||
- wwlog.Warn(fmt.Sprintf("Couldn't create overlay for ephermal mount points: %s", err))
|
||||
+ wwlog.Warn("Couldn't create overlay for ephermal mount points: %s", err)
|
||||
}
|
||||
} else if nodename != "" {
|
||||
nodeDB, err := node.New()
|
||||
@@ -142,6 +142,10 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
}
|
||||
|
||||
for _, mntPnt := range mountPts {
|
||||
+ if mntPnt.Cow {
|
||||
+ continue
|
||||
+ }
|
||||
+ wwlog.Debug("bind mounting: %s -> %s", mntPnt.Source, path.Join(containerPath, mntPnt.Dest))
|
||||
err = syscall.Mount(mntPnt.Source, path.Join(containerPath, mntPnt.Dest), "", syscall.MS_BIND, "")
|
||||
if err != nil {
|
||||
wwlog.Warn("Couldn't mount %s to %s: %s", mntPnt.Source, mntPnt.Dest, err)
|
||||
@@ -195,6 +199,9 @@ the invalid mount points. Directories always have '/' as suffix
|
||||
func checkMountPoints(containerName string, binds []*warewulfconf.MountEntry) (overlayObjects []string) {
|
||||
overlayObjects = []string{}
|
||||
for _, b := range binds {
|
||||
+ if b.Cow {
|
||||
+ continue
|
||||
+ }
|
||||
_, err := os.Stat(b.Source)
|
||||
if err != nil {
|
||||
wwlog.Debug("Couldn't stat %s create no mount point in container", b.Source)
|
||||
diff --git a/internal/app/wwctl/container/exec/main.go b/internal/app/wwctl/container/exec/main.go
|
||||
index 60cf9d48..788adc86 100644
|
||||
--- a/internal/app/wwctl/container/exec/main.go
|
||||
+++ b/internal/app/wwctl/container/exec/main.go
|
||||
@@ -54,7 +54,6 @@ func runContainedCmd(cmd *cobra.Command, containerName string, args []string) (e
|
||||
}()
|
||||
|
||||
logStr := fmt.Sprint(wwlog.GetLogLevel())
|
||||
-
|
||||
childArgs := []string{"--warewulfconf", conf.GetWarewulfConf(), "--loglevel", logStr, "container", "exec", "__child"}
|
||||
childArgs = append(childArgs, containerName)
|
||||
for _, b := range binds {
|
||||
@@ -64,8 +63,40 @@ func runContainedCmd(cmd *cobra.Command, containerName string, args []string) (e
|
||||
childArgs = append(childArgs, "--node", nodeName)
|
||||
}
|
||||
childArgs = append(childArgs, args...)
|
||||
+ // copy the files into the container at this stage, es in __child the
|
||||
+ // command syscall.Exec which replaces the __child process with the
|
||||
+ // exec command in the container. All the mounts, have to be done in
|
||||
+ // __child so that the used mounts don't propagate outside on the host
|
||||
+ // (see the CLONE attributes), but as for the cow copy option we need
|
||||
+ // to see if a file was modified after it was copied into the container
|
||||
+ // so do this here.
|
||||
+ // At first read out conf, the parse commandline, as copy files has the
|
||||
+ // same synatx as mount points
|
||||
+ mountPts := conf.MountsContainer
|
||||
+ mountPts = append(container.InitMountPnts(binds), mountPts...)
|
||||
+ filesToCpy := getCopyFiles(containerName, mountPts)
|
||||
+ for i, cpyFile := range filesToCpy {
|
||||
+ if err = util.CopyFile(cpyFile.Src, path.Join(container.RootFsDir(containerName), cpyFile.FileName)); err != nil {
|
||||
+ return fmt.Errorf("couldn't copy files into container: %w", err)
|
||||
+ }
|
||||
+ // we can ignore error as the file was copied
|
||||
+ stat, _ := os.Stat(path.Join(container.RootFsDir(containerName), cpyFile.FileName))
|
||||
+ filesToCpy[i].ModTime = stat.ModTime()
|
||||
+ }
|
||||
wwlog.Verbose("Running contained command: %s", childArgs)
|
||||
- return childCommandFunc(cmd, childArgs)
|
||||
+ retVal := childCommandFunc(cmd, childArgs)
|
||||
+ for _, cpyFile := range filesToCpy {
|
||||
+ if modStat, err := os.Stat(path.Join(container.RootFsDir(containerName), cpyFile.FileName)); err != nil {
|
||||
+ wwlog.Warn("copied file was removed: %s", err)
|
||||
+ } else {
|
||||
+ if modStat.ModTime() == cpyFile.ModTime {
|
||||
+ if err := os.Remove(path.Join(container.RootFsDir(containerName), cpyFile.FileName)); err != nil {
|
||||
+ wwlog.Warn("couldn't remove copied file: %s", err)
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return retVal
|
||||
}
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
@@ -154,3 +185,40 @@ func SetBinds(myBinds []string) {
|
||||
func SetNode(myNode string) {
|
||||
nodeName = myNode
|
||||
}
|
||||
+
|
||||
+// file name and last modification time so we can remove the file if it wasn't modified
|
||||
+type cowFile struct {
|
||||
+ FileName string
|
||||
+ Src string
|
||||
+ ModTime time.Time
|
||||
+ Cow bool
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+Check the objects we want to copy in, instead of mounting
|
||||
+*/
|
||||
+func getCopyFiles(containerNamer string, binds []*warewulfconf.MountEntry) (copyObjects []cowFile) {
|
||||
+ for _, bind := range binds {
|
||||
+ if !bind.Cow || bind.ReadOnly {
|
||||
+ continue
|
||||
+ }
|
||||
+ if _, err := os.Stat(path.Join(container.RootFsDir(containerNamer), path.Dir(bind.Dest))); err != nil {
|
||||
+ wwlog.Warn("destination directory doesn't exist: %s", err)
|
||||
+ continue
|
||||
+ }
|
||||
+ if _, err := os.Stat(path.Join(container.RootFsDir(containerNamer), bind.Dest)); err == nil {
|
||||
+ wwlog.Verbose("file exists in container: %s", bind.Dest)
|
||||
+ continue
|
||||
+ }
|
||||
+ if _, err := os.Stat(bind.Source); err != nil {
|
||||
+ wwlog.Warn("source doesn't exist: %s", err)
|
||||
+ continue
|
||||
+ }
|
||||
+ copyObjects = append(copyObjects, cowFile{
|
||||
+ FileName: bind.Dest,
|
||||
+ Src: bind.Source,
|
||||
+ Cow: bind.Cow,
|
||||
+ })
|
||||
+ }
|
||||
+ return
|
||||
+}
|
||||
diff --git a/internal/app/wwctl/container/exec/root.go b/internal/app/wwctl/container/exec/root.go
|
||||
index 4b74c941..0b6aaf63 100644
|
||||
--- a/internal/app/wwctl/container/exec/root.go
|
||||
+++ b/internal/app/wwctl/container/exec/root.go
|
||||
@@ -32,7 +32,11 @@ var (
|
||||
|
||||
func init() {
|
||||
baseCmd.AddCommand(child.GetCommand())
|
||||
- baseCmd.PersistentFlags().StringArrayVarP(&binds, "bind", "b", []string{}, "Bind a local path into the container (must exist)")
|
||||
+ baseCmd.PersistentFlags().StringArrayVarP(&binds, "bind", "b", []string{}, `Bind a local path which must exist into the container. Syntax is
|
||||
+source[:destination[:{ro|cow}]] If destination is not set,
|
||||
+it will the same path as source.The additional parameter is
|
||||
+ro for read only and cow, which means the file is copied into
|
||||
+the container and removed if not modified.`)
|
||||
baseCmd.PersistentFlags().BoolVar(&SyncUser, "syncuser", false, "Synchronize UIDs/GIDs from host to container")
|
||||
baseCmd.PersistentFlags().StringVarP(&nodeName, "node", "n", "", "Create a read only view of the container for the given node")
|
||||
}
|
||||
diff --git a/internal/app/wwctl/container/shell/root.go b/internal/app/wwctl/container/shell/root.go
|
||||
index cceb7512..52d9825d 100644
|
||||
--- a/internal/app/wwctl/container/shell/root.go
|
||||
+++ b/internal/app/wwctl/container/shell/root.go
|
||||
@@ -28,7 +28,11 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
- baseCmd.PersistentFlags().StringArrayVarP(&binds, "bind", "b", []string{}, "Bind a local path into the container (must exist)")
|
||||
+ baseCmd.PersistentFlags().StringArrayVarP(&binds, "bind", "b", []string{}, `Bind a local path which must exist into the container. Syntax is
|
||||
+source[:destination[:{ro|cow}]] If destination is not set,
|
||||
+it will the same path as source.The additional parameter is
|
||||
+ro for read only and cow, which means the file is copied into
|
||||
+the container and removed if not modified.`)
|
||||
baseCmd.PersistentFlags().StringVarP(&nodeName, "node", "n", "", "Create a read only view of the container for the given node")
|
||||
}
|
||||
|
||||
diff --git a/internal/pkg/config/mounts.go b/internal/pkg/config/mounts.go
|
||||
index 2eb5060b..35805202 100644
|
||||
--- a/internal/pkg/config/mounts.go
|
||||
+++ b/internal/pkg/config/mounts.go
|
||||
@@ -7,4 +7,5 @@ type MountEntry struct {
|
||||
Dest string `yaml:"dest,omitempty"`
|
||||
ReadOnly bool `yaml:"readonly,omitempty"`
|
||||
Options string `yaml:"options,omitempty"` // ignored at the moment
|
||||
+ Cow bool `yaml:"cow,omitempty"` // copy the file into the container and don't remove if modified
|
||||
}
|
||||
diff --git a/internal/pkg/container/mountpoints.go b/internal/pkg/container/mountpoints.go
|
||||
index 5de00c75..7c16a0a9 100644
|
||||
--- a/internal/pkg/container/mountpoints.go
|
||||
+++ b/internal/pkg/container/mountpoints.go
|
||||
@@ -21,13 +21,19 @@ func InitMountPnts(binds []string) (mounts []*warewulfconf.MountEntry) {
|
||||
dest = bind[1]
|
||||
}
|
||||
readonly := false
|
||||
- if len(bind) >= 3 && bind[2] == "ro" {
|
||||
- readonly = true
|
||||
+ cow := false
|
||||
+ if len(bind) >= 3 {
|
||||
+ if bind[2] == "ro" {
|
||||
+ readonly = true
|
||||
+ } else if bind[2] == "cow" {
|
||||
+ cow = true
|
||||
+ }
|
||||
}
|
||||
mntPnt := warewulfconf.MountEntry{
|
||||
Source: bind[0],
|
||||
Dest: dest,
|
||||
ReadOnly: readonly,
|
||||
+ Cow: cow,
|
||||
}
|
||||
mounts = append(mounts, &mntPnt)
|
||||
}
|
||||
diff --git a/userdocs/contents/containers.rst b/userdocs/contents/containers.rst
|
||||
index aa8385eb..02e0fbc6 100644
|
||||
--- a/userdocs/contents/containers.rst
|
||||
+++ b/userdocs/contents/containers.rst
|
||||
@@ -216,6 +216,21 @@ when using the exec command. This works as follows:
|
||||
location, as it is almost always present and empty in every Linux
|
||||
distribution (as prescribed by the LSB file hierarchy standard).
|
||||
|
||||
+Files which should always be present in a container image like ``resolv.conf``
|
||||
+can be specified in ``warewulf.conf`` with following container_exit
|
||||
+
|
||||
+.. code-block:: yaml
|
||||
+ container mounts:
|
||||
+ - source: /etc/resolv.conf
|
||||
+ dest: /etc/resolv.conf
|
||||
+ readonly: true
|
||||
+
|
||||
+.. note::
|
||||
+ Instead of the ``readonly`` setting you can set ``cow``, which
|
||||
+ has the effect, that the source file is copied to the container
|
||||
+ and removed if it was modified. This useful for file used for
|
||||
+ registrations.
|
||||
+
|
||||
When the command completes, if anything within the container changed,
|
||||
the container will be rebuilt into a bootable static object
|
||||
automatically.
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5f8e5c963f2f3c8496b9946547403cfa67f1605a84852f5fc20d8237e295011a
|
||||
size 5453108
|
||||
oid sha256:1bcb88969fa42ca31e86f10d23492b0a8ef4c01d906acdb2ea6fea5ca05f2011
|
||||
size 5458040
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e9eb2bf48a885a73e7bc34dbb803528ee8943346c28f5f946f1af3871734ef78
|
||||
size 3755020
|
3
warewulf-4.5.8.obscpio
Normal file
3
warewulf-4.5.8.obscpio
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bc87304e69e168da9cdac808189058e7d57f3f21305b4d771a8f3986854829b3
|
||||
size 4151820
|
@ -1,4 +1,4 @@
|
||||
name: warewulf
|
||||
version: 4.5.6
|
||||
mtime: 1722867783
|
||||
commit: ad21463ac4c885e19818c131391a0fbf04053a89
|
||||
version: 4.5.8
|
||||
mtime: 1727737516
|
||||
commit: f69dac7264522dda383ebb1584ddb6ddd82cb199
|
||||
|
@ -1,3 +1,18 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Oct 14 13:41:00 UTC 2024 - cgoll@suse.com
|
||||
|
||||
- Update to version 4.5.8:
|
||||
- Warewulf v4.5.8 simplifies the "wwinit" boot process for SELinux and
|
||||
configures tmpfs to spread the node image across all available NUMA nodes. It
|
||||
also improves the detection of kernels in the container image to more
|
||||
reliably detect the newest available kernel and to avoid debug / rescue
|
||||
kernels.
|
||||
- Warewulf v4.5.7 fixes the ability to override overlay files configured in
|
||||
profiles with overlays configured per-node; fixes a template processing bug
|
||||
bug in development-time overlay rendering; and improves the preview
|
||||
dracut-based boot process to better support a "secure" boot process.
|
||||
- rmeoved added-cow-option-to-bind.patch as now in upstream
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Aug 22 12:56:41 UTC 2024 - Christian Goll <cgoll@suse.com>
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
ExclusiveArch: x86_64 aarch64
|
||||
|
||||
Name: warewulf4
|
||||
Version: 4.5.6
|
||||
Version: 4.5.8
|
||||
Release: 0
|
||||
Summary: A suite of tools for clustering
|
||||
License: BSD-3-Clause
|
||||
@ -35,7 +35,6 @@ Source5: warewulf4-rpmlintrc
|
||||
Source10: config-ww4.sh
|
||||
Source11: adjust_overlays.sh
|
||||
Source20: README.dnsmasq
|
||||
Patch0: added-cow-option-to-bind.patch
|
||||
|
||||
# no firewalld in sle12
|
||||
%if 0%{?sle_version} >= 150000 || 0%{?suse_version} > 1500
|
||||
|
Loading…
x
Reference in New Issue
Block a user