From 95ad9e457388472e2c7f8175e0bf5444ba02a76a Mon Sep 17 00:00:00 2001 From: Antony Messerli Date: Fri, 22 Mar 2013 10:28:51 -0500 Subject: [PATCH 01/20] Adding support for the Rackspace Open Cloud --- README.md | 24 +++++++++++++++++++++--- Vagrantfile | 21 +++++++++++++++++---- puppet/modules/docker/manifests/init.pp | 24 ++++++++++++++++-------- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 68473ce383aa5..60ee1c56e4ea6 100644 --- a/README.md +++ b/README.md @@ -94,10 +94,11 @@ Docker probably works on other distributions featuring a recent kernel, the AUFS Installing with Vagrant ----------------------- -Currently, Docker can be installed with Vagrant both on your localhost -with VirtualBox as well as on Amazon EC2. Vagrant 1.1 is required for -EC2, but deploying is as simple as: +Currently, Docker can be installed with Vagrant on your localhost with VirtualBox, +Amazon EC2, and Rackspace Cloud Servers. Vagrant 1.1 is required for EC2 and +Rackspace Cloud, but deploying is as simple as: +Amazon EC2: ```bash $ export AWS_ACCESS_KEY_ID=xxx \ AWS_SECRET_ACCESS_KEY=xxx \ @@ -114,6 +115,23 @@ The environment variables are: * `AWS_KEYPAIR_NAME` - The name of the keypair used for this EC2 instance * `AWS_SSH_PRIVKEY` - The path to the private key for the named keypair +Rackspace Cloud Servers: +```bash +$ export RS_USERNAME=xxx \ + RS_API_KEY=xxx \ + RS_PUBLIC_KEY=xxx \ + RS_PRIVATE_KEY=xxx +$ vagrant plugin install vagrant-rackspace +$ vagrant up --provider=rackspace +``` + +The environment variables are: + +* `RS_USERNAME` - The user name used to make requests to Rackspace Cloud +* `RS_API_KEY` - The secret key to make Rackspace Cloud API requests +* `RS_PUBLIC_KEY` - The location on disk to your public key that will be injected into the instance. +* `RS_PRIVATE_KEY` - The private key that matches the public key being injected. + For VirtualBox, you can simply ignore setting any of the environment variables and omit the `provider` flag. VirtualBox is still supported with Vagrant <= 1.1: diff --git a/Vagrantfile b/Vagrantfile index e847659848ec2..e58d83ee1226d 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -31,6 +31,9 @@ Vagrant.configure("1") do |config| # computers to access the VM, whereas host only networking does not. # config.vm.forward_port 80, 8080 + # Ensure puppet is installed on the instance + config.vm.provision :shell, :inline => "apt-get -qq update; apt-get install -y puppet" + # Share an additional folder to the guest VM. The first argument is # an identifier, the second is the path on the guest to mount the # folder, and the third is the path on the host to the actual folder. @@ -103,17 +106,27 @@ Vagrant.configure("2") do |config| config.vm.provider :aws do |aws| config.vm.box = "dummy" config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box" - aws.access_key_id = ENV["AWS_ACCESS_KEY_ID"] + aws.access_key_id = ENV["AWS_ACCESS_KEY_ID"] aws.secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"] aws.keypair_name = ENV["AWS_KEYPAIR_NAME"] aws.ssh_private_key_path = ENV["AWS_SSH_PRIVKEY"] aws.region = "us-east-1" - aws.ami = "ami-1c1e8075" - aws.ssh_username = "vagrant" + aws.ami = "ami-1c1e8075" + aws.ssh_username = "vagrant" aws.instance_type = "t1.micro" end + config.vm.provider :rackspace do |rs| + config.vm.box = "dummy" + config.vm.box_url = "https://github.com/mitchellh/vagrant-rackspace/raw/master/dummy.box" + config.ssh.private_key_path = ENV["RS_PRIVATE_KEY"] + rs.username = ENV["RS_USERNAME"] + rs.api_key = ENV["RS_API_KEY"] + rs.public_key_path = ENV["RS_PUBLIC_KEY"] + rs.flavor = /512MB/ + rs.image = /Ubuntu/ + end config.vm.provider :virtualbox do |vb| config.vm.box = "quantal64_3.5.0-25" config.vm.box_url = "http://get.docker.io/vbox/ubuntu/12.10/quantal64_3.5.0-25.box" - end + end end diff --git a/puppet/modules/docker/manifests/init.pp b/puppet/modules/docker/manifests/init.pp index 1862c524b8931..ab14ef2c4c349 100644 --- a/puppet/modules/docker/manifests/init.pp +++ b/puppet/modules/docker/manifests/init.pp @@ -25,6 +25,9 @@ class ec2 { } +class rax { +} + class docker { # update this with latest docker binary distro @@ -42,13 +45,17 @@ notify { "docker_url = $docker_url": withpath => true } - $ec2_version = file("/etc/ec2_version", "/dev/null") - if ($ec2_version) { - include ec2 - } else { - # virtualbox is the vagrant default, so it should be safe to assume - include virtualbox - } + $ec2_version = file("/etc/ec2_version", "/dev/null") + $rax_version = inline_template("<%= %x{/usr/bin/xenstore-read vm-data/provider_data/provider} %>") + + if ($ec2_version) { + include ec2 + } elsif ($rax_version) { + include rax + } else { + # virtualbox is the vagrant default, so it should be safe to assume + include virtualbox + } user { "vagrant": ensure => present, @@ -84,6 +91,7 @@ } file { "/home/vagrant": + ensure => directory, mode => 644, require => User["vagrant"], } @@ -91,7 +99,7 @@ file { "/home/vagrant/.profile": mode => 644, owner => "vagrant", - group => "ubuntu", + group => "vagrant", content => template("docker/profile"), require => File["/home/vagrant"], } From 94b9ca988de6970406789759b5f75fee19fd5dbb Mon Sep 17 00:00:00 2001 From: Charles Hooper Date: Sun, 24 Mar 2013 10:49:16 +0000 Subject: [PATCH 02/20] Fix missing group "Vagrant" error --- puppet/modules/docker/manifests/init.pp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/puppet/modules/docker/manifests/init.pp b/puppet/modules/docker/manifests/init.pp index 13de621749147..b6b8aecd1ccbf 100644 --- a/puppet/modules/docker/manifests/init.pp +++ b/puppet/modules/docker/manifests/init.pp @@ -62,8 +62,30 @@ comment => "Vagrant User", shell => "/bin/bash", home => "/home/vagrant", + groups => [ + "sudo", + "vagrant", + "ubuntu", + ], + require => [ + Group["sudo"], + Group["vagrant"], + Group["ubuntu"], + ], } + group { "ubuntu": + ensure => present, + } + + group { "vagrant": + ensure => present, + } + + group { "sudo": + ensure => present, + } + file { "/usr/local/bin": ensure => directory, owner => root, From 91d78a10c33d9e1c33120634fb3dad5e0d247d28 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Tue, 26 Mar 2013 03:05:10 -0700 Subject: [PATCH 03/20] #175 Add autodownload on run command --- commands.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/commands.go b/commands.go index 1f2c3650d7a5a..7cc46dfcdd681 100644 --- a/commands.go +++ b/commands.go @@ -826,10 +826,19 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) fmt.Fprintln(stdout, "Error: Command not specified") return fmt.Errorf("Command not specified") } + // Create new container container, err := srv.runtime.Create(config) if err != nil { - return errors.New("Error creating container: " + err.Error()) + // If container not found, try to pull it + // FIXME: not found != error + fmt.Fprintf(stdout, "Image %s not found, trying to pull it from registry.\n", config.Image) + if err = srv.CmdPull(stdin, stdout, config.Image); err != nil { + return err + } + if container, err = srv.runtime.Create(config); err != nil { + return fmt.Errorf("Error creating container: %s", err) + } } if config.OpenStdin { cmd_stdin, err := container.StdinPipe() From 004a5310d93c5373d6db7683058fb392c8a3bd37 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Tue, 26 Mar 2013 05:28:17 -0700 Subject: [PATCH 04/20] Try to fetch missing base only on "not found" error --- commands.go | 15 +++++++++------ graph.go | 7 +++++++ tags.go | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/commands.go b/commands.go index 7cc46dfcdd681..e7def9afec718 100644 --- a/commands.go +++ b/commands.go @@ -831,14 +831,17 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) container, err := srv.runtime.Create(config) if err != nil { // If container not found, try to pull it - // FIXME: not found != error - fmt.Fprintf(stdout, "Image %s not found, trying to pull it from registry.\n", config.Image) - if err = srv.CmdPull(stdin, stdout, config.Image); err != nil { + if srv.runtime.graph.IsNotExist(err) { + fmt.Fprintf(stdout, "Image %s not found, trying to pull it from registry.\n", config.Image) + if err = srv.CmdPull(stdin, stdout, config.Image); err != nil { + return err + } + if container, err = srv.runtime.Create(config); err != nil { + return err + } + } else { return err } - if container, err = srv.runtime.Create(config); err != nil { - return fmt.Errorf("Error creating container: %s", err) - } } if config.OpenStdin { cmd_stdin, err := container.StdinPipe() diff --git a/graph.go b/graph.go index 35f092703f3f3..29d8b2bb6f494 100644 --- a/graph.go +++ b/graph.go @@ -6,6 +6,7 @@ import ( "os" "path" "path/filepath" + "strings" "time" ) @@ -27,6 +28,12 @@ func NewGraph(root string) (*Graph, error) { }, nil } +// FIXME: Implement error subclass instead of looking at the error text +// Note: This is the way golang implements os.IsNotExists on Plan9 +func (graph *Graph) IsNotExist(err error) bool { + return err != nil && strings.Contains(err.Error(), "does not exist") +} + func (graph *Graph) Exists(id string) bool { if _, err := graph.Get(id); err != nil { return false diff --git a/tags.go b/tags.go index 1df7c6e463692..e259c2e7ea5a9 100644 --- a/tags.go +++ b/tags.go @@ -75,7 +75,7 @@ func (store *TagStore) LookupImage(name string) (*Image, error) { if i, err := store.GetImage(repoAndTag[0], repoAndTag[1]); err != nil { return nil, err } else if i == nil { - return nil, fmt.Errorf("No such image: %s", name) + return nil, fmt.Errorf("Image does not exist: %s", name) } else { img = i } From cca59081de9dc243fefe2816ded509bd4e1caad9 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Tue, 26 Mar 2013 07:01:59 -0700 Subject: [PATCH 05/20] #189 Fix the env in TTY mode --- container.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/container.go b/container.go index 785b351c22dbb..77d16c786b817 100644 --- a/container.go +++ b/container.go @@ -258,8 +258,9 @@ func (container *Container) Start() error { var err error if container.Config.Tty { - container.cmd.Env = append(container.Config.Env, - "TERM=xterm", + container.cmd.Env = append( + []string{"TERM=xterm"}, + container.cmd.Env..., ) err = container.startPty() } else { From 1c5162c5a9e47a5e6f774f2bf31ef6f156d2e18b Mon Sep 17 00:00:00 2001 From: Thatcher Peskens Date: Tue, 26 Mar 2013 10:03:10 -0700 Subject: [PATCH 06/20] Added two user quotes. Cleanup of images. --- docs/sources/index.html | 21 +- docs/theme/docker/static/css/docs.css | 1397 ----------------- .../theme/docker/static/img/alert_info_32.png | Bin 1168 -> 0 bytes .../docker/static/img/alert_warning_32.png | Bin 1060 -> 0 bytes docs/theme/docker/static/img/bodybg.png | Bin 966 -> 0 bytes docs/theme/docker/static/img/crane-logo.png | Bin 4226 -> 0 bytes .../static/img/crane-logo_small_80px.gif | Bin 454 -> 0 bytes .../docker/static/img/docs-disc-closed.png | Bin 1177 -> 0 bytes .../docker/static/img/docs-disc-open.png | Bin 1148 -> 0 bytes .../docker/static/img/docs-dotcloud-logo.png | Bin 6637 -> 0 bytes docs/theme/docker/static/img/docs-headbg.png | Bin 977 -> 0 bytes .../static/img/docs-leftbar-bg-selected.png | Bin 946 -> 0 bytes .../docker/static/img/docs-leftbar-bg.png | Bin 946 -> 0 bytes .../docker/static/img/docs-mediawiki-ex.png | Bin 29876 -> 0 bytes .../docker/static/img/docs-splash-top-1.png | Bin 5281 -> 0 bytes .../docker/static/img/docs-splash-top-2.png | Bin 4383 -> 0 bytes .../docker/static/img/docs-splash-top-3.png | Bin 4354 -> 0 bytes .../static/img/docs-splash-top-horizbar.png | Bin 1409 -> 0 bytes .../docker/static/img/new-nav-disc-closed.png | Bin 1160 -> 0 bytes .../docker/static/img/new-nav-disc-open.png | Bin 1141 -> 0 bytes .../docker/static/img/new-nav-section.png | Bin 946 -> 0 bytes docs/theme/docker/static/img/padlock.png | Bin 1074 -> 0 bytes docs/theme/docker/static/img/twitter.png | Bin 964 -> 0 bytes 23 files changed, 17 insertions(+), 1401 deletions(-) delete mode 100755 docs/theme/docker/static/css/docs.css delete mode 100755 docs/theme/docker/static/img/alert_info_32.png delete mode 100755 docs/theme/docker/static/img/alert_warning_32.png delete mode 100755 docs/theme/docker/static/img/bodybg.png delete mode 100644 docs/theme/docker/static/img/crane-logo.png delete mode 100644 docs/theme/docker/static/img/crane-logo_small_80px.gif delete mode 100755 docs/theme/docker/static/img/docs-disc-closed.png delete mode 100755 docs/theme/docker/static/img/docs-disc-open.png delete mode 100755 docs/theme/docker/static/img/docs-dotcloud-logo.png delete mode 100755 docs/theme/docker/static/img/docs-headbg.png delete mode 100755 docs/theme/docker/static/img/docs-leftbar-bg-selected.png delete mode 100755 docs/theme/docker/static/img/docs-leftbar-bg.png delete mode 100755 docs/theme/docker/static/img/docs-mediawiki-ex.png delete mode 100755 docs/theme/docker/static/img/docs-splash-top-1.png delete mode 100755 docs/theme/docker/static/img/docs-splash-top-2.png delete mode 100755 docs/theme/docker/static/img/docs-splash-top-3.png delete mode 100755 docs/theme/docker/static/img/docs-splash-top-horizbar.png delete mode 100755 docs/theme/docker/static/img/new-nav-disc-closed.png delete mode 100755 docs/theme/docker/static/img/new-nav-disc-open.png delete mode 100755 docs/theme/docker/static/img/new-nav-section.png delete mode 100755 docs/theme/docker/static/img/padlock.png delete mode 100644 docs/theme/docker/static/img/twitter.png diff --git a/docs/sources/index.html b/docs/sources/index.html index 427fe4de9b368..6a3b363f9e37e 100644 --- a/docs/sources/index.html +++ b/docs/sources/index.html @@ -93,7 +93,7 @@

Docker encapsulates heterogeneo
-
+
@@ -119,8 +119,6 @@

Repeatability

Because containers are isolated in their own filesystem, they behave the same regardless of where, when, and alongside what they run.

- -
@@ -138,7 +136,7 @@

Repeatability

-
+
@@ -152,6 +150,21 @@

Repeatability

+
+
+
+ + David Romulan ‏@destructuring: I haven't had this much fun since AWS +
+
+
+
+ + Ricardo Gladwell ‏@rgladwell: wow @getdocker is either amazing or totally stupid +
+
+ +