summaryrefslogtreecommitdiff
path: root/commands.go
diff options
context:
space:
mode:
authorAndrej Shadura <andrew.shadura@collabora.co.uk>2020-01-16 15:25:17 +0100
committerAndrej Shadura <andrew.shadura@collabora.co.uk>2020-01-16 15:25:17 +0100
commitfef5746ee329eb560d740132895ed29a44e44d10 (patch)
treeacbe7190a025de95c107fce342e2d2175aa88e2f /commands.go
parentafdeba754f8766de3b12211953eced5304991cde (diff)
New upstream version 1.0.0+git20191223.292995b
Diffstat (limited to 'commands.go')
-rw-r--r--commands.go118
1 files changed, 113 insertions, 5 deletions
diff --git a/commands.go b/commands.go
index 0ea2b9a..52704c5 100644
--- a/commands.go
+++ b/commands.go
@@ -2,8 +2,10 @@ package debos
import (
"bytes"
+ "crypto/sha256"
"fmt"
"io"
+ "io/ioutil"
"log"
"os"
"os/exec"
@@ -115,9 +117,101 @@ func (cmd *Command) AddBindMount(source, target string) {
cmd.bindMounts = append(cmd.bindMounts, mount)
}
+func (cmd *Command) saveResolvConf() (*[sha256.Size]byte, error) {
+ hostconf := "/etc/resolv.conf"
+ chrootedconf := path.Join(cmd.Chroot, hostconf)
+ savedconf := chrootedconf + ".debos"
+ var sum [sha256.Size]byte
+
+ if cmd.ChrootMethod == CHROOT_METHOD_NONE {
+ return nil, nil
+ }
+
+ // There may not be an existing resolv.conf
+ if _, err := os.Lstat(chrootedconf); !os.IsNotExist(err) {
+ if err = os.Rename(chrootedconf, savedconf); err != nil {
+ return nil, err
+ }
+ }
+
+ /* Expect a relatively small file here */
+ data, err := ioutil.ReadFile(hostconf)
+ if err != nil {
+ return nil, err
+ }
+ out := []byte("# Automatically generated by Debos\n")
+ out = append(out, data...)
+
+ sum = sha256.Sum256(out)
+
+ err = ioutil.WriteFile(chrootedconf, out, 0644)
+ if err != nil {
+ return nil, err
+ }
+
+ return &sum, nil
+}
+
+func (cmd *Command) restoreResolvConf(sum *[sha256.Size]byte) error {
+ hostconf := "/etc/resolv.conf"
+ chrootedconf := path.Join(cmd.Chroot, hostconf)
+ savedconf := chrootedconf + ".debos"
+
+ if cmd.ChrootMethod == CHROOT_METHOD_NONE || sum == nil {
+ return nil
+ }
+
+ // Remove the original copy anyway
+ defer os.Remove(savedconf)
+
+ fi, err := os.Lstat(chrootedconf)
+
+ // resolv.conf was removed during the command call
+ // Nothing to do with it -- file has been changed anyway
+ if os.IsNotExist(err) {
+ return nil
+ }
+
+ mode := fi.Mode()
+ switch {
+ case mode.IsRegular():
+ // Try to calculate checksum
+ data, err := ioutil.ReadFile(chrootedconf)
+ if err != nil {
+ return err
+ }
+ currentsum := sha256.Sum256(data)
+
+ // Leave the changed resolv.conf untouched
+ if bytes.Compare(currentsum[:], (*sum)[:]) == 0 {
+ // Remove the generated version
+ if err := os.Remove(chrootedconf); err != nil {
+ return err
+ }
+
+ if _, err := os.Lstat(savedconf); !os.IsNotExist(err) {
+ // Restore the original version
+ if err = os.Rename(savedconf, chrootedconf); err != nil {
+ return err
+ }
+ }
+ }
+ case mode&os.ModeSymlink != 0:
+ // If the 'resolv.conf' is a symlink
+ // Nothing to do with it -- file has been changed anyway
+ default:
+ // File is not regular or symlink
+ // Let's get out here with verbose message
+ log.Printf("Warning: /etc/resolv.conf inside the chroot is not a regular file")
+ }
+
+ return nil
+}
+
func (cmd Command) Run(label string, cmdline ...string) error {
q := newQemuHelper(cmd)
q.Setup()
+ defer q.Cleanup()
var options []string
switch cmd.ChrootMethod {
@@ -128,7 +222,8 @@ func (cmd Command) Run(label string, cmdline ...string) error {
options = append(options, cmd.Chroot)
options = append(options, cmdline...)
case CHROOT_METHOD_NSPAWN:
- options = append(options, "systemd-nspawn", "-q", "-D", cmd.Chroot)
+ // We use own resolv.conf handling
+ options = append(options, "systemd-nspawn", "-q", "--resolv-conf=off", "-D", cmd.Chroot)
for _, e := range cmd.extraEnv {
options = append(options, "--setenv", e)
@@ -147,6 +242,8 @@ func (cmd Command) Run(label string, cmdline ...string) error {
exe.Stdout = w
exe.Stderr = w
+ defer w.flush()
+
if len(cmd.extraEnv) > 0 && cmd.ChrootMethod != CHROOT_METHOD_NSPAWN {
exe.Env = append(os.Environ(), cmd.extraEnv...)
}
@@ -158,11 +255,22 @@ func (cmd Command) Run(label string, cmdline ...string) error {
defer services.Allow()
}
- err := exe.Run()
- w.flush()
- q.Cleanup()
+ // Save the original resolv.conf and copy version from host
+ resolvsum, err := cmd.saveResolvConf()
+ if err != nil {
+ return err
+ }
+
+ if err = exe.Run(); err != nil {
+ return err
+ }
+
+ // Restore the original resolv.conf if not changed
+ if err = cmd.restoreResolvConf(resolvsum); err != nil {
+ return err
+ }
- return err
+ return nil
}
type qemuHelper struct {