Skip to content

feat: Pass Dockerfiles to unikraft build - #503

Open
danielvallance wants to merge 2 commits into
prod-stagingfrom
danielvallance/dockerfile_builds
Open

danielvallance wants to merge 2 commits into
prod-stagingfrom
danielvallance/dockerfile_builds

Conversation

@danielvallance

Copy link
Copy Markdown
Contributor

Now that the platform supports kernel-less images, it is not strictly necessary to pass a Kraftfile
to unikraft build - instead it can accept a
Dockerfile.

Passing a Dockerfile will build a image which
contains a rootfs based off the Dockerfile,
and no kernel.

The filename is used to determine which
type of file has been passed. If a directory
is passed, the Kraftfile takes precedence
over the Dockerfile.

When a Dockerfile is passed, the --arch argument
must be set so the CLI knows which architecure
to build for.

Kernel-less images can only be run on metros
with a default kernel installed.

Closes: TOOL-1439

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃煛 Changes recommended

Add end-to-end coverage for direct Kraftfile inputs, precedence, relative sources, and resource cleanup.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds Dockerfile-based, kernel-less image builds with architecture validation and Kraftfile precedence.

Changes:

  • Supports directory and direct-file build inputs.
  • Adds input-resolution tests, integration coverage, help snapshots, and documentation.
File summaries
File Summary
skills/unikraft-cli/SKILL.md Documents Dockerfile builds.
README.md Adds Dockerfile build guidance.
internal/cmd/build.go Loads inputs and validates architecture.
internal/builder/rootfs.go Reuses Dockerfile detection.
internal/builder/input.go Resolves Kraftfile and Dockerfile inputs; needs additional end-to-end coverage.
internal/builder/input_test.go Tests input resolution.
cmd/unikraft/testdata/TestHelp/images Updates image help output.
cmd/unikraft/testdata/TestHelp/build Updates build help output.
cmd/unikraft/integration/build_test.go Tests Dockerfile-only builds.
Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 1
  • Review effort level: Lite

馃挕 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/builder/input.go
if isDockerfileName(filepath.Base(path)) {
return DockerfileToBuildOpts(path), nil
}
return loadKraftfile(ctx, path, filepath.Dir(path))

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃煛 Changes recommended

Dockerfile-only builds currently discard Dockerfile labels, and architecture documentation contradicts supported runtime-derived platforms.

Get a fresh assessment by requesting another Copilot review.

Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment thread internal/builder/input.go Outdated
Comment on lines +82 to +88
func DockerfileToBuildOpts(path string) BuildOpts {
return BuildOpts{
Rootfs: FSOpts{
Path: path,
Type: kraftfile.SourceTypeDockerfile,
},
}
Comment thread internal/cmd/build.go Outdated
Comment thread skills/unikraft-cli/SKILL.md Outdated
@danielvallance
danielvallance force-pushed the danielvallance/dockerfile_builds branch 2 times, most recently from c1c1158 to f6f6e9b Compare September 16, 2026 15:02
Comment thread internal/builder/build_test.go Outdated
ctx := integrationContext(t)
dockerfile := `
FROM scratch
LABEL org.unikraft.source=dockerfile org.unikraft.only=dockerfile

@nderjung nderjung Sep 17, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is org.unikraft.source coming from?

IMHO we should use com. || cloud. for anything specifically cloud-based - so as not to mess with stuff in the OSS/KraftKit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a similar label was in TestBuildCmdEnvLabelsIntegration - however that test and the tests I added do not rely on the meaning of the label at all, so am just going to change them to use com.example.* type labels

@craciunoiuc

Copy link
Copy Markdown
Contributor

do let me know when I should check it out 馃槈

@danielvallance
danielvallance force-pushed the danielvallance/dockerfile_builds branch from f6f6e9b to 55d7e45 Compare September 18, 2026 10:11
@danielvallance
danielvallance marked this pull request as ready for review September 18, 2026 10:11
@danielvallance
danielvallance requested review from craciunoiuc and a balanced review from Copilot September 18, 2026 10:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃煝 Approval recommended

The implementation is consistent with the stated behavior and has comprehensive unit and end-to-end coverage.

Review details
  • Files reviewed: 12/12 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@danielvallance

Copy link
Copy Markdown
Contributor Author

@craciunoiuc stable integration test is failing because of a platform issue fixed in latest version

@danielvallance

Copy link
Copy Markdown
Contributor Author

@craciunoiuc they pass now!

@craciunoiuc craciunoiuc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First set of comments

General note: Go people hate abstraction (for the sake of abstraction)

Comment thread internal/builder/input.go
Comment on lines +26 to +34
// kraftfileNames are the Kraftfile names that a project directory can contain,
// in order of precedence. The order is the name order of the directory listing.
var kraftfileNames = []string{
"Kraftfile",
"Kraftfile.yaml",
"Kraftfile.yml",
"kraft.yaml",
"kraft.yml",
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this isn't already in x/kraftfile then it should be probably 馃

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure - I can add that afterwards

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's already there 馃

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃

Comment thread internal/builder/input.go Outdated
Comment thread internal/builder/input.go
Comment on lines +71 to +88
func loadKraftfile(ctx context.Context, path, dir string) (BuildOpts, error) {
kf, err := kraftfile.ParseFile(path, kraftfile.WithSkippedVersionCheck())
if err != nil {
return BuildOpts{}, err
}
if semver.Compare(kf.Spec, kraftfile.SpecVersionMin) < 0 {
log.G(ctx).Warn().
Str("spec", kf.Spec).
Str("min", kraftfile.SpecVersionMin).
Msg("Kraftfile spec version is older than minimum; parsing is best-effort")
} else if semver.Compare(kf.Spec, kraftfile.SpecVersionMax) > 0 {
log.G(ctx).Warn().
Str("spec", kf.Spec).
Str("max", kraftfile.SpecVersionMax).
Msg("Kraftfile spec version is newer than maximum; parsing is best-effort")
}
return KraftfileToBuildOpts(dir, kf)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just one use place, so inline

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mind if i keep this as its own function? it is used twice so i think having it as its own function keeps it simpler

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well if you ask me so nicely how can I say no

Comment thread internal/builder/input.go Outdated
Comment thread internal/cmd/build.go
Comment thread skills/unikraft-cli/SKILL.md Outdated
Comment thread README.md Outdated
Comment thread internal/builder/input.go
@craciunoiuc
craciunoiuc requested a review from jedevc September 18, 2026 13:30
@danielvallance
danielvallance force-pushed the danielvallance/dockerfile_builds branch from 55d7e45 to 0abe268 Compare September 20, 2026 20:45
Now that the platform supports kernel-less images,
it is not strictly necessary to pass a Kraftfile
to unikraft build - instead it can accept a
Dockerfile.

Passing a Dockerfile will build a image which
contains a rootfs based off the Dockerfile,
and no kernel.

The filename is used to determine which
type of file has been passed. If a directory
is passed, the Kraftfile takes precedence
over the Dockerfile.

When a Dockerfile is passed, the --arch argument
must be set so the CLI knows which architecure
to build for.

Kernel-less images can only be run on metros
with a default kernel installed.

Closes: TOOL-1439

Signed-off-by: Daniel Vallance <daniel@unikraft.com>
unikraft.org is the OSS project and we don't want
to confuse that with our cloud offering

Signed-off-by: Daniel Vallance <daniel@unikraft.com>
@danielvallance
danielvallance force-pushed the danielvallance/dockerfile_builds branch from 0abe268 to 7f27c21 Compare September 21, 2026 09:01

@craciunoiuc craciunoiuc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you have like a crazy commit message rule.

You can ask it for under 50 lines for titles and under 70 lines for commit bodies.

Other than that it looks good to me I think? @jedevc you're free to do a pass

Comment thread internal/builder/input.go

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this logic is very similar to ParseDirectory.

Instead of doing all that, can we just try that first, then if we detect an error (probably need to make an exported "no kraftfile found in directory" error type), try and load from a dockerfile?

Then we don't need to import all this logic again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants