mirror of https://github.com/docker/docs.git
Merge pull request #1940 from nathanleclaire/gh_api_rate_limit
Add --github-api-token flag and troubleshooting section
This commit is contained in:
commit
cc00ece828
72
README.md
72
README.md
|
@ -54,3 +54,75 @@ Full documentation [is available here](https://docs.docker.com/machine/).
|
|||
|
||||
Want to hack on Machine? Please start with the [Contributing Guide](https://github.com/docker/machine/blob/master/CONTRIBUTING.md).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Docker Machine tries to do the right thing in a variety of scenarios but
|
||||
sometimes things do not go according to plan. Here is a quick troubleshooting
|
||||
guide which may help you to resolve of the issues you may be seeing.
|
||||
|
||||
Note that some of the suggested solutions are only available on the Docker
|
||||
Machine master branch. If you need them, consider compiling Docker Machine from
|
||||
source. There are also [unofficial pre-compiled master
|
||||
binaries](https://docker-machine-builds.evanhazlett.com/latest) hosted by
|
||||
[@ehazlett](https://github.com/ehazlett).
|
||||
|
||||
#### `docker-machine` hangs
|
||||
|
||||
A common issue with Docker Machine is that it will hang when attempting to start
|
||||
up the virtual machine. Since starting the machine is part of the `create`
|
||||
process, `create` is often where these types of errors show up.
|
||||
|
||||
A hang could be due to a variety of factors, but the most common suspect is
|
||||
networking. Consider the following:
|
||||
|
||||
- Are you using a VPN? If so, try disconnecting and see if creation will
|
||||
succeed without the VPN. Some VPN software aggressively controls routes and
|
||||
you may need to [manually add the route](https://github.com/docker/machine/issues/1500#issuecomment-121134958).
|
||||
- Are you connected to a proxy server, corporate or otherwise? If so, take a
|
||||
look at the `--no-proxy` flag for `env` and at [setting environment variables
|
||||
for the created Docker Engine](https://docs.docker.com/machine/reference/create/#specifying-configuration-options-for-the-created-docker-engine).
|
||||
- Are there a lot of host-only interfaces listed by the command `VBoxManage list
|
||||
hostonlyifs`? If so, this has sometimes been known to cause bugs. Consider
|
||||
removing the ones you are not using (`VBoxManage hostonlyif remove name`) and
|
||||
trying machine creation again.
|
||||
|
||||
We are keenly aware of this as an issue and working towards a set of solutions
|
||||
which is robust for all users, so please give us feedback and/or report issues,
|
||||
workarounds, and desired workflows as you discover them.
|
||||
|
||||
#### Machine creation errors out before finishing
|
||||
|
||||
If you see messages such as "exit status 1" creating machines with VirtualBox,
|
||||
this frequently indicates that there is an issue with VirtualBox itself. Please
|
||||
[file an issue](https://github.com/docker/machine/issues/new) and include a link
|
||||
to a [Github Gist](https://gist.github.com/) with the output of the VirtualBox
|
||||
log (usually located at
|
||||
`$HOME/.docker/machine/machines/machinename/machinename/Logs/VBox.log`), as well
|
||||
as the output of running the Docker Machine command which is failing with the
|
||||
global `--debug` flag enabled. This will help us to track down which versions
|
||||
of VirtualBox are failing where, and under which conditions.
|
||||
|
||||
If you see messages such as "exit status 255", this frequently indicates there
|
||||
has been an issue with SSH. Please investigate your SSH configuration if you
|
||||
have one, and/or [file an issue](https://github.com/docker/machine/issues).
|
||||
|
||||
#### "You may be getting rate limited by Github" error message
|
||||
|
||||
In order to `create` or `upgrade` virtual machines running Docker, Docker
|
||||
Machine will check the Github API for the latest release of the [boot2docker
|
||||
operating system](https://github.com/boot2docker/boot2docker). The Github API
|
||||
allows for a small number of unauthenticated requests from a given client, but
|
||||
if you share an IP address with many other users (e.g. in an office), you may
|
||||
get rate limited by their API, and Docker Machine will error out with messages
|
||||
indicating this.
|
||||
|
||||
In order to work around this issue, you can [generate a
|
||||
token](https://help.github.com/articles/creating-an-access-token-for-command-line-use/)
|
||||
and pass it to Docker Machine using the global `--github-api-token` flag like
|
||||
so:
|
||||
|
||||
```console
|
||||
$ docker-machine --github-api-token=token create -d virtualbox newbox
|
||||
```
|
||||
|
||||
This should eliminate any issues you've been experiencing with rate limiting.
|
||||
|
|
|
@ -15,6 +15,10 @@ import (
|
|||
"github.com/docker/machine/libmachine/log"
|
||||
)
|
||||
|
||||
var (
|
||||
GithubApiToken string
|
||||
)
|
||||
|
||||
const (
|
||||
timeout = time.Second * 5
|
||||
)
|
||||
|
@ -70,15 +74,36 @@ func NewB2dUtils(githubApiBaseUrl, githubBaseUrl, storePath string) *B2dUtils {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *B2dUtils) getReleasesRequest() (*http.Request, error) {
|
||||
apiUrl := fmt.Sprintf("%s/repos/boot2docker/boot2docker/releases", b.githubApiBaseUrl)
|
||||
|
||||
req, err := http.NewRequest("GET", apiUrl, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if GithubApiToken != "" {
|
||||
req.Header.Add("Authorization", fmt.Sprintf("token %s", GithubApiToken))
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Get the latest boot2docker release tag name (e.g. "v0.6.0").
|
||||
// FIXME: find or create some other way to get the "latest release" of boot2docker since the GitHub API has a pretty low rate limit on API requests
|
||||
func (b *B2dUtils) GetLatestBoot2DockerReleaseURL() (string, error) {
|
||||
client := getClient()
|
||||
apiUrl := fmt.Sprintf("%s/repos/boot2docker/boot2docker/releases", b.githubApiBaseUrl)
|
||||
rsp, err := client.Get(apiUrl)
|
||||
|
||||
req, err := b.getReleasesRequest()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
rsp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer rsp.Body.Close()
|
||||
|
||||
var t []struct {
|
||||
|
|
|
@ -56,3 +56,31 @@ func TestDownloadIso(t *testing.T) {
|
|||
t.Fatalf("expected data \"%s\"; received \"%s\"", testData, string(data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetReleasesRequestNoToken(t *testing.T) {
|
||||
GithubApiToken = ""
|
||||
b2d := NewB2dUtils("", "", "/tmp/store")
|
||||
req, err := b2d.getReleasesRequest()
|
||||
if err != nil {
|
||||
t.Fatal("Expected err to be nil, got ", err)
|
||||
}
|
||||
|
||||
if req.Header.Get("Authorization") != "" {
|
||||
t.Fatal("Expected not to get an 'Authorization' header, but got one: ", req.Header.Get("Authorization"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetReleasesRequest(t *testing.T) {
|
||||
expectedToken := "CATBUG"
|
||||
GithubApiToken = expectedToken
|
||||
b2d := NewB2dUtils("", "", "/tmp/store")
|
||||
|
||||
req, err := b2d.getReleasesRequest()
|
||||
if err != nil {
|
||||
t.Fatal("Expected err to be nil, got ", err)
|
||||
}
|
||||
|
||||
if req.Header.Get("Authorization") != fmt.Sprintf("token %s", expectedToken) {
|
||||
t.Fatal("Header was not set as expected: ", req.Header.Get("Authorization"))
|
||||
}
|
||||
}
|
||||
|
|
11
main.go
11
main.go
|
@ -7,10 +7,10 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
|
||||
"github.com/docker/machine/commands"
|
||||
"github.com/docker/machine/commands/mcndirs"
|
||||
"github.com/docker/machine/libmachine/log"
|
||||
"github.com/docker/machine/libmachine/mcnutils"
|
||||
"github.com/docker/machine/libmachine/ssh"
|
||||
"github.com/docker/machine/version"
|
||||
)
|
||||
|
@ -75,9 +75,12 @@ func main() {
|
|||
app.Author = "Docker Machine Contributors"
|
||||
app.Email = "https://github.com/docker/machine"
|
||||
app.Before = func(c *cli.Context) error {
|
||||
// TODO: Need better handling of config, everything is too
|
||||
// complected together right now.
|
||||
if c.GlobalBool("native-ssh") {
|
||||
ssh.SetDefaultClient(ssh.Native)
|
||||
}
|
||||
mcnutils.GithubApiToken = c.GlobalString("github-api-token")
|
||||
return nil
|
||||
}
|
||||
app.Commands = commands.Commands
|
||||
|
@ -120,6 +123,12 @@ func main() {
|
|||
Usage: "Private key used in client TLS auth",
|
||||
Value: "",
|
||||
},
|
||||
cli.StringFlag{
|
||||
EnvVar: "MACHINE_GITHUB_API_TOKEN",
|
||||
Name: "github-api-token",
|
||||
Usage: "Token to use for requests to the Github API",
|
||||
Value: "",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
EnvVar: "MACHINE_NATIVE_SSH",
|
||||
Name: "native-ssh",
|
||||
|
|
Loading…
Reference in New Issue