428 lines
22 KiB
Go
428 lines
22 KiB
Go
package api
|
|
|
|
import (
|
|
domainAPIKey "RenewCMS/internal/domain/apikey"
|
|
domainArticle "RenewCMS/internal/domain/article"
|
|
domainAudit "RenewCMS/internal/domain/audit"
|
|
domainImage "RenewCMS/internal/domain/image"
|
|
domainInvite "RenewCMS/internal/domain/invite"
|
|
domainMail "RenewCMS/internal/domain/mail"
|
|
domainPurge "RenewCMS/internal/domain/purge"
|
|
domainUpdate "RenewCMS/internal/domain/update"
|
|
domainUser "RenewCMS/internal/domain/user"
|
|
"RenewCMS/internal/infrastructure/auditing"
|
|
"RenewCMS/internal/infrastructure/config"
|
|
"RenewCMS/internal/infrastructure/hashing"
|
|
"RenewCMS/internal/infrastructure/imaging"
|
|
"RenewCMS/internal/infrastructure/mailer"
|
|
"RenewCMS/internal/infrastructure/markdown"
|
|
"RenewCMS/internal/infrastructure/persistence/database"
|
|
persistence "RenewCMS/internal/infrastructure/persistence/repositories"
|
|
"RenewCMS/internal/infrastructure/scheduler"
|
|
"RenewCMS/internal/infrastructure/storage"
|
|
"RenewCMS/internal/infrastructure/update"
|
|
"RenewCMS/internal/infrastructure/useCases"
|
|
"context"
|
|
"crypto/ed25519"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/go-chi/jwtauth/v5"
|
|
)
|
|
|
|
type UseCases struct {
|
|
apiKeyAuthOnce sync.Once
|
|
apiKeyAuthMiddleware func(http.Handler) http.Handler
|
|
Token *jwtauth.JWTAuth
|
|
PurgeScheduler *scheduler.Runner
|
|
ActivityCleanupScheduler *scheduler.Runner
|
|
CreateArticleUseCase *useCases.CreateArticleUseCase
|
|
GetArticleUseCase *useCases.GetArticleUseCase
|
|
ListArticlesUseCase *useCases.ListArticlesUseCase
|
|
UpdateArticleUseCase *useCases.UpdateArticleUseCase
|
|
DeleteArticleUseCase *useCases.DeleteArticleUseCase
|
|
GetUserUseCase *useCases.GetUserUseCase
|
|
CreateUserUseCase *useCases.CreateUserUseCase
|
|
AuthenticateUserUseCase *useCases.AuthenticateUserUseCase
|
|
VerifyUserUseCase *useCases.VerifyUserUseCase
|
|
CancelRegistrationUseCase *useCases.CancelRegistrationUseCase
|
|
RequestPasswordResetUseCase *useCases.RequestPasswordResetUseCase
|
|
ResetPasswordUseCase *useCases.ResetPasswordUseCase
|
|
UpdateUserProfileUseCase *useCases.UpdateUserProfileUseCase
|
|
ListUsersUseCase *useCases.ListUsersUseCase
|
|
CreateInviteUseCase *useCases.CreateInviteUseCase
|
|
CancelInviteUseCase *useCases.CancelInviteUseCase
|
|
RenewInviteUseCase *useCases.RenewInviteUseCase
|
|
ListUsersAndInvitesUseCase *useCases.ListUsersAndInvitesUseCase
|
|
GetInviteUseCase *useCases.GetInviteUseCase
|
|
AcceptInviteUseCase *useCases.AcceptInviteUseCase
|
|
SendMailUseCase *useCases.SendMailUseCase
|
|
CreateImageUseCase *useCases.CreateImageUseCase
|
|
OpenMediaUseCase *useCases.OpenMediaUseCase
|
|
ListMediaUseCase *useCases.ListMediaUseCase
|
|
RenameMediaUseCase *useCases.RenameMediaUseCase
|
|
DeleteMediaUseCase *useCases.DeleteMediaUseCase
|
|
MergeMediaUseCase *useCases.MergeMediaUseCase
|
|
GetMediaUsageUseCase *useCases.GetMediaUsageUseCase
|
|
GetPurgeSettingsUseCase *useCases.GetPurgeSettingsUseCase
|
|
UpdatePurgeSettingsUseCase *useCases.UpdatePurgeSettingsUseCase
|
|
PreviewPurgeUseCase *useCases.PreviewPurgeUseCase
|
|
RunPurgeUseCase *useCases.RunPurgeUseCase
|
|
GetSettingsUseCase *useCases.GetSettingsUseCase
|
|
GetUpdateStatusUseCase *useCases.GetUpdateStatusUseCase
|
|
CheckForUpdateUseCase *useCases.CheckForUpdateUseCase
|
|
StartUpdateDownloadUseCase *useCases.StartUpdateDownloadUseCase
|
|
RequestRestartUseCase *useCases.RequestRestartUseCase
|
|
RecordRunningInfoUseCase *useCases.RecordRunningInfoUseCase
|
|
CreateAPIKeyUseCase *useCases.CreateAPIKeyUseCase
|
|
ListAPIKeysUseCase *useCases.ListAPIKeysUseCase
|
|
RevokeAPIKeyUseCase *useCases.RevokeAPIKeyUseCase
|
|
AuthenticateAPIKeyUseCase *useCases.AuthenticateAPIKeyUseCase
|
|
ListActivityUseCase *useCases.ListActivityUseCase
|
|
GetActivitySummaryUseCase *useCases.GetActivitySummaryUseCase
|
|
ExportActivityUseCase *useCases.ExportActivityUseCase
|
|
GetActivityRetentionUseCase *useCases.GetActivityRetentionUseCase
|
|
UpdateActivityRetentionUseCase *useCases.UpdateActivityRetentionUseCase
|
|
ListVariantsUseCase *useCases.ListVariantsUseCase
|
|
CreateVariantUseCase *useCases.CreateVariantUseCase
|
|
UpdateVariantUseCase *useCases.UpdateVariantUseCase
|
|
SetVariantEnabledUseCase *useCases.SetVariantEnabledUseCase
|
|
DeleteVariantUseCase *useCases.DeleteVariantUseCase
|
|
PurgeVariantUseCase *useCases.PurgeVariantUseCase
|
|
ServeVariantUseCase *useCases.ServeVariantUseCase
|
|
}
|
|
|
|
func (c *UseCases) RunSchedulers(ctx context.Context) {
|
|
var running sync.WaitGroup
|
|
for _, runner := range []*scheduler.Runner{c.PurgeScheduler, c.ActivityCleanupScheduler} {
|
|
if runner == nil {
|
|
continue
|
|
}
|
|
running.Add(1)
|
|
go func() {
|
|
defer running.Done()
|
|
runner.Run(ctx)
|
|
}()
|
|
}
|
|
running.Wait()
|
|
}
|
|
|
|
type Repositories struct {
|
|
ArticleRepo domainArticle.Repository
|
|
UserRepo domainUser.Repository
|
|
ImageRepo domainImage.Repository
|
|
VariantRepo domainImage.VariantRepository
|
|
VariantFileRepo domainImage.VariantFileRepository
|
|
VariantRenderer domainImage.VariantRenderer
|
|
InviteRepo domainInvite.Repository
|
|
APIKeyRepo domainAPIKey.Repository
|
|
PurgeSettingsRepo domainPurge.Repository
|
|
AuditRepo domainAudit.Repository
|
|
AuditSettingsRepo domainAudit.SettingsRepository
|
|
MailRepo domainMail.Repository
|
|
ReleaseFeed domainUpdate.ReleaseFeed
|
|
UpdateStore domainUpdate.StatusStore
|
|
UpdateJobs domainUpdate.JobStore
|
|
UpdateHelper domainUpdate.HelperDetector
|
|
AssetFetcher domainUpdate.AssetFetcher
|
|
SignatureVerifier domainUpdate.SignatureVerifier
|
|
StagedRunner domainUpdate.StagedBinaryRunner
|
|
DatabaseBackup domainUpdate.DatabaseBackup
|
|
UpdateResults domainUpdate.ResultStore
|
|
RestartRequests domainUpdate.RestartRequestStore
|
|
RunningInfo domainUpdate.RunningInfoStore
|
|
}
|
|
|
|
const (
|
|
updateStatusFileName = "update-status.json"
|
|
updateJobFileName = "update-job.json"
|
|
updateHelperFileName = "update-helper.json"
|
|
updatesDirName = "updates"
|
|
backupsDirName = "backups"
|
|
)
|
|
|
|
func imageStorageConfig(settings config.Settings) storage.Config {
|
|
if settings.Storage.Driver == config.StorageDriverS3 {
|
|
s3 := settings.Storage.S3
|
|
return storage.Config{
|
|
Driver: storage.DriverS3,
|
|
S3: storage.S3Config{
|
|
Bucket: s3.Bucket,
|
|
Region: s3.Region,
|
|
Endpoint: s3.Endpoint,
|
|
AccessKeyID: s3.AccessKeyID,
|
|
SecretAccessKey: s3.SecretAccessKey,
|
|
KeyPrefix: s3.KeyPrefix,
|
|
PathStyle: s3.PathStyle,
|
|
TLS: s3.TLS,
|
|
},
|
|
}
|
|
}
|
|
return storage.Config{Driver: storage.DriverLocal, Location: settings.UploadDir}
|
|
}
|
|
|
|
func openImageStorage(settings config.Settings) domainImage.Storage {
|
|
imageStorage, err := storage.Open(imageStorageConfig(settings))
|
|
if err != nil {
|
|
panic("Unable to open the image storage: " + err.Error())
|
|
}
|
|
return imageStorage
|
|
}
|
|
|
|
func databaseConfig(settings config.Settings) database.Config {
|
|
switch settings.Database.Driver {
|
|
case config.DatabaseDriverMySQL:
|
|
return mysqlDatabaseConfig(settings.Database)
|
|
case config.DatabaseDriverPostgres:
|
|
return postgresDatabaseConfig(settings.Database)
|
|
case "", config.DatabaseDriverSQLite:
|
|
return database.Config{Driver: database.DriverSQLite, Source: settings.DBFile}
|
|
default:
|
|
return database.Config{Driver: settings.Database.Driver}
|
|
}
|
|
}
|
|
|
|
func mysqlDatabaseConfig(settings config.DatabaseSettings) database.Config {
|
|
return database.Config{
|
|
Driver: database.DriverMySQL,
|
|
Source: database.MySQLDSN(database.MySQLConfig{
|
|
Host: settings.Host,
|
|
Port: settings.Port,
|
|
User: settings.User,
|
|
Password: settings.Password,
|
|
Name: settings.Name,
|
|
TLS: settings.TLS,
|
|
}),
|
|
Pool: &database.PoolSettings{
|
|
MaxOpenConns: settings.MaxOpenConns,
|
|
MaxIdleConns: settings.MaxIdleConns,
|
|
ConnMaxLifetime: settings.ConnMaxLifetime,
|
|
},
|
|
}
|
|
}
|
|
|
|
func postgresDatabaseConfig(settings config.DatabaseSettings) database.Config {
|
|
return database.Config{
|
|
Driver: database.DriverPostgres,
|
|
Source: database.PostgresDSN(database.PostgresConfig{
|
|
Host: settings.Host,
|
|
Port: settings.Port,
|
|
User: settings.User,
|
|
Password: settings.Password,
|
|
Name: settings.Name,
|
|
SSLMode: settings.SSLMode,
|
|
}),
|
|
Pool: &database.PoolSettings{
|
|
MaxOpenConns: settings.MaxOpenConns,
|
|
MaxIdleConns: settings.MaxIdleConns,
|
|
ConnMaxLifetime: settings.ConnMaxLifetime,
|
|
},
|
|
}
|
|
}
|
|
|
|
func openDatabase(settings config.Settings) *database.Connection {
|
|
connection, err := database.Connect(databaseConfig(settings))
|
|
if err != nil {
|
|
panic("Unable to open the database: " + err.Error())
|
|
}
|
|
if err := database.Migrate(connection.DB); err != nil {
|
|
panic("Failed to migrate database: " + err.Error())
|
|
}
|
|
return connection
|
|
}
|
|
|
|
func releasePublicKey() ed25519.PublicKey {
|
|
key, err := update.EmbeddedPublicKey()
|
|
if err != nil {
|
|
panic("Unable to read the embedded release key: " + err.Error())
|
|
}
|
|
return key
|
|
}
|
|
|
|
func getRepositories(connection *database.Connection, settings config.Settings) *Repositories {
|
|
db := connection.DB
|
|
dataDir := settings.DataDir()
|
|
return &Repositories{
|
|
ArticleRepo: persistence.NewArticleRepository(db),
|
|
UserRepo: persistence.NewUserRepository(db),
|
|
ImageRepo: persistence.NewImageRepository(db),
|
|
VariantRepo: persistence.NewVariantRepository(db),
|
|
VariantFileRepo: persistence.NewVariantFileRepository(db),
|
|
VariantRenderer: imaging.NewVariantRenderer(),
|
|
InviteRepo: persistence.NewInviteRepository(db),
|
|
APIKeyRepo: persistence.NewAPIKeyRepository(db),
|
|
PurgeSettingsRepo: persistence.NewPurgeSettingsRepository(db),
|
|
AuditRepo: persistence.NewAuditEventRepository(db),
|
|
AuditSettingsRepo: persistence.NewAuditSettingsRepository(db),
|
|
MailRepo: mailer.NewMailRepository(settings.Smtp),
|
|
ReleaseFeed: update.NewGiteaReleaseFeed(settings.UpdateFeedURL),
|
|
UpdateStore: update.NewJSONStatusStore(filepath.Join(dataDir, updateStatusFileName)),
|
|
UpdateJobs: update.NewJSONJobStore(filepath.Join(dataDir, updateJobFileName)),
|
|
UpdateHelper: update.NewContainerHelperDetector(update.NewFileHelperDetector(filepath.Join(dataDir, updateHelperFileName)), settings.Container),
|
|
AssetFetcher: update.NewHTTPAssetFetcher(settings.UpdateFeedURL),
|
|
SignatureVerifier: update.NewEd25519SignatureVerifier(releasePublicKey()),
|
|
StagedRunner: update.NewExecStagedBinaryRunner(),
|
|
DatabaseBackup: connection.NewBackup(filepath.Join(dataDir, backupsDirName), time.Now),
|
|
UpdateResults: update.NewJSONResultStore(filepath.Join(dataDir, domainUpdate.ResultFileName)),
|
|
RestartRequests: update.NewJSONRestartRequestStore(filepath.Join(dataDir, domainUpdate.RestartRequestFileName)),
|
|
RunningInfo: update.NewJSONRunningInfoStore(filepath.Join(dataDir, domainUpdate.RunningInfoFileName)),
|
|
}
|
|
}
|
|
|
|
func getUseCases(repos *Repositories, imageStorage domainImage.Storage, settings config.Settings) *UseCases {
|
|
hasher := hashing.NewBcryptHasher()
|
|
renderer := markdown.NewConverter()
|
|
keyGenerator := hashing.NewSHA256KeyGenerator()
|
|
recorder := auditing.NewRecorder(repos.AuditRepo, time.Now, log.Default())
|
|
mergeMedia := useCases.NewMergeMediaUseCase(repos.ImageRepo, repos.ArticleRepo, imageStorage, repos.VariantFileRepo, recorder)
|
|
|
|
runPurge := useCases.NewRunPurgeUseCase(repos.ImageRepo, repos.ArticleRepo, mergeMedia, repos.PurgeSettingsRepo, time.Now, log.Default(), recorder)
|
|
purgeScheduler := useCases.NewPurgeSchedulerUseCase(repos.PurgeSettingsRepo, runPurge, recorder)
|
|
activityCleanup := useCases.NewCleanupActivityUseCase(repos.AuditRepo, repos.AuditSettingsRepo, recorder)
|
|
|
|
return &UseCases{
|
|
PurgeScheduler: scheduler.NewSystemRunner(purgeScheduler, log.Default()),
|
|
ActivityCleanupScheduler: scheduler.NewSystemCleanupRunner(activityCleanup, log.Default()),
|
|
Token: jwtauth.New("HS256", []byte(settings.JWTSecret), nil),
|
|
CreateArticleUseCase: useCases.NewCreateArticleUseCase(repos.ArticleRepo, renderer, recorder),
|
|
GetArticleUseCase: useCases.NewGetArticleUseCase(repos.ArticleRepo, renderer),
|
|
ListArticlesUseCase: useCases.NewListArticlesUseCase(repos.ArticleRepo, renderer),
|
|
UpdateArticleUseCase: useCases.NewUpdateArticleUseCase(repos.ArticleRepo, renderer, recorder),
|
|
DeleteArticleUseCase: useCases.NewDeleteArticleUseCase(repos.ArticleRepo, recorder),
|
|
GetUserUseCase: useCases.NewGetUserUseCase(repos.UserRepo),
|
|
CreateUserUseCase: useCases.NewCreateUserUseCase(repos.UserRepo, hasher, repos.MailRepo, settings.PublicURL, recorder),
|
|
AuthenticateUserUseCase: useCases.NewAuthenticateUserUseCase(repos.UserRepo, hasher, recorder),
|
|
VerifyUserUseCase: useCases.NewVerifyUserUseCase(repos.UserRepo, hasher, recorder),
|
|
CancelRegistrationUseCase: useCases.NewCancelRegistrationUseCase(repos.UserRepo),
|
|
RequestPasswordResetUseCase: useCases.NewRequestPasswordResetUseCase(repos.UserRepo, hasher, repos.MailRepo, settings.PublicURL, recorder),
|
|
ResetPasswordUseCase: useCases.NewResetPasswordUseCase(repos.UserRepo, hasher, repos.APIKeyRepo, time.Now, recorder),
|
|
UpdateUserProfileUseCase: useCases.NewUpdateUserProfileUseCase(repos.UserRepo, recorder),
|
|
ListUsersUseCase: useCases.NewListUsersUseCase(repos.UserRepo),
|
|
CreateInviteUseCase: useCases.NewCreateInviteUseCase(repos.UserRepo, repos.InviteRepo, hasher, repos.MailRepo, settings.PublicURL, recorder),
|
|
CancelInviteUseCase: useCases.NewCancelInviteUseCase(repos.InviteRepo, recorder),
|
|
RenewInviteUseCase: useCases.NewRenewInviteUseCase(repos.UserRepo, repos.InviteRepo, hasher, repos.MailRepo, settings.PublicURL, recorder),
|
|
ListUsersAndInvitesUseCase: useCases.NewListUsersAndInvitesUseCase(repos.UserRepo, repos.InviteRepo),
|
|
GetInviteUseCase: useCases.NewGetInviteUseCase(repos.InviteRepo, hasher),
|
|
AcceptInviteUseCase: useCases.NewAcceptInviteUseCase(repos.UserRepo, repos.InviteRepo, hasher, recorder),
|
|
SendMailUseCase: useCases.NewSendMailUseCase(repos.MailRepo),
|
|
CreateImageUseCase: useCases.NewCreateImageUseCase(repos.ImageRepo, imageStorage, recorder),
|
|
OpenMediaUseCase: useCases.NewOpenMediaUseCase(imageStorage),
|
|
ListMediaUseCase: useCases.NewListMediaUseCase(repos.ImageRepo, repos.ArticleRepo, repos.UserRepo),
|
|
RenameMediaUseCase: useCases.NewRenameMediaUseCase(repos.ImageRepo, recorder),
|
|
DeleteMediaUseCase: useCases.NewDeleteMediaUseCase(repos.ImageRepo, imageStorage, repos.VariantFileRepo, recorder),
|
|
MergeMediaUseCase: mergeMedia,
|
|
GetMediaUsageUseCase: useCases.NewGetMediaUsageUseCase(repos.ImageRepo, repos.ArticleRepo),
|
|
GetPurgeSettingsUseCase: useCases.NewGetPurgeSettingsUseCase(repos.PurgeSettingsRepo),
|
|
UpdatePurgeSettingsUseCase: useCases.NewUpdatePurgeSettingsUseCase(repos.PurgeSettingsRepo, time.Now),
|
|
PreviewPurgeUseCase: useCases.NewPreviewPurgeUseCase(repos.ImageRepo, repos.ArticleRepo),
|
|
RunPurgeUseCase: runPurge,
|
|
GetSettingsUseCase: useCases.NewGetSettingsUseCase(settings.Version),
|
|
GetUpdateStatusUseCase: useCases.NewGetUpdateStatusUseCase(repos.UpdateStore, repos.UpdateJobs, repos.UpdateHelper, repos.UpdateResults, repos.RestartRequests, settings.Version, settings.Container, time.Now),
|
|
CheckForUpdateUseCase: useCases.NewCheckForUpdateUseCase(repos.ReleaseFeed, repos.UpdateStore, settings.Version, time.Now, recorder),
|
|
StartUpdateDownloadUseCase: startUpdateDownloadUseCase(repos, settings, recorder),
|
|
RequestRestartUseCase: useCases.NewRequestRestartUseCase(repos.UpdateStore, repos.UpdateJobs, repos.UpdateHelper, repos.UpdateResults, repos.RestartRequests, settings.Version, time.Now, recorder),
|
|
RecordRunningInfoUseCase: useCases.NewRecordRunningInfoUseCase(repos.RunningInfo, settings.Version, os.Getpid(), time.Now),
|
|
CreateAPIKeyUseCase: useCases.NewCreateAPIKeyUseCase(repos.APIKeyRepo, keyGenerator, time.Now, recorder),
|
|
ListAPIKeysUseCase: useCases.NewListAPIKeysUseCase(repos.APIKeyRepo, repos.UserRepo, time.Now),
|
|
RevokeAPIKeyUseCase: useCases.NewRevokeAPIKeyUseCase(repos.APIKeyRepo, repos.UserRepo, time.Now, recorder),
|
|
AuthenticateAPIKeyUseCase: useCases.NewAuthenticateAPIKeyUseCase(repos.APIKeyRepo, keyGenerator, repos.UserRepo, time.Now),
|
|
ListActivityUseCase: useCases.NewListActivityUseCase(repos.AuditRepo, repos.UserRepo, repos.ArticleRepo, repos.ImageRepo, repos.APIKeyRepo, time.Now),
|
|
GetActivitySummaryUseCase: useCases.NewGetActivitySummaryUseCase(repos.AuditRepo, time.Now),
|
|
ExportActivityUseCase: useCases.NewExportActivityUseCase(repos.AuditRepo, time.Now),
|
|
GetActivityRetentionUseCase: useCases.NewGetActivityRetentionUseCase(repos.AuditSettingsRepo, repos.AuditRepo, time.Now),
|
|
UpdateActivityRetentionUseCase: useCases.NewUpdateActivityRetentionUseCase(repos.AuditSettingsRepo, repos.AuditRepo, recorder, time.Now),
|
|
ListVariantsUseCase: useCases.NewListVariantsUseCase(repos.VariantRepo, repos.VariantFileRepo),
|
|
CreateVariantUseCase: useCases.NewCreateVariantUseCase(repos.VariantRepo, repos.VariantRenderer, time.Now, recorder),
|
|
UpdateVariantUseCase: useCases.NewUpdateVariantUseCase(repos.VariantRepo, repos.VariantFileRepo, imageStorage, repos.VariantRenderer, time.Now, recorder),
|
|
SetVariantEnabledUseCase: useCases.NewSetVariantEnabledUseCase(repos.VariantRepo, repos.VariantFileRepo, time.Now, recorder),
|
|
DeleteVariantUseCase: useCases.NewDeleteVariantUseCase(repos.VariantRepo, repos.VariantFileRepo, imageStorage, recorder),
|
|
PurgeVariantUseCase: useCases.NewPurgeVariantUseCase(repos.VariantRepo, repos.VariantFileRepo, imageStorage, recorder),
|
|
ServeVariantUseCase: useCases.NewServeVariantUseCase(repos.VariantRepo, repos.VariantFileRepo, repos.ImageRepo, imageStorage, repos.VariantRenderer, useCases.ServeVariantLimits{MaxSourceBytes: settings.ImageVariantMaxSourceBytes, MaxSourcePixels: settings.ImageVariantMaxSourcePixels, MaxConcurrentRenders: settings.ImageVariantMaxConcurrentRenders}),
|
|
}
|
|
}
|
|
|
|
func startUpdateDownloadUseCase(repos *Repositories, settings config.Settings, recorder domainAudit.Recorder) *useCases.StartUpdateDownloadUseCase {
|
|
return useCases.NewStartUpdateDownloadUseCase(useCases.StartUpdateDownloadDependencies{
|
|
Store: repos.UpdateStore,
|
|
Jobs: repos.UpdateJobs,
|
|
Helper: repos.UpdateHelper,
|
|
Results: repos.UpdateResults,
|
|
Requests: repos.RestartRequests,
|
|
Fetcher: repos.AssetFetcher,
|
|
Verifier: repos.SignatureVerifier,
|
|
Runner: repos.StagedRunner,
|
|
Backup: repos.DatabaseBackup,
|
|
Staging: update.NewOSStagingArea(filepath.Join(settings.DataDir(), updatesDirName)),
|
|
Logger: log.Default(),
|
|
CurrentVersion: settings.Version,
|
|
Platform: domainUpdate.Platform{OS: runtime.GOOS, Arch: runtime.GOARCH},
|
|
FeedURL: settings.UpdateFeedURL,
|
|
Now: time.Now,
|
|
Recorder: recorder,
|
|
})
|
|
}
|
|
|
|
func backfillImageMetadata(imageRepo domainImage.Repository, imageStorage domainImage.Storage, settings config.Settings) error {
|
|
run := func(readable domainImage.Storage) error {
|
|
return useCases.NewBackfillImageMetadataUseCase(imageRepo, readable).Run()
|
|
}
|
|
if settings.Storage.Driver == config.StorageDriverS3 {
|
|
return storage.RunBackfillReportingReads(imageStorage, log.Default(), run)
|
|
}
|
|
return run(imageStorage)
|
|
}
|
|
|
|
func InitContainer(settings config.Settings) (*UseCases, func() error) {
|
|
imageStorage := openImageStorage(settings)
|
|
connection := openDatabase(settings)
|
|
repos := getRepositories(connection, settings)
|
|
if err := backfillImageMetadata(repos.ImageRepo, imageStorage, settings); err != nil {
|
|
panic("Failed to backfill image metadata: " + err.Error())
|
|
}
|
|
return getUseCases(repos, imageStorage, settings), connection.Close
|
|
}
|
|
|
|
type BrowserUpdateCommands struct {
|
|
Enable *useCases.EnableBrowserUpdatesUseCase
|
|
Disable *useCases.DisableBrowserUpdatesUseCase
|
|
}
|
|
|
|
func InitBrowserUpdateCommands() *BrowserUpdateCommands {
|
|
units := update.NewSystemdUnits()
|
|
dependencies := useCases.ManageBrowserUpdatesDependencies{
|
|
Probe: update.NewSystemMachineProbe(),
|
|
Locator: units,
|
|
Units: units,
|
|
Manager: update.NewSystemctlControl(domainUpdate.ServiceUnitName),
|
|
Status: update.NewJSONHelperStatusWriter(),
|
|
Now: time.Now,
|
|
}
|
|
return &BrowserUpdateCommands{
|
|
Enable: useCases.NewEnableBrowserUpdatesUseCase(dependencies),
|
|
Disable: useCases.NewDisableBrowserUpdatesUseCase(dependencies),
|
|
}
|
|
}
|
|
|
|
func InitApplyUpdateCommand(options domainUpdate.InstallOptions) *useCases.ApplyRestartRequestUseCase {
|
|
layout := domainUpdate.HelperLayout{DataDir: options.DataDir, BinaryPath: options.Binary}
|
|
files := update.NewNoFollowFilesystem()
|
|
return useCases.NewApplyRestartRequestUseCase(useCases.ApplyRestartRequestDependencies{
|
|
Requests: update.NewFSRestartRequestStore(files, layout.RestartRequestPath()),
|
|
Results: update.NewFSResultStore(files, layout.ResultPath()),
|
|
Running: update.NewJSONRunningInfoStore(filepath.Join(options.DataDir, domainUpdate.RunningInfoFileName)),
|
|
Files: files,
|
|
Service: update.NewSystemctlControl(options.Service),
|
|
Health: update.NewHTTPHealthChecker(options.Port),
|
|
Verifier: update.NewEd25519SignatureVerifier(releasePublicKey()),
|
|
Clock: update.NewSystemClock(),
|
|
Logger: log.Default(),
|
|
Layout: layout,
|
|
Platform: domainUpdate.Platform{OS: runtime.GOOS, Arch: runtime.GOARCH},
|
|
})
|
|
}
|