README & other things
This commit is contained in:
parent
eddf850c4f
commit
c207a8a038
|
|
@ -0,0 +1,107 @@
|
||||||
|
# lxcd
|
||||||
|
|
||||||
|
A Distrobox-like wrapper for LXD: it creates, manages, and enters LXD dev
|
||||||
|
containers as drop-in development environments, mapped to your host workspace
|
||||||
|
and home.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- LXD (`lxc`) reachable on your host — either the user is in the `lxd`
|
||||||
|
group (invoked directly) or `sudo lxc` is used
|
||||||
|
- Python 3.9+
|
||||||
|
- Bash completion (optional): `lxcd.completion`
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make install # copies lxcd.py to /usr/local/bin/lxcd + installs completion
|
||||||
|
```
|
||||||
|
|
||||||
|
Or run in place from this directory:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./lxcd.py --help
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
```sh
|
||||||
|
lxcd init # write ~/.lxcdrc (never shown; edit with -e)
|
||||||
|
lxcd init -e # open the config in $EDITOR, created first if missing
|
||||||
|
|
||||||
|
lxcd create web1 # new container "web1" (defaults from ~/.lxcdrc)
|
||||||
|
lxcd ls # alias for "list"
|
||||||
|
lxcd enter web1 # cloud-init workspaces + mappings auto-applied
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `init` | Write/edit the `~/.lxcdrc` config |
|
||||||
|
| `create` | Create a new container (defaults from config) |
|
||||||
|
| `clone <src> <name>` | Clone an existing managed container |
|
||||||
|
| `rename\|mv <old> <new>` | Rename a container |
|
||||||
|
| `enter <name>` | Enter a container (applies workspace + mappings) |
|
||||||
|
| `list\|ls` | List managed containers |
|
||||||
|
| `delete\|stop\|start\|restart` | Operate on containers (`-a` for all) |
|
||||||
|
|
||||||
|
Run `lxcd <command> --help` for full options.
|
||||||
|
|
||||||
|
## Config (`~/.lxcdrc`)
|
||||||
|
|
||||||
|
INI format. Keys:
|
||||||
|
|
||||||
|
- `[options]` — `workspace`, `image`, `nested`, `aptcache`, `ssh`
|
||||||
|
(absolute paths OK for `workspace`/`image` when used as-is)
|
||||||
|
- `[packages]` — default apt packages installed at create time
|
||||||
|
- `[mappings]` under `[options]` or top-level — a list of host paths to
|
||||||
|
mount into every container. A spec ending in `/` mounts a directory;
|
||||||
|
an absolute host path (starting with `/`) is used **as-is** (not relative to
|
||||||
|
`~`) and mounts at the same path in the container.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[options]
|
||||||
|
workspace=/home/andrew/Code # absolute — mounted as-is
|
||||||
|
image=ubuntu:
|
||||||
|
nested=true
|
||||||
|
aptcache=http://10.0.0.1:3142
|
||||||
|
ssh=ssh-ed25519 AAAA...andrew@host
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
git
|
||||||
|
vim
|
||||||
|
|
||||||
|
[mappings]
|
||||||
|
configs/ # directory: ~/configs -> /home/<user>/configs/
|
||||||
|
notes # file: ~/notes -> /home/<user>/notes
|
||||||
|
/etc/hosts # absolute: used as-is
|
||||||
|
```
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Containers are tagged with `user.lxcd=true` for listing.
|
||||||
|
- `security.nesting` is enabled when `nested=true` (cli `-n/--nested`).
|
||||||
|
- Disk mounts use `shift=true` so container writes map cleanly to the host.
|
||||||
|
- `enter` mounts the `[options] workspace=` host dir into the container and
|
||||||
|
applies `[mappings]` before running an interactive shell as the host user.
|
||||||
|
|
||||||
|
## Completion
|
||||||
|
|
||||||
|
`lxcd.completion` (bash). Keep it sourced for container-name + option
|
||||||
|
completion, including `lxcd list --brief [cols]`.
|
||||||
|
|
||||||
|
## Building a snap
|
||||||
|
|
||||||
|
```sh
|
||||||
|
snapcraft --destructive-mode -v
|
||||||
|
```
|
||||||
|
|
||||||
|
produces `lxcd_0.1.0_amd64.snap` (version pinned in `snap/snapcraft.yaml`).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT.
|
||||||
|
</content>
|
||||||
|
|
@ -66,6 +66,14 @@ _lxcd_completion() {
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
list|ls)
|
||||||
|
if [[ "$cur" == -* ]]; then
|
||||||
|
COMPREPLY=($(compgen -W "-b --brief" -- "$cur"))
|
||||||
|
else
|
||||||
|
COMPREPLY=($(compgen -W "ipv4 status,ipv4 image,ipv4 packages,ipv4 opts image,packages,opts ipv4,image,packages" -- "$cur"))
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
13
lxcd.py
13
lxcd.py
|
|
@ -433,12 +433,17 @@ def apply_mappings(name, host_username, host_home):
|
||||||
paths = cfg.get("mappings")
|
paths = cfg.get("mappings")
|
||||||
if not isinstance(paths, list) or not paths:
|
if not isinstance(paths, list) or not paths:
|
||||||
return
|
return
|
||||||
for idx, path in enumerate(paths):
|
for idx, spec in enumerate(paths):
|
||||||
host_path = host_home / path
|
is_dir = spec.endswith("/")
|
||||||
container_path = f"/home/{host_username}/{path}"
|
if spec.startswith("/"):
|
||||||
|
host_path = spec.rstrip("/")
|
||||||
|
container_path = spec
|
||||||
|
else:
|
||||||
|
host_path = str(host_home / spec.rstrip("/"))
|
||||||
|
container_path = f"/home/{host_username}/{spec}"
|
||||||
lxc_subprocess(["config", "device", "remove", name, f"map-{idx}"],
|
lxc_subprocess(["config", "device", "remove", name, f"map-{idx}"],
|
||||||
capture_output=True, text=True, check=False)
|
capture_output=True, text=True, check=False)
|
||||||
if host_path.exists():
|
if os.path.exists(host_path):
|
||||||
lxc_run(["config", "device", "add", name, f"map-{idx}", "disk",
|
lxc_run(["config", "device", "add", name, f"map-{idx}", "disk",
|
||||||
f"source={host_path}",
|
f"source={host_path}",
|
||||||
f"path={container_path}",
|
f"path={container_path}",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
name: lxcd
|
name: lxcd
|
||||||
base: core22
|
base: core22
|
||||||
version: git
|
version: 0.1.0
|
||||||
summary: A Distrobox-like wrapper for LXD
|
summary: A Distrobox-like wrapper for LXD
|
||||||
description: |
|
description: |
|
||||||
lxcd provides a Distrobox-like experience using LXD containers.
|
lxcd provides a Distrobox-like experience using LXD containers.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue