...

Source file src/github.com/Microsoft/hcsshim/cmd/hooks/wait-paths/main.go

Documentation: github.com/Microsoft/hcsshim/cmd/hooks/wait-paths

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"os"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/sirupsen/logrus"
    12  	"github.com/urfave/cli"
    13  )
    14  
    15  const (
    16  	pathsFlag   = "paths"
    17  	timeoutFlag = "timeout"
    18  )
    19  
    20  var errEmptyPaths = errors.New("paths cannot be empty")
    21  
    22  // This is a hook that waits for a specific path to appear.
    23  // The hook has required list of comma-separated paths and a default timeout in seconds.
    24  
    25  func main() {
    26  	app := newCliApp()
    27  	if err := app.Run(os.Args); err != nil {
    28  		logrus.Fatalf("%s\n", err)
    29  	}
    30  	os.Exit(0)
    31  }
    32  
    33  func newCliApp() *cli.App {
    34  	app := cli.NewApp()
    35  	app.Name = "wait-paths"
    36  	app.Usage = "Provide a list paths and an optional timeout"
    37  	app.Flags = []cli.Flag{
    38  		cli.StringFlag{
    39  			Name:     pathsFlag + ",p",
    40  			Usage:    "Comma-separated list of paths that should become available",
    41  			Required: true,
    42  		},
    43  		cli.IntFlag{
    44  			Name:  timeoutFlag + ",t",
    45  			Usage: "Timeout in seconds",
    46  			Value: 30,
    47  		},
    48  	}
    49  	app.Action = run
    50  	return app
    51  }
    52  
    53  func run(cCtx *cli.Context) error {
    54  	timeout := cCtx.GlobalInt(timeoutFlag)
    55  
    56  	pathsVal := cCtx.GlobalString(pathsFlag)
    57  	if pathsVal == "" {
    58  		return errEmptyPaths
    59  	}
    60  	paths := strings.Split(cCtx.GlobalString(pathsFlag), ",")
    61  
    62  	waitCtx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
    63  	defer cancel()
    64  
    65  	for _, path := range paths {
    66  		for {
    67  			if _, err := os.Stat(path); err != nil {
    68  				if !os.IsNotExist(err) {
    69  					return err
    70  				}
    71  				select {
    72  				case <-waitCtx.Done():
    73  					return fmt.Errorf("timeout while waiting for path %q to appear: %w", path, context.DeadlineExceeded)
    74  				default:
    75  					time.Sleep(time.Millisecond * 10)
    76  					continue
    77  				}
    78  			}
    79  			break
    80  		}
    81  	}
    82  	return nil
    83  }
    84  

View as plain text