@@ -107,9 +107,28 @@ def __init__(self):
107
107
if self .config_json_location is None :
108
108
self .config_json_location = self .DEFAULT_FABRIC_CONFIG_JSON_LOCATION
109
109
110
- def create_config_dir (self ):
110
+ def create_config_dir (self , dir_only : bool = True ):
111
+ """
112
+ Create a configuration directory and optionally populate environment files.
113
+
114
+ This method creates a directory specified by `self.config_location` and optionally populates
115
+ environment files based on environment variables. It sets up necessary configurations for
116
+ Fabric operations including credentials, keys, logging settings, and SSH configurations.
117
+
118
+ :param dir_only: If True (default), only create the directory without populating environment files.
119
+ If False, populate environment files based on configured environment variables.
120
+ :type dir_only: bool
121
+ :raises Exception: If there is an error during directory creation or file writing.
122
+ """
111
123
try :
124
+ # Create the configuration directory
112
125
os .mkdir (self .config_location )
126
+
127
+ # If dir_only is True, return after creating the directory
128
+ if dir_only :
129
+ return
130
+
131
+ # Define environment variables with default or placeholder values
113
132
environment_vars = {
114
133
self .FABRIC_CREDMGR_HOST : os .environ [self .FABRIC_CREDMGR_HOST ],
115
134
self .FABRIC_ORCHESTRATOR_HOST : os .environ [self .FABRIC_ORCHESTRATOR_HOST ],
@@ -123,29 +142,38 @@ def create_config_dir(self):
123
142
self .FABRIC_LOG_LEVEL : self .DEFAULT_FABRIC_LOG_LEVEL ,
124
143
self .FABRIC_LOG_FILE : self .DEFAULT_FABRIC_LOG_FILE
125
144
}
145
+
146
+ # Prepare string to write to environment file
126
147
string_to_write = ""
127
148
for key , value in environment_vars .items ():
128
- if '<' in value and '>' :
129
- string_to_write += f"#export { key } ={ value } \n "
149
+ if '<' in value and '>' in value :
150
+ string_to_write += f"#export { key } ={ value } \n " # Placeholder value comment
130
151
else :
131
- string_to_write += f"export { key } ={ value } \n "
152
+ string_to_write += f"export { key } ={ value } \n " # Actual value
132
153
154
+ # Write environment file atomically
133
155
with atomic_write (f'{ self .config_location } /fabric_rc' , overwrite = True ) as f :
134
156
f .write (string_to_write )
135
157
136
- string_to_write = f"UserKnownHostsFile /dev/null\n " \
137
- f"StrictHostKeyChecking no\n " \
138
- f"ServerAliveInterval 120 \n " \
139
- f"Host bastion-?.fabric-testbed.net\n " \
140
- f"User <Update Bastion User Name>\n " \
141
- f"ForwardAgent yes\n " \
142
- f"Hostname %h\n " \
143
- f"IdentityFile { self .config_location } /{ os .environ [self .FABRIC_BASTION_PRIVATE_KEY_NAME ]} \n " \
144
- f"IdentitiesOnly yes\n " \
145
- f"Host * !bastion-?.fabric-testbed.net\n " \
146
- f"ProxyJump <Update Bastion User Name>@{ os .environ [self .FABRIC_BASTION_HOST ]} :22\n "
158
+ # Prepare SSH configuration string
159
+ ssh_config_string = (
160
+ f"UserKnownHostsFile /dev/null\n "
161
+ f"StrictHostKeyChecking no\n "
162
+ f"ServerAliveInterval 120 \n "
163
+ f"Host bastion-?.fabric-testbed.net\n "
164
+ f"User <Update Bastion User Name>\n "
165
+ f"ForwardAgent yes\n "
166
+ f"Hostname %h\n "
167
+ f"IdentityFile { self .config_location } /{ os .environ [self .FABRIC_BASTION_PRIVATE_KEY_NAME ]} \n "
168
+ f"IdentitiesOnly yes\n "
169
+ f"Host * !bastion-?.fabric-testbed.net\n "
170
+ f"ProxyJump <Update Bastion User Name>@{ os .environ [self .FABRIC_BASTION_HOST ]} :22\n "
171
+ )
172
+
173
+ # Write SSH configuration file atomically
147
174
with atomic_write (f'{ self .config_location } /ssh_config' , overwrite = True ) as f :
148
- f .write (string_to_write )
175
+ f .write (ssh_config_string )
176
+
149
177
except Exception as e :
150
178
print ("Failed to create config directory and default environment file" )
151
179
print ("Exception: " + str (e ))
@@ -269,36 +297,40 @@ def update_permissions(self):
269
297
"""
270
298
if not os .path .exists (f"{ self .config_location } /fabric_rc" ):
271
299
return
272
- # Open the file in read mode
273
- with open (f"{ self .config_location } /fabric_rc" , 'r' ) as file :
274
- # Read the content of the file
275
- content = file .read ()
276
-
277
- # Split the content into lines
278
- lines = content .splitlines ()
279
-
280
- # Process each line to extract the environment variable and its value
281
- for line in lines :
282
- # Ignore empty lines or lines starting with '#' (comments)
283
- if line .strip () == '' or line .strip ().startswith ('#' ):
284
- continue
285
-
286
- # Split each line into variable and value using the first occurrence of '='
287
- variable , value = line .split ('=' , 1 )
288
- variable = variable .replace ("export" , "" )
289
-
290
- # Remove leading/trailing whitespaces from the variable and value
291
- variable = variable .strip ()
292
- value = value .strip ()
293
-
294
- if variable in [self .FABRIC_BASTION_KEY_LOCATION , self .FABRIC_SLICE_PRIVATE_KEY_FILE ]:
295
- if os .path .exists (value ):
296
- os .chmod (value , 0o600 )
297
- elif variable in [self .FABRIC_SLICE_PUBLIC_KEY_FILE ]:
298
- if os .path .exists (value ):
299
- os .chmod (value , 0o644 )
300
-
301
- def initialize (self ):
300
+ try :
301
+ # Open the file in read mode
302
+ with open (f"{ self .config_location } /fabric_rc" , 'r' ) as file :
303
+ # Read the content of the file
304
+ content = file .read ()
305
+
306
+ # Split the content into lines
307
+ lines = content .splitlines ()
308
+
309
+ # Process each line to extract the environment variable and its value
310
+ for line in lines :
311
+ # Ignore empty lines or lines starting with '#' (comments)
312
+ if line .strip () == '' or line .strip ().startswith ('#' ):
313
+ continue
314
+
315
+ # Split each line into variable and value using the first occurrence of '='
316
+ variable , value = line .split ('=' , 1 )
317
+ variable = variable .replace ("export" , "" )
318
+
319
+ # Remove leading/trailing whitespaces from the variable and value
320
+ variable = variable .strip ()
321
+ value = value .strip ()
322
+
323
+ if variable in [self .FABRIC_BASTION_KEY_LOCATION , self .FABRIC_SLICE_PRIVATE_KEY_FILE ]:
324
+ if os .path .exists (value ):
325
+ os .chmod (value , 0o600 )
326
+ elif variable in [self .FABRIC_SLICE_PUBLIC_KEY_FILE ]:
327
+ if os .path .exists (value ):
328
+ os .chmod (value , 0o644 )
329
+ except Exception as e :
330
+ print (f"Exception occurred while updating permissions: { e } " )
331
+ traceback .print_exc ()
332
+
333
+ def initialize (self , sliver_keys : bool = False ):
302
334
"""
303
335
Initialize Jupyter Notebook Container
304
336
"""
@@ -310,7 +342,7 @@ def initialize(self):
310
342
311
343
if not os .path .exists (self .config_location ):
312
344
print ("Creating config directory and all files" )
313
- self .create_config_dir ()
345
+ self .create_config_dir (dir_only = True )
314
346
315
347
if not os .path .exists (self .requirements_location ):
316
348
print ("Creating default requirements.txt" )
@@ -324,28 +356,30 @@ def initialize(self):
324
356
self .download_notebooks ()
325
357
326
358
# Create SSH Keys
327
- ssh_key = FABRICSSHKey .generate (comment = "fabric@localhost" , algorithm = "rsa" )
328
- with atomic_write (f'{ self .DEFAULT_PRIVATE_SSH_KEY } ' , overwrite = True ) as f :
329
- f .write (ssh_key .private_key )
330
- with atomic_write (f'{ self .DEFAULT_PUBLIC_SSH_KEY } ' , overwrite = True ) as f :
331
- f .write (f'{ ssh_key .name } { ssh_key .public_key } { ssh_key .comment } ' )
332
-
333
- # Default key in config directory
334
- default_slice_priv_key_config = f'{ self .config_location } /{ os .environ [self .FABRIC_SLICE_PRIVATE_KEY_NAME ]} '
335
- default_slice_pub_key_config = f'{ self .config_location } /{ os .environ [self .FABRIC_SLICE_PUBLIC_KEY_NAME ]} '
336
-
337
- if not os .path .exists (default_slice_priv_key_config ):
338
- with atomic_write (default_slice_priv_key_config , overwrite = True ) as f :
359
+ # This is now made optional as JH notebook takes care of key creation
360
+ if sliver_keys :
361
+ ssh_key = FABRICSSHKey .generate (comment = "fabric@localhost" , algorithm = "rsa" )
362
+ with atomic_write (f'{ self .DEFAULT_PRIVATE_SSH_KEY } ' , overwrite = True ) as f :
339
363
f .write (ssh_key .private_key )
340
-
341
- if not os .path .exists (default_slice_pub_key_config ):
342
- with atomic_write (default_slice_pub_key_config , overwrite = True ) as f :
364
+ with atomic_write (f'{ self .DEFAULT_PUBLIC_SSH_KEY } ' , overwrite = True ) as f :
343
365
f .write (f'{ ssh_key .name } { ssh_key .public_key } { ssh_key .comment } ' )
344
366
345
- os .chmod (self .DEFAULT_PRIVATE_SSH_KEY , 0o600 )
346
- os .chmod (self .DEFAULT_PUBLIC_SSH_KEY , 0o644 )
347
- os .chmod (default_slice_priv_key_config , 0o600 )
348
- os .chmod (default_slice_pub_key_config , 0o644 )
367
+ # Default key in config directory
368
+ default_slice_priv_key_config = f'{ self .config_location } /{ os .environ [self .FABRIC_SLICE_PRIVATE_KEY_NAME ]} '
369
+ default_slice_pub_key_config = f'{ self .config_location } /{ os .environ [self .FABRIC_SLICE_PUBLIC_KEY_NAME ]} '
370
+
371
+ if not os .path .exists (default_slice_priv_key_config ):
372
+ with atomic_write (default_slice_priv_key_config , overwrite = True ) as f :
373
+ f .write (ssh_key .private_key )
374
+
375
+ if not os .path .exists (default_slice_pub_key_config ):
376
+ with atomic_write (default_slice_pub_key_config , overwrite = True ) as f :
377
+ f .write (f'{ ssh_key .name } { ssh_key .public_key } { ssh_key .comment } ' )
378
+
379
+ os .chmod (self .DEFAULT_PRIVATE_SSH_KEY , 0o600 )
380
+ os .chmod (self .DEFAULT_PUBLIC_SSH_KEY , 0o644 )
381
+ os .chmod (default_slice_priv_key_config , 0o600 )
382
+ os .chmod (default_slice_pub_key_config , 0o644 )
349
383
350
384
self .update_permissions ()
351
385
self .custom_install_packages ()
0 commit comments