mirror of
https://github.com/AlchemillaHQ/Sylve.git
synced 2026-06-24 02:27:19 +03:00
159 lines
3.9 KiB
Go
159 lines
3.9 KiB
Go
// SPDX-License-Identifier: BSD-2-Clause
|
|
//
|
|
// Copyright (c) 2025 The FreeBSD Foundation.
|
|
//
|
|
// This software was developed by Hayzam Sherif <hayzam@alchemilla.io>
|
|
// of Alchemilla Ventures Pvt. Ltd. <hello@alchemilla.io>,
|
|
// under sponsorship from the FreeBSD Foundation.
|
|
|
|
package system
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/alchemillahq/gzfs"
|
|
"github.com/alchemillahq/sylve/internal/db/models"
|
|
systemServiceInterfaces "github.com/alchemillahq/sylve/internal/interfaces/services/system"
|
|
"github.com/alchemillahq/sylve/internal/logger"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func (s *Service) GetUsablePools(ctx context.Context) ([]*gzfs.ZPool, error) {
|
|
var basicSettings models.BasicSettings
|
|
var pools []*gzfs.ZPool
|
|
|
|
if err := s.DB.First(&basicSettings).Error; err != nil {
|
|
return pools, err
|
|
}
|
|
|
|
for _, name := range basicSettings.Pools {
|
|
pool, err := s.GZFS.Zpool.Get(ctx, name)
|
|
if err != nil {
|
|
return pools, err
|
|
}
|
|
|
|
pools = append(pools, pool)
|
|
}
|
|
|
|
return pools, nil
|
|
}
|
|
|
|
func (s *Service) Initialize(ctx context.Context, req systemServiceInterfaces.InitializeRequest) []error {
|
|
var basicSettings models.BasicSettings
|
|
err := s.DB.First(&basicSettings).Error
|
|
|
|
if err != nil {
|
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return []error{err}
|
|
}
|
|
basicSettings = models.BasicSettings{}
|
|
}
|
|
|
|
if basicSettings.Initialized {
|
|
return []error{fmt.Errorf("system_already_initialized")}
|
|
}
|
|
|
|
var newSets []*gzfs.Dataset
|
|
|
|
for _, poolName := range req.Pools {
|
|
pool, err := s.GZFS.Zpool.Get(ctx, poolName)
|
|
if err != nil {
|
|
return []error{fmt.Errorf("invalid_pool_%s: %w", poolName, err)}
|
|
}
|
|
|
|
if pool == nil {
|
|
return []error{fmt.Errorf("pool_not_found_%s", poolName)}
|
|
}
|
|
|
|
created, err := s.ensureSylveDatasetsOnPool(ctx, pool.Name)
|
|
if err != nil {
|
|
for i := len(newSets) - 1; i >= 0; i-- {
|
|
newSets[i].Destroy(ctx, true, false)
|
|
}
|
|
|
|
return []error{err}
|
|
}
|
|
|
|
newSets = append(newSets, created...)
|
|
}
|
|
|
|
var errs []error
|
|
|
|
if !s.IsSupportedArch() {
|
|
errs = append(errs, fmt.Errorf("unsupported_architecture"))
|
|
}
|
|
|
|
for _, service := range req.Services {
|
|
if service == models.Virtualization {
|
|
if err := s.CheckVirtualization(); err != nil {
|
|
errs = append(errs, fmt.Errorf("virtualization_check_failed: %w", err))
|
|
}
|
|
}
|
|
|
|
if service == models.Jails {
|
|
if err := s.CheckJails(); err != nil {
|
|
if err.Error() == "jails_racct_not_enabled" {
|
|
updated, updateErr := s.ensureJailRacctEnabledAtBoot()
|
|
if updateErr != nil {
|
|
errs = append(errs, fmt.Errorf("jails_check_failed: jails_racct_autoconfig_failed: %w", updateErr))
|
|
continue
|
|
}
|
|
|
|
if updated {
|
|
logger.L.Warn().Msg("jails_racct_auto_configured_in_loader_conf_reboot_required")
|
|
} else {
|
|
logger.L.Warn().Msg("jails_racct_not_enabled_runtime_loader_conf_already_set_reboot_required")
|
|
}
|
|
|
|
continue
|
|
}
|
|
|
|
errs = append(errs, fmt.Errorf("jails_check_failed: %w", err))
|
|
}
|
|
}
|
|
|
|
if service == models.DHCPServer {
|
|
if err := s.CheckDHCPServer(); err != nil {
|
|
errs = append(errs, fmt.Errorf("dhcp_server_check_failed: %w", err))
|
|
}
|
|
}
|
|
|
|
if service == models.SambaServer {
|
|
if err := s.CheckSambaServer(); err != nil {
|
|
errs = append(errs, fmt.Errorf("samba_server_check_failed: %w", err))
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(errs) > 0 {
|
|
return errs
|
|
}
|
|
|
|
basicSettings.Pools = req.Pools
|
|
basicSettings.Services = req.Services
|
|
basicSettings.Initialized = true
|
|
basicSettings.Restarted = false
|
|
|
|
if err := s.DB.Create(&basicSettings).Error; err != nil {
|
|
return []error{fmt.Errorf("failed_to_create_basic_settings: %w", err)}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) GetBasicSettings() (models.BasicSettings, error) {
|
|
var settings models.BasicSettings
|
|
if err := s.DB.First(&settings).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return settings, fmt.Errorf("basic_settings_not_found")
|
|
}
|
|
|
|
return settings, fmt.Errorf("failed_to_fetch_basic_settings: %v", err)
|
|
}
|
|
|
|
return settings, nil
|
|
}
|