package router import ( "errors" "fmt" "github.com/gin-gonic/gin" "github.com/pterodactyl/wings/server" "github.com/pterodactyl/wings/server/backup" "net/http" "os" ) // Backs up a server. func postServerBackup(c *gin.Context) { s := GetServer(c.Param("server")) data := &backup.Request{} // BindJSON sends 400 if the request fails, all we need to do is return if err := c.BindJSON(&data); err != nil { return } var adapter backup.BackupInterface var err error switch data.Adapter { case backup.LocalBackupAdapter: adapter, err = data.NewLocalBackup() case backup.S3BackupAdapter: adapter, err = data.NewS3Backup() default: err = errors.New(fmt.Sprintf("unknown backup adapter [%s] provided", data.Adapter)) return } if err != nil { TrackedServerError(err, s).Abort(c) return } go func(b backup.BackupInterface, serv *server.Server) { if err := serv.Backup(b); err != nil { serv.Log().WithField("error", err).Error("failed to generate backup for server") } }(adapter, s) c.Status(http.StatusAccepted) } // Deletes a local backup of a server. If the backup is not found on the machine just return // a 404 error. The service calling this endpoint can make its own decisions as to how it wants // to handle that response. func deleteServerBackup(c *gin.Context) { s := GetServer(c.Param("server")) b, _, err := backup.LocateLocal(c.Param("backup")) if err != nil { // Just return from the function at this point if the backup was not located. if errors.Is(err, os.ErrNotExist) { c.AbortWithStatusJSON(http.StatusNotFound, gin.H{ "error": "The requested backup was not found on this server.", }) return } TrackedServerError(err, s).Abort(c) return } if err := b.Remove(); err != nil { // I'm not entirely sure how likely this is to happen, however if we did manage to locate // the backup previously and it is now missing when we go to delete, just treat it as having // been successful, rather than returning a 404. if !errors.Is(err, os.ErrNotExist) { TrackedServerError(err, s).Abort(c) return } } c.Status(http.StatusNoContent) }