gopkg.in/ubuntu-core/snappy.v0@v0.0.0-20210902073436-25a8614f10a6/overlord/hookstate/ctlcmd/services.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package ctlcmd 21 22 import ( 23 "fmt" 24 "sort" 25 "text/tabwriter" 26 27 "github.com/snapcore/snapd/client/clientutil" 28 "github.com/snapcore/snapd/i18n" 29 "github.com/snapcore/snapd/overlord/servicestate" 30 "github.com/snapcore/snapd/progress" 31 "github.com/snapcore/snapd/snap" 32 ) 33 34 var ( 35 shortServicesHelp = i18n.G("Query the status of services") 36 longServicesHelp = i18n.G(` 37 The services command lists information about the services specified. 38 `) 39 ) 40 41 func init() { 42 addCommand("services", shortServicesHelp, longServicesHelp, func() command { return &servicesCommand{} }) 43 } 44 45 type servicesCommand struct { 46 baseCommand 47 Positional struct { 48 ServiceNames []string `positional-arg-name:"<service>"` 49 } `positional-args:"yes"` 50 } 51 52 type byApp []*snap.AppInfo 53 54 func (a byApp) Len() int { return len(a) } 55 func (a byApp) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 56 func (a byApp) Less(i, j int) bool { 57 return a[i].Name < a[j].Name 58 } 59 60 func (c *servicesCommand) Execute([]string) error { 61 context, err := c.ensureContext() 62 if err != nil { 63 return err 64 } 65 66 st := context.State() 67 svcInfos, err := getServiceInfos(st, context.InstanceName(), c.Positional.ServiceNames) 68 if err != nil { 69 return err 70 } 71 sort.Sort(byApp(svcInfos)) 72 73 sd := servicestate.NewStatusDecorator(progress.Null) 74 75 services, err := clientutil.ClientAppInfosFromSnapAppInfos(svcInfos, sd) 76 if err != nil || len(services) == 0 { 77 return err 78 } 79 80 w := tabwriter.NewWriter(c.stdout, 5, 3, 2, ' ', 0) 81 defer w.Flush() 82 83 fmt.Fprintln(w, i18n.G("Service\tStartup\tCurrent\tNotes")) 84 85 for _, svc := range services { 86 startup := i18n.G("disabled") 87 if svc.Enabled { 88 startup = i18n.G("enabled") 89 } 90 current := i18n.G("inactive") 91 if svc.DaemonScope == snap.UserDaemon { 92 current = "-" 93 } else if svc.Active { 94 current = i18n.G("active") 95 } 96 fmt.Fprintf(w, "%s.%s\t%s\t%s\t%s\n", svc.Snap, svc.Name, startup, current, clientutil.ClientAppInfoNotes(&svc)) 97 } 98 99 return nil 100 }