undocker

extract docker archives
Log | Files | Refs | README | LICENSE

main.go (1604B) - Raw


      1 // Package main is a simple command-line application on top of rootfs.Flatten.
      2 package main
      3 
      4 import (
      5 	"errors"
      6 	"fmt"
      7 	"io"
      8 	"os"
      9 	"path/filepath"
     10 	"runtime"
     11 
     12 	"git.jakstys.lt/motiejus/undocker/rootfs"
     13 )
     14 
     15 var Version = "unknown"
     16 var VersionHash = "unknown"
     17 
     18 const _usage = `Usage:
     19   %s <infile> <outfile>
     20 
     21 Flatten a Docker container image to a root file system.
     22 
     23 Arguments:
     24   <infile>:  Input Docker container. Tarball.
     25   <outfile>: Output tarball, the root file system. '-' is stdout.
     26 
     27 undocker %s (%s)
     28 Built with %s
     29 `
     30 
     31 func main() {
     32 	runtime.GOMAXPROCS(1) // no need to create that many threads
     33 
     34 	if len(os.Args) != 3 {
     35 		fmt.Fprintf(os.Stderr, _usage,
     36 			filepath.Base(os.Args[0]),
     37 			Version,
     38 			VersionHash,
     39 			runtime.Version(),
     40 		)
     41 		os.Exit(1)
     42 	}
     43 
     44 	c := &command{flattener: rootfs.Flatten, Stdout: os.Stdout}
     45 	if err := c.execute(os.Args[1], os.Args[2]); err != nil {
     46 		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
     47 		os.Exit(1)
     48 	}
     49 	os.Exit(0)
     50 }
     51 
     52 type command struct {
     53 	flattener func(io.ReadSeeker, io.Writer) error
     54 	Stdout    io.Writer
     55 }
     56 
     57 func (c *command) execute(infile string, outfile string) (_err error) {
     58 	rd, err := os.Open(infile)
     59 	if err != nil {
     60 		return err
     61 	}
     62 	defer func() {
     63 		_err = errors.Join(_err, rd.Close())
     64 	}()
     65 
     66 	var out io.Writer
     67 	if outfile == "-" {
     68 		out = c.Stdout
     69 	} else {
     70 		outf, err := os.Create(outfile)
     71 		if err != nil {
     72 			return fmt.Errorf("create: %w", err)
     73 		}
     74 		defer func() {
     75 			if _err != nil {
     76 				_err = errors.Join(_err, os.Remove(outfile))
     77 			} else {
     78 				_err = errors.Join(_err, outf.Close())
     79 			}
     80 		}()
     81 		out = outf
     82 	}
     83 
     84 	return c.flattener(rd, out)
     85 }