Skip to content

Commit

Permalink
refine
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Jan 30, 2026
1 parent 5915306 commit a3155ff
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 49 deletions.
56 changes: 56 additions & 0 deletions local-app/python-tools/build-ansible-distribution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Portable Ansible Distribution

A self-contained Ansible environment built with `uv`, designed to be packaged as a tarball and deployed to systems with minimal dependencies.

## Architecture
- **Root**: `/apps/ansible`
- **Binaries**: Located in `/apps/ansible/bin` (Symlinked to `.venv/bin`)
- **Python**: Bundled Python 3.13 interpreter (isolated from system Python).
- **Isolation**: Uses `--link-mode copy` to ensure no dependencies on the local `uv` cache.

## Usage

### Deployment
1. Tar the directory: `tar -czvf ansible-dist.tar.gz /apps/ansible`
2. Extract on target: `tar -xzvf ansible-dist.tar.gz -C /`
3. Load path: `source /etc/profile.d/ansible.sh`

### Adding Packages
To add new Python dependencies or Ansible collections:
```bash
cd /apps/ansible
uv add <package-name> --link-mode copy
```

## Profile Configuration

To enable this globally, run:

```bash
sudo cp /apps/ansible/ansible_path.sh /etc/profile.d/ansible.sh
sudo chmod +x /etc/profile.d/ansible.sh
```

OR

```bash
sudo ln -sf /apps/ansible/ansible_path.sh /etc/profile.d/ansible.sh
```

## Portability Notes

* **Relocatable Mode**: When enabled, shebangs use `#!/usr/bin/env python`.
* **Paths**: If `MAKE_RELOCATABLE` is 0, the distribution must reside in `/apps/ansible`.


# CHANGELOG

| Version | Description |
| --- | --- |
| **1.0.5** | Added `MAKE_RELOCATABLE` toggle. Added `/etc/profile.d` path script generation. |
| **1.0.4** | Replaced `--copy-python` with physical binary replacement for `uv 0.5+` compatibility. |
| **1.0.3** | Switched to `dependency-groups` to resolve `tool.uv.dev-dependencies` deprecation. |
| **1.0.2** | Implemented `--link-mode copy` to prevent symlinking to user home directory. |
| **1.0.1** | Initial `uv` integration with Python 3.13 and symlinked `bin` directory. |
| **1.0.0** | Basic project structure and `pyproject.toml` initialization. |

83 changes: 34 additions & 49 deletions local-app/python-tools/build-ansible-distribution/create-ansible.sh
Original file line number Diff line number Diff line change
@@ -1,95 +1,80 @@
#!/bin/bash

VERSION="1.0.3"
THIS=$(basename $0 .sh)
# --- Configuration ---
APP_DIR="/apps/ansible"
PYTHON_VERSION="3.13"
MAKE_RELOCATABLE=0
VERSION="1.0.5"
# ---------------------

# Define the target directory
if [ -z "$1" ]
THIS=$(basename $0 .sh)
if [ ! -z "$1" ]
then
APP_DIR="/apps/ansible"
else
APP_DIR="$1"
fi

PYTHON_VERSION="3.13" # Can be changed to 3.12 or latest
MAKE_RELOCATABLE=0 # Set to 1 to patch shebangs for any-path portability
echo "Initializing Ansible Distribution v$VERSION..."

# 0. export environment variables needed
export SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
#export UV_PYTHON_INSTALL_DIR=/apps/uv/share
export UV_LINK_MODE=copy
export UV_NATIVE_TLS=true

# 1. Create and enter the directory
mkdir -p "$APP_DIR"
chown $(whoami):$(whoami) "$APP_DIR"
# 1. Prepare Directory
sudo mkdir -p "$APP_DIR"
sudo chown $(whoami):$(whoami) "$APP_DIR"
cd "$APP_DIR"

# 2. Initialize the uv project
# 2. Initialize project
uv init --no-workspace --app

# 3. Create the pyproject.toml with Ansible dependencies
# 3. Create pyproject.toml
cat <<EOF > pyproject.toml
[project]
name = "ansible-distribution"
version = "1.0.0"
name = "ansible-dist"
version = "$VERSION"
description = "Self-contained Ansible distribution"
readme = "README.md"
requires-python = ">=3.12"
requires-python = ">=$PYTHON_VERSION"
dependencies = [
"ansible>=10.0.0",
"ansible-lint",
"jmespath",
"netaddr",
"dnspython>=2.8.0",
]
[dependency-groups]
dev = [
"pytest",
]
dev = ["pytest"]
[[tool.uv.index]]
name = "pypi"
url = "https://nexus.it.census.gov:8443/repository/DataScience-Group/simple"
EOF

# 4. Create the venv and install dependencies
# Use --python to specify 3.12, 3.13, etc.
uv venv --python "$PYTHON_VERSION" \
--link-mode copy \
--seed
# 4. Create the Venv with Hard Copies
uv venv .venv --python "$PYTHON_VERSION" --seed --link-mode copy

# 5. Sync dependencies
source .venv/bin/activate

# 5. Sync the environment
uv sync --link-mode copy

# 6. Ensure the Python binary itself is a physical copy
# This severs the link to ~/.local/share/uv/python/...
# 6. Physical Python Binary Copy
REAL_PYTHON=$(readlink -f .venv/bin/python)
if [ -L ".venv/bin/python" ]; then
echo "Converting Python symlink to physical binary..."
rm .venv/bin/python
cp "$REAL_PYTHON" .venv/bin/python
fi

# 7. Optional: Make Relocatable
# 7. Optional: Relocatable Shebangs
if [ "$MAKE_RELOCATABLE" -eq 1 ]; then
echo "MAKE_RELOCATABLE is active. Patching shebangs..."
# Replaces absolute path shebangs with /usr/bin/env python
# This allows the binaries to work regardless of the parent directory path
find .venv/bin -maxdepth 1 -type f -executable -exec \
sed -i '1s|#!.*python|#!/usr/bin/env python|' {} +
else
echo "Skipping relocation patch. Scripts will use absolute paths: $APP_DIR"
fi

# 8. Link bin to .venv/bin for easy access to all tools
# 8. Link bin
ln -snf .venv/bin bin

echo "------------------------------------------------"
echo "Ansible distribution ready at $APP_DIR"
echo "Relocatable: $([ "$MAKE_RELOCATABLE" -eq 1 ] && echo "YES" || echo "NO")"
echo "Try: $APP_DIR/bin/ansible --version"
echo "------------------------------------------------"
# 9. Create /etc/profile.d script
cat <<EOF > ansible_path.sh
# Ansible Distribution Path Configuration
# Copy this to /etc/profile.d/ansible.sh
if [ -d "$APP_DIR/bin" ]; then
export PATH="$APP_DIR/bin:\$PATH"
fi
EOF

echo "Setup complete. Version $VERSION created."

0 comments on commit a3155ff

Please sign in to comment.