with '#' will be ignored, and an empty message aborts the commit. Author: Ethan Alicea <64653625+Tech-Gamer@users.noreply.github.com> On branch develop Your branch is up to date with 'origin/develop'. Changes to be committed: modified: .github/workflows/push.yaml modified: .github/workflows/release.yaml modified: CHANGELOG.md modified: Dockerfile modified: Makefile modified: README.md modified: cmd/configure.go modified: cmd/diagnostics.go modified: cmd/root.go modified: config/config.go modified: environment/allocations.go modified: environment/docker.go modified: environment/docker/api.go modified: environment/docker/container.go modified: environment/docker/environment.go modified: environment/docker/power.go modified: environment/docker/stats.go modified: environment/environment.go modified: environment/settings.go modified: events/events.go modified: go.mod modified: internal/cron/activity_cron.go modified: internal/cron/cron.go modified: internal/cron/sftp_cron.go modified: internal/database/database.go modified: internal/progress/progress.go modified: internal/progress/progress_test.go modified: loggers/cli/cli.go new file: oryxBuildBinary modified: parser/parser.go modified: remote/http.go modified: remote/servers.go modified: remote/types.go modified: router/downloader/downloader.go modified: router/middleware.go modified: router/middleware/middleware.go modified: router/middleware/request_error.go modified: router/router.go modified: router/router_download.go modified: router/router_server.go modified: router/router_server_backup.go modified: router/router_server_files.go modified: router/router_server_transfer.go modified: router/router_server_ws.go modified: router/router_system.go modified: router/router_transfer.go modified: router/tokens/parser.go modified: router/websocket/listeners.go modified: router/websocket/websocket.go modified: server/activity.go modified: server/backup.go modified: server/backup/backup.go modified: server/backup/backup_local.go modified: server/backup/backup_s3.go modified: server/configuration.go modified: server/console.go modified: server/crash.go modified: server/events.go modified: server/filesystem/archive.go modified: server/filesystem/filesystem.go modified: server/filesystem/filesystem_test.go modified: server/install.go modified: server/installer/installer.go modified: server/listeners.go modified: server/manager.go modified: server/mounts.go modified: server/power.go modified: server/power_test.go modified: server/resources.go modified: server/server.go modified: server/transfer/archive.go modified: server/transfer/source.go modified: server/transfer/transfer.go modified: server/update.go modified: sftp/event.go modified: sftp/handler.go modified: sftp/server.go modified: wings.go
131 lines
3.6 KiB
Go
131 lines
3.6 KiB
Go
package router
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"emperror.dev/errors"
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/Tech-Gamer/nwy-wings/environment"
|
|
"github.com/Tech-Gamer/nwy-wings/router/middleware"
|
|
"github.com/Tech-Gamer/nwy-wings/server"
|
|
"github.com/Tech-Gamer/nwy-wings/server/installer"
|
|
"github.com/Tech-Gamer/nwy-wings/server/transfer"
|
|
)
|
|
|
|
// Data passed over to initiate a server transfer.
|
|
type serverTransferRequest struct {
|
|
URL string `binding:"required" json:"url"`
|
|
Token string `binding:"required" json:"token"`
|
|
Server installer.ServerDetails `json:"server"`
|
|
}
|
|
|
|
// postServerTransfer handles the start of a transfer for a server.
|
|
func postServerTransfer(c *gin.Context) {
|
|
var data serverTransferRequest
|
|
if err := c.BindJSON(&data); err != nil {
|
|
return
|
|
}
|
|
|
|
s := ExtractServer(c)
|
|
|
|
// Check if the server is already being transferred.
|
|
// There will be another endpoint for resetting this value either by deleting the
|
|
// server, or by canceling the transfer.
|
|
if s.IsTransferring() {
|
|
c.AbortWithStatusJSON(http.StatusConflict, gin.H{
|
|
"error": "A transfer is already in progress for this server.",
|
|
})
|
|
return
|
|
}
|
|
|
|
manager := middleware.ExtractManager(c)
|
|
|
|
notifyPanelOfFailure := func() {
|
|
if err := manager.Client().SetTransferStatus(context.Background(), s.ID(), false); err != nil {
|
|
s.Log().WithField("subsystem", "transfer").
|
|
WithField("status", false).
|
|
WithError(err).
|
|
Error("failed to set transfer status")
|
|
}
|
|
|
|
s.Events().Publish(server.TransferStatusEvent, "failure")
|
|
s.SetTransferring(false)
|
|
}
|
|
|
|
// Block the server from starting while we are transferring it.
|
|
s.SetTransferring(true)
|
|
|
|
// Ensure the server is offline. Sometimes a "No such container" error gets through
|
|
// which means the server is already stopped. We can ignore that.
|
|
if s.Environment.State() != environment.ProcessOfflineState {
|
|
if err := s.Environment.WaitForStop(
|
|
s.Context(),
|
|
time.Second*15,
|
|
false,
|
|
); err != nil && !strings.Contains(strings.ToLower(err.Error()), "no such container") {
|
|
s.SetTransferring(false)
|
|
middleware.CaptureAndAbort(c, errors.Wrap(err, "failed to stop server for transfer"))
|
|
return
|
|
}
|
|
}
|
|
|
|
// Create a new transfer instance for this server.
|
|
trnsfr := transfer.New(context.Background(), s)
|
|
transfer.Outgoing().Add(trnsfr)
|
|
|
|
go func() {
|
|
defer transfer.Outgoing().Remove(trnsfr)
|
|
|
|
if _, err := trnsfr.PushArchiveToTarget(data.URL, data.Token); err != nil {
|
|
notifyPanelOfFailure()
|
|
|
|
if err == context.Canceled {
|
|
trnsfr.Log().Debug("canceled")
|
|
trnsfr.SendMessage("Canceled.")
|
|
return
|
|
}
|
|
|
|
trnsfr.Log().WithError(err).Error("failed to push archive to target")
|
|
return
|
|
}
|
|
|
|
// DO NOT NOTIFY THE PANEL OF SUCCESS HERE. The only node that should send
|
|
// a success status is the destination node. When we send a failure status,
|
|
// the panel will automatically cancel the transfer and attempt to reset
|
|
// the server state on the destination node, we just need to make sure
|
|
// we clean up our statuses for failure.
|
|
|
|
trnsfr.Log().Debug("transfer complete")
|
|
}()
|
|
|
|
c.Status(http.StatusAccepted)
|
|
}
|
|
|
|
// deleteServerTransfer cancels an outgoing transfer for a server.
|
|
func deleteServerTransfer(c *gin.Context) {
|
|
s := ExtractServer(c)
|
|
|
|
if !s.IsTransferring() {
|
|
c.AbortWithStatusJSON(http.StatusConflict, gin.H{
|
|
"error": "Server is not currently being transferred.",
|
|
})
|
|
return
|
|
}
|
|
|
|
trnsfr := transfer.Outgoing().Get(s.ID())
|
|
if trnsfr == nil {
|
|
c.AbortWithStatusJSON(http.StatusConflict, gin.H{
|
|
"error": "Server is not currently being transferred.",
|
|
})
|
|
return
|
|
}
|
|
|
|
trnsfr.Cancel()
|
|
|
|
c.Status(http.StatusAccepted)
|
|
}
|