1/*
2Copyright 2014 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package container
18
19import (
20	"fmt"
21	"time"
22
23	"k8s.io/klog/v2"
24)
25
26// GCPolicy specifies a policy for garbage collecting containers.
27type GCPolicy struct {
28	// Minimum age at which a container can be garbage collected, zero for no limit.
29	MinAge time.Duration
30
31	// Max number of dead containers any single pod (UID, container name) pair is
32	// allowed to have, less than zero for no limit.
33	MaxPerPodContainer int
34
35	// Max number of total dead containers, less than zero for no limit.
36	MaxContainers int
37}
38
39// GC manages garbage collection of dead containers.
40//
41// Implementation is thread-compatible.
42type GC interface {
43	// Garbage collect containers.
44	GarbageCollect() error
45	// Deletes all unused containers, including containers belonging to pods that are terminated but not deleted
46	DeleteAllUnusedContainers() error
47}
48
49// SourcesReadyProvider knows how to determine if configuration sources are ready
50type SourcesReadyProvider interface {
51	// AllReady returns true if the currently configured sources have all been seen.
52	AllReady() bool
53}
54
55// TODO(vmarmol): Preferentially remove pod infra containers.
56type realContainerGC struct {
57	// Container runtime
58	runtime Runtime
59
60	// Policy for garbage collection.
61	policy GCPolicy
62
63	// sourcesReadyProvider provides the readiness of kubelet configuration sources.
64	sourcesReadyProvider SourcesReadyProvider
65}
66
67// NewContainerGC creates a new instance of GC with the specified policy.
68func NewContainerGC(runtime Runtime, policy GCPolicy, sourcesReadyProvider SourcesReadyProvider) (GC, error) {
69	if policy.MinAge < 0 {
70		return nil, fmt.Errorf("invalid minimum garbage collection age: %v", policy.MinAge)
71	}
72
73	return &realContainerGC{
74		runtime:              runtime,
75		policy:               policy,
76		sourcesReadyProvider: sourcesReadyProvider,
77	}, nil
78}
79
80func (cgc *realContainerGC) GarbageCollect() error {
81	return cgc.runtime.GarbageCollect(cgc.policy, cgc.sourcesReadyProvider.AllReady(), false)
82}
83
84func (cgc *realContainerGC) DeleteAllUnusedContainers() error {
85	klog.InfoS("Attempting to delete unused containers")
86	return cgc.runtime.GarbageCollect(cgc.policy, cgc.sourcesReadyProvider.AllReady(), true)
87}
88