Skip to content

Commit

Permalink
internally mark if a server is restoring to restrict actions
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewpi committed Mar 12, 2021
1 parent b63a491 commit 471886d
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 3 deletions.
20 changes: 17 additions & 3 deletions router/router_server_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func postServerBackup(c *gin.Context) {
// This endpoint will block until the backup is fully restored allowing for a
// spinner to be displayed in the Panel UI effectively.
//
// TODO: stop the server if it is running; internally mark it as suspended
// TODO: stop the server if it is running
func postServerRestoreBackup(c *gin.Context) {
s := middleware.ExtractServer(c)
client := middleware.ExtractApiClient(c)
Expand All @@ -84,9 +84,19 @@ func postServerRestoreBackup(c *gin.Context) {
return
}

s.SetRestoring(true)
hasError := true
defer func() {
if !hasError {
return
}

s.SetRestoring(false)
}()

logger.Info("processing server backup restore request")
if data.TruncateDirectory {
logger.Info(`recieved "truncate_directory" flag in request: deleting server files`)
logger.Info("received \"truncate_directory\" flag in request: deleting server files")
if err := s.Filesystem().TruncateRootDirectory(); err != nil {
middleware.CaptureAndAbort(c, err)
return
Expand All @@ -109,7 +119,9 @@ func postServerRestoreBackup(c *gin.Context) {
s.Events().Publish(server.DaemonMessageEvent, "Completed server restoration from local backup.")
s.Events().Publish(server.BackupRestoreCompletedEvent, "")
logger.Info("completed server restoration from local backup")
s.SetRestoring(false)
}(s, b, logger)
hasError = false
c.Status(http.StatusAccepted)
return
}
Expand All @@ -136,7 +148,7 @@ func postServerRestoreBackup(c *gin.Context) {
}
// Don't allow content types that we know are going to give us problems.
if res.Header.Get("Content-Type") == "" || !strings.Contains("application/x-gzip application/gzip", res.Header.Get("Content-Type")) {
res.Body.Close()
_ = res.Body.Close()
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"error": "The provided backup link is not a supported content type. \"" + res.Header.Get("Content-Type") + "\" is not application/x-gzip.",
})
Expand All @@ -151,8 +163,10 @@ func postServerRestoreBackup(c *gin.Context) {
s.Events().Publish(server.DaemonMessageEvent, "Completed server restoration from S3 backup.")
s.Events().Publish(server.BackupRestoreCompletedEvent, "")
logger.Info("completed server restoration from S3 backup")
s.SetRestoring(false)
}(s, c.Param("backup"), logger)

hasError = false
c.Status(http.StatusAccepted)
}

Expand Down
1 change: 1 addition & 0 deletions server/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var (
ErrSuspended = errors.New("server is currently in a suspended state")
ErrServerIsInstalling = errors.New("server is currently installing")
ErrServerIsTransferring = errors.New("server is currently being transferred")
ErrServerIsRestoring = errors.New("server is currently being restored")
)

type crashTooFrequent struct {
Expand Down
8 changes: 8 additions & 0 deletions server/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ func (s *Server) SetTransferring(state bool) {
s.transferring.Store(state)
}

func (s *Server) IsRestoring() bool {
return s.restoring.Load()
}

func (s *Server) SetRestoring(state bool) {
s.restoring.Store(state)
}

// Removes the installer container for the server.
func (ip *InstallationProcess) RemoveContainer() error {
err := ip.client.ContainerRemove(ip.context, ip.Server.Id()+"_installer", types.ContainerRemoveOptions{
Expand Down
4 changes: 4 additions & 0 deletions server/power.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ func (s *Server) HandlePowerAction(action PowerAction, waitSeconds ...int) error
return ErrServerIsTransferring
}

if s.IsRestoring() {
return ErrServerIsRestoring
}

if s.powerLock == nil {
s.powerLock = semaphore.NewWeighted(1)
}
Expand Down
2 changes: 2 additions & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type Server struct {
// installer process is still running.
installing *system.AtomicBool
transferring *system.AtomicBool
restoring *system.AtomicBool

// The console throttler instance used to control outputs.
throttler *ConsoleThrottler
Expand All @@ -79,6 +80,7 @@ func New(client remote.Client) (*Server, error) {
client: client,
installing: system.NewAtomicBool(false),
transferring: system.NewAtomicBool(false),
restoring: system.NewAtomicBool(false),
}
if err := defaults.Set(&s); err != nil {
return nil, errors.Wrap(err, "server: could not set default values for struct")
Expand Down

0 comments on commit 471886d

Please sign in to comment.