1+ import base64
12import hashlib
23import json
34import os
@@ -129,14 +130,13 @@ def flash( # noqa: C901
129130 oci_username : str | None = None ,
130131 oci_password : str | None = None ,
131132 ):
133+ """Flash image to DUT"""
132134 if bearer_token :
133135 bearer_token = self ._validate_bearer_token (bearer_token )
134136
135137 if headers :
136138 headers = self ._validate_header_dict (headers )
137- oci_username , oci_password = self ._validate_oci_credentials (oci_username , oci_password )
138-
139- """Flash image to DUT"""
139+ oci_username , oci_password = self ._resolve_oci_credentials (path , oci_username , oci_password )
140140 should_download_to_httpd = True
141141 image_url = ""
142142 original_http_url = None
@@ -653,7 +653,7 @@ def _flash_with_fls(
653653
654654 # Flash the image
655655 creds_file = None
656- with self ._redaction_scope ([oci_username , oci_password ]):
656+ with self ._redaction_scope ([oci_password ]):
657657 if str (path ).startswith ("oci://" ) and oci_username :
658658 creds_file = self ._setup_fls_oci_credential_file (console , prompt , oci_username , oci_password or "" )
659659
@@ -664,12 +664,8 @@ def _flash_with_fls(
664664 )
665665 console .sendline (flash_cmd )
666666
667- try :
668- # Start monitoring the flash operation
669- self ._monitor_fls_progress (console , prompt )
670- finally :
671- if creds_file :
672- self ._cleanup_fls_oci_credential_file (console , prompt , creds_file )
667+ # Start monitoring the flash operation
668+ self ._monitor_fls_progress (console , prompt )
673669
674670 self .logger .info ("Flushing buffers" )
675671 console .sendline ("sync" )
@@ -1304,12 +1300,24 @@ def _validate_oci_credentials(
13041300
13051301 if bool (username ) != bool (password ):
13061302 raise click .ClickException (
1307- "OCI authentication requires both --oci-username and --oci-password "
1308- "(or OCI_USERNAME and OCI_PASSWORD environment variables )"
1303+ "OCI authentication requires both OCI_USERNAME and OCI_PASSWORD "
1304+ "environment variables (or both oci_username and oci_password arguments )"
13091305 )
13101306
13111307 return username , password
13121308
1309+ def _resolve_oci_credentials (
1310+ self , path : PathBuf , username : str | None , password : str | None
1311+ ) -> tuple [str | None , str | None ]:
1312+ if username is None and password is None and path .startswith ("oci://" ):
1313+ username = os .environ .get ("OCI_USERNAME" )
1314+ password = os .environ .get ("OCI_PASSWORD" )
1315+
1316+ if username or password :
1317+ self .logger .info ("Using OCI registry credentials from environment variables" )
1318+
1319+ return self ._validate_oci_credentials (username , password )
1320+
13131321 def _fls_oci_auth_env (self , path : PathBuf , creds_file : str | None ) -> str :
13141322 if not str (path ).startswith ("oci://" ) or not creds_file :
13151323 return ""
@@ -1345,20 +1353,35 @@ def _temporarily_disable_console_debug_stream(self, console):
13451353 def _setup_fls_oci_credential_file (
13461354 self , console , prompt : str , oci_username : str , oci_password : str , creds_file : str = "/tmp/fls_creds"
13471355 ) -> str :
1356+ # Write credential file using base64-encoded chunks to avoid serial
1357+ # console line buffer overflow with long tokens (e.g. 1400+ char JWTs).
1358+ creds_content = (
1359+ f"FLS_REGISTRY_USERNAME={ shlex .quote (oci_username )} \n "
1360+ f"FLS_REGISTRY_PASSWORD={ shlex .quote (oci_password )} \n "
1361+ )
1362+ encoded = base64 .b64encode (creds_content .encode ()).decode ()
1363+
1364+ chunk_size = 512
13481365 with self ._temporarily_disable_console_debug_stream (console ):
1349- console .sendline (f"umask 077 && cat > { shlex .quote (creds_file )} <<'EOF_FLS_CREDS'" )
1350- console .sendline (f"FLS_REGISTRY_USERNAME={ shlex .quote (oci_username )} " )
1351- console .sendline (f"FLS_REGISTRY_PASSWORD={ shlex .quote (oci_password )} " )
1352- console .sendline ("EOF_FLS_CREDS" )
1366+ console .sendline (f"true > { shlex .quote (creds_file )} " )
13531367 console .expect (prompt , timeout = EXPECT_TIMEOUT_DEFAULT )
1354- console .sendline (f"chmod 600 { shlex .quote (creds_file )} " )
1368+
1369+ # Write base64 data in chunks to a temp file
1370+ b64_file = f"{ creds_file } .b64"
1371+ console .sendline (f"true > { shlex .quote (b64_file )} " )
13551372 console .expect (prompt , timeout = EXPECT_TIMEOUT_DEFAULT )
1356- return creds_file
13571373
1358- def _cleanup_fls_oci_credential_file (self , console , prompt : str , creds_file : str ):
1359- with self ._temporarily_disable_console_debug_stream (console ):
1360- console .sendline (f"rm -f { shlex .quote (creds_file )} " )
1374+ for i in range (0 , len (encoded ), chunk_size ):
1375+ chunk = encoded [i : i + chunk_size ]
1376+ console .sendline (f"printf '%s' { shlex .quote (chunk )} >> { shlex .quote (b64_file )} " )
1377+ console .expect (prompt , timeout = EXPECT_TIMEOUT_DEFAULT )
1378+
1379+ # Decode into the actual creds file
1380+ console .sendline (f"base64 -d { shlex .quote (b64_file )} > { shlex .quote (creds_file )} " )
13611381 console .expect (prompt , timeout = EXPECT_TIMEOUT_DEFAULT )
1382+ console .sendline (f"chmod 600 { shlex .quote (creds_file )} " )
1383+ console .expect (prompt , timeout = EXPECT_TIMEOUT_DEFAULT )
1384+ return creds_file
13621385
13631386 def _resolve_flash_parameters (
13641387 self , file : str | None , partitions : tuple [str , ...] | None , block_device : str | None
@@ -1425,6 +1448,7 @@ def _resolve_flash_parameters(
14251448
14261449 return flash_ops
14271450
1451+
14281452 def cli (self ):
14291453 @driver_click_group (self )
14301454 def base ():
@@ -1465,18 +1489,6 @@ def base():
14651489 type = str ,
14661490 help = "Bearer token for HTTP authentication" ,
14671491 )
1468- @click .option (
1469- "--oci-username" ,
1470- type = str ,
1471- envvar = "OCI_USERNAME" ,
1472- help = "OCI registry username (or OCI_USERNAME environment variable)" ,
1473- )
1474- @click .option (
1475- "--oci-password" ,
1476- type = str ,
1477- envvar = "OCI_PASSWORD" ,
1478- help = "OCI registry password (or OCI_PASSWORD environment variable)" ,
1479- )
14801492 @click .option (
14811493 "--retries" ,
14821494 type = int ,
@@ -1514,8 +1526,6 @@ def flash(
15141526 insecure_tls ,
15151527 header ,
15161528 bearer ,
1517- oci_username ,
1518- oci_password ,
15191529 retries ,
15201530 method ,
15211531 fls_version ,
@@ -1576,8 +1586,6 @@ def flash(
15761586 insecure_tls = insecure_tls ,
15771587 headers = headers_dict ,
15781588 bearer_token = bearer ,
1579- oci_username = oci_username ,
1580- oci_password = oci_password ,
15811589 retries = retries ,
15821590 method = method ,
15831591 fls_version = fls_version ,
0 commit comments