aap-demo 2.0.0.dev0__py3-none-any.whl
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.
- aap_demo/__init__.py +6 -0
- aap_demo/__main__.py +10 -0
- aap_demo/cli/__init__.py +0 -0
- aap_demo/cli/_schema_args.py +137 -0
- aap_demo/cli/addons.py +21 -0
- aap_demo/cli/completion.py +16 -0
- aap_demo/cli/day2.py +17 -0
- aap_demo/cli/gui.py +12 -0
- aap_demo/cli/lifecycle.py +156 -0
- aap_demo/cli/main.py +565 -0
- aap_demo/cli/observe.py +68 -0
- aap_demo/cli/ops.py +378 -0
- aap_demo/cluster/__init__.py +3 -0
- aap_demo/cluster/aap.py +907 -0
- aap_demo/cluster/bootstrap.py +662 -0
- aap_demo/cluster/catalog_signature.py +575 -0
- aap_demo/cluster/coredns.py +337 -0
- aap_demo/cluster/deploy.py +369 -0
- aap_demo/cluster/ingress_ca.py +316 -0
- aap_demo/cluster/kubeconfig.py +190 -0
- aap_demo/cluster/namespace.py +136 -0
- aap_demo/cluster/olm.py +276 -0
- aap_demo/cluster/preflight.py +134 -0
- aap_demo/cluster/pull_secret.py +380 -0
- aap_demo/cluster/runtime.py +324 -0
- aap_demo/cluster/scc.py +174 -0
- aap_demo/cluster/status.py +582 -0
- aap_demo/cluster/storage.py +73 -0
- aap_demo/core/__init__.py +0 -0
- aap_demo/core/bash_v1.py +171 -0
- aap_demo/core/config.py +219 -0
- aap_demo/core/console.py +907 -0
- aap_demo/core/context.py +65 -0
- aap_demo/core/errors.py +84 -0
- aap_demo/core/events.py +135 -0
- aap_demo/core/migration.py +369 -0
- aap_demo/core/output.py +43 -0
- aap_demo/core/paths.py +173 -0
- aap_demo/core/prompts.py +51 -0
- aap_demo/core/schema.py +164 -0
- aap_demo/core/secrets.py +221 -0
- aap_demo/core/version.py +101 -0
- aap_demo/core/waiting.py +89 -0
- aap_demo/data/__init__.py +27 -0
- aap_demo/data/crc-release +1 -0
- aap_demo/data/crs/__init__.py +1 -0
- aap_demo/data/crs/aap-controller-eda.yaml +16 -0
- aap_demo/data/crs/aap-controller.yaml +16 -0
- aap_demo/data/crs/aap-minimal-noingress.yaml +63 -0
- aap_demo/data/crs/aap-minimal-rwx.yaml +21 -0
- aap_demo/data/crs/aap-minimal.yaml +48 -0
- aap_demo/data/manifests/__init__.py +1 -0
- aap_demo/data/manifests/aap-storage-pvcs.yaml +31 -0
- aap_demo/data/manifests/nfs-provisioner.yaml +113 -0
- aap_demo/data/manifests/nfs-server.yaml +76 -0
- aap_demo/data/olm/__init__.py +1 -0
- aap_demo/data/olm/catalogsource.yaml +27 -0
- aap_demo/data/olm/operatorgroup.yaml +15 -0
- aap_demo/data/olm/subscription.yaml +18 -0
- aap_demo/data/schema/__init__.py +0 -0
- aap_demo/data/schema/addons.yaml +30 -0
- aap_demo/data/schema/core.yaml +59 -0
- aap_demo/data/schema/crc.yaml +78 -0
- aap_demo/data/schema/deploy.yaml +74 -0
- aap_demo/data/schema/gui.yaml +52 -0
- aap_demo/data/schema/playbooks.yaml +88 -0
- aap_demo/data/schema/secrets.yaml +19 -0
- aap_demo/data/schema/trust.yaml +28 -0
- aap_demo/diagnostics/__init__.py +3 -0
- aap_demo/diagnostics/checks.py +388 -0
- aap_demo/diagnostics/report.py +55 -0
- aap_demo/exec/__init__.py +0 -0
- aap_demo/exec/kubectl.py +65 -0
- aap_demo/exec/oc.py +58 -0
- aap_demo/exec/operator_sdk.py +140 -0
- aap_demo/exec/runner.py +366 -0
- aap_demo/exec/ssh.py +152 -0
- aap_demo/infra/__init__.py +9 -0
- aap_demo/infra/crc.py +445 -0
- aap_demo/infra/crc_install.py +280 -0
- aap_demo-2.0.0.dev0.dist-info/METADATA +291 -0
- aap_demo-2.0.0.dev0.dist-info/RECORD +85 -0
- aap_demo-2.0.0.dev0.dist-info/WHEEL +4 -0
- aap_demo-2.0.0.dev0.dist-info/entry_points.txt +2 -0
- aap_demo-2.0.0.dev0.dist-info/licenses/LICENSE +202 -0
aap_demo/__init__.py
ADDED
aap_demo/__main__.py
ADDED
aap_demo/cli/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""Generate argparse arguments from a JSON Schema document (design §9.3).
|
|
2
|
+
|
|
3
|
+
Three deliberate omissions, each with a reason:
|
|
4
|
+
|
|
5
|
+
* ``minimum``/``maximum`` are not turned into argparse type-checkers. The merged
|
|
6
|
+
result is validated by ``jsonschema`` immediately afterwards, and a second
|
|
7
|
+
range check in a second place is exactly the drift this mechanism exists to
|
|
8
|
+
prevent — argparse handles *parsing*, jsonschema handles *validity*.
|
|
9
|
+
* ``required`` is not enforced here: a value may arrive from config or an env
|
|
10
|
+
var, so requiredness is a property of the resolved document.
|
|
11
|
+
* Nested objects are not flattened into dotted flags. A nested section gets its
|
|
12
|
+
own document and its own ``add_schema_arguments`` call against the same
|
|
13
|
+
parser, which is how ``crc.*`` and ``deploy.*`` both land on ``aap-demo create``.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
from typing import Any, Dict, Mapping, Optional
|
|
20
|
+
|
|
21
|
+
from aap_demo.core import schema
|
|
22
|
+
|
|
23
|
+
_TYPES = {"string": str, "integer": int, "number": float}
|
|
24
|
+
|
|
25
|
+
#: Options that may be hand-written because they are verbs or output modifiers,
|
|
26
|
+
#: not settings — they have no config or GUI analogue. ``test_schema_parity``
|
|
27
|
+
#: fails on any optional argument outside this list that is not schema-derived.
|
|
28
|
+
#: The design's §3.1 allowlist is the first group; the rest are per-command
|
|
29
|
+
#: modifiers of the same kind (a flag that changes what a command *does*, not a
|
|
30
|
+
#: value it persists).
|
|
31
|
+
CLI_ONLY_OPTIONS = frozenset(
|
|
32
|
+
{
|
|
33
|
+
# §3.1's explicit allowlist
|
|
34
|
+
"--output",
|
|
35
|
+
"--quiet",
|
|
36
|
+
"-q",
|
|
37
|
+
"--yes",
|
|
38
|
+
"-y",
|
|
39
|
+
"--config",
|
|
40
|
+
"--verbose",
|
|
41
|
+
"-v",
|
|
42
|
+
"-h",
|
|
43
|
+
"--help",
|
|
44
|
+
# global, CLI-shaped: they select a target or an escape hatch, not a setting
|
|
45
|
+
"--kubeconfig",
|
|
46
|
+
"--context",
|
|
47
|
+
"--force",
|
|
48
|
+
"--set",
|
|
49
|
+
"--version",
|
|
50
|
+
"-V",
|
|
51
|
+
# per-command verb modifiers
|
|
52
|
+
"--reset",
|
|
53
|
+
"--ai",
|
|
54
|
+
"--all",
|
|
55
|
+
"--dry-run",
|
|
56
|
+
"--check",
|
|
57
|
+
"--purge-creds",
|
|
58
|
+
"--refresh-catalog",
|
|
59
|
+
"--extra-vars",
|
|
60
|
+
"-e",
|
|
61
|
+
"--stdin",
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _dest_for(section_name: str, key: str) -> str:
|
|
67
|
+
return f"{section_name}__{key}"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def add_schema_arguments(
|
|
71
|
+
parser: argparse.ArgumentParser,
|
|
72
|
+
section_name: str,
|
|
73
|
+
*,
|
|
74
|
+
resolved: Optional[Mapping[str, Any]] = None,
|
|
75
|
+
doc: Optional[Dict[str, Any]] = None,
|
|
76
|
+
suppress: bool = False,
|
|
77
|
+
) -> None:
|
|
78
|
+
"""Add one argparse argument per property in a schema section.
|
|
79
|
+
|
|
80
|
+
``resolved`` is the post-config-resolution value map, so ``--help`` shows the
|
|
81
|
+
*effective* default rather than the schema default. ``suppress`` builds the
|
|
82
|
+
same parser with ``SUPPRESS`` defaults, which is how ``cli/main.py`` learns
|
|
83
|
+
which values the user actually typed and which merely defaulted.
|
|
84
|
+
"""
|
|
85
|
+
document = doc if doc is not None else schema.section(section_name)
|
|
86
|
+
values = resolved or {}
|
|
87
|
+
|
|
88
|
+
properties = document.get("properties", {})
|
|
89
|
+
for key, prop in sorted(properties.items(), key=lambda kv: kv[1].get("x-order", 1000)):
|
|
90
|
+
flags = schema.cli_flag(prop, key)
|
|
91
|
+
if flags is None:
|
|
92
|
+
continue
|
|
93
|
+
|
|
94
|
+
default = values.get(key, prop.get("default"))
|
|
95
|
+
kwargs: Dict[str, Any] = {
|
|
96
|
+
"dest": _dest_for(section_name, key),
|
|
97
|
+
"help": prop.get("description"),
|
|
98
|
+
"default": argparse.SUPPRESS if suppress else default,
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
prop_type = prop.get("type")
|
|
102
|
+
if prop_type == "boolean":
|
|
103
|
+
kwargs["action"] = "store_true" if not default else "store_false"
|
|
104
|
+
elif prop_type in _TYPES:
|
|
105
|
+
kwargs["type"] = _TYPES[prop_type]
|
|
106
|
+
if "enum" in prop:
|
|
107
|
+
# No metavar for an enum: argparse then renders the choices
|
|
108
|
+
# themselves in --help, which is the useful thing to show. A
|
|
109
|
+
# metavar would replace them with the widget name.
|
|
110
|
+
kwargs["choices"] = prop["enum"]
|
|
111
|
+
else:
|
|
112
|
+
kwargs["metavar"] = prop.get("x-gui", {}).get("widget", key).upper()
|
|
113
|
+
else:
|
|
114
|
+
raise ValueError(
|
|
115
|
+
f"{section_name}.{key}: type {prop_type!r} has no argparse mapping; "
|
|
116
|
+
"mark it 'x-cli: false' or give it a scalar type"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
parser.add_argument(*flags, **kwargs)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def collect_overrides(namespace: argparse.Namespace) -> Dict[str, Dict[str, Any]]:
|
|
123
|
+
"""Pull schema-derived values back out of a parsed namespace.
|
|
124
|
+
|
|
125
|
+
Only values the user actually supplied should override config, so callers
|
|
126
|
+
pass the *supplied* namespace produced by a second parse with suppressed
|
|
127
|
+
defaults; see ``cli/main.py``.
|
|
128
|
+
"""
|
|
129
|
+
overrides: Dict[str, Dict[str, Any]] = {}
|
|
130
|
+
for dest, value in vars(namespace).items():
|
|
131
|
+
if "__" not in dest:
|
|
132
|
+
continue
|
|
133
|
+
section_name, _, key = dest.partition("__")
|
|
134
|
+
if section_name not in schema.sections():
|
|
135
|
+
continue
|
|
136
|
+
overrides.setdefault(section_name, {})[key] = value
|
|
137
|
+
return overrides
|
aap_demo/cli/addons.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Addon commands — phase 0 stubs (the addon platform lands in phase 5+6)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
|
|
7
|
+
from aap_demo.core.context import AppContext
|
|
8
|
+
from aap_demo.core.errors import NotImplementedYetError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def enable(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
12
|
+
raise NotImplementedYetError("enable")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def disable(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
16
|
+
raise NotImplementedYetError("disable")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def addon(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
20
|
+
action = getattr(args, "addon_action", None) or "addon"
|
|
21
|
+
raise NotImplementedYetError(f"addon {action}".strip())
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""``aap-demo completion`` — phase 0 stub.
|
|
2
|
+
|
|
3
|
+
bash/zsh completion is backed by argcomplete over the argparse parser; fish and
|
|
4
|
+
PowerShell get hand-written scripts shipped as package data (design §3.1).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
|
|
11
|
+
from aap_demo.core.context import AppContext
|
|
12
|
+
from aap_demo.core.errors import NotImplementedYetError
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def completion(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
16
|
+
raise NotImplementedYetError("completion")
|
aap_demo/cli/day2.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Day-2 playbook commands — phase 0 stubs (the day2 package lands in phase 6b).
|
|
2
|
+
|
|
3
|
+
Named ``day2`` rather than ``playbooks`` because ``cli/ops.py`` already carries
|
|
4
|
+
idle/ssh/config; the user-facing noun everywhere is still "playbooks".
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
|
|
11
|
+
from aap_demo.core.context import AppContext
|
|
12
|
+
from aap_demo.core.errors import NotImplementedYetError
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def playbooks(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
16
|
+
action = getattr(args, "playbooks_action", None) or ""
|
|
17
|
+
raise NotImplementedYetError(f"playbooks {action}".strip())
|
aap_demo/cli/gui.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""``aap-demo gui`` — phase 0 stub (the GUI lands in phase 7)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
|
|
7
|
+
from aap_demo.core.context import AppContext
|
|
8
|
+
from aap_demo.core.errors import NotImplementedYetError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def gui(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
12
|
+
raise NotImplementedYetError("gui")
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""Cluster and AAP lifecycle commands (design §12.4).
|
|
2
|
+
|
|
3
|
+
``deploy``, ``clean``, ``redeploy``, ``setup``, ``create`` and ``destroy`` are
|
|
4
|
+
implemented. ``redeploy-all``, ``start``, ``stop`` and ``repair`` stay stubs.
|
|
5
|
+
The command functions are thin: every decision lives in ``cluster/``, which
|
|
6
|
+
is what lets the GUI reach the same behavior without importing ``cli/`` (§2.2).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import time
|
|
13
|
+
from typing import Callable
|
|
14
|
+
|
|
15
|
+
from aap_demo.cluster import aap as aap_mod
|
|
16
|
+
from aap_demo.cluster import bootstrap as bootstrap_mod
|
|
17
|
+
from aap_demo.cluster import deploy as deploy_mod
|
|
18
|
+
from aap_demo.cluster import runtime as runtime_mod
|
|
19
|
+
from aap_demo.cluster import status as status_mod
|
|
20
|
+
from aap_demo.core import prompts
|
|
21
|
+
from aap_demo.core.context import AppContext
|
|
22
|
+
from aap_demo.core.errors import NotImplementedYetError
|
|
23
|
+
from aap_demo.core.output import is_structured, render
|
|
24
|
+
from aap_demo.infra import crc as infra_crc
|
|
25
|
+
|
|
26
|
+
#: ``read -t 10`` before the destructive clean (aap-demo.sh:748).
|
|
27
|
+
CLEAN_CONFIRM_SECONDS = 10
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def create(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
31
|
+
"""Ports ``aap-demo create`` for the MicroShift preset."""
|
|
32
|
+
del args
|
|
33
|
+
bootstrap_mod.create(ctx)
|
|
34
|
+
return 0
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def deploy(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
38
|
+
"""Ports ``cmd_deploy`` (aap-demo.sh:2018).
|
|
39
|
+
|
|
40
|
+
Exit status follows bash: reaching the CR and then timing out in
|
|
41
|
+
``watch_aap`` is a failure (bash's ``return 1``), while the
|
|
42
|
+
already-exists short-circuit is a success.
|
|
43
|
+
"""
|
|
44
|
+
deploy_mod.ensure_cluster_running(ctx)
|
|
45
|
+
result = deploy_mod.run(ctx, cr_name=getattr(args, "deploy__cr", None) or None)
|
|
46
|
+
if is_structured(ctx.output):
|
|
47
|
+
render(ctx.console, result.as_dict(), output=ctx.output)
|
|
48
|
+
return 0 if (result.ready or result.skipped_existing) else 1
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def redeploy(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
52
|
+
"""Ports ``cmd_redeploy`` (aap-demo.sh:1902): clean, pause, deploy."""
|
|
53
|
+
_clean(ctx)
|
|
54
|
+
time.sleep(2)
|
|
55
|
+
ctx.console.out("")
|
|
56
|
+
ctx.console.out("Redeploying AAP...")
|
|
57
|
+
ctx.console.out("")
|
|
58
|
+
result = deploy_mod.run(ctx, cr_name=getattr(args, "deploy__cr", None) or None)
|
|
59
|
+
if is_structured(ctx.output):
|
|
60
|
+
render(ctx.console, result.as_dict(), output=ctx.output)
|
|
61
|
+
return 0 if result.ready else 1
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def redeploy_all(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
65
|
+
raise NotImplementedYetError("redeploy-all")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def setup(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
69
|
+
"""Ports ``cmd_setup`` (aap-demo.sh:2013), which is one ``echo`` and nothing else.
|
|
70
|
+
|
|
71
|
+
The help text still advertises "Run setup only (storage, coredns, mkcert)",
|
|
72
|
+
but that work moved into ``crc-create.sh`` long ago and the command has
|
|
73
|
+
been a pointer ever since. Porting the *advertised* behavior instead of
|
|
74
|
+
the actual behavior would invent a command that has never existed.
|
|
75
|
+
"""
|
|
76
|
+
ctx.console.out("CRC setup is handled during 'aap-demo create'")
|
|
77
|
+
return 0
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def start(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
81
|
+
"""Ports ``cmd_start``."""
|
|
82
|
+
del args
|
|
83
|
+
runtime_mod.start(ctx)
|
|
84
|
+
return 0
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def stop(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
88
|
+
"""Ports ``cmd_stop``."""
|
|
89
|
+
del args
|
|
90
|
+
runtime_mod.stop(ctx)
|
|
91
|
+
return 0
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def destroy(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
95
|
+
"""Ports ``cmd_destroy``. ``--reset`` clears the YAML config file."""
|
|
96
|
+
bootstrap_mod.destroy(ctx, reset=bool(getattr(args, "reset", False)))
|
|
97
|
+
return 0
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def clean(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
101
|
+
_clean(ctx)
|
|
102
|
+
return 0
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def repair(ctx: AppContext, args: argparse.Namespace) -> int:
|
|
106
|
+
"""Ports ``cmd_repair``."""
|
|
107
|
+
del args
|
|
108
|
+
runtime_mod.repair(ctx)
|
|
109
|
+
return 0
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _clean(ctx: AppContext, *, wait: Callable[[float], None] = None) -> None: # type: ignore[assignment]
|
|
113
|
+
"""Ports ``_clean_operator``'s warning banner plus ``cluster/aap.py::teardown``."""
|
|
114
|
+
ns = ctx.namespace
|
|
115
|
+
|
|
116
|
+
from aap_demo.exec import kubectl
|
|
117
|
+
|
|
118
|
+
if not kubectl.exists(ctx.runner, "namespace", ns):
|
|
119
|
+
ctx.console.out(f"Namespace {ns} not found - nothing to clean")
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
ctx.console.out("")
|
|
123
|
+
ctx.console.out("WARNING: AAP CLEANUP - DESTRUCTIVE OPERATION!")
|
|
124
|
+
ctx.console.out("")
|
|
125
|
+
status_mod.show_cluster_info(ctx)
|
|
126
|
+
ctx.console.out("")
|
|
127
|
+
|
|
128
|
+
listing = ctx.runner.run(
|
|
129
|
+
["kubectl", "get", "aap", "-n", ns, "--no-headers", "--request-timeout=2s"]
|
|
130
|
+
)
|
|
131
|
+
names = [line.split()[0] for line in (listing.stdout or "").splitlines() if line.strip()]
|
|
132
|
+
if names:
|
|
133
|
+
ctx.console.out(" AAP resources that will be DELETED:")
|
|
134
|
+
for name in names:
|
|
135
|
+
ctx.console.out(f" - {name}")
|
|
136
|
+
ctx.console.out("")
|
|
137
|
+
|
|
138
|
+
ctx.console.out(f"This will DELETE the namespace '{ns}' and all resources within it!")
|
|
139
|
+
ctx.console.out("")
|
|
140
|
+
prompts.timed_continue(ctx.console, seconds=CLEAN_CONFIRM_SECONDS, quiet=ctx.quiet, wait=wait)
|
|
141
|
+
|
|
142
|
+
import shutil
|
|
143
|
+
|
|
144
|
+
steps = ["Deleting the AAP instance", "Deleting the namespace", "Pruning unused images"]
|
|
145
|
+
if shutil.which("operator-sdk") is not None:
|
|
146
|
+
steps.insert(0, "Cleaning up OLM")
|
|
147
|
+
ctx.console.tasks(steps)
|
|
148
|
+
if not aap_mod.teardown(ctx, namespace=ns):
|
|
149
|
+
return
|
|
150
|
+
ctx.console.step("Pruning unused images")
|
|
151
|
+
pruned = infra_crc.prune_images(ctx)
|
|
152
|
+
if pruned:
|
|
153
|
+
ctx.console.checkpoint(f"Pruned {pruned} unused images")
|
|
154
|
+
else:
|
|
155
|
+
ctx.console.checkpoint("No unused images to prune")
|
|
156
|
+
ctx.console.success("AAP operator deployment removed")
|