@@ -32,16 +32,17 @@ class KubernetesWaitForPodStatusState(Enum):
32
32
33
33
class KubernetesWaitForPodStatus (BaseAction ):
34
34
35
- def __init__ (self , within_cluster : bool ):
35
+ def __init__ (self , within_cluster : bool , namespace : str ):
36
36
super ().__init__ ()
37
37
self .target = None
38
- self .namespace = None
38
+ self .namespace = namespace
39
39
self .expected_status = None
40
40
self .within_cluster = within_cluster
41
41
self .regex = None
42
42
self .client = None
43
43
self .update_queue = queue .Queue ()
44
44
self .current_state = KubernetesWaitForPodStatusState .IDLE
45
+ self .last_state = None
45
46
46
47
def setup (self , ** kwargs ):
47
48
if self .within_cluster :
@@ -53,44 +54,50 @@ def setup(self, **kwargs):
53
54
self .monitoring_thread = threading .Thread (target = self .watch_pods , daemon = True )
54
55
self .monitoring_thread .start ()
55
56
56
- def execute (self , target : str , regex : bool , status : tuple , namespace : str ):
57
+ def execute (self , target : str , regex : bool , status : tuple , ):
57
58
self .target = target
58
- self .namespace = namespace
59
59
if not isinstance (status , tuple ) or not isinstance (status [0 ], str ):
60
60
raise ValueError ("Status expected to be enum." )
61
61
self .expected_status = status [0 ]
62
62
self .regex = regex
63
63
self .current_state = KubernetesWaitForPodStatusState .MONITORING
64
+ self .last_state = None
64
65
65
66
def update (self ) -> py_trees .common .Status :
66
67
while not self .update_queue .empty ():
67
68
item = self .update_queue .get ()
68
69
if len (item ) != 2 :
69
70
return py_trees .common .Status .FAILURE
70
-
71
- self .feedback_message = f"waiting for status of pod '{ self .target } '." # pylint: disable= attribute-defined-outside-init
71
+ if self . last_state is None :
72
+ self .feedback_message = f"waiting for status of pod '{ self .target } '." # pylint: disable= attribute-defined-outside-init
72
73
if not self .regex :
73
74
if item [0 ] != self .target :
74
75
continue
75
76
else :
76
77
if not re .search (self .target , item [0 ]):
77
78
continue
78
- if item [1 ].lower () == self .expected_status :
79
+ if item [1 ].lower () == self .expected_status and self . last_state is not None :
79
80
self .feedback_message = f"Pod '{ item [0 ]} ' changed to expected status '{ item [1 ].lower ()} '." # pylint: disable= attribute-defined-outside-init
81
+ self .current_state = KubernetesWaitForPodStatusState .IDLE
80
82
return py_trees .common .Status .SUCCESS
81
83
else :
82
84
self .feedback_message = f"Pod '{ item [0 ]} ' changed to status '{ item [1 ].lower ()} ', expected '{ self .expected_status } '." # pylint: disable= attribute-defined-outside-init
85
+ self .last_state = item [1 ].lower ()
83
86
return py_trees .common .Status .RUNNING
84
87
85
88
def watch_pods (self ):
86
89
w = watch .Watch ()
87
90
try :
88
- # TODO: make use of send_initial_events=false in the future
91
+ initial_pods = self .client .list_namespaced_pod (namespace = self .namespace ).items
92
+ for pod in initial_pods :
93
+ pod_name = pod .metadata .name
94
+ pod_status = pod .status .phase
95
+ self .update_queue .put ((pod_name , pod_status ))
89
96
for event in w .stream (self .client .list_namespaced_pod , namespace = self .namespace ):
90
97
pod_name = event ['object' ].metadata .name
91
98
pod_status = event ['object' ].status .phase
92
99
if self .current_state == KubernetesWaitForPodStatusState .MONITORING :
93
100
self .update_queue .put ((pod_name , pod_status ))
94
101
except ApiException as e :
95
- self .logger .error (f"Error accessing kubernetes : { e } " )
102
+ self .logger .error (f"Error accessing Kubernetes : { e } " )
96
103
self .update_queue .put (())
0 commit comments