@@ -16,6 +16,7 @@ import (
1616 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1717 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1818 "k8s.io/apimachinery/pkg/runtime"
19+ "k8s.io/apimachinery/pkg/runtime/schema"
1920 "k8s.io/utils/ptr"
2021 "sigs.k8s.io/yaml"
2122)
@@ -25,7 +26,8 @@ const (
2526 defaultMustGatherImage = "registry.redhat.io/openshift4/ose-must-gather:latest"
2627 defaultGatherCmd = "/usr/bin/gather"
2728 // annotation to look for in ClusterServiceVersions and ClusterOperators when using --all-images
28- mgAnnotation = "operators.openshift.io/must-gather-image"
29+ mgAnnotation = "operators.openshift.io/must-gather-image"
30+ maxConcurrentGathers = 8
2931)
3032
3133func initMustGatherPlan (o internalk8s.Openshift ) []api.ServerTool {
@@ -153,6 +155,23 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
153155 images = args ["images" ].([]string )
154156 }
155157
158+ if allImages {
159+ componentImages , err := getComponentImages (params )
160+ if err != nil {
161+ return api .NewToolCallResult ("" ,
162+ fmt .Errorf ("failed to get operator images: %v" , err ),
163+ ), nil
164+ }
165+
166+ images = append (images , componentImages ... )
167+ }
168+
169+ if len (images ) > maxConcurrentGathers {
170+ return api .NewToolCallResult ("" ,
171+ fmt .Errorf ("more than %d gather images are not supported" , maxConcurrentGathers ),
172+ ), nil
173+ }
174+
156175 if args ["timeout" ] != nil {
157176 timeout = args ["timeout" ].(string )
158177
@@ -181,6 +200,8 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
181200 })
182201 }
183202
203+ // template container for gather,
204+ // if multiple images are added multiple containers in the same pod will be spin up
184205 gatherContainerTemplate := corev1.Container {
185206 Name : "gather" ,
186207 Image : defaultMustGatherImage ,
@@ -189,24 +210,24 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
189210 Env : envVars ,
190211 VolumeMounts : []corev1.VolumeMount {
191212 {
192- Name : "must-gather-collection " ,
213+ Name : "must-gather-output " ,
193214 MountPath : sourceDir ,
194215 },
195216 },
196217 }
197218
198219 gatherContainers := make ([]corev1.Container , 1 )
199220 gatherContainers [0 ] = * gatherContainerTemplate .DeepCopy ()
221+
200222 for i , image := range images {
201223 gatherContainers [i ] = * gatherContainerTemplate .DeepCopy ()
202- gatherContainers [i ].Image = image
203- }
204224
205- if allImages {
206- // TODO: list each ClusterOperator object and check for mgAnnotation
207- // TODO: list each ClusterServiceVersion object (OLM operators) and check for mgAnnotation
208- _ = allImages
209- _ = mgAnnotation
225+ // if more than one gather container(s) are added,
226+ // suffix container name with int id
227+ if len (images ) > 1 {
228+ gatherContainers [i ].Name = fmt .Sprintf ("gather-%d" , i + 1 )
229+ }
230+ gatherContainers [i ].Image = image
210231 }
211232
212233 serviceAccountName := "must-gather-collector"
@@ -223,7 +244,7 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
223244 RestartPolicy : corev1 .RestartPolicyNever ,
224245 Volumes : []corev1.Volume {
225246 {
226- Name : "must-gather-collection " ,
247+ Name : "must-gather-output " ,
227248 VolumeSource : corev1.VolumeSource {
228249 EmptyDir : & corev1.EmptyDirVolumeSource {},
229250 },
@@ -236,7 +257,7 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
236257 Command : []string {"/bin/bash" , "-c" , "sleep infinity" },
237258 VolumeMounts : []corev1.VolumeMount {
238259 {
239- Name : "must-gather-collection " ,
260+ Name : "must-gather-output " ,
240261 MountPath : "/must-gather" ,
241262 },
242263 },
@@ -369,6 +390,49 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
369390 return api .NewToolCallResult (result .String (), nil ), nil
370391}
371392
393+ func getComponentImages (params api.ToolHandlerParams ) ([]string , error ) {
394+ var images []string
395+ appendImageFromAnnotation := func (obj runtime.Object ) error {
396+ unstruct , err := runtime .DefaultUnstructuredConverter .ToUnstructured (obj )
397+ if err != nil {
398+ return err
399+ }
400+
401+ u := unstructured.Unstructured {Object : unstruct }
402+ annotations := u .GetAnnotations ()
403+ if annotations [mgAnnotation ] != "" {
404+ images = append (images , annotations [mgAnnotation ])
405+ }
406+
407+ return nil
408+ }
409+
410+ clusterOperatorsList , err := params .ResourcesList (params , & schema.GroupVersionKind {
411+ Group : "config.openshift.io" ,
412+ Version : "v1" ,
413+ Kind : "ClusterOperator" ,
414+ }, "" , internalk8s.ResourceListOptions {})
415+ if err != nil {
416+ return nil , err
417+ }
418+
419+ if err := clusterOperatorsList .EachListItem (appendImageFromAnnotation ); err != nil {
420+ return images , err
421+ }
422+
423+ csvList , err := params .ResourcesList (params , & schema.GroupVersionKind {
424+ Group : "operators.coreos.com" ,
425+ Version : "v1alpha1" ,
426+ Kind : "ClusterServiceVersion" ,
427+ }, "" , internalk8s.ResourceListOptions {})
428+ if err != nil {
429+ return images , err
430+ }
431+
432+ err = csvList .EachListItem (appendImageFromAnnotation )
433+ return images , err
434+ }
435+
372436func generateRandomString (length int ) string {
373437 r := strings .ToLower (rand .Text ())
374438 if length > len (r ) {
0 commit comments