Beispiel #1
0
// 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)
	}
}
Beispiel #2
0
// 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
}
Beispiel #3
0
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)
}
Beispiel #4
0
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
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
// 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
}
Beispiel #8
0
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)
}
Beispiel #9
0
// 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
}