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
6 changes: 6 additions & 0 deletions api/core/v1beta1/site_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,12 @@ type InternalConnectSpec struct {

NodeSelector map[string]string `json:"nodeSelector,omitempty"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The Workbench spec differentiates between server-level NodeSelector/Tolerations (applied universally) and session-only ones. For Connect, NodeSelector at this line applies to the server pod (line 148 in the controller), but there's no server-level Tolerations equivalent. If Connect server pods need to run on tainted nodes (e.g., to co-locate with Karpenter-provisioned infra), there's currently no way to do that. Worth noting in docs or adding a Tolerations field to mirror Workbench's server-level one — but fine to defer if not needed yet.


// ContentTolerations are tolerations applied only to Connect content (session) pods, not the Connect server.
ContentTolerations []corev1.Toleration `json:"contentTolerations,omitempty"`

// ContentNodeSelector is a node selector applied only to Connect content (session) pods, not the Connect server.
ContentNodeSelector map[string]string `json:"contentNodeSelector,omitempty"`

// Resources sets the server container's resource requests/limits.
// If unset, product defaults are applied. Setting this replaces the defaults entirely.
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
Expand Down
14 changes: 14 additions & 0 deletions api/core/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions client-go/applyconfiguration/core/v1beta1/internalconnectspec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions config/crd/bases/core.posit.team_sites.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,52 @@ spec:
BaseDomain overrides site.Spec.Domain for this product's URL construction.
When set, the product URL will be: domainPrefix.baseDomain
type: string
contentNodeSelector:
additionalProperties:
type: string
description: ContentNodeSelector is a node selector applied only
to Connect content (session) pods, not the Connect server.
type: object
contentTolerations:
description: ContentTolerations are tolerations applied only to
Connect content (session) pods, not the Connect server.
items:
description: |-
The pod this Toleration is attached to tolerates any taint that matches
the triple <key,value,effect> using the matching operator <operator>.
properties:
effect:
description: |-
Effect indicates the taint effect to match. Empty means match all taint effects.
When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.
type: string
key:
description: |-
Key is the taint key that the toleration applies to. Empty means match all taint keys.
If the key is empty, operator must be Exists; this combination means to match all values and all keys.
type: string
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
type: string
tolerationSeconds:
description: |-
TolerationSeconds represents the period of time the toleration (which must be
of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,
it is not set, which means tolerate the taint forever (do not evict). Zero and
negative values will be treated as 0 (evict immediately) by the system.
format: int64
type: integer
value:
description: |-
Value is the taint value the toleration matches to.
If the operator is Exists, the value should be empty, otherwise just a regular string.
type: string
type: object
type: array
databaseSettings:
properties:
instrumentationSchema:
Expand Down
46 changes: 46 additions & 0 deletions dist/chart/templates/crd/core.posit.team_sites.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,52 @@ spec:
BaseDomain overrides site.Spec.Domain for this product's URL construction.
When set, the product URL will be: domainPrefix.baseDomain
type: string
contentNodeSelector:
additionalProperties:
type: string
description: ContentNodeSelector is a node selector applied only
to Connect content (session) pods, not the Connect server.
type: object
contentTolerations:
description: ContentTolerations are tolerations applied only to
Connect content (session) pods, not the Connect server.
items:
description: |-
The pod this Toleration is attached to tolerates any taint that matches
the triple <key,value,effect> using the matching operator <operator>.
properties:
effect:
description: |-
Effect indicates the taint effect to match. Empty means match all taint effects.
When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.
type: string
key:
description: |-
Key is the taint key that the toleration applies to. Empty means match all taint keys.
If the key is empty, operator must be Exists; this combination means to match all values and all keys.
type: string
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
type: string
tolerationSeconds:
description: |-
TolerationSeconds represents the period of time the toleration (which must be
of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,
it is not set, which means tolerate the taint forever (do not evict). Zero and
negative values will be treated as 0 (evict immediately) by the system.
format: int64
type: integer
value:
description: |-
Value is the taint value the toleration matches to.
If the operator is Exists, the value should be empty, otherwise just a regular string.
type: string
type: object
type: array
databaseSettings:
properties:
instrumentationSchema:
Expand Down
2 changes: 2 additions & 0 deletions internal/controller/core/site_controller_connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ func (r *SiteReconciler) reconcileConnect(
ImagePullPolicy: site.Spec.Connect.ImagePullPolicy,
ImagePullSecrets: product.MakePullSecrets(site.Spec.ImagePullSecrets),
ServiceAccountName: fmt.Sprintf("%s-connect-session", req.Name),
Tolerations: site.Spec.Connect.ContentTolerations,
NodeSelector: site.Spec.Connect.ContentNodeSelector,
},
},
Config: v1beta1.ConnectConfig{
Expand Down
31 changes: 31 additions & 0 deletions internal/controller/core/site_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,37 @@ func TestSiteReconcileWithTolerations(t *testing.T) {
assert.Equal(t, "workbench-session", workbench.Spec.SessionConfig.Pod.Tolerations[0].Key)
}

func TestSiteReconcileWithContentPlacement(t *testing.T) {
siteName := "content-placement-site"
siteNamespace := "posit-team"
site := defaultSite(siteName)
// ContentTolerations and ContentNodeSelector apply to Connect content (session) pods
site.Spec.Connect.ContentTolerations = []corev1.Toleration{
{
Key: "workload-type",
Operator: corev1.TolerationOpEqual,
Value: "session",
Effect: corev1.TaintEffectNoSchedule,
},
}
site.Spec.Connect.ContentNodeSelector = map[string]string{
"karpenter.sh/nodepool": "test-pool",
}

cli, _, err := runFakeSiteReconciler(t, siteNamespace, siteName, site)
assert.Nil(t, err)

// Verify content (session) pods receive the ContentTolerations and ContentNodeSelector
connect := getConnect(t, cli, siteNamespace, siteName)
assert.NotNil(t, connect.Spec.SessionConfig)
assert.NotNil(t, connect.Spec.SessionConfig.Pod)
assert.Len(t, connect.Spec.SessionConfig.Pod.Tolerations, 1)
assert.Equal(t, "workload-type", connect.Spec.SessionConfig.Pod.Tolerations[0].Key)
assert.Equal(t, "session", connect.Spec.SessionConfig.Pod.Tolerations[0].Value)
assert.Equal(t, corev1.TaintEffectNoSchedule, connect.Spec.SessionConfig.Pod.Tolerations[0].Effect)
assert.Equal(t, "test-pool", connect.Spec.SessionConfig.Pod.NodeSelector["karpenter.sh/nodepool"])
}

func TestSiteReconcileWithSharedDirectory(t *testing.T) {
siteName := "shared-site"
siteNamespace := "posit-team"
Expand Down
46 changes: 46 additions & 0 deletions internal/crdapply/bases/core.posit.team_sites.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,52 @@ spec:
BaseDomain overrides site.Spec.Domain for this product's URL construction.
When set, the product URL will be: domainPrefix.baseDomain
type: string
contentNodeSelector:
additionalProperties:
type: string
description: ContentNodeSelector is a node selector applied only
to Connect content (session) pods, not the Connect server.
type: object
contentTolerations:
description: ContentTolerations are tolerations applied only to
Connect content (session) pods, not the Connect server.
items:
description: |-
The pod this Toleration is attached to tolerates any taint that matches
the triple <key,value,effect> using the matching operator <operator>.
properties:
effect:
description: |-
Effect indicates the taint effect to match. Empty means match all taint effects.
When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.
type: string
key:
description: |-
Key is the taint key that the toleration applies to. Empty means match all taint keys.
If the key is empty, operator must be Exists; this combination means to match all values and all keys.
type: string
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
type: string
tolerationSeconds:
description: |-
TolerationSeconds represents the period of time the toleration (which must be
of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,
it is not set, which means tolerate the taint forever (do not evict). Zero and
negative values will be treated as 0 (evict immediately) by the system.
format: int64
type: integer
value:
description: |-
Value is the taint value the toleration matches to.
If the operator is Exists, the value should be empty, otherwise just a regular string.
type: string
type: object
type: array
databaseSettings:
properties:
instrumentationSchema:
Expand Down
Loading