Skip to content

Commit beedb68

Browse files
authored
Merge branch 'main' into fix/chart-default-image-tags
2 parents 2dae57b + 4462cb7 commit beedb68

8 files changed

Lines changed: 307 additions & 31 deletions

File tree

api/v1/hermesinstance_types.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,17 @@ type SchedulingSpec struct {
847847
Affinity *corev1.Affinity `json:"affinity,omitempty"`
848848
// +optional
849849
PriorityClassName string `json:"priorityClassName,omitempty"`
850+
851+
// RuntimeClassName selects the RuntimeClass the instance pod runs under,
852+
// so an agent executing model-driven code can be placed on a sandboxed
853+
// runtime (gVisor "runsc", Kata) instead of the cluster default.
854+
//
855+
// The named RuntimeClass must already exist in the cluster; an unknown name
856+
// leaves the pod unschedulable. Empty means the cluster default runtime.
857+
// +kubebuilder:validation:MaxLength=253
858+
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
859+
// +optional
860+
RuntimeClassName string `json:"runtimeClassName,omitempty"`
850861
}
851862

852863
// InstanceSkill: Plan 3 fills the runtime semantics. The field exists here so

bundle/manifests/hermes.agent_hermesinstances.yaml

Lines changed: 215 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4641,6 +4641,66 @@ spec:
46414641
networking:
46424642
description: Networking exposes the agent via Service / Ingress.
46434643
properties:
4644+
httpRoute:
4645+
description: |-
4646+
HTTPRoute controls optional Gateway API HTTPRoute creation. The operator
4647+
emits an unstructured gateway.networking.k8s.io/v1 HTTPRoute; the Gateway
4648+
API CRDs must be installed in the cluster for this to take effect.
4649+
properties:
4650+
annotations:
4651+
additionalProperties:
4652+
type: string
4653+
description: Annotations are applied verbatim onto the HTTPRoute.
4654+
type: object
4655+
enabled:
4656+
default: false
4657+
description: |-
4658+
Enabled: when true, the operator creates an HTTPRoute for the agent.
4659+
Default false.
4660+
type: boolean
4661+
hostnames:
4662+
description: Hostnames are the hostnames matched by this route.
4663+
items:
4664+
type: string
4665+
type: array
4666+
x-kubernetes-list-type: set
4667+
parentRefs:
4668+
description: |-
4669+
ParentRefs are the Gateways (or other parents) this route attaches to.
4670+
At least one is required for the route to take effect.
4671+
items:
4672+
description: HTTPRouteParentRef references a parent (typically
4673+
a Gateway) the route attaches to.
4674+
properties:
4675+
name:
4676+
description: Name of the parent resource (e.g. the Gateway
4677+
name).
4678+
minLength: 1
4679+
type: string
4680+
namespace:
4681+
description: Namespace of the parent. Defaults to the
4682+
HermesInstance namespace when empty.
4683+
type: string
4684+
sectionName:
4685+
description: SectionName is the name of a section within
4686+
the parent (e.g. a Gateway listener).
4687+
type: string
4688+
required:
4689+
- name
4690+
type: object
4691+
type: array
4692+
path:
4693+
default: /
4694+
description: Path is the path prefix routed to the agent Service.
4695+
Default "/".
4696+
type: string
4697+
servicePortName:
4698+
default: gateway
4699+
description: |-
4700+
ServicePortName: name of the Service port the route should target.
4701+
Default "gateway".
4702+
type: string
4703+
type: object
46444704
ingress:
46454705
description: Ingress controls optional Ingress creation.
46464706
properties:
@@ -5540,9 +5600,15 @@ spec:
55405600
type: string
55415601
runtime:
55425602
description: |-
5543-
Runtime controls the agent's Python toolchain and OS-level dependencies.
5544-
All fields default to the values that match the operator's published
5545-
ghcr.io/paperclipinc/hermes-agent image.
5603+
Runtime configured the agent's Python toolchain and OS-level dependencies
5604+
for the old hand-rolled agent image. It is now IGNORED: the published agent
5605+
image is the upstream NousResearch/hermes-agent s6 runtime, which ships its
5606+
own Python env, browser, node, and dependencies (see docs/runtime.md), so
5607+
the operator no longer builds a runtime via init containers. Setting this
5608+
has no effect.
5609+
5610+
Deprecated: ignored since the upstream-image runtime (v0.1.19); scheduled
5611+
for removal no earlier than v0.3.0 and 2027-01-01. See docs/deprecations.md.
55465612
properties:
55475613
extraAptPackages:
55485614
description: |-
@@ -6581,6 +6647,17 @@ spec:
65816647
type: object
65826648
priorityClassName:
65836649
type: string
6650+
runtimeClassName:
6651+
description: |-
6652+
RuntimeClassName selects the RuntimeClass the instance pod runs under,
6653+
so an agent executing model-driven code can be placed on a sandboxed
6654+
runtime (gVisor "runsc", Kata) instead of the cluster default.
6655+
6656+
The named RuntimeClass must already exist in the cluster; an unknown name
6657+
leaves the pod unschedulable. Empty means the cluster default runtime.
6658+
maxLength: 253
6659+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
6660+
type: string
65846661
tolerations:
65856662
items:
65866663
description: |-
@@ -7370,19 +7447,18 @@ spec:
73707447
x-kubernetes-list-type: set
73717448
type: object
73727449
shareProcessNamespace:
7373-
default: true
7450+
default: false
73747451
description: |-
73757452
ShareProcessNamespace enables PID namespace sharing between all containers
7376-
in the pod. When true (the default), the infrastructure (pause) container
7377-
becomes PID 1 and reaps zombie processes, preventing accumulation of defunct
7378-
helper processes (git, plugins, shells) spawned under the agent entrypoint
7379-
when it does not call waitpid().
7453+
in the pod. Defaults to false: the upstream hermes-agent image runs under
7454+
s6-overlay, whose /init must be PID 1 (s6-overlay-suexec aborts otherwise),
7455+
and s6 already reaps zombies non-blocking on SIGCHLD — so sharing the process
7456+
namespace (which makes the pause container PID 1) is both incompatible and
7457+
unnecessary.
73807458

73817459
Security note: enabling this lets every container in the pod see and signal
73827460
every other container's processes. A compromised sidecar could send signals
7383-
to the agent and vice versa. Set to false to keep per-container PID isolation;
7384-
you are then responsible for reaping zombies (e.g. by baking tini or dumb-init
7385-
into the image).
7461+
to the agent and vice versa. Leave false to keep per-container PID isolation.
73867462
type: boolean
73877463
sidecars:
73887464
description: |-
@@ -8953,6 +9029,134 @@ spec:
89539029
description: Suspended scales the StatefulSet to zero replicas without
89549030
deleting state.
89559031
type: boolean
9032+
tailscale:
9033+
description: Tailscale exposes the gateway over a Tailscale tailnet.
9034+
properties:
9035+
authKey:
9036+
description: |-
9037+
AuthKey references the Secret holding a reusable, ephemeral Tailscale auth
9038+
key, exposed to the sidecar as TS_AUTHKEY. Required when Enabled is true.
9039+
properties:
9040+
secretRef:
9041+
description: SecretKeySelector selects a key of a Secret.
9042+
properties:
9043+
key:
9044+
description: The key of the secret to select from. Must
9045+
be a valid secret key.
9046+
type: string
9047+
name:
9048+
default: ""
9049+
description: |-
9050+
Name of the referent.
9051+
This field is effectively required, but due to backwards compatibility is
9052+
allowed to be empty. Instances of this type with an empty value here are
9053+
almost certainly wrong.
9054+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
9055+
type: string
9056+
optional:
9057+
description: Specify whether the Secret or its key must
9058+
be defined
9059+
type: boolean
9060+
required:
9061+
- key
9062+
type: object
9063+
x-kubernetes-map-type: atomic
9064+
type: object
9065+
enabled:
9066+
default: false
9067+
description: Enabled turns on the operator-managed Tailscale sidecar.
9068+
type: boolean
9069+
hostname:
9070+
description: Hostname overrides the tailnet/MagicDNS hostname.
9071+
Defaults to metadata.name.
9072+
maxLength: 63
9073+
pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$
9074+
type: string
9075+
image:
9076+
description: Image overrides the tailscale sidecar image.
9077+
properties:
9078+
pullPolicy:
9079+
default: IfNotPresent
9080+
enum:
9081+
- Always
9082+
- IfNotPresent
9083+
- Never
9084+
type: string
9085+
repository:
9086+
default: tailscale/tailscale
9087+
type: string
9088+
tag:
9089+
default: v1.86.2
9090+
type: string
9091+
type: object
9092+
mode:
9093+
default: serve
9094+
description: |-
9095+
Mode selects how the gateway is exposed over the tailnet. Only "serve"
9096+
is implemented today (private tailnet exposure with a Tailscale TLS cert).
9097+
enum:
9098+
- serve
9099+
type: string
9100+
resources:
9101+
description: Resources sets the sidecar resource requirements.
9102+
properties:
9103+
claims:
9104+
description: |-
9105+
Claims lists the names of resources, defined in spec.resourceClaims,
9106+
that are used by this container.
9107+
9108+
This field depends on the
9109+
DynamicResourceAllocation feature gate.
9110+
9111+
This field is immutable. It can only be set for containers.
9112+
items:
9113+
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
9114+
properties:
9115+
name:
9116+
description: |-
9117+
Name must match the name of one entry in pod.spec.resourceClaims of
9118+
the Pod where this field is used. It makes that resource available
9119+
inside a container.
9120+
type: string
9121+
request:
9122+
description: |-
9123+
Request is the name chosen for a request in the referenced claim.
9124+
If empty, everything from the claim is made available, otherwise
9125+
only the result of this request.
9126+
type: string
9127+
required:
9128+
- name
9129+
type: object
9130+
type: array
9131+
x-kubernetes-list-map-keys:
9132+
- name
9133+
x-kubernetes-list-type: map
9134+
limits:
9135+
additionalProperties:
9136+
anyOf:
9137+
- type: integer
9138+
- type: string
9139+
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
9140+
x-kubernetes-int-or-string: true
9141+
description: |-
9142+
Limits describes the maximum amount of compute resources allowed.
9143+
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
9144+
type: object
9145+
requests:
9146+
additionalProperties:
9147+
anyOf:
9148+
- type: integer
9149+
- type: string
9150+
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
9151+
x-kubernetes-int-or-string: true
9152+
description: |-
9153+
Requests describes the minimum amount of compute resources required.
9154+
If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
9155+
otherwise to an implementation-defined value. Requests cannot exceed Limits.
9156+
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
9157+
type: object
9158+
type: object
9159+
type: object
89569160
workspace:
89579161
description: Workspace seeds initial files and directories into ~/.hermes
89589162
on first start.

charts/hermes-operator/templates/crds/hermes.agent_hermesinstances.yaml

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5602,8 +5602,10 @@ spec:
56025602
description: |-
56035603
Runtime configured the agent's Python toolchain and OS-level dependencies
56045604
for the old hand-rolled agent image. It is now IGNORED: the published agent
5605-
image is the upstream NousResearch/hermes-agent s6 runtime, which is
5606-
self-contained (see docs/runtime.md). Setting this has no effect.
5605+
image is the upstream NousResearch/hermes-agent s6 runtime, which ships its
5606+
own Python env, browser, node, and dependencies (see docs/runtime.md), so
5607+
the operator no longer builds a runtime via init containers. Setting this
5608+
has no effect.
56075609

56085610
Deprecated: ignored since the upstream-image runtime (v0.1.19); scheduled
56095611
for removal no earlier than v0.3.0 and 2027-01-01. See docs/deprecations.md.
@@ -6645,6 +6647,17 @@ spec:
66456647
type: object
66466648
priorityClassName:
66476649
type: string
6650+
runtimeClassName:
6651+
description: |-
6652+
RuntimeClassName selects the RuntimeClass the instance pod runs under,
6653+
so an agent executing model-driven code can be placed on a sandboxed
6654+
runtime (gVisor "runsc", Kata) instead of the cluster default.
6655+
6656+
The named RuntimeClass must already exist in the cluster; an unknown name
6657+
leaves the pod unschedulable. Empty means the cluster default runtime.
6658+
maxLength: 253
6659+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
6660+
type: string
66486661
tolerations:
66496662
items:
66506663
description: |-
@@ -7437,16 +7450,15 @@ spec:
74377450
default: false
74387451
description: |-
74397452
ShareProcessNamespace enables PID namespace sharing between all containers
7440-
in the pod. When true (the default), the infrastructure (pause) container
7441-
becomes PID 1 and reaps zombie processes, preventing accumulation of defunct
7442-
helper processes (git, plugins, shells) spawned under the agent entrypoint
7443-
when it does not call waitpid().
7453+
in the pod. Defaults to false: the upstream hermes-agent image runs under
7454+
s6-overlay, whose /init must be PID 1 (s6-overlay-suexec aborts otherwise),
7455+
and s6 already reaps zombies non-blocking on SIGCHLD — so sharing the process
7456+
namespace (which makes the pause container PID 1) is both incompatible and
7457+
unnecessary.
74447458

74457459
Security note: enabling this lets every container in the pod see and signal
74467460
every other container's processes. A compromised sidecar could send signals
7447-
to the agent and vice versa. Set to false to keep per-container PID isolation;
7448-
you are then responsible for reaping zombies (e.g. by baking tini or dumb-init
7449-
into the image).
7461+
to the agent and vice versa. Leave false to keep per-container PID isolation.
74507462
type: boolean
74517463
sidecars:
74527464
description: |-

0 commit comments

Comments
 (0)