osism 0.20250826.0__tar.gz → 0.20250827.0__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 (155) hide show
  1. osism-0.20250827.0/AUTHORS +1 -0
  2. osism-0.20250827.0/ChangeLog +7 -0
  3. {osism-0.20250826.0/osism.egg-info → osism-0.20250827.0}/PKG-INFO +3 -3
  4. {osism-0.20250826.0 → osism-0.20250827.0}/Pipfile +1 -1
  5. {osism-0.20250826.0 → osism-0.20250827.0}/Pipfile.lock +67 -43
  6. osism-0.20250827.0/files/data/flavors.yaml +274 -0
  7. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/package-lock.json +6 -6
  8. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/apply.py +4 -0
  9. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/configuration.py +4 -0
  10. osism-0.20250827.0/osism/commands/lock.py +91 -0
  11. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/manage.py +132 -6
  12. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/netbox.py +12 -0
  13. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/noset.py +7 -0
  14. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/reconciler.py +3 -0
  15. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/redfish.py +4 -0
  16. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/service.py +4 -0
  17. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/set.py +7 -0
  18. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/sonic.py +3 -0
  19. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/sync.py +7 -0
  20. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/validate.py +3 -0
  21. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/worker.py +4 -0
  22. {osism-0.20250826.0 → osism-0.20250827.0}/osism/data/__init__.py +33 -0
  23. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/ansible.py +3 -0
  24. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/ceph.py +4 -0
  25. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/__init__.py +10 -0
  26. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/kolla.py +4 -0
  27. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/kubernetes.py +4 -0
  28. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/netbox.py +12 -0
  29. osism-0.20250827.0/osism/tasks/openstack.py +454 -0
  30. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/reconciler.py +3 -0
  31. {osism-0.20250826.0 → osism-0.20250827.0}/osism/utils/__init__.py +81 -0
  32. {osism-0.20250826.0 → osism-0.20250827.0/osism.egg-info}/PKG-INFO +3 -3
  33. {osism-0.20250826.0 → osism-0.20250827.0}/osism.egg-info/SOURCES.txt +2 -0
  34. {osism-0.20250826.0 → osism-0.20250827.0}/osism.egg-info/entry_points.txt +4 -0
  35. osism-0.20250827.0/osism.egg-info/pbr.json +1 -0
  36. {osism-0.20250826.0 → osism-0.20250827.0}/osism.egg-info/requires.txt +2 -2
  37. osism-0.20250827.0/requirements.openstack-flavor-manager.txt +1 -0
  38. osism-0.20250827.0/requirements.openstack-image-manager.txt +1 -0
  39. {osism-0.20250826.0 → osism-0.20250827.0}/requirements.txt +1 -1
  40. {osism-0.20250826.0 → osism-0.20250827.0}/setup.cfg +4 -0
  41. osism-0.20250826.0/AUTHORS +0 -1
  42. osism-0.20250826.0/ChangeLog +0 -7
  43. osism-0.20250826.0/osism/tasks/openstack.py +0 -227
  44. osism-0.20250826.0/osism.egg-info/pbr.json +0 -1
  45. osism-0.20250826.0/requirements.openstack-flavor-manager.txt +0 -1
  46. osism-0.20250826.0/requirements.openstack-image-manager.txt +0 -1
  47. {osism-0.20250826.0 → osism-0.20250827.0}/.flake8 +0 -0
  48. {osism-0.20250826.0 → osism-0.20250827.0}/.github/renovate.json +0 -0
  49. {osism-0.20250826.0 → osism-0.20250827.0}/.github/workflows/publish.yml +0 -0
  50. {osism-0.20250826.0 → osism-0.20250827.0}/.hadolint.yaml +0 -0
  51. {osism-0.20250826.0 → osism-0.20250827.0}/.zuul.yaml +0 -0
  52. {osism-0.20250826.0 → osism-0.20250827.0}/Containerfile +0 -0
  53. {osism-0.20250826.0 → osism-0.20250827.0}/Dockerfile +0 -0
  54. {osism-0.20250826.0 → osism-0.20250827.0}/LICENSE +0 -0
  55. {osism-0.20250826.0 → osism-0.20250827.0}/README.md +0 -0
  56. {osism-0.20250826.0 → osism-0.20250827.0}/files/change.sh +0 -0
  57. {osism-0.20250826.0 → osism-0.20250827.0}/files/cleanup-ansible-collections.sh +0 -0
  58. {osism-0.20250826.0 → osism-0.20250827.0}/files/clustershell/clush.conf +0 -0
  59. {osism-0.20250826.0 → osism-0.20250827.0}/files/clustershell/groups.conf +0 -0
  60. {osism-0.20250826.0 → osism-0.20250827.0}/files/data/SCS-Spec.MandatoryFlavors.verbose.yaml +0 -0
  61. {osism-0.20250826.0 → osism-0.20250827.0}/files/netbox-manager/settings.toml +0 -0
  62. {osism-0.20250826.0 → osism-0.20250827.0}/files/redfishMockupCreate.py +0 -0
  63. {osism-0.20250826.0 → osism-0.20250827.0}/files/run-ansible-console.sh +0 -0
  64. {osism-0.20250826.0 → osism-0.20250827.0}/files/sonic/config_db.json +0 -0
  65. {osism-0.20250826.0 → osism-0.20250827.0}/files/sonic/port_config/Accton-AS4625-54T.ini +0 -0
  66. {osism-0.20250826.0 → osism-0.20250827.0}/files/sonic/port_config/Accton-AS5835-54T.ini +0 -0
  67. {osism-0.20250826.0 → osism-0.20250827.0}/files/sonic/port_config/Accton-AS5835-54X.ini +0 -0
  68. {osism-0.20250826.0 → osism-0.20250827.0}/files/sonic/port_config/Accton-AS7326-56X.ini +0 -0
  69. {osism-0.20250826.0 → osism-0.20250827.0}/files/sonic/port_config/Accton-AS7726-32X.ini +0 -0
  70. {osism-0.20250826.0 → osism-0.20250827.0}/files/sonic/port_config/Accton-AS9716-32D.ini +0 -0
  71. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/.dockerignore +0 -0
  72. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/.gitignore +0 -0
  73. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/Containerfile +0 -0
  74. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/Dockerfile +0 -0
  75. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/api/config/route.ts +0 -0
  76. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/api/health/route.ts +0 -0
  77. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/components/ConnectionStatus.tsx +0 -0
  78. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/components/EventsFilters.tsx +0 -0
  79. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/components/EventsList.tsx +0 -0
  80. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/events/page.tsx +0 -0
  81. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/favicon.ico +0 -0
  82. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/globals.css +0 -0
  83. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/layout.tsx +0 -0
  84. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/nodes/page.tsx +0 -0
  85. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/page.tsx +0 -0
  86. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/app/services/page.tsx +0 -0
  87. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/components.json +0 -0
  88. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/eslint.config.mjs +0 -0
  89. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/lib/api.ts +0 -0
  90. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/lib/hooks/useWebSocket.ts +0 -0
  91. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/lib/types.ts +0 -0
  92. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/lib/utils.ts +0 -0
  93. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/next.config.ts +0 -0
  94. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/package.json +0 -0
  95. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/postcss.config.mjs +0 -0
  96. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/public/file.svg +0 -0
  97. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/public/globe.svg +0 -0
  98. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/public/next.svg +0 -0
  99. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/public/vercel.svg +0 -0
  100. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/public/window.svg +0 -0
  101. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/tailwind.config.ts +0 -0
  102. {osism-0.20250826.0 → osism-0.20250827.0}/frontend/tsconfig.json +0 -0
  103. {osism-0.20250826.0 → osism-0.20250827.0}/osism/__init__.py +0 -0
  104. {osism-0.20250826.0 → osism-0.20250827.0}/osism/__main__.py +0 -0
  105. {osism-0.20250826.0 → osism-0.20250827.0}/osism/api.py +0 -0
  106. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/__init__.py +0 -0
  107. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/baremetal.py +0 -0
  108. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/compose.py +0 -0
  109. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/compute.py +0 -0
  110. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/console.py +0 -0
  111. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/container.py +0 -0
  112. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/get.py +0 -0
  113. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/log.py +0 -0
  114. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/server.py +0 -0
  115. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/status.py +0 -0
  116. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/task.py +0 -0
  117. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/vault.py +0 -0
  118. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/volume.py +0 -0
  119. {osism-0.20250826.0 → osism-0.20250827.0}/osism/commands/wait.py +0 -0
  120. {osism-0.20250826.0 → osism-0.20250827.0}/osism/data/enums.py +0 -0
  121. {osism-0.20250826.0 → osism-0.20250827.0}/osism/data/playbooks.py +0 -0
  122. {osism-0.20250826.0 → osism-0.20250827.0}/osism/main.py +0 -0
  123. {osism-0.20250826.0 → osism-0.20250827.0}/osism/services/__init__.py +0 -0
  124. {osism-0.20250826.0 → osism-0.20250827.0}/osism/services/event_bridge.py +0 -0
  125. {osism-0.20250826.0 → osism-0.20250827.0}/osism/services/listener.py +0 -0
  126. {osism-0.20250826.0 → osism-0.20250827.0}/osism/services/websocket_manager.py +0 -0
  127. {osism-0.20250826.0 → osism-0.20250827.0}/osism/settings.py +0 -0
  128. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/__init__.py +0 -0
  129. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/config.py +0 -0
  130. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/ironic.py +0 -0
  131. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/netbox.py +0 -0
  132. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/redfish.py +0 -0
  133. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/__init__.py +0 -0
  134. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/bgp.py +0 -0
  135. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/cache.py +0 -0
  136. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/config_generator.py +0 -0
  137. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/connections.py +0 -0
  138. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/constants.py +0 -0
  139. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/device.py +0 -0
  140. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/exporter.py +0 -0
  141. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/interface.py +0 -0
  142. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/sonic/sync.py +0 -0
  143. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor/utils.py +0 -0
  144. {osism-0.20250826.0 → osism-0.20250827.0}/osism/tasks/conductor.py +0 -0
  145. {osism-0.20250826.0 → osism-0.20250827.0}/osism/utils/ssh.py +0 -0
  146. {osism-0.20250826.0 → osism-0.20250827.0}/osism.egg-info/dependency_links.txt +0 -0
  147. {osism-0.20250826.0 → osism-0.20250827.0}/osism.egg-info/not-zip-safe +0 -0
  148. {osism-0.20250826.0 → osism-0.20250827.0}/osism.egg-info/top_level.txt +0 -0
  149. {osism-0.20250826.0 → osism-0.20250827.0}/playbooks/build.yml +0 -0
  150. {osism-0.20250826.0 → osism-0.20250827.0}/playbooks/pre.yml +0 -0
  151. {osism-0.20250826.0 → osism-0.20250827.0}/playbooks/test-setup.yml +0 -0
  152. {osism-0.20250826.0 → osism-0.20250827.0}/requirements.ansible.txt +0 -0
  153. {osism-0.20250826.0 → osism-0.20250827.0}/requirements.netbox-manager.txt +0 -0
  154. {osism-0.20250826.0 → osism-0.20250827.0}/requirements.yml +0 -0
  155. {osism-0.20250826.0 → osism-0.20250827.0}/setup.py +0 -0
@@ -0,0 +1 @@
1
+ renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@@ -0,0 +1,7 @@
1
+ CHANGES
2
+ =======
3
+
4
+ v0.20250827.0
5
+ -------------
6
+
7
+ * chore(deps): update react monorepo to v19.1.12 (#1679)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osism
3
- Version: 0.20250826.0
3
+ Version: 0.20250827.0
4
4
  Summary: OSISM manager interface
5
5
  Home-page: https://github.com/osism/python-osism
6
6
  Author: OSISM GmbH
@@ -43,7 +43,7 @@ Requires-Dist: nbcli==0.10.0.dev2
43
43
  Requires-Dist: openstacksdk==4.7.0
44
44
  Requires-Dist: paramiko==3.5.1
45
45
  Requires-Dist: pottery==3.0.1
46
- Requires-Dist: prompt-toolkit==3.0.51
46
+ Requires-Dist: prompt-toolkit==3.0.52
47
47
  Requires-Dist: pynetbox==7.5.0
48
48
  Requires-Dist: pytest-testinfra==10.2.2
49
49
  Requires-Dist: python-dateutil==2.9.0.post0
@@ -60,7 +60,7 @@ Provides-Extra: ansible
60
60
  Requires-Dist: ansible-runner==2.4.1; extra == "ansible"
61
61
  Requires-Dist: ansible-core==2.19.1; extra == "ansible"
62
62
  Provides-Extra: openstack-image-manager
63
- Requires-Dist: openstack-image-manager==0.20250508.0; extra == "openstack-image-manager"
63
+ Requires-Dist: openstack-image-manager==0.20250827.0; extra == "openstack-image-manager"
64
64
  Dynamic: author
65
65
  Dynamic: author-email
66
66
  Dynamic: classifier
@@ -27,7 +27,7 @@ nbcli = "0.10.0.dev2"
27
27
  openstacksdk = "==4.7.0"
28
28
  paramiko = "==3.5.1"
29
29
  pottery = "==3.0.1"
30
- prompt-toolkit = "==3.0.51"
30
+ prompt-toolkit = "==3.0.52"
31
31
  pynetbox = "==7.5.0"
32
32
  pytest-testinfra = "==10.2.2"
33
33
  python-dateutil = "==2.9.0.post0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_meta": {
3
3
  "hash": {
4
- "sha256": "e8b77ed25ea8d9164f944f0b58d5c4242305ac9b12c3a081d010e2a5c2435e53"
4
+ "sha256": "c797a785299708bfb3a6fb132a0f452ac0c6f9d41a509b7c888abfe0132ab586"
5
5
  },
6
6
  "pipfile-spec": 6,
7
7
  "requires": {},
@@ -480,42 +480,6 @@
480
480
  "markers": "python_version >= '3.7'",
481
481
  "version": "==3.1.45"
482
482
  },
483
- "gnureadline": {
484
- "hashes": [
485
- "sha256:07231f8191adb7f204010a86a91df9df9a80944981a16576a471f59304ad6a16",
486
- "sha256:0ca03501ce0939d7ecf9d075860d6f6ceb2f49f30331b4e96e4678ce03687bab",
487
- "sha256:0cc77fc9c8a8fcf10e0a554e49ee763219683386b8f906b7e6ef07c9e40e8420",
488
- "sha256:10fcaf561bc4ed6ab7075ab3ead188a18faaf4e6e92d916f81a09c0a670ce906",
489
- "sha256:23b43c8e9e2e6566cb3094749826181a86dba1d94b1e023b5f9923dc26e37876",
490
- "sha256:265bcf6ef7082e130160fb34b9664284affb216a22c5bffcd518b35d02bcc4e9",
491
- "sha256:2d3e33d2e0dd694d623a2ca1fae6990b52f1d25955504b7293a9350fb9912940",
492
- "sha256:30cc1b6cb11d94554815cb91eb1dfa6a11887185aae50f253adaa393e91c6a86",
493
- "sha256:3f1050ecf789f34d0ab0aacdb605f177725009a864e0038e70380614af92dc0d",
494
- "sha256:4f57a3aa97c3379b2513c8bfbac0de2dfb41f695623c0b2ad337babb646b51a7",
495
- "sha256:4f5fc90af56a1ae6f88c9c7122fc76141c395b6c342a63800abed8c813f48b85",
496
- "sha256:50c40bfffffa82d4fcb0fde4940d4ff128ba2f876c1da09bae9d6d9ff770095e",
497
- "sha256:561a60b12f74ea7234036cc4fe558f3b46023be0dac5ed73541ece58cba2f88a",
498
- "sha256:576dac060887adc6067ee9d23fb2f0031fb2b3e560e07a6c9e666e05f0473af7",
499
- "sha256:59c5505026646da6d5ced6a5316d6d191d011e8be422cba4abce71730ef37dc6",
500
- "sha256:6472e3a780087eecd67c03e5455aecb209de51bcae74583222976f6b816f6192",
501
- "sha256:6c550d08c4d2882a83293a724b14a262ee5078fd4fa7acdc78aa59cab26ae343",
502
- "sha256:811d85a70ac97cddeb1755282915e8a93c279dcf89513426f28617b8feff5aec",
503
- "sha256:85e362d2d0e85e45f0affae7bbfaf998b00167c55a78d31ee0f214de9ff429d2",
504
- "sha256:94b143ea5d22b0c1ca4a591265afe135272c69b7757e968e34fbb47a7858d1ce",
505
- "sha256:9c152a82613fa012ab4331bb9a0ffddb415e37561d376b910bf9e7d535607faf",
506
- "sha256:a7d6e3f5d9fd0cf8a84fb382d4e3ad2914331be4d929f17d50da01f1571c4b03",
507
- "sha256:b69e6608cc94e110018b721a11718d480a6330e0b62cbab65a22880e84011205",
508
- "sha256:c28e33bfc56d4204693f213abeab927f65c505ce91f668a039720bc7c46b0353",
509
- "sha256:c7b8d3f2a2c9b7e6feaf1f20bdb6ebb8210e207b8c5360ffe407a47efeeb3fb8",
510
- "sha256:c9b9e1e7ba99a80bb50c12027d6ce692574f77a65bf57bc97041cf81c0f49bd1",
511
- "sha256:d708e8f655d3b556a138f13e9fcb2d8a10a6901e3125c04cad5ef7c883191fe8",
512
- "sha256:daa405028b9fe92bfbb93624e13e0674a242a1c5434b70ef61a04294502fdb65",
513
- "sha256:dcfa601d95c00aa670ec5e4bf791caf6ba0bcf266de940fb54d44c278bd302fe",
514
- "sha256:f59275168cae1b02ca1ec7586a9804bb04ce427df92f8582a80d16e96c846b78"
515
- ],
516
- "markers": "platform_system == 'Darwin'",
517
- "version": "==8.2.13"
518
- },
519
483
  "google-auth": {
520
484
  "hashes": [
521
485
  "sha256:1370d4593e86213563547f97a92752fc658456fe4514c809544f330fed45a7ca",
@@ -524,6 +488,66 @@
524
488
  "markers": "python_version >= '3.7'",
525
489
  "version": "==2.40.3"
526
490
  },
491
+ "greenlet": {
492
+ "hashes": [
493
+ "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b",
494
+ "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735",
495
+ "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079",
496
+ "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d",
497
+ "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433",
498
+ "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58",
499
+ "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52",
500
+ "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31",
501
+ "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246",
502
+ "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f",
503
+ "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671",
504
+ "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8",
505
+ "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d",
506
+ "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f",
507
+ "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0",
508
+ "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd",
509
+ "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337",
510
+ "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0",
511
+ "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633",
512
+ "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b",
513
+ "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa",
514
+ "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31",
515
+ "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9",
516
+ "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b",
517
+ "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4",
518
+ "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc",
519
+ "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c",
520
+ "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98",
521
+ "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f",
522
+ "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c",
523
+ "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590",
524
+ "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3",
525
+ "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2",
526
+ "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9",
527
+ "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5",
528
+ "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02",
529
+ "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0",
530
+ "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1",
531
+ "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c",
532
+ "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594",
533
+ "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5",
534
+ "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d",
535
+ "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a",
536
+ "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6",
537
+ "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b",
538
+ "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df",
539
+ "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945",
540
+ "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae",
541
+ "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb",
542
+ "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504",
543
+ "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb",
544
+ "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01",
545
+ "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c",
546
+ "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968"
547
+ ],
548
+ "markers": "python_version >= '3.9'",
549
+ "version": "==3.2.4"
550
+ },
527
551
  "hiredis": {
528
552
  "hashes": [
529
553
  "sha256:0079ef1e03930b364556b78548e67236ab3def4e07e674f6adfc52944aa972dd",
@@ -1053,11 +1077,11 @@
1053
1077
  },
1054
1078
  "platformdirs": {
1055
1079
  "hashes": [
1056
- "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc",
1057
- "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"
1080
+ "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85",
1081
+ "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf"
1058
1082
  ],
1059
1083
  "markers": "python_version >= '3.9'",
1060
- "version": "==4.3.8"
1084
+ "version": "==4.4.0"
1061
1085
  },
1062
1086
  "pluggy": {
1063
1087
  "hashes": [
@@ -1100,12 +1124,12 @@
1100
1124
  },
1101
1125
  "prompt-toolkit": {
1102
1126
  "hashes": [
1103
- "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07",
1104
- "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed"
1127
+ "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855",
1128
+ "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"
1105
1129
  ],
1106
1130
  "index": "pypi",
1107
1131
  "markers": "python_version >= '3.8'",
1108
- "version": "==3.0.51"
1132
+ "version": "==3.0.52"
1109
1133
  },
1110
1134
  "psutil": {
1111
1135
  "hashes": [
@@ -0,0 +1,274 @@
1
+ ---
2
+ reference:
3
+ - field: name
4
+ mandatory_prefix: SCS-
5
+ - field: cpus
6
+ - field: ram
7
+ - field: disk
8
+ - field: public
9
+ default: true
10
+ - field: disabled
11
+ default: false
12
+
13
+ mandatory:
14
+ - name: SCS-1L-1
15
+ cpus: 1
16
+ ram: 1024
17
+ disk: 0
18
+ scs:cpu-type: crowded-core
19
+ scs:disk0-type: network
20
+ scs:name-v1: SCS-1L:1
21
+ scs:name-v2: SCS-1L-1
22
+ hw_rng:allowed: "true"
23
+ - name: SCS-1L-1-5
24
+ cpus: 1
25
+ ram: 1024
26
+ disk: 5
27
+ scs:cpu-type: crowded-core
28
+ scs:disk0-type: network
29
+ scs:name-v1: SCS-1L:5
30
+ scs:name-v2: SCS-1L-5
31
+ hw_rng:allowed: "true"
32
+ - name: SCS-1V-2
33
+ cpus: 1
34
+ ram: 2048
35
+ disk: 0
36
+ scs:cpu-type: shared-core
37
+ scs:disk0-type: network
38
+ scs:name-v1: SCS-1V:2
39
+ scs:name-v2: SCS-1V-2
40
+ hw_rng:allowed: "true"
41
+ - name: SCS-1V-2-5
42
+ cpus: 1
43
+ ram: 2048
44
+ disk: 5
45
+ scs:cpu-type: shared-core
46
+ scs:disk0-type: network
47
+ scs:name-v1: SCS-1V:2:5
48
+ scs:name-v2: SCS-1V-2-5
49
+ hw_rng:allowed: "true"
50
+ - name: SCS-1V-4
51
+ cpus: 1
52
+ ram: 4096
53
+ disk: 0
54
+ scs:cpu-type: shared-core
55
+ scs:disk0-type: network
56
+ scs:name-v1: SCS-1V:4
57
+ scs:name-v2: SCS-1V-4
58
+ hw_rng:allowed: "true"
59
+ - name: SCS-1V-4-10
60
+ cpus: 1
61
+ ram: 4096
62
+ disk: 10
63
+ scs:cpu-type: shared-core
64
+ scs:disk0-type: network
65
+ scs:name-v1: SCS-1V:4:10
66
+ scs:name-v2: SCS-1V-4-10
67
+ hw_rng:allowed: "true"
68
+ - name: SCS-1V-8
69
+ cpus: 1
70
+ ram: 8192
71
+ disk: 0
72
+ scs:cpu-type: shared-core
73
+ scs:disk0-type: network
74
+ scs:name-v1: SCS-1V:8
75
+ scs:name-v2: SCS-1V-8
76
+ hw_rng:allowed: "true"
77
+ - name: SCS-1V-8-20
78
+ cpus: 1
79
+ ram: 8192
80
+ disk: 20
81
+ scs:cpu-type: shared-core
82
+ scs:disk0-type: network
83
+ scs:name-v1: SCS-1V:8:20
84
+ scs:name-v2: SCS-1V-8-20
85
+ hw_rng:allowed: "true"
86
+ - name: SCS-2V-4
87
+ cpus: 2
88
+ ram: 4096
89
+ disk: 0
90
+ scs:cpu-type: shared-core
91
+ scs:disk0-type: network
92
+ scs:name-v1: SCS-2V:4
93
+ scs:name-v2: SCS-2V-4
94
+ hw_rng:allowed: "true"
95
+ - name: SCS-2V-4-10
96
+ cpus: 2
97
+ ram: 4096
98
+ disk: 10
99
+ scs:cpu-type: shared-core
100
+ scs:disk0-type: network
101
+ scs:name-v1: SCS-2V:4:10
102
+ scs:name-v2: SCS-2V-4-10
103
+ hw_rng:allowed: "true"
104
+ - name: SCS-2V-8
105
+ cpus: 2
106
+ ram: 8192
107
+ disk: 0
108
+ scs:cpu-type: shared-core
109
+ scs:disk0-type: network
110
+ scs:name-v1: SCS-2V:8
111
+ scs:name-v2: SCS-2V-8
112
+ hw_rng:allowed: "true"
113
+ - name: SCS-2V-8-20
114
+ cpus: 2
115
+ ram: 8192
116
+ disk: 20
117
+ scs:cpu-type: shared-core
118
+ scs:disk0-type: network
119
+ scs:name-v1: SCS-2V:8:20
120
+ scs:name-v2: SCS-2V-8-20
121
+ hw_rng:allowed: "true"
122
+ - name: SCS-2V-16
123
+ cpus: 2
124
+ ram: 16384
125
+ disk: 0
126
+ scs:cpu-type: shared-core
127
+ scs:disk0-type: network
128
+ scs:name-v1: SCS-2V:16
129
+ scs:name-v2: SCS-2V-16
130
+ hw_rng:allowed: "true"
131
+ - name: SCS-2V-16-50
132
+ cpus: 2
133
+ ram: 16384
134
+ disk: 50
135
+ scs:cpu-type: shared-core
136
+ scs:disk0-type: network
137
+ scs:name-v1: SCS-2V:16:50
138
+ scs:name-v2: SCS-2V-16-50
139
+ hw_rng:allowed: "true"
140
+ - name: SCS-4V-8
141
+ cpus: 4
142
+ ram: 8192
143
+ disk: 0
144
+ scs:cpu-type: shared-core
145
+ scs:disk0-type: network
146
+ scs:name-v1: SCS-4V:8
147
+ scs:name-v2: SCS-4V-8
148
+ hw_rng:allowed: "true"
149
+ - name: SCS-4V-8-20
150
+ cpus: 4
151
+ ram: 8192
152
+ disk: 20
153
+ scs:cpu-type: shared-core
154
+ scs:disk0-type: network
155
+ scs:name-v1: SCS-4V:8:20
156
+ scs:name-v2: SCS-4V-8-20
157
+ hw_rng:allowed: "true"
158
+ - name: SCS-4V-16
159
+ cpus: 4
160
+ ram: 16384
161
+ disk: 0
162
+ scs:cpu-type: shared-core
163
+ scs:disk0-type: network
164
+ scs:name-v1: SCS-4V:16
165
+ scs:name-v2: SCS-4V-16
166
+ hw_rng:allowed: "true"
167
+ - name: SCS-4V-16-50
168
+ cpus: 4
169
+ ram: 16384
170
+ disk: 50
171
+ scs:cpu-type: shared-core
172
+ scs:disk0-type: network
173
+ scs:name-v1: SCS-4V:16:50
174
+ scs:name-v2: SCS-4V-16-50
175
+ hw_rng:allowed: "true"
176
+ - name: SCS-4V-32
177
+ cpus: 4
178
+ ram: 32768
179
+ disk: 0
180
+ scs:cpu-type: shared-core
181
+ scs:disk0-type: network
182
+ scs:name-v1: SCS-4V:32
183
+ scs:name-v2: SCS-4V-32
184
+ hw_rng:allowed: "true"
185
+ - name: SCS-4V-32-100
186
+ cpus: 4
187
+ ram: 32768
188
+ disk: 100
189
+ scs:cpu-type: shared-core
190
+ scs:disk0-type: network
191
+ scs:name-v1: SCS-4V:32:100
192
+ scs:name-v2: SCS-4V-32-100
193
+ hw_rng:allowed: "true"
194
+ - name: SCS-8V-16
195
+ cpus: 8
196
+ ram: 16384
197
+ disk: 0
198
+ scs:cpu-type: shared-core
199
+ scs:disk0-type: network
200
+ scs:name-v1: SCS-8V:16
201
+ scs:name-v2: SCS-8V-16
202
+ hw_rng:allowed: "true"
203
+ - name: SCS-8V-16-50
204
+ cpus: 8
205
+ ram: 16384
206
+ disk: 50
207
+ scs:cpu-type: shared-core
208
+ scs:disk0-type: network
209
+ scs:name-v1: SCS-8V:16:50
210
+ scs:name-v2: SCS-8V-16-50
211
+ hw_rng:allowed: "true"
212
+ - name: SCS-8V-32
213
+ cpus: 8
214
+ ram: 32768
215
+ disk: 0
216
+ scs:cpu-type: shared-core
217
+ scs:disk0-type: network
218
+ scs:name-v1: SCS-8V:32
219
+ scs:name-v2: SCS-8V-32
220
+ hw_rng:allowed: "true"
221
+ - name: SCS-8V-32-100
222
+ cpus: 8
223
+ ram: 32768
224
+ disk: 100
225
+ scs:cpu-type: shared-core
226
+ scs:disk0-type: network
227
+ scs:name-v1: SCS-8V:32:100
228
+ scs:name-v2: SCS-8V-32-100
229
+ hw_rng:allowed: "true"
230
+ - name: SCS-16V-32
231
+ cpus: 16
232
+ ram: 32768
233
+ disk: 0
234
+ scs:cpu-type: shared-core
235
+ scs:disk0-type: network
236
+ scs:name-v1: SCS-16V:32
237
+ scs:name-v2: SCS-16V-32
238
+ hw_rng:allowed: "true"
239
+ - name: SCS-16V-32-100
240
+ cpus: 16
241
+ ram: 32768
242
+ disk: 100
243
+ scs:cpu-type: shared-core
244
+ scs:disk0-type: network
245
+ scs:name-v1: SCS-16V:32:100
246
+ scs:name-v2: SCS-16V-32-100
247
+ hw_rng:allowed: "true"
248
+ - name: SCS-2V-4-20s
249
+ cpus: 2
250
+ ram: 4096
251
+ disk: 20
252
+ scs:cpu-type: shared-core
253
+ scs:disk0-type: ssd
254
+ scs:name-v1: SCS-2V:4:20s
255
+ scs:name-v2: SCS-2V-4-20s
256
+ hw_rng:allowed: "true"
257
+ - name: SCS-4V-8-50s
258
+ cpus: 4
259
+ ram: 8192
260
+ disk: 50
261
+ scs:cpu-type: shared-core
262
+ scs:disk0-type: ssd
263
+ scs:name-v1: SCS-4V:8:50s
264
+ scs:name-v2: SCS-4V-8-50s
265
+ hw_rng:allowed: "true"
266
+ - name: SCS-8V-32-100s
267
+ cpus: 8
268
+ ram: 32768
269
+ disk: 100
270
+ scs:cpu-type: shared-core
271
+ scs:disk0-type: ssd
272
+ scs:name-v1: SCS-8V:32:100s
273
+ scs:name-v2: SCS-8V-32-100s
274
+ hw_rng:allowed: "true"
@@ -1313,9 +1313,9 @@
1313
1313
  }
1314
1314
  },
1315
1315
  "node_modules/@types/react": {
1316
- "version": "19.1.11",
1317
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.11.tgz",
1318
- "integrity": "sha512-lr3jdBw/BGj49Eps7EvqlUaoeA0xpj3pc0RoJkHpYaCHkVK7i28dKyImLQb3JVlqs3aYSXf7qYuWOW/fgZnTXQ==",
1316
+ "version": "19.1.12",
1317
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz",
1318
+ "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==",
1319
1319
  "dev": true,
1320
1320
  "license": "MIT",
1321
1321
  "dependencies": {
@@ -1323,9 +1323,9 @@
1323
1323
  }
1324
1324
  },
1325
1325
  "node_modules/@types/react-dom": {
1326
- "version": "19.1.7",
1327
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz",
1328
- "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==",
1326
+ "version": "19.1.8",
1327
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.8.tgz",
1328
+ "integrity": "sha512-xG7xaBMJCpcK0RpN8jDbAACQo54ycO6h4dSSmgv8+fu6ZIAdANkx/WsawASUjVXYfy+J9AbUpRMNNEsXCDfDBQ==",
1329
1329
  "dev": true,
1330
1330
  "license": "MIT",
1331
1331
  "peerDependencies": {
@@ -9,6 +9,7 @@ from cliff.command import Command
9
9
  from loguru import logger
10
10
  from tabulate import tabulate
11
11
 
12
+ from osism import utils
12
13
  from osism.data import enums
13
14
  from osism.data.playbooks import MAP_ROLE2ENVIRONMENT, MAP_ROLE2RUNTIME
14
15
  from osism.tasks import ansible, ceph, kolla, kubernetes, handle_task
@@ -451,6 +452,9 @@ class Run(Command):
451
452
  return rc
452
453
 
453
454
  def take_action(self, parsed_args):
455
+ # Check if tasks are locked before proceeding
456
+ utils.check_task_lock_and_exit()
457
+
454
458
  action = parsed_args.action
455
459
  arguments = parsed_args.arguments
456
460
  environment = parsed_args.environment
@@ -5,6 +5,7 @@ import argparse
5
5
  from cliff.command import Command
6
6
  from loguru import logger
7
7
 
8
+ from osism import utils
8
9
  from osism.tasks import ansible, handle_task
9
10
 
10
11
 
@@ -17,6 +18,9 @@ class Sync(Command):
17
18
  return parser
18
19
 
19
20
  def take_action(self, parsed_args):
21
+ # Check if tasks are locked before proceeding
22
+ utils.check_task_lock_and_exit()
23
+
20
24
  arguments = parsed_args.arguments
21
25
 
22
26
  t = ansible.run.delay(
@@ -0,0 +1,91 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+
3
+ from cliff.command import Command
4
+ from loguru import logger
5
+
6
+ from osism import utils
7
+
8
+
9
+ class Lock(Command):
10
+ """Lock task execution to prevent new tasks from starting"""
11
+
12
+ def get_parser(self, prog_name):
13
+ parser = super(Lock, self).get_parser(prog_name)
14
+ parser.add_argument(
15
+ "--user",
16
+ help="User name to associate with the lock (defaults to dragon)",
17
+ )
18
+ parser.add_argument("--reason", help="Reason for locking tasks")
19
+ return parser
20
+
21
+ def take_action(self, parsed_args):
22
+ user = parsed_args.user or "dragon"
23
+ reason = parsed_args.reason
24
+
25
+ # Check if already locked
26
+ lock_info = utils.is_task_locked()
27
+ if lock_info and lock_info.get("locked"):
28
+ existing_user = lock_info.get("user", "unknown")
29
+ existing_timestamp = lock_info.get("timestamp", "unknown")
30
+ existing_reason = lock_info.get("reason")
31
+ logger.warning(
32
+ f"Tasks are already locked by {existing_user} at {existing_timestamp}"
33
+ )
34
+ if existing_reason:
35
+ logger.warning(f"Existing reason: {existing_reason}")
36
+ return
37
+
38
+ # Set the lock
39
+ if utils.set_task_lock(user, reason):
40
+ logger.info(f"Tasks locked by {user}")
41
+ if reason:
42
+ logger.info(f"Reason: {reason}")
43
+ logger.info("New tasks will be prevented from starting")
44
+ logger.info("Running tasks will continue normally")
45
+ logger.info("Use 'osism unlock' to remove the lock")
46
+ else:
47
+ logger.error("Failed to set task lock")
48
+ return 1
49
+
50
+
51
+ class Unlock(Command):
52
+ """Unlock task execution to allow new tasks to start"""
53
+
54
+ def take_action(self, parsed_args):
55
+ # Check if currently locked
56
+ lock_info = utils.is_task_locked()
57
+ if not lock_info or not lock_info.get("locked"):
58
+ logger.info("Tasks are not currently locked")
59
+ return
60
+
61
+ existing_user = lock_info.get("user", "unknown")
62
+ existing_timestamp = lock_info.get("timestamp", "unknown")
63
+ existing_reason = lock_info.get("reason")
64
+
65
+ # Remove the lock
66
+ if utils.remove_task_lock():
67
+ logger.info(
68
+ f"Task lock removed (was set by {existing_user} at {existing_timestamp})"
69
+ )
70
+ if existing_reason:
71
+ logger.info(f"Previous reason: {existing_reason}")
72
+ logger.info("New tasks can now be started")
73
+ else:
74
+ logger.error("Failed to remove task lock")
75
+ return 1
76
+
77
+
78
+ class LockStatus(Command):
79
+ """Show current task lock status"""
80
+
81
+ def take_action(self, parsed_args):
82
+ lock_info = utils.is_task_locked()
83
+ if lock_info and lock_info.get("locked"):
84
+ user = lock_info.get("user", "unknown")
85
+ timestamp = lock_info.get("timestamp", "unknown")
86
+ reason = lock_info.get("reason")
87
+ logger.info(f"Tasks are LOCKED by {user} at {timestamp}")
88
+ if reason:
89
+ logger.info(f"Reason: {reason}")
90
+ else:
91
+ logger.info("Tasks are UNLOCKED")