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  }