go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/services/upstart.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package services
     5  
     6  import (
     7  	"bufio"
     8  	"io"
     9  	"regexp"
    10  
    11  	"github.com/rs/zerolog/log"
    12  )
    13  
    14  // see https://wiki.ubuntu.com/SystemdForUpstartUsers
    15  type UpstartServiceManager struct {
    16  	SysVServiceManager
    17  }
    18  
    19  func (s *UpstartServiceManager) Name() string {
    20  	return "Upstart Service Manager"
    21  }
    22  
    23  func (s *UpstartServiceManager) List() ([]*Service, error) {
    24  	// gather sysv-managed services
    25  	sysvservices, err := s.SysVServiceManager.List()
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  
    30  	// gather upstart-managed services
    31  	upstartservices, err := s.upstartservices()
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	services := []*Service{}
    37  
    38  	for k := range upstartservices {
    39  		services = append(services, upstartservices[k])
    40  	}
    41  
    42  	// some services are listed in upstart and sysv, we are filtering them here
    43  	for i := range sysvservices {
    44  		srv := sysvservices[i]
    45  
    46  		_, ok := upstartservices[srv.Name]
    47  		if ok {
    48  			// ignore sysv entry
    49  			continue
    50  		}
    51  
    52  		services = append(services, srv)
    53  	}
    54  
    55  	return services, nil
    56  }
    57  
    58  func (s *UpstartServiceManager) upstartservices() (map[string]*Service, error) {
    59  	// NOTE: without /sbin prefix this command would fail on Amazon Linux 1
    60  	c, err := s.conn.RunCommand("/sbin/initctl list")
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	return ParseUpstartServices(c.Stdout)
    65  }
    66  
    67  var upstartServiceRegex = regexp.MustCompile(`^(.*?)\s(stop/waiting|start/running)(?:, process (\d+)){0,1}$`)
    68  
    69  func ParseUpstartServices(r io.Reader) (map[string]*Service, error) {
    70  	res := map[string]*Service{}
    71  
    72  	scanner := bufio.NewScanner(r)
    73  	for scanner.Scan() {
    74  		line := scanner.Text()
    75  		m := upstartServiceRegex.FindStringSubmatch(line)
    76  		if len(m) != 4 {
    77  			log.Error().Str("line", line).Msg("cannot parse upstart service")
    78  			continue
    79  		}
    80  
    81  		service := m[1]
    82  		srv := &Service{
    83  			Name:      service,
    84  			Enabled:   true,
    85  			Installed: true,
    86  			Running:   m[2] == "start/running",
    87  			Type:      "upstart",
    88  		}
    89  
    90  		res[service] = srv
    91  	}
    92  
    93  	return res, nil
    94  }