Tentative: dbus daemon setup for profiles that need it

master
xSmurf 9 years ago
parent 9dbfaec596
commit 4ff81d924f

@ -2,6 +2,7 @@ package ozinit
import ( import (
"bufio" "bufio"
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -11,6 +12,7 @@ import (
"os/signal" "os/signal"
"os/user" "os/user"
"path" "path"
"regexp"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -44,6 +46,7 @@ type initState struct {
xpra *xpra.Xpra xpra *xpra.Xpra
xpraReady sync.WaitGroup xpraReady sync.WaitGroup
network *network.SandboxNetwork network *network.SandboxNetwork
dbusUuid string
} }
type InitData struct { type InitData struct {
@ -59,6 +62,12 @@ type InitData struct {
Display int Display int
} }
const (
DBUS_VAR_REGEXP = "[A-Za-z_]+=[a-zA-Z_:-@]+=/tmp/.+"
)
var dbusValidVar = regexp.MustCompile(DBUS_VAR_REGEXP)
// By convention oz-init writes log messages to stderr with a single character // By convention oz-init writes log messages to stderr with a single character
// prefix indicating the logging level. These messages are read one line at a time // prefix indicating the logging level. These messages are read one line at a time
// over a pipe by oz-daemon and translated into appropriate log events. // over a pipe by oz-daemon and translated into appropriate log events.
@ -164,12 +173,20 @@ func (st *initState) runInit() {
if syscall.Sethostname([]byte(st.profile.Name)) != nil { if syscall.Sethostname([]byte(st.profile.Name)) != nil {
st.log.Error("Failed to set hostname to (%s)", st.profile.Name) st.log.Error("Failed to set hostname to (%s)", st.profile.Name)
os.Exit(1)
} }
if syscall.Setdomainname([]byte("local")) != nil { if syscall.Setdomainname([]byte("local")) != nil {
st.log.Error("Failed to set domainname") st.log.Error("Failed to set domainname")
} }
st.log.Info("Hostname set to (%s.local)", st.profile.Name) st.log.Info("Hostname set to (%s.local)", st.profile.Name)
if st.needsDbus() {
if err := st.setupDbus(); err != nil {
st.log.Error("Unable to setup dbus: %v", err)
os.Exit(1)
}
}
oz.ReapChildProcs(st.log, st.handleChildExit) oz.ReapChildProcs(st.log, st.handleChildExit)
if st.profile.XServer.Enabled { if st.profile.XServer.Enabled {
@ -179,6 +196,13 @@ func (st *initState) runInit() {
st.xpraReady.Wait() st.xpraReady.Wait()
st.log.Info("XPRA started") st.log.Info("XPRA started")
if st.needsDbus() {
if err := st.getDbusSession(); err != nil {
st.log.Error("Unable to get dbus session information: %v", err)
os.Exit(1)
}
}
fsbx := path.Join("/tmp", "oz-sandbox") fsbx := path.Join("/tmp", "oz-sandbox")
err = ioutil.WriteFile(fsbx, []byte(st.profile.Name), 0644) err = ioutil.WriteFile(fsbx, []byte(st.profile.Name), 0644)
@ -195,6 +219,63 @@ func (st *initState) runInit() {
st.log.Info("oz-init exiting...") st.log.Info("oz-init exiting...")
} }
func (st *initState) needsDbus() bool {
return (st.profile.XServer.AudioMode == oz.PROFILE_AUDIO_FULL ||
st.profile.XServer.AudioMode == oz.PROFILE_AUDIO_SPEAKER ||
st.profile.XServer.EnableNotifications == true)
}
func (st *initState) setupDbus() error {
exec.Command("/usr/bin/dbus-uuidgen", "--ensure").Run()
buuid, err := exec.Command("/usr/bin/dbus-uuidgen", "--get").CombinedOutput()
if err != nil || string(buuid) == "" {
return fmt.Errorf("dbus-uuidgen failed: %v %v", err, string(buuid))
}
st.dbusUuid = strings.TrimSpace(string(bytes.Trim(buuid, "\x00")))
st.log.Debug("dbus-uuid: %s", st.dbusUuid)
return nil
}
func (st *initState) getDbusSession() error {
args := []string{
"--autolaunch",
st.dbusUuid,
"--sh-syntax",
"--close-stderr",
}
dcmd := exec.Command("/usr/bin/dbus-launch", args...)
dcmd.Env = append([]string{}, st.launchEnv...)
st.log.Debug("%s /usr/bin/dbus-launch %s", strings.Join(dcmd.Env, " "), strings.Join(args, " "))
dcmd.SysProcAttr = &syscall.SysProcAttr{}
dcmd.SysProcAttr.Credential = &syscall.Credential{
Uid: st.uid,
Gid: st.gid,
}
benvs, err := dcmd.Output()
if err != nil && len(benvs) <= 1 {
return fmt.Errorf("dbus-launch failed: %v %v", err, string(benvs))
}
benvs = bytes.Trim(benvs, "\x00")
senvs := strings.TrimSpace(string(benvs))
senvs = strings.Replace(senvs, "export ", "", -1)
senvs = strings.Replace(senvs, ";", "", -1)
senvs = strings.Replace(senvs, "'", "", -1)
dbusenv := ""
for _, line := range strings.Split(senvs, "\n") {
if dbusValidVar.MatchString(line) {
dbusenv = line
break;
}
}
if dbusenv != "" {
st.launchEnv = append(st.launchEnv, dbusenv)
vv := strings.Split(dbusenv, "=")
os.Setenv(vv[0], strings.Join(vv[1:], "="))
}
return nil
}
func (st *initState) startXpraServer() { func (st *initState) startXpraServer() {
if st.user == nil { if st.user == nil {
st.log.Warning("Cannot start xpra server because no user is set") st.log.Warning("Cannot start xpra server because no user is set")

@ -7,7 +7,7 @@ import (
"path" "path"
"strconv" "strconv"
"syscall" "syscall"
"github.com/subgraph/oz/fs" "github.com/subgraph/oz/fs"
) )
@ -18,7 +18,7 @@ var basicBindDirs = []string{
var basicEmptyDirs = []string{ var basicEmptyDirs = []string{
"/boot", "/dev", "/home", "/media", "/mnt", "/boot", "/dev", "/home", "/media", "/mnt",
"/opt", "/proc", "/root", "/run", "/run/lock", "/run/user", "/opt", "/proc", "/root", "/run", "/run/lock", "/run/user",
"/sbin", "/srv", "/sys", "/tmp", "/var", "/var/lib", "/sbin", "/srv", "/sys", "/tmp", "/var", "/var/lib", "/var/lib/dbus",
"/var/cache", "/var/crash", "/var/cache", "/var/crash",
} }
@ -38,7 +38,12 @@ var deviceSymlinks = [][2]string{
} }
var basicBlacklist = []string{ var basicBlacklist = []string{
"/usr/sbin", "/sbin", "/etc/X11", /*"${PATH}/dbus-daemon", "${PATH}/dbus-launch", "${PATH}/pulseaudio",*/
"/usr/lib/gvfs",
"/usr/sbin", "/sbin",
"/etc/X11", "/etc/machine-id",
"${PATH}/sudo", "${PATH}/su", "${PATH}/sudo", "${PATH}/su",
"${PATH}/xinput", "${PATH}/strace", "${PATH}/xinput", "${PATH}/strace",
"${PATH}/mount", "${PATH}/umount", "${PATH}/mount", "${PATH}/umount",

Loading…
Cancel
Save