Skip to content

Commit

Permalink
contrib: Catch signals to delete tmp folder in local-analyze-images
Browse files Browse the repository at this point in the history
- Create the temporary folder earlier in the app (main instead of save)
- Catch SIGINT/SIGKILL signals to delete the temporary folder and exit
  • Loading branch information
Quentin-M committed Apr 25, 2016
1 parent 51e4086 commit ff3c6ec
Showing 1 changed file with 46 additions and 25 deletions.
71 changes: 46 additions & 25 deletions contrib/analyze-local-images/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"net/http"
"os"
"os/exec"
"os/signal"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -85,6 +86,10 @@ func (s *sorter) Less(i, j int) bool {
}

func main() {
os.Exit(intMain())
}

func intMain() int {
// Parse command-line arguments.
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [options] image-id\n\nOptions:\n", os.Args[0])
Expand All @@ -94,14 +99,14 @@ func main() {

if len(flag.Args()) != 1 {
flag.Usage()
os.Exit(1)
return 1
}
imageName := flag.Args()[0]

minSeverity := types.Priority(*flagMinimumSeverity)
if !minSeverity.IsValid() {
flag.Usage()
os.Exit(1)
return 1
}

if *flagColorMode == "never" {
Expand All @@ -110,24 +115,46 @@ func main() {
color.NoColor = false
}

err := AnalyzeLocalImage(imageName, minSeverity, *flagEndpoint, *flagMyAddress)
// Create a temporary folder.
tmpPath, err := ioutil.TempDir("", "analyze-local-image-")
if err != nil {
log.Fatal(err)
log.Fatalf("Could not create temporary folder: %s", err)
}
defer os.RemoveAll(tmpPath)

// Intercept SIGINT / SIGKILl signals.
interrupt := make(chan os.Signal)
signal.Notify(interrupt, os.Interrupt, os.Kill)

// Analyze the image.
analyzeCh := make(chan error, 1)
go func() {
analyzeCh <- AnalyzeLocalImage(imageName, minSeverity, *flagEndpoint, *flagMyAddress, tmpPath)
}()

select {
case <-interrupt:
return 130
case err := <-analyzeCh:
if err != nil {
log.Print(err)
return 1
}
}
return 0
}

func AnalyzeLocalImage(imageName string, minSeverity types.Priority, endpoint, myAddress string) error {
func AnalyzeLocalImage(imageName string, minSeverity types.Priority, endpoint, myAddress, tmpPath string) error {
// Save image.
log.Printf("Saving %s to local disk (this may take some time)", imageName)
path, err := save(imageName)
defer os.RemoveAll(path)
err := save(imageName, tmpPath)
if err != nil {
return fmt.Errorf("Could not save image: %s", err)
}

// Retrieve history.
log.Println("Retrieving image history")
layerIDs, err := historyFromManifest(path)
layerIDs, err := historyFromManifest(tmpPath)
if err != nil {
layerIDs, err = historyFromCommand(imageName)
}
Expand All @@ -146,27 +173,26 @@ func AnalyzeLocalImage(imageName string, minSeverity types.Priority, endpoint, m
log.Printf("Setting up HTTP server (allowing: %s)\n", allowedHost)

ch := make(chan error)
go listenHTTP(path, allowedHost, ch)
go listenHTTP(tmpPath, allowedHost, ch)
select {
case err := <-ch:
return fmt.Errorf("An error occured when starting HTTP server: %s", err)
case <-time.After(100 * time.Millisecond):
break
}

path = "http://" + myAddress + ":" + strconv.Itoa(httpPort)
tmpPath = "http://" + myAddress + ":" + strconv.Itoa(httpPort)
}

// Analyze layers.
log.Printf("Analyzing %d layers... \n", len(layerIDs))
for i := 0; i < len(layerIDs); i++ {
log.Printf("Analyzing %s\n", layerIDs[i])

var err error
if i > 0 {
err = analyzeLayer(endpoint, path+"/"+layerIDs[i]+"/layer.tar", layerIDs[i], layerIDs[i-1])
err = analyzeLayer(endpoint, tmpPath+"/"+layerIDs[i]+"/layer.tar", layerIDs[i], layerIDs[i-1])
} else {
err = analyzeLayer(endpoint, path+"/"+layerIDs[i]+"/layer.tar", layerIDs[i], "")
err = analyzeLayer(endpoint, tmpPath+"/"+layerIDs[i]+"/layer.tar", layerIDs[i], "")
}
if err != nil {
return fmt.Errorf("Could not analyze layer: %s", err)
Expand Down Expand Up @@ -249,41 +275,36 @@ func AnalyzeLocalImage(imageName string, minSeverity types.Priority, endpoint, m
return nil
}

func save(imageName string) (string, error) {
path, err := ioutil.TempDir("", "analyze-local-image-")
if err != nil {
return "", err
}

func save(imageName, path string) error {
var stderr bytes.Buffer
save := exec.Command("docker", "save", imageName)
save.Stderr = &stderr
extract := exec.Command("tar", "xf", "-", "-C"+path)
extract.Stderr = &stderr
pipe, err := extract.StdinPipe()
if err != nil {
return "", err
return err
}
save.Stdout = pipe

err = extract.Start()
if err != nil {
return "", errors.New(stderr.String())
return errors.New(stderr.String())
}
err = save.Run()
if err != nil {
return "", errors.New(stderr.String())
return errors.New(stderr.String())
}
err = pipe.Close()
if err != nil {
return "", err
return err
}
err = extract.Wait()
if err != nil {
return "", errors.New(stderr.String())
return errors.New(stderr.String())
}

return path, nil
return nil
}

func historyFromManifest(path string) ([]string, error) {
Expand Down

0 comments on commit ff3c6ec

Please sign in to comment.