1
1
import os
2
- import json
3
- import grpc
2
+ import asyncio
4
3
import math
5
4
import logging
6
5
import argparse
7
6
from github import Github
8
- from datetime import datetime , timezone
9
- from nebius .compute .v1 .image_pb2 import Image , ImageStatus
10
- from nebius .compute .v1 .image_service_pb2 import ListImagesRequest
7
+ from nebius .sdk import SDK
8
+ from nebius .aio .service_error import RequestError
9
+ from nebius .api .nebius .compute .v1 import (
10
+ ListImagesRequest ,
11
+ ImageServiceClient ,
12
+ )
11
13
12
- from nebius . compute . v1 . image_service_pb2_grpc import ImageServiceStub
13
- import nebius . compute . v1 . image_service_pb2 as image_service_pb2
14
- from nebiusai import SDK , RetryInterceptor , backoff_linear_with_jitter
14
+ SENSITIVE_DATA_VALUES = {}
15
+ if os . environ . get ( "GITHUB_TOKEN" ):
16
+ SENSITIVE_DATA_VALUES [ "github_token" ] = os . environ . get ( "GITHUB_TOKEN" )
15
17
16
- logging .basicConfig (
17
- level = logging .INFO , format = "%(asctime)s: %(levelname)s: %(message)s"
18
- )
19
- logger = logging .getLogger (__name__ )
18
+
19
+ class MaskingFormatter (logging .Formatter ):
20
+ @staticmethod
21
+ def mask_sensitive_data (msg ):
22
+ # Iterate over the patterns and replace sensitive data with '***'
23
+ for pattern_name , pattern in SENSITIVE_DATA_VALUES .items ():
24
+ msg = msg .replace (pattern , f"[{ pattern_name } =***]" )
25
+ return msg
26
+
27
+ def format (self , record ):
28
+ original = logging .Formatter .format (self , record )
29
+ return self .mask_sensitive_data (original )
30
+
31
+
32
+ formatter = MaskingFormatter ("%(asctime)s: %(levelname)s: %(message)s" )
33
+ console_handler = logging .StreamHandler ()
34
+ console_handler .setLevel (logging .INFO )
35
+ console_handler .setFormatter (formatter )
36
+
37
+ logger = logging .getLogger ()
38
+ logger .addHandler (console_handler )
39
+ logger .setLevel (logging .INFO )
20
40
21
41
# they won't appear in the list of images
22
42
# but they will be protected from deletion anyway
25
45
]
26
46
27
47
28
- def status_to_string (image : Image ) -> str :
29
- return ImageStatus .State .Name (image .status .state )
30
-
31
-
32
48
def convert_size (size_bytes ):
33
49
if size_bytes == 0 :
34
50
return "0 B"
@@ -39,7 +55,7 @@ def convert_size(size_bytes):
39
55
return f"{ s } { size_name [i ]} "
40
56
41
57
42
- def main (
58
+ async def main (
43
59
sdk : SDK ,
44
60
github_token : str ,
45
61
github_repository : str ,
@@ -68,19 +84,21 @@ def main(
68
84
else :
69
85
logger .info ("Would set %s (new) = %s" , image_variable_name , new_image_id )
70
86
87
+ service = ImageServiceClient (sdk )
71
88
request = ListImagesRequest (
72
89
parent_id = parent_id ,
73
90
filter = f"family IN ('{ image_family_name } ') AND status = 'READY'" ,
74
91
)
92
+ try :
93
+ response = await service .list (request )
94
+ except RequestError as e :
95
+ logger .error ("Failed to list images: %s" , e )
96
+ return
75
97
76
- client = sdk .client (image_service_pb2 , ImageServiceStub )
77
- response = client .List (request )
78
98
candidate_images = []
79
99
for image in response .items :
80
- status = status_to_string (image )
81
- created_at = datetime .fromtimestamp (
82
- image .metadata .created_at .seconds , tz = timezone .utc
83
- )
100
+ status = image .status .state .name
101
+ created_at = image .metadata .created_at
84
102
storage_size = convert_size (image .status .storage_size_bytes )
85
103
min_disk_size = convert_size (image .status .min_disk_size_bytes )
86
104
prefix = " (PROTECTED)"
@@ -158,25 +176,15 @@ def main(
158
176
args = parser .parse_args ()
159
177
logger .info (args )
160
178
161
- interceptor = RetryInterceptor (
162
- max_retry_count = 30 ,
163
- retriable_codes = [grpc .StatusCode .UNAVAILABLE ],
164
- back_off_func = backoff_linear_with_jitter (5 , 0 ),
165
- )
166
-
167
- with open (args .service_account_key , "r" ) as fp :
168
- sdk = SDK (
169
- service_account_key = json .load (fp ),
170
- endpoint = args .api_endpoint ,
171
- interceptor = interceptor ,
179
+ sdk = SDK (credentials_file_name = args .service_account_key )
180
+ asyncio .run (
181
+ main (
182
+ sdk = sdk ,
183
+ github_token = args .github_token ,
184
+ github_repository = args .github_repo ,
185
+ new_image_id = args .new_image_id ,
186
+ image_variable_name = args .image_variable_name ,
187
+ update_image_id = args .update_image_id ,
188
+ parent_id = args .parent_id ,
172
189
)
173
-
174
- main (
175
- sdk = sdk ,
176
- github_token = args .github_token ,
177
- github_repository = args .github_repo ,
178
- new_image_id = args .new_image_id ,
179
- image_variable_name = args .image_variable_name ,
180
- update_image_id = args .update_image_id ,
181
- parent_id = args .parent_id ,
182
190
)
0 commit comments