Skip to content

Commit

Permalink
feat(cleanup): more logging for saved images
Browse files Browse the repository at this point in the history
Log reason why image being saved: it is either reached by the Git-History based policy, or it is used in the Kubernetes cluster, or it is parent of image being used in the Kubernetes cluster

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed Mar 9, 2023
1 parent edba555 commit 0bda54d
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 89 deletions.
152 changes: 101 additions & 51 deletions pkg/cleaning/allow_list/kubernetes.go
Expand Up @@ -13,70 +13,93 @@ import (
"github.com/werf/logboek"
)

func DeployedDockerImages(ctx context.Context, kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var deployedDockerImages []string
type DeployedImage struct {
Name string
ResourcesNames []string
}

func AppendDeployedImages(deployedImages []*DeployedImage, newDeployedImages ...*DeployedImage) (res []*DeployedImage) {
for _, desc := range deployedImages {
res = append(res, &DeployedImage{
Name: desc.Name,
ResourcesNames: desc.ResourcesNames,
})
}

AppendNewImages:
for _, newDesc := range newDeployedImages {
for _, desc := range res {
if desc.Name == newDesc.Name {
desc.ResourcesNames = append(desc.ResourcesNames, newDesc.ResourcesNames...)
continue AppendNewImages
}
}

res = append(res, &DeployedImage{
Name: newDesc.Name,
ResourcesNames: newDesc.ResourcesNames,
})
}

return
}

func DeployedDockerImages(ctx context.Context, kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var deployedDockerImages []*DeployedImage

images, err := getPodsImages(kubernetesClient, kubernetesNamespace)
if err != nil {
return nil, fmt.Errorf("cannot get Pods images: %w", err)
}

deployedDockerImages = append(deployedDockerImages, images...)
deployedDockerImages = AppendDeployedImages(deployedDockerImages, images...)

images, err = getReplicationControllersImages(kubernetesClient, kubernetesNamespace)
if err != nil {
return nil, fmt.Errorf("cannot get ReplicationControllers images: %w", err)
}

deployedDockerImages = append(deployedDockerImages, images...)
deployedDockerImages = AppendDeployedImages(deployedDockerImages, images...)

images, err = getDeploymentsImages(kubernetesClient, kubernetesNamespace)
if err != nil {
return nil, fmt.Errorf("cannot get Deployments images: %w", err)
}

deployedDockerImages = append(deployedDockerImages, images...)
deployedDockerImages = AppendDeployedImages(deployedDockerImages, images...)

images, err = getStatefulSetsImages(kubernetesClient, kubernetesNamespace)
if err != nil {
return nil, fmt.Errorf("cannot get StatefulSets images: %w", err)
}

deployedDockerImages = append(deployedDockerImages, images...)
deployedDockerImages = AppendDeployedImages(deployedDockerImages, images...)

images, err = getDaemonSetsImages(kubernetesClient, kubernetesNamespace)
if err != nil {
return nil, fmt.Errorf("cannot get DaemonSets images: %w", err)
}

deployedDockerImages = append(deployedDockerImages, images...)
deployedDockerImages = AppendDeployedImages(deployedDockerImages, images...)

images, err = getReplicaSetsImages(kubernetesClient, kubernetesNamespace)
if err != nil {
return nil, fmt.Errorf("cannot get ReplicaSets images: %w", err)
}

deployedDockerImages = append(deployedDockerImages, images...)
deployedDockerImages = AppendDeployedImages(deployedDockerImages, images...)

images, err = getCronJobsImages(ctx, kubernetesClient, kubernetesNamespace)
if err != nil {
return nil, fmt.Errorf("cannot get CronJobs images: %w", err)
}

deployedDockerImages = append(deployedDockerImages, images...)
deployedDockerImages = AppendDeployedImages(deployedDockerImages, images...)

images, err = getJobsImages(ctx, kubernetesClient, kubernetesNamespace)
if err != nil {
return nil, fmt.Errorf("cannot get Jobs images: %w", err)
}

deployedDockerImages = append(deployedDockerImages, images...)
deployedDockerImages = AppendDeployedImages(deployedDockerImages, images...)

return deployedDockerImages, nil
}

func getPodsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getPodsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage
list, err := kubernetesClient.CoreV1().Pods(kubernetesNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
Expand All @@ -87,15 +110,18 @@ func getPodsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace st
pod.Spec.Containers,
pod.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s pod/%s container/%s", pod.Namespace, pod.Name, container.Name)},
})
}
}

return images, nil
}

func getReplicationControllersImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getReplicationControllersImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage
list, err := kubernetesClient.CoreV1().ReplicationControllers(kubernetesNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
Expand All @@ -106,15 +132,18 @@ func getReplicationControllersImages(kubernetesClient kubernetes.Interface, kube
replicationController.Spec.Template.Spec.Containers,
replicationController.Spec.Template.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s rc/%s container/%s", replicationController.Namespace, replicationController.Name, container.Name)},
})
}
}

return images, nil
}

func getDeploymentsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getDeploymentsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage
list, err := kubernetesClient.AppsV1().Deployments(kubernetesNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
Expand All @@ -125,15 +154,18 @@ func getDeploymentsImages(kubernetesClient kubernetes.Interface, kubernetesNames
deployment.Spec.Template.Spec.Containers,
deployment.Spec.Template.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s deploy/%s container/%s", deployment.Namespace, deployment.Name, container.Name)},
})
}
}

return images, nil
}

func getStatefulSetsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getStatefulSetsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage
list, err := kubernetesClient.AppsV1().StatefulSets(kubernetesNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
Expand All @@ -144,34 +176,40 @@ func getStatefulSetsImages(kubernetesClient kubernetes.Interface, kubernetesName
statefulSet.Spec.Template.Spec.Containers,
statefulSet.Spec.Template.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s sts/%s container/%s", statefulSet.Namespace, statefulSet.Name, container.Name)},
})
}
}

return images, nil
}

func getDaemonSetsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getDaemonSetsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage
list, err := kubernetesClient.AppsV1().DaemonSets(kubernetesNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
}

for _, daemonSets := range list.Items {
for _, daemonSet := range list.Items {
for _, container := range append(
daemonSets.Spec.Template.Spec.Containers,
daemonSets.Spec.Template.Spec.InitContainers...,
daemonSet.Spec.Template.Spec.Containers,
daemonSet.Spec.Template.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s ds/%s container/%s", daemonSet.Namespace, daemonSet.Name, container.Name)},
})
}
}

return images, nil
}

func getReplicaSetsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getReplicaSetsImages(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage
list, err := kubernetesClient.AppsV1().ReplicaSets(kubernetesNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
Expand All @@ -182,14 +220,17 @@ func getReplicaSetsImages(kubernetesClient kubernetes.Interface, kubernetesNames
replicaSet.Spec.Template.Spec.Containers,
replicaSet.Spec.Template.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s rs/%s container/%s", replicaSet.Namespace, replicaSet.Name, container.Name)},
})
}
}

return images, nil
}

func getCronJobsImages(ctx context.Context, kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
func getCronJobsImages(ctx context.Context, kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
images, err := getCronJobsImagesBatchV1(kubernetesClient, kubernetesNamespace)
if apierrors.IsNotFound(err) {
logboek.Context(ctx).Warn().LogF("\n")
Expand All @@ -203,8 +244,8 @@ func getCronJobsImages(ctx context.Context, kubernetesClient kubernetes.Interfac
return images, err
}

func getCronJobsImagesBatchV1(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getCronJobsImagesBatchV1(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage

list, err := kubernetesClient.BatchV1().CronJobs(kubernetesNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
Expand All @@ -216,15 +257,18 @@ func getCronJobsImagesBatchV1(kubernetesClient kubernetes.Interface, kubernetesN
cronJob.Spec.JobTemplate.Spec.Template.Spec.Containers,
cronJob.Spec.JobTemplate.Spec.Template.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s cronjob/%s container/%s", cronJob.Namespace, cronJob.Name, container.Name)},
})
}
}

return images, nil
}

func getCronJobsImagesBatchV1beta1(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getCronJobsImagesBatchV1beta1(kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage

list, err := kubernetesClient.BatchV1beta1().CronJobs(kubernetesNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
Expand All @@ -236,15 +280,18 @@ func getCronJobsImagesBatchV1beta1(kubernetesClient kubernetes.Interface, kubern
cronJob.Spec.JobTemplate.Spec.Template.Spec.Containers,
cronJob.Spec.JobTemplate.Spec.Template.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s cronjob/%s container/%s", cronJob.Namespace, cronJob.Name, container.Name)},
})
}
}

return images, nil
}

func getJobsImages(ctx context.Context, kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]string, error) {
var images []string
func getJobsImages(ctx context.Context, kubernetesClient kubernetes.Interface, kubernetesNamespace string) ([]*DeployedImage, error) {
var images []*DeployedImage
list, err := kubernetesClient.BatchV1().Jobs(kubernetesNamespace).List(ctx, metav1.ListOptions{})
if err != nil {
return nil, err
Expand All @@ -256,12 +303,12 @@ FindActiveJobs:
switch c.Type {
case batchv1.JobComplete:
if c.Status == corev1.ConditionTrue {
logboek.Context(ctx).Debug().LogF("Ignore complete job/%s: images in this resource are not used anymore and can be safely removed\n", job.Name)
logboek.Context(ctx).Info().LogF("Ignore complete job/%s: images in this resource are not used anymore and can be safely removed\n", job.Name)
continue FindActiveJobs
}
case batchv1.JobFailed:
if c.Status == corev1.ConditionTrue {
logboek.Context(ctx).Debug().LogF("Ignore failed job/%s: images in this resource are not used anymore and can be safely removed\n", job.Name)
logboek.Context(ctx).Info().LogF("Ignore failed job/%s: images in this resource are not used anymore and can be safely removed\n", job.Name)
continue FindActiveJobs
}
}
Expand All @@ -271,7 +318,10 @@ FindActiveJobs:
job.Spec.Template.Spec.Containers,
job.Spec.Template.Spec.InitContainers...,
) {
images = append(images, container.Image)
images = AppendDeployedImages(images, &DeployedImage{
Name: container.Image,
ResourcesNames: []string{fmt.Sprintf("ns/%s job/%s container/%s", job.Namespace, job.Name, container.Name)},
})
}
}

Expand Down

0 comments on commit 0bda54d

Please sign in to comment.