Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions Sources/cctl/ImageCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ extension Application {
})
var unpackPath: String?

@Flag(help: "Pull via plain text http") var http: Bool = false
@Flag(help: "Pull anonymously via plain-text HTTP.")
var http: Bool = false

func run() async throws {
let imageStore = Application.imageStore
Expand All @@ -124,7 +125,7 @@ extension Application {
}

var startTime = ContinuousClock.now
let image = try await Images.withAuthentication(ref: normalizedReference) { auth in
let image = try await Images.withAuthentication(ref: normalizedReference, insecure: http) { auth in
try await imageStore.pull(reference: normalizedReference, platform: platform, insecure: http, auth: auth)
}

Expand Down Expand Up @@ -177,7 +178,8 @@ extension Application {

@Option(help: "Platform string in the form 'os/arch/variant'. Example 'linux/arm64/v8', 'linux/amd64'") var platformString: String?

@Flag(help: "Push via plain text http") var http: Bool = false
@Flag(help: "Push anonymously via plain-text HTTP.")
var http: Bool = false

@Argument var ref: String

Expand All @@ -197,7 +199,7 @@ extension Application {
print("Reference resolved to \(reference.description)")
}

try await Images.withAuthentication(ref: normalizedReference) { auth in
try await Images.withAuthentication(ref: normalizedReference, insecure: http) { auth in
try await imageStore.push(reference: normalizedReference, platform: platform, insecure: http, auth: auth)
}
print("image pushed")
Expand Down Expand Up @@ -264,22 +266,26 @@ extension Application {
}

private static func withAuthentication<T>(
ref: String, _ body: @Sendable @escaping (_ auth: Authentication?) async throws -> T?
ref: String, insecure: Bool,
_ body: @Sendable @escaping (_ auth: Authentication?) async throws -> T?
) async throws -> T? {
var authentication: Authentication?
let ref = try Reference.parse(ref)
guard let host = ref.resolvedDomain else {
let parsed = try Reference.parse(ref)
guard let host = parsed.resolvedDomain else {
throw ContainerizationError(.invalidArgument, message: "no host specified in image reference")
}
authentication = Self.authenticationFromEnv(host: host)
if let authentication {
return try await body(authentication)
if insecure {
return try await body(nil)
}
if let auth = Self.authenticationFromEnv(host: host) {
return try await body(auth)
}
#if os(macOS)
let keychain = KeychainHelper(securityDomain: Application.keychainID)
authentication = try? keychain.lookup(hostname: host)
#endif
let authentication = try? keychain.lookup(hostname: host)
return try await body(authentication)
#else
return try await body(nil)
#endif
}

private static func authenticationFromEnv(host: String) -> Authentication? {
Expand Down
5 changes: 1 addition & 4 deletions Sources/cctl/LoginCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ extension Application {
@Argument(help: "Registry server name")
var server: String

@Flag(help: "Use plain text http to authenticate") var http: Bool = false

func run() async throws {
var username = self.username
var password = ""
Expand All @@ -65,10 +63,9 @@ extension Application {
}

let server = Reference.resolveDomain(domain: self.server)
let scheme = http ? "http" : "https"
let client = RegistryClient(
host: server,
scheme: scheme,
scheme: "https",
authentication: BasicAuthentication(username: username, password: password),
retryOptions: .init(
maxRetries: 10,
Expand Down
Loading