github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/windows/service/service_windows.go (about) 1 package service 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 8 "github.com/juju/loggo" 9 "launchpad.net/juju-core/utils/exec" 10 ) 11 12 var logger = loggo.GetLogger("juju.worker.deployer.service_windows") 13 14 type Cmd struct { 15 Service 16 Description string 17 ServiceBin string 18 Cmd string 19 } 20 21 type Service struct { 22 Name string 23 } 24 25 // gets the service status 26 func (s *Service) Status() (string, error){ 27 logger.Infof("checking unit %q", s.Name) 28 cmd := []string{ 29 "powershell", 30 "Invoke-Command {", 31 fmt.Sprintf(`$x = Get-Service "%s"`, s.Name), 32 exec.CheckError, 33 "$x.Status", 34 "}", 35 } 36 out, err := exec.RunCommand(cmd) 37 logger.Infof("checking unit %v --> %v", out, err) 38 if err != nil { 39 return "", err 40 } 41 return out, nil 42 } 43 44 func (s *Service) Running() bool{ 45 status, err := s.Status() 46 logger.Infof("Service %q Status %q", s.Name, status) 47 if err != nil { 48 return false 49 } 50 if strings.TrimSpace(status) == "Stopped" { 51 return false 52 } 53 return true 54 } 55 56 func (s *Service) Installed() bool { 57 _, err := s.Status() 58 if err == nil { 59 return true 60 } 61 return false 62 } 63 64 func (s *Service) Start() error { 65 logger.Infof("Starting service %q", s.Name) 66 if s.Running() { 67 logger.Infof("Service %q ALREADY RUNNING", s.Name) 68 return nil 69 } 70 cmd := []string{ 71 "powershell", 72 "Invoke-Command {", 73 fmt.Sprintf(`Start-Service "%s"`, s.Name), 74 exec.CheckError, 75 "}", 76 } 77 _, err := exec.RunCommand(cmd) 78 logger.Infof("--> Starting service %q", err) 79 if err != nil { 80 return err 81 } 82 return nil 83 } 84 85 func (s *Service) Stop() error { 86 if !s.Running() { 87 return nil 88 } 89 cmd := []string{ 90 "powershell", 91 "Invoke-Command {", 92 fmt.Sprintf(`Stop-Service "%s"`, s.Name), 93 exec.CheckError, 94 "}", 95 } 96 _, err := exec.RunCommand(cmd) 97 if err != nil { 98 return err 99 } 100 return nil 101 } 102 103 func (s *Service) Remove() error { 104 _, err := s.Status() 105 if err != nil { 106 return err 107 } 108 cmd := []string{ 109 "powershell", 110 "Invoke-Command {", 111 fmt.Sprintf(`$x = gwmi win32_service -filter 'name="%s"'`, s.Name), 112 exec.CheckError, 113 "$x.Delete()", 114 exec.CheckError, 115 "}", 116 } 117 _, errCmd := exec.RunCommand(cmd) 118 if errCmd != nil { 119 return errCmd 120 } 121 return nil 122 } 123 124 func (c *Cmd) validate() error { 125 if c.ServiceBin == "" { 126 return errors.New("missing Service") 127 } 128 if c.Cmd == "" { 129 return errors.New("missing Cmd") 130 } 131 if c.Description == "" { 132 return errors.New("missing Description") 133 } 134 if c.Name == "" { 135 return errors.New("missing Name") 136 } 137 return nil 138 } 139 140 func (c *Cmd) Install() error{ 141 err := c.validate() 142 if err != nil { 143 return err 144 } 145 if c.Service.Installed(){ 146 return errors.New(fmt.Sprintf("Service %s already installed", c.Service.Name)) 147 } 148 logger.Infof("Installing Service %v", c.Service.Name) 149 serviceString := fmt.Sprintf(`"%s" "%s" %s`, c.ServiceBin, c.Service.Name, c.Cmd) 150 cmd := []string{ 151 "powershell", 152 "Invoke-Command {", 153 fmt.Sprintf(`$data = Get-Content C:\Juju\Jujud.pass`), 154 exec.CheckError, 155 fmt.Sprintf(`$secpasswd = $data | convertto-securestring`), 156 exec.CheckError, 157 fmt.Sprintf(`$juju_user = whoami`), 158 exec.CheckError, 159 fmt.Sprintf(`$jujuCreds = New-Object System.Management.Automation.PSCredential($juju_user, $secpasswd)`), 160 exec.CheckError, 161 fmt.Sprintf(`New-Service -Credential $jujuCreds -Name '%s' -DisplayName '%s' '%s'`, c.Service.Name, c.Description, serviceString), 162 exec.CheckError, 163 "}", 164 } 165 outCmd, errCmd := exec.RunCommand(cmd) 166 logger.Infof("ERROR installing service %v --> %v", outCmd, errCmd) 167 if errCmd != nil { 168 return errCmd 169 } 170 return c.Service.Start() 171 } 172 173 func (s *Service) StopAndRemove() error { 174 err := s.Stop() 175 if err != nil { 176 return err 177 } 178 return s.Remove() 179 } 180 181 func NewService(name string) *Service{ 182 return &Service{ 183 Name: name, 184 } 185 }