github.com/chenbh/concourse/v6@v6.4.2/worker/workercmd/guardian.go (about)

     1  // +build linux
     2  
     3  package workercmd
     4  
     5  import (
     6  	"fmt"
     7  	"os"
     8  	"os/exec"
     9  	"path/filepath"
    10  	"strings"
    11  	"syscall"
    12  
    13  	"code.cloudfoundry.org/lager"
    14  	"code.cloudfoundry.org/localip"
    15  	concourseCmd "github.com/chenbh/concourse/v6/cmd"
    16  	"github.com/tedsuo/ifrit"
    17  	"github.com/tedsuo/ifrit/grouper"
    18  )
    19  
    20  // This prepares the Guardian runtime using the gdn binary.
    21  // The gdn binary exposes Guardian's functionality via a Garden server.
    22  func (cmd *WorkerCommand) guardianRunner(logger lager.Logger) (ifrit.Runner, error) {
    23  	depotDir := filepath.Join(cmd.WorkDir.Path(), "depot")
    24  
    25  	// must be readable by other users so unprivileged containers can run their
    26  	// own `initc' process
    27  	err := os.MkdirAll(depotDir, 0755)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	members := grouper.Members{}
    33  
    34  	gdnConfigFlag := []string{}
    35  
    36  	if cmd.Guardian.Config.Path() != "" {
    37  		gdnConfigFlag = append(gdnConfigFlag, "--config", cmd.Guardian.Config.Path())
    38  	}
    39  
    40  	gdnServerFlags := []string{
    41  		"--bind-ip", cmd.BindIP.IP.String(),
    42  		"--bind-port", fmt.Sprintf("%d", cmd.BindPort),
    43  
    44  		"--depot", depotDir,
    45  		"--properties-path", filepath.Join(cmd.WorkDir.Path(), "garden-properties.json"),
    46  
    47  		"--time-format", "rfc3339",
    48  
    49  		// disable graph and grootfs setup; all images passed to Concourse
    50  		// containers are raw://
    51  		"--no-image-plugin",
    52  	}
    53  
    54  	gdnServerFlags = append(gdnServerFlags, detectGuardianFlags(logger)...)
    55  
    56  	if cmd.Guardian.DNS.Enable {
    57  		dnsProxyRunner, err := cmd.dnsProxyRunner(logger.Session("dns-proxy"))
    58  		if err != nil {
    59  			return nil, err
    60  		}
    61  
    62  		lip, err := localip.LocalIP()
    63  		if err != nil {
    64  			return nil, err
    65  		}
    66  
    67  		members = append(members, grouper.Member{
    68  			Name: "dns-proxy",
    69  			Runner: concourseCmd.NewLoggingRunner(
    70  				logger.Session("dns-proxy-runner"),
    71  				dnsProxyRunner,
    72  			),
    73  		})
    74  
    75  		gdnServerFlags = append(gdnServerFlags, "--dns-server", lip)
    76  
    77  		// must permit access to host network in order for DNS proxy address to be
    78  		// reachable
    79  		gdnServerFlags = append(gdnServerFlags, "--allow-host-access")
    80  	}
    81  
    82  	gdnArgs := append(gdnConfigFlag, append([]string{"server"}, gdnServerFlags...)...)
    83  
    84  	bin := "gdn"
    85  	if cmd.Guardian.Bin != "" {
    86  		bin = cmd.Guardian.Bin
    87  	}
    88  
    89  	gdnCmd := exec.Command(bin, gdnArgs...)
    90  	gdnCmd.Stdout = os.Stdout
    91  	gdnCmd.Stderr = os.Stderr
    92  	gdnCmd.SysProcAttr = &syscall.SysProcAttr{
    93  		Pdeathsig: syscall.SIGKILL,
    94  	}
    95  
    96  	members = append(members, grouper.Member{
    97  		Name: "gdn",
    98  		Runner: concourseCmd.NewLoggingRunner(
    99  			logger.Session("gdn-runner"),
   100  			CmdRunner{gdnCmd},
   101  		),
   102  	})
   103  
   104  	return grouper.NewParallel(os.Interrupt, members), nil
   105  }
   106  
   107  func detectGuardianFlags(logger lager.Logger) []string {
   108  	env := os.Environ()
   109  
   110  	flags := []string{}
   111  	for _, e := range env {
   112  		spl := strings.SplitN(e, "=", 2)
   113  		if len(spl) != 2 {
   114  			logger.Info("bogus-env", lager.Data{"env": spl})
   115  			continue
   116  		}
   117  
   118  		name := spl[0]
   119  		val := spl[1]
   120  
   121  		if !strings.HasPrefix(name, guardianEnvPrefix) {
   122  			continue
   123  		}
   124  
   125  		strip := strings.Replace(name, guardianEnvPrefix, "", 1)
   126  		flag := flagify(strip)
   127  
   128  		logger.Info("forwarding-garden-env-var", lager.Data{
   129  			"env":  name,
   130  			"flag": flag,
   131  		})
   132  
   133  		vals := strings.Split(val, ",")
   134  
   135  		for _, v := range vals {
   136  			flags = append(flags, "--"+flag, v)
   137  		}
   138  
   139  		// clear out env (as twentythousandtonnesofcrudeoil does)
   140  		_ = os.Unsetenv(name)
   141  	}
   142  
   143  	return flags
   144  }
   145  
   146  func flagify(env string) string {
   147  	return strings.Replace(strings.ToLower(env), "_", "-", -1)
   148  }