Compare commits
4 Commits
d131c55351
...
ec92777135
Author | SHA1 | Date | |
---|---|---|---|
ec92777135 | |||
f59dc1b7ce | |||
70df28d90e | |||
c639daca5a |
@ -55,10 +55,43 @@ func main() {
|
||||
func mountVirtualFilesystems() {
|
||||
fmt.Print("Mounting virtual filesystems... ")
|
||||
|
||||
commonFlags := uintptr(0 | syscall.MS_NOSUID | syscall.MS_RELATIME)
|
||||
// Mount /proc
|
||||
if err := syscall.Mount("proc", "/proc", "proc", commonFlags|syscall.MS_NODEV|syscall.MS_NOEXEC|syscall.MS_REMOUNT, ""); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Mount /sys
|
||||
if err := syscall.Mount("sys", "/sys", "sysfs", commonFlags|syscall.MS_NODEV|syscall.MS_NOEXEC|syscall.MS_REMOUNT, ""); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Mount /dev
|
||||
if err := syscall.Mount("dev", "/dev", "devtmpfs", commonFlags|syscall.MS_REMOUNT, "mode=755,inode64"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Mount /run
|
||||
if err := syscall.Mount("run", "/run", "tmpfs", commonFlags|syscall.MS_NODEV|syscall.MS_REMOUNT, "mode=755,inode64"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Mount /dev/pts
|
||||
if err := os.Mkdir("/dev/pts", 0755); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := syscall.Mount("none", "/dev/pts", "devpts", syscall.MS_NOSUID|syscall.MS_NOEXEC, ""); err != nil {
|
||||
if err := syscall.Mount("devpts", "/dev/pts", "devpts", commonFlags, "gid=5,mode=620,ptmxmode=000"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Mount /dev/shm
|
||||
if err := os.Mkdir("/dev/shm", 0755); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := syscall.Mount("shm", "/dev/shm", "tmpfs", commonFlags|syscall.MS_NODEV, "inode64"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Mount securityfs
|
||||
if err := syscall.Mount("securityfs", "/sys/kernel/security", "securityfs", commonFlags, ""); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Mount cgroups v2
|
||||
if err := syscall.Mount("cgroup2", "/sys/fs/cgroup", "cgroup2", commonFlags|syscall.MS_NOEXEC, ""); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,14 @@ const (
|
||||
type EnitService struct {
|
||||
Name string `yaml:"name"`
|
||||
Description string `yaml:"description,omitempty"`
|
||||
Dependencies []string `yaml:"dependencies,omitempty"`
|
||||
Type string `yaml:"type"`
|
||||
StartCmd string `yaml:"start_cmd"`
|
||||
ExitMethod string `yaml:"exit_method"`
|
||||
StopCmd string `yaml:"stop_cmd,omitempty"`
|
||||
Restart bool `yaml:"restart,omitempty"`
|
||||
ServiceRunPath string
|
||||
restartCount int
|
||||
stopChannel chan bool
|
||||
}
|
||||
|
||||
@ -124,6 +126,7 @@ func Init() {
|
||||
logger.Fatalf("Could not initialize ESVM! Error: %s", err)
|
||||
}
|
||||
|
||||
// Read and initialize service files
|
||||
for _, entry := range dirEntries {
|
||||
if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".esv") {
|
||||
logger.Printf("Initializing service (%s)...\n", entry.Name())
|
||||
@ -136,12 +139,14 @@ func Init() {
|
||||
service := EnitService{
|
||||
Name: "",
|
||||
Description: "",
|
||||
Dependencies: make([]string, 0),
|
||||
Type: "",
|
||||
StartCmd: "",
|
||||
ExitMethod: "",
|
||||
StopCmd: "",
|
||||
Restart: false,
|
||||
ServiceRunPath: "",
|
||||
restartCount: 0,
|
||||
stopChannel: make(chan bool),
|
||||
}
|
||||
if err := yaml.Unmarshal(bytes, &service); err != nil {
|
||||
@ -176,11 +181,46 @@ func Init() {
|
||||
|
||||
Services = append(Services, service)
|
||||
|
||||
if err := service.StartService(); err != nil {
|
||||
logger.Printf("Could not start service %s: %s\n", service.Name, err)
|
||||
logger.Printf("Service (%s) has been initialized!\n", service.Name)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Printf("Service (%s) has been initialized!\n", service.Name)
|
||||
// Get services that meet their dependencies
|
||||
servicesWithMetDepends := make([]EnitService, 0)
|
||||
for _, service := range Services {
|
||||
if len(service.GetUnmetDependencies()) == 0 {
|
||||
servicesWithMetDepends = append(servicesWithMetDepends, service)
|
||||
}
|
||||
}
|
||||
|
||||
// Loop until all services have started or timed out
|
||||
for start := time.Now(); time.Since(start) < 60*time.Second; {
|
||||
if len(servicesWithMetDepends) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
for i := len(servicesWithMetDepends) - 1; i >= 0; i-- {
|
||||
service := servicesWithMetDepends[i]
|
||||
canStart := true
|
||||
for _, dependency := range service.Dependencies {
|
||||
if GetServiceByName(dependency).GetCurrentState() != EnitServiceRunning && GetServiceByName(dependency).GetCurrentState() != EnitServiceCompleted {
|
||||
canStart = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if canStart {
|
||||
err := service.StartService()
|
||||
if err != nil {
|
||||
logger.Printf("Could not start service (%s)! Error: %s", service.Name, err)
|
||||
}
|
||||
servicesWithMetDepends = append(servicesWithMetDepends[:i], servicesWithMetDepends[i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(servicesWithMetDepends) > 0 {
|
||||
for _, service := range servicesWithMetDepends {
|
||||
logger.Printf("Could not start service (%s)! Error: dependencies not met", service.Name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,6 +246,17 @@ func GetServiceByName(name string) *EnitService {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service *EnitService) GetUnmetDependencies() (missingDependencies []string) {
|
||||
for _, dependency := range service.Dependencies {
|
||||
depService := GetServiceByName(dependency)
|
||||
if depService == nil {
|
||||
missingDependencies = append(missingDependencies, dependency)
|
||||
}
|
||||
}
|
||||
|
||||
return missingDependencies
|
||||
}
|
||||
|
||||
func (service *EnitService) GetProcess() *os.Process {
|
||||
bytes, err := os.ReadFile(path.Join(service.ServiceRunPath, "process"))
|
||||
if err != nil {
|
||||
@ -281,15 +332,19 @@ func (service *EnitService) StartService() error {
|
||||
err := cmd.Wait()
|
||||
select {
|
||||
case <-service.stopChannel:
|
||||
service.restartCount = 0
|
||||
_ = service.setCurrentState(EnitServiceStopped)
|
||||
default:
|
||||
if service.Type == "simple" && err == nil {
|
||||
service.restartCount = 0
|
||||
_ = service.setCurrentState(EnitServiceCompleted)
|
||||
return
|
||||
}
|
||||
logger.Printf("Service (%s) has crashed!\n", service.Name)
|
||||
_ = service.setCurrentState(EnitServiceCrashed)
|
||||
|
||||
if service.Restart {
|
||||
if service.Restart && service.restartCount < 5 {
|
||||
service.restartCount++
|
||||
_ = service.StartService()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user