tar-install

Library core for safely installing Linux app tarballs into desktop-friendly locations.


Keywords
app-manager, installer, linux, rust, tarball, tarballs, tools, untar, utility
License
MIT

Documentation

Tarminal

Tarminal installs Linux application tarballs as proper desktop apps.

Debian Ubuntu Zorin OS Fedora openSUSE Alpine Linux Void Linux Arch Linux

Instead of asking users to extract a .tar.xz somewhere and run a random binary manually, Tarminal can install the app into a standard location, create a command, create a desktop menu entry, install an icon, track state, and remove it cleanly later.

The project is split into two Cargo packages:

tar-install  = reusable library/core package
tarminal     = CLI frontend powered by tar-install

tar-install also ships a small hint command. If someone runs tar-install ..., it tells them to install or use tarminal.

Screenshot Tarminal Preview

Install

Debian / Ubuntu / Zorin

curl -fsSL https://packages.tamkungz.me/gpg.key | \
  sudo gpg --dearmor -o /usr/share/keyrings/tamkungz-packages.gpg

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/tamkungz-packages.gpg] https://packages.tamkungz.me/apt stable main" | \
  sudo tee /etc/apt/sources.list.d/tamkungz-packages.list

sudo apt update
sudo apt install tarminal

Optional: If you prefer packages built by Launchpad for Ubuntu Jammy or Noble, you can install from the PPA instead:

sudo add-apt-repository ppa:tamkungz/stable
sudo apt update
sudo apt install tarminal

Fedora / RPM

sudo tee /etc/yum.repos.d/tamkungz-packages.repo >/dev/null <<'EOF'
[tamkungz-packages]
name=TamKungZ Packages
baseurl=https://packages.tamkungz.me/rpm/$basearch/
enabled=1
gpgcheck=0
repo_gpgcheck=1
gpgkey=https://packages.tamkungz.me/gpg.key
EOF

sudo dnf makecache
sudo dnf install tarminal

openSUSE Tumbleweed

Packages built by Open Build Service are available for openSUSE Tumbleweed:

sudo zypper ar https://download.opensuse.org/repositories/home:/TamKungZ_/openSUSE_Tumbleweed/home:TamKungZ_.repo
sudo zypper refresh
sudo zypper install tarminal

Alpine APK

sudo mkdir -p /etc/apk/keys
curl -fsSL https://packages.tamkungz.me/apk/tamkungz.rsa.pub | \
  sudo tee /etc/apk/keys/tamkungz.rsa.pub >/dev/null

echo "https://packages.tamkungz.me/apk" | \
  sudo tee -a /etc/apk/repositories

sudo apk update
sudo apk add tarminal

Void XBPS

Details
sudo mkdir -p /etc/xbps.d
sudo tee /etc/xbps.d/tamkungz.conf >/dev/null <<'EOF'
repository=https://packages.tamkungz.me/xbps/$XBPS_ARCH
EOF

sudo xbps-install -S
sudo xbps-install tarminal

Arch Linux

Details
curl -fsSL https://packages.tamkungz.me/gpg.key | sudo pacman-key --add -
sudo pacman-key --lsign-key release@tamkungz.me || true

sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[tamkungz]
Server = https://packages.tamkungz.me/arch/$arch
SigLevel = DatabaseRequired PackageOptional
EOF

sudo pacman -Sy
sudo pacman -S tarminal

 

gpgcheck=0 is currently used because the repository metadata is signed, while embedded RPM package signing may be added later.

GitHub Releases

Release artifacts are also published on GitHub:

  • standalone Linux binaries
  • .deb
  • .rpm
  • .tar.xz
  • SHA256SUMS
  • detached GPG signatures (.asc)

Developer Packages

For developers who want to build on the installer core directly:

  • Python: tar-install on PyPI provides bindings around the shared library, so Python applications and tools can reuse and extend the installer behavior.
  • Rust: tar-install on crates.io is published as a Cargo crate, allowing Rust applications to use the API directly instead of shelling out to the tarminal CLI.

See also:

Usage

Inspect a tarball before installing:

tarminal inspect ./myapp-1.2.0-linux-x64.tar.xz

Install with automatic detection:

tarminal install ./myapp-1.2.0-linux-x64.tar.xz

Install with manual configuration prompts:

tarminal install ./myapp.tar.xz --config

Install using a recipe:

tarminal install ./myapp.tar.xz --recipe ./myapp.tarapp.yml

System-wide install:

sudo tarminal install ./myapp.tar.xz --system

List installed apps:

tarminal list

Remove an app:

tarminal remove myapp

Check an installed app:

tarminal doctor myapp

 

Tarminal Command --help
 

What Tarminal does

For a normal user install, Tarminal installs files here:

App files:   ~/.local/share/tarapp/apps/<app-id>/
Command:     ~/.local/bin/<command>
Desktop:     ~/.local/share/applications/<app-id>.desktop
Icon:        ~/.local/share/icons/hicolor/256x256/apps/<app-id>.*
State DB:    ~/.local/state/tarapp/apps.json

For a system install:

App files:   /opt/<app-id>/
Command:     /usr/local/bin/<command>
Desktop:     /usr/share/applications/<app-id>.desktop
Icon:        /usr/share/icons/hicolor/256x256/apps/<app-id>.*
State DB:    /var/lib/tarapp/apps.json

Supported archive formats

Current prototype support:

  • .tar.xz, .txz
  • .tar.gz, .tgz
  • .tar.bz2, .tbz2
  • .tar

Detection behavior

Tarminal first tries to infer app metadata from common file names such as:

<app>-<version>-<os>-<architecture>.tar.xz
<app>_<version>_<os>_<architecture>.tar.xz

Then it inspects the archive and looks for likely executable files, including names that match:

<app>
<app>-<architecture>
<app>_<architecture>
bin/<app>

If detection is not good enough, use:

tarminal install ./app.tar.xz --config

or provide a recipe.

Recipe format

A recipe can be supplied externally:

tarminal install ./app.tar.xz --recipe ./app.tarapp.yml

Example:

id: com.example.myapp
name: My App
version: 1.0.0
exec: MyApp
command: myapp
icon: assets/icon.png
desktop:
  categories:
    - Utility
  terminal: false

A recipe can also be embedded inside the archive as one of:

tarapp.yml
tarapp.yaml
.tarapp.yml
.tarapp.yaml
manifest.yml
manifest.yaml

Recipes are optional, but they are the recommended way for communities or app authors to make tarball installs reliable.

Safety behavior

Tarminal refuses to install archives with unsafe entries such as:

  • absolute paths
  • .. path traversal
  • symlinks that point outside the archive root
  • hard-link entries

Relative symlinks are allowed only when they resolve inside the extracted app tree.

Build

Build all packages:

cargo build --workspace

Build release binaries:

cargo build --release -p tar-install --bin tar-install
cargo build --release -p tarminal

Build packages separately:

cargo build -p tar-install --lib
cargo build -p tar-install --bin tar-install
cargo build -p tarminal

CLI binary:

target/release/tarminal

Library crate:

use tar_install::install_archive;

More examples are available in the Rust API guide.

Package locally

Install package tools:

cargo install cargo-deb cargo-generate-rpm

Build .deb packages:

cargo deb -p tar-install
cargo deb -p tarminal

Build .rpm packages:

cargo build --release -p tar-install --bin tar-install
cargo build --release -p tarminal

cargo generate-rpm -p crates/tar-install
cargo generate-rpm -p crates/tarminal

Inspect package contents:

for deb in target/debian/*.deb; do
  dpkg -I "$deb"
  dpkg -c "$deb"
done

for rpm in target/generate-rpm/*.rpm; do
  rpm -qpi "$rpm"
  rpm -qpl "$rpm"
  rpm -qpR "$rpm"
done

Release

Releases are handled by GitHub Actions when pushing a version tag:

git tag v0.1.0
git push origin v0.1.0

The release workflow builds packages, signs artifacts, creates GitHub Release files, and publishes package repository files to:

https://packages.tamkungz.me/

Repository layout:

/gpg.key
/apt
/rpm/x86_64
/apk
/xbps
/arch
/apps/tarminal

/apps/tarminal is only the landing/documentation page. Package managers install from the package-manager-specific repository paths above.

Tagged releases also publish:

  • GitHub Release assets
  • OBS sources for openSUSE Tumbleweed
  • AUR PKGBUILD updates when AUR credentials are configured
  • tar-install on crates.io when CARGO_REGISTRY_TOKEN is configured
  • tar-install on PyPI through the pylib-tar-install workflow when PYLIB_WORKFLOW_TOKEN is configured

Project shape

crates/
  tar-install/
    src/lib.rs          library exports
    src/bin/            hint command binary
    src/archive.rs      inspect tarball, detect binary/icon/manifest
    src/filename.rs     parse <app>-<version>-<os>-<arch>
    src/install.rs      install/remove/doctor logic
    src/ffi.rs          C ABI used by Python bindings
    src/desktop.rs      .desktop generation
    src/paths.rs        user/system install targets
    src/recipe.rs       manifest/recipe schema
    src/state.rs        installed apps database

  tarminal/
    src/main.rs         CLI frontend

pylib-tar-install/
  python/tarinstall/    Python bindings around libtar_install.so

Status

This is an early prototype designed for iteration.

The important architecture is already separated:

  • tar-install can be reused by other GUIs or tools
  • tarminal is only a CLI wrapper
  • recipes are optional but first-class
  • --config lets users fix bad filename/archive detection
  • package publishing is automated for GitHub Releases and packages.tamkungz.me

License

MIT