Skip to content

Commit

Permalink
Merge branch 'main' of github.com:SongStitch/anchor into feature/add-…
Browse files Browse the repository at this point in the history
…ci-cleanup
  • Loading branch information
TheDen committed May 13, 2024
2 parents ca21080 + 050e475 commit c3467b2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 28 deletions.
31 changes: 27 additions & 4 deletions cmd/anchor/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package anchor

import (
"bufio"
"context"
"fmt"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"

"github.com/fatih/color"
"github.com/moby/buildkit/frontend/dockerfile/parser"
Expand Down Expand Up @@ -41,6 +44,14 @@ var rootCmd = &cobra.Command{
SilenceUsage: true,
SilenceErrors: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithCancel(context.Background())
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
cancel()
os.Exit(1)
}()

if anchor.IsDockerInstalled() {
if !anchor.IsDockerRunning() {
Expand Down Expand Up @@ -78,30 +89,42 @@ var rootCmd = &cobra.Command{
}
appendArch := len(options.Architectures) > 1

content, err := os.Open(options.InputFile)
if err != nil {
return err
}
defer content.Close()
lines := []string{}
scanner := bufio.NewScanner(content)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}

if err := scanner.Err(); err != nil {
return err
}
for _, architecture := range options.Architectures {
content, err := os.Open(options.InputFile)
if err != nil {
return err
}

defer content.Close()
result, err := parser.Parse(content)
if err != nil {
return err
}

node := result.AST
anchor.PrintNode(node)

color.Cyan("Anchoring to architecture: %s\n", architecture)
image := ""
err = anchor.ParseNode(node, architecture, &image)
err = anchor.ParseNode(ctx, node, architecture, &image)
if err != nil {
return err
}

var builder strings.Builder
anchor.WriteDockerfile(&builder, node, true)
anchor.WriteDockerfile(&builder, node, true, 0, lines)
outputName := options.OutputFile
if appendArch {
outputName = fmt.Sprintf("%s.%s", outputName, architecture)
Expand Down
40 changes: 22 additions & 18 deletions docker.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package anchor

import (
"context"
"fmt"
"os/exec"
"strings"
Expand Down Expand Up @@ -28,7 +29,19 @@ func attachDockerSha(node *parser.Node) (string, error) {
return node.Value, nil
}

func WriteDockerfile(builder *strings.Builder, node *parser.Node, useOriginal bool) {
func WriteDockerfile(builder *strings.Builder, node *parser.Node, useOriginal bool, currentLine int, lines []string) int {
// this allows us to maintain things like comments and newlines in the original Dockerfile
if currentLine != 0 && node.StartLine != 0 && currentLine < node.StartLine {
for i := currentLine + 1; i < node.StartLine; i++ {
builder.WriteString(lines[i-1])
builder.WriteString("\n")
}
}
if currentLine == 0 {
currentLine = 1
} else if node.EndLine != 0 {
currentLine = node.EndLine
}
if node.Value == "FROM" || node.Value == "RUN" {
useOriginal = false
}
Expand All @@ -46,27 +59,18 @@ func WriteDockerfile(builder *strings.Builder, node *parser.Node, useOriginal bo
builder.WriteString(s)
}
for _, child := range node.Children {
WriteDockerfile(builder, child, useOriginal)
builder.WriteString("\n\n")
currentLine = WriteDockerfile(builder, child, useOriginal, currentLine, lines)
builder.WriteString("\n")
}

if node.Next != nil {
builder.WriteString(" ")
WriteDockerfile(builder, node.Next, useOriginal)
}
}

func PrintNode(node *parser.Node) {
for _, child := range node.Children {
PrintNode(child)
}

if node.Next != nil {
PrintNode(node.Next)
currentLine = WriteDockerfile(builder, node.Next, useOriginal, currentLine, lines)
}
return currentLine
}

func ParseNode(node *parser.Node, architecture string, image *string) error {
func ParseNode(ctx context.Context, node *parser.Node, architecture string, image *string) error {
if node == nil {
return nil
}
Expand All @@ -79,16 +83,16 @@ func ParseNode(node *parser.Node, architecture string, image *string) error {
}
*image = newImage
} else if node.Value == "RUN" {
err := parseRunCommand(node.Next, architecture, *image)
err := parseRunCommand(ctx, node.Next, architecture, *image)
if err != nil {
return err
}
} else if node.Next != nil {
ParseNode(node.Next, architecture, image)
ParseNode(ctx, node.Next, architecture, image)
}

for _, child := range node.Children {
ParseNode(child, architecture, image)
ParseNode(ctx, child, architecture, image)
}
return nil
}
Expand Down
11 changes: 5 additions & 6 deletions packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package anchor

import (
"bytes"
"context"
"fmt"
"os/exec"
"strings"
Expand All @@ -10,16 +11,14 @@ import (
)

func fetchPackageVersions(
packages []string,
architecture string,
image string,
ctx context.Context, packages []string, architecture string, image string,
) (map[string]string, error) {
var stdoutBuf, stderrBuf bytes.Buffer
command := "dpkg --add-architecture " + architecture + " && apt-get update && apt-cache show --"
for _, pkg := range packages {
command += " " + pkg + ":" + architecture
}
c := exec.Command("docker", "run", "--rm", image, "bash", "-c", command) // #nosec G204
c := exec.CommandContext(ctx, "docker", "run", "--rm", image, "bash", "-c", command) // #nosec G204
c.Stdout = &stdoutBuf
c.Stderr = &stderrBuf // Use a buffer to capture stderr output

Expand Down Expand Up @@ -97,7 +96,7 @@ func parseCommand(command string) []string {
return packages
}

func parseRunCommand(node *parser.Node, architecture string, image string) error {
func parseRunCommand(ctx context.Context, node *parser.Node, architecture string, image string) error {
if node == nil {
return nil
}
Expand All @@ -108,7 +107,7 @@ func parseRunCommand(node *parser.Node, architecture string, image string) error
if len(packageNames) == 0 {
continue
}
packageMap, err := fetchPackageVersions(packageNames, architecture, image)
packageMap, err := fetchPackageVersions(ctx, packageNames, architecture, image)
if err != nil {
return err
}
Expand Down

0 comments on commit c3467b2

Please sign in to comment.