move rootfs to its own package

This commit is contained in:
Motiejus Jakštys 2021-05-24 00:11:57 +03:00
parent ce445b19b7
commit 3279b52973
4 changed files with 44 additions and 39 deletions

10
BUILD
View File

@ -2,13 +2,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library( go_library(
name = "undocker_lib", name = "undocker_lib",
srcs = [ srcs = ["main.go"],
"main.go",
"rootfs.go",
],
importpath = "github.com/motiejus/code/undocker", importpath = "github.com/motiejus/code/undocker",
visibility = ["//visibility:private"], visibility = ["//visibility:private"],
deps = ["@com_github_jessevdk_go_flags//:go-flags"], deps = [
"//src/undocker/rootfs:rootfs_lib",
"@com_github_jessevdk_go_flags//:go-flags",
],
) )
go_binary( go_binary(

28
main.go
View File

@ -1,9 +1,11 @@
package main package main
import ( import (
"errors"
"os" "os"
goflags "github.com/jessevdk/go-flags" goflags "github.com/jessevdk/go-flags"
"github.com/motiejus/code/undocker/rootfs"
) )
type ( type (
@ -31,3 +33,29 @@ func run(args []string) error {
return nil return nil
} }
type cmdRootFS struct {
PositionalArgs struct {
Infile goflags.Filename `long:"infile" description:"Input tarball"`
Outfile string `long:"outfile" description:"Output tarball (flattened file system)"`
} `positional-args:"yes" required:"yes"`
}
func (r *cmdRootFS) Execute(args []string) error {
if len(args) != 0 {
return errors.New("too many args")
}
in, err := os.Open(string(r.PositionalArgs.Infile))
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(string(r.PositionalArgs.Outfile))
if err != nil {
return err
}
defer out.Close()
return rootfs.Rootfs(in, out)
}

8
rootfs/BUILD Normal file
View File

@ -0,0 +1,8 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "rootfs_lib",
srcs = ["rootfs.go"],
importpath = "github.com/motiejus/code/undocker/rootfs",
visibility = ["//visibility:public"],
)

View File

@ -1,53 +1,23 @@
package main package rootfs
import ( import (
"archive/tar" "archive/tar"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"os"
"strings" "strings"
goflags "github.com/jessevdk/go-flags"
) )
type cmdRootFS struct {
PositionalArgs struct {
Infile goflags.Filename `long:"infile" description:"Input tarball"`
Outfile string `long:"outfile" description:"Output tarball (flattened file system)"`
} `positional-args:"yes" required:"yes"`
}
const ( const (
_manifestJSON = "manifest.json" _manifestJSON = "manifest.json"
) )
func (r *cmdRootFS) Execute(args []string) error {
if len(args) != 0 {
return errors.New("too many args")
}
in, err := os.Open(string(r.PositionalArgs.Infile))
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(string(r.PositionalArgs.Outfile))
if err != nil {
return err
}
defer out.Close()
return r.rootfs(in, out)
}
type dockerManifestJSON []struct { type dockerManifestJSON []struct {
Config string `json:"Config"` Config string `json:"Config"`
Layers []string `json:"Layers"` Layers []string `json:"Layers"`
} }
// rootfs accepts a docker layer tarball and writes it to outfile. // Rootfs accepts a docker layer tarball and writes it to outfile.
// 1. create map[string]io.ReadSeeker for each layer. // 1. create map[string]io.ReadSeeker for each layer.
// 2. parse manifest.json and get the layer order. // 2. parse manifest.json and get the layer order.
// 3. go through each layer in order and write: // 3. go through each layer in order and write:
@ -56,7 +26,7 @@ type dockerManifestJSON []struct {
// I) layer name // I) layer name
// II) offset (0 being the first file in the layer) // II) offset (0 being the first file in the layer)
// 4. go through // 4. go through
func (r *cmdRootFS) rootfs(in io.ReadSeeker, out io.Writer) error { func Rootfs(in io.ReadSeeker, out io.Writer) error {
tr := tar.NewReader(in) tr := tar.NewReader(in)
tw := tar.NewWriter(out) tw := tar.NewWriter(out)
// layerOffsets maps a layer name (a9b123c0daa/layer.tar) to it's offset // layerOffsets maps a layer name (a9b123c0daa/layer.tar) to it's offset
@ -88,7 +58,6 @@ func (r *cmdRootFS) rootfs(in io.ReadSeeker, out io.Writer) error {
return fmt.Errorf("seek: %w", err) return fmt.Errorf("seek: %w", err)
} }
layerOffsets[hdr.Name] = here layerOffsets[hdr.Name] = here
//fmt.Printf("%s\t%x\n", hdr.Name, here)
} }
} }