Skip to content

Commit 9b43553

Browse files
authored
[container-build]: Support inline Dockerfile from stdin (#827)
- Closes #727
1 parent 739f5e5 commit 9b43553

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

Sources/ContainerCommands/BuildCommand.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,33 @@ extension Application {
207207
buildFilePath = resolvedPath
208208
}
209209

210-
let buildFileData = try Data(contentsOf: URL(filePath: buildFilePath))
210+
let buildFileData: Data
211+
// Dockerfile should be read from stdin
212+
if file == "-" {
213+
let tempFile = FileManager.default.temporaryDirectory.appendingPathComponent("Dockerfile-\(UUID().uuidString)")
214+
defer {
215+
try? FileManager.default.removeItem(at: tempFile)
216+
}
217+
218+
guard FileManager.default.createFile(atPath: tempFile.path(), contents: nil) else {
219+
throw ContainerizationError(.internalError, message: "unable to create temporary file")
220+
}
221+
222+
guard let fileHandle = try? FileHandle(forWritingTo: tempFile) else {
223+
throw ContainerizationError(.internalError, message: "unable to open temporary file for writing")
224+
}
225+
226+
let bufferSize = 4096
227+
while true {
228+
let chunk = FileHandle.standardInput.readData(ofLength: bufferSize)
229+
if chunk.isEmpty { break }
230+
fileHandle.write(chunk)
231+
}
232+
try fileHandle.close()
233+
buildFileData = try Data(contentsOf: URL(filePath: tempFile.path()))
234+
} else {
235+
buildFileData = try Data(contentsOf: URL(filePath: buildFilePath))
236+
}
211237

212238
let systemHealth = try await ClientHealthCheck.ping(timeout: .seconds(10))
213239
let exportPath = systemHealth.appRoot

Tests/CLITests/Subcommands/Build/CLIBuildBase.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,42 @@ class TestCLIBuildBase: CLITest {
144144
return response.output
145145
}
146146

147+
@discardableResult
148+
func buildWithStdin(
149+
tags: [String],
150+
tempContext: URL,
151+
dockerfileContents: String,
152+
buildArgs: [String] = [],
153+
otherArgs: [String] = []
154+
) throws -> String {
155+
let contextDir: URL = tempContext.appendingPathComponent("context")
156+
let contextDirPath = contextDir.absoluteURL.path
157+
var args = [
158+
"build",
159+
"-f",
160+
"-",
161+
]
162+
for tag in tags {
163+
args.append("-t")
164+
args.append(tag)
165+
}
166+
for arg in buildArgs {
167+
args.append("--build-arg")
168+
args.append(arg)
169+
}
170+
args.append(contextDirPath)
171+
172+
args.append(contentsOf: otherArgs)
173+
174+
let stdinData = Data(dockerfileContents.utf8)
175+
let response = try run(arguments: args, stdin: stdinData)
176+
if response.status != 0 {
177+
throw CLIError.executionFailed("build failed: stdout=\(response.output) stderr=\(response.error)")
178+
}
179+
180+
return response.output
181+
}
182+
147183
enum FileSystemEntry {
148184
case file(
149185
_ path: String,

Tests/CLITests/Subcommands/Build/CLIBuilderTest.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,5 +456,20 @@ extension TestCLIBuildBase {
456456
#expect(try self.inspectImage(tag2) == tag2, "expected to have successfully built \(tag2)")
457457
#expect(try self.inspectImage(tag3) == tag3, "expected to have successfully built \(tag3)")
458458
}
459+
460+
@Test func testBuildWithDockerfileFromStdin() throws {
461+
let tempDir: URL = try createTempDir()
462+
let dockerfile =
463+
"""
464+
FROM scratch
465+
466+
ADD emptyFile /
467+
"""
468+
let context: [FileSystemEntry] = [.file("emptyFile", content: .zeroFilled(size: 1))]
469+
try createContext(tempDir: tempDir, dockerfile: "", context: context)
470+
let imageName = "registry.local/stdin-file:\(UUID().uuidString)"
471+
try buildWithStdin(tags: [imageName], tempContext: tempDir, dockerfileContents: dockerfile)
472+
#expect(try self.inspectImage(imageName) == imageName, "expected to have successfully built \(imageName)")
473+
}
459474
}
460475
}

0 commit comments

Comments
 (0)