// CopyDirTree copies all files from srcDir to destDir func CopyDirTree(srcDir, destDir string) { srcs, err := filepath.Glob(srcDir) if err != nil { blog.Exit(err, ": Error in generating matches for", srcDir) } args := []string{"-rp"} dirs := append(args, append(srcs, destDir)...) cpCmd := exec.Command("cp", dirs...) err = cpCmd.Run() if err != nil { blog.Exit(err, ": Error in copying", srcDir, " to ", destDir) } }
// GetRegistryURL determines the full URL, with or without HTTP Basic Auth, needed to // access the registry or Docker Hub. func GetRegistryURL() (URL string, hubAPI bool, BasicAuth string, XRegistryAuth string) { basicAuth, fullRegistry, XRegistryAuth := RegAuth(RegistrySpec) if *AuthRegistry == true { if basicAuth == "" { blog.Exit("Registry auth could not be determined from docker config.") } BasicAuth = basicAuth } if *HTTPSRegistry == false { URL = "http://" + RegistrySpec } else { // HTTPS is required if strings.HasPrefix(fullRegistry, "https://") { URL = fullRegistry } else { URL = "https://" + RegistrySpec } if *RegistryTokenAuth == true { hubAPI = true } if strings.Contains(URL, "docker.io") || strings.Contains(URL, "gcr.io") { hubAPI = true if *RegistryTokenAuth == false { blog.Warn("Forcing --registrytokenauth=true, as required for Docker Hub and Google Container Registry") *RegistryTokenAuth = true } } } return }
func setupLogging() { consoleLog := blog.NewConsoleLogWriter() consoleLog = consoleLog.SetColor(true) blog.AddFilter("stdout", CONSOLELOGLEVEL, consoleLog) f, e := os.OpenFile(LOGFILENAME, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if e != nil { blog.Exit(e, ": Error in opening log file: ", LOGFILENAME) } f.Close() flw := blog.NewFileLogWriter(LOGFILENAME, false) blog.AddFilter("file", FILELOGLEVEL, flw) }
func getScriptsToRun() (scripts []Script) { // get default scripts defaultScripts, err := getScripts(DefaultScriptsDir) if err != nil { blog.Exit(err, ": Error in getting default scripts") } // get user-specified scripts userScripts, err := getScripts(UserScriptsDir) if err != nil { blog.Warn(err, ": Error in getting user-specified scripts") } scripts = append(defaultScripts, userScripts...) return }
// getAuthConfig returns the Base64-encoded JSONified AuthConfig struct needed to authorize // with the Docker Remote API. func getAuthConfig(user, password, auth, email, registry string) (authConfig string) { ac := AuthConfig{ Username: user, Password: password, Auth: auth, Email: email, ServerAddress: registry, } jsonString, err := json.Marshal(ac) if err != nil { blog.Exit("Failed to marshal authconfig") } dst := make([]byte, base64.URLEncoding.EncodedLen(len(jsonString))) base64.URLEncoding.Encode(dst, jsonString) authConfig = string(dst) return }
// doFlags defines the cmdline Usage string and parses flag options. func doFlags() { flag.Usage = func() { fmt.Fprintf(os.Stderr, " Usage: %s [OPTIONS] REGISTRY REPO [REPO...]\n", os.Args[0]) fmt.Fprintf(os.Stderr, "\n REGISTRY:\n") fmt.Fprintf(os.Stderr, "\tURL of your Docker registry; use index.docker.io for Docker Hub, use local.host to collect images from local Docker host\n") fmt.Fprintf(os.Stderr, "\n REPO:\n") fmt.Fprintf(os.Stderr, "\tOne or more repos to gather info about; if no repo is specified Collector will gather info on *all* repos in the Registry\n") fmt.Fprintf(os.Stderr, "\n Environment variables:\n") fmt.Fprintf(os.Stderr, "\tCOLLECTOR_DIR: (Required) Directory that contains the \"data\" folder with Collector default scripts, e.g., $GOPATH/src/github.com/banyanops/collector\n") fmt.Fprintf(os.Stderr, "\tCOLLECTOR_ID: ID provided by Banyan web interface to register Collector with the Banyan service\n") fmt.Fprintf(os.Stderr, "\tBANYAN_HOST_DIR: Host directory mounted into Collector/Target containers where results are stored (default: $HOME/.banyan)\n") fmt.Fprintf(os.Stderr, "\tBANYAN_DIR: (Specify only in Dockerfile) Directory in the Collector container where host directory BANYAN_HOST_DIR is mounted\n") fmt.Fprintf(os.Stderr, "\tDOCKER_{HOST,CERT_PATH,TLS_VERIFY}: If set, e.g., by docker-machine, then they take precedence over --dockerProto and --dockerAddr\n") printExampleUsage() fmt.Fprintf(os.Stderr, " Options:\n") flag.PrintDefaults() } flag.Parse() if config.COLLECTORDIR() == "" { flag.Usage() os.Exit(1) } if len(flag.Args()) < 1 { flag.Usage() os.Exit(1) } if *dockerProto != "unix" && *dockerProto != "tcp" { flag.Usage() os.Exit(1) } requiredDirs := []string{config.BANYANDIR(), filepath.Dir(*imageList), filepath.Dir(*repoList), *config.BanyanOutDir, collector.DefaultScriptsDir, collector.UserScriptsDir, collector.BinDir} for _, dir := range requiredDirs { blog.Debug("Creating directory: " + dir) err := fsutil.CreateDirIfNotExist(dir) if err != nil { blog.Exit(err, ": Error in creating a required directory: ", dir) } } collector.RegistrySpec = flag.Arg(0) // EqualFold: case insensitive comparison if strings.EqualFold(flag.Arg(0), "local.host") { collector.LocalHost = true } //nextMaxImages = *maxImages }
// JWT uses the JWT provider to obtain DockerConfig. func JWT() credentialprovider.DockerConfig { enabled := jprovider.Enabled() if !enabled { blog.Exit("Failed to enable JWT credential provider") } DockerConfig := jprovider.Provide() /* for registry, entry := range DockerConfig { fmt.Println("Registry", registry) fmt.Println("\tUsername:"******"\tPassword:"******"\tEmail:", entry.Email) fieldValue := entry.Username + ":" + entry.Password fmt.Println("\tAuth:", base64.StdEncoding.EncodeToString([]byte(fieldValue))) } */ return DockerConfig }
func main() { doFlags() setupLogging() //verifyVolumes() copyBanyanData() // setup connection to docker daemon's unix/tcp socket var e error collector.DockerTransport, e = collector.NewDockerTransport(*dockerProto, *dockerAddr) if e != nil { blog.Exit(e, ": Error in connecting to docker remote API socket") } authToken := RegisterCollector() // Set output writers SetOutputWriters(authToken) SetupBanyanStatus(authToken) checkConfigUpdate(true) if collector.LocalHost == false && collector.RegistryAPIURL == "" { collector.RegistryAPIURL, collector.HubAPI, collector.BasicAuth, collector.XRegistryAuth = collector.GetRegistryURL() blog.Info("registry API URL: %s", collector.RegistryAPIURL) } // Images we have processed already processedImages := collector.NewImageSet() e = getImageList(processedImages) if e != nil { blog.Info("Fresh start: No previously collected images were found in %s", *imageList) } blog.Debug(processedImages) // Image Metadata we have already seen MetadataSet := collector.NewMetadataSet() PulledList := []collector.ImageMetadataInfo{} // Main infinite loop. InfLoop(authToken, processedImages, MetadataSet, PulledList) }
// RegAuth takes as input the name of a registry, and it parses the contents of // $HOME/.dockercfg or $HOME/.docker/config.json to return the user authentication info and registry URL. // TODO: Change this to return authConfig instead of user&password, and then // use X-Registry-Auth in the HTTP request header. func RegAuth(registry string) (basicAuth, fullRegistry, authConfig string) { if *AuthRegistry == false { fullRegistry = registry return } if *GCRMetadata { return GCRMetadataRegAuth(registry) } if *GCRKeyFile > "" { return GCRKeyFileRegAuth(registry) } if len(DockerConfig) == 0 { major, minor, revision, err := dockerVersion() if err != nil { blog.Exit("Could not determine Docker version") } if major < 1 || (major == 1 && minor <= 2) { blog.Exit("Unsupported docker version %d.%d.%d", major, minor, revision) } if major == 1 && minor <= 6 { DockerConfig = os.Getenv("HOME") + "/.dockercfg" } else { DockerConfig = os.Getenv("HOME") + "/.docker/config.json" } } useDotDockerDir := strings.Contains(DockerConfig, ".docker/config.json") data, err := ioutil.ReadFile(DockerConfig) if err != nil { if useDotDockerDir == false { blog.Exit("Could not read", DockerConfig) } // new .docker/config.json didn't work, so try the old .dockercfg blog.Error("Could not read %s, trying $HOME/.dockercfg", DockerConfig) DockerConfig = os.Getenv("HOME") + "/.dockercfg" useDotDockerDir = false data, err = ioutil.ReadFile(DockerConfig) if err != nil { blog.Exit("Could not read", DockerConfig) } } var dcj DockerConfigJSON var das DockerAuthSet if useDotDockerDir { err = json.Unmarshal(data, &dcj) das = dcj.Auths } else { err = json.Unmarshal(data, &das) } if err != nil { blog.Error(err, "Couldn't JSON unmarshal from docker auth data") return } for r, d := range das { if r == registry || r == "https://"+registry || r == "https://"+registry+"/v1/" { encData, err := base64.StdEncoding.DecodeString(d.Auth) if err != nil { blog.Error(err, ": error") return } up := strings.Split(string(encData), ":") if len(up) != 2 { blog.Error("Invalid auth: %s", string(encData)) return } if strings.HasSuffix(registry, "/v1/") { registry = registry[0 : len(registry)-4] } user := up[0] password := up[1] basicAuth = d.Auth fullRegistry = registry authConfig = getAuthConfig(user, password, d.Auth, d.Email, r) return } } return }