mirror of
https://github.com/lingble/talos.git
synced 2025-11-24 01:44:51 +00:00
feat: add ability to append to existing files with extrafiles
This PR introduces "op" to the extra files options. This allows for a user to specify "append" as the op, which will create a copy of the file specified, add the extra data provided, and bind mount over the existing file. Will close #1467 Signed-off-by: Spencer Smith <robertspencersmith@gmail.com>
This commit is contained in:
committed by
Andrew Rynhard
parent
264c5440ef
commit
84354c5941
@@ -5,11 +5,14 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
|
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
|
||||||
"github.com/talos-systems/talos/internal/pkg/runtime"
|
"github.com/talos-systems/talos/internal/pkg/runtime"
|
||||||
@@ -32,13 +35,48 @@ func (task *ExtraFiles) runtime(r runtime.Runtime) (err error) {
|
|||||||
var result *multierror.Error
|
var result *multierror.Error
|
||||||
|
|
||||||
for _, f := range r.Config().Machine().Files() {
|
for _, f := range r.Config().Machine().Files() {
|
||||||
p := filepath.Join("/var", f.Path)
|
// Slurp existing file if append is our op and add contents to it
|
||||||
|
if f.Op == "append" {
|
||||||
|
var existingFileContents []byte
|
||||||
|
|
||||||
|
existingFileContents, err = ioutil.ReadFile(f.Path)
|
||||||
|
if err != nil {
|
||||||
|
result = multierror.Append(result, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Contents = string(existingFileContents) + "\n" + f.Contents
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if supplied path is in /var or not.
|
||||||
|
// If not, we'll write it to /var anyways and bind mount below
|
||||||
|
p := f.Path
|
||||||
|
inVar := true
|
||||||
|
explodedPath := strings.Split(
|
||||||
|
strings.TrimLeft(f.Path, "/"),
|
||||||
|
string(os.PathSeparator),
|
||||||
|
)
|
||||||
|
|
||||||
|
if explodedPath[0] != "var" {
|
||||||
|
p = filepath.Join("/var", f.Path)
|
||||||
|
inVar = false
|
||||||
|
}
|
||||||
|
|
||||||
if err = os.MkdirAll(filepath.Dir(p), os.ModeDir); err != nil {
|
if err = os.MkdirAll(filepath.Dir(p), os.ModeDir); err != nil {
|
||||||
result = multierror.Append(result, err)
|
result = multierror.Append(result, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = ioutil.WriteFile(p, []byte(f.Contents), f.Permissions); err != nil {
|
if err = ioutil.WriteFile(p, []byte(f.Contents), f.Permissions); err != nil {
|
||||||
result = multierror.Append(result, err)
|
result = multierror.Append(result, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// File path was not /var/... so we assume a bind mount is wanted
|
||||||
|
if !inVar {
|
||||||
|
if err = unix.Mount(p, f.Path, "", unix.MS_BIND|unix.MS_RDONLY, ""); err != nil {
|
||||||
|
result = multierror.Append(result, fmt.Errorf("failed to create bind mount for %s: %w", p, err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ type File struct {
|
|||||||
Contents string `yaml:"contents"`
|
Contents string `yaml:"contents"`
|
||||||
Permissions os.FileMode `yaml:"permissions"`
|
Permissions os.FileMode `yaml:"permissions"`
|
||||||
Path string `yaml:"path"`
|
Path string `yaml:"path"`
|
||||||
|
Op string `yaml:"op"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Security defines the requirements for a config that pertains to security
|
// Security defines the requirements for a config that pertains to security
|
||||||
|
|||||||
Reference in New Issue
Block a user