9
9
from pathlib import Path
10
10
11
11
import structlog
12
+ from fc .util import nixos
12
13
from fc .util .directory import connect
14
+ from fc .util .time_date import utcnow
13
15
14
16
structlog = structlog .get_logger ()
15
17
@@ -112,15 +114,15 @@ def update_enc_nixos_config(log, enc, enc_path):
112
114
content = hashlib .sha256 (config .encode ("utf-8" )).hexdigest (),
113
115
)
114
116
target = os .path .join (basedir , filename )
115
- conditional_update (target , config , encode_json = False )
117
+ conditional_update (target , config , mode = 0o640 , encode_json = False )
116
118
os .chown (target , - 1 , sudo_srv )
117
119
previous_files -= {filename }
118
120
for filename in previous_files :
119
121
log .info ("remove-stale-enc-nixos-config" , filename = filename )
120
122
os .unlink (os .path .join (basedir , filename ))
121
123
122
124
123
- def conditional_update (filename , data , encode_json = True ):
125
+ def conditional_update (filename , data , mode = 0o640 , encode_json = True ):
124
126
"""Updates JSON file on disk only if there is different content."""
125
127
with tempfile .NamedTemporaryFile (
126
128
mode = "w" ,
@@ -134,7 +136,7 @@ def conditional_update(filename, data, encode_json=True):
134
136
else :
135
137
tf .write (data )
136
138
tf .write ("\n " )
137
- os .chmod (tf .fileno (), 0o640 )
139
+ os .chmod (tf .fileno (), mode )
138
140
if not (os .path .exists (filename )) or not (filecmp .cmp (filename , tf .name )):
139
141
with open (tf .name , "a" ) as f :
140
142
os .fsync (f .fileno ())
@@ -158,15 +160,15 @@ def inplace_update(filename, data):
158
160
os .fsync (f .fileno ())
159
161
160
162
161
- def retrieve (log , directory_lookup , tgt ):
163
+ def retrieve (log , func , tgt , mode = 0o640 ):
162
164
log .info ("retrieve-enc" , _replace_msg = "Getting: {tgt}" , tgt = tgt )
163
165
try :
164
- data = directory_lookup ()
166
+ data = func ()
165
167
except Exception :
166
168
log .error ("retrieve-enc-failed" , exc_info = True )
167
169
return
168
170
try :
169
- conditional_update ("/etc/nixos/{}" .format (tgt ), data )
171
+ conditional_update ("/etc/nixos/{}" .format (tgt ), data , mode )
170
172
except (IOError , OSError ):
171
173
inplace_update ("/etc/nixos/{}" .format (tgt ), data )
172
174
@@ -208,6 +210,32 @@ def load_system_state():
208
210
)
209
211
210
212
213
+ def get_release_info (log , enc ):
214
+ release_info_path = Path ("releases.json" )
215
+ if release_info_path .exists ():
216
+ with release_info_path .open () as f :
217
+ releases = json .load (f )
218
+ else :
219
+ releases = {}
220
+
221
+ params = enc ["parameters" ]
222
+ release_name = params .get ("release_name" )
223
+ known_releases = [r ["release_name" ] for r in releases .values ()]
224
+
225
+ if release_name and release_name not in known_releases :
226
+ environment_url = params ["environment_url" ]
227
+ version = nixos .channel_version (environment_url )
228
+ releases [version ] = {
229
+ "environment" : params ["environment" ],
230
+ "environment_url" : environment_url ,
231
+ "first_seen_at" : utcnow ().isoformat (),
232
+ "release_name" : release_name ,
233
+ "release_changelog" : params .get ("release_changelog" , "" ),
234
+ }
235
+
236
+ return releases
237
+
238
+
211
239
def update_inventory (log , enc ):
212
240
if (
213
241
not enc
@@ -250,6 +278,7 @@ def update_inventory(log, enc):
250
278
(lambda : directory .list_service_clients (), "service_clients.json" ),
251
279
(lambda : directory .list_services (), "services.json" ),
252
280
(lambda : directory .list_users (), "users.json" ),
281
+ (lambda : get_release_info (log , enc ), "releases.json" , 0o644 ),
253
282
],
254
283
)
255
284
0 commit comments