Skip to content

Commit be4781b

Browse files
authored
Merge branch 'main' into update_kubespawner
2 parents 5829038 + 0652d36 commit be4781b

File tree

13 files changed

+296
-50
lines changed

13 files changed

+296
-50
lines changed

.cirun.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ runners:
66
cloud: aws
77
# Instance Type has 8 vcpu, 32 GiB memory, Up to 5 Gbps Network Performance
88
instance_type: t3a.2xlarge
9-
# Custom AMI with docker/cypress/hub pre-installed
10-
machine_image: ami-0a388df278199ff52
9+
# Custom Ubuntu 24.04 AMI with docker/hub pre-installed
10+
machine_image: ami-01b494943951b97c7
1111
# Region: Oregon
1212
region: us-west-2
1313
# Use Spot Instances for cost savings

.github/workflows/test_local_integration.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ jobs:
5353
with:
5454
fetch-depth: 0
5555

56+
# https://kind.sigs.k8s.io/docs/user/known-issues/#pod-errors-due-to-too-many-open-files
57+
- name: "Update inotify ulimit"
58+
run: |
59+
sudo sysctl fs.inotify.max_user_watches=524288
60+
sudo sysctl fs.inotify.max_user_instances=512
61+
5662
- name: Setup runner for local deployment
5763
uses: ./.github/actions/setup-local
5864

src/_nebari/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
DEFAULT_NEBARI_IMAGE_TAG = CURRENT_RELEASE
1717
DEFAULT_NEBARI_WORKFLOW_CONTROLLER_IMAGE_TAG = CURRENT_RELEASE
1818

19-
DEFAULT_CONDA_STORE_IMAGE_TAG = "2025.2.1"
19+
DEFAULT_CONDA_STORE_IMAGE_TAG = "2025.2.2"
2020

2121
LATEST_SUPPORTED_PYTHON_VERSION = "3.10"
2222

src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/main.tf

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,22 @@ resource "azurerm_kubernetes_cluster" "main" {
2525
dynamic "network_profile" {
2626
for_each = var.network_profile != null ? [var.network_profile] : []
2727
content {
28-
network_plugin = network_profile.value.network_plugin != null ? network_profile.value.network_plugin : null
29-
network_policy = network_profile.value.network_policy != null ? network_profile.value.network_policy : null
30-
service_cidr = network_profile.value.service_cidr != null ? network_profile.value.service_cidr : null
31-
dns_service_ip = network_profile.value.dns_service_ip != null ? network_profile.value.dns_service_ip : null
32-
docker_bridge_cidr = network_profile.value.docker_bridge_cidr != null ? network_profile.value.docker_bridge_cidr : null
28+
network_plugin = network_profile.value.network_plugin != null ? network_profile.value.network_plugin : null
29+
network_policy = network_profile.value.network_policy != null ? network_profile.value.network_policy : null
30+
service_cidr = network_profile.value.service_cidr != null ? network_profile.value.service_cidr : null
31+
dns_service_ip = network_profile.value.dns_service_ip != null ? network_profile.value.dns_service_ip : null
3332
}
3433
}
3534

3635
kubernetes_version = var.kubernetes_version
3736
default_node_pool {
38-
vnet_subnet_id = var.vnet_subnet_id
39-
name = var.node_groups[0].name
40-
vm_size = var.node_groups[0].instance_type
41-
enable_auto_scaling = "true"
42-
min_count = var.node_groups[0].min_size
43-
max_count = var.node_groups[0].max_size
44-
max_pods = var.max_pods
37+
vnet_subnet_id = var.vnet_subnet_id
38+
name = var.node_groups[0].name
39+
vm_size = var.node_groups[0].instance_type
40+
auto_scaling_enabled = "true"
41+
min_count = var.node_groups[0].min_size
42+
max_count = var.node_groups[0].max_size
43+
max_pods = var.max_pods
4544

4645
orchestrator_version = var.kubernetes_version
4746
node_labels = {
@@ -76,7 +75,7 @@ resource "azurerm_kubernetes_cluster_node_pool" "node_group" {
7675
name = each.value.name
7776
kubernetes_cluster_id = azurerm_kubernetes_cluster.main.id
7877
vm_size = each.value.instance_type
79-
enable_auto_scaling = "true"
78+
auto_scaling_enabled = "true"
8079
mode = "User" # "System" or "User", only "User" nodes can scale down to 0
8180
min_count = each.value.min_size
8281
max_count = each.value.max_size

src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/variables.tf

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,10 @@ variable "tags" {
5656
variable "network_profile" {
5757
description = "Network profile"
5858
type = object({
59-
network_plugin = string
60-
network_policy = string
61-
service_cidr = string
62-
dns_service_ip = string
63-
docker_bridge_cidr = string
59+
network_plugin = string
60+
network_policy = string
61+
service_cidr = string
62+
dns_service_ip = string
6463
})
6564
default = null
6665
}

src/_nebari/stages/infrastructure/template/azure/variables.tf

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,10 @@ variable "tags" {
6262
variable "network_profile" {
6363
description = "Network profile"
6464
type = object({
65-
network_plugin = string
66-
network_policy = string
67-
service_cidr = string
68-
dns_service_ip = string
69-
docker_bridge_cidr = string
65+
network_plugin = string
66+
network_policy = string
67+
service_cidr = string
68+
dns_service_ip = string
7069
})
7170
default = null
7271
}

src/_nebari/stages/infrastructure/template/azure/versions.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
azurerm = {
44
source = "hashicorp/azurerm"
5-
version = "=3.97.1"
5+
version = "=4.7.0"
66
}
77
}
88
required_version = ">= 1.0"

src/_nebari/stages/kubernetes_services/__init__.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
from typing import Any, Dict, List, Optional, Type, Union
66
from urllib.parse import urlencode
77

8-
from pydantic import ConfigDict, Field, field_validator, model_validator
8+
from pydantic import (
9+
ConfigDict,
10+
Field,
11+
field_validator,
12+
model_serializer,
13+
model_validator,
14+
)
915
from typing_extensions import Self
1016

1117
from _nebari import constants
@@ -109,6 +115,42 @@ class KubeSpawner(schema.Base):
109115
model_config = ConfigDict(extra="allow")
110116

111117

118+
class ProfileOptionUnlistedChoice(schema.Base):
119+
enabled: bool = False
120+
display_name: str
121+
display_name_in_choices: Optional[str] = None
122+
validation_regex: Optional[str] = None
123+
validation_message: Optional[str] = None
124+
kubespawner_override: Dict[str, Any]
125+
126+
127+
class ProfileOptionChoice(schema.Base):
128+
display_name: str
129+
default: Optional[bool] = False
130+
kubespawner_override: Dict[str, Any]
131+
132+
133+
class ProfileOption(schema.Base):
134+
display_name: str
135+
unlisted_choice: Optional[ProfileOptionUnlistedChoice] = None
136+
choices: Dict[str, ProfileOptionChoice]
137+
138+
@field_validator("choices")
139+
def validate_choices(cls, v):
140+
defaults = [choice for choice in v.values() if choice.default]
141+
if len(defaults) > 1:
142+
raise ValueError("Only one choice can be marked as default")
143+
return v
144+
145+
# We need to exclude unlisted_choice if not set.
146+
# This was the recommended solution without affecting the parent.
147+
# reference: https://github.com/pydantic/pydantic/discussions/7315
148+
@model_serializer(mode="wrap")
149+
def serialize_model(self, handler) -> dict[str, Any]:
150+
result = handler(self)
151+
return {k: v for k, v in result.items() if v is not None}
152+
153+
112154
class JupyterLabProfile(schema.Base):
113155
access: AccessEnum = AccessEnum.all
114156
display_name: str
@@ -117,6 +159,7 @@ class JupyterLabProfile(schema.Base):
117159
users: Optional[List[str]] = None
118160
groups: Optional[List[str]] = None
119161
kubespawner_override: Optional[KubeSpawner] = None
162+
profile_options: Optional[dict[str, ProfileOption]] = None
120163

121164
@model_validator(mode="after")
122165
def only_yaml_can_have_groups_and_users(self):

src/_nebari/stages/terraform_state/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ def deploy(
219219
# terraform show command, inside check_immutable_fields
220220
with super().deploy(stage_outputs, disable_prompt, tofu_init=False):
221221
env_mapping = {}
222-
223222
with modified_environ(**env_mapping):
224223
yield
225224

@@ -262,6 +261,7 @@ def check_immutable_fields(self):
262261

263262
def get_nebari_config_state(self) -> dict:
264263
directory = str(self.output_directory / self.stage_prefix)
264+
265265
tf_state = opentofu.show(directory)
266266
nebari_config_state = None
267267

src/_nebari/stages/terraform_state/template/azure/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ terraform {
4747
required_providers {
4848
azurerm = {
4949
source = "hashicorp/azurerm"
50-
version = "=3.97.1"
50+
version = "=4.7.0"
5151
}
5252
}
5353
required_version = ">= 1.0"

0 commit comments

Comments
 (0)