labops 0.3.0__tar.gz → 0.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. labops-0.3.2/.release-please-manifest.json +3 -0
  2. {labops-0.3.0 → labops-0.3.2}/CHANGELOG.md +14 -0
  3. {labops-0.3.0 → labops-0.3.2}/PKG-INFO +2 -2
  4. {labops-0.3.0 → labops-0.3.2}/README.md +1 -1
  5. {labops-0.3.0 → labops-0.3.2}/labops_cli.py +2 -2
  6. {labops-0.3.0/models/inputConf → labops-0.3.2/models/input_conf}/hosts.py +1 -1
  7. {labops-0.3.0/models/inputConf → labops-0.3.2/models/input_conf}/settings.py +1 -1
  8. labops-0.3.0/models/inputConf/YamlRoot.py → labops-0.3.2/models/input_conf/yaml_root.py +2 -2
  9. {labops-0.3.0 → labops-0.3.2}/pyproject.toml +4 -1
  10. {labops-0.3.0 → labops-0.3.2}/src/cli/core.py +1 -1
  11. {labops-0.3.0 → labops-0.3.2}/src/cli/host.py +5 -5
  12. {labops-0.3.0 → labops-0.3.2}/src/cli/lxc.py +4 -4
  13. {labops-0.3.0 → labops-0.3.2}/src/cli/validate.py +2 -2
  14. {labops-0.3.0 → labops-0.3.2}/src/cli/vm.py +2 -2
  15. {labops-0.3.0 → labops-0.3.2}/src/host/find.py +2 -2
  16. {labops-0.3.0 → labops-0.3.2}/src/host/setup.py +6 -4
  17. {labops-0.3.0 → labops-0.3.2}/src/host/update.py +7 -5
  18. {labops-0.3.0 → labops-0.3.2}/src/lxc/find.py +2 -2
  19. {labops-0.3.0 → labops-0.3.2}/src/lxc/update.py +4 -4
  20. {labops-0.3.0 → labops-0.3.2}/src/utils/ansible_runner.py +7 -6
  21. {labops-0.3.0 → labops-0.3.2}/src/utils/yaml_validator.py +1 -1
  22. {labops-0.3.0 → labops-0.3.2}/src/vm/find.py +2 -2
  23. {labops-0.3.0 → labops-0.3.2}/uv.lock +1 -1
  24. labops-0.3.0/.release-please-manifest.json +0 -3
  25. {labops-0.3.0 → labops-0.3.2}/.devcontainer/devcontainer.json +0 -0
  26. {labops-0.3.0 → labops-0.3.2}/.github/dependabot.yml +0 -0
  27. {labops-0.3.0 → labops-0.3.2}/.github/workflows/publish.yml +0 -0
  28. {labops-0.3.0 → labops-0.3.2}/.github/workflows/release_please.yml +0 -0
  29. {labops-0.3.0 → labops-0.3.2}/.gitignore +0 -0
  30. {labops-0.3.0 → labops-0.3.2}/.pre-commit-config.yaml +0 -0
  31. {labops-0.3.0 → labops-0.3.2}/.python-version +0 -0
  32. {labops-0.3.0 → labops-0.3.2}/LICENSE +0 -0
  33. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/setup/alpine.yml +0 -0
  34. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/setup/common.yml +0 -0
  35. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/setup/debian.yml +0 -0
  36. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/setup/redhat.yml +0 -0
  37. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/setup.yml +0 -0
  38. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/update/alpine.yml +0 -0
  39. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/update/debian.yml +0 -0
  40. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/update/redhat.yml +0 -0
  41. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/host/update.yml +0 -0
  42. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/lxc/update/alpine.yml +0 -0
  43. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/lxc/update/debian.yml +0 -0
  44. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/lxc/update/redhat.yml +0 -0
  45. {labops-0.3.0 → labops-0.3.2}/ansible/playbooks/lxc/update.yml +0 -0
  46. {labops-0.3.0 → labops-0.3.2}/ansible/requirements.yml +0 -0
  47. {labops-0.3.0 → labops-0.3.2}/img/Cover.png +0 -0
  48. {labops-0.3.0 → labops-0.3.2}/justfile +0 -0
  49. {labops-0.3.0/models/inputConf → labops-0.3.2/models/input_conf}/creds.py +0 -0
  50. {labops-0.3.0 → labops-0.3.2}/release-please-config.json +0 -0
  51. {labops-0.3.0 → labops-0.3.2}/src/host/__init__.py +0 -0
  52. {labops-0.3.0 → labops-0.3.2}/src/lxc/__init__.py +0 -0
  53. {labops-0.3.0 → labops-0.3.2}/src/utils/__init__.py +0 -0
  54. {labops-0.3.0 → labops-0.3.2}/src/vm/__init__.py +0 -0
  55. {labops-0.3.0 → labops-0.3.2}/test-samples/docker/homeassistant/docker-compose.yaml +0 -0
  56. {labops-0.3.0 → labops-0.3.2}/test-samples/docker/nebula-sync/docker-compose.yaml +0 -0
  57. {labops-0.3.0 → labops-0.3.2}/test-samples/docker/nginx/docker-compose.yaml +0 -0
  58. {labops-0.3.0 → labops-0.3.2}/test-samples/homelab-complete.yml +0 -0
  59. {labops-0.3.0 → labops-0.3.2}/test-samples/homelab-test.yml +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.3.2"
3
+ }
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.2](https://github.com/FreezeManny/labops/compare/labops-v0.3.1...labops-v0.3.2) (2026-04-21)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * Added LXC to Readme ([abb1910](https://github.com/FreezeManny/labops/commit/abb1910e8d427d93125ee81c062debe906f60d43))
9
+
10
+ ## [0.3.1](https://github.com/FreezeManny/labops/compare/labops-v0.3.0...labops-v0.3.1) (2026-04-21)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * ansible directory not in built package ([33bc327](https://github.com/FreezeManny/labops/commit/33bc32740934daed8827c9d1c30a7a1d7e38b4bc))
16
+
3
17
  ## [0.3.0](https://github.com/FreezeManny/labops/compare/labops-v0.2.1...labops-v0.3.0) (2026-04-21)
4
18
 
5
19
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labops
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: YAML Based homeLAB
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.14
@@ -21,10 +21,10 @@ A declarative, YAML-based homelab manager. `labops` is a CLI tool designed to si
21
21
  ### Current Capabilities
22
22
  - **Declarative YAML Configuration**: Define your complete homelab environment comprehensively using simple YAML configuration files.
23
23
  - **Host Management**: Automated setup, initialization, and system updates for a variety of host operating systems (Alpine, Debian, RedHat) powered by integrated Ansible playbooks.
24
+ - **Proxmox LXC**: Update Proxmox Linux Containers (LXC) natively (through Proxmox Root Host)
24
25
 
25
26
  ### Roadmap & Future Scope
26
27
  - **Docker Stack Management**: Seamlessly deploy, spin up, and manage Docker Compose stacks across your nodes.
27
- - **Proxmox LXC**: Update Proxmox Linux Containers (LXC) natively.
28
28
  - **DNS Automation**: Automated updating of internal DNS records.
29
29
  - **Reverse Proxy Orchestration**: Manage, update, and automate reverse proxy routes
30
30
 
@@ -7,10 +7,10 @@ A declarative, YAML-based homelab manager. `labops` is a CLI tool designed to si
7
7
  ### Current Capabilities
8
8
  - **Declarative YAML Configuration**: Define your complete homelab environment comprehensively using simple YAML configuration files.
9
9
  - **Host Management**: Automated setup, initialization, and system updates for a variety of host operating systems (Alpine, Debian, RedHat) powered by integrated Ansible playbooks.
10
+ - **Proxmox LXC**: Update Proxmox Linux Containers (LXC) natively (through Proxmox Root Host)
10
11
 
11
12
  ### Roadmap & Future Scope
12
13
  - **Docker Stack Management**: Seamlessly deploy, spin up, and manage Docker Compose stacks across your nodes.
13
- - **Proxmox LXC**: Update Proxmox Linux Containers (LXC) natively.
14
14
  - **DNS Automation**: Automated updating of internal DNS records.
15
15
  - **Reverse Proxy Orchestration**: Manage, update, and automate reverse proxy routes
16
16
 
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from models.inputConf.YamlRoot import YamlRoot
2
+ from models.input_conf.yaml_root import YamlRoot
3
3
  import typer
4
4
  from rich.console import Console
5
5
 
@@ -11,7 +11,7 @@ from src.cli.validate import app as validate_app
11
11
 
12
12
  # ------------- APP -----------------
13
13
  app = typer.Typer(
14
- help="[bold cyan]LabOPS CLI[/bold cyan] — manage homelab hosts, VMs and more from a single YAML.",
14
+ help="[bold cyan]LabOPS CLI[/bold cyan] — manage homelab hosts, LXCs, VMs and more from a single YAML.",
15
15
  rich_markup_mode="rich",
16
16
  no_args_is_help=True,
17
17
  )
@@ -2,7 +2,7 @@ from pydantic import BaseModel, model_validator, DirectoryPath
2
2
  from typing import Optional, Dict, Any, Literal
3
3
  from ipaddress import IPv4Address
4
4
 
5
- from models.inputConf.creds import Creds
5
+ from models.input_conf.creds import Creds
6
6
 
7
7
  OSType = Literal["debian", "alpine", "redhat"]
8
8
  HostType = Literal["bare-metal", "proxmox"]
@@ -2,7 +2,7 @@ from pydantic import BaseModel, FilePath, model_validator
2
2
  from typing import Optional
3
3
  from ipaddress import IPv4Address
4
4
 
5
- from models.inputConf.creds import Creds
5
+ from models.input_conf.creds import Creds
6
6
 
7
7
  class Dns(BaseModel):
8
8
  local_dns_suffix: str
@@ -1,8 +1,8 @@
1
1
  from pydantic import BaseModel, model_validator
2
2
  from typing import Optional, Dict
3
3
 
4
- from models.inputConf.hosts import Host
5
- from models.inputConf.settings import Settings
4
+ from models.input_conf.hosts import Host
5
+ from models.input_conf.settings import Settings
6
6
 
7
7
  class YamlRoot(BaseModel):
8
8
  settings: Settings
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "labops"
3
- version = "0.3.0"
3
+ version = "0.3.2"
4
4
  description = "YAML Based homeLAB"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -20,6 +20,9 @@ build-backend = "hatchling.build"
20
20
  [tool.hatch.build.targets.wheel]
21
21
  packages = ["src", "models", "labops_cli.py"]
22
22
 
23
+ [tool.hatch.build.targets.wheel.force-include]
24
+ "ansible" = "ansible"
25
+
23
26
  [project.scripts]
24
27
  labops = "labops_cli:main"
25
28
 
@@ -5,7 +5,7 @@ import typer
5
5
  import yaml
6
6
  from rich.console import Console
7
7
  from src.utils.yaml_validator import validate_yaml
8
- from models.inputConf.YamlRoot import YamlRoot
8
+ from models.input_conf.yaml_root import YamlRoot
9
9
 
10
10
  # ─── Shared state ─────────────────────────────────────────────────────────────
11
11
 
@@ -2,9 +2,9 @@ from typing import Optional
2
2
  import typer
3
3
  from rich.table import Table
4
4
 
5
- from src.cli.core import get_model, resolve_targets, console
6
- from models.inputConf.YamlRoot import YamlRoot
7
- from models.inputConf.hosts import Host
5
+ from src.cli.core import get_model, resolve_targets, console, state
6
+ from models.input_conf.yaml_root import YamlRoot
7
+ from models.input_conf.hosts import Host
8
8
  import src.host as host
9
9
 
10
10
  app = typer.Typer(help="Manage bare-metal hosts.", no_args_is_help=True)
@@ -18,7 +18,7 @@ def host_setup(
18
18
  model: YamlRoot = get_model()
19
19
  hosts = resolve_targets(model, target, False,
20
20
  host.find, host.findAll, label="host")
21
- host.setup(hosts[0], model.settings.default_creds)
21
+ host.setup(hosts[0], model.settings.default_creds, dry_run=state.dry_run, verbose=state.verbose)
22
22
 
23
23
  @app.command("update")
24
24
  def host_update(
@@ -33,7 +33,7 @@ def host_update(
33
33
  model: YamlRoot = get_model()
34
34
  hosts: list[Host] = resolve_targets(model, target, all, host.find,
35
35
  host.findAll, label="host")
36
- host.update(hosts, model.settings.default_creds)
36
+ host.update(hosts, model.settings.default_creds, dry_run=state.dry_run, verbose=state.verbose)
37
37
 
38
38
  @app.command("list")
39
39
  def host_list() -> None:
@@ -3,9 +3,9 @@ from typing import Optional
3
3
  import typer
4
4
  from rich.table import Table
5
5
 
6
- from src.cli.core import get_model, resolve_targets, console
7
- from models.inputConf.YamlRoot import YamlRoot
8
- from models.inputConf.hosts import LXC, Host
6
+ from src.cli.core import get_model, resolve_targets, console, state
7
+ from models.input_conf.yaml_root import YamlRoot
8
+ from models.input_conf.hosts import LXC, Host
9
9
  import src.lxc as lxc
10
10
 
11
11
  app = typer.Typer(help="Manage Proxmox LXC containers from Config.", no_args_is_help=True)
@@ -50,4 +50,4 @@ def execute_update(
50
50
  targets: list[tuple[Host, LXC]] = resolve_targets(model, target, all, lxc.find,lxc.findAll, label="LXC")
51
51
 
52
52
  # Pass them directly to the Ansible builder
53
- lxc.update(targets, model.settings.default_creds)
53
+ lxc.update(targets, model.settings.default_creds, dry_run=state.dry_run, verbose=state.verbose)
@@ -4,8 +4,8 @@ from pathlib import Path
4
4
  from rich.table import Table
5
5
 
6
6
  from src.cli.core import ConfigError, get_model, console
7
- from models.inputConf.YamlRoot import YamlRoot
8
- from models.inputConf.hosts import Host
7
+ from models.input_conf.yaml_root import YamlRoot
8
+ from models.input_conf.hosts import Host
9
9
 
10
10
  app = typer.Typer(help="Validate configuration.")
11
11
 
@@ -3,8 +3,8 @@ import typer
3
3
  from rich.table import Table
4
4
 
5
5
  from src.cli.core import get_model, resolve_targets, console
6
- from models.inputConf.YamlRoot import YamlRoot
7
- from models.inputConf.hosts import Host
6
+ from models.input_conf.yaml_root import YamlRoot
7
+ from models.input_conf.hosts import Host
8
8
  import src.vm as vm
9
9
 
10
10
  app = typer.Typer(help="Manage virtual machines.", no_args_is_help=True)
@@ -1,5 +1,5 @@
1
- from models.inputConf.YamlRoot import YamlRoot
2
- from models.inputConf.hosts import Host
1
+ from models.input_conf.yaml_root import YamlRoot
2
+ from models.input_conf.hosts import Host
3
3
 
4
4
  def findAll(config: YamlRoot) -> list[Host]:
5
5
  if config.hosts is None:
@@ -2,11 +2,11 @@ from ansible_runner.runner import Runner
2
2
  from pathlib import Path
3
3
  import getpass
4
4
 
5
- from models.inputConf.hosts import Host
6
- from models.inputConf.creds import Creds
5
+ from models.input_conf.hosts import Host
6
+ from models.input_conf.creds import Creds
7
7
  from src.utils.ansible_runner import run_playbook
8
8
 
9
- def setup(host: Host, default_creds: Creds) -> None:
9
+ def setup(host: Host, default_creds: Creds, dry_run: bool = False, verbose: bool = False) -> None:
10
10
  creds: Creds = host.creds or default_creds
11
11
 
12
12
  if not creds.ssh_key_path:
@@ -65,7 +65,9 @@ def setup(host: Host, default_creds: Creds) -> None:
65
65
  r: Runner = run_playbook(
66
66
  playbook=f"host/setup.yml",
67
67
  inventory=inventory,
68
- extravars=extravars
68
+ extravars=extravars,
69
+ dry_run=dry_run,
70
+ verbose=verbose
69
71
  )
70
72
 
71
73
  if r.rc == 0:
@@ -1,10 +1,10 @@
1
1
  from ansible_runner.runner import Runner
2
- from models.inputConf.hosts import Host
3
- from models.inputConf.hosts import OSType
4
- from models.inputConf.creds import Creds
2
+ from models.input_conf.hosts import Host
3
+ from models.input_conf.hosts import OSType
4
+ from models.input_conf.creds import Creds
5
5
  from src.utils.ansible_runner import run_playbook
6
6
 
7
- def update(hosts: list[Host], default_creds: Creds) -> None:
7
+ def update(hosts: list[Host], default_creds: Creds, dry_run: bool = False, verbose: bool = False) -> None:
8
8
  # Group hosts by OS to run the correct playbooks
9
9
  hosts_by_os: dict[OSType, list[Host]] = {}
10
10
  for host in hosts:
@@ -43,7 +43,9 @@ def update(hosts: list[Host], default_creds: Creds) -> None:
43
43
 
44
44
  r: Runner = run_playbook(
45
45
  playbook="host/update.yml",
46
- inventory=inventory
46
+ inventory=inventory,
47
+ dry_run=dry_run,
48
+ verbose=verbose
47
49
  )
48
50
 
49
51
  if r.rc == 0:
@@ -1,6 +1,6 @@
1
1
  from src.utils.ansible_runner import run_playbook
2
- from models.inputConf.YamlRoot import YamlRoot
3
- from models.inputConf.hosts import Host, LXC
2
+ from models.input_conf.yaml_root import YamlRoot
3
+ from models.input_conf.hosts import Host, LXC
4
4
 
5
5
  def findAll(config: YamlRoot) -> list[tuple[Host, LXC]]:
6
6
  """Returns a list of all LXCs found inside Proxmox hosts in the Yaml config."""
@@ -1,8 +1,8 @@
1
1
  from src.utils.ansible_runner import run_playbook
2
- from models.inputConf.hosts import Host, LXC
3
- from models.inputConf.creds import Creds
2
+ from models.input_conf.hosts import Host, LXC
3
+ from models.input_conf.creds import Creds
4
4
 
5
- def update(proxmox_lxc_pairs: list[tuple[Host, LXC]], default_creds: Creds) -> None:
5
+ def update(proxmox_lxc_pairs: list[tuple[Host, LXC]], default_creds: Creds, dry_run: bool = False, verbose: bool = False) -> None:
6
6
  """
7
7
  Builds a dynamic ansible inventory from the Yaml config and proxies the
8
8
  commands via community.proxmox.proxmox_pct_remote inside community OS groups.
@@ -39,4 +39,4 @@ def update(proxmox_lxc_pairs: list[tuple[Host, LXC]], default_creds: Creds) -> N
39
39
 
40
40
  inventory["all"]["children"][group_name]["hosts"][lxc_obj.name] = host_vars
41
41
 
42
- run_playbook(playbook="lxc/update.yml", inventory=inventory)
42
+ run_playbook(playbook="lxc/update.yml", inventory=inventory, dry_run=dry_run, verbose=verbose)
@@ -6,7 +6,7 @@ from typing import Optional
6
6
  project_root: str = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
7
7
  playbook_root: str = os.path.join(project_root, "ansible", "playbooks")
8
8
 
9
- def run_playbook(playbook: str, inventory: dict, extravars: Optional[dict] = None) -> Runner:
9
+ def run_playbook(playbook: str, inventory: dict, extravars: Optional[dict] = None, dry_run: bool = False, verbose: bool = False) -> Runner:
10
10
  """
11
11
  Wrapper for ansible_runner.run with standard application settings.
12
12
  """
@@ -25,14 +25,15 @@ def run_playbook(playbook: str, inventory: dict, extravars: Optional[dict] = Non
25
25
  if extravars:
26
26
  kwargs["extravars"] = extravars
27
27
 
28
- from src.cli.core import state
29
28
  cmdline = []
30
- if getattr(state, "dry_run", False):
29
+ if dry_run:
31
30
  cmdline.append("--check")
32
- if getattr(state, "verbose", False):
31
+ if verbose:
33
32
  cmdline.append("-v")
34
33
 
35
34
  if cmdline:
36
35
  kwargs["cmdline"] = " ".join(cmdline)
37
-
38
- return ansible_runner.run(**kwargs)
36
+
37
+ runner = ansible_runner.run(**kwargs)
38
+ return runner
39
+ return runner
@@ -3,7 +3,7 @@ from pydantic import ValidationError
3
3
  import os
4
4
  from pathlib import Path
5
5
 
6
- from models.inputConf.YamlRoot import YamlRoot
6
+ from models.input_conf.yaml_root import YamlRoot
7
7
 
8
8
 
9
9
  def validate_yaml(raw: Dict[str, Any], rootPath: str) -> Optional[YamlRoot]:
@@ -1,5 +1,5 @@
1
- from models.inputConf.YamlRoot import YamlRoot
2
- from models.inputConf.hosts import Host
1
+ from models.input_conf.yaml_root import YamlRoot
2
+ from models.input_conf.hosts import Host
3
3
 
4
4
 
5
5
  def findAll(config: YamlRoot) -> list[Host]:
@@ -268,7 +268,7 @@ wheels = [
268
268
 
269
269
  [[package]]
270
270
  name = "labops"
271
- version = "0.3.0"
271
+ version = "0.3.2"
272
272
  source = { editable = "." }
273
273
  dependencies = [
274
274
  { name = "ansible-core" },
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.3.0"
3
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes