Menu

Tree [ab133d] master /
 History

HTTPS access


File Date Author Commit
 config-sample 2022-07-31 Chloris Chloris [a4bcbc] Update sample config
 icons 2022-06-14 Chloris Chloris [b30099] Add icons
 .gitignore 2022-07-31 Chloris Chloris [1539df] Update Makefile
 CHANGELOG.md 2023-02-12 Chloris Chloris [ab133d] Print sync direction before final confirm prompt
 Makefile 2022-07-31 Chloris Chloris [1539df] Update Makefile
 README.md 2022-07-31 Chloris Chloris [2b4324] Update README
 UNLICENSE 2022-06-13 Chloris Chloris [1e7008] Initial commit
 teleport.rb 2023-02-12 Chloris Chloris [ab133d] Print sync direction before final confirm prompt

Read Me

teleport

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.

Dependencies

  • UNIX-like operating system that provides findmnt (mount -p is used as a fallback) and sync
  • Ruby interpreter (only standard library required)
  • A pager (less by default; see constant Commands::PAGER in the source)
  • rsync

Configuration

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

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 format

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 manually
    • never: Never run the task, even if specified manually
  • copy_links (boolean): Whether the actual data pointed to by the symlinks should be copied (passes -L flag to rsync). false by default and optional.

Path specification

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.

Additional considerations

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.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.