Example #1
0
func getInstalledVersions(pattern string) []dockerversion.Version {
	searchPath := filepath.Join(getVersionsDir(), pattern)
	versions, _ := filepath.Glob(searchPath)

	var results []dockerversion.Version
	for _, versionDir := range versions {
		version := dockerversion.Parse(filepath.Base(versionDir))

		if version.IsExperimental() {
			experimentalDockerPath := filepath.Join(versionDir, getBinaryName())
			experimentalVersion, err := getDockerVersion(experimentalDockerPath, true)
			if err != nil {
				writeDebug("Unable to get version of installed experimental version at %s.\n%s", versionDir, err)
				continue
			}
			version.SemVer = experimentalVersion.SemVer
		}

		results = append(results, version)
	}

	if glob.Glob(pattern, dockerversion.SystemAlias) {
		systemVersion, err := getSystemDockerVersion()
		if err == nil {
			results = append(results, systemVersion)
		}
	}

	dockerversion.Sort(results)
	return results
}
Example #2
0
func getDockerVersion(dockerPath string, includeBuild bool) (dockerversion.Version, error) {
	rawVersion, _ := exec.Command(dockerPath, "-v").Output()

	writeDebug("%s -v output: %s", dockerPath, rawVersion)

	versionRegex := regexp.MustCompile(`^Docker version (.+), build ([^,]+),?`)
	match := versionRegex.FindSubmatch(rawVersion)
	if len(match) < 2 {
		return dockerversion.Version{}, errors.New("Could not detect docker version.")
	}

	version := string(match[1][:])
	build := string(match[2][:])
	if includeBuild {
		version = fmt.Sprintf("%s+%s", version, build)
	}
	return dockerversion.Parse(version), nil
}
Example #3
0
func getAvailableVersions(pattern string) []dockerversion.Version {
	gh := buildGithubClient()
	options := &github.ListOptions{PerPage: 100}

	var allReleases []github.RepositoryRelease
	for {
		releases, response, err := gh.Repositories.ListReleases("docker", "docker", options)
		if err != nil {
			warnWhenRateLimitExceeded(err, response)
			die("Unable to retrieve list of Docker releases from GitHub", err, retCodeRuntimeError)
		}
		allReleases = append(allReleases, releases...)
		if response.StatusCode != 200 {
			die("Unable to retrieve list of Docker releases from GitHub (Status %s).", nil, retCodeRuntimeError, response.StatusCode)
		}
		if response.NextPage == 0 {
			break
		}
		options.Page = response.NextPage
	}

	versionRegex := regexp.MustCompile(`^v([1-9]+\.\d+\.\d+)$`)
	patternRegex, err := regexp.Compile(pattern)
	if err != nil {
		die("Invalid pattern.", err, retCodeInvalidOperation)
	}

	var results []dockerversion.Version
	for _, release := range allReleases {
		version := *release.Name
		match := versionRegex.FindStringSubmatch(version)
		if len(match) > 1 && patternRegex.MatchString(version) {
			results = append(results, dockerversion.Parse(match[1]))
		}
	}

	dockerversion.Sort(results)
	return results
}
Example #4
0
func main() {
	app := cli.NewApp()
	app.Name = "Docker Version Manager"
	app.Usage = "Manage multiple versions of the Docker client"
	app.Version = fmt.Sprintf("%s (%s)", dvmVersion, dvmCommit)
	app.EnableBashCompletion = true
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "github-token", EnvVar: "GITHUB_TOKEN", Usage: "Increase the github api rate limit by specifying your github personal access token."},
		cli.StringFlag{Name: "dvm-dir", EnvVar: "DVM_DIR", Usage: "Specify an alternate DVM home directory, defaults to ~/.dvm."},
		cli.StringFlag{Name: "shell", EnvVar: "SHELL", Usage: "Specify the shell format in which environment variables should be output, e.g. powershell, cmd or sh/bash. Defaults to sh/bash."},
		cli.BoolFlag{Name: "debug", Usage: "Print additional debug information."},
		cli.BoolFlag{Name: "silent", EnvVar: "DVM_SILENT", Usage: "Suppress output. Errors will still be displayed."},
	}
	app.Commands = []cli.Command{
		{
			Name:    "install",
			Aliases: []string{"i"},
			Usage:   "dvm install [<version>], dvm install experimental\n\tInstall a Docker version, using $DOCKER_VERSION if the version is not specified.",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "mirror-url", EnvVar: "DVM_MIRROR_URL", Usage: "Specify an alternate URL from which to download the Docker client. Defaults to https://get.docker.com/builds"},
				cli.BoolFlag{Name: "nocheck", EnvVar: "DVM_NOCHECK", Usage: "Do not check if version exists (use with caution)."},
			},
			Action: func(c *cli.Context) error {
				setGlobalVars(c)

				versionName := c.Args().First()
				if versionName == "" {
					versionName = getDockerVersionVar()
				}
				version := dockerversion.Parse(versionName)

				install(version)
				return nil
			},
		},
		{
			Name:  "uninstall",
			Usage: "dvm uninstall <version>\n\tUninstall a Docker version.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				version := dockerversion.Parse(c.Args().First())
				uninstall(version)
				return nil
			},
		},
		{
			Name:  "use",
			Usage: "dvm use [<version>], dvm use system, dvm use experimental\n\tUse a Docker version, using $DOCKER_VERSION if the version is not specified.",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "mirror-url", EnvVar: "DVM_MIRROR_URL", Usage: "Specify an alternate URL from which to download the Docker client. Defaults to https://get.docker.com/builds"},
				cli.BoolFlag{Name: "nocheck", EnvVar: "DVM_NOCHECK", Usage: "Do not check if version exists (use with caution)."},
			},
			Action: func(c *cli.Context) error {
				setGlobalVars(c)

				versionName := c.Args().First()
				if versionName == "" {
					versionName = getDockerVersionVar()
				}
				version := dockerversion.Parse(versionName)

				use(version)
				return nil
			},
		},
		{
			Name:  "deactivate",
			Usage: "dvm deactivate\n\tUndo the effects of `dvm` on current shell.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				deactivate()
				return nil
			},
		},
		{
			Name:  "current",
			Usage: "dvm current\n\tPrint the current Docker version.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				current()
				return nil
			},
		},
		{
			Name:  "which",
			Usage: "dvm which\n\tPrint the path to the current Docker version.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				which()
				return nil
			},
		},
		{
			Name:  "alias",
			Usage: "dvm alias <alias> <version>\n\tCreate an alias to a Docker version.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				name := c.Args().Get(0)
				version := dockerversion.Parse(c.Args().Get(1))
				alias(name, version)
				return nil
			},
		},
		{
			Name:  "unalias",
			Usage: "dvm unalias <alias>\n\tRemove a Docker version alias.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				name := c.Args().First()
				unalias(name)
				return nil
			},
		},
		{
			Name:    "list",
			Aliases: []string{"ls"},
			Usage:   "dvm list [<pattern>]\n\tList installed Docker versions.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				list(c.Args().First())
				return nil
			},
		},
		{
			Name:    "list-remote",
			Aliases: []string{"ls-remote"},
			Usage:   "dvm list-remote [<pattern>]\n\tList available Docker versions.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				listRemote(c.Args().First())
				return nil
			},
		},
		{
			Name:    "list-alias",
			Aliases: []string{"ls-alias"},
			Usage:   "dvm list-alias\n\tList Docker version aliases.",
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				listAlias()
				return nil
			},
		},
	}

	if upgradeDisabled != "true" {
		app.Commands = append(app.Commands, cli.Command{
			Name:  "upgrade",
			Usage: "dvm upgrade\n\tUpgrade dvm to the latest release.",
			Flags: []cli.Flag{
				cli.BoolFlag{Name: "check", Usage: "Checks if an newer version of dvm is available, but does not perform the upgrade."},
				cli.StringFlag{Name: "version", Usage: "Upgrade to the specified version."},
			},
			Action: func(c *cli.Context) error {
				setGlobalVars(c)
				upgrade(c.Bool("check"), c.String("version"))
				return nil
			},
		})
	}

	app.Run(os.Args)
}