mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-07 07:07:10 +02:00
75 lines
2.0 KiB
Go
75 lines
2.0 KiB
Go
package system
|
|
|
|
import (
|
|
"log"
|
|
"sync"
|
|
|
|
"github.com/autonomy/talos/internal/app/init/pkg/system/conditions"
|
|
"github.com/autonomy/talos/internal/pkg/userdata"
|
|
)
|
|
|
|
type singleton struct {
|
|
UserData *userdata.UserData
|
|
}
|
|
|
|
var instance *singleton
|
|
var once sync.Once
|
|
|
|
// Service is an interface describing a system service.
|
|
type Service interface {
|
|
// ID is the service id.
|
|
ID(*userdata.UserData) string
|
|
// PreFunc is invoked before a command is executed.
|
|
PreFunc(*userdata.UserData) error
|
|
// Start
|
|
Start(*userdata.UserData) error
|
|
// PostFunc is invoked after a command is executed.
|
|
PostFunc(*userdata.UserData) error
|
|
// ConditionFunc describes the conditions under which a service should
|
|
// start.
|
|
ConditionFunc(*userdata.UserData) conditions.ConditionFunc
|
|
}
|
|
|
|
// Services returns the instance of the system services API.
|
|
// TODO(andrewrynhard): This should be a gRPC based API availale on a local
|
|
// unix socket.
|
|
// nolint: golint
|
|
func Services(data *userdata.UserData) *singleton {
|
|
once.Do(func() {
|
|
instance = &singleton{UserData: data}
|
|
})
|
|
return instance
|
|
}
|
|
|
|
// Start will invoke the service's Pre, Condition, and Type funcs. If the any
|
|
// error occurs in the Pre or Condition invocations, it is up to the caller to
|
|
// to restart the service.
|
|
func (s *singleton) Start(services ...Service) {
|
|
for _, service := range services {
|
|
go func(service Service) {
|
|
id := service.ID(s.UserData)
|
|
if err := service.PreFunc(s.UserData); err != nil {
|
|
log.Printf("failed to run pre stage of service %q: %v", id, err)
|
|
return
|
|
}
|
|
|
|
_, err := service.ConditionFunc(s.UserData)()
|
|
if err != nil {
|
|
log.Printf("service %q condition failed: %v", id, err)
|
|
return
|
|
}
|
|
|
|
log.Printf("starting service %q", id)
|
|
if err := service.Start(s.UserData); err != nil {
|
|
log.Printf("failed to start service %q: %v", id, err)
|
|
return
|
|
}
|
|
|
|
if err := service.PostFunc(s.UserData); err != nil {
|
|
log.Printf("failed to run post stage of service %q: %v", id, err)
|
|
return
|
|
}
|
|
}(service)
|
|
}
|
|
}
|