-
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.
Merge pull request #1 from decoyjoe/build-sanoid-portable
Create sanoid-portable
- Loading branch information
Showing
8 changed files
with
965 additions
and
202 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 @@ | ||
/build/ |
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,74 @@ | ||
|
||
# sanoid-portable | ||
A portable self-contained binary build of Sanoid, a ZFS snapshot management tool. | ||
|
||
Run [Sanoid](https://github.com/jimsalterjrs/sanoid) without installing any dependencies. | ||
|
||
## Summary | ||
|
||
*sanoid-portable* is a self-contained, portable build of the [Sanoid](https://github.com/jimsalterjrs/sanoid) ZFS | ||
snapshot management tool. Built using [APPerl (Actually Portable Perl)](https://computoid.com/APPerl/), this | ||
self-contained, portable binary encompasses the Perl runtime, all required Perl dependencies, and the Sanoid script | ||
itself. This enables you to run Sanoid on any Linux or FreeBSD system without needing to install additional Perl | ||
dependencies or configure the system's Perl environment. | ||
|
||
This is useful if you'd like to use Sanoid on an appliance-like storage system, such as TrueNAS, where standard package | ||
installations are restricted or non-ideal. | ||
|
||
## Installation | ||
|
||
Download the latest version of sanoid-portable from the GitHub releases and make it executable: | ||
|
||
```console | ||
wget https://github.com/decoyjoe/sanoid-portable/releases/latest/download/sanoid-portable | ||
chmod +x sanoid-portable | ||
``` | ||
|
||
Create symbolic links for each tool you plan to use (sanoid-portable uses the invoking command name (`argv[0]`) to | ||
determine its behavior): | ||
|
||
```console | ||
ln -s sanoid-portable sanoid | ||
ln -s sanoid-portable syncoid | ||
ln -s sanoid-portable findoid | ||
``` | ||
|
||
## Usage | ||
|
||
Invoke the symbolic link: | ||
|
||
```console | ||
./sanoid --help | ||
./syncoid --help | ||
./findoid --help | ||
``` | ||
|
||
Refer to the [Sanoid documentation](https://github.com/jimsalterjrs/sanoid) for configuration instructions. | ||
|
||
### Important Compatibility Note | ||
|
||
sanoid-portable ***must*** be run from a Thompson Shell-compatible shell such as `bash` ([due to a limitation of | ||
APPerl](https://computoid.com/APPerl/)). It is *not* compatible with shells like `zsh` or `fish`, which will fail to run | ||
sanoid-portable with an error such as: `zsh: exec format error: sanoid-portable`. | ||
|
||
## Developing | ||
|
||
Run the initialization script to prepare your environment to build the sanoid-portable executable on a Debian-based | ||
system: | ||
|
||
```console | ||
./init.sh | ||
``` | ||
|
||
Build the executable: | ||
|
||
```console | ||
./build.sh | ||
``` | ||
|
||
This script will download and configure APPerl, download necessary Perl modules, and build the portable Sanoid binary. | ||
|
||
The executable gets built to `build/sanoid-portable`. | ||
|
||
## License | ||
|
||
This project is licensed under the GPL v3.0 license - see the [LICENSE](LICENSE) file for details. |
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,25 @@ | ||
{ | ||
"apperl_configs": { | ||
"sanoid-portable": { | ||
"desc": "Portable sanoid binary", | ||
"base": "full", | ||
"dest": "sanoid-portable", | ||
"default_script": "/zip/bin/sanoid-portable.pl", | ||
"install_modules": [ | ||
"Module-Build-0.4234.tar.gz", | ||
"Config-IniFiles-3.000003.tar.gz", | ||
"Capture-Tiny-0.48.tar.gz" | ||
], | ||
"zip_extra_files": { | ||
"bin": [ | ||
"sanoid-portable.pl", | ||
"sanoid_source/sanoid", | ||
"sanoid_source/syncoid", | ||
"sanoid_source/findoid", | ||
"versions.json" | ||
] | ||
} | ||
} | ||
}, | ||
"defaultconfig": "sanoid-portable" | ||
} |
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,108 @@ | ||
#!/bin/bash | ||
|
||
set -euo pipefail | ||
|
||
SANOID_VERSION=$(jq -r '.Sanoid' versions.json) | ||
PACKAGING_REVISION=$(jq -r '.PackagingRevision' versions.json) | ||
APPERL_VERSION=$(jq -r '.APPerl' versions.json) | ||
SANOID_PORTABLE_VERSION="${SANOID_VERSION}-${PACKAGING_REVISION}" | ||
|
||
echo "Building sanoid-portable version ${SANOID_PORTABLE_VERSION}, based on Sanoid version ${SANOID_VERSION} and APPerl version ${APPERL_VERSION}" | ||
|
||
repo_root="$(realpath "$(dirname "$0")")" | ||
|
||
# Cleanup previous artifacts if they exist | ||
if [ -d build ]; then | ||
echo 'Cleaning up previous build...' | ||
rm -rf build | ||
fi | ||
|
||
mkdir build | ||
pushd build > /dev/null | ||
|
||
echo 'Downloading necessary modules...' | ||
|
||
# Perl build dependency | ||
# https://metacpan.org/dist/Module-Build | ||
wget https://cpan.metacpan.org/authors/id/L/LE/LEONT/Module-Build-0.4234.tar.gz | ||
|
||
# Sanoid dependency | ||
# https://metacpan.org/dist/Config-IniFiles | ||
wget https://cpan.metacpan.org/authors/id/S/SH/SHLOMIF/Config-IniFiles-3.000003.tar.gz | ||
|
||
# Sanoid dependency | ||
## https://metacpan.org/dist/Capture-Tiny | ||
wget https://cpan.metacpan.org/authors/id/D/DA/DAGOLDEN/Capture-Tiny-0.48.tar.gz | ||
|
||
echo 'Cloning sanoid repository...' | ||
rm -rf sanoid_source | ||
git clone https://github.com/jimsalterjrs/sanoid.git sanoid_source | ||
echo '' | ||
|
||
echo "Checking out Sanoid version \"${SANOID_VERSION}\"" | ||
pushd sanoid_source > /dev/null | ||
git -c advice.detachedHead=false checkout "v${SANOID_VERSION}" | ||
git log -1 | ||
popd > /dev/null | ||
echo '' | ||
|
||
echo 'Downloading APPerl (Actually Portable Perl)...' | ||
wget -O perl.com "https://github.com/G4Vi/Perl-Dist-APPerl/releases/download/v${APPERL_VERSION}/perl.com" | ||
chmod u+x perl.com | ||
|
||
echo 'APPerl (perl.com) SHA-256 checksum:' | ||
sha256sum perl.com | ||
echo '' | ||
|
||
# Bootstrap; use APPerl to build a custom APPerl. | ||
ln -s perl.com apperlm | ||
|
||
cp "${repo_root}/apperl-project.json" . | ||
cp "${repo_root}/sanoid-portable.pl" . | ||
cp "${repo_root}/versions.json" . | ||
|
||
echo 'Installing build dependencies...' | ||
./apperlm install-build-deps | ||
|
||
echo 'Checking out the APPerl sanoid-portable build...' | ||
./apperlm checkout sanoid-portable | ||
|
||
echo 'Configuring build environment...' | ||
./apperlm configure | ||
|
||
echo 'Building sanoid-portable...' | ||
./apperlm build | ||
|
||
echo '' | ||
echo 'Build complete.' | ||
echo '' | ||
|
||
stat sanoid-portable | ||
echo '' | ||
|
||
./sanoid-portable | ||
|
||
# APPerl uses the invoking command name (argv[0]) to determine which internal script to run | ||
ln -s sanoid-portable sanoid | ||
ln -s sanoid-portable syncoid | ||
ln -s sanoid-portable findoid | ||
|
||
./sanoid --version | ||
echo '' | ||
|
||
echo 'Testing execution of sanoid...' | ||
./sanoid --help | ||
echo '' | ||
|
||
echo 'Testing execution of syncoid...' | ||
./syncoid --help | ||
echo '' | ||
|
||
echo 'Testing execution of findoid...' | ||
./findoid --help | ||
echo '' | ||
|
||
echo 'SHA-256 checksum:' | ||
sha256sum sanoid-portable | ||
|
||
popd > /dev/null |
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,28 @@ | ||
#!/bin/bash | ||
|
||
set -euo pipefail | ||
|
||
# Identify the operating system from /etc/os-release | ||
OS=$(grep ^ID= /etc/os-release | cut -d '=' -f 2 | tr -d '"') | ||
|
||
# Check if the OS is Debian or a Debian derivative (like Ubuntu) | ||
if [[ "$OS" != 'debian' && "$OS" != 'ubuntu' ]]; then | ||
echo 'Error: This script is intended only for Debian-based systems.' | ||
exit 1 | ||
fi | ||
|
||
# Determine whether to use 'sudo' or run directly (if root) | ||
if [[ "$EUID" -ne 0 ]]; then | ||
SUDO='sudo' | ||
else | ||
SUDO='' | ||
fi | ||
|
||
# Update package lists to ensure packages are up to date | ||
$SUDO apt-get update | ||
|
||
$SUDO apt-get install -y build-essential wget git unzip zip jq | ||
|
||
echo '' | ||
echo 'All necessary dependencies have been installed.' | ||
echo '' |
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,51 @@ | ||
#!/usr/bin/perl | ||
use strict; | ||
use warnings; | ||
use FindBin; | ||
use Getopt::Long; | ||
use JSON::PP; | ||
|
||
open my $versions_json_file, '<', "$FindBin::Bin/versions.json" or die "Can't open versions.json: $!"; | ||
my $versions_json = do { local $/; <$versions_json_file> }; | ||
close $versions_json_file; | ||
|
||
my $versions = decode_json($versions_json); | ||
my $sanoid_version = $versions->{'Sanoid'}; | ||
my $packaging_revision = $versions->{'PackagingRevision'}; | ||
my $apperl_version = $versions->{'APPerl'}; | ||
my $sanoid_portable_version = "$sanoid_version-$packaging_revision"; | ||
|
||
# Only output the version number when using -V|--version | ||
my $print_version_only = 0; | ||
GetOptions('V|version' => \$print_version_only); | ||
|
||
if ($print_version_only) { | ||
print "$sanoid_portable_version\n"; | ||
exit 0; | ||
} | ||
|
||
# Print versions | ||
print "sanoid-portable: $sanoid_portable_version\n"; | ||
print "Sanoid: $sanoid_version\n"; | ||
print "Perl: $^V\n"; # Built-in variable for Perl version | ||
print "APPerl: $apperl_version\n"; | ||
|
||
my $usage = <<'USAGE'; | ||
This binary executes sanoid, syncoid, or findoid based on the name of the symbolic link invoked. | ||
Create symbolic links to use the different tools: | ||
ln -s sanoid-portable sanoid | ||
ln -s sanoid-portable syncoid | ||
ln -s sanoid-portable findoid | ||
Make sure to make sanoid-portable executable: | ||
chmod +x sanoid-portable | ||
Then invoke the symlink: | ||
./sanoid --help | ||
./syncoid --help | ||
./findoid --help | ||
USAGE | ||
|
||
print "\n$usage"; |
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,5 @@ | ||
{ | ||
"Sanoid": "2.2.0", | ||
"PackagingRevision": "1", | ||
"APPerl": "0.6.1" | ||
} |