|
45 | 45 | deployment_status, |
46 | 46 | ) |
47 | 47 | from .....deployment.kubernetes._util import core_v1_client |
48 | | -from .....deployment.kubernetes.neonvm import PowerState as NeonVMPowerState |
49 | 48 | from .....deployment.kubernetes.neonvm import set_virtualmachine_power_state |
50 | 49 | from .....deployment.kubernetes.volume_clone import ( |
51 | 50 | clone_branch_database_volume, |
|
95 | 94 | from ....settings import get_settings as get_api_settings |
96 | 95 | from .api_keys import api as api_key_api |
97 | 96 | from .auth import api as auth_api |
| 97 | +from .control_tasks import ( |
| 98 | + _CONTROL_TO_POWER_STATE, |
| 99 | + _CONTROL_TRANSITION_INITIAL, |
| 100 | + dispatch_control, |
| 101 | + perform_control, |
| 102 | +) |
98 | 103 | from .resize_tasks import dispatch_resize |
99 | 104 | from .tasks import task_api |
100 | 105 |
|
@@ -284,6 +289,12 @@ async def refresh_branch_status(branch_id: Identifier) -> BranchServiceStatus: |
284 | 289 |
|
285 | 290 |
|
286 | 291 | async def _refresh_branch_status(branch: Branch) -> BranchServiceStatus: |
| 292 | + if branch.control_task_id is not None: |
| 293 | + result = perform_control.AsyncResult(str(branch.control_task_id)) |
| 294 | + action = (result.kwargs or {}).get("action") |
| 295 | + if action in _CONTROL_TRANSITION_INITIAL: |
| 296 | + return _CONTROL_TRANSITION_INITIAL[action] |
| 297 | + |
287 | 298 | current_status = _parse_branch_status(branch.status) |
288 | 299 | status = deployment_status(branch.id) |
289 | 300 |
|
@@ -1908,109 +1919,58 @@ async def resize( |
1908 | 1919 | 404: NotFound, |
1909 | 1920 | } |
1910 | 1921 |
|
1911 | | -_CONTROL_TO_AUTOSCALER_POWERSTATE: dict[str, NeonVMPowerState] = { |
1912 | | - "pause": "Stopped", |
1913 | | - "resume": "Running", |
1914 | | - "start": "Running", |
1915 | | - "stop": "Stopped", |
1916 | | -} |
1917 | | - |
1918 | | -_CONTROL_TRANSITION_INITIAL: dict[str, BranchServiceStatus] = { |
1919 | | - "pause": BranchServiceStatus.PAUSING, |
1920 | | - "resume": BranchServiceStatus.RESUMING, |
1921 | | - "start": BranchServiceStatus.STARTING, |
1922 | | - "stop": BranchServiceStatus.STOPPING, |
1923 | | -} |
1924 | | - |
1925 | | -_CONTROL_TRANSITION_FINAL: dict[str, BranchServiceStatus | None] = { |
1926 | | - "pause": BranchServiceStatus.PAUSED, |
1927 | | - "resume": BranchServiceStatus.STARTING, |
1928 | | - "start": None, |
1929 | | - "stop": BranchServiceStatus.STOPPED, |
1930 | | -} |
1931 | | - |
1932 | 1922 |
|
1933 | 1923 | async def _set_branch_status(session: SessionDep, branch: Branch, status: BranchServiceStatus): |
1934 | 1924 | branch.set_status(status) |
1935 | 1925 | await session.commit() |
1936 | 1926 |
|
1937 | 1927 |
|
1938 | | -async def _set_final_branch_status(session: SessionDep, branch: Branch, action: str) -> None: |
1939 | | - final_status = _CONTROL_TRANSITION_FINAL[action] |
1940 | | - if final_status is None: |
1941 | | - return |
1942 | | - await _set_branch_status(session, branch, final_status) |
1943 | | - |
1944 | | - |
1945 | | -async def _set_autoscaler_power_state(action: str, namespace: str, name: str) -> None: |
1946 | | - power_state = _CONTROL_TO_AUTOSCALER_POWERSTATE.get(action) |
1947 | | - if power_state is None: |
1948 | | - return |
1949 | | - await set_virtualmachine_power_state(namespace, name, power_state) |
1950 | | - |
1951 | | - |
1952 | | -async def _apply_branch_action( |
1953 | | - *, |
1954 | | - action: str, |
1955 | | - autoscaler_namespace: str, |
1956 | | - autoscaler_vm_name: str, |
1957 | | -) -> None: |
1958 | | - await _set_autoscaler_power_state(action, autoscaler_namespace, autoscaler_vm_name) |
1959 | | - |
1960 | | - |
1961 | 1928 | @instance_api.post( |
1962 | 1929 | "/pause", |
1963 | 1930 | name="organizations:projects:branch:pause", |
1964 | | - status_code=204, |
| 1931 | + status_code=202, |
1965 | 1932 | responses=_control_responses, |
1966 | 1933 | ) |
1967 | 1934 | @instance_api.post( |
1968 | 1935 | "/resume", |
1969 | 1936 | name="organizations:projects:branch:resume", |
1970 | | - status_code=204, |
| 1937 | + status_code=202, |
1971 | 1938 | responses=_control_responses, |
1972 | 1939 | ) |
1973 | 1940 | @instance_api.post( |
1974 | 1941 | "/start", |
1975 | 1942 | name="organizations:projects:branch:start", |
1976 | | - status_code=204, |
| 1943 | + status_code=202, |
1977 | 1944 | responses=_control_responses, |
1978 | 1945 | ) |
1979 | 1946 | @instance_api.post( |
1980 | 1947 | "/stop", |
1981 | 1948 | name="organizations:projects:branch:stop", |
1982 | | - status_code=204, |
| 1949 | + status_code=202, |
1983 | 1950 | responses=_control_responses, |
1984 | 1951 | ) |
1985 | 1952 | async def control_branch( |
1986 | 1953 | session: SessionDep, |
1987 | 1954 | request: Request, |
1988 | | - _organization: OrganizationDep, |
1989 | | - _project: ProjectDep, |
| 1955 | + organization: OrganizationDep, |
| 1956 | + project: ProjectDep, |
1990 | 1957 | branch: BranchDep, |
1991 | 1958 | ): |
1992 | 1959 | action = request.scope["route"].name.split(":")[-1] |
1993 | | - assert action in _CONTROL_TO_AUTOSCALER_POWERSTATE |
1994 | | - branch_in_session = await session.merge(branch) |
1995 | | - branch_id = branch_in_session.id |
1996 | | - autoscaler_namespace, autoscaler_vm_name = get_autoscaler_vm_identity(branch_id) |
1997 | | - await _set_branch_status(session, branch_in_session, _CONTROL_TRANSITION_INITIAL[action]) |
1998 | | - try: |
1999 | | - await _apply_branch_action( |
2000 | | - action=action, |
2001 | | - autoscaler_namespace=autoscaler_namespace, |
2002 | | - autoscaler_vm_name=autoscaler_vm_name, |
2003 | | - ) |
2004 | | - except ApiException as e: |
2005 | | - await _set_branch_status(session, branch_in_session, BranchServiceStatus.ERROR) |
2006 | | - status = 404 if e.status == 404 else 400 |
2007 | | - raise HTTPException(status_code=status, detail=e.body or str(e)) from e |
2008 | | - except VelaKubernetesError as e: |
2009 | | - await _set_branch_status(session, branch_in_session, BranchServiceStatus.ERROR) |
2010 | | - raise HTTPException(status_code=500, detail=str(e)) from e |
2011 | | - else: |
2012 | | - await _set_final_branch_status(session, branch_in_session, action) |
2013 | | - return Response(status_code=204) |
| 1960 | + assert action in _CONTROL_TO_POWER_STATE |
| 1961 | + task_id = dispatch_control(str(branch.id), action) |
| 1962 | + branch.control_task_id = task_id |
| 1963 | + await session.commit() |
| 1964 | + |
| 1965 | + task_url = url_path_for( |
| 1966 | + request, |
| 1967 | + "organizations:projects:branch:tasks:detail", |
| 1968 | + organization_id=await organization.awaitable_attrs.id, |
| 1969 | + project_id=await project.awaitable_attrs.id, |
| 1970 | + branch_id=await branch.awaitable_attrs.id, |
| 1971 | + task_id=task_id, |
| 1972 | + ) |
| 1973 | + return Response(status_code=202, headers={"Location": task_url}) |
2014 | 1974 |
|
2015 | 1975 |
|
2016 | 1976 | instance_api.include_router(auth_api, prefix="/auth") |
|
0 commit comments