@@ -185,6 +185,40 @@ spec:
185185 required :
186186 - httpGet
187187 type : object
188+ resources :
189+ description : |-
190+ Resources are the compute limits for this container, enforced inside the
191+ actor's sandbox. Only cpu and memory are supported, and only on micro-VM
192+ actors: gVisor applies cgroup limits at the sandbox level, so a
193+ per-container cgroup there is created but stays empty.
194+ properties :
195+ limits :
196+ additionalProperties :
197+ anyOf :
198+ - type : integer
199+ - type : string
200+ pattern : ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
201+ x-kubernetes-int-or-string : true
202+ description : |-
203+ Limits is the maximum amount of compute resources allowed. Only cpu and
204+ memory are supported, and each must be greater than zero.
205+
206+ A cpu limit below 10m is raised to 10m: the kernel rejects a CFS quota
207+ under 1ms, and the quota is expressed against a 100ms period.
208+ maxProperties : 2
209+ type : object
210+ type : object
211+ x-kubernetes-validations :
212+ - message : only cpu and memory limits are supported
213+ rule : ' !has(self.limits) || self.limits.all(k, k == '' cpu''
214+ || k == '' memory'' )'
215+ - message : memory limit must be greater than zero
216+ rule : ' !has(self.limits) || !('' memory'' in self.limits) ||
217+ quantity(string(self.limits['' memory'' ])).isGreaterThan(quantity('' 0'' ))'
218+ - message : cpu limit must be greater than zero
219+ rule : ' !has(self.limits) || !('' cpu'' in self.limits) || quantity(string(self.limits['' cpu'' ])).isGreaterThan(quantity('' 0'' ))'
220+ - message : cpu limit must be less than 1000 cores
221+ rule : ' !has(self.limits) || !('' cpu'' in self.limits) || quantity(string(self.limits['' cpu'' ])).isLessThan(quantity('' 1k'' ))'
188222 securityContext :
189223 description : |-
190224 securityContext holds security settings for this container. Unset leaves
@@ -497,9 +531,9 @@ spec:
497531 DataSources is the list of data sources to place within the SystemInfo
498532 volume.
499533
500- At most one actorMetadata entry may appear; this is what keeps file
501- paths unique across the whole volume (uniqueness within the entry is
502- enforced on its items).
534+ At most one actorMetadata entry may appear, and file paths must be
535+ unique across all entries (uniqueness within actorMetadata is enforced
536+ on its items).
503537 items :
504538 description : |-
505539 SystemInfoDataSource is a container allowing you to pick a particular
@@ -534,17 +568,18 @@ spec:
534568 path :
535569 description : |-
536570 Relative path from the root of the SystemInfo volume at which the
537- field's value is written. Must be a clean relative Unix path: must not
538- start or end with '/', and contain no ':', '.. ', '.', '//', or control
539- characters.
571+ field's value is written. Must be a clean relative Unix path: it must
572+ not start or end with '/' and must not contain ':', '// ', '.' or '..'
573+ segments, or control characters.
540574 maxLength : 255
541575 minLength : 1
542576 type : string
543577 x-kubernetes-validations :
544578 - message : ' path must be a clean relative
545- Unix path: must not start or end with
546- '' /'' , and contain no '' :'' , '' ..'' ,
547- '' .'' , '' //'' , or control characters'
579+ Unix path: it must not start or end
580+ with '' /'' and must not contain '' :'' ,
581+ '' //'' , '' .'' or '' ..'' segments, or
582+ control characters'
548583 rule : ' !self.startsWith('' /'' ) && !self.endsWith('' /'' )
549584 && !self.contains('' //'' ) && !self.contains('' :'' )
550585 && !self.matches('' [\x00-\x1f\x7f]'' )
@@ -567,18 +602,76 @@ spec:
567602 required :
568603 - items
569604 type : object
605+ trustBundle :
606+ description : |-
607+ TrustBundleDataSource is a SystemInfo volume data source that projects the
608+ trust anchors of a named trust bundle to a single PEM file — inspired by
609+ the Kubernetes clusterTrustBundle projected volume source, but
610+ source-neutral: the name selects a bundle substrate knows how to fetch,
611+ and where it is fetched from is a substrate deployment concern, not part
612+ of this API (atelet enforces the supported set and resolves the backend).
613+
614+ Supported names are allowlisted in atelet. Initially the only supported
615+ bundle is "egress-mitm.ate.dev" (the egress gateway CA bundle), resolved
616+ from the Kubernetes ClusterTrustBundle (certificates.k8s.io/v1beta1) that
617+ atecontroller derives from the egress-mitm-ca-pool; a configurable backend
618+ registry may widen this later.
619+
620+ The bundle is resolved and sanitized on the node when the actor starts:
621+ atelet reads the backing object through a cluster-wide watch and keeps
622+ only CERTIFICATE PEM blocks, deduplicated and deliberately shuffled (order
623+ carries no meaning); the actor itself never talks to any bundle backend.
624+ Starting the actor fails if the named bundle is not on the allowlist, its
625+ backend is unavailable in this deployment, or the resolved bundle is
626+ missing, empty, or unparseable.
627+ properties :
628+ name :
629+ description : |-
630+ Name of the trust bundle to project. Must be a bundle name supported
631+ by this deployment (currently only "egress-mitm.ate.dev").
632+ maxLength : 253
633+ minLength : 1
634+ type : string
635+ path :
636+ description : |-
637+ Relative path from the root of the SystemInfo volume at which the PEM
638+ bundle is written. Must be a clean relative Unix path: it must not
639+ start or end with '/' and must not contain ':', '//', '.' or '..'
640+ segments, or control characters.
641+ maxLength : 255
642+ minLength : 1
643+ type : string
644+ x-kubernetes-validations :
645+ - message : ' path must be a clean relative Unix
646+ path: it must not start or end with '' /''
647+ and must not contain '' :'' , '' //'' , '' .''
648+ or '' ..'' segments, or control characters'
649+ rule : ' !self.startsWith('' /'' ) && !self.endsWith('' /'' )
650+ && !self.contains('' //'' ) && !self.contains('' :'' )
651+ && !self.matches('' [\x00-\x1f\x7f]'' ) && !self.matches('' (^|/)[.][.]?(/|$)'' )'
652+ required :
653+ - name
654+ - path
655+ type : object
570656 type : object
571657 x-kubernetes-validations :
572- - message : exactly one of the fields in [actorMetadata]
573- must be set
574- rule : ' [has(self.actorMetadata)].filter(x,x==true).size()
658+ - message : exactly one of the fields in [actorMetadata
659+ trustBundle] must be set
660+ rule : ' [has(self.actorMetadata),has(self.trustBundle) ].filter(x,x==true).size()
575661 == 1'
576- maxItems : 32
662+ maxItems : 8
577663 type : array
578664 x-kubernetes-validations :
579665 - message : dataSources must contain at most one actorMetadata
580666 entry
581667 rule : self.filter(x, has(x.actorMetadata)).size() <= 1
668+ - message : dataSources must not contain duplicate paths
669+ rule : self.all(x, !has(x.trustBundle) || self.exists_one(y,
670+ has(y.trustBundle) && y.trustBundle.path == x.trustBundle.path))
671+ - message : dataSources must not contain duplicate paths
672+ rule : ' !self.exists(x, has(x.trustBundle) && self.exists(y,
673+ has(y.actorMetadata) && y.actorMetadata.items.exists(i,
674+ i.path == x.trustBundle.path)))'
582675 type : object
583676 required :
584677 - name
@@ -675,6 +768,10 @@ spec:
675768 rule : ' !has(self.containers) || self.containers.all(c, !has(c.volumeMounts)
676769 || c.volumeMounts.all(vm, has(self.volumes) && self.volumes.exists(v,
677770 v.name == vm.name)))'
771+ - message : container resources are only supported when sandboxClass is
772+ ' microvm'
773+ rule : ' !has(self.containers) || !self.containers.exists(c, has(c.resources))
774+ || (has(self.sandboxClass) && self.sandboxClass == '' microvm'' )'
678775 status :
679776 description : status is the observed state of ActorTemplate
680777 properties :
0 commit comments