From 37c52dd439b17157124fb7f4fe7af957d45f4a7f Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 4 Jul 2021 14:07:03 -0700 Subject: [PATCH] Shore up the logic for migrations to allow multiple passes if needed --- cmd/migrate_vhd.go | 62 +++++++++++++++++++++++++++++++-------------- internal/vhd/vhd.go | 8 ++++++ 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/cmd/migrate_vhd.go b/cmd/migrate_vhd.go index 6f3dc2e..7a487ae 100644 --- a/cmd/migrate_vhd.go +++ b/cmd/migrate_vhd.go @@ -54,10 +54,12 @@ func (m *MigrateVHDCommand) Run(ctx context.Context) error { s.Log().Debug("starting migration of server contents to virtual disk...") v := vhd.New(s.DiskSpace(), filesystem.VirtualDiskPath(s.Id()), s.Filesystem().Path()) + s.Log().WithField("disk_image", v.Path()).Info("creating virtual disk for server") if err := v.Allocate(ctx); err != nil { return errors.WithStackIf(err) } + s.Log().Info("creating virtual filesystem for server") if err := v.MakeFilesystem(ctx); err != nil { // If the filesystem already exists no worries, just move on with our // day here. @@ -67,19 +69,26 @@ func (m *MigrateVHDCommand) Run(ctx context.Context) error { } bak := strings.TrimSuffix(s.Filesystem().Path(), "/") + "_bak" - // Create a backup directory of the server files if one does not already exist - // at that location. If one does exists we'll just assume it is good to go and - // rely on it to provide the files we'll need. - if _, err := os.Lstat(bak); os.IsNotExist(err) { - if err := os.Rename(s.Filesystem().Path(), bak); err != nil { - return errors.Wrap(err, "failed to rename existing data directory for backup") + mounted, err := v.IsMounted(ctx) + if err != nil { + return err + } else if !mounted { + s.Log().WithField("backup_dir", bak).Debug("virtual disk is not yet mounted, creating backup directory") + // Create a backup directory of the server files if one does not already exist + // at that location. If one does exists we'll just assume it is good to go and + // rely on it to provide the files we'll need. + if _, err := os.Lstat(bak); os.IsNotExist(err) { + if err := os.Rename(s.Filesystem().Path(), bak); err != nil { + return errors.Wrap(err, "failed to rename existing data directory for backup") + } + } else if err != nil { + return errors.WithStack(err) } - } else if err != nil { - return errors.WithStack(err) - } - - if err := os.RemoveAll(s.Filesystem().Path()); err != nil && !os.IsNotExist(err) { - return errors.Wrap(err, "failed to remove base server files path") + if err := os.RemoveAll(s.Filesystem().Path()); err != nil && !os.IsNotExist(err) { + return errors.Wrap(err, "failed to remove base server files path") + } + } else { + s.Log().Warn("server appears to already have existing mount, not creating data backup") } // Attempt to mount the disk at the expected path now that we've created @@ -88,14 +97,29 @@ func (m *MigrateVHDCommand) Run(ctx context.Context) error { return errors.WithStackIf(err) } - // Copy over the files from the backup for this server. - cmd := exec.CommandContext(ctx, "mv", bak + "/*", s.Filesystem().Path()) - s.Log().Debug(cmd.String()) - if err := cmd.Run(); err != nil { - return errors.Wrap(err, "migrate: failed to move old server files into new direcotry") + // Copy over the files from the backup for this server but only + // if we have a backup directory currently. + _, err = os.Lstat(bak) + if err != nil { + if !os.IsNotExist(err) { + s.Log().WithField("error", err).Warn("failed to stat backup directory") + } else { + s.Log().Info("no backup data directory exists, not restoring files") + } + } else { + cmd := exec.CommandContext(ctx, "cp", "-r", bak+"/.", s.Filesystem().Path()) + if err := cmd.Run(); err != nil { + return errors.Wrap(err, "migrate: failed to move old server files into new direcotry") + } else { + if err := os.RemoveAll(bak); err != nil { + s.Log().WithField("directory", bak).WithField("error", err).Warn("failed to remove backup directory") + } + } } - if err := os.Remove(bak); err != nil { - s.Log().WithField("directory", bak).Warn("failed to remove backup directory") + + s.Log().Info("updating server file ownership...") + if err := s.Filesystem().Chown("/"); err != nil { + s.Log().WithField("error", err).Warn("failed to update ownership of new server files") } s.Log().Info("finished migration to virtual disk...") diff --git a/internal/vhd/vhd.go b/internal/vhd/vhd.go index 39dfed5..be4d016 100644 --- a/internal/vhd/vhd.go +++ b/internal/vhd/vhd.go @@ -95,6 +95,14 @@ func WithCommander(c CommanderProvider) func(*Disk) { } } +func (d *Disk) Path() string { + return d.diskPath +} + +func (d *Disk) MountPath() string { + return d.mountAt +} + // Exists reports if the disk exists on the system yet or not. This only verifies // the presence of the disk image, not the validity of it. An error is returned // if the path exists but the destination is not a file or is a symlink.