Famlab CLI Architecture¶
Overview¶
The Famlab CLI is designed as a modular, extensible command-line interface for managing a Famlab deployment. It provides direct management of Proxmox VE containers.
Design Principles¶
- Modular Command Structure: Each command is a separate script for easy extension
- Direct Container Management: No complex orchestration dependencies
- Zero Configuration Overhead: Sensible defaults with optional customization
- Extensible Architecture: New commands can be added without modifying core router
- Human-oriented CLI: The interface is meant to be helpful and guided
- Working Directory Aware: The working directory contains the Famlab node inventory used by all commands
- Expected Behavior: The commands are not surprising and follow standard practices
-s,--silentwill silence all stdout messages (keeping stderr for errors)-f,--forcewill override and bypass any warning raised during a WRITE operation-n,--dry-runwill display what would have happened during a WRITE operation-v,--verbosewill increase the verbosity to DEBUG level (the default is INFO)- ambiguous state resolution should ask for confirmation and default to no destruction (
-fwould force a "yes", and-nwould force a "no")
Typical Use¶
(Once the CLI is installed, see Installation Process first.)
% mkdir my-famlab
% cd my-famlab
% echo famlab-1 > inventory.ini
% echo famlab-2 >> inventory.ini
% echo famlab-3.example.com >> inventory.ini
% famlab bootstrap proxmox-ve.local
[…]
Famlab nodes 'famlab-1', 'famlab-2', 'famlab-3.example.com' bootstrapped successfully
% famlab deploy
[…]
Famlab nodes 'famlab-1', 'famlab-2', 'famlab-3.example.com' deployed successfully
% famlab ping
[…]
Famlab nodes 'famlab-1', 'famlab-2', 'famlab-3.example.com' pinged successfully
% famlab test
[…]
Famlab nodes 'famlab-1', 'famlab-2', 'famlab-3.example.com' tested successfully
Directory Structure¶
famlab.net/
├── bin/famlab # Main CLI router script
├── scripts/install.sh # Installation script for the CLI
└── share/famlab/ # Shared data
├── commands/ # Command implementations
│ ├── famlab-bootstrap # Create containers
│ ├── famlab-deploy # Configure services
│ ├── famlab-ping # Test connectivity
│ ├── famlab-test # Full service testing
│ └── famlab-user # User management
└── lib/ # Shared library functions
└── famlab-core.sh # Core functionality
Command Architecture¶
Main Router (bin/famlab)¶
- POSIX-compatible shell script
- Validates subcommand exists in
commands/directory - Routes execution to appropriate command script
- Provides top-level help and listing of available subcommands
Individual Commands (share/famlab/commands/famlab-*)¶
- Self-contained POSIX shell scripts
- Source shared library (
../lib/famlab-core.sh) - Implement specific functionality for Famlab management
- Handle their own argument parsing and validation
Shared Library (share/famlab/lib/famlab-core.sh)¶
- Common functions for Famlab operations
- Logging, error handling, container operations
- IP resolution, connectivity testing
- SMB configuration utilities
Command Specifications¶
famlab bootstrap PVE [HOSTNAME...]¶
Purpose: Create Proxmox VE containers for Famlab nodes
Functionality:
- SSH to Proxmox VE and create containers
- Default configuration: 1 CPU, 512MiB RAM, 32GiB disk, DHCP IPv4
- Install SSHd and allow current user to remote login as root
- Warn against invalid configuration (ask for confirmation)
- … both IPv4 and IPv6 disabled
- … less than 8GiB disk
- … less than 512MiB RAM
- Optional overrides via command arguments
- Bootstrap all hosts from inventory, unless hostnames are given as positional arguments
Arguments:
--cpu <cores>- Override CPU count--memory <mib>- Override memory allocation--disk <gib>- Override disk size--ipv4 dhcp|disabled- IPv4 configuration--ipv6 dhcp|disabled- IPv6 configuration--storage <pool>- Proxmox storage poolPVE- Proxmox VE hostname to execute remote commands from (SSH)[HOSTNAME...]- Bootstrap specific hosts only
Example:
% famlab bootstrap proxmox-ve.local
Remote logging to 'root@proxmox-ve.local' successful
famlab-1: container created
famlab-1: container booted
famlab-1: resolved to 192.168.0.101
famlab-2: container created
famlab-2: container booted
famlab-2: resolved to 192.168.0.102
famlab-3.example.com: container created
famlab-3.example.com: container booted
famlab-3.example.com: resolved to 192.168.0.103
Famlab nodes 'famlab-1', 'famlab-2', 'famlab-3.example.com' bootstrapped successfully
famlab deploy [HOSTNAME...]¶
Purpose: Configure existing containers as home backup servers
Functionality:
- Install and configure: Samba, Avahi, unattended-upgrades
- Configure mDNS resolution
- Set up basic SMB shares (homes, anonymous
backupshare) without users - Configure SMB to automatically create corresponding host users when SMB users are created
- Handle re-runs gracefully (e.g. update existing configuration in-place rather than appending)
- Deploy all hosts from inventory, unless hostnames are given as positional arguments
Arguments:
[HOSTNAME...]- Deploy specific hosts only
Example:
% famlab deploy
famlab-1: packages installed
famlab-1: Samba configured
famlab-1: unattended-upgrades configured
famlab-2: packages installed
famlab-2: Samba configured
famlab-2: unattended-upgrades configured
famlab-3.example.com: packages installed
famlab-3.example.com: Samba configured
famlab-3.example.com: unattended-upgrades configured
Famlab nodes 'famlab-1', 'famlab-2', 'famlab-3.example.com' deployed successfully
famlab ping [HOSTNAME...]¶
Purpose: Test network connectivity of containers
Functionality:
- Test network connectivity and hostname resolution via
ping - Display resolved IP addresses
- Ping all hosts from inventory, unless hostnames are given as positional arguments
Arguments:
[HOSTNAME...]- Ping specific hosts only
Example:
% famlab ping famlab-1 famlab-3.example.com
famlab-1: network connectivity tested
famlab-1: resolved to 192.168.0.101
famlab-3.example.com: network connectivity tested
famlab-3.example.com: resolved to 192.168.0.103
Famlab nodes 'famlab-1', 'famlab-2', 'famlab-3.example.com' pinged successfully
famlab test [HOSTNAME...]¶
Purpose: Test services of Famlab nodes
Functionality:
- Test remote login as root with SSH
- Test SMB service availability and configuration
- Test mDNS resolution
- Check basic SMB functionality (without user-specific tests)
- Test all hosts from inventory, unless hostnames are given as positional arguments
Arguments:
[HOSTNAME...]- Test specific hosts only
Example:
% famlab test famlab-1
famlab-1: remote logging as root successful
famlab-1: SMB is available and configured
famlab-1: anonymous SMB share is readable and writable
famlab-1: personal SMB share is readable and writable
famlab-1: mDNS resolved to 192.168.0.101
Famlab node 'famlab-1' tested successfully
famlab user HOSTNAME OPERATION¶
Purpose: Manage SMB/host user accounts on a Famlab node
Functionality:
- Manage SMB user accounts
- Set default password to username
Arguments:
HOSTNAME- Target Famlab nodeOPERATION- Where operation is one of:list(list existing users),add USERNAME(create a new SMB user),remove USERNAME(remove an SMB user)
Example:
% famlab user famlab-1 list
Famlab node 'famlab-1' has no SMB users
% famlab user famlab-1 add borjan
New user 'borjan' created on Famlab node 'famlab-1'
% famlab user famlab-1 list
Famlab node 'famlab-1' has 1 SMB user: 'borjan'
Installation Process¶
scripts/install.sh¶
- Copy
bin/famlabto$HOME/.local/bin/famlabwith executable permissions - Recursively copy
share/famlab/to${XDG_DATA_HOME:-$HOME/.local/share}/famlab/ - Ensure
$HOME/.local/binis in PATH (warn if not) - Set executable permissions on all command scripts
Paths¶
- Main CLI:
$HOME/.local/bin/famlab - Commands:
${XDG_DATA_HOME:-$HOME/.local/share}/famlab/commands/ - Library:
${XDG_DATA_HOME:-$HOME/.local/share}/famlab/lib/
Configuration File Format¶
Inventory File (inventory.ini)¶
Simple format for storing Famlab node information:
famlab-1
famlab-2
famlab-3.example.com
Format Rules:
- One hostname per line
- Empty lines ignored
Implementation Notes¶
Exit Codes¶
0- Success1- General error2- Invalid arguments3- Missing dependencies
Extension Points¶
Adding New Commands¶
- Create
share/famlab/commands/famlab-<newcommand> - Source
../lib/famlab-core.sh - Implement functionality
- Add help text and argument parsing
- Command automatically available via router
Library Extension¶
- Add new shared functions to
famlab-core.sh - Maintain backward compatibility
- Follow established naming conventions