From 842052f5bdca8cf29cc4afd99bdb537f8d88b7cb Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Tue, 20 Feb 2024 00:19:24 +0400 Subject: [PATCH 1/3] tart pull: experimental --json-digest option --- Sources/tart/Commands/Pull.swift | 9 ++++++++- Sources/tart/Logging/Logger.swift | 17 ++++++++++------- Sources/tart/VMStorageOCI.swift | 5 ++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Sources/tart/Commands/Pull.swift b/Sources/tart/Commands/Pull.swift index 489439f8..07358285 100644 --- a/Sources/tart/Commands/Pull.swift +++ b/Sources/tart/Commands/Pull.swift @@ -23,6 +23,9 @@ struct Pull: AsyncParsableCommand { @Option(help: "network concurrency to use when pulling a remote VM from the OCI-compatible registry") var concurrency: UInt = 4 + @Flag(help: .hidden) + var jsonDigest: Bool = false + func validate() throws { if concurrency < 1 { throw ValidationError("network concurrency cannot be less than 1") @@ -30,10 +33,14 @@ struct Pull: AsyncParsableCommand { } func run() async throws { + if jsonDigest { + jsonLogger = SimpleConsoleLogger() + } + // Be more liberal when accepting local image as argument, // see https://github.com/cirruslabs/tart/issues/36 if VMStorageLocal().exists(remoteName) { - print("\"\(remoteName)\" is a local image, nothing to pull here!") + defaultLogger.appendNewLine("\"\(remoteName)\" is a local image, nothing to pull here!") return } diff --git a/Sources/tart/Logging/Logger.swift b/Sources/tart/Logging/Logger.swift index 5ac31389..ef5608ac 100644 --- a/Sources/tart/Logging/Logger.swift +++ b/Sources/tart/Logging/Logger.swift @@ -12,16 +12,13 @@ var defaultLogger: Logger = { return InteractiveConsoleLogger() } }() +var jsonLogger: Logger = NopLogger() public class InteractiveConsoleLogger: Logger { private let eraseCursorDown = "\u{001B}[J" // clear entire line private let moveUp = "\u{001B}[1A" // move one line up private let moveBeginningOfLine = "\r" // - public init() { - - } - public func appendNewLine(_ line: String) { print(line, terminator: "\n") } @@ -32,15 +29,21 @@ public class InteractiveConsoleLogger: Logger { } public class SimpleConsoleLogger: Logger { - public init() { + public func appendNewLine(_ line: String) { + print(line, terminator: "\n") + } + public func updateLastLine(_ line: String) { + print(line, terminator: "\n") } +} +public class NopLogger: Logger { public func appendNewLine(_ line: String) { - print(line, terminator: "\n") + // do nothing } public func updateLastLine(_ line: String) { - print(line, terminator: "\n") + // do nothing } } diff --git a/Sources/tart/VMStorageOCI.swift b/Sources/tart/VMStorageOCI.swift index a2e58310..0cce9bfb 100644 --- a/Sources/tart/VMStorageOCI.swift +++ b/Sources/tart/VMStorageOCI.swift @@ -147,6 +147,7 @@ class VMStorageOCI: PrunableStorage { if exists(name) && exists(digestName) && linked(from: name, to: digestName) { // optimistically check if we need to do anything at all before locking defaultLogger.appendNewLine("\(digestName) image is already cached and linked!") + jsonLogger.appendNewLine("{\"digest\": \"\(digestName)\"}") return } @@ -159,7 +160,7 @@ class VMStorageOCI: PrunableStorage { let sucessfullyLocked = try lock.trylock() if !sucessfullyLocked { - print("waiting for lock...") + defaultLogger.appendNewLine("waiting for lock...") try lock.lock() } defer { try! lock.unlock() } @@ -199,6 +200,8 @@ class VMStorageOCI: PrunableStorage { defaultLogger.appendNewLine("\(digestName) image is already cached! creating a symlink...") } + jsonLogger.appendNewLine("{\"digest\": \"\(digestName)\"}") + if name != digestName { // Create new or overwrite the old symbolic link try link(from: name, to: digestName) From 50cdd9546b0753123433e286810dce8c29afdd8f Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Tue, 20 Feb 2024 01:02:06 +0400 Subject: [PATCH 2/3] Introduce "tart fqn" command --- Sources/tart/Commands/FQN.swift | 22 ++++++++++++++++++++++ Sources/tart/Root.swift | 1 + 2 files changed, 23 insertions(+) create mode 100644 Sources/tart/Commands/FQN.swift diff --git a/Sources/tart/Commands/FQN.swift b/Sources/tart/Commands/FQN.swift new file mode 100644 index 00000000..0fd7f060 --- /dev/null +++ b/Sources/tart/Commands/FQN.swift @@ -0,0 +1,22 @@ +import ArgumentParser +import Foundation +import SystemConfiguration + +struct FQN: AsyncParsableCommand { + static var configuration = CommandConfiguration(abstract: "Get a fully-qualified VM name", shouldDisplay: false) + + @Argument(help: "VM name") + var name: String + + func run() async throws { + if var remoteName = try? RemoteName(name) { + let digest = try VMStorageOCI().digest(remoteName) + + remoteName.reference = Reference(digest: digest) + + print(remoteName) + } else { + print(name) + } + } +} diff --git a/Sources/tart/Root.swift b/Sources/tart/Root.swift index e9345963..1be21f12 100644 --- a/Sources/tart/Root.swift +++ b/Sources/tart/Root.swift @@ -26,6 +26,7 @@ struct Root: AsyncParsableCommand { Rename.self, Stop.self, Delete.self, + FQN.self, ]) public static func main() async throws { From 5751a31a07a882aa0cd2db93921a0f558ec8cbb8 Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Tue, 20 Feb 2024 01:02:22 +0400 Subject: [PATCH 3/3] Revert "tart pull: experimental --json-digest option" This reverts commit 842052f5bdca8cf29cc4afd99bdb537f8d88b7cb. --- Sources/tart/Commands/Pull.swift | 9 +-------- Sources/tart/Logging/Logger.swift | 17 +++++++---------- Sources/tart/VMStorageOCI.swift | 5 +---- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/Sources/tart/Commands/Pull.swift b/Sources/tart/Commands/Pull.swift index 07358285..489439f8 100644 --- a/Sources/tart/Commands/Pull.swift +++ b/Sources/tart/Commands/Pull.swift @@ -23,9 +23,6 @@ struct Pull: AsyncParsableCommand { @Option(help: "network concurrency to use when pulling a remote VM from the OCI-compatible registry") var concurrency: UInt = 4 - @Flag(help: .hidden) - var jsonDigest: Bool = false - func validate() throws { if concurrency < 1 { throw ValidationError("network concurrency cannot be less than 1") @@ -33,14 +30,10 @@ struct Pull: AsyncParsableCommand { } func run() async throws { - if jsonDigest { - jsonLogger = SimpleConsoleLogger() - } - // Be more liberal when accepting local image as argument, // see https://github.com/cirruslabs/tart/issues/36 if VMStorageLocal().exists(remoteName) { - defaultLogger.appendNewLine("\"\(remoteName)\" is a local image, nothing to pull here!") + print("\"\(remoteName)\" is a local image, nothing to pull here!") return } diff --git a/Sources/tart/Logging/Logger.swift b/Sources/tart/Logging/Logger.swift index ef5608ac..5ac31389 100644 --- a/Sources/tart/Logging/Logger.swift +++ b/Sources/tart/Logging/Logger.swift @@ -12,13 +12,16 @@ var defaultLogger: Logger = { return InteractiveConsoleLogger() } }() -var jsonLogger: Logger = NopLogger() public class InteractiveConsoleLogger: Logger { private let eraseCursorDown = "\u{001B}[J" // clear entire line private let moveUp = "\u{001B}[1A" // move one line up private let moveBeginningOfLine = "\r" // + public init() { + + } + public func appendNewLine(_ line: String) { print(line, terminator: "\n") } @@ -29,21 +32,15 @@ public class InteractiveConsoleLogger: Logger { } public class SimpleConsoleLogger: Logger { - public func appendNewLine(_ line: String) { - print(line, terminator: "\n") - } + public init() { - public func updateLastLine(_ line: String) { - print(line, terminator: "\n") } -} -public class NopLogger: Logger { public func appendNewLine(_ line: String) { - // do nothing + print(line, terminator: "\n") } public func updateLastLine(_ line: String) { - // do nothing + print(line, terminator: "\n") } } diff --git a/Sources/tart/VMStorageOCI.swift b/Sources/tart/VMStorageOCI.swift index 0cce9bfb..a2e58310 100644 --- a/Sources/tart/VMStorageOCI.swift +++ b/Sources/tart/VMStorageOCI.swift @@ -147,7 +147,6 @@ class VMStorageOCI: PrunableStorage { if exists(name) && exists(digestName) && linked(from: name, to: digestName) { // optimistically check if we need to do anything at all before locking defaultLogger.appendNewLine("\(digestName) image is already cached and linked!") - jsonLogger.appendNewLine("{\"digest\": \"\(digestName)\"}") return } @@ -160,7 +159,7 @@ class VMStorageOCI: PrunableStorage { let sucessfullyLocked = try lock.trylock() if !sucessfullyLocked { - defaultLogger.appendNewLine("waiting for lock...") + print("waiting for lock...") try lock.lock() } defer { try! lock.unlock() } @@ -200,8 +199,6 @@ class VMStorageOCI: PrunableStorage { defaultLogger.appendNewLine("\(digestName) image is already cached! creating a symlink...") } - jsonLogger.appendNewLine("{\"digest\": \"\(digestName)\"}") - if name != digestName { // Create new or overwrite the old symbolic link try link(from: name, to: digestName)