added layer info
This commit is contained in:
parent
e67734d38d
commit
a8cc8db4a5
24
.vscode/launch.json
vendored
Normal file
24
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"remotePath": "",
|
||||
"port": 2345,
|
||||
"host": "127.0.0.1",
|
||||
"program": "${workspaceRoot}/cmd/die/main.go",
|
||||
"externalConsole": true,
|
||||
"env": {
|
||||
"TERM": "xterm-256color"
|
||||
},
|
||||
"args": ["die-test"],
|
||||
"showLog": true
|
||||
}
|
||||
]
|
||||
}
|
@ -208,9 +208,10 @@ func (tree *FileTree) MarkRemoved(path string) error {
|
||||
return node.AssignDiffType(Removed)
|
||||
}
|
||||
|
||||
func StackRange(trees []*FileTree, index uint) *FileTree {
|
||||
func StackRange(trees []*FileTree, index int) *FileTree {
|
||||
// TMP TMP TMP: TODO: later change the index of both of these to 0
|
||||
tree := trees[1].Copy()
|
||||
for idx := uint(1); idx <= index; idx++ {
|
||||
for idx := 1; idx <= index; idx++ {
|
||||
tree.Stack(trees[idx])
|
||||
}
|
||||
return tree
|
||||
|
@ -12,7 +12,9 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
"github.com/wagoodman/docker-image-explorer/filetree"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
@ -24,9 +26,9 @@ func check(e error) {
|
||||
}
|
||||
|
||||
type ImageManifest struct {
|
||||
Config string
|
||||
RepoTags []string
|
||||
Layers []string
|
||||
ConfigPath string `json:"Config"`
|
||||
RepoTags []string `json:"RepoTags"`
|
||||
LayerTarPaths []string `json:"Layers"`
|
||||
}
|
||||
|
||||
func NewManifest(reader *tar.Reader, header *tar.Header) ImageManifest {
|
||||
@ -44,24 +46,37 @@ func NewManifest(reader *tar.Reader, header *tar.Header) ImageManifest {
|
||||
return m[0]
|
||||
}
|
||||
|
||||
func InitializeData(imageID string) (*ImageManifest, []*filetree.FileTree) {
|
||||
imageTarPath, tmpDir := saveImage(imageID)
|
||||
type Layer struct {
|
||||
TarPath string
|
||||
History types.ImageHistory
|
||||
}
|
||||
|
||||
f, err := os.Open(imageTarPath)
|
||||
func (layer *Layer) String() string {
|
||||
id := layer.History.ID[0:25]
|
||||
if len(layer.History.Tags) > 0 {
|
||||
id = "[" + strings.Join(layer.History.Tags, ",") + "]"
|
||||
}
|
||||
return fmt.Sprintf("%25s %7s %s", id, humanize.Bytes(uint64(layer.History.Size)), layer.History.CreatedBy)
|
||||
}
|
||||
|
||||
func InitializeData(imageID string) ([]*Layer, []*filetree.FileTree) {
|
||||
var manifest ImageManifest
|
||||
var layerMap = make(map[string]*filetree.FileTree)
|
||||
var trees []*filetree.FileTree = make([]*filetree.FileTree, 0)
|
||||
|
||||
// save this image to disk temporarily to get the content info
|
||||
imageTarPath, tmpDir := saveImage(imageID)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// read through the image contents and build a tree
|
||||
tarFile, err := os.Open(imageTarPath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer tarFile.Close()
|
||||
|
||||
defer f.Close()
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
tarReader := tar.NewReader(f)
|
||||
targetName := "manifest.json"
|
||||
var manifest ImageManifest
|
||||
var layerMap map[string]*filetree.FileTree
|
||||
layerMap = make(map[string]*filetree.FileTree)
|
||||
|
||||
tarReader := tar.NewReader(tarFile)
|
||||
for {
|
||||
header, err := tarReader.Next()
|
||||
|
||||
@ -75,7 +90,7 @@ func InitializeData(imageID string) (*ImageManifest, []*filetree.FileTree) {
|
||||
}
|
||||
|
||||
name := header.Name
|
||||
if name == targetName {
|
||||
if name == "manifest.json" {
|
||||
manifest = NewManifest(tarReader, header)
|
||||
}
|
||||
|
||||
@ -96,13 +111,30 @@ func InitializeData(imageID string) (*ImageManifest, []*filetree.FileTree) {
|
||||
fmt.Printf("ERRG: unknown tar entry: %v: %s\n", header.Typeflag, name)
|
||||
}
|
||||
}
|
||||
var trees []*filetree.FileTree
|
||||
trees = make([]*filetree.FileTree, 0)
|
||||
for _, treeName := range manifest.Layers {
|
||||
|
||||
// build the content tree
|
||||
for _, treeName := range manifest.LayerTarPaths {
|
||||
trees = append(trees, layerMap[treeName])
|
||||
}
|
||||
|
||||
return &manifest, trees
|
||||
// get the history of this image
|
||||
ctx := context.Background()
|
||||
dockerClient, err := client.NewEnvClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
history, err := dockerClient.ImageHistory(ctx, imageID)
|
||||
|
||||
// build the layers array
|
||||
layers := make([]*Layer, len(history)-1)
|
||||
for idx := 0; idx < len(layers); idx++ {
|
||||
layers[idx] = new(Layer)
|
||||
layers[idx].History = history[idx]
|
||||
layers[idx].TarPath = manifest.LayerTarPaths[idx]
|
||||
}
|
||||
|
||||
return layers, trees
|
||||
}
|
||||
|
||||
func saveImage(imageID string) (string, string) {
|
||||
@ -154,14 +186,14 @@ func saveImage(imageID string) (string, string) {
|
||||
|
||||
func getFileList(parentReader *tar.Reader, h *tar.Header) []filetree.FileChangeInfo {
|
||||
var files []filetree.FileChangeInfo
|
||||
size := h.Size
|
||||
tarredBytes := make([]byte, size)
|
||||
var tarredBytes = make([]byte, h.Size)
|
||||
|
||||
_, err := parentReader.Read(tarredBytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
r := bytes.NewReader(tarredBytes)
|
||||
tarReader := tar.NewReader(r)
|
||||
reader := bytes.NewReader(tarredBytes)
|
||||
tarReader := tar.NewReader(reader)
|
||||
for {
|
||||
header, err := tarReader.Next()
|
||||
|
||||
|
@ -11,7 +11,7 @@ type FileTreeView struct {
|
||||
Name string
|
||||
gui *gocui.Gui
|
||||
view *gocui.View
|
||||
TreeIndex uint
|
||||
TreeIndex int
|
||||
Tree *filetree.FileTree
|
||||
RefTrees []*filetree.FileTree
|
||||
}
|
||||
@ -54,7 +54,7 @@ func (view *FileTreeView) Setup(v *gocui.View) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (view *FileTreeView) setLayer(layerIndex uint) error {
|
||||
func (view *FileTreeView) setLayer(layerIndex int) error {
|
||||
view.Tree = filetree.StackRange(view.RefTrees, layerIndex-1)
|
||||
view.Tree.Compare(view.RefTrees[layerIndex])
|
||||
v, _ := view.gui.View("debug")
|
||||
@ -84,7 +84,7 @@ func (view *FileTreeView) CursorUp() error {
|
||||
func (view *FileTreeView) getAbsPositionNode() (node *filetree.FileNode) {
|
||||
var visiter func(*filetree.FileNode) error
|
||||
var evaluator func(*filetree.FileNode) bool
|
||||
var dfsCounter uint
|
||||
var dfsCounter int
|
||||
|
||||
visiter = func(curNode *filetree.FileNode) error {
|
||||
if dfsCounter == view.TreeIndex {
|
||||
|
@ -11,17 +11,17 @@ type LayerView struct {
|
||||
Name string
|
||||
gui *gocui.Gui
|
||||
view *gocui.View
|
||||
LayerIndex uint
|
||||
Manifest *image.ImageManifest
|
||||
LayerIndex int
|
||||
Layers []*image.Layer
|
||||
}
|
||||
|
||||
func NewLayerView(name string, gui *gocui.Gui, manifest *image.ImageManifest) (layerview *LayerView) {
|
||||
func NewLayerView(name string, gui *gocui.Gui, layers []*image.Layer) (layerview *LayerView) {
|
||||
layerview = new(LayerView)
|
||||
|
||||
// populate main fields
|
||||
layerview.Name = name
|
||||
layerview.gui = gui
|
||||
layerview.Manifest = manifest
|
||||
layerview.Layers = layers
|
||||
|
||||
return layerview
|
||||
}
|
||||
@ -30,7 +30,7 @@ func (view *LayerView) Setup(v *gocui.View) error {
|
||||
|
||||
// set view options
|
||||
view.view = v
|
||||
view.view.Wrap = true
|
||||
view.view.Wrap = false
|
||||
view.view.Highlight = true
|
||||
view.view.SelBgColor = gocui.ColorGreen
|
||||
view.view.SelFgColor = gocui.ColorBlack
|
||||
@ -51,8 +51,9 @@ func (view *LayerView) Setup(v *gocui.View) error {
|
||||
func (view *LayerView) Render() error {
|
||||
view.gui.Update(func(g *gocui.Gui) error {
|
||||
view.view.Clear()
|
||||
for ix, layerName := range view.Manifest.Layers {
|
||||
fmt.Fprintf(view.view, "%d: %s\n", ix+1, layerName[0:25])
|
||||
for idx := len(view.Layers) - 1; idx >= 0; idx-- {
|
||||
layer := view.Layers[idx]
|
||||
fmt.Fprintln(view.view, layer.String())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -61,22 +62,25 @@ func (view *LayerView) Render() error {
|
||||
}
|
||||
|
||||
func (view *LayerView) CursorDown() error {
|
||||
if int(view.LayerIndex) < len(view.Manifest.Layers) {
|
||||
CursorDown(view.gui, view.view)
|
||||
view.LayerIndex++
|
||||
view.Render()
|
||||
Views.Tree.setLayer(view.LayerIndex)
|
||||
if int(view.LayerIndex) < len(view.Layers) {
|
||||
err := CursorDown(view.gui, view.view)
|
||||
if err == nil {
|
||||
view.LayerIndex++
|
||||
view.Render()
|
||||
Views.Tree.setLayer(view.LayerIndex)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (view *LayerView) CursorUp() error {
|
||||
if int(view.LayerIndex) > 0 {
|
||||
CursorUp(view.gui, view.view)
|
||||
view.LayerIndex--
|
||||
view.Render()
|
||||
// this line is evil
|
||||
Views.Tree.setLayer(view.LayerIndex)
|
||||
err := CursorUp(view.gui, view.view)
|
||||
if err == nil {
|
||||
view.LayerIndex--
|
||||
view.Render()
|
||||
Views.Tree.setLayer(view.LayerIndex)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
8
ui/ui.go
8
ui/ui.go
@ -76,8 +76,8 @@ func keybindings(g *gocui.Gui) error {
|
||||
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
splitCol := 50
|
||||
debugCol := maxX - 100
|
||||
splitCol := 100
|
||||
debugCol := maxX - 70
|
||||
if view, err := g.SetView(Views.Layer.Name, -1, -1, splitCol, maxY); err != nil {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
@ -105,7 +105,7 @@ func layout(g *gocui.Gui) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Run(manifest *image.ImageManifest, refTrees []*filetree.FileTree) {
|
||||
func Run(layers []*image.Layer, refTrees []*filetree.FileTree) {
|
||||
|
||||
g, err := gocui.NewGui(gocui.OutputNormal)
|
||||
if err != nil {
|
||||
@ -113,7 +113,7 @@ func Run(manifest *image.ImageManifest, refTrees []*filetree.FileTree) {
|
||||
}
|
||||
defer g.Close()
|
||||
|
||||
Views.Layer = NewLayerView("side", g, manifest)
|
||||
Views.Layer = NewLayerView("side", g, layers)
|
||||
Views.Tree = NewFileTreeView("main", g, filetree.StackRange(refTrees, 0), refTrees)
|
||||
|
||||
g.Cursor = false
|
||||
|
Loading…
x
Reference in New Issue
Block a user