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 }