apache-airflow-providers-edge3 2.0.0rc1__py3-none-any.whl → 3.0.1rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airflow/providers/edge3/__init__.py +1 -1
- airflow/providers/edge3/cli/api_client.py +30 -28
- airflow/providers/edge3/cli/dataclasses.py +3 -10
- airflow/providers/edge3/cli/definition.py +261 -0
- airflow/providers/edge3/cli/edge_command.py +8 -206
- airflow/providers/edge3/cli/worker.py +226 -198
- airflow/providers/edge3/example_dags/win_notepad.py +1 -1
- airflow/providers/edge3/executors/edge_executor.py +24 -49
- airflow/providers/edge3/get_provider_info.py +1 -0
- airflow/providers/edge3/models/edge_job.py +1 -2
- airflow/providers/edge3/models/edge_worker.py +61 -16
- airflow/providers/edge3/plugins/edge_executor_plugin.py +1 -1
- airflow/providers/edge3/plugins/www/dist/main.umd.cjs +8 -8
- airflow/providers/edge3/plugins/www/package.json +32 -27
- airflow/providers/edge3/plugins/www/pnpm-lock.yaml +1625 -1716
- airflow/providers/edge3/plugins/www/src/global.d.ts +24 -0
- airflow/providers/edge3/plugins/www/src/layouts/NavTabs.tsx +25 -3
- airflow/providers/edge3/plugins/www/src/main.tsx +6 -1
- airflow/providers/edge3/plugins/www/src/theme.ts +1 -1
- airflow/providers/edge3/worker_api/datamodels.py +12 -1
- airflow/providers/edge3/worker_api/routes/jobs.py +21 -8
- airflow/providers/edge3/worker_api/routes/logs.py +1 -1
- airflow/providers/edge3/worker_api/routes/worker.py +16 -3
- {apache_airflow_providers_edge3-2.0.0rc1.dist-info → apache_airflow_providers_edge3-3.0.1rc1.dist-info}/METADATA +14 -10
- {apache_airflow_providers_edge3-2.0.0rc1.dist-info → apache_airflow_providers_edge3-3.0.1rc1.dist-info}/RECORD +29 -29
- {apache_airflow_providers_edge3-2.0.0rc1.dist-info → apache_airflow_providers_edge3-3.0.1rc1.dist-info}/licenses/NOTICE +1 -1
- airflow/providers/edge3/plugins/templates/edge_worker_hosts.html +0 -175
- airflow/providers/edge3/plugins/templates/edge_worker_jobs.html +0 -69
- {apache_airflow_providers_edge3-2.0.0rc1.dist-info → apache_airflow_providers_edge3-3.0.1rc1.dist-info}/WHEEL +0 -0
- {apache_airflow_providers_edge3-2.0.0rc1.dist-info → apache_airflow_providers_edge3-3.0.1rc1.dist-info}/entry_points.txt +0 -0
- {apache_airflow_providers_edge3-2.0.0rc1.dist-info → apache_airflow_providers_edge3-3.0.1rc1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export type global = object;
|
|
21
|
+
|
|
22
|
+
declare global {
|
|
23
|
+
var ChakraUISystem: SystemContext | undefined;
|
|
24
|
+
}
|
|
@@ -17,10 +17,13 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
import { Center, Flex } from "@chakra-ui/react";
|
|
20
|
+
import axios from "axios";
|
|
21
|
+
import { useQuery } from "@tanstack/react-query";
|
|
20
22
|
import { useRef, type ReactNode } from "react";
|
|
21
23
|
import { NavLink } from "react-router-dom";
|
|
22
24
|
|
|
23
25
|
import { useContainerWidth } from "src/utils";
|
|
26
|
+
import { lte } from "semver";
|
|
24
27
|
|
|
25
28
|
type Props = {
|
|
26
29
|
readonly tabs: Array<{ icon?: ReactNode; label: string; value: string }>;
|
|
@@ -30,10 +33,29 @@ export const NavTabs = ({ tabs }: Props) => {
|
|
|
30
33
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
31
34
|
const containerWidth = useContainerWidth(containerRef);
|
|
32
35
|
|
|
36
|
+
const { data } = useQuery<{version: string, git_version: string | null}>({
|
|
37
|
+
queryFn: async () => {
|
|
38
|
+
const res = await axios.get("/api/v2/version");
|
|
39
|
+
return res.data;
|
|
40
|
+
},
|
|
41
|
+
queryKey: ["appVersion"],
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
let legacyRouterNavigation: boolean | undefined = undefined;
|
|
45
|
+
|
|
46
|
+
if (data) {
|
|
47
|
+
const airflowCoreVersion = data.version;
|
|
48
|
+
if (lte(airflowCoreVersion, "3.1.6")) {
|
|
49
|
+
legacyRouterNavigation = true;
|
|
50
|
+
} else {
|
|
51
|
+
legacyRouterNavigation = false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
33
55
|
return (
|
|
34
56
|
<Flex alignItems="center" borderBottomWidth={1} mb={2} ref={containerRef}>
|
|
35
|
-
{tabs.map(({ icon, label, value }) => (
|
|
36
|
-
<NavLink end key={value} title={label} to={value}>
|
|
57
|
+
{legacyRouterNavigation !== undefined ? tabs.map(({ icon, label, value }) => (
|
|
58
|
+
<NavLink end key={value} title={label} to={legacyRouterNavigation ? value : `../${value}`} relative={legacyRouterNavigation ? "route" : "path"}>
|
|
37
59
|
{({ isActive }) => (
|
|
38
60
|
<Center
|
|
39
61
|
borderBottomColor="border.info"
|
|
@@ -50,7 +72,7 @@ export const NavTabs = ({ tabs }: Props) => {
|
|
|
50
72
|
</Center>
|
|
51
73
|
)}
|
|
52
74
|
</NavLink>
|
|
53
|
-
))}
|
|
75
|
+
)): undefined}
|
|
54
76
|
</Flex>
|
|
55
77
|
);
|
|
56
78
|
};
|
|
@@ -24,7 +24,7 @@ import { FC } from "react";
|
|
|
24
24
|
import { ColorModeProvider } from "src/context/colorMode";
|
|
25
25
|
import { EdgeLayout } from "src/layouts/EdgeLayout";
|
|
26
26
|
|
|
27
|
-
import {
|
|
27
|
+
import { localSystem } from "./theme";
|
|
28
28
|
|
|
29
29
|
export type PluginComponentProps = object;
|
|
30
30
|
|
|
@@ -37,6 +37,11 @@ const PluginComponent: FC<PluginComponentProps> = () => {
|
|
|
37
37
|
const baseUrl = new URL(baseHref, globalThis.location.origin);
|
|
38
38
|
OpenAPI.BASE = baseUrl.pathname.replace(/\/$/, ""); // Remove trailing slash
|
|
39
39
|
|
|
40
|
+
// Use the globalChakraUISystem provided by the Airflow Core UI,
|
|
41
|
+
// so the plugin has a consistent theming with the host Airflow UI,
|
|
42
|
+
// fallback to localSystem for local development.
|
|
43
|
+
const system = globalThis.ChakraUISystem ?? localSystem;
|
|
44
|
+
|
|
40
45
|
const queryClient = new QueryClient({
|
|
41
46
|
defaultOptions: {
|
|
42
47
|
queries: {
|
|
@@ -394,7 +394,7 @@ export const customConfig = defineConfig({
|
|
|
394
394
|
},
|
|
395
395
|
});
|
|
396
396
|
|
|
397
|
-
export const
|
|
397
|
+
export const localSystem = createSystem(defaultConfig, customConfig);
|
|
398
398
|
|
|
399
399
|
// Utility function to resolve CSS variables to their computed values
|
|
400
400
|
// See: https://github.com/chakra-ui/panda/discussions/2200
|
|
@@ -26,7 +26,7 @@ from fastapi import Path
|
|
|
26
26
|
from pydantic import BaseModel, Field
|
|
27
27
|
|
|
28
28
|
from airflow.executors.workloads import ExecuteTask # noqa: TCH001
|
|
29
|
-
from airflow.
|
|
29
|
+
from airflow.providers.common.compat.sdk import TaskInstanceKey
|
|
30
30
|
from airflow.providers.edge3.models.edge_worker import EdgeWorkerState # noqa: TCH001
|
|
31
31
|
|
|
32
32
|
|
|
@@ -99,6 +99,17 @@ class EdgeJobFetched(EdgeJobBase):
|
|
|
99
99
|
]
|
|
100
100
|
concurrency_slots: Annotated[int, Field(description="Number of concurrency slots the job requires.")]
|
|
101
101
|
|
|
102
|
+
@property
|
|
103
|
+
def identifier(self) -> str:
|
|
104
|
+
"""Get a human readable identifier for the edge job."""
|
|
105
|
+
return (
|
|
106
|
+
f"dag_id={self.dag_id} "
|
|
107
|
+
f"task_id={self.task_id} "
|
|
108
|
+
f"run_id={self.run_id} "
|
|
109
|
+
f"map_index={self.map_index} "
|
|
110
|
+
f"try_number={self.try_number}"
|
|
111
|
+
)
|
|
112
|
+
|
|
102
113
|
|
|
103
114
|
class WorkerQueuesBase(BaseModel):
|
|
104
115
|
"""Queues that a worker supports to run jobs on."""
|
|
@@ -80,14 +80,19 @@ def fetch(
|
|
|
80
80
|
job: EdgeJobModel | None = session.scalar(query)
|
|
81
81
|
if not job:
|
|
82
82
|
return None
|
|
83
|
-
job.state = TaskInstanceState.
|
|
83
|
+
job.state = TaskInstanceState.RESTARTING # keep this intermediate state until worker sets to running
|
|
84
84
|
job.edge_worker = worker_name
|
|
85
85
|
job.last_update = timezone.utcnow()
|
|
86
86
|
session.commit()
|
|
87
87
|
# Edge worker does not backport emitted Airflow metrics, so export some metrics
|
|
88
88
|
tags = {"dag_id": job.dag_id, "task_id": job.task_id, "queue": job.queue}
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
try:
|
|
90
|
+
from airflow.sdk._shared.observability.metrics.dual_stats_manager import DualStatsManager
|
|
91
|
+
|
|
92
|
+
DualStatsManager.incr("edge_worker.ti.start", tags=tags)
|
|
93
|
+
except ImportError:
|
|
94
|
+
Stats.incr(f"edge_worker.ti.start.{job.queue}.{job.dag_id}.{job.task_id}", tags=tags)
|
|
95
|
+
Stats.incr("edge_worker.ti.start", tags=tags)
|
|
91
96
|
return EdgeJobFetched(
|
|
92
97
|
dag_id=job.dag_id,
|
|
93
98
|
task_id=job.task_id,
|
|
@@ -140,11 +145,19 @@ def state(
|
|
|
140
145
|
"queue": job.queue,
|
|
141
146
|
"state": str(state),
|
|
142
147
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
try:
|
|
149
|
+
from airflow.sdk._shared.observability.metrics.dual_stats_manager import DualStatsManager
|
|
150
|
+
|
|
151
|
+
DualStatsManager.incr(
|
|
152
|
+
"edge_worker.ti.finish",
|
|
153
|
+
tags=tags,
|
|
154
|
+
)
|
|
155
|
+
except ImportError:
|
|
156
|
+
Stats.incr(
|
|
157
|
+
f"edge_worker.ti.finish.{job.queue}.{state}.{job.dag_id}.{job.task_id}",
|
|
158
|
+
tags=tags,
|
|
159
|
+
)
|
|
160
|
+
Stats.incr("edge_worker.ti.finish", tags=tags)
|
|
148
161
|
|
|
149
162
|
query2 = (
|
|
150
163
|
update(EdgeJobModel)
|
|
@@ -28,7 +28,7 @@ from airflow.api_fastapi.common.router import AirflowRouter
|
|
|
28
28
|
from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc
|
|
29
29
|
from airflow.configuration import conf
|
|
30
30
|
from airflow.models.taskinstance import TaskInstance
|
|
31
|
-
from airflow.
|
|
31
|
+
from airflow.providers.common.compat.sdk import TaskInstanceKey
|
|
32
32
|
from airflow.providers.edge3.models.edge_logs import EdgeLogsModel
|
|
33
33
|
from airflow.providers.edge3.worker_api.auth import jwt_token_authorization_rest
|
|
34
34
|
from airflow.providers.edge3.worker_api.datamodels import PushLogsBody, WorkerApiDocs
|
|
@@ -26,7 +26,7 @@ from sqlalchemy import select
|
|
|
26
26
|
from airflow.api_fastapi.common.db.common import SessionDep # noqa: TC001
|
|
27
27
|
from airflow.api_fastapi.common.router import AirflowRouter
|
|
28
28
|
from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc
|
|
29
|
-
from airflow.providers.common.compat.sdk import
|
|
29
|
+
from airflow.providers.common.compat.sdk import timezone
|
|
30
30
|
from airflow.providers.edge3.models.edge_worker import EdgeWorkerModel, EdgeWorkerState, set_metrics
|
|
31
31
|
from airflow.providers.edge3.worker_api.auth import jwt_token_authorization_rest
|
|
32
32
|
from airflow.providers.edge3.worker_api.datamodels import (
|
|
@@ -212,8 +212,21 @@ def set_state(
|
|
|
212
212
|
worker.sysinfo = json.dumps(body.sysinfo)
|
|
213
213
|
worker.last_update = timezone.utcnow()
|
|
214
214
|
session.commit()
|
|
215
|
-
|
|
216
|
-
|
|
215
|
+
try:
|
|
216
|
+
from airflow.sdk._shared.observability.metrics.dual_stats_manager import DualStatsManager
|
|
217
|
+
|
|
218
|
+
DualStatsManager.incr(
|
|
219
|
+
"edge_worker.heartbeat_count",
|
|
220
|
+
1,
|
|
221
|
+
1,
|
|
222
|
+
tags={},
|
|
223
|
+
extra_tags={"worker_name": worker_name},
|
|
224
|
+
)
|
|
225
|
+
except ImportError:
|
|
226
|
+
from airflow.providers.common.compat.sdk import Stats
|
|
227
|
+
|
|
228
|
+
Stats.incr(f"edge_worker.heartbeat_count.{worker_name}", 1, 1)
|
|
229
|
+
Stats.incr("edge_worker.heartbeat_count", 1, 1, tags={"worker_name": worker_name})
|
|
217
230
|
set_metrics(
|
|
218
231
|
worker_name=worker_name,
|
|
219
232
|
state=body.state,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apache-airflow-providers-edge3
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.1rc1
|
|
4
4
|
Summary: Provider package apache-airflow-providers-edge3 for Apache Airflow
|
|
5
5
|
Keywords: airflow-provider,edge3,airflow,integration
|
|
6
6
|
Author-email: Apache Software Foundation <dev@airflow.apache.org>
|
|
@@ -23,12 +23,14 @@ Classifier: Topic :: System :: Monitoring
|
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
License-File: NOTICE
|
|
25
25
|
Requires-Dist: apache-airflow>=3.0.0,!=3.1.0
|
|
26
|
-
Requires-Dist: apache-airflow-providers-common-compat>=1.
|
|
26
|
+
Requires-Dist: apache-airflow-providers-common-compat>=1.13.0rc1
|
|
27
27
|
Requires-Dist: pydantic>=2.11.0
|
|
28
|
-
Requires-Dist: retryhttp>=1.
|
|
28
|
+
Requires-Dist: retryhttp>=1.4.0
|
|
29
|
+
Requires-Dist: aiofiles>=23.2.0
|
|
30
|
+
Requires-Dist: aiohttp>=3.9.2
|
|
29
31
|
Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
|
|
30
|
-
Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/
|
|
31
|
-
Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/
|
|
32
|
+
Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/3.0.1/changelog.html
|
|
33
|
+
Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/3.0.1
|
|
32
34
|
Project-URL: Mastodon, https://fosstodon.org/@airflow
|
|
33
35
|
Project-URL: Slack Chat, https://s.apache.org/airflow-slack
|
|
34
36
|
Project-URL: Source Code, https://github.com/apache/airflow
|
|
@@ -59,7 +61,7 @@ Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
|
|
|
59
61
|
|
|
60
62
|
Package ``apache-airflow-providers-edge3``
|
|
61
63
|
|
|
62
|
-
Release: ``
|
|
64
|
+
Release: ``3.0.1``
|
|
63
65
|
|
|
64
66
|
|
|
65
67
|
Handle edge workers on remote sites via HTTP(s) connection and orchestrates work over distributed sites.
|
|
@@ -84,7 +86,7 @@ This is a provider package for ``edge3`` provider. All classes for this provider
|
|
|
84
86
|
are in ``airflow.providers.edge3`` python package.
|
|
85
87
|
|
|
86
88
|
You can find package information and changelog for the provider
|
|
87
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-edge3/
|
|
89
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-edge3/3.0.1/>`_.
|
|
88
90
|
|
|
89
91
|
Installation
|
|
90
92
|
------------
|
|
@@ -102,9 +104,11 @@ Requirements
|
|
|
102
104
|
PIP package Version required
|
|
103
105
|
========================================== ===================
|
|
104
106
|
``apache-airflow`` ``>=3.0.0,!=3.1.0``
|
|
105
|
-
``apache-airflow-providers-common-compat`` ``>=1.
|
|
107
|
+
``apache-airflow-providers-common-compat`` ``>=1.13.0``
|
|
106
108
|
``pydantic`` ``>=2.11.0``
|
|
107
|
-
``retryhttp`` ``>=1.
|
|
109
|
+
``retryhttp`` ``>=1.4.0``
|
|
110
|
+
``aiofiles`` ``>=23.2.0``
|
|
111
|
+
``aiohttp`` ``>=3.9.2``
|
|
108
112
|
========================================== ===================
|
|
109
113
|
|
|
110
114
|
Cross provider package dependencies
|
|
@@ -127,5 +131,5 @@ Dependent package
|
|
|
127
131
|
================================================================================================================== =================
|
|
128
132
|
|
|
129
133
|
The changelog for the provider package can be found in the
|
|
130
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-edge3/
|
|
134
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-edge3/3.0.1/changelog.html>`_.
|
|
131
135
|
|
|
@@ -1,34 +1,33 @@
|
|
|
1
|
-
airflow/providers/edge3/__init__.py,sha256=
|
|
2
|
-
airflow/providers/edge3/get_provider_info.py,sha256=
|
|
1
|
+
airflow/providers/edge3/__init__.py,sha256=Ua9vrlUHXeOcB6JPL3jXuCvWUeVCwBhnsGn4NdQkzVY,1492
|
|
2
|
+
airflow/providers/edge3/get_provider_info.py,sha256=GyA1KMmElIuPiRDI3dQLgaiSCctEMXP1XdT068g2k3I,7449
|
|
3
3
|
airflow/providers/edge3/version_compat.py,sha256=mek4-fV-grwkP7F_kmRHKgZDfloTXi2ngS396UjjJUo,1577
|
|
4
4
|
airflow/providers/edge3/cli/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
5
|
-
airflow/providers/edge3/cli/api_client.py,sha256=
|
|
6
|
-
airflow/providers/edge3/cli/dataclasses.py,sha256=
|
|
7
|
-
airflow/providers/edge3/cli/
|
|
5
|
+
airflow/providers/edge3/cli/api_client.py,sha256=24U_AUUWQs85lBD01u7F92mYo0Av_to8alxTfmJtIg0,7690
|
|
6
|
+
airflow/providers/edge3/cli/dataclasses.py,sha256=qTN47g9C22TwWVepgkFiQNR9Y_n1wMsTadjbtbhouVE,2594
|
|
7
|
+
airflow/providers/edge3/cli/definition.py,sha256=bXMrfhEf7xYlXxc4lTuVhQFYLRosd98PaN6eJNpRK9o,8707
|
|
8
|
+
airflow/providers/edge3/cli/edge_command.py,sha256=U9JpPV1a3jgM_im1jQ0fAI1KnU9Y9b72bLpeDIojH7w,16158
|
|
8
9
|
airflow/providers/edge3/cli/signalling.py,sha256=sf4S6j6OoP0bLkda3UlCmlZabjv5wsMypy3kAvx56Z0,3220
|
|
9
|
-
airflow/providers/edge3/cli/worker.py,sha256=
|
|
10
|
+
airflow/providers/edge3/cli/worker.py,sha256=_c8VWTfNFRPv7zkyjQ42QodLLYJeyGJkIUU2A-fsHiU,18182
|
|
10
11
|
airflow/providers/edge3/example_dags/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
11
12
|
airflow/providers/edge3/example_dags/integration_test.py,sha256=CTxHCy1Saaz_fdAilPkQ3nmeq1ScWdL9iUFdCkx-j4k,6281
|
|
12
|
-
airflow/providers/edge3/example_dags/win_notepad.py,sha256=
|
|
13
|
+
airflow/providers/edge3/example_dags/win_notepad.py,sha256=DK-S8J3DOwmmEW44nFAYx5gFqLp8qGeew50jVm_labI,2822
|
|
13
14
|
airflow/providers/edge3/example_dags/win_test.py,sha256=6kHelD1Uu8KfPJLdjHXrnC3SvnWEAKin-HdfVP3bh8o,13850
|
|
14
15
|
airflow/providers/edge3/executors/__init__.py,sha256=y830gGSKCvjOcLwLuCDp84NCrHWWB9RSSH1qvJpFhyY,923
|
|
15
|
-
airflow/providers/edge3/executors/edge_executor.py,sha256=
|
|
16
|
+
airflow/providers/edge3/executors/edge_executor.py,sha256=DM2FSDJs1BjK32ZIDLgUki2u9bKoIP0oWlhcNM08puE,16562
|
|
16
17
|
airflow/providers/edge3/models/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
17
|
-
airflow/providers/edge3/models/edge_job.py,sha256=
|
|
18
|
+
airflow/providers/edge3/models/edge_job.py,sha256=TP0qNSVbTEjZQVbCij-hX1Enwq0dqqIX0uaNea02WZo,3579
|
|
18
19
|
airflow/providers/edge3/models/edge_logs.py,sha256=rFVz4gR0GYiEpwai5Q2C5znkiuaUQTjq5EhfLnQUeZQ,3022
|
|
19
|
-
airflow/providers/edge3/models/edge_worker.py,sha256=
|
|
20
|
+
airflow/providers/edge3/models/edge_worker.py,sha256=nnJcvvokYMniZxOQNx4Pl0cEy97NNwDFp6uRiz69woI,15193
|
|
20
21
|
airflow/providers/edge3/plugins/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
21
|
-
airflow/providers/edge3/plugins/edge_executor_plugin.py,sha256=
|
|
22
|
-
airflow/providers/edge3/plugins/templates/edge_worker_hosts.html,sha256=0_P2yfZwpy3Kvqd3GBvu_PgmmKCUbso3ieW8aYa76iU,8997
|
|
23
|
-
airflow/providers/edge3/plugins/templates/edge_worker_jobs.html,sha256=bZ-6ysmIy6j4eR_TPHiqbgb3qpNMKCcEEB-SpxuxNgc,2831
|
|
22
|
+
airflow/providers/edge3/plugins/edge_executor_plugin.py,sha256=PkHWUOQOIfEoGS6DTa9KVNdIADDtIy4VuLK9SGP7YRI,4899
|
|
24
23
|
airflow/providers/edge3/plugins/www/.gitignore,sha256=glCQO0xBUzFDPKNjn3_mw7F6e51j3sjyo4knJAUqMz4,281
|
|
25
24
|
airflow/providers/edge3/plugins/www/.prettierignore,sha256=3FQ52dyPew57fO1lXEQTVRKfJClYQaM5tVkKWKSv4hg,56
|
|
26
25
|
airflow/providers/edge3/plugins/www/.prettierrc,sha256=l0bDuMVuy86p4BwgAssF2AqJL6x_pZMSt8vm401QHyo,365
|
|
27
26
|
airflow/providers/edge3/plugins/www/README.md,sha256=VLm9Gf_vSdATdAaSeHDkKHmw3Oo_r4ZIHyu_8o0hju4,5110
|
|
28
27
|
airflow/providers/edge3/plugins/www/eslint.config.js,sha256=8KEosRBtZkvb2mZYWagAukze0WUu8hrPWz4eSj1ONKE,1851
|
|
29
28
|
airflow/providers/edge3/plugins/www/index.html,sha256=PsqOtfHrJYYwQjxqcAkVOmsl2cRJe8biKygXJjAj2ng,413
|
|
30
|
-
airflow/providers/edge3/plugins/www/package.json,sha256=
|
|
31
|
-
airflow/providers/edge3/plugins/www/pnpm-lock.yaml,sha256=
|
|
29
|
+
airflow/providers/edge3/plugins/www/package.json,sha256=_GQtJRwY7b4q6YSas493EabPoTilbntPLM09Z8BU3-w,2710
|
|
30
|
+
airflow/providers/edge3/plugins/www/pnpm-lock.yaml,sha256=nOo507toNxCSTfoPBKwW8mSUt9_OJEZ6MhNF1QTQcEM,219401
|
|
32
31
|
airflow/providers/edge3/plugins/www/testsSetup.ts,sha256=x1L_lXmigZgufra1L32Xcci_lLifbaG_tP6vx6gPscc,852
|
|
33
32
|
airflow/providers/edge3/plugins/www/tsconfig.app.json,sha256=zpihgvrBvwjOwtHddJtYUi7Gp26diFtNYmJ7XlM3GUU,753
|
|
34
33
|
airflow/providers/edge3/plugins/www/tsconfig.json,sha256=jZfUc2grkJB0eRDSFPEPfmBblsr__nGAww3ojidM0ho,158
|
|
@@ -36,7 +35,7 @@ airflow/providers/edge3/plugins/www/tsconfig.lib.json,sha256=Z5M3uhtIZ0Uc9CFjc7F
|
|
|
36
35
|
airflow/providers/edge3/plugins/www/tsconfig.node.json,sha256=On9I0qUPqRSyxJNKP5OlnWX_rYR1CKZV8A3IgF1UxvE,680
|
|
37
36
|
airflow/providers/edge3/plugins/www/vite.config.ts,sha256=mxAyXyZhIaFA46v7DY4yAo__y6gs9YXuIIPEhN-6xis,2971
|
|
38
37
|
airflow/providers/edge3/plugins/www/dist/main.d.ts,sha256=eZKjnWzeXgUOt4RhqL-a2YYXWpSCboNcEQs5ZykL0kk,10
|
|
39
|
-
airflow/providers/edge3/plugins/www/dist/main.umd.cjs,sha256
|
|
38
|
+
airflow/providers/edge3/plugins/www/dist/main.umd.cjs,sha256=QCeiNGd32TXE7P6nosRs2iMxfPIavpYagphrKVdZCh4,637057
|
|
40
39
|
airflow/providers/edge3/plugins/www/openapi-gen/queries/common.ts,sha256=8_JCD7ZPhld5Mkf8qVlMZC4Ai-T-KRsxbZe4vhA_Gj4,3780
|
|
41
40
|
airflow/providers/edge3/plugins/www/openapi-gen/queries/ensureQueryData.ts,sha256=NVtfnBCRXCFppIh_7oPtwExL4n0xd3fCcFwVcsc9EMs,1612
|
|
42
41
|
airflow/providers/edge3/plugins/www/openapi-gen/queries/index.ts,sha256=p941sYs7pyF4XLKPxPgBXIko0H6s2U4sowFygzJ6Jos,114
|
|
@@ -56,8 +55,9 @@ airflow/providers/edge3/plugins/www/openapi-gen/requests/core/OpenAPI.ts,sha256=
|
|
|
56
55
|
airflow/providers/edge3/plugins/www/openapi-gen/requests/core/request.ts,sha256=jG833drJAZFBKN9hnEL6RIRmAfys9eb5rC8p99wBWXk,9598
|
|
57
56
|
airflow/providers/edge3/plugins/www/src/constants.ts,sha256=431h7ZAwkQbZd4evYw7eGcEnj3z_PP2cPOtHTHb3GT0,1580
|
|
58
57
|
airflow/providers/edge3/plugins/www/src/dev.tsx,sha256=5sZlduF3IFFXKZMxV06hLsxhcCuWNzUMM4Ni1RITG8w,1114
|
|
59
|
-
airflow/providers/edge3/plugins/www/src/
|
|
60
|
-
airflow/providers/edge3/plugins/www/src/
|
|
58
|
+
airflow/providers/edge3/plugins/www/src/global.d.ts,sha256=chLVHQJy1jR2szTg4c12GU2NF20SlGmf14bThSdm61Q,908
|
|
59
|
+
airflow/providers/edge3/plugins/www/src/main.tsx,sha256=jIba75vA0gIL3UND_ZYnRPwP9mX0ayLDJV2pz1_fge8,2253
|
|
60
|
+
airflow/providers/edge3/plugins/www/src/theme.ts,sha256=tl79j5JV9bw1VmSnNKrw7_2X5KGvpJ-3y06rjw0PKNo,21463
|
|
61
61
|
airflow/providers/edge3/plugins/www/src/vite-env.d.ts,sha256=eY6SmeO3WS4Bxne5yY6kn_PXLilnlFfluNuZswLUDys,848
|
|
62
62
|
airflow/providers/edge3/plugins/www/src/components/AddQueueButton.tsx,sha256=Ahyf0_NXqEM0UjIdMyTuANKToD1coqfEjdsQiudK_Fg,4159
|
|
63
63
|
airflow/providers/edge3/plugins/www/src/components/ErrorAlert.tsx,sha256=4DFdnxEPWRBHCvMm5q5HKMH4D223jMNUX6zxKdZStNM,2182
|
|
@@ -89,7 +89,7 @@ airflow/providers/edge3/plugins/www/src/context/colorMode/ColorModeProvider.tsx,
|
|
|
89
89
|
airflow/providers/edge3/plugins/www/src/context/colorMode/index.ts,sha256=nTdA6xva8PrXEybO-JdQN4oSY9GHlHCPvUwREzJvhDM,879
|
|
90
90
|
airflow/providers/edge3/plugins/www/src/context/colorMode/useColorMode.tsx,sha256=YYcXELSveM_10fOwZeCh9yxiN8H7essKz1QDiy9Jio8,1122
|
|
91
91
|
airflow/providers/edge3/plugins/www/src/layouts/EdgeLayout.tsx,sha256=17S8T1rnKA9416bz1yTeybK4_U_ENx2PbnezyN9PcXg,1532
|
|
92
|
-
airflow/providers/edge3/plugins/www/src/layouts/NavTabs.tsx,sha256=
|
|
92
|
+
airflow/providers/edge3/plugins/www/src/layouts/NavTabs.tsx,sha256=1Uwki5aE9vIqJyZIukRzapbSYQNIMxq-nVDg0hBxkZw,2781
|
|
93
93
|
airflow/providers/edge3/plugins/www/src/pages/JobsPage.tsx,sha256=tBgeEsd5TRDkwcsH2x3oOCMKyC4ak6GzfRbAZK6vjLI,4801
|
|
94
94
|
airflow/providers/edge3/plugins/www/src/pages/WorkerPage.tsx,sha256=M8t8B5WfZHXRmTKYuVR1f3XIXG-QNIaw2EdCkZJUjpo,8403
|
|
95
95
|
airflow/providers/edge3/plugins/www/src/res/README.md,sha256=v9BEjvcB_pOcCP0bCL8wZ00xovBdzSk79FPFlqM9ZoQ,1010
|
|
@@ -101,18 +101,18 @@ airflow/providers/edge3/plugins/www/src/utils/useContainerWidth.ts,sha256=lLNc0N
|
|
|
101
101
|
airflow/providers/edge3/worker_api/__init__.py,sha256=nnPvxWGTEKZ9YyB1Yd7P9IvDOenK01LVHm22Owwxj3g,839
|
|
102
102
|
airflow/providers/edge3/worker_api/app.py,sha256=yM2S2JLYE2lS4kN88XYnbeKKRa8vqVVhRq10yA_X0ig,3003
|
|
103
103
|
airflow/providers/edge3/worker_api/auth.py,sha256=e6e9ZLIXP7qDwtsp_H2ZHEKpELsv7C8VZF6N_Qd68nI,4113
|
|
104
|
-
airflow/providers/edge3/worker_api/datamodels.py,sha256=
|
|
104
|
+
airflow/providers/edge3/worker_api/datamodels.py,sha256=O8fVAwY2di7Fs_QfJ47FbE-5l9csbIte78updB1yU-g,7018
|
|
105
105
|
airflow/providers/edge3/worker_api/datamodels_ui.py,sha256=yPEdtZ7noV5BBNXvA9F-pqVDq7UxTIKUdoUf3_FTDdE,2795
|
|
106
106
|
airflow/providers/edge3/worker_api/v2-edge-generated.yaml,sha256=bcyJE_k2Mlc8Xn9bWSCG2A1ofhlpnvuz9LHWaMdRd_E,41191
|
|
107
107
|
airflow/providers/edge3/worker_api/routes/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
108
108
|
airflow/providers/edge3/worker_api/routes/health.py,sha256=LTYvGxvs_OKcyEP6hFSw3J-bnBFP6soXmJlIKlkAyBI,1057
|
|
109
|
-
airflow/providers/edge3/worker_api/routes/jobs.py,sha256=
|
|
110
|
-
airflow/providers/edge3/worker_api/routes/logs.py,sha256=
|
|
109
|
+
airflow/providers/edge3/worker_api/routes/jobs.py,sha256=YugykZO5IMu0YERxxO8WkD9vH-1xiZ1v_6XjcczxPg0,6459
|
|
110
|
+
airflow/providers/edge3/worker_api/routes/logs.py,sha256=PG4Ikj4YwHACGchT3g2xt09aLxMnwiUzRA80Jparyn8,5044
|
|
111
111
|
airflow/providers/edge3/worker_api/routes/ui.py,sha256=dnlNZRUNw8WFMwL_oKKMAtu5vKlAeSQHTA_ko7n2raU,10491
|
|
112
|
-
airflow/providers/edge3/worker_api/routes/worker.py,sha256=
|
|
113
|
-
apache_airflow_providers_edge3-
|
|
114
|
-
apache_airflow_providers_edge3-
|
|
115
|
-
apache_airflow_providers_edge3-
|
|
116
|
-
apache_airflow_providers_edge3-
|
|
117
|
-
apache_airflow_providers_edge3-
|
|
118
|
-
apache_airflow_providers_edge3-
|
|
112
|
+
airflow/providers/edge3/worker_api/routes/worker.py,sha256=K30GQ4FncuPe3q4NJVgLeL0V618zhONjwJa9e8-bfA4,10261
|
|
113
|
+
apache_airflow_providers_edge3-3.0.1rc1.dist-info/entry_points.txt,sha256=7WUIGfd3o9NvvbK5trbZxNXTgYGc6pqg74wZPigbx5o,206
|
|
114
|
+
apache_airflow_providers_edge3-3.0.1rc1.dist-info/licenses/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
|
|
115
|
+
apache_airflow_providers_edge3-3.0.1rc1.dist-info/licenses/NOTICE,sha256=_cWHznIoUSbLCY_KfmKqetlKlsoH0c2VBjmZjElAzuc,168
|
|
116
|
+
apache_airflow_providers_edge3-3.0.1rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
117
|
+
apache_airflow_providers_edge3-3.0.1rc1.dist-info/METADATA,sha256=Mh0_gOHiQ7JXyNdy0T3XNzyCtzz7lizw6qus-NC6zAc,6300
|
|
118
|
+
apache_airflow_providers_edge3-3.0.1rc1.dist-info/RECORD,,
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
{#
|
|
2
|
-
Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
-
or more contributor license agreements. See the NOTICE file
|
|
4
|
-
distributed with this work for additional information
|
|
5
|
-
regarding copyright ownership. The ASF licenses this file
|
|
6
|
-
to you under the Apache License, Version 2.0 (the
|
|
7
|
-
"License"); you may not use this file except in compliance
|
|
8
|
-
with the License. You may obtain a copy of the License at
|
|
9
|
-
|
|
10
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
|
|
12
|
-
Unless required by applicable law or agreed to in writing,
|
|
13
|
-
software distributed under the License is distributed on an
|
|
14
|
-
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
-
KIND, either express or implied. See the License for the
|
|
16
|
-
specific language governing permissions and limitations
|
|
17
|
-
under the License.
|
|
18
|
-
#}
|
|
19
|
-
|
|
20
|
-
{% extends base_template %}
|
|
21
|
-
|
|
22
|
-
{% block title %}
|
|
23
|
-
Edge Worker Hosts
|
|
24
|
-
{% endblock %}
|
|
25
|
-
|
|
26
|
-
{% block content %}
|
|
27
|
-
<h2>Edge Worker Hosts</h2>
|
|
28
|
-
{% if hosts|length == 0 %}
|
|
29
|
-
<p>No Edge Workers connected or known currently.</p>
|
|
30
|
-
{% else %}
|
|
31
|
-
|
|
32
|
-
<script>
|
|
33
|
-
function showForm(worker_name) {
|
|
34
|
-
var button = document.getElementById("button_" + worker_name);
|
|
35
|
-
var form = document.getElementById("form_" + worker_name);
|
|
36
|
-
form.style.display = "block";
|
|
37
|
-
button.style.display = "none";
|
|
38
|
-
}
|
|
39
|
-
function showEditComment(worker_name) {
|
|
40
|
-
var display = document.getElementById("display_" + worker_name);
|
|
41
|
-
var textarea = document.getElementById("textarea_" + worker_name);
|
|
42
|
-
var button = document.getElementById("update_" + worker_name);
|
|
43
|
-
display.style.display = "none";
|
|
44
|
-
textarea.style.display = "block";
|
|
45
|
-
button.style.display = "inline";
|
|
46
|
-
}
|
|
47
|
-
</script>
|
|
48
|
-
<table class="table table-striped table-bordered">
|
|
49
|
-
<tr>
|
|
50
|
-
<th>Hostname</th>
|
|
51
|
-
<th>State</th>
|
|
52
|
-
<th>Queues</th>
|
|
53
|
-
<th>First Online</th>
|
|
54
|
-
<th>Last Heart Beat</th>
|
|
55
|
-
<th>Active Jobs</th>
|
|
56
|
-
<!-- Stats are not collected (yet) leave the columns out until available
|
|
57
|
-
<th>Jobs Taken</th>
|
|
58
|
-
<th>Jobs Success</th>
|
|
59
|
-
<th>Jobs Failed</th>
|
|
60
|
-
-->
|
|
61
|
-
<th>System Information</th>
|
|
62
|
-
<th>Operations</th>
|
|
63
|
-
</tr>
|
|
64
|
-
{% for host in hosts %}
|
|
65
|
-
<tr>
|
|
66
|
-
<td>{{ host.worker_name }}</a></td>
|
|
67
|
-
<td>
|
|
68
|
-
{%- if host.state in["offline", "offline maintenance"] -%}
|
|
69
|
-
<span class="label" style="color:white; background-color:black;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
70
|
-
{%- elif host.state == "unknown" -%}
|
|
71
|
-
<span class="label" style="color:white; background-color:red;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
72
|
-
{%- elif host.last_update.timestamp() <= five_min_ago.timestamp() -%}
|
|
73
|
-
Reported <span class="label" style="color:white; background-color:red;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
74
|
-
but no heartbeat
|
|
75
|
-
{%- elif host.state in ["starting", "maintenance request", "maintenance exit"] -%}
|
|
76
|
-
<span class="label" style="color:black; background-color:gold;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
77
|
-
{%- elif host.state == "running" -%}
|
|
78
|
-
<span class="label" style="color:white; background-color:green;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
79
|
-
{%- elif host.state == "idle" -%}
|
|
80
|
-
<span class="label" style="color:black; background-color:gray;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
81
|
-
{%- elif host.state == "terminating" -%}
|
|
82
|
-
<span class="label" style="color:black; background-color:violet;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
83
|
-
{%- elif host.state in ["maintenance pending", "maintenance mode"] -%}
|
|
84
|
-
<span class="label" style="color:black; background-color:orange;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
85
|
-
{%- else -%}
|
|
86
|
-
<span class="label" style="color:white; background-color:hotpink;" title="Current State: {{ host.state }}">{{ host.state }}</span>
|
|
87
|
-
{%- endif -%}
|
|
88
|
-
</td>
|
|
89
|
-
<td>
|
|
90
|
-
{% if host.queues %}
|
|
91
|
-
<ul>
|
|
92
|
-
{% for item in host.queues %}
|
|
93
|
-
<li>
|
|
94
|
-
<a href="../taskinstance/list/?_flt_7_state=success&_flt_7_state=failed&_flt_3_queue={{ item }}#"">{{ item }}</a>
|
|
95
|
-
</li>
|
|
96
|
-
{% endfor %}
|
|
97
|
-
</ul>
|
|
98
|
-
{% else %}
|
|
99
|
-
(all)
|
|
100
|
-
{% endif %}
|
|
101
|
-
</td>
|
|
102
|
-
<td><time datetime="{{ host.first_online }}">{{ host.first_online }}</time></td>
|
|
103
|
-
<td>{% if host.last_update %}<time datetime="{{ host.last_update }}">{{ host.last_update }}</time>{% endif %}</td>
|
|
104
|
-
<td>
|
|
105
|
-
<a href="../taskinstance/list/?_flt_3_hostname={{ host.worker_name }}&_flt_7_state=success&_flt_7_state=failed#">{{ host.jobs_active }}</a>
|
|
106
|
-
</td>
|
|
107
|
-
<!-- Stats are not collected (yet) leave the columns out until available
|
|
108
|
-
<td>{{ host.jobs_taken }}</td>
|
|
109
|
-
<td>{{ host.jobs_success }}</td>
|
|
110
|
-
<td>{{ host.jobs_failed }}</td>
|
|
111
|
-
-->
|
|
112
|
-
<td>
|
|
113
|
-
<ul>
|
|
114
|
-
{% for item in host.sysinfo_json %}
|
|
115
|
-
<li>{{ item }}: {{ host.sysinfo_json[item] }}</li>
|
|
116
|
-
{% endfor %}
|
|
117
|
-
</ul>
|
|
118
|
-
</td>
|
|
119
|
-
{%- if host.state in ["idle", "running"] -%}
|
|
120
|
-
<td>
|
|
121
|
-
<button id="button_{{ host.worker_name }}" onclick="showForm('{{ host.worker_name }}')" class="btn btn-sm btn-primary">
|
|
122
|
-
Enter Maintenance
|
|
123
|
-
</button>
|
|
124
|
-
<form id="form_{{ host.worker_name }}" style="display: none" action="../edgeworkerhosts/status/maintenance/{{ host.worker_name }}/on" method="POST">
|
|
125
|
-
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
|
126
|
-
<div style="white-space: pre-line;">
|
|
127
|
-
<label for="maintenance_comment">Maintenance Comment:</label>
|
|
128
|
-
</div>
|
|
129
|
-
<textarea name="maintenance_comment" rows="3" maxlength="1024" style="width: 100%; margin-bottom: 5px;" required></textarea>
|
|
130
|
-
<br />
|
|
131
|
-
<button type="submit" class="btn btn-sm btn-primary">
|
|
132
|
-
Confirm Maintenance
|
|
133
|
-
</button>
|
|
134
|
-
</td>
|
|
135
|
-
</form>
|
|
136
|
-
{%- elif host.state in ["maintenance pending", "maintenance mode", "maintenance request"] -%}
|
|
137
|
-
<form action="../edgeworkerhosts/status/maintenance/{{ host.worker_name }}/off" method="POST">
|
|
138
|
-
<td>
|
|
139
|
-
<div id="display_{{ host.worker_name }}" style="white-space: pre-line;">
|
|
140
|
-
{{ host.maintenance_comment }}
|
|
141
|
-
<a onclick="showEditComment('{{ host.worker_name }}')" class="btn btn-sm btn-default" data-toggle="tooltip" rel="tooltip" title="Edit maintenance comment">
|
|
142
|
-
<span class="sr-only">Edit</span>
|
|
143
|
-
<i class="fa fa-edit"></i>
|
|
144
|
-
</a>
|
|
145
|
-
</div>
|
|
146
|
-
<textarea id="textarea_{{ host.worker_name }}" name="maintenance_comment" rows="3" maxlength="1024" style="display: none; width:100%;" required>{{ host.maintenance_comment }}</textarea>
|
|
147
|
-
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
|
148
|
-
<div style="margin-top: 10px;">
|
|
149
|
-
<button type="submit" class="btn btn-sm btn-primary">
|
|
150
|
-
Exit Maintenance
|
|
151
|
-
</button>
|
|
152
|
-
<button id="update_{{ host.worker_name }}" type="submit" class="btn btn-sm btn-primary" style="display: none;" formaction="../edgeworkerhosts/status/maintenance/{{ host.worker_name }}/change_comment">
|
|
153
|
-
Update comment
|
|
154
|
-
</button>
|
|
155
|
-
</div>
|
|
156
|
-
</td>
|
|
157
|
-
</form>
|
|
158
|
-
{%- elif host.state in ["offline", "unknown", "offline maintenance"] -%}
|
|
159
|
-
<form action="../edgeworkerhosts/status/maintenance/{{ host.worker_name }}/remove" method="POST">
|
|
160
|
-
<td>
|
|
161
|
-
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
|
162
|
-
<button type="submit" class="btn btn-sm btn-primary">
|
|
163
|
-
Remove
|
|
164
|
-
</button>
|
|
165
|
-
</td>
|
|
166
|
-
</form>
|
|
167
|
-
{%- else -%}
|
|
168
|
-
<td></td>
|
|
169
|
-
{% endif %}
|
|
170
|
-
</tr>
|
|
171
|
-
{% endfor %}
|
|
172
|
-
</table>
|
|
173
|
-
{% endif %}
|
|
174
|
-
{% endblock %}
|
|
175
|
-
<html>
|