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(part *SnapPart) (env []string) {
	desc := struct {
		AppName     string
		AppArch     string
		AppPath     string
		Version     string
		UdevAppName string
		Origin      string
	}{
		part.Name(),
		arch.UbuntuArchitecture(),
		part.basedir,
		part.Version(),
		QualifiedName(part),
		part.Origin(),
	}

	vars := helpers.GetBasicSnapEnvVars(desc)
	vars = append(vars, helpers.GetDeprecatedBasicSnapEnvVars(desc)...)
	snapEnv := helpers.MakeMapFromEnvList(vars)

	// merge regular env and new snapEnv
	envMap := helpers.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}}
{{if .IsFramework}}Before=ubuntu-snappy.frameworks.target
After=ubuntu-snappy.frameworks-pre.target{{ if .Socket }} {{.SocketFileName}}{{end}}
Requires=ubuntu-snappy.frameworks-pre.target{{ if .Socket }} {{.SocketFileName}}{{end}}{{else}}After=ubuntu-snappy.frameworks.target{{ if .Socket }} {{.SocketFileName}}{{end}}
Requires=ubuntu-snappy.frameworks.target{{ if .Socket }} {{.SocketFileName}}{{end}}{{end}}{{if .IsNetworked}}
After=snappy-wait4network.service
Requires=snappy-wait4network.service{{end}}
X-Snappy=yes

[Service]
ExecStart=/usr/bin/ubuntu-core-launcher {{.UdevAppName}} {{.AaProfile}} {{.FullPathStart}}
Restart=on-failure
WorkingDirectory={{.AppPath}}
Environment="SNAP_APP={{.AppTriple}}" {{.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}}
{{if .BusName}}BusName={{.BusName}}
Type=dbus{{else}}{{if .Forking}}Type=forking{{end}}
{{end}}

[Install]
WantedBy={{.ServiceSystemdTarget}}
`
	var templateOut bytes.Buffer
	t := template.Must(template.New("wrapper").Parse(serviceTemplate))
	origin := ""
	if len(desc.UdevAppName) > len(desc.AppName) {
		origin = desc.UdevAppName[len(desc.AppName)+1:]
	}
	wrapperData := struct {
		// the service description
		ServiceDescription
		// and some composed values
		FullPathStart        string
		FullPathStop         string
		FullPathPostStop     string
		AppTriple            string
		ServiceSystemdTarget string
		Origin               string
		AppArch              string
		Home                 string
		EnvVars              string
		SocketFileName       string
	}{
		*desc,
		filepath.Join(desc.AppPath, desc.Start),
		filepath.Join(desc.AppPath, desc.Stop),
		filepath.Join(desc.AppPath, desc.PostStop),
		fmt.Sprintf("%s_%s_%s", desc.AppName, desc.ServiceName, desc.Version),
		servicesSystemdTarget,
		origin,
		helpers.UbuntuArchitecture(),
		"%h",
		"",
		desc.SocketFileName,
	}
	allVars := helpers.GetBasicSnapEnvVars(wrapperData)
	allVars = append(allVars, helpers.GetUserSnapEnvVars(wrapperData)...)
	allVars = append(allVars, helpers.GetDeprecatedBasicSnapEnvVars(wrapperData)...)
	allVars = append(allVars, helpers.GetDeprecatedUserSnapEnvVars(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 *AppYaml, pkgPath, aaProfile string, m *snapYaml) (string, error) {
	wrapperTemplate := `#!/bin/sh
set -e

# app info (deprecated)
{{.OldAppVars}}

# app info
{{.NewAppVars}}

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

# export old pwd
export SNAP_OLD_PWD="$(pwd)"
cd {{.AppPath}}
ubuntu-core-launcher {{.UdevAppName}} {{.AaProfile}} {{.Target}} "$@"
`

	// it's fine for this to error out; we might be in a framework or sth
	origin := originFromBasedir(pkgPath)

	if err := verifyAppYaml(app); err != nil {
		return "", err
	}

	actualBinPath := binPathForBinary(pkgPath, app)
	udevPartName := m.qualifiedName(origin)

	var templateOut bytes.Buffer
	t := template.Must(template.New("wrapper").Parse(wrapperTemplate))
	wrapperData := struct {
		AppName     string
		AppArch     string
		AppPath     string
		Version     string
		UdevAppName string
		Origin      string
		Home        string
		Target      string
		AaProfile   string
		OldAppVars  string
		NewAppVars  string
	}{
		AppName:     m.Name,
		AppArch:     arch.UbuntuArchitecture(),
		AppPath:     pkgPath,
		Version:     m.Version,
		UdevAppName: udevPartName,
		Origin:      origin,
		Home:        "$HOME",
		Target:      actualBinPath,
		AaProfile:   aaProfile,
	}

	oldVars := []string{}
	for _, envVar := range append(
		helpers.GetDeprecatedBasicSnapEnvVars(wrapperData),
		helpers.GetDeprecatedUserSnapEnvVars(wrapperData)...) {
		oldVars = append(oldVars, quoteEnvVar(envVar))
	}
	wrapperData.OldAppVars = strings.Join(oldVars, "\n")

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

	t.Execute(&templateOut, wrapperData)

	return templateOut.String(), nil
}