flyteplugins-union 0.5.0__tar.gz → 0.5.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.
- {flyteplugins_union-0.5.0/src/flyteplugins_union.egg-info → flyteplugins_union-0.5.2}/PKG-INFO +1 -1
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/licenses/BSL.txt +1 -1
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/role.py +13 -7
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_base_volume.py +50 -1
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/_juicefs/_backend.py +14 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/_juicefs/_redis.py +98 -22
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/_juicefs/_sqlite.py +12 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_role.py +20 -12
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2/src/flyteplugins_union.egg-info}/PKG-INFO +1 -1
- flyteplugins_union-0.5.2/src/flyteplugins_union.egg-info/scm_version.json +8 -0
- flyteplugins_union-0.5.0/src/flyteplugins_union.egg-info/scm_version.json +0 -8
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/LICENSE +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/README.md +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/README_PYPI.md +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/licenses/APL.txt +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/pyproject.toml +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/setup.cfg +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/_debug.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/_tui/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/_tui/_volume_explore.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/_volume_index.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/_volume_session.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/api_key.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/assignment.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/cluster.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/cluster_pool.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/debug.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/member.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/policy.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/queue.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/user.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/volume.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/errors.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/authorizer/authorizer_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/authorizer/authorizer_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/authorizer/authorizer_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/authorizer/definition_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/authorizer/definition_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/authorizer/payload_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/authorizer/payload_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/cluster/cluster_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/cluster/cluster_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/cluster/cluster_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/cluster/definition_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/cluster/definition_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/cluster/payload_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/cluster/payload_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/clusterpool/clusterpool_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/clusterpool/clusterpool_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/clusterpool/clusterpool_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/clusterpool/payload_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/clusterpool/payload_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/authorization_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/authorization_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/cluster_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/cluster_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/deployment_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/deployment_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/identifier_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/identifier_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/identity_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/identity_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/list_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/list_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/policy_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/policy_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/role_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/common/role_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/app_definition_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/app_definition_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/app_payload_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/app_payload_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/app_service_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/app_service_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/app_service_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/enums_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/enums_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/member_payload_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/member_payload_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/member_service_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/member_service_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/member_service_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/policy_payload_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/policy_payload_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/policy_service_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/policy_service_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/policy_service_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/role_payload_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/role_payload_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/role_service_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/role_service_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/role_service_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/user_payload_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/user_payload_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/user_service_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/user_service_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/identity/user_service_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/queue/queue_connect.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/queue/queue_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/queue/queue_pb2.pyi +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/validate/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/validate/validate/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/validate/validate/validate_pb2.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/_juicefs/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/_juicefs/_common.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/_juicefs/_metadata.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/_juicefs/bin/.gitkeep +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/backend.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_ro_volume.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_rw_volume.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_volume_transformer.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_api_key.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_assignment.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_cluster.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_cluster_pool.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_member.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_policy.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_queue.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_ssh_debug.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_user.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_volume_explore.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/utils/__init__.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/utils/auth.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/utils/image.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/ws_proxy.py +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/SOURCES.txt +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/dependency_links.txt +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/entry_points.txt +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/requires.txt +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/scm_file_list.json +0 -0
- {flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/top_level.txt +0 -0
|
@@ -17,7 +17,7 @@ Additional Use Grant: You may make use of the Licensed Work, provided that
|
|
|
17
17
|
computer programs whose source code are controlled by
|
|
18
18
|
such third parties.
|
|
19
19
|
|
|
20
|
-
Change Date: 2030-
|
|
20
|
+
Change Date: 2030-07-13
|
|
21
21
|
|
|
22
22
|
Change License: Apache License, Version 2.0
|
|
23
23
|
|
|
@@ -21,10 +21,13 @@ def _new_role_yaml(name: str, description: str = "") -> str:
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def _role_to_yaml(role: Role) -> str:
|
|
24
|
-
"""Serialize a Role to YAML for interactive editing.
|
|
25
|
-
|
|
24
|
+
"""Serialize a Role to YAML for interactive editing.
|
|
25
|
+
|
|
26
|
+
Only actions are editable; the role name and description cannot be changed.
|
|
27
|
+
"""
|
|
28
|
+
data = {"name": role.name, "actions": role.actions}
|
|
26
29
|
body = _yaml.safe_dump(data, default_flow_style=False, sort_keys=False)
|
|
27
|
-
comment = "# Valid actions:\n"
|
|
30
|
+
comment = "# Only 'actions' can be edited. Valid actions:\n"
|
|
28
31
|
for a in _ALL_ACTIONS:
|
|
29
32
|
comment += f"# - {a}\n"
|
|
30
33
|
return comment + "\n" + body
|
|
@@ -141,9 +144,10 @@ def delete_role(cfg: common.CLIConfig, name: str, yes: bool):
|
|
|
141
144
|
@click.argument("name", type=str)
|
|
142
145
|
@click.pass_obj
|
|
143
146
|
def update_role(cfg: common.CLIConfig, name: str):
|
|
144
|
-
"""Update a role interactively.
|
|
147
|
+
"""Update a role's actions interactively.
|
|
145
148
|
|
|
146
149
|
Opens the role in your $EDITOR as YAML. Save and close to apply changes.
|
|
150
|
+
Only actions can be edited; the role name and description cannot be changed.
|
|
147
151
|
|
|
148
152
|
Examples:
|
|
149
153
|
|
|
@@ -161,11 +165,13 @@ def update_role(cfg: common.CLIConfig, name: str):
|
|
|
161
165
|
|
|
162
166
|
def _apply(edited_yaml):
|
|
163
167
|
data = _yaml.safe_load(edited_yaml)
|
|
164
|
-
new_description = data.get("description", "")
|
|
165
168
|
new_actions = sorted(data.get("actions") or [])
|
|
166
|
-
if
|
|
169
|
+
if new_actions == sorted(role.actions):
|
|
167
170
|
return "no_changes"
|
|
168
|
-
Role.update(name,
|
|
171
|
+
Role.update(name, actions=data.get("actions") or [])
|
|
172
|
+
# edit_with_retry treats None as "cancelled"; return a marker so the
|
|
173
|
+
# success message below is printed.
|
|
174
|
+
return "updated"
|
|
169
175
|
|
|
170
176
|
result = edit_with_retry(yaml_text, _apply, console=console, noun="role")
|
|
171
177
|
if result == "no_changes":
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_base_volume.py
RENAMED
|
@@ -56,6 +56,7 @@ automatically at task return) also unmounts.
|
|
|
56
56
|
from __future__ import annotations
|
|
57
57
|
|
|
58
58
|
import asyncio
|
|
59
|
+
import functools
|
|
59
60
|
import os
|
|
60
61
|
import re
|
|
61
62
|
import secrets
|
|
@@ -172,6 +173,30 @@ def _ensure_etc_mtab() -> None:
|
|
|
172
173
|
_VOLUME_BACKENDS: dict[str, _VolumeBackend] = {"juicefs": JuiceFSVolumeBackend()}
|
|
173
174
|
|
|
174
175
|
|
|
176
|
+
def _lifecycle_serialized(method):
|
|
177
|
+
"""Serialize lifecycle ops (mount / fork / commit) per metadata store.
|
|
178
|
+
|
|
179
|
+
A background checkpoint loop (:meth:`RWVolume.commit` on a timer) can
|
|
180
|
+
otherwise interleave with a concurrent :meth:`fork` or terminal
|
|
181
|
+
:meth:`RWVolume.finalize` on the same volume: fork's live path unmounts
|
|
182
|
+
and remounts the store mid-snapshot, so an unserialized checkpoint can
|
|
183
|
+
flush a store that fork just tore down, snapshot a half-materialized
|
|
184
|
+
index, or double-register the mount daemon. All entry points funnel
|
|
185
|
+
through one ``asyncio.Lock`` keyed by resolved ``meta_dir`` (the store
|
|
186
|
+
identity; mount paths alias it 1:1 today). Internal helpers stay
|
|
187
|
+
undecorated — only entry points take the lock, so the
|
|
188
|
+
``_commit_unmount`` → keep-alive fallback can't self-deadlock.
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
@functools.wraps(method)
|
|
192
|
+
async def wrapper(self, *args, **kwargs):
|
|
193
|
+
meta_dir = kwargs.get("meta_dir") or self._active_meta_dir or self._default_meta_dir()
|
|
194
|
+
async with type(self)._lifecycle_lock(meta_dir):
|
|
195
|
+
return await method(self, *args, **kwargs)
|
|
196
|
+
|
|
197
|
+
return wrapper
|
|
198
|
+
|
|
199
|
+
|
|
175
200
|
class ActionRef(BaseModel):
|
|
176
201
|
"""Provenance: the action (one task execution within a run) that
|
|
177
202
|
produced a particular :class:`Volume` version, plus the output slot it
|
|
@@ -312,6 +337,13 @@ class Volume(BaseModel):
|
|
|
312
337
|
# to decide whether to use the live flush-and-upload path or the cold
|
|
313
338
|
# File.copy_to path. Populated by mount(), cleared by commit().
|
|
314
339
|
_live_meta: ClassVar[Set[str]] = set()
|
|
340
|
+
# One lock per metadata store, taken by every lifecycle entry point via
|
|
341
|
+
# ``@_lifecycle_serialized``. Never handed out — see that decorator.
|
|
342
|
+
_lifecycle_locks: ClassVar[Dict[str, asyncio.Lock]] = {}
|
|
343
|
+
|
|
344
|
+
@classmethod
|
|
345
|
+
def _lifecycle_lock(cls, meta_dir: str) -> asyncio.Lock:
|
|
346
|
+
return cls._lifecycle_locks.setdefault(meta_dir, asyncio.Lock())
|
|
315
347
|
|
|
316
348
|
# Per-instance: where THIS Volume was last mounted by mount(), so the
|
|
317
349
|
# type transformer can auto-commit on task return without the caller
|
|
@@ -435,6 +467,7 @@ class Volume(BaseModel):
|
|
|
435
467
|
base = cls.empty(name, bucket, storage=storage, region=region, metadata_store_type=metadata_store_type)
|
|
436
468
|
return _coerce_class(base, RWVolume)
|
|
437
469
|
|
|
470
|
+
@_lifecycle_serialized
|
|
438
471
|
async def mount(
|
|
439
472
|
self,
|
|
440
473
|
*,
|
|
@@ -774,6 +807,7 @@ class Volume(BaseModel):
|
|
|
774
807
|
message=message,
|
|
775
808
|
)
|
|
776
809
|
|
|
810
|
+
@_lifecycle_serialized
|
|
777
811
|
async def _commit_unmount(
|
|
778
812
|
self,
|
|
779
813
|
*,
|
|
@@ -840,7 +874,8 @@ class Volume(BaseModel):
|
|
|
840
874
|
"add `RUN ln -sf /proc/self/mounts /etc/mtab` to the task image.",
|
|
841
875
|
e,
|
|
842
876
|
)
|
|
843
|
-
|
|
877
|
+
# Direct impl call: we already hold this store's lifecycle lock.
|
|
878
|
+
return await self._commit_keepalive_impl(mount_path=mount_path, meta_dir=meta_dir, message=message)
|
|
844
879
|
new_index, index_bytes, metadata_path = await self._snapshot_and_upload_index(
|
|
845
880
|
meta_dir=meta_dir, tmp_prefix="vol-commit-", flush_live=False
|
|
846
881
|
)
|
|
@@ -1016,6 +1051,7 @@ class Volume(BaseModel):
|
|
|
1016
1051
|
except OSError:
|
|
1017
1052
|
pass
|
|
1018
1053
|
|
|
1054
|
+
@_lifecycle_serialized
|
|
1019
1055
|
async def fork(
|
|
1020
1056
|
self,
|
|
1021
1057
|
name: str,
|
|
@@ -1195,12 +1231,25 @@ class Volume(BaseModel):
|
|
|
1195
1231
|
|
|
1196
1232
|
return config
|
|
1197
1233
|
|
|
1234
|
+
@_lifecycle_serialized
|
|
1198
1235
|
async def _commit_keepalive(
|
|
1199
1236
|
self,
|
|
1200
1237
|
*,
|
|
1201
1238
|
mount_path: Optional[str] = None,
|
|
1202
1239
|
meta_dir: Optional[str] = None,
|
|
1203
1240
|
message: Optional[str] = None,
|
|
1241
|
+
) -> "Volume":
|
|
1242
|
+
"""Serialized entry point for keep-alive commits (see
|
|
1243
|
+
:func:`_lifecycle_serialized`); :meth:`_commit_unmount` calls the impl
|
|
1244
|
+
directly because it already holds the store's lock."""
|
|
1245
|
+
return await self._commit_keepalive_impl(mount_path=mount_path, meta_dir=meta_dir, message=message)
|
|
1246
|
+
|
|
1247
|
+
async def _commit_keepalive_impl(
|
|
1248
|
+
self,
|
|
1249
|
+
*,
|
|
1250
|
+
mount_path: Optional[str] = None,
|
|
1251
|
+
meta_dir: Optional[str] = None,
|
|
1252
|
+
message: Optional[str] = None,
|
|
1204
1253
|
) -> "Volume":
|
|
1205
1254
|
"""Drain writeback, then snapshot + publish the live index — without
|
|
1206
1255
|
unmounting. The keep-alive counterpart to :meth:`_commit_unmount`,
|
|
@@ -318,6 +318,20 @@ class JuiceFSVolumeBackend:
|
|
|
318
318
|
cmd = [
|
|
319
319
|
self.client_binary,
|
|
320
320
|
"mount",
|
|
321
|
+
# Branches share one bucket but each has a private metadata DB, so a
|
|
322
|
+
# client's slice refcounts can't see sibling/parent references. Any
|
|
323
|
+
# client-side object deletion (slice compaction — fired inline on
|
|
324
|
+
# the read/write path, not bgjob-gated — file purge, trash expiry)
|
|
325
|
+
# may therefore destroy chunks other branches still reference.
|
|
326
|
+
# --max-deletes 0 no-ops the single gate all those paths funnel
|
|
327
|
+
# through (meta.deleteSlice); compaction still rewrites metadata
|
|
328
|
+
# and writes the merged slice, it just never deletes old objects.
|
|
329
|
+
# --no-bgjob additionally stops the hourly cleanup sweeps and
|
|
330
|
+
# shared-bucket meta backups. Garbage is reclaimed by an external
|
|
331
|
+
# reaper that unions live-branch references; never `juicefs gc`.
|
|
332
|
+
"--max-deletes",
|
|
333
|
+
"0",
|
|
334
|
+
"--no-bgjob",
|
|
321
335
|
"--cache-dir",
|
|
322
336
|
config.cache_dir,
|
|
323
337
|
"--max-uploads",
|
|
@@ -31,7 +31,9 @@ def _free_tcp_port() -> int:
|
|
|
31
31
|
def _redis_server_cmd(port: int, dirpath: str, dbfilename: str) -> list[str]:
|
|
32
32
|
"""Argv for an in-process ``redis-server`` bound to localhost on ``port``,
|
|
33
33
|
persisting ``dbfilename`` under ``dirpath``. RDB-only (no AOF), no periodic
|
|
34
|
-
save — we drive persistence explicitly via ``
|
|
34
|
+
save — we drive persistence explicitly via ``BGSAVE`` (see
|
|
35
|
+
:func:`_bgsave_and_wait`, which relies on ours being the only dump in
|
|
36
|
+
flight).
|
|
35
37
|
"""
|
|
36
38
|
return [
|
|
37
39
|
"redis-server",
|
|
@@ -82,7 +84,21 @@ async def _redis_cli(port: int, *args: str, check: bool = False, timeout: float
|
|
|
82
84
|
return rc, stdout
|
|
83
85
|
|
|
84
86
|
|
|
85
|
-
|
|
87
|
+
def _tail_log(log_path: Optional[Path], max_bytes: int = 4096) -> str:
|
|
88
|
+
"""Best-effort read of the last ``max_bytes`` of a daemon log file."""
|
|
89
|
+
if log_path is None:
|
|
90
|
+
return ""
|
|
91
|
+
try:
|
|
92
|
+
with open(log_path, "rb") as f:
|
|
93
|
+
f.seek(0, 2)
|
|
94
|
+
size = f.tell()
|
|
95
|
+
f.seek(max(0, size - max_bytes))
|
|
96
|
+
return f.read().decode(errors="replace")
|
|
97
|
+
except OSError:
|
|
98
|
+
return ""
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
async def _wait_redis_ready(proc: subprocess.Popen, port: int, timeout: float, log_path: Optional[Path] = None) -> None:
|
|
86
102
|
"""Poll ``PING`` until the server replies ``PONG`` (or ``timeout``).
|
|
87
103
|
|
|
88
104
|
Raises :class:`RuntimeError` if the server exits before becoming ready and
|
|
@@ -92,9 +108,9 @@ async def _wait_redis_ready(proc: subprocess.Popen, port: int, timeout: float) -
|
|
|
92
108
|
deadline = asyncio.get_running_loop().time() + timeout
|
|
93
109
|
while True:
|
|
94
110
|
if proc.poll() is not None:
|
|
95
|
-
out = proc.stdout.read().decode(errors="replace") if proc.stdout else ""
|
|
96
111
|
raise RuntimeSystemError(
|
|
97
|
-
"RedisStartFailed",
|
|
112
|
+
"RedisStartFailed",
|
|
113
|
+
f"redis-server exited prematurely (rc={proc.returncode}): {_tail_log(log_path)}",
|
|
98
114
|
)
|
|
99
115
|
rc, stdout = await _redis_cli(port, "ping", timeout=5.0)
|
|
100
116
|
if rc == 0 and "PONG" in stdout:
|
|
@@ -125,14 +141,24 @@ class RedisMetadataStore:
|
|
|
125
141
|
async def start(self, meta_dir: str, timeout: float = 30.0) -> _MetadataStoreHandle:
|
|
126
142
|
port = _free_tcp_port()
|
|
127
143
|
_logger.info("[Volume.mount] starting redis-server in %s", meta_dir)
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
144
|
+
# Route the daemon's logs to a file, never a captured pipe: redis-server
|
|
145
|
+
# logs for its whole lifetime (background saves etc.), and a PIPE that
|
|
146
|
+
# nothing drains fills its ~64 KiB kernel buffer — redis then blocks
|
|
147
|
+
# inside its log write, every metadata op stalls behind it, and the
|
|
148
|
+
# whole mount wedges. Same failure mode (and same fix) as the mount
|
|
149
|
+
# daemon's stdio in ``_start_mount``; a file also preserves premature-
|
|
150
|
+
# exit diagnostics, which inherited stdio would scatter into the
|
|
151
|
+
# container log.
|
|
152
|
+
log_path = Path(meta_dir) / "redis-server.log"
|
|
153
|
+
with open(log_path, "ab") as logf: # noqa: ASYNC230 - local append-open, microseconds
|
|
154
|
+
proc = subprocess.Popen( # noqa: ASYNC220 - long-lived daemon held in a class-level dict
|
|
155
|
+
_redis_server_cmd(port, meta_dir, _INDEX_FILENAME),
|
|
156
|
+
stdout=logf,
|
|
157
|
+
stderr=subprocess.STDOUT,
|
|
158
|
+
start_new_session=True,
|
|
159
|
+
)
|
|
160
|
+
await _wait_redis_ready(proc, port, timeout, log_path)
|
|
161
|
+
_logger.info("[Volume.mount] redis-server ready on port %d (logs: %s)", port, log_path)
|
|
136
162
|
return _MetadataStoreHandle(proc=proc, port=port)
|
|
137
163
|
|
|
138
164
|
async def stop(self, handle: Optional[_MetadataStoreHandle], timeout: float) -> None:
|
|
@@ -141,7 +167,7 @@ class RedisMetadataStore:
|
|
|
141
167
|
"""
|
|
142
168
|
if handle is None:
|
|
143
169
|
return
|
|
144
|
-
# SHUTDOWN NOSAVE — we drove persistence ourselves via
|
|
170
|
+
# SHUTDOWN NOSAVE — we drove persistence ourselves via BGSAVE. redis-cli
|
|
145
171
|
# may return non-zero as the connection drops mid-shutdown; that's
|
|
146
172
|
# expected, so this call is unchecked. Never let a hung/failed shutdown
|
|
147
173
|
# leave the daemon unreaped — fall through to the wait + kill below.
|
|
@@ -157,7 +183,7 @@ class RedisMetadataStore:
|
|
|
157
183
|
async def flush(self, meta_dir: str, handle: Optional[_MetadataStoreHandle] = None) -> None:
|
|
158
184
|
if handle is None:
|
|
159
185
|
raise RuntimeError("RedisMetadataStore.flush requires a live handle from start().")
|
|
160
|
-
await
|
|
186
|
+
await _bgsave_and_wait(handle.port)
|
|
161
187
|
|
|
162
188
|
async def snapshot(self, meta_dir: str, tmp_prefix: str) -> str:
|
|
163
189
|
src = Path(meta_dir) / _INDEX_FILENAME
|
|
@@ -176,6 +202,49 @@ class RedisMetadataStore:
|
|
|
176
202
|
return await _disjoint_counters_redis(snapshot_path, offset)
|
|
177
203
|
|
|
178
204
|
|
|
205
|
+
async def _bgsave_and_wait(port: int, timeout: float = 600.0, poll_interval: float = 0.2) -> None:
|
|
206
|
+
"""Persist the dataset to the RDB via ``BGSAVE`` and wait for completion.
|
|
207
|
+
|
|
208
|
+
Replaces blocking ``SAVE``, which had two failure modes: (a) it stalls the
|
|
209
|
+
(single-threaded) server for the whole dump, so every metadata op — and
|
|
210
|
+
therefore every FUSE op on a live mount — hangs during a keep-alive
|
|
211
|
+
commit; (b) ``redis-cli SAVE`` ran under the default 10s client timeout,
|
|
212
|
+
so a dump that took longer killed the cli, failed the flush, and aborted
|
|
213
|
+
the commit spuriously while the server kept SAVEing.
|
|
214
|
+
|
|
215
|
+
``BGSAVE`` forks; the parent keeps serving. Our servers run with
|
|
216
|
+
``--save ""`` (no periodic saves), so the only BGSAVE in flight is ours:
|
|
217
|
+
completion is "``rdb_bgsave_in_progress`` back to 0", and correctness is
|
|
218
|
+
``rdb_last_bgsave_status:ok``. If a BGSAVE is already running (commit
|
|
219
|
+
racing a previous flush), the initial ``BGSAVE`` command reports the
|
|
220
|
+
schedule error but the poll below still tracks the in-flight dump; we
|
|
221
|
+
re-issue once it clears rather than fail.
|
|
222
|
+
"""
|
|
223
|
+
loop = asyncio.get_running_loop()
|
|
224
|
+
deadline = loop.time() + timeout
|
|
225
|
+
rc, out = await _redis_cli(port, "BGSAVE")
|
|
226
|
+
already_running = rc != 0 or "in progress" in out.lower()
|
|
227
|
+
while True:
|
|
228
|
+
_, info = await _redis_cli(port, "INFO", "persistence", check=True)
|
|
229
|
+
fields = dict(
|
|
230
|
+
line.split(":", 1) for line in info.splitlines() if ":" in line and not line.startswith("#")
|
|
231
|
+
)
|
|
232
|
+
if fields.get("rdb_bgsave_in_progress", "").strip() == "0":
|
|
233
|
+
if already_running:
|
|
234
|
+
# The dump we watched finish was a racing predecessor's; run
|
|
235
|
+
# our own so this flush's writes are guaranteed on disk.
|
|
236
|
+
already_running = False
|
|
237
|
+
await _redis_cli(port, "BGSAVE", check=True)
|
|
238
|
+
continue
|
|
239
|
+
status = fields.get("rdb_last_bgsave_status", "").strip()
|
|
240
|
+
if status != "ok":
|
|
241
|
+
raise RuntimeSystemError("RedisBgsaveFailed", f"BGSAVE finished with status {status!r}")
|
|
242
|
+
return
|
|
243
|
+
if loop.time() >= deadline:
|
|
244
|
+
raise RuntimeSystemError("RedisBgsaveTimeout", f"BGSAVE did not complete within {timeout}s")
|
|
245
|
+
await asyncio.sleep(poll_interval)
|
|
246
|
+
|
|
247
|
+
|
|
179
248
|
async def _disjoint_counters_redis(rdb_path: str, offset: int, timeout: float = 30.0) -> int:
|
|
180
249
|
if offset <= 0:
|
|
181
250
|
raise ValueError(f"offset must be positive, got {offset}")
|
|
@@ -184,14 +253,17 @@ async def _disjoint_counters_redis(rdb_path: str, offset: int, timeout: float =
|
|
|
184
253
|
raise RuntimeError(f"{rdb_path} does not exist")
|
|
185
254
|
|
|
186
255
|
port = _free_tcp_port()
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
256
|
+
# File-backed logs for the same no-undrained-pipe reason as ``start()``.
|
|
257
|
+
log_path = rdb.parent / f"{rdb.name}.redis-fork.log"
|
|
258
|
+
with open(log_path, "ab") as logf: # noqa: ASYNC230 - local append-open, microseconds
|
|
259
|
+
proc = subprocess.Popen( # noqa: ASYNC220 - ephemeral daemon, reaped in finally
|
|
260
|
+
_redis_server_cmd(port, str(rdb.parent), rdb.name),
|
|
261
|
+
stdout=logf,
|
|
262
|
+
stderr=subprocess.STDOUT,
|
|
263
|
+
start_new_session=True,
|
|
264
|
+
)
|
|
193
265
|
try:
|
|
194
|
-
await _wait_redis_ready(proc, port, timeout)
|
|
266
|
+
await _wait_redis_ready(proc, port, timeout, log_path)
|
|
195
267
|
|
|
196
268
|
current_max = 0
|
|
197
269
|
for name in _FORK_COUNTER_NAMES:
|
|
@@ -208,7 +280,7 @@ async def _disjoint_counters_redis(rdb_path: str, offset: int, timeout: float =
|
|
|
208
280
|
for name in _FORK_COUNTER_NAMES:
|
|
209
281
|
await _redis_cli(port, "INCRBY", name, str(applied), check=True)
|
|
210
282
|
|
|
211
|
-
await
|
|
283
|
+
await _bgsave_and_wait(port, timeout=timeout)
|
|
212
284
|
finally:
|
|
213
285
|
# Best-effort shutdown — never let cleanup mask the real error.
|
|
214
286
|
try:
|
|
@@ -218,4 +290,8 @@ async def _disjoint_counters_redis(rdb_path: str, offset: int, timeout: float =
|
|
|
218
290
|
if not await _await_proc_exit(proc, 5):
|
|
219
291
|
proc.kill()
|
|
220
292
|
await _await_proc_exit(proc, 5)
|
|
293
|
+
try:
|
|
294
|
+
log_path.unlink()
|
|
295
|
+
except OSError:
|
|
296
|
+
pass
|
|
221
297
|
return applied
|
|
@@ -58,6 +58,18 @@ class SqliteMetadataStore:
|
|
|
58
58
|
# caller runs it off the loop. Kept sync so the sync CLI path can call
|
|
59
59
|
# it directly without an event loop.
|
|
60
60
|
dst = Path(meta_dir) / _INDEX_FILENAME
|
|
61
|
+
# Scrub sidecars from any previous incarnation of this meta_dir (a
|
|
62
|
+
# remount after commit, or a task retry reusing the pod). SQLite pairs
|
|
63
|
+
# a WAL/SHM with its main file via a header salt, but a leftover
|
|
64
|
+
# ``-wal`` written by an *older* database at this same path can pass
|
|
65
|
+
# that check and get replayed over the fresh snapshot, silently mixing
|
|
66
|
+
# two versions' metadata. The snapshot itself is complete (backup API
|
|
67
|
+
# folds the WAL in), so stale sidecars are never legitimate here.
|
|
68
|
+
for sidecar in (dst, Path(str(dst) + "-wal"), Path(str(dst) + "-shm")):
|
|
69
|
+
try:
|
|
70
|
+
sidecar.unlink()
|
|
71
|
+
except FileNotFoundError:
|
|
72
|
+
pass
|
|
61
73
|
shutil.move(snapshot_path, str(dst))
|
|
62
74
|
|
|
63
75
|
async def disjoint_fork_counters(self, snapshot_path: str, offset: int) -> int:
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_role.py
RENAMED
|
@@ -13,11 +13,12 @@ from flyteplugins.union.internal.common.identifier_pb2 import RoleIdentifier
|
|
|
13
13
|
from flyteplugins.union.internal.common.role_pb2 import ROLE_TYPE_CUSTOM, RoleSpec, RoleType
|
|
14
14
|
from flyteplugins.union.internal.common.role_pb2 import Role as RolePb2
|
|
15
15
|
from flyteplugins.union.internal.identity.role_payload_pb2 import (
|
|
16
|
+
CreateRoleActionRequest,
|
|
16
17
|
CreateRoleRequest,
|
|
18
|
+
DeleteRoleActionRequest,
|
|
17
19
|
DeleteRoleRequest,
|
|
18
20
|
GetRoleRequest,
|
|
19
21
|
ListRolesRequest,
|
|
20
|
-
UpdateRoleRequest,
|
|
21
22
|
)
|
|
22
23
|
from flyteplugins.union.internal.identity.role_service_connect import RoleServiceClient
|
|
23
24
|
|
|
@@ -112,22 +113,29 @@ class Role(ToJSONMixin):
|
|
|
112
113
|
|
|
113
114
|
@syncify
|
|
114
115
|
@classmethod
|
|
115
|
-
async def update(cls, name: str, *,
|
|
116
|
-
"""Update a role.
|
|
116
|
+
async def update(cls, name: str, *, actions: list[str]) -> None:
|
|
117
|
+
"""Update a role so its actions match exactly the given list.
|
|
118
|
+
|
|
119
|
+
The UpdateRole RPC is deprecated and rejected server-side, so the
|
|
120
|
+
current actions are diffed against the desired ones and each delta is
|
|
121
|
+
applied via CreateRoleAction/DeleteRoleAction. The role name and
|
|
122
|
+
description cannot be changed.
|
|
123
|
+
"""
|
|
117
124
|
ensure_client()
|
|
118
125
|
client = get_client()
|
|
119
126
|
org = get_init_config().org
|
|
120
127
|
svc = RoleServiceClient(**client.session_config.connect_kwargs())
|
|
121
128
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
role_id = RoleIdentifier(organization=org, name=name)
|
|
130
|
+
response = await svc.get_role(GetRoleRequest(id=role_id))
|
|
131
|
+
|
|
132
|
+
desired = {Action.Value(_resolve_action_name(a)) for a in actions}
|
|
133
|
+
current = set(response.role.actions)
|
|
134
|
+
|
|
135
|
+
for action in sorted(desired - current):
|
|
136
|
+
await svc.create_role_action(CreateRoleActionRequest(id=role_id, action=action))
|
|
137
|
+
for action in sorted(current - desired):
|
|
138
|
+
await svc.delete_role_action(DeleteRoleActionRequest(id=role_id, action=action))
|
|
131
139
|
|
|
132
140
|
@syncify
|
|
133
141
|
@classmethod
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/__init__.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/_tui/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/_volume_index.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/_volume_session.py
RENAMED
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/assignment.py
RENAMED
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/cli/cluster_pool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/internal/__init__.py
RENAMED
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_internal/backend.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_ro_volume.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/io/_rw_volume.py
RENAMED
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/__init__.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_api_key.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_assignment.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_cluster.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_cluster_pool.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_member.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_policy.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_queue.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_ssh_debug.py
RENAMED
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/remote/_user.py
RENAMED
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins/union/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
{flyteplugins_union-0.5.0 → flyteplugins_union-0.5.2}/src/flyteplugins_union.egg-info/top_level.txt
RENAMED
|
File without changes
|