File | Date | Author | Commit |
---|---|---|---|
config-sample | 2022-07-31 |
![]() |
[a4bcbc] Update sample config |
icons | 2022-06-14 |
![]() |
[b30099] Add icons |
.gitignore | 2022-07-31 |
![]() |
[1539df] Update Makefile |
CHANGELOG.md | 2023-02-12 |
![]() |
[ab133d] Print sync direction before final confirm prompt |
Makefile | 2022-07-31 |
![]() |
[1539df] Update Makefile |
README.md | 2022-07-31 |
![]() |
[2b4324] Update README |
UNLICENSE | 2022-06-13 |
![]() |
[1e7008] Initial commit |
teleport.rb | 2023-02-12 |
![]() |
[ab133d] Print sync direction before final confirm prompt |
teleport is a rsync-based backup script designed to sync files between local and portable storage for easy migration between multiple PCs without relying on network transfer or cloud storage. It allows separation and separate configuration of multiple sync tasks, as well as their selective use.
findmnt
(mount -p
is used as a fallback) and sync
less
by default; see constant Commands::PAGER
in the source)rsync
teleport depends on a configuration file in JSON format. Default path to the configuration file is $HOME/.config/teleport/config.json
. Alternate configuration file can be specified with -c
flag.
Sample configuration file is provided in the code repository in folder config-sample
.
Usage instructions can always be obtained by running the script with -h
or --help
flag:
ruby teleport.rb -h
To list available sync tasks (read from the configuration file), use the -l
flag.
When invoked without any flags, teleport will attempt to execute all sync tasks with priority always
(default priority). If additional task IDs are provided as command line arguments, they will be executed in addition to the aforementioned tasks. When flag -a
is used, all sync tasks with priorities always
and explicit
will be executed.
Specific tasks can be executed using the -o
("only") flag. To execute only tasks with IDs documents
and teleport
, use:
ruby teleport.rb -o documents teleport
When executed, the script will first read and, to some extent, validate the configuration file. Afterwards, it will try to find any portable storage matching portable IDs in the configuration file (IDs are searched in the order they are given. The first match is used.).
If portable storage is found, the script displays base sync paths and asks the user for sync destination (either local or portable). Then it executes rsync
in dry run mode for all applicable sync tasks and collects the output in a temporary file, that is opened in a pager, so the user can inspect changes sync operations would cause. Finally, the user is asked to confirm the sync. Sync tasks are executed and filesystems are synced to write the data to persistent storage and allow the portable storage to be safely unmounted and removed.
JSON configuration file can consist of the following top-level fields, of which some are optional. Fields (on any level) with unknown names are silently ignored.
local
Configures sync parameters for local storage. It supports only a string parameter base_path
, which determines the local base path, relative to which sync task paths are specified. If omitted or empty string, home directory path is used as a base.
portable
Configures sync parameters for portable storage.
String field subdir
sets the subdirectory of the portable storage in which to place synced files. teleport
is used by default. The subdirectory serves as the portable base path for the sync process.
Field ids
is mandatory for determination of path to the portable storage. It must be an array of strings. The strings contain IDs by which desired portable storage can be identified. Presently, ID should be some unique part of the device's mount path - usually a label of the hard drive or USB drive partition.
global_exclude
An optional array of strings. Strings will be passed to every rsync
command with exclude option. This can be used to exlude unwanted files or patterns from all sync tasks at once. Example usage would be to exclude swap files produced by text editors.
tasks
An array of objects containing sync task information. A sync task object can contain the following fields:
name
(string): Human-readable name of the task (if not present, ID is used as a name instead)id
(string): Keyboard-friendly ID of the task used to manually specify the task (required)path
(string): Relative or absolute path to a directory or file to sync. See Path specification for more information.exclude
(array of strings): Files or patterns to exclude from the sync task (forwarded to rsync
). Optional.include
(array of strings): Files or patterns to include from the sync task. Include parameters are always passed to rsync
before exclude parameters to achieve the desired effect. Optional.delete
(boolean): Whether files that are missing on the sending side should be deleted from the receiving side. true
by default. Optional.priority
(string): Sync task priority (optional). Can be one of the following strings:always
: Run the task without manually specifying it (default option)explicit
: Only run the task when specified manuallynever
: Never run the task, even if specified manuallycopy_links
(boolean): Whether the actual data pointed to by the symlinks should be copied (passes -L
flag to rsync
). false
by default and optional.If relative path is specified in a sync task, the sync is performed relative to the local base path, which is the user's home directory by default. It can be reconfigured using base_path
described above. On the portable storage, data specified by relative paths are stored in HOME
subdirectory of the subdir
(teleport/HOME
by default).
If absolute path is specified, the sync is performed relative to the filesystem root and, therefore, allows for syncing files outside of the user's home directory. Files data synced with absolute paths are stored in ROOT
subdirectory of the subdir
(teleport/ROOT
by default) on the portable storage. Absolute paths are recognized by leading /
.
Using absolute paths can be useful to avoid potential problems with symlinks. For example, one can have a symlink pointing to a directory stored on a larger HDD drive instead of a "real" Documents folder in their home directory. Using relative path to sync the whole Documents directory can lead to only the symlink being copied, unless option copy_links
is used. However, this can cause some symlinks inside the folder to be replaced by the actual data they point to. Such behaviour is likely undesired and can be avoided by providing the real path of the Documents folder.
Relative source sync paths are always assembled by joining base path (generally home directory) and path specified by the sync task – it can either end with /
or not (consult rsync
documentation to understand the difference). Absolute source paths are used as provided.
Destination sync paths are treate similarly, except that the segment of the path is stripped and /
is appended. For example, .config/teleport/config.json
will be transformed to $HOME/teleport/
(note the trailing /
). This helps to avoid creation of duplicate nested directories in sync tasks where a directory is specified as a target. The script will attempt to create potentially unexistent sync paths at the sync destinaton to avoid rsync
errors when performing a sync for the first time.
A combination of include
and exclude
settings can be used to make a sync task sync only specific files in a directory. For example, we have a directory Documents
and only want to sync files file1.txt
and file3.rb
:
-- Documents
|-- Dir1
| `-- ...
|-- file1.txt
|-- file2.odt
|-- file3.rb
|-- file4.png
`-- ...
To achieve that, first set the sync task path to the directory Documents
(without trailing slash):
"path": "Documents"
Then exclude all contents of the directory Documents
using pattern Documents/*
, and include desired files or patterns to "bring them back" from exclusion:
"exclude": [ "Documents/*" ],
"include": [
"Documents/file1.txt",
"Documents/file3.rb"
]
The script seems to work best when task paths are specified without trailing slashes, as in the example above. Follow this rule of thumb in the absence of better reasoning.