Shore up the logic for migrations to allow multiple passes if needed

This commit is contained in:
Dane Everitt 2021-07-04 14:07:03 -07:00 committed by DaneEveritt
parent f8a25cb040
commit 37c52dd439
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
2 changed files with 51 additions and 19 deletions

View File

@ -54,10 +54,12 @@ func (m *MigrateVHDCommand) Run(ctx context.Context) error {
s.Log().Debug("starting migration of server contents to virtual disk...") s.Log().Debug("starting migration of server contents to virtual disk...")
v := vhd.New(s.DiskSpace(), filesystem.VirtualDiskPath(s.Id()), s.Filesystem().Path()) 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 { if err := v.Allocate(ctx); err != nil {
return errors.WithStackIf(err) return errors.WithStackIf(err)
} }
s.Log().Info("creating virtual filesystem for server")
if err := v.MakeFilesystem(ctx); err != nil { if err := v.MakeFilesystem(ctx); err != nil {
// If the filesystem already exists no worries, just move on with our // If the filesystem already exists no worries, just move on with our
// day here. // day here.
@ -67,19 +69,26 @@ func (m *MigrateVHDCommand) Run(ctx context.Context) error {
} }
bak := strings.TrimSuffix(s.Filesystem().Path(), "/") + "_bak" bak := strings.TrimSuffix(s.Filesystem().Path(), "/") + "_bak"
// Create a backup directory of the server files if one does not already exist mounted, err := v.IsMounted(ctx)
// at that location. If one does exists we'll just assume it is good to go and if err != nil {
// rely on it to provide the files we'll need. return err
if _, err := os.Lstat(bak); os.IsNotExist(err) { } else if !mounted {
if err := os.Rename(s.Filesystem().Path(), bak); err != nil { s.Log().WithField("backup_dir", bak).Debug("virtual disk is not yet mounted, creating backup directory")
return errors.Wrap(err, "failed to rename existing data directory for backup") // 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 { if err := os.RemoveAll(s.Filesystem().Path()); err != nil && !os.IsNotExist(err) {
return errors.WithStack(err) return errors.Wrap(err, "failed to remove base server files path")
} }
} else {
if err := os.RemoveAll(s.Filesystem().Path()); err != nil && !os.IsNotExist(err) { s.Log().Warn("server appears to already have existing mount, not creating data backup")
return errors.Wrap(err, "failed to remove base server files path")
} }
// Attempt to mount the disk at the expected path now that we've created // 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) return errors.WithStackIf(err)
} }
// Copy over the files from the backup for this server. // Copy over the files from the backup for this server but only
cmd := exec.CommandContext(ctx, "mv", bak + "/*", s.Filesystem().Path()) // if we have a backup directory currently.
s.Log().Debug(cmd.String()) _, err = os.Lstat(bak)
if err := cmd.Run(); err != nil { if err != nil {
return errors.Wrap(err, "migrate: failed to move old server files into new direcotry") 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...") s.Log().Info("finished migration to virtual disk...")

View File

@ -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 // 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 // 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. // if the path exists but the destination is not a file or is a symlink.