contrib: Catch signals to delete tmp folder in local-analyze-images

- Create the temporary folder earlier in the app (main instead of save)
- Catch SIGINT/SIGKILL signals to delete the temporary folder and exit
pull/158/head
Quentin Machu 8 years ago
parent 51e4086298
commit ff3c6eccc8

@ -27,6 +27,7 @@ import (
"net/http"
"os"
"os/exec"
"os/signal"
"sort"
"strconv"
"strings"
@ -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])
@ -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" {
@ -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)
}
@ -146,7 +173,7 @@ 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)
@ -154,7 +181,7 @@ func AnalyzeLocalImage(imageName string, minSeverity types.Priority, endpoint, m
break
}
path = "http://" + myAddress + ":" + strconv.Itoa(httpPort)
tmpPath = "http://" + myAddress + ":" + strconv.Itoa(httpPort)
}
// Analyze layers.
@ -162,11 +189,10 @@ func AnalyzeLocalImage(imageName string, minSeverity types.Priority, endpoint, m
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)
@ -249,12 +275,7 @@ 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
@ -262,28 +283,28 @@ func save(imageName string) (string, error) {
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) {

Loading…
Cancel
Save