github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/cmd/snap/cmd_userd.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 // +build !darwin 3 4 /* 5 * Copyright (C) 2017-2019 Canonical Ltd 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 3 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 package main 22 23 import ( 24 "fmt" 25 "os" 26 "os/signal" 27 "syscall" 28 29 "github.com/jessevdk/go-flags" 30 31 "github.com/snapcore/snapd/i18n" 32 "github.com/snapcore/snapd/snapdtool" 33 "github.com/snapcore/snapd/usersession/agent" 34 "github.com/snapcore/snapd/usersession/autostart" 35 "github.com/snapcore/snapd/usersession/userd" 36 ) 37 38 type cmdUserd struct { 39 Autostart bool `long:"autostart"` 40 Agent bool `long:"agent"` 41 } 42 43 var shortUserdHelp = i18n.G("Start the userd service") 44 var longUserdHelp = i18n.G(` 45 The userd command starts the snap user session service. 46 `) 47 48 func init() { 49 cmd := addCommand("userd", 50 shortUserdHelp, 51 longUserdHelp, 52 func() flags.Commander { 53 return &cmdUserd{} 54 }, map[string]string{ 55 // TRANSLATORS: This should not start with a lowercase letter. 56 "autostart": i18n.G("Autostart user applications"), 57 // TRANSLATORS: This should not start with a lowercase letter. 58 "agent": i18n.G("Run the user session agent"), 59 }, nil) 60 cmd.hidden = true 61 } 62 63 func (x *cmdUserd) Execute(args []string) error { 64 if len(args) > 0 { 65 return ErrExtraArgs 66 } 67 68 if x.Autostart { 69 return x.runAutostart() 70 } 71 72 if x.Agent { 73 return x.runAgent() 74 } 75 76 return x.runUserd() 77 } 78 79 var signalNotify = signalNotifyImpl 80 81 func (x *cmdUserd) runUserd() error { 82 var userd userd.Userd 83 if err := userd.Init(); err != nil { 84 return err 85 } 86 userd.Start() 87 88 ch, stop := signalNotify(syscall.SIGINT, syscall.SIGTERM) 89 defer stop() 90 91 select { 92 case sig := <-ch: 93 fmt.Fprintf(Stdout, "Exiting on %s.\n", sig) 94 case <-userd.Dying(): 95 // something called Stop() 96 } 97 98 return userd.Stop() 99 } 100 101 func (x *cmdUserd) runAgent() error { 102 agent, err := agent.New() 103 if err != nil { 104 return err 105 } 106 agent.Version = snapdtool.Version 107 agent.Start() 108 109 ch, stop := signalNotify(syscall.SIGINT, syscall.SIGTERM) 110 defer stop() 111 112 select { 113 case sig := <-ch: 114 fmt.Fprintf(Stdout, "Exiting on %s.\n", sig) 115 case <-agent.Dying(): 116 // something called Stop() 117 } 118 119 return agent.Stop() 120 } 121 122 func (x *cmdUserd) runAutostart() error { 123 if err := autostart.AutostartSessionApps(); err != nil { 124 return fmt.Errorf("autostart failed for the following apps:\n%v", err) 125 } 126 return nil 127 } 128 129 func signalNotifyImpl(sig ...os.Signal) (ch chan os.Signal, stop func()) { 130 ch = make(chan os.Signal, len(sig)) 131 signal.Notify(ch, sig...) 132 stop = func() { signal.Stop(ch) } 133 return ch, stop 134 }