-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
1,313 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
snapkup | ||
bin/ | ||
test/ | ||
|
||
# Created by https://www.toptal.com/developers/gitignore/api/go,visualstudiocode,macos,linux,windows | ||
# Edit at https://www.toptal.com/developers/gitignore?templates=go,visualstudiocode,macos,linux,windows | ||
|
||
### Go ### | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
|
||
### Go Patch ### | ||
/vendor/ | ||
/Godeps/ | ||
|
||
### Linux ### | ||
*~ | ||
|
||
# temporary files which can be created if a process still has a handle open of a deleted file | ||
.fuse_hidden* | ||
|
||
# KDE directory preferences | ||
.directory | ||
|
||
# Linux trash folder which might appear on any partition or disk | ||
.Trash-* | ||
|
||
# .nfs files are created when an open file is removed but is still being accessed | ||
.nfs* | ||
|
||
### macOS ### | ||
# General | ||
.DS_Store | ||
.AppleDouble | ||
.LSOverride | ||
|
||
# Icon must end with two \r | ||
Icon | ||
|
||
|
||
# Thumbnails | ||
._* | ||
|
||
# Files that might appear in the root of a volume | ||
.DocumentRevisions-V100 | ||
.fseventsd | ||
.Spotlight-V100 | ||
.TemporaryItems | ||
.Trashes | ||
.VolumeIcon.icns | ||
.com.apple.timemachine.donotpresent | ||
|
||
# Directories potentially created on remote AFP share | ||
.AppleDB | ||
.AppleDesktop | ||
Network Trash Folder | ||
Temporary Items | ||
.apdisk | ||
|
||
### VisualStudioCode ### | ||
.vscode/* | ||
!.vscode/settings.json | ||
!.vscode/tasks.json | ||
!.vscode/launch.json | ||
!.vscode/extensions.json | ||
*.code-workspace | ||
|
||
# Local History for Visual Studio Code | ||
.history/ | ||
|
||
### VisualStudioCode Patch ### | ||
# Ignore all local history of files | ||
.history | ||
.ionide | ||
|
||
### Windows ### | ||
# Windows thumbnail cache files | ||
Thumbs.db | ||
Thumbs.db:encryptable | ||
ehthumbs.db | ||
ehthumbs_vista.db | ||
|
||
# Dump file | ||
*.stackdump | ||
|
||
# Folder config file | ||
[Dd]esktop.ini | ||
|
||
# Recycle Bin used on file shares | ||
$RECYCLE.BIN/ | ||
|
||
# Windows Installer files | ||
*.cab | ||
*.msi | ||
*.msix | ||
*.msm | ||
*.msp | ||
|
||
# Windows shortcuts | ||
*.lnk | ||
|
||
# End of https://www.toptal.com/developers/gitignore/api/go,visualstudiocode,macos,linux,windows |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
.PHONY: list | ||
list: | ||
@LC_ALL=C $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | ||
|
||
build-prepare: | ||
make clean | ||
mkdir bin | ||
|
||
clean: | ||
rm -rf bin | ||
|
||
build: | ||
make build-prepare | ||
cd src; go build -o snapkup; strip snapkup | ||
mv src/snapkup bin/ | ||
|
||
zbuild: | ||
make build | ||
upx --lzma bin/snapkup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,67 @@ | ||
# snapkup | ||
A snapshot-based backup tool, easy to understand and use | ||
# 🗃️ snapkup v0.1.0 | ||
|
||
Snapkup is a simple backup tool that takes snapshots of your filesystem (or the parts that you'll decide), storing them efficiently and conveniently. | ||
|
||
## Basic workflow | ||
|
||
Snapkup's goal is to store efficiently one or more filesystem's situation at given points in time, in a manner that is friendly to e.g. Dropbox sync or removable storage. | ||
|
||
- You initialize an empty directory that will store the backups | ||
- You register one or more backup roots, directory or files that will be snapshotted | ||
- You take one or more snapshots. Snapkup lists all the tree for those roots, taking a snapshot of the contents | ||
- All the files in the roots are deduplicated, and only the files that are different are stored | ||
- All files that can be compressed are stored as such, using `zstd -9` | ||
- Files are stored in an efficient manner, with a shallow directory structure. | ||
- You can restore the situation of the roots at a given snapshot, later on | ||
- Files' and dirs' mode and modification time are preserved | ||
- If you choose to delete any snapshot, dangling backup files are removed. | ||
- Of course, it's possible to list roots and snapshots and delete any of them. | ||
|
||
All paths are converted to absolute paths, for consistency. | ||
|
||
## Mini-tutorial | ||
|
||
We will backup the contents of the `C:\MyImportantDir`, using the `C:\MySnapkupDir` folder as the container of the backup structures. This example is styled after windows, but it's completely similar under UNIXes. | ||
|
||
### Initialize the backup directory | ||
|
||
`snapkup.exe -d C:\MySnapkupDir init` | ||
|
||
### Register the directory to backup as a root | ||
|
||
`snapkup.exe -d C:\MySnapkupDir add-root C:\MyImportantDir` | ||
|
||
### Take your first snapshot | ||
|
||
`snapkup.exe -d C:\MySnapkupDir snap` | ||
|
||
*add `-z` if you want to compress the files being backed up*. | ||
|
||
### Delete it, because... just because. | ||
|
||
`snapkup.exe -d C:\MySnapkupDir del-snap 0` | ||
|
||
### Or restore it! | ||
|
||
`snapkup.exe -d C:\MySnapkupDir restore 0 C:\MyRestoreDir` | ||
|
||
*the destination directory should be empty.* | ||
|
||
## Status | ||
|
||
Everything described above should work. **It's still at an early stage of development, so don't trust it with any critical data, yet**. | ||
|
||
Next steps: | ||
|
||
- Proper testing framework, for reliability | ||
- Improved documentation | ||
- Mounting a snapshot as a FUSE filesystem | ||
- Proper cross-compiling | ||
- Better error handling | ||
- Better recovery of the data structures from errors | ||
|
||
## Build | ||
|
||
`cd` to the `src/` dir and `go build`. On UNIX systems you can also use `make build` from the root. | ||
|
||
It uses `CGO`, so cross-compilation comes with the usual caveats, and a proper build stack should be installed. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
CREATE TABLE SNAPS ( | ||
ID INTEGER NOT NULL, | ||
TIMESTAMP INTEGER NOT NULL, | ||
PRIMARY KEY(ID) | ||
); | ||
|
||
CREATE TABLE ITEMS ( | ||
PATH TEXT NOT NULL, | ||
SNAP INTEGER NOT NULL, | ||
HASH TEXT NOT NULL, | ||
IS_DIR INTEGER NOT NULL, | ||
MODE INTEGER NOT NULL, | ||
MOD_TIME INTEGER NOT NULL, | ||
PRIMARY KEY(PATH, SNAP) | ||
); | ||
|
||
CREATE TABLE BLOBS ( | ||
HASH TEXT NOT NULL, | ||
SIZE INTEGER NOT NULL, | ||
BLOB_SIZE INTEGER NOT NULL, | ||
IS_COMPRESSED INTEGER NOT NULL, | ||
IS_ENCRYPTED INTEGER NOT NULL, | ||
PRIMARY KEY(HASH) | ||
); | ||
|
||
CREATE TABLE ROOTS ( | ||
PATH TEXT NOT NULL, | ||
PRIMARY KEY(PATH) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package addroot | ||
|
||
import ( | ||
"database/sql" | ||
"fmt" | ||
|
||
"github.com/proofrock/snapkup/util" | ||
) | ||
|
||
func AddRoot(bkpDir string, toAdd string) error { | ||
dbPath, errComposingDbPath := util.DbFile(bkpDir) | ||
if errComposingDbPath != nil { | ||
return errComposingDbPath | ||
} | ||
|
||
db, errOpeningDb := sql.Open("sqlite3", dbPath) | ||
if errOpeningDb != nil { | ||
return errOpeningDb | ||
} | ||
defer db.Close() | ||
|
||
tx, errBeginning := db.Begin() | ||
if errBeginning != nil { | ||
return errBeginning | ||
} | ||
|
||
// TODO QueryOnce | ||
throwaway := 1 | ||
row := db.QueryRow("SELECT 1 FROM ROOTS WHERE PATH = ?", toAdd) | ||
if errQuerying := row.Scan(&throwaway); errQuerying == nil { | ||
tx.Rollback() | ||
return fmt.Errorf("Root already present (%s)", toAdd) | ||
} else if errQuerying != sql.ErrNoRows { | ||
tx.Rollback() | ||
return errQuerying | ||
} | ||
|
||
if _, errExecing := tx.Exec("INSERT INTO ROOTS (PATH) VALUES (?)", toAdd); errExecing != nil { | ||
tx.Rollback() // error is not managed | ||
return errExecing | ||
} | ||
|
||
if errCommitting := tx.Commit(); errCommitting != nil { | ||
return errCommitting | ||
} | ||
|
||
println("Root correctly added (", toAdd, ")") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package delroot | ||
|
||
import ( | ||
"database/sql" | ||
"fmt" | ||
|
||
"github.com/proofrock/snapkup/util" | ||
) | ||
|
||
func DelRoot(bkpDir string, toDel string) error { | ||
dbPath, errComposingDbPath := util.DbFile(bkpDir) | ||
if errComposingDbPath != nil { | ||
return errComposingDbPath | ||
} | ||
|
||
db, errOpeningDb := sql.Open("sqlite3", dbPath) | ||
if errOpeningDb != nil { | ||
return errOpeningDb | ||
} | ||
defer db.Close() | ||
|
||
if res, errExecing := db.Exec("DELETE FROM ROOTS WHERE PATH = ?", toDel); errExecing != nil { | ||
return errExecing | ||
} else if numAffected, errCalcRowsAffected := res.RowsAffected(); errCalcRowsAffected != nil { | ||
return errExecing | ||
} else if numAffected == 0 { | ||
return fmt.Errorf("Root not found in pool (%s)", toDel) | ||
} | ||
|
||
println("Root correctly deleted (", toDel, ")") | ||
|
||
return nil | ||
} |
Oops, something went wrong.