Example #1
0
// makeSnapHookEnv returns an environment suitable for passing to
// os/exec.Cmd.Env
//
// The returned environment contains additional SNAP_* variables that
// are required when calling a meta/hook/ script and that will override
// any already existing SNAP_* variables in os.Environment()
func makeSnapHookEnv(snap *Snap) (env []string) {
	desc := struct {
		SnapName    string
		SnapArch    string
		SnapPath    string
		Version     string
		Revision    int
		UdevAppName string
	}{
		snap.Name(),
		arch.UbuntuArchitecture(),
		snap.Info().MountDir(),
		snap.Version(),
		snap.Revision(),
		snap.Name(),
	}

	vars := snapenv.GetBasicSnapEnvVars(desc)
	snapEnv := snapenv.MakeMapFromEnvList(vars)

	// merge regular env and new snapEnv
	envMap := snapenv.MakeMapFromEnvList(os.Environ())
	for k, v := range snapEnv {
		envMap[k] = v
	}

	// force default locale
	envMap["LC_ALL"] = "C.UTF-8"

	// flatten
	for k, v := range envMap {
		env = append(env, fmt.Sprintf("%s=%s", k, v))
	}

	return env
}
Example #2
0
func (s *systemd) GenServiceFile(desc *ServiceDescription) string {
	serviceTemplate := `[Unit]
Description={{.Description}}
After=snapd.frameworks.target{{ if .Socket }} {{.SocketFileName}}{{end}}
Requires=snapd.frameworks.target{{ if .Socket }} {{.SocketFileName}}{{end}}
X-Snappy=yes

[Service]
ExecStart=/usr/bin/ubuntu-core-launcher {{.UdevAppName}} {{.AaProfile}} {{.FullPathStart}}
Restart={{.Restart}}
WorkingDirectory=/var{{.SnapPath}}
Environment={{.EnvVars}}
{{if .Stop}}ExecStop=/usr/bin/ubuntu-core-launcher {{.UdevAppName}} {{.AaProfile}} {{.FullPathStop}}{{end}}
{{if .PostStop}}ExecStopPost=/usr/bin/ubuntu-core-launcher {{.UdevAppName}} {{.AaProfile}} {{.FullPathPostStop}}{{end}}
{{if .StopTimeout}}TimeoutStopSec={{.StopTimeout.Seconds}}{{end}}
Type={{.Type}}
{{if .BusName}}BusName={{.BusName}}{{end}}

[Install]
WantedBy={{.ServiceSystemdTarget}}
`
	var templateOut bytes.Buffer
	t := template.Must(template.New("wrapper").Parse(serviceTemplate))

	restartCond := desc.Restart.String()
	if restartCond == "" {
		restartCond = RestartOnFailure.String()
	}

	wrapperData := struct {
		// the service description
		ServiceDescription
		// and some composed values
		FullPathStart        string
		FullPathStop         string
		FullPathPostStop     string
		ServiceSystemdTarget string
		SnapArch             string
		Home                 string
		EnvVars              string
		SocketFileName       string
		Restart              string
		Type                 string
	}{
		*desc,
		filepath.Join(desc.SnapPath, desc.Start),
		filepath.Join(desc.SnapPath, desc.Stop),
		filepath.Join(desc.SnapPath, desc.PostStop),
		servicesSystemdTarget,
		arch.UbuntuArchitecture(),
		// systemd runs as PID 1 so %h will not work.
		"/root",
		"",
		desc.SocketFileName,
		restartCond,
		desc.Type,
	}
	allVars := snapenv.GetBasicSnapEnvVars(wrapperData)
	allVars = append(allVars, snapenv.GetUserSnapEnvVars(wrapperData)...)
	wrapperData.EnvVars = "\"" + strings.Join(allVars, "\" \"") + "\"" // allVars won't be empty

	if err := t.Execute(&templateOut, wrapperData); err != nil {
		// this can never happen, except we forget a variable
		logger.Panicf("Unable to execute template: %v", err)
	}

	return templateOut.String()
}
Example #3
0
func generateSnapBinaryWrapper(app *snap.AppInfo, pkgPath string) (string, error) {
	wrapperTemplate := `#!/bin/sh
set -e

# snap info
{{.NewAppVars}}

if [ ! -d "$SNAP_USER_DATA" ]; then
   mkdir -p "$SNAP_USER_DATA"
fi
export HOME="$SNAP_USER_DATA"

# Snap name is: {{.SnapName}}
# App name is: {{.AppName}}

ubuntu-core-launcher {{.UdevAppName}} {{.AaProfile}} {{.Target}} "[email protected]"
`

	if err := snap.ValidateApp(app); err != nil {
		return "", err
	}

	actualBinPath := binPathForBinary(pkgPath, app)

	var templateOut bytes.Buffer
	t := template.Must(template.New("wrapper").Parse(wrapperTemplate))
	wrapperData := struct {
		SnapName    string
		AppName     string
		SnapArch    string
		SnapPath    string
		Version     string
		Revision    int
		UdevAppName string
		Home        string
		Target      string
		AaProfile   string
		OldAppVars  string
		NewAppVars  string
	}{
		SnapName:    app.Snap.Name(),
		AppName:     app.Name,
		SnapArch:    arch.UbuntuArchitecture(),
		SnapPath:    pkgPath,
		Version:     app.Snap.Version,
		Revision:    app.Snap.Revision,
		UdevAppName: app.SecurityTag(),
		Home:        "$HOME",
		Target:      actualBinPath,
		AaProfile:   app.SecurityTag(),
	}

	newVars := []string{}
	for _, envVar := range append(
		snapenv.GetBasicSnapEnvVars(wrapperData),
		snapenv.GetUserSnapEnvVars(wrapperData)...) {
		newVars = append(newVars, quoteEnvVar(envVar))
	}
	wrapperData.NewAppVars = strings.Join(newVars, "\n")

	t.Execute(&templateOut, wrapperData)

	return templateOut.String(), nil
}