Skip to content

Commit 343ae08

Browse files
committed
feat(init): scaffold guaranteed qos pod resources
1 parent f5fef6e commit 343ae08

5 files changed

Lines changed: 74 additions & 2 deletions

File tree

docs/command-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
- Pod-only setups default to `.okdev.yaml`.
6767
- When built-in workload scaffolding also writes files under `.okdev/`, the config is written as `.okdev/okdev.yaml`.
6868
- `--workload`: chooses the scaffold mode. `pod` keeps the current simple config shape; `job` and `pytorchjob` add a `spec.workload` block plus a starter manifest; `generic` requires explicit inject information and can optionally use a preset such as `--generic-preset deployment`.
69-
- `--dev-image`: sets the dev container image for pod workloads. When provided, the generated config includes a `podTemplate` with the given image.
69+
- `--dev-image`: sets the dev container image for pod workloads. Pod configs generated from the built-in template include a `podTemplate` with the dev container image plus equal CPU/memory requests and limits for the dev container and sidecar, so the starter pod is eligible for Kubernetes `Guaranteed` QoS.
7070
- `--template`: accepts built-in `basic`, a user template name from `~/.okdev/templates/`, a file path, or a URL.
7171
- For built-in templates, it also writes a starter local `.stignore` file for the initialized sync root.
7272
- For built-in `basic`, `job` and `pytorchjob` scaffold `.okdev/job.yaml` or `.okdev/pytorchjob.yaml`. When the config itself is `.okdev/okdev.yaml`, the generated `manifestPath` stays relative to that directory, for example `job.yaml` or `pytorchjob.yaml`. okdev resolves those paths from `.okdev/` first and falls back to the project root for compatibility with older layouts. `generic --generic-preset deployment` scaffolds `.okdev/deployment.yaml` while still using `spec.workload.type=generic`.

internal/cli/init_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,27 @@ func TestInitUsesRootConfigForPod(t *testing.T) {
300300
if _, err := os.Stat(filepath.Join(tmp, ".okdev.yaml")); err != nil {
301301
t.Fatalf("expected root config, got err=%v", err)
302302
}
303+
cfgRaw, err := os.ReadFile(filepath.Join(tmp, ".okdev.yaml"))
304+
if err != nil {
305+
t.Fatalf("read config: %v", err)
306+
}
307+
cfg := string(cfgRaw)
308+
for _, want := range []string{
309+
"podTemplate:",
310+
"name: dev",
311+
"image: ubuntu:22.04",
312+
"resources:",
313+
"cpu: \"500m\"",
314+
"memory: 512Mi",
315+
"cpu: \"250m\"",
316+
} {
317+
if !strings.Contains(cfg, want) {
318+
t.Fatalf("expected generated pod config to contain %q, got:\n%s", want, cfg)
319+
}
320+
}
321+
if strings.Count(cfg, "cpu: \"500m\"") != 2 || strings.Count(cfg, "cpu: \"250m\"") != 2 || strings.Count(cfg, "memory: 512Mi") != 4 {
322+
t.Fatalf("expected generated pod config to use equal requests and limits for Guaranteed QoS, got:\n%s", cfg)
323+
}
303324
}
304325

305326
func TestInitScaffoldsJobManifest(t *testing.T) {

internal/config/template.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,13 @@ type TemplateVars struct {
7777
Name string
7878
Namespace string
7979
DevImage string
80+
DevCPURequest string
81+
DevMemoryRequest string
82+
DevCPULimit string
83+
DevMemoryLimit string
8084
SidecarImage string
85+
SidecarCPU string
86+
SidecarMemory string
8187
SyncthingVersion string
8288
SyncLocal string
8389
SyncRemote string
@@ -102,7 +108,14 @@ func NewTemplateVars() *TemplateVars {
102108
return &TemplateVars{
103109
Name: "",
104110
Namespace: "default",
111+
DevImage: "ubuntu:22.04",
112+
DevCPURequest: "500m",
113+
DevMemoryRequest: "512Mi",
114+
DevCPULimit: "500m",
115+
DevMemoryLimit: "512Mi",
105116
SidecarImage: "",
117+
SidecarCPU: "250m",
118+
SidecarMemory: "512Mi",
106119
SyncthingVersion: DefaultSyncthingVersion,
107120
SyncLocal: ".",
108121
SyncRemote: "/workspace",

internal/config/template_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ func TestDefaultTemplateVars(t *testing.T) {
2828
if vars.SyncRemote != "/workspace" {
2929
t.Fatalf("expected /workspace sync remote, got %q", vars.SyncRemote)
3030
}
31+
if vars.DevImage != "ubuntu:22.04" {
32+
t.Fatalf("expected default dev image, got %q", vars.DevImage)
33+
}
34+
if vars.DevCPURequest != "500m" || vars.DevMemoryRequest != "512Mi" || vars.DevCPULimit != "500m" || vars.DevMemoryLimit != "512Mi" {
35+
t.Fatalf("unexpected default dev resources: %#v", vars)
36+
}
37+
if vars.SidecarCPU != "250m" || vars.SidecarMemory != "512Mi" {
38+
t.Fatalf("unexpected default sidecar resources: %#v", vars)
39+
}
3140
if vars.WorkloadType != "pod" {
3241
t.Fatalf("expected pod workload type, got %q", vars.WorkloadType)
3342
}
@@ -62,6 +71,21 @@ func TestRenderBuiltinBasic(t *testing.T) {
6271
if strings.Contains(out, "\n exclude:\n") {
6372
t.Fatalf("expected starter template to keep local ignore rules out of .okdev.yaml, got:\n%s", out)
6473
}
74+
if !strings.Contains(out, "podTemplate:") {
75+
t.Fatalf("expected default pod template, got:\n%s", out)
76+
}
77+
if !strings.Contains(out, "image: ubuntu:22.04") {
78+
t.Fatalf("expected default dev image, got:\n%s", out)
79+
}
80+
if !strings.Contains(out, "cpu: \"500m\"") || !strings.Contains(out, "memory: 512Mi") {
81+
t.Fatalf("expected default dev resource requests, got:\n%s", out)
82+
}
83+
if strings.Count(out, "cpu: \"500m\"") != 2 || strings.Count(out, "memory: 512Mi") != 4 {
84+
t.Fatalf("expected default dev resource limits, got:\n%s", out)
85+
}
86+
if strings.Count(out, "cpu: \"250m\"") != 2 {
87+
t.Fatalf("expected equal default sidecar CPU request/limit, got:\n%s", out)
88+
}
6589
}
6690

6791
func TestBuiltinTemplateLocalIgnores(t *testing.T) {

internal/config/templates/basic.yaml.tmpl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,25 @@ spec:
4040
{{- if .SidecarImage }}
4141
image: {{ .SidecarImage }}
4242
{{- end }}
43-
{{- if and (eq .WorkloadType "pod") .DevImage }}
43+
resources:
44+
requests:
45+
cpu: "{{ .SidecarCPU }}"
46+
memory: {{ .SidecarMemory }}
47+
limits:
48+
cpu: "{{ .SidecarCPU }}"
49+
memory: {{ .SidecarMemory }}
50+
{{- if eq .WorkloadType "pod" }}
4451
podTemplate:
4552
spec:
4653
containers:
4754
- name: dev
4855
image: {{ .DevImage }}
4956
command: ["sleep", "infinity"]
57+
resources:
58+
requests:
59+
cpu: "{{ .DevCPURequest }}"
60+
memory: {{ .DevMemoryRequest }}
61+
limits:
62+
cpu: "{{ .DevCPULimit }}"
63+
memory: {{ .DevMemoryLimit }}
5064
{{- end }}

0 commit comments

Comments
 (0)