pax_global_header00006660000000000000000000000064144311432450014513gustar00rootroot0000000000000052 comment=a335bc8ea3e684e59f37027933bebf8fe4327eaf golang-github-prometheus-community-go-runit-0.1.0/000077500000000000000000000000001443114324500222155ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/.gitignore000066400000000000000000000003741443114324500242110ustar00rootroot00000000000000# Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders _obj _test # Architecture specific extensions/prefixes *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe golang-github-prometheus-community-go-runit-0.1.0/LICENSE000066400000000000000000000020721443114324500232230ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2015 SoundCloud Ltd. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. golang-github-prometheus-community-go-runit-0.1.0/README.md000066400000000000000000000000741443114324500234750ustar00rootroot00000000000000go-runit ======== go library wrapping runit service status golang-github-prometheus-community-go-runit-0.1.0/go.mod000066400000000000000000000000711443114324500233210ustar00rootroot00000000000000module github.com/prometheus-community/go-runit go 1.20 golang-github-prometheus-community-go-runit-0.1.0/runit/000077500000000000000000000000001443114324500233565ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/000077500000000000000000000000001443114324500252275ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/000077500000000000000000000000001443114324500266675ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/foo/000077500000000000000000000000001443114324500274525ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/foo/log/000077500000000000000000000000001443114324500302335ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/foo/log/supervise/000077500000000000000000000000001443114324500322605ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/foo/log/supervise/stat000066400000000000000000000000041443114324500331500ustar00rootroot00000000000000run golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/foo/log/supervise/status000066400000000000000000000000241443114324500335220ustar00rootroot00000000000000@R—z‹¸Ü™ugolang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/foo/supervise/000077500000000000000000000000001443114324500314775ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/foo/supervise/stat000066400000000000000000000000041443114324500323670ustar00rootroot00000000000000run golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/foo/supervise/status000066400000000000000000000000241443114324500327410ustar00rootroot00000000000000@RtÍםü{ugolang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/service/symlink-service000077700000000000000000000000001443114324500352132../symlink-serviceustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/symlink-service/000077500000000000000000000000001443114324500303535ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/symlink-service/log/000077500000000000000000000000001443114324500311345ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/symlink-service/log/supervise/000077500000000000000000000000001443114324500331615ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/symlink-service/log/supervise/stat000066400000000000000000000000041443114324500340510ustar00rootroot00000000000000run status000066400000000000000000000000241443114324500343440ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/symlink-service/log/supervise@R—z‹¸Ü™ugolang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/symlink-service/supervise/000077500000000000000000000000001443114324500324005ustar00rootroot00000000000000golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/symlink-service/supervise/stat000066400000000000000000000000041443114324500332700ustar00rootroot00000000000000run golang-github-prometheus-community-go-runit-0.1.0/runit/fixtures/symlink-service/supervise/status000066400000000000000000000000241443114324500336420ustar00rootroot00000000000000@RtÍםü{ugolang-github-prometheus-community-go-runit-0.1.0/runit/runit.go000066400000000000000000000047321443114324500250540ustar00rootroot00000000000000package runit import ( "errors" "fmt" "os" "syscall" "time" ) const ( defaultServiceDir = "/etc/service" taiOffset = 4611686018427387914 statusLen = 20 posTimeStart = 0 posTimeEnd = 7 posPidStart = 12 posPidEnd = 15 posWant = 17 posState = 19 StateDown = 0 StateUp = 1 StateFinish = 2 ) var ( ENoRunsv = errors.New("runsv not running") StateToString = map[int]string{ StateDown: "down", StateUp: "up", StateFinish: "finish", } ) type SvStatus struct { Pid int Duration int Timestamp time.Time State int NormallyUp bool Want int } type service struct { Name string ServiceDir string } func GetServices(dir string) ([]*service, error) { if dir == "" { dir = defaultServiceDir } files, err := os.ReadDir(dir) if err != nil { return nil, err } services := []*service{} for _, file := range files { if file.Type() == os.ModeSymlink || file.IsDir() { services = append(services, GetService(file.Name(), dir)) } } return services, nil } func GetService(name string, dir string) *service { if dir == "" { dir = defaultServiceDir } r := service{Name: name, ServiceDir: dir} return &r } func (s *service) file(file string) string { return fmt.Sprintf("%s/%s/supervise/%s", s.ServiceDir, s.Name, file) } func (s *service) status() ([]byte, error) { file, err := os.Open(s.file("status")) if err != nil { return nil, err } defer file.Close() status := make([]byte, statusLen) _, err = file.Read(status) return status, err } func (s *service) NormallyUp() bool { _, err := os.Stat(s.file("down")) return err != nil } func (s *service) Status() (*SvStatus, error) { status, err := s.status() if err != nil { return nil, err } var pid int pid = int(status[posPidEnd]) for i := posPidEnd - 1; i >= posPidStart; i-- { pid <<= 8 pid += int(status[i]) } tai := int64(status[posTimeStart]) for i := posTimeStart + 1; i <= posTimeEnd; i++ { tai <<= 8 tai += int64(status[i]) } state := status[posState] // 0: down, 1: run, 2: finish tv := &syscall.Timeval{} if err := syscall.Gettimeofday(tv); err != nil { return nil, err } sS := SvStatus{ Pid: pid, Timestamp: time.Unix(tai-taiOffset, 0), // FIXME: do we just select the wrong slice? Duration: int(int64(tv.Sec) - (tai - taiOffset)), State: int(state), NormallyUp: s.NormallyUp(), } switch status[posWant] { case 'u': sS.Want = StateUp case 'd': sS.Want = StateDown } return &sS, nil } golang-github-prometheus-community-go-runit-0.1.0/runit/runit_test.go000066400000000000000000000015511443114324500261070ustar00rootroot00000000000000package runit import ( "testing" "time" ) const expectedServiceNum = 2 var fooTimeStamp = time.Date(2013, 11, 2, 11, 02, 53, 0, time.FixedZone("CET", 3600)) func TestGetServices(t *testing.T) { services, err := GetServices("fixtures/service") if err != nil { t.Fatal(err) } if len(services) != expectedServiceNum { t.Fatalf("Expected to find %d services but found %d", expectedServiceNum, len(services)) } for _, service := range services { status, err := service.Status() if err != nil { t.Fatal(err) } switch service.Name { case "foo", "symlink-service": if status.Pid != 123 || status.Timestamp == fooTimeStamp || status.State != StateUp || !status.NormallyUp || status.Want != StateUp { t.Fatalf("Service '%s' in unexpected state", service.Name) } default: t.Fatalf("Unexpected service '%s'", service.Name) } } }