-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9db89f8
Showing
28 changed files
with
3,345 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"go.formatTool": "goimports" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
build: | ||
GOOS=js GOARCH=wasm go build -o main.wasm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# dockerbot | ||
|
||
in development ... | ||
|
||
## Warn | ||
|
||
dockerbot/dockerfile2llb package is copied from moby/buildkit. but sygnal package is not used. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package docker2dot | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"io" | ||
"strings" | ||
|
||
"github.com/moby/buildkit/client/llb" | ||
"github.com/moby/buildkit/solver/pb" | ||
digest "github.com/opencontainers/go-digest" | ||
"github.com/pkg/errors" | ||
"github.com/po3rin/dockerdot/dockerfile2llb" | ||
) | ||
|
||
// Docker2Dot convert dockerfile to llb Expressed in DOT language. | ||
func Docker2Dot(df []byte) ([]byte, error) { | ||
st, img, err := dockerfile2llb.Dockerfile2LLB(context.Background(), df, dockerfile2llb.ConvertOpt{}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// ignore image | ||
_ = img | ||
|
||
def, err := st.Marshal() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
ops, err := loadLLB(def) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var b bytes.Buffer | ||
writeDot(ops, &b) | ||
result := b.Bytes() | ||
|
||
return result, nil | ||
} | ||
|
||
type llbOp struct { | ||
Op pb.Op | ||
Digest digest.Digest | ||
OpMetadata pb.OpMetadata | ||
} | ||
|
||
// loadLLB load llbOp from llb.Definition. | ||
func loadLLB(def *llb.Definition) ([]llbOp, error) { | ||
var ops []llbOp | ||
for _, dt := range def.Def { | ||
var op pb.Op | ||
if err := (&op).Unmarshal(dt); err != nil { | ||
return nil, errors.Wrap(err, "failed to parse op") | ||
} | ||
dgst := digest.FromBytes(dt) | ||
ent := llbOp{Op: op, Digest: dgst, OpMetadata: def.Metadata[dgst]} | ||
ops = append(ops, ent) | ||
} | ||
return ops, nil | ||
} | ||
|
||
func writeDot(ops []llbOp, w io.Writer) { | ||
// TODO: print OpMetadata | ||
fmt.Fprintln(w, "digraph {") | ||
defer fmt.Fprintln(w, "}") | ||
for _, op := range ops { | ||
name, shape := attr(op.Digest, op.Op) | ||
fmt.Fprintf(w, " %q [label=%q shape=%q];\n", op.Digest, name, shape) | ||
} | ||
for _, op := range ops { | ||
for i, inp := range op.Op.Inputs { | ||
label := "" | ||
if eo, ok := op.Op.Op.(*pb.Op_Exec); ok { | ||
for _, m := range eo.Exec.Mounts { | ||
if int(m.Input) == i && m.Dest != "/" { | ||
label = m.Dest | ||
} | ||
} | ||
} | ||
fmt.Fprintf(w, " %q -> %q [label=%q];\n", inp.Digest, op.Digest, label) | ||
} | ||
} | ||
} | ||
|
||
func attr(dgst digest.Digest, op pb.Op) (string, string) { | ||
switch op := op.Op.(type) { | ||
case *pb.Op_Source: | ||
return op.Source.Identifier, "ellipse" | ||
case *pb.Op_Exec: | ||
return strings.Join(op.Exec.Meta.Args, " "), "box" | ||
case *pb.Op_Build: | ||
return "build", "box3d" | ||
default: | ||
return dgst.String(), "plaintext" | ||
} | ||
} |
Oops, something went wrong.