Skip to content

Commit 8166f57

Browse files
committed
feat(site): correctly display values of type clibase.Duration
1 parent e0afee1 commit 8166f57

File tree

4 files changed

+76
-12
lines changed

4 files changed

+76
-12
lines changed

codersdk/deployment.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,9 @@ type HealthcheckConfig struct {
403403
}
404404

405405
const (
406-
annotationEnterpriseKey = "enterprise"
407-
annotationSecretKey = "secret"
406+
annotationFormatDurationNS = "format_duration_ns"
407+
annotationEnterpriseKey = "enterprise"
408+
annotationSecretKey = "secret"
408409
// annotationExternalProxies is used to mark options that are used by workspace
409410
// proxies. This is used to filter out options that are not relevant.
410411
annotationExternalProxies = "external_workspace_proxies"
@@ -630,6 +631,7 @@ when required by your organization's security policy.`,
630631
Default: time.Minute.String(),
631632
Value: &c.AutobuildPollInterval,
632633
YAML: "autobuildPollInterval",
634+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
633635
},
634636
{
635637
Name: "Job Hang Detector Interval",
@@ -640,6 +642,7 @@ when required by your organization's security policy.`,
640642
Default: time.Minute.String(),
641643
Value: &c.JobHangDetectorInterval,
642644
YAML: "jobHangDetectorInterval",
645+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
643646
},
644647
httpAddress,
645648
tlsBindAddress,
@@ -1333,6 +1336,7 @@ when required by your organization's security policy.`,
13331336
Value: &c.Provisioner.DaemonPollInterval,
13341337
Group: &deploymentGroupProvisioning,
13351338
YAML: "daemonPollInterval",
1339+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
13361340
},
13371341
{
13381342
Name: "Poll Jitter",
@@ -1343,6 +1347,7 @@ when required by your organization's security policy.`,
13431347
Value: &c.Provisioner.DaemonPollJitter,
13441348
Group: &deploymentGroupProvisioning,
13451349
YAML: "daemonPollJitter",
1350+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
13461351
},
13471352
{
13481353
Name: "Force Cancel Interval",
@@ -1353,6 +1358,7 @@ when required by your organization's security policy.`,
13531358
Value: &c.Provisioner.ForceCancelInterval,
13541359
Group: &deploymentGroupProvisioning,
13551360
YAML: "forceCancelInterval",
1361+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
13561362
},
13571363
{
13581364
Name: "Provisioner Daemon Pre-shared Key (PSK)",
@@ -1502,10 +1508,11 @@ when required by your organization's security policy.`,
15021508
// The default value is essentially "forever", so just use 100 years.
15031509
// We have to add in the 25 leap days for the frontend to show the
15041510
// "100 years" correctly.
1505-
Default: ((100 * 365 * time.Hour * 24) + (25 * time.Hour * 24)).String(),
1506-
Value: &c.MaxTokenLifetime,
1507-
Group: &deploymentGroupNetworkingHTTP,
1508-
YAML: "maxTokenLifetime",
1511+
Default: ((100 * 365 * time.Hour * 24) + (25 * time.Hour * 24)).String(),
1512+
Value: &c.MaxTokenLifetime,
1513+
Group: &deploymentGroupNetworkingHTTP,
1514+
YAML: "maxTokenLifetime",
1515+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
15091516
},
15101517
{
15111518
Name: "Enable swagger endpoint",
@@ -1613,6 +1620,7 @@ when required by your organization's security policy.`,
16131620
Hidden: true,
16141621
Default: time.Hour.String(),
16151622
Value: &c.MetricsCacheRefreshInterval,
1623+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
16161624
},
16171625
{
16181626
Name: "Agent Stat Refresh Interval",
@@ -1622,6 +1630,7 @@ when required by your organization's security policy.`,
16221630
Hidden: true,
16231631
Default: (30 * time.Second).String(),
16241632
Value: &c.AgentStatRefreshInterval,
1633+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
16251634
},
16261635
{
16271636
Name: "Agent Fallback Troubleshooting URL",
@@ -1688,6 +1697,7 @@ when required by your organization's security policy.`,
16881697
Value: &c.SessionDuration,
16891698
Group: &deploymentGroupNetworkingHTTP,
16901699
YAML: "sessionDuration",
1700+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
16911701
},
16921702
{
16931703
Name: "Disable Session Expiry Refresh",
@@ -1790,6 +1800,7 @@ Write out the current server config as YAML to stdout.`,
17901800
Value: &c.ProxyHealthStatusInterval,
17911801
Group: &deploymentGroupNetworkingHTTP,
17921802
YAML: "proxyHealthInterval",
1803+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
17931804
},
17941805
{
17951806
Name: "Default Quiet Hours Schedule",
@@ -1821,6 +1832,7 @@ Write out the current server config as YAML to stdout.`,
18211832
Value: &c.Healthcheck.Refresh,
18221833
Group: &deploymentGroupIntrospectionHealthcheck,
18231834
YAML: "refresh",
1835+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
18241836
},
18251837
{
18261838
Name: "Health Check Threshold: Database",
@@ -1831,6 +1843,7 @@ Write out the current server config as YAML to stdout.`,
18311843
Value: &c.Healthcheck.ThresholdDatabase,
18321844
Group: &deploymentGroupIntrospectionHealthcheck,
18331845
YAML: "thresholdDatabase",
1846+
Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),
18341847
},
18351848
}
18361849

codersdk/deployment_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,24 @@ func must[T any](value T, err error) T {
256256
}
257257
return value
258258
}
259+
260+
func TestDeploymentValues_DurationFormatNanoseconds(t *testing.T) {
261+
t.Parallel()
262+
263+
set := (&codersdk.DeploymentValues{}).Options()
264+
for _, s := range set {
265+
if s.Value.Type() != "duration" {
266+
continue
267+
}
268+
// Just make sure the annotation is set.
269+
// If someone wants to not format a duration, they can
270+
// explicitly set the annotation to false.
271+
if s.Annotations.IsSet("format_duration_ns") {
272+
continue
273+
}
274+
t.Logf("Option %q is a duration but does not have the format_duration_ns annotation.", s.Name)
275+
t.Logf("To fix this, add the following to the option declaration:")
276+
t.Logf(`Annotations: clibase.Annotations{}.Mark(annotationFormatDurationNS, "true"),`)
277+
t.FailNow()
278+
}
279+
}

site/src/components/DeploySettingsLayout/optionValue.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,24 @@ describe("optionValue", () => {
104104
additionalValues: ["single_tailnet", "deployment_health_page"],
105105
expected: { single_tailnet: true, deployment_health_page: true },
106106
},
107+
{
108+
option: {
109+
...defaultOption,
110+
name: "Some Go Duration We Want To Show As A String",
111+
value: 30 * 1e9,
112+
annotations: { "format_duration_ns": "true" },
113+
},
114+
expected: "30s",
115+
},
116+
{
117+
option: {
118+
...defaultOption,
119+
name: "Some Other Go Duration We Want To Just Display As A Number",
120+
value: 30 * 1e9,
121+
annotations: { "format_duration_ns": "false" },
122+
},
123+
expected: "30000000000"
124+
},
107125
])(
108126
`[$option.name]optionValue($option.value)`,
109127
({ option, expected, additionalValues }) => {

site/src/components/DeploySettingsLayout/optionValue.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,25 @@ export function optionValue(
66
option: ClibaseOption,
77
additionalValues?: string[],
88
) {
9+
// If option annotations are present, use them to format the value.
10+
if (option.annotations) {
11+
for (const [k, v] of Object.entries(option.annotations)) {
12+
if (v !== "true") {
13+
continue; // skip if not explicitly true
14+
}
15+
switch (k) {
16+
case "format_duration_ns":
17+
return formatDuration(
18+
// intervalToDuration takes ms, so convert nanoseconds to ms
19+
intervalToDuration({ start: 0, end: option.value as number / 1e6 }),
20+
)
21+
// Add additional cases here as needed.
22+
}
23+
};
24+
}
25+
26+
// If no format annotations are present, use the option name to format the value.
927
switch (option.name) {
10-
case "Max Token Lifetime":
11-
case "Session Duration":
12-
// intervalToDuration takes ms, so convert nanoseconds to ms
13-
return formatDuration(
14-
intervalToDuration({ start: 0, end: (option.value as number) / 1e6 }),
15-
);
1628
case "Strict-Transport-Security":
1729
if (option.value === 0) {
1830
return "Disabled";

0 commit comments

Comments
 (0)