Skip to content

Commit e7a6f00

Browse files
committed
merged main and fix conflict
2 parents e51b0b8 + 24395c2 commit e7a6f00

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+723
-300
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- Use `--file-log-rotation-period` (or `FILE_LOG_ROTATION_PERIOD`) to configure the frequency of rotation.
1111
- Use `--console-log-format` (or `CONSOLE_LOG_FORMAT`) to set the format to `plain` (default) or `json`.
1212
- Add support for airflow `2.10.5` ([#625]).
13+
- Add experimental support for airflow `3.0.1` ([#630]).
1314

1415
### Changed
1516

@@ -45,6 +46,7 @@
4546
[#623]: https://github.com/stackabletech/airflow-operator/pull/623
4647
[#624]: https://github.com/stackabletech/airflow-operator/pull/624
4748
[#625]: https://github.com/stackabletech/airflow-operator/pull/625
49+
[#630]: https://github.com/stackabletech/airflow-operator/pull/630
4850
[#636]: https://github.com/stackabletech/airflow-operator/pull/636
4951

5052
## [25.3.0] - 2025-03-21

docs/modules/airflow/pages/usage-guide/storage-resources.adoc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ include::home:concepts:stackable_resource_requests.adoc[]
55

66
A minimal HA setup consisting of 2 schedulers, 2 workers and 2 webservers has the following https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/[resource requirements]:
77

8-
* `5700m` CPU request
8+
* `8700m` CPU request
99
* `17400m` CPU limit
10-
* `10752Mi` memory request and limit
10+
* `15872Mi` memory request and limit
1111
1212
Corresponding to the values above, the operator uses the following resource defaults:
1313

@@ -18,24 +18,24 @@ spec:
1818
config:
1919
resources:
2020
cpu:
21-
min: 500m
21+
min: "1"
2222
max: "2"
2323
memory:
24-
limit: 512Mi
24+
limit: 1Gi
2525
celeryExecutors:
2626
config:
2727
resources:
2828
cpu:
29-
min: 500m
29+
min: "1"
3030
max: "2"
3131
memory:
32-
limit: 2Gi
32+
limit: 3Gi
3333
webservers:
3434
config:
3535
resources:
3636
cpu:
37-
min: 500m
37+
min: "1"
3838
max: "2"
3939
memory:
40-
limit: 2Gi
40+
limit: 3Gi
4141
----

docs/modules/airflow/partials/supported-versions.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// This is a separate file, since it is used by both the direct Airflow-Operator documentation, and the overarching
33
// Stackable Platform documentation.
44

5+
- 3.0.1 (experimental)
56
- 2.10.5
67
- 2.10.4 (deprecated)
78
- 2.9.3 (LTS)

rust/operator-binary/src/airflow_controller.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,8 @@ fn build_server_rolegroup_statefulset(
951951
.context(GracefulShutdownSnafu)?;
952952

953953
let mut airflow_container_args = Vec::new();
954-
airflow_container_args.extend(airflow_role.get_commands(authentication_config));
954+
airflow_container_args
955+
.extend(airflow_role.get_commands(authentication_config, resolved_product_image));
955956

956957
airflow_container
957958
.image_from_product_image(resolved_product_image)
@@ -974,6 +975,7 @@ fn build_server_rolegroup_statefulset(
974975
authentication_config,
975976
authorization_config,
976977
git_sync_resources,
978+
resolved_product_image,
977979
)
978980
.context(BuildStatefulsetEnvVarsSnafu)?,
979981
);
@@ -1164,7 +1166,10 @@ fn build_server_rolegroup_statefulset(
11641166
match_labels: Some(statefulset_match_labels.into()),
11651167
..LabelSelector::default()
11661168
},
1167-
service_name: Some(rolegroup_ref.object_name()),
1169+
service_name: Some(format!(
1170+
"{name}-metrics",
1171+
name = rolegroup_ref.object_name()
1172+
)),
11681173
template: pod_template,
11691174
volume_claim_templates: pvcs,
11701175
..StatefulSetSpec::default()
@@ -1251,6 +1256,7 @@ fn build_executor_template_config_map(
12511256
env_overrides,
12521257
merged_executor_config,
12531258
git_sync_resources,
1259+
resolved_product_image,
12541260
))
12551261
.add_volume_mounts(airflow.volume_mounts())
12561262
.context(AddVolumeMountSnafu)?

rust/operator-binary/src/crd/mod.rs

Lines changed: 81 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use stackable_operator::{
99
cache::UserInformationCache,
1010
cluster_operation::ClusterOperation,
1111
opa::OpaConfig,
12-
product_image_selection::ProductImage,
12+
product_image_selection::{ProductImage, ResolvedProductImage},
1313
resources::{
1414
CpuLimitsFragment, MemoryLimitsFragment, NoRuntimeLimits, NoRuntimeLimitsFragment,
1515
Resources, ResourcesFragment,
@@ -323,11 +323,6 @@ impl v1alpha1::AirflowCluster {
323323
self.spec.cluster_config.volume_mounts.clone()
324324
}
325325

326-
/// The name of the role-level load-balanced Kubernetes `Service`
327-
pub fn node_role_service_name(&self) -> Option<String> {
328-
self.metadata.name.clone()
329-
}
330-
331326
/// Retrieve and merge resource configs for role and role groups
332327
pub fn merged_config(
333328
&self,
@@ -550,6 +545,7 @@ impl AirflowRole {
550545
pub fn get_commands(
551546
&self,
552547
auth_config: &AirflowClientAuthenticationDetailsResolved,
548+
resolved_product_image: &ResolvedProductImage,
553549
) -> Vec<String> {
554550
let mut command = vec![
555551
format!(
@@ -560,43 +556,79 @@ impl AirflowRole {
560556
remove_vector_shutdown_file_command(STACKABLE_LOG_DIR),
561557
];
562558

563-
match &self {
564-
AirflowRole::Webserver => {
565-
// Getting auth commands for AuthClass
566-
command.extend(Self::authentication_start_commands(auth_config));
567-
command.extend(vec![
559+
if resolved_product_image.product_version.starts_with("3.") {
560+
// Start-up commands have changed in 3.x.
561+
// See https://airflow.apache.org/docs/apache-airflow/3.0.1/installation/upgrading_to_airflow3.html#step-6-changes-to-your-startup-scripts and
562+
// https://airflow.apache.org/docs/apache-airflow/3.0.1/installation/setting-up-the-database.html#setting-up-the-database.
563+
// `airflow db migrate` is not run for each role so there may be
564+
// re-starts of webserver and/or workers (which require the DB).
565+
// DB-migrations should be eventually be optional:
566+
// See https://github.com/stackabletech/airflow-operator/issues/589.
567+
match &self {
568+
AirflowRole::Webserver => {
569+
command.extend(Self::authentication_start_commands(auth_config));
570+
command.extend(vec![
571+
"prepare_signal_handlers".to_string(),
572+
container_debug_command(),
573+
"airflow api-server &".to_string(),
574+
]);
575+
}
576+
AirflowRole::Scheduler => command.extend(vec![
577+
"airflow db migrate".to_string(),
578+
"airflow users create \
579+
--username \"$ADMIN_USERNAME\" \
580+
--firstname \"$ADMIN_FIRSTNAME\" \
581+
--lastname \"$ADMIN_LASTNAME\" \
582+
--email \"$ADMIN_EMAIL\" \
583+
--password \"$ADMIN_PASSWORD\" \
584+
--role \"Admin\""
585+
.to_string(),
586+
"prepare_signal_handlers".to_string(),
587+
container_debug_command(),
588+
"airflow dag-processor &".to_string(),
589+
"airflow scheduler &".to_string(),
590+
]),
591+
AirflowRole::Worker => command.extend(vec![
568592
"prepare_signal_handlers".to_string(),
569-
format!("containerdebug --output={STACKABLE_LOG_DIR}/containerdebug-state.json --loop &"),
570-
"airflow webserver &".to_string(),
571-
]);
593+
container_debug_command(),
594+
"airflow celery worker &".to_string(),
595+
]),
596+
}
597+
} else {
598+
match &self {
599+
AirflowRole::Webserver => {
600+
// Getting auth commands for AuthClass
601+
command.extend(Self::authentication_start_commands(auth_config));
602+
command.extend(vec![
603+
"prepare_signal_handlers".to_string(),
604+
container_debug_command(),
605+
"airflow webserver &".to_string(),
606+
]);
607+
}
608+
AirflowRole::Scheduler => command.extend(vec![
609+
// Database initialization is limited to the scheduler, see https://github.com/stackabletech/airflow-operator/issues/259
610+
"airflow db init".to_string(),
611+
"airflow db upgrade".to_string(),
612+
"airflow users create \
613+
--username \"$ADMIN_USERNAME\" \
614+
--firstname \"$ADMIN_FIRSTNAME\" \
615+
--lastname \"$ADMIN_LASTNAME\" \
616+
--email \"$ADMIN_EMAIL\" \
617+
--password \"$ADMIN_PASSWORD\" \
618+
--role \"Admin\""
619+
.to_string(),
620+
"prepare_signal_handlers".to_string(),
621+
container_debug_command(),
622+
"airflow scheduler &".to_string(),
623+
]),
624+
AirflowRole::Worker => command.extend(vec![
625+
"prepare_signal_handlers".to_string(),
626+
container_debug_command(),
627+
"airflow celery worker &".to_string(),
628+
]),
572629
}
573-
574-
AirflowRole::Scheduler => command.extend(vec![
575-
// Database initialization is limited to the scheduler, see https://github.com/stackabletech/airflow-operator/issues/259
576-
"airflow db init".to_string(),
577-
"airflow db upgrade".to_string(),
578-
"airflow users create \
579-
--username \"$ADMIN_USERNAME\" \
580-
--firstname \"$ADMIN_FIRSTNAME\" \
581-
--lastname \"$ADMIN_LASTNAME\" \
582-
--email \"$ADMIN_EMAIL\" \
583-
--password \"$ADMIN_PASSWORD\" \
584-
--role \"Admin\""
585-
.to_string(),
586-
"prepare_signal_handlers".to_string(),
587-
format!(
588-
"containerdebug --output={STACKABLE_LOG_DIR}/containerdebug-state.json --loop &"
589-
),
590-
"airflow scheduler &".to_string(),
591-
]),
592-
AirflowRole::Worker => command.extend(vec![
593-
"prepare_signal_handlers".to_string(),
594-
format!(
595-
"containerdebug --output={STACKABLE_LOG_DIR}/containerdebug-state.json --loop &"
596-
),
597-
"airflow celery worker &".to_string(),
598-
]),
599630
}
631+
600632
// graceful shutdown part
601633
command.extend(vec![
602634
"wait_for_termination $!".to_string(),
@@ -657,6 +689,10 @@ impl AirflowRole {
657689
}
658690
}
659691

692+
fn container_debug_command() -> String {
693+
format!("containerdebug --output={STACKABLE_LOG_DIR}/containerdebug-state.json --loop &")
694+
}
695+
660696
#[derive(Clone, Debug, Deserialize, Display, JsonSchema, PartialEq, Serialize)]
661697
pub enum AirflowExecutor {
662698
/// The celery executor.
@@ -854,17 +890,17 @@ fn default_resources(role: &AirflowRole) -> ResourcesFragment<AirflowStorageConf
854890
let (cpu, memory) = match role {
855891
AirflowRole::Worker => (
856892
CpuLimitsFragment {
857-
min: Some(Quantity("500m".into())),
893+
min: Some(Quantity("1".into())),
858894
max: Some(Quantity("2".into())),
859895
},
860896
MemoryLimitsFragment {
861-
limit: Some(Quantity("2Gi".into())),
897+
limit: Some(Quantity("3Gi".into())),
862898
runtime_limits: NoRuntimeLimitsFragment {},
863899
},
864900
),
865901
AirflowRole::Webserver => (
866902
CpuLimitsFragment {
867-
min: Some(Quantity("500m".into())),
903+
min: Some(Quantity("1".into())),
868904
max: Some(Quantity("2".into())),
869905
},
870906
MemoryLimitsFragment {
@@ -874,11 +910,11 @@ fn default_resources(role: &AirflowRole) -> ResourcesFragment<AirflowStorageConf
874910
),
875911
AirflowRole::Scheduler => (
876912
CpuLimitsFragment {
877-
min: Some(Quantity("500m".to_owned())),
913+
min: Some(Quantity("1".to_owned())),
878914
max: Some(Quantity("2".to_owned())),
879915
},
880916
MemoryLimitsFragment {
881-
limit: Some(Quantity("512Mi".to_owned())),
917+
limit: Some(Quantity("1Gi".to_owned())),
882918
runtime_limits: NoRuntimeLimitsFragment {},
883919
},
884920
),

0 commit comments

Comments
 (0)