Jetpack (aka Jet) is a general-purpose, community-driven IT automation platform for configuration management, deployment, orchestration, patching, and arbitrary task execution workflows.
Jetpack is a GPLv3 licensed project, based on the original Jetporch project created and run by Michael DeHaan. (michael@michaeldehaan.net).
Links (currently outdated, will be updated soon)
Please route all questions, help requests, and feature discussion to Discord. Thanks!
Jetpack now includes a universal skip_if_exists parameter that works with ALL modules:
- !any_module
# ... module parameters ...
with:
skip_if_exists: /path/to/file # Skip task if this path existsThis is part of the with section that provides pre-execution modifiers:
condition: Conditional execution based on expressionsskip_if_exists: Skip task if specified path exists (NEW in Jetpack!)sudo: Execute with elevated privilegesitems: Loop over a list of itemsdelegate_to: Execute on a different hostsubscribe: Handler subscriptiontags: Task categorization
Example:
- !unpack
src: /tmp/archive.tar.gz
dest: /opt/app
with:
skip_if_exists: /opt/app/bin/app # Don't extract if app already exists
sudo: rootDownloads files from URLs with atomic writes and permission management:
url: Source URL to download fromdest: Local destination pathmode,owner,group: Optional file permissionsforce: Re-download even if file exists
Extracts various archive formats:
- Supports: tar.gz, tar.bz2, tar.xz, zip, gz, bz2, xz
src: Archive file pathdest: Extraction destination directorymode,owner,group: Apply to extracted files
Moves files and directories with optional backup:
src: Source file/directory pathdest: Destination pathbackup: Create timestamped backup if destination existsforce: Overwrite destinationmode,owner,group: Apply permissions after move
The current architecture forces every module to use shell commands for basic file operations. The cmd_library is just a bash string factory that returns commands like mv '{}' '{}'. This is fundamentally broken.
Current (bad) architecture:
// Module calls:
handle.remote.rename(&src, &dest)
// Which calls:
cmd_library::get_rename_command() -> "mv 'src' 'dest'"
// Which gets executed as bashWhat it SHOULD be:
trait Connection {
fn rename(&self, src: &Path, dest: &Path) -> Result<()>;
fn copy(&self, src: &Path, dest: &Path) -> Result<()>;
fn remove(&self, path: &Path) -> Result<()>;
fn exists(&self, path: &Path) -> Result<bool>;
// etc...
}
// Local uses std::fs, SSH uses commands, but modules don't care!Every file operation should be a proper method on the Connection trait, not a bash string generator. Modules shouldn't have to know about shell escaping or command formatting.
- Tilde expansion (
~) is NOT supported in paths. Use explicit paths like/home/{{ username }}instead of~/. - This is intentional - shell expansions can be unpredictable across different execution contexts.
- Always use absolute paths or template variables for home directories.
- Improved channel semantics (DONE):
stable/latest: Production - stable releases only (these are synonyms, default islatest)prerelease: Smart mode - gets the absolute latest version, preferring stable over RC of same versionunstable: Testing only - stays on prereleases even if stable existsany: Latest regardless of stability
- ETag caching support: Add optional
cache_etags: trueparameter to enable GitHub API ETag caching- Store ETags in
~/.local/share/jetpack/github_etags.json - Send
If-None-Matchheader to receive 304 responses that don't count against rate limits - Include cache expiry timestamps
- Privacy-focused: opt-in only feature to avoid tracking user lookups
- Store ETags in
- GitHub token authentication: Add optional
github_tokenparameter for authenticated requests (5000 req/hour vs 60)