-
Notifications
You must be signed in to change notification settings - Fork 673
Added --export command #4405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Added --export command #4405
Conversation
|
||
// For now, use direct tar access. nsenter may have permission issues in rootless mode. | ||
tarArgs := []string{"-c", "-f", "-", "-C", rootPath, "."} | ||
cmd := exec.CommandContext(ctx, tarBinary, tarArgs...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to fix this to use that WriteDiff function but couldn't get it working. No matter what that 'WriteDiff' function seems to only write 1024 bytes.
Here's my debug code while testing it:
func createTarArchive(ctx context.Context, rootPath string, pid int, options types.ContainerExportOptions) error {
// Create a temporary empty directory to use as the "before" state for WriteDiff
emptyDir, err := os.MkdirTemp("", "nerdctl-export-empty-")
if err != nil {
return fmt.Errorf("failed to create temporary empty directory: %w", err)
}
defer os.RemoveAll(emptyDir)
// Debug logging
log.G(ctx).Debugf("Using WriteDiff to export container filesystem from %s", rootPath)
log.G(ctx).Debugf("Empty directory: %s", emptyDir)
log.G(ctx).Debugf("Output writer type: %T", options.Stdout)
// Check if the rootPath directory exists and has contents
if entries, err := os.ReadDir(rootPath); err != nil {
log.G(ctx).Debugf("Failed to read rootPath directory %s: %v", rootPath, err)
} else {
log.G(ctx).Debugf("RootPath %s contains %d entries", rootPath, len(entries))
for i, entry := range entries {
if i < 10 { // Only log first 10 entries to avoid spam
log.G(ctx).Debugf(" - %s (dir: %v)", entry.Name(), entry.IsDir())
}
}
if len(entries) > 10 {
log.G(ctx).Debugf(" ... and %d more entries", len(entries)-10)
}
}
// Create a counting writer to track bytes written
cw := &countingWriter{w: options.Stdout}
// Use WriteDiff to create a tar stream comparing the container rootfs (rootPath)
// with an empty directory (emptyDir). This produces a complete export of the container.
err = archive.WriteDiff(ctx, cw, rootPath, emptyDir)
if err != nil {
return fmt.Errorf("failed to write tar diff: %w", err)
}
log.G(ctx).Debugf("WriteDiff completed successfully, wrote %d bytes", cw.count)
return nil
}
// countingWriter wraps an io.Writer and counts the bytes written
type countingWriter struct {
w io.Writer
count int64
}
func (cw *countingWriter) Write(p []byte) (n int, err error) {
n, err = cw.w.Write(p)
cw.count += int64(n)
return n, err
}
And it gave this debug output
❯ nerdctl --debug export -o /tmp/test.tar temp-container
DEBU[0000] stateDir: /run/user/1000/containerd-rootless
DEBU[0000] RootlessKit detach-netns mode: true
DEBU[0000] rootless parent main: executing "/usr/sbin/nsenter" with [-r/ -w/home/craig/dev/nerdctl --preserve-credentials -m -U -t 446 -F nerdctl --debug export -o /tmp/test.tar temp-container]
DEBU[0000] Using running container root /proc/26209/root (pid 26209)
DEBU[0000] Using WriteDiff to export container filesystem from /proc/26209/root
DEBU[0000] Empty directory: /tmp/nerdctl-export-empty-3661002940
DEBU[0000] Output writer type: *os.File
DEBU[0000] RootPath /proc/26209/root contains 17 entries
DEBU[0000] - bin (dir: true)
DEBU[0000] - dev (dir: true)
DEBU[0000] - etc (dir: true)
DEBU[0000] - home (dir: true)
DEBU[0000] - lib (dir: true)
DEBU[0000] - media (dir: true)
DEBU[0000] - mnt (dir: true)
DEBU[0000] - opt (dir: true)
DEBU[0000] - proc (dir: true)
DEBU[0000] - root (dir: true)
DEBU[0000] ... and 7 more entries
DEBU[0000] Using double walk diff for /tmp/nerdctl-export-empty-3661002940 from /proc/26209/root
DEBU[0000] WriteDiff completed successfully, wrote 1024 bytes
So it seems like it should work? But just doesn't
Co-authored-by: Akihiro Suda <suda.kyoto@gmail.com> Signed-off-by: Craig Loewen <crloewen@microsoft.com>
I made a PR to add the
--export
command to nerdctl.I did it to solve issues like #1854 and since I saw it had support from the maintainers.
I also looked at this PR for inspiration: https://github.com/containerd/nerdctl/pull/2161/files
Please let me know if you want any changes or if it looks good!