Skip to content

Commit

Permalink
cmd/lxd-to-incus: Uncompress snapshot files in the target database
Browse files Browse the repository at this point in the history
Signed-off-by: Free Ekanayaka <[email protected]>
  • Loading branch information
freeekanayaka committed Sep 7, 2023
1 parent 32c270b commit 1c7a455
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 0 deletions.
105 changes: 105 additions & 0 deletions cmd/lxd-to-incus/db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package main

import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"

"github.com/pierrec/lz4/v4"

"github.com/lxc/incus/shared"
)

// Uncompress the raft snapshot files in the given database directory.
//
// A backup will be created and kept around in case of errors.
func migrateDatabase(dir string) error {
global := filepath.Join(dir, "global")

err := shared.DirCopy(global, global+".bak")
if err != nil {
return fmt.Errorf("Failed to backup database directory %q: %w", global, err)
}

files, err := ioutil.ReadDir(global)
if err != nil {
return fmt.Errorf("Failed to list database directory %q: %w", global, err)
}

for _, file := range files {
var timestamp uint64
var first uint64
var last uint64

if !file.Mode().IsRegular() {
continue
}

n, err := fmt.Sscanf(file.Name(), "snapshot-%d-%d-%d\n", &timestamp, &first, &last)
if err != nil || n != 3 {
continue
}

filename := filepath.Join(global, file.Name())
err = lz4Uncompress(filename)
if err != nil {
return fmt.Errorf("Failed to uncompress snapshot %q: %w", filename, err)
}
}

return nil
}

// Uncompress the given file, preserving its mode and ownership.
func lz4Uncompress(zfilename string) error {
zr := lz4.NewReader(nil)

zfile, err := os.Open(zfilename)
if err != nil {
return fmt.Errorf("Failed to open file %q: %w", zfilename, err)
}

zinfo, err := zfile.Stat()
if err != nil {
return fmt.Errorf("Fialed to get file info for %q: %w", zfilename, err)
}

// use the same mode for the output file
mode := zinfo.Mode()

_, uid, gid := shared.GetOwnerMode(zinfo)

filename := zfilename + ".uncompressed"
file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)
if err != nil {
return fmt.Errorf("Failed to open file %q: %w", filename, err)
}

zr.Reset(zfile)

_, err = io.Copy(file, zr)
if err != nil {
return fmt.Errorf("Failed to uncompress %q into %q: %w", zfilename, filename, err)
}

for _, c := range []io.Closer{zfile, file} {
err := c.Close()
if err != nil {
return fmt.Errorf("Failed to close file: %w", err)
}
}

err = os.Chown(filename, uid, gid)
if err != nil {
return fmt.Errorf("Failed to set ownership of %q: %w", filename, err)
}

err = os.Rename(filename, zfilename)
if err != nil {
return fmt.Errorf("Failed to rename %q to %q: %w", filename, zfilename, err)
}

return nil
}
1 change: 1 addition & 0 deletions cmd/lxd-to-incus/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ require (
github.com/muhlemmer/gu v0.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pborman/uuid v1.2.1 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pkg/sftp v1.13.6 // indirect
github.com/pkg/xattr v0.4.9 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
Expand Down
2 changes: 2 additions & 0 deletions cmd/lxd-to-incus/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE=
Expand Down
7 changes: 7 additions & 0 deletions cmd/lxd-to-incus/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,13 @@ Instances will come back online once the migration is complete.
return fmt.Errorf("Failed to move %q to %q: %w", sourcePaths.Daemon, targetPaths.Daemon, err)
}

// Migrate database format.
fmt.Println("=> Migrating database")
err = migrateDatabase(filepath.Join(targetPaths.Daemon, "database"))
if err != nil {
return fmt.Errorf("Failed to migrate database in %q: %w", filepath.Join(targetPaths.Daemon, "database"), err)
}

// Cleanup paths.
fmt.Println("=> Cleaning up target paths")

Expand Down

0 comments on commit 1c7a455

Please sign in to comment.