github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/nodeagent/dep/health/dep.go (about) 1 package health 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "regexp" 9 "strings" 10 11 "github.com/caos/orbos/internal/operator/nodeagent/dep" 12 13 "github.com/caos/orbos/internal/operator/common" 14 "github.com/caos/orbos/internal/operator/nodeagent" 15 "github.com/caos/orbos/internal/operator/nodeagent/dep/middleware" 16 "github.com/caos/orbos/mntr" 17 ) 18 19 const dir string = "/lib/systemd/system" 20 21 type Installer interface { 22 isHealth() 23 nodeagent.Installer 24 } 25 type healthDep struct { 26 monitor mntr.Monitor 27 systemd *dep.SystemD 28 } 29 30 func New(monitor mntr.Monitor, systemd *dep.SystemD) Installer { 31 return &healthDep{monitor: monitor, systemd: systemd} 32 } 33 34 func (healthDep) isHealth() {} 35 36 func (healthDep) Is(other nodeagent.Installer) bool { 37 _, ok := middleware.Unwrap(other).(Installer) 38 return ok 39 } 40 41 func (healthDep) String() string { return "health" } 42 43 func (*healthDep) Equals(other nodeagent.Installer) bool { 44 _, ok := other.(*healthDep) 45 return ok 46 } 47 func (*healthDep) InstalledFilter() []string { return nil } 48 49 var r = regexp.MustCompile(`ExecStart=/usr/local/bin/health --listen ([^\s]+) (.*)`) 50 51 func (s *healthDep) Current() (pkg common.Package, err error) { 52 53 files, _ := ioutil.ReadDir(dir) 54 for _, file := range files { 55 if !strings.HasPrefix(file.Name(), "orbos.health.") { 56 continue 57 } 58 content, err := ioutil.ReadFile(filepath.Join(dir, file.Name())) 59 if err != nil { 60 return pkg, err 61 } 62 63 if pkg.Config == nil { 64 pkg.Config = make(map[string]string) 65 } 66 67 if s.systemd.Active(file.Name()) { 68 http, checks := extractArguments(content) 69 pkg.Config[http] = unquote(checks) 70 } 71 } 72 return pkg, nil 73 } 74 75 func extractArguments(content []byte) (string, string) { 76 match := r.FindStringSubmatch(string(content)) 77 return match[1], match[2] 78 } 79 80 func (s *healthDep) Ensure(_ common.Package, ensure common.Package, _ bool) error { 81 82 files, _ := ioutil.ReadDir(dir) 83 for _, file := range files { 84 if strings.HasPrefix(file.Name(), "orbos.health.") { 85 if err := s.systemd.Disable(file.Name()); err != nil { 86 return err 87 } 88 if err := os.Remove(filepath.Join(dir, file.Name())); err != nil { 89 return err 90 } 91 } 92 } 93 94 var i int 95 for location, args := range ensure.Config { 96 i++ 97 svc := fmt.Sprintf("orbos.health.%d.service", i) 98 if err := ioutil.WriteFile(filepath.Join(dir, svc), []byte(fmt.Sprintf(` 99 [Unit] 100 Description=Healthchecks Proxy 101 After=network.target 102 103 [Service] 104 Type=simple 105 User=root 106 ExecStart=/usr/local/bin/health --listen %s %s 107 Restart=always 108 MemoryLimit=20M 109 MemoryAccounting=yes 110 RestartSec=10 111 CPUAccounting=yes 112 113 [Install] 114 WantedBy=multi-user.target 115 `, location, quote(args))), 0644); err != nil { 116 return err 117 } 118 119 if err := s.systemd.Enable(svc); err != nil { 120 return err 121 } 122 if err := s.systemd.Start(svc); err != nil { 123 return err 124 } 125 } 126 127 return nil 128 } 129 130 func unquote(args string) string { 131 s := strings.Split(args, " ") 132 for idx, a := range s { 133 s[idx] = strings.Trim(a, `"`) 134 } 135 return strings.Join(s, " ") 136 } 137 138 func quote(args string) string { 139 s := strings.Split(args, " ") 140 for idx, a := range s { 141 s[idx] = fmt.Sprintf(`"%s"`, a) 142 } 143 return strings.Join(s, " ") 144 }