Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions airflow-core/src/airflow/cli/commands/jobs_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from sqlalchemy import select

from airflow.cli.utils import deprecated_for_airflowctl
from airflow.jobs.job import Job, JobState
from airflow.utils.net import get_hostname
from airflow.utils.providers_configuration_loader import providers_configuration_loaded
Expand All @@ -29,6 +30,7 @@
from sqlalchemy.orm import Session


@deprecated_for_airflowctl("airflowctl jobs check")
@providers_configuration_loaded
@provide_session
def check(args, *, session: Session = NEW_SESSION) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
config_command,
connection_command,
dag_command,
jobs_command,
pool_command,
provider_command,
task_command,
Expand Down Expand Up @@ -79,6 +80,7 @@
(config_command.show_config, "airflowctl config list"),
(task_command.task_states_for_dag_run, "airflowctl tasks states-for-dag-run"),
(task_command.task_clear, "airflowctl tasks clear"),
(jobs_command.check, "airflowctl jobs check"),
]


Expand Down
2 changes: 1 addition & 1 deletion airflow-ctl/docs/images/command_hashes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ config:a3d936cb15fe3b547bf6c82cf93d923f
connections:942f9f88cb908c28bf5c19159fc5065b
dags:5ad68174a1111563dff870a241914b30
dagrun:07035226eaaff0a557d3ad9aab4b41b5
jobs:a5b644c5da8889443bb40ee10b599270
jobs:d4af478f28dae48ee18d43b998edc345
pools:19efe105b9515ab1926ebcaf0e028d71
providers:34502fe09dc0b8b0a13e7e46efdffda6
taskinstances:7e323968c0b585287c2a4ab4339aee1f
Expand Down
66 changes: 35 additions & 31 deletions airflow-ctl/docs/images/output_jobs.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions airflow-ctl/src/airflowctl/ctl/cli_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,35 @@ def _load_help_texts_yaml() -> dict[str, dict[str, str]]:
choices=("overwrite", "fail", "skip"),
)

# Jobs command args
ARG_JOB_TYPE_FILTER = Arg(
flags=("--job-type",),
choices=("SchedulerJob", "TriggererJob", "DagProcessorJob"),
help="The type of job(s) that will be checked.",
)
ARG_JOB_HOSTNAME_FILTER = Arg(
flags=("--hostname",),
type=str,
default=None,
help="The hostname of job(s) that will be checked.",
)
ARG_JOB_LOCAL_FILTER = Arg(
flags=("--local",),
action="store_true",
help="If passed, this command will only show jobs from the local host.",
)
ARG_JOB_LIMIT = Arg(
flags=("--limit",),
type=positive_int(allow_zero=True),
default=1,
help="The number of recent jobs that will be checked. To disable limit, set 0.",
)
ARG_JOB_ALLOW_MULTIPLE = Arg(
flags=("--allow-multiple",),
action="store_true",
help="If passed, this command will be successful even if multiple matching alive jobs are found.",
)

# Config arguments
ARG_CONFIG_SECTION = Arg(
flags=("--section",),
Expand Down Expand Up @@ -1111,6 +1140,21 @@ def merge_commands(
),
)

JOB_COMMANDS = (
ActionCommand(
name="check",
help="Check if job(s) are still alive.",
func=lazy_load_command("airflowctl.ctl.commands.jobs_command.check"),
args=(
ARG_JOB_TYPE_FILTER,
ARG_JOB_HOSTNAME_FILTER,
ARG_JOB_LOCAL_FILTER,
ARG_JOB_LIMIT,
ARG_JOB_ALLOW_MULTIPLE,
),
),
)

core_commands: list[CLICommand] = [
GroupCommand(
name="auth",
Expand All @@ -1133,6 +1177,11 @@ def merge_commands(
help="Manage Airflow Dags",
subcommands=DAG_COMMANDS,
),
GroupCommand(
name="jobs",
help="Manage Airflow jobs",
subcommands=JOB_COMMANDS,
),
GroupCommand(
name="pools",
help="Manage Airflow pools",
Expand Down
50 changes: 50 additions & 0 deletions airflow-ctl/src/airflowctl/ctl/commands/jobs_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from __future__ import annotations

import socket

import rich

from airflowctl.api.client import NEW_API_CLIENT, ClientKind, provide_api_client


@provide_api_client(kind=ClientKind.CLI)
def check(args, api_client=NEW_API_CLIENT) -> None:
"""Check if job(s) are still alive."""
if args.allow_multiple and args.limit == 1:
raise SystemExit(
"To use option --allow-multiple, you must set the limit to a value greater than 1 "
"or 0 to disable it."
)
if args.hostname and args.local:
raise SystemExit("You can't use --hostname and --local at the same time")

hostname = socket.getfqdn() if args.local else args.hostname
alive_jobs = api_client.jobs.list(job_type=args.job_type, hostname=hostname, is_alive=True).jobs
if args.limit > 0:
alive_jobs = alive_jobs[: args.limit]

count_alive_jobs = len(alive_jobs)
if count_alive_jobs == 0:
raise SystemExit("No alive jobs found.")
if count_alive_jobs > 1 and not args.allow_multiple:
raise SystemExit(f"Found {count_alive_jobs} alive jobs. Expected only one.")
if count_alive_jobs == 1:
rich.print("Found one alive job.")
else:
rich.print(f"Found {count_alive_jobs} alive jobs.")
Loading