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() }
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 }