...

Source file src/github.com/datawire/ambassador/v2/cmd/entrypoint/envoy.go

Documentation: github.com/datawire/ambassador/v2/cmd/entrypoint

     1  package entrypoint
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"os"
     8  	"time"
     9  
    10  	"github.com/datawire/dlib/dcontext"
    11  	"github.com/datawire/dlib/dexec"
    12  	"github.com/datawire/dlib/dgroup"
    13  	"github.com/datawire/dlib/dlog"
    14  )
    15  
    16  func runEnvoy(ctx context.Context, envoyHUP chan os.Signal) error {
    17  	// Wait until we get a SIGHUP to start envoy.
    18  	//var bootstrap string
    19  	select {
    20  	case <-ctx.Done():
    21  		return nil
    22  	case <-envoyHUP:
    23  	}
    24  
    25  	// Try to run envoy directly, but fallback to running it inside docker if there is
    26  	// no envoy executable available.
    27  	if IsEnvoyAvailable() {
    28  		cmd := subcommand(ctx, "envoy", GetEnvoyFlags()...)
    29  		if envbool("DEV_SHUTUP_ENVOY") {
    30  			cmd.Stdout = nil
    31  			cmd.Stderr = nil
    32  		}
    33  		return cmd.Run()
    34  	} else {
    35  		// For some reason docker only sometimes passes the signal onto the process inside
    36  		// the container, so we setup this cleanup function so that in the docker case we
    37  		// can do a docker kill, just to be sure it is really dead and we don't leave an
    38  		// envoy lying around.
    39  
    40  		// Create a label unique to this invocation so we can use it to do a docker
    41  		// kill for cleanup.
    42  		label := fmt.Sprintf("amb-envoy-label-%d", os.Getpid())
    43  
    44  		snapdir := GetSnapshotDir()
    45  
    46  		group := dgroup.NewGroup(ctx, dgroup.GroupConfig{
    47  			ShutdownOnNonError: true,
    48  		})
    49  		group.Go("envoy", func(ctx context.Context) error {
    50  			// XXX: will host networking work on a mac? (probably not)
    51  			dockerArgs := []string{
    52  				"run", "-l", label, "--rm", "--network", "host",
    53  				"-v", fmt.Sprintf("%s:%s", snapdir, snapdir),
    54  				"-v", fmt.Sprintf("%s:%s", GetEnvoyBootstrapFile(), GetEnvoyBootstrapFile()),
    55  			}
    56  
    57  			if envbool("DEV_ENVOY_DOCKER_PRIVILEGED") {
    58  				dockerArgs = append(dockerArgs, "--privileged")
    59  			}
    60  
    61  			dockerArgs = append(dockerArgs, "--entrypoint", "envoy", "docker.io/datawire/aes:1.12.2")
    62  			cmd := subcommand(ctx, "docker", append(dockerArgs, GetEnvoyFlags()...)...)
    63  			if envbool("DEV_SHUTUP_ENVOY") {
    64  				cmd.Stdout = nil
    65  				cmd.Stderr = nil
    66  			}
    67  			return cmd.Run()
    68  		})
    69  		group.Go("cleanup", func(ctx context.Context) error {
    70  			<-ctx.Done()
    71  			ctx = dcontext.HardContext(ctx)
    72  
    73  			for {
    74  				cids, err := cidsForLabel(ctx, label)
    75  				if err != nil {
    76  					return err
    77  				}
    78  				if len(cids) == 0 {
    79  					return nil
    80  				}
    81  
    82  				// Give the container one second to exit
    83  				tctx, cancel := context.WithTimeout(ctx, 1*time.Second)
    84  				defer cancel()
    85  				wait := subcommand(tctx, "docker", append([]string{"wait"}, cids...)...)
    86  				wait.Stdout = nil
    87  				if err := wait.Run(); err != nil {
    88  					var exitErr *dexec.ExitError
    89  					if errors.As(err, &exitErr) {
    90  						dlog.Errorf(ctx, "docker wait: %v\n%s", err, string(exitErr.Stderr))
    91  					} else {
    92  						return err
    93  					}
    94  				}
    95  
    96  				cids, err = cidsForLabel(ctx, label)
    97  				if err != nil {
    98  					return err
    99  				}
   100  				if len(cids) == 0 {
   101  					return nil
   102  				}
   103  
   104  				kill := subcommand(ctx, "docker", append([]string{"kill"}, cids...)...)
   105  				kill.Stdout = nil
   106  				if err := wait.Run(); err != nil {
   107  					var exitErr *dexec.ExitError
   108  					if errors.As(err, &exitErr) {
   109  						dlog.Errorf(ctx, "docker kill: %v\n%s", err, string(exitErr.Stderr))
   110  					} else {
   111  						return err
   112  					}
   113  				}
   114  			}
   115  		})
   116  		return group.Wait()
   117  	}
   118  }
   119  

View as plain text