@@ -210,6 +210,11 @@ pub struct ImageProxyConfig {
210210 /// If set, disable TLS verification. Equivalent to `skopeo --tls-verify=false`.
211211 pub insecure_skip_tls_verification : Option < bool > ,
212212
213+ /// Prefix to add to the user agent string. Equivalent to `skopeo --user-agent-prefix`.
214+ /// The resulting user agent will be in the format "prefix skopeo/version".
215+ /// This option is only used if the installed skopeo version supports it.
216+ pub user_agent_prefix : Option < String > ,
217+
213218 /// If enabled, propagate debug-logging level from the proxy via stderr to the
214219 /// current process' stderr. Note than when enabled, this also means that standard
215220 /// error will no longer be captured.
@@ -238,6 +243,25 @@ pub struct ImageProxyConfig {
238243 pub skopeo_cmd : Option < Command > ,
239244}
240245
246+ /// Check if skopeo supports --user-agent-prefix by probing --help output
247+ fn supports_user_agent_prefix ( ) -> bool {
248+ static SUPPORTS_USER_AGENT : OnceLock < bool > = OnceLock :: new ( ) ;
249+ * SUPPORTS_USER_AGENT . get_or_init ( || {
250+ Command :: new ( "skopeo" )
251+ . arg ( "--help" )
252+ . stdout ( Stdio :: piped ( ) )
253+ . stderr ( Stdio :: null ( ) )
254+ . output ( )
255+ . ok ( )
256+ . and_then ( |output| {
257+ String :: from_utf8 ( output. stdout )
258+ . ok ( )
259+ . map ( |help| help. contains ( "--user-agent-prefix" ) )
260+ } )
261+ . unwrap_or ( false )
262+ } )
263+ }
264+
241265impl TryFrom < ImageProxyConfig > for Command {
242266 type Error = Error ;
243267
@@ -320,6 +344,15 @@ impl TryFrom<ImageProxyConfig> for Command {
320344 if config. insecure_skip_tls_verification . unwrap_or_default ( ) {
321345 c. arg ( "--tls-verify=false" ) ;
322346 }
347+
348+ // Add user agent prefix if provided and supported by skopeo
349+ if let Some ( user_agent_prefix) = config. user_agent_prefix {
350+ if supports_user_agent_prefix ( ) {
351+ c. arg ( "--user-agent-prefix" ) ;
352+ c. arg ( user_agent_prefix) ;
353+ }
354+ }
355+
323356 c. stdout ( Stdio :: null ( ) ) ;
324357 if !debug {
325358 c. stderr ( Stdio :: piped ( ) ) ;
@@ -853,6 +886,18 @@ mod tests {
853886 } )
854887 . unwrap ( ) ;
855888 validate ( c, & [ "--authfile" , "/proc/self/fd/100" ] , & [ ] ) ;
889+
890+ // Test user-agent-prefix - only validate if supported
891+ let c = Command :: try_from ( ImageProxyConfig {
892+ user_agent_prefix : Some ( "bootc/1.0" . to_string ( ) ) ,
893+ ..Default :: default ( )
894+ } )
895+ . unwrap ( ) ;
896+ if supports_user_agent_prefix ( ) {
897+ validate ( c, & [ "--user-agent-prefix" , "bootc/1.0" ] , & [ ] ) ;
898+ } else {
899+ validate ( c, & [ ] , & [ "--user-agent-prefix" ] ) ;
900+ }
856901 }
857902
858903 #[ tokio:: test]
0 commit comments