@mriekki/lean 0.1.0 → 0.1.1

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 (37) hide show
  1. package/README.md +67 -67
  2. package/assets/components.json +33 -33
  3. package/assets/core/distribution.json +51 -51
  4. package/assets/deployment/distribution.json +34 -34
  5. package/assets/generated/ASSEMBLY.json +28 -28
  6. package/assets/generated/deployment/distribution/lean-poc-deploy.py +8 -8
  7. package/assets/generated/deployment/src/lean_poc_deployment/__init__.py +3 -3
  8. package/assets/generated/deployment/src/lean_poc_deployment/__main__.py +3 -3
  9. package/assets/generated/deployment/src/lean_poc_deployment/app_cli.py +140 -140
  10. package/assets/generated/deployment/src/lean_poc_deployment/app_runtime.py +455 -455
  11. package/assets/generated/deployment/src/lean_poc_deployment/app_runtime_remote.py +415 -415
  12. package/assets/generated/deployment/src/lean_poc_deployment/box_platform.py +208 -208
  13. package/assets/generated/deployment/src/lean_poc_deployment/box_platform_assets.py +100 -100
  14. package/assets/generated/deployment/src/lean_poc_deployment/box_platform_remote.py +271 -271
  15. package/assets/generated/deployment/src/lean_poc_deployment/cli.py +437 -437
  16. package/assets/generated/deployment/src/lean_poc_deployment/doctor.py +121 -121
  17. package/assets/generated/deployment/src/lean_poc_deployment/entrypoint.py +25 -25
  18. package/assets/generated/deployment/src/lean_poc_deployment/errors.py +5 -5
  19. package/assets/generated/deployment/src/lean_poc_deployment/keys.py +171 -171
  20. package/assets/generated/deployment/src/lean_poc_deployment/profiles.py +204 -204
  21. package/assets/generated/deployment/src/lean_poc_deployment/route_registry.py +367 -367
  22. package/assets/generated/deployment/src/lean_poc_deployment/route_registry_remote.py +443 -443
  23. package/assets/generated/deployment/src/lean_poc_deployment/security.py +290 -290
  24. package/assets/generated/deployment/src/lean_poc_deployment/sqlite_adapter.py +334 -334
  25. package/assets/generated/deployment/src/lean_poc_deployment/sqlite_adapter_remote.py +339 -339
  26. package/assets/generated/deployment/src/lean_poc_deployment/sqlite_cli.py +85 -85
  27. package/assets/generated/deployment/src/lean_poc_deployment/sqlite_import_recovery.py +437 -437
  28. package/assets/generated/deployment/src/lean_poc_deployment/ssh.py +118 -118
  29. package/assets/generated/deployment/src/lean_poc_deployment/teardown.py +286 -286
  30. package/assets/generated/deployment/src/lean_poc_deployment/teardown_cli.py +120 -120
  31. package/assets/generated/deployment/src/lean_poc_deployment/teardown_remote.py +100 -100
  32. package/assets/generated/deployment/src/lean_poc_deployment/trust.py +278 -278
  33. package/bin/lean.mjs +9 -9
  34. package/package.json +33 -33
  35. package/src/cli.mjs +131 -131
  36. package/src/engine.mjs +243 -243
  37. package/src/package-data.mjs +18 -18
@@ -1,86 +1,86 @@
1
- """CLI for the SQLite persistence adapter."""
2
- from __future__ import annotations
3
- import argparse, json, sys
4
- from typing import Any
5
- from .errors import DeploymentKitError
6
- from .sqlite_adapter import authorization_phrase, apply_sqlite_operation, normalize_sqlite_request, plan_sqlite_operation, sqlite_inventory
7
- from .sqlite_import_recovery import (
8
- apply_sqlite_import_recovery,
9
- authorization_phrase as recovery_authorization_phrase,
10
- plan_sqlite_import_recovery,
11
- )
12
-
13
-
14
- def _print(value: Any, *, as_json: bool) -> None:
15
- if as_json:
16
- print(json.dumps(value, indent=2, sort_keys=True)); return
17
- if isinstance(value, dict):
18
- for key, item in value.items():
19
- print(f"{key}: {json.dumps(item, sort_keys=True) if isinstance(item,(dict,list)) else item}")
20
- else: print(value)
21
-
22
-
23
- def _parse_env(items: list[str]) -> list[tuple[str,str]]:
24
- out=[]
25
- for item in items:
26
- if '=' not in item: raise DeploymentKitError("--maintenance-env entries must use NAME=value form.")
27
- out.append(tuple(item.split('=',1)))
28
- return out
29
-
30
-
31
- def _confirm(args: argparse.Namespace, phrase: str, action: str) -> None:
32
- if args.yes: return
33
- if input(f"Type {phrase} to {action}: ").strip() != phrase:
34
- raise DeploymentKitError(f"{action.capitalize()} was not authorized.")
35
-
36
-
37
- def _common(parser: argparse.ArgumentParser) -> None:
38
- parser.add_argument('name')
39
- parser.add_argument('--owner-repo', required=True)
40
- parser.add_argument('--environment', required=True)
41
- parser.add_argument('--app-slug', required=True)
42
- parser.add_argument('--image', required=True)
43
- parser.add_argument('--maintenance-env', action='append', default=[], help='Non-secret image maintenance environment value in NAME=value form; repeat as needed')
44
- parser.add_argument('--json', action='store_true')
45
- parser.add_argument('--yes', action='store_true')
46
-
47
-
48
- def _import_args(parser: argparse.ArgumentParser) -> None:
49
- parser.add_argument('--run-as', required=True)
50
- parser.add_argument('--database-file', required=True)
51
- parser.add_argument('--source-database', required=True)
52
-
53
-
54
- def build_parser() -> argparse.ArgumentParser:
55
- parser=argparse.ArgumentParser(prog='lean-poc-deploy sqlite')
56
- sub=parser.add_subparsers(dest='command',required=True)
57
- inv=sub.add_parser('inventory',help='Read SQLite persistence reservations without writes'); inv.add_argument('name'); inv.add_argument('--json',action='store_true')
58
- imp=sub.add_parser('import',help='Import an existing SQLite DB via the exact image online-backup contract'); _common(imp); _import_args(imp)
59
- recover=sub.add_parser('recover-import',help='Recover a verified failed import without overwriting or recopying the database'); _common(recover); _import_args(recover)
60
- backup=sub.add_parser('backup',help='Create a verified SQLite backup with the exact image'); _common(backup)
61
- migrate=sub.add_parser('migrate',help='Create required backup and run exact-image SQLite migration'); _common(migrate)
62
- migrate.add_argument('--first-install',action='store_true'); migrate.add_argument('--run-as'); migrate.add_argument('--database-file')
63
- check=sub.add_parser('rollback-check',help='Verify that an exact rollback image accepts the current SQLite state'); _common(check)
64
- return parser
65
-
66
-
67
- def main(argv: list[str]|None=None) -> int:
68
- args=build_parser().parse_args(argv)
69
- try:
70
- if args.command=='inventory': _print(sqlite_inventory(args.name),as_json=args.json); return 0
71
- request=normalize_sqlite_request(owner_repo=args.owner_repo,environment=args.environment,app_slug=args.app_slug,image=args.image,
72
- maintenance_environment=_parse_env(args.maintenance_env),run_as=getattr(args,'run_as',None),database_file=getattr(args,'database_file',None),
73
- source_database=getattr(args,'source_database',None),first_install=getattr(args,'first_install',False))
74
- if args.command=='recover-import':
75
- plan=plan_sqlite_import_recovery(args.name,request)
76
- _print({k:v for k,v in plan.items() if k!='request'},as_json=False)
77
- phrase=recovery_authorization_phrase(plan)
78
- _confirm(args,phrase,f"recover SQLite import for {plan['appSlug']} ({plan['environment']}) on target {args.name}")
79
- _print(apply_sqlite_import_recovery(plan),as_json=args.json); return 0
80
- plan=plan_sqlite_operation(args.name,args.command,request)
81
- _print({k:v for k,v in plan.items() if k!='spec'},as_json=False)
82
- phrase=authorization_phrase(plan)
83
- _confirm(args,phrase,f"run SQLite {args.command} for {plan['appSlug']} ({plan['environment']}) on target {args.name}")
84
- _print(apply_sqlite_operation(plan),as_json=args.json); return 0
85
- except DeploymentKitError as error:
1
+ """CLI for the SQLite persistence adapter."""
2
+ from __future__ import annotations
3
+ import argparse, json, sys
4
+ from typing import Any
5
+ from .errors import DeploymentKitError
6
+ from .sqlite_adapter import authorization_phrase, apply_sqlite_operation, normalize_sqlite_request, plan_sqlite_operation, sqlite_inventory
7
+ from .sqlite_import_recovery import (
8
+ apply_sqlite_import_recovery,
9
+ authorization_phrase as recovery_authorization_phrase,
10
+ plan_sqlite_import_recovery,
11
+ )
12
+
13
+
14
+ def _print(value: Any, *, as_json: bool) -> None:
15
+ if as_json:
16
+ print(json.dumps(value, indent=2, sort_keys=True)); return
17
+ if isinstance(value, dict):
18
+ for key, item in value.items():
19
+ print(f"{key}: {json.dumps(item, sort_keys=True) if isinstance(item,(dict,list)) else item}")
20
+ else: print(value)
21
+
22
+
23
+ def _parse_env(items: list[str]) -> list[tuple[str,str]]:
24
+ out=[]
25
+ for item in items:
26
+ if '=' not in item: raise DeploymentKitError("--maintenance-env entries must use NAME=value form.")
27
+ out.append(tuple(item.split('=',1)))
28
+ return out
29
+
30
+
31
+ def _confirm(args: argparse.Namespace, phrase: str, action: str) -> None:
32
+ if args.yes: return
33
+ if input(f"Type {phrase} to {action}: ").strip() != phrase:
34
+ raise DeploymentKitError(f"{action.capitalize()} was not authorized.")
35
+
36
+
37
+ def _common(parser: argparse.ArgumentParser) -> None:
38
+ parser.add_argument('name')
39
+ parser.add_argument('--owner-repo', required=True)
40
+ parser.add_argument('--environment', required=True)
41
+ parser.add_argument('--app-slug', required=True)
42
+ parser.add_argument('--image', required=True)
43
+ parser.add_argument('--maintenance-env', action='append', default=[], help='Non-secret image maintenance environment value in NAME=value form; repeat as needed')
44
+ parser.add_argument('--json', action='store_true')
45
+ parser.add_argument('--yes', action='store_true')
46
+
47
+
48
+ def _import_args(parser: argparse.ArgumentParser) -> None:
49
+ parser.add_argument('--run-as', required=True)
50
+ parser.add_argument('--database-file', required=True)
51
+ parser.add_argument('--source-database', required=True)
52
+
53
+
54
+ def build_parser() -> argparse.ArgumentParser:
55
+ parser=argparse.ArgumentParser(prog='lean-poc-deploy sqlite')
56
+ sub=parser.add_subparsers(dest='command',required=True)
57
+ inv=sub.add_parser('inventory',help='Read SQLite persistence reservations without writes'); inv.add_argument('name'); inv.add_argument('--json',action='store_true')
58
+ imp=sub.add_parser('import',help='Import an existing SQLite DB via the exact image online-backup contract'); _common(imp); _import_args(imp)
59
+ recover=sub.add_parser('recover-import',help='Recover a verified failed import without overwriting or recopying the database'); _common(recover); _import_args(recover)
60
+ backup=sub.add_parser('backup',help='Create a verified SQLite backup with the exact image'); _common(backup)
61
+ migrate=sub.add_parser('migrate',help='Create required backup and run exact-image SQLite migration'); _common(migrate)
62
+ migrate.add_argument('--first-install',action='store_true'); migrate.add_argument('--run-as'); migrate.add_argument('--database-file')
63
+ check=sub.add_parser('rollback-check',help='Verify that an exact rollback image accepts the current SQLite state'); _common(check)
64
+ return parser
65
+
66
+
67
+ def main(argv: list[str]|None=None) -> int:
68
+ args=build_parser().parse_args(argv)
69
+ try:
70
+ if args.command=='inventory': _print(sqlite_inventory(args.name),as_json=args.json); return 0
71
+ request=normalize_sqlite_request(owner_repo=args.owner_repo,environment=args.environment,app_slug=args.app_slug,image=args.image,
72
+ maintenance_environment=_parse_env(args.maintenance_env),run_as=getattr(args,'run_as',None),database_file=getattr(args,'database_file',None),
73
+ source_database=getattr(args,'source_database',None),first_install=getattr(args,'first_install',False))
74
+ if args.command=='recover-import':
75
+ plan=plan_sqlite_import_recovery(args.name,request)
76
+ _print({k:v for k,v in plan.items() if k!='request'},as_json=False)
77
+ phrase=recovery_authorization_phrase(plan)
78
+ _confirm(args,phrase,f"recover SQLite import for {plan['appSlug']} ({plan['environment']}) on target {args.name}")
79
+ _print(apply_sqlite_import_recovery(plan),as_json=args.json); return 0
80
+ plan=plan_sqlite_operation(args.name,args.command,request)
81
+ _print({k:v for k,v in plan.items() if k!='spec'},as_json=False)
82
+ phrase=authorization_phrase(plan)
83
+ _confirm(args,phrase,f"run SQLite {args.command} for {plan['appSlug']} ({plan['environment']}) on target {args.name}")
84
+ _print(apply_sqlite_operation(plan),as_json=args.json); return 0
85
+ except DeploymentKitError as error:
86
86
  print(f"ERROR: {error}",file=sys.stderr); return 2