initial transfer

This commit is contained in:
Benjamin Diedrichsen
2026-07-27 13:09:00 +02:00
parent 9f25d48dc2
commit 736c01216a
191 changed files with 17622 additions and 136 deletions
+130
View File
@@ -0,0 +1,130 @@
# user-add
**Add a user with Fish shell and tools**
## Purpose
This cube creates a new user account with a modern shell environment (Fish), SSH key authentication, and enhanced productivity tools pre-configured.
## What This Cube Does
1. **Creates a new user account**
- Sets up home directory with proper permissions
- Configures password authentication
- Adds user to specified groups (e.g., `docker`, `sudo`)
- Sets Fish as the default login shell
2. **Configures SSH access**
- Deploys the specified SSH public key for passwordless authentication
- Creates `.ssh` directory with proper permissions
- Sets up SSH config file
- Configures SSH agent auto-loading for Fish shell
3. **Installs Fish shell enhancements**
- Installs **Oh My Fish** (OMF) - Fish shell framework with themes and plugins
- Deploys custom Fish configuration (`config.fish`)
- Sets up Fish rc directory for modular configurations
4. **Creates workspace directories**
- Creates `/home/{USER}/tmp` directory for temporary files
## Configuration
### Parameters
- **USER** (string, auto-generated)
- Username for the new user account
- Default: `userXXXXX` (randomly generated 5-character suffix)
- **PASSWORD** (string, auto-generated)
- Password for the new user account
- Default: randomly generated secure password
- **GROUPS** (string, default: `''`)
- Comma-separated list of additional groups (e.g., `"docker,sudo"`)
- Common groups:
- `docker` - Run Docker without sudo
- `sudo` - Administrative privileges
- `www-data` - Web server file access
- **PUBKEY** (string, has default)
- SSH public key to authorize for the user
- Should be your public key for passwordless SSH access
## Dependencies
- **apt:essentials** - Provides Fish shell and basic tools
## What is Fish?
Fish (Friendly Interactive Shell) is a modern command-line shell that focuses on usability:
- **Smart autosuggestions**: Suggests commands as you type based on history
- **Syntax highlighting**: Color-codes commands in real-time
- **Tab completions**: Comprehensive, discoverable command completions
- **No configuration needed**: Works great out of the box
## Post-Installation
After deployment:
- SSH into the server as the new user: `ssh {USER}@server`
- Your SSH key will be pre-authorized (no password needed if using key)
- Fish shell will start automatically with OMF installed
- SSH agent auto-loads to manage your SSH keys
## Notes
- The user's home directory is created at `/home/{USER}`
- Fish configuration is stored in `/home/{USER}/.config/fish/`
- Oh My Fish provides package management: `omf install <package>`
- To switch shells: `chsh -s /bin/bash` (or back to fish: `chsh -s /usr/bin/fish`)
---
# 📌 Most Useful Fish Key Bindings (with Fisher Extensions)
## 🐟 Default Fish Key Bindings
- `Ctrl + C` → Cancel the current command
- `Ctrl + D` → Exit the shell (or logout if in SSH)
- `Ctrl + L` → Clear the terminal
- `Ctrl + R` → Search command history (enhanced by `fzf.fish`)
- `Ctrl + U` → Delete the entire command line
- `Ctrl + W` → Delete the last word
- `Alt + ← / →` → Move backward/forward by a word
## 🔍 Enhanced with `fzf.fish`
- `Ctrl + R`**Fuzzy search command history**
- `Ctrl + T`**Fuzzy search and insert file path**
- `Alt + C`**Fuzzy search directories (`cd` with `z`)**
## 📂 Directory Navigation (with `z`)
- `z <dir>` → Jump to a frequently used directory
- `z -l` → List most-used directories
- `z -c` → Remove a directory from `z`'s database
## 🔄 Process & Job Management
- `Ctrl + Z` → Suspend the current process
- `fg` → Bring a suspended process back to foreground
- `jobs` → List background jobs
## 🎨 Other Handy Shortcuts
- `fish_vi_key_bindings` → Enable Vi mode (press `Esc` for normal mode)
- `Ctrl + G` → Show Git status (if using `fzf.fish`)
- `Ctrl + E` → Edit command line in `$EDITOR`
## ⚙️ Useful Commands for Key Binding
```fish
# Set Fish default key bindings
fish_default_key_bindings
# Enable Vi mode
fish_vi_key_bindings
# Rebind a custom key (Example: Ctrl + G for git status)
bind \cg 'git status'
+10
View File
@@ -0,0 +1,10 @@
if status is-interactive
# Commands to run in interactive sessions can go here
# Execute all scripts in ~/.config/fish/rc/ on shell startup
for script in ~/.config/fish/rc/*.fish
if test -f $script
source $script
end
end
end
+90
View File
@@ -0,0 +1,90 @@
from pyinfra import host
from pyinfra.operations import server, files, apt
from io import StringIO
# Define the username, password, and public key for the new admin user
USER = host.data.USER
HOME_DIR = f"/home/{USER}"
TMP_DIR = f"{HOME_DIR}/tmp"
PASSWORD = host.data.PASSWORD
PUBKEY = host.data.PUBKEY
GROUPS = list(filter(None, map(str.strip, str(host.data.GROUPS).split())))
FISH_PATH = "/usr/bin/fish"
FISH_CONFIG_DIR = f"{HOME_DIR}/.config/fish"
FISH_CONFIG_FILE = f"{FISH_CONFIG_DIR}/config.fish"
FISH_RC_DIR = f"{FISH_CONFIG_DIR}/rc"
SSH_AGENT_SCRIPT = f"{FISH_RC_DIR}/ssh-agent.fish"
apt.packages(
name='Ensure fish shell is installed',
packages=[ 'fish'],
_sudo=True
)
# Ensure the user exists with a login shell
server.user(
name=f"Create user {USER} [{GROUPS}]",
present=True,
user=USER,
password=PASSWORD,
create_home=True,
groups=GROUPS,
shell=FISH_PATH,
public_keys=[PUBKEY],
_sudo=True
)
for dir in [f"{HOME_DIR}/.ssh", FISH_RC_DIR, TMP_DIR]:
files.directory(
name=f"Ensure {dir} directory exists",
path=dir,
present=True,
mode=700,
user=USER,
group=USER,
_sudo=True,
_sudo_user=USER,
_use_sudo_login=True
)
files.file(
name="Ensure .ssh/config exists",
path=f"{HOME_DIR}/.ssh/config",
present=True,
user=USER,
group=USER,
_sudo=True
)
server.shell(
name=f"Install OMF(Oh My Fish) for {USER}",
commands=[
f"curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install > install-omf",
f"fish install-omf --yes --noninteractive",
],
_sudo=True,
_sudo_user=USER,
_use_sudo_login=True
)
files.put(
name="Add SSH agent auto-load script to Fish rc directory",
src="ssh-agent.fish",
dest=SSH_AGENT_SCRIPT,
user=USER,
group=USER,
mode="755", # Make it executable
_sudo=True,
)
files.put(
name="Add custom config.fish",
src="config.fish",
dest=FISH_CONFIG_FILE,
user=USER,
group=USER,
mode="755", # Make it executable
_sudo=True,
)
+25
View File
@@ -0,0 +1,25 @@
import { cubes } from '@bitstack/nopy';
import { z } from 'zod';
export default cubes.Manifest({
id: 'user:add',
name: 'Add a user with fish shell and tools',
dependencies: () => ['apt:essentials'],
schema: z.object({
USER: z
.string()
.describe('Username for the new user account')
.default(() => `user${cubes.uniqid(5)}`),
PASSWORD: z.string().describe('Password for the new user account').default(cubes.uniqid),
GROUPS: z
.string()
.describe('Comma-separated list of additional groups (e.g., "docker,sudo")')
.default(''),
PUBKEY: z
.string()
.describe('SSH public key to authorize for the user')
.default(
'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICpnZ6IxwQKL1rBE4dy7w5Sd3s2tLFZUDfjH87C1QIlc bdiedrichsen@Benjamins-MBP.lan'
),
}),
});
+14
View File
@@ -0,0 +1,14 @@
# Start SSH agent if not already running
if not set -q SSH_AUTH_SOCK
eval (ssh-agent -c)
end
# Add all private SSH keys in ~/.ssh to the agent
for key in ~/.ssh/id_*;
if test -f $key; and not string match -q "*pub" $key
ssh-add $key 2>/dev/null
end
end
# Export user and group ID for Docker
set -x UID (id -u)
set -x GID (id -g)