Bladeren bron

Merge remote-tracking branch 'dotcloud/docs'

Thatcher Peskens 12 jaren geleden
bovenliggende
commit
261003ceb0

+ 1 - 0
AUTHORS

@@ -11,3 +11,4 @@ Ken Cochrane
 Charles Hooper
 Guillaume Charmes
 Daniel Mizyrycki
+John Costa

+ 12 - 8
commands.go

@@ -283,7 +283,10 @@ func (srv *Server) CmdPort(stdin io.ReadCloser, stdout io.Writer, args ...string
 // 'docker rmi NAME' removes all images with the name NAME
 func (srv *Server) CmdRmi(stdin io.ReadCloser, stdout io.Writer, args ...string) (err error) {
 	cmd := rcli.Subcmd(stdout, "rmimage", "[OPTIONS] IMAGE", "Remove an image")
-	if cmd.Parse(args) != nil || cmd.NArg() < 1 {
+	if err := cmd.Parse(args); err != nil {
+		return nil
+	}
+	if cmd.NArg() < 1 {
 		cmd.Usage()
 		return nil
 	}
@@ -297,7 +300,10 @@ func (srv *Server) CmdRmi(stdin io.ReadCloser, stdout io.Writer, args ...string)
 
 func (srv *Server) CmdHistory(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
 	cmd := rcli.Subcmd(stdout, "history", "[OPTIONS] IMAGE", "Show the history of an image")
-	if cmd.Parse(args) != nil || cmd.NArg() != 1 {
+	if err := cmd.Parse(args); err != nil {
+		return nil
+	}
+	if cmd.NArg() != 1 {
 		cmd.Usage()
 		return nil
 	}
@@ -472,19 +478,15 @@ func (srv *Server) CmdPull(stdin io.ReadCloser, stdout io.Writer, args ...string
 	}
 
 	if srv.runtime.graph.LookupRemoteImage(remote, srv.runtime.authConfig) {
-		fmt.Fprintf(stdout, "Pulling %s...\n", remote)
-		if err := srv.runtime.graph.PullImage(remote, srv.runtime.authConfig); err != nil {
+		if err := srv.runtime.graph.PullImage(stdout, remote, srv.runtime.authConfig); err != nil {
 			return err
 		}
-		fmt.Fprintf(stdout, "Pulled\n")
 		return nil
 	}
 	// FIXME: Allow pull repo:tag
-	fmt.Fprintf(stdout, "Pulling %s...\n", remote)
 	if err := srv.runtime.graph.PullRepository(stdout, remote, "", srv.runtime.repositories, srv.runtime.authConfig); err != nil {
 		return err
 	}
-	fmt.Fprintf(stdout, "Pull completed\n")
 	return nil
 }
 
@@ -812,14 +814,16 @@ func (srv *Server) CmdTag(stdin io.ReadCloser, stdout io.Writer, args ...string)
 }
 
 func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
-	config, err := ParseRun(args)
+	config, err := ParseRun(args, stdout)
 	if err != nil {
 		return err
 	}
 	if config.Image == "" {
+		fmt.Fprintln(stdout, "Error: Image not specified")
 		return fmt.Errorf("Image not specified")
 	}
 	if len(config.Cmd) == 0 {
+		fmt.Fprintln(stdout, "Error: Command not specified")
 		return fmt.Errorf("Command not specified")
 	}
 	// Create new container

+ 10 - 4
container.go

@@ -3,8 +3,8 @@ package docker
 import (
 	"encoding/json"
 	"errors"
-	"flag"
 	"fmt"
+	"github.com/dotcloud/docker/rcli"
 	"github.com/kr/pty"
 	"io"
 	"io/ioutil"
@@ -60,9 +60,12 @@ type Config struct {
 	Image      string // Name of the image as it was passed by the operator (eg. could be symbolic)
 }
 
-func ParseRun(args []string) (*Config, error) {
-	cmd := flag.NewFlagSet("", flag.ContinueOnError)
-	cmd.SetOutput(ioutil.Discard)
+func ParseRun(args []string, stdout io.Writer) (*Config, error) {
+	cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
+	if len(args) > 0 && args[0] != "--help" {
+		cmd.SetOutput(ioutil.Discard)
+	}
+
 	fl_user := cmd.String("u", "", "Username or UID")
 	fl_detach := cmd.Bool("d", false, "Detached mode: leave the container running in the background")
 	fl_stdin := cmd.Bool("i", false, "Keep stdin open even if not attached")
@@ -255,6 +258,9 @@ func (container *Container) Start() error {
 
 	var err error
 	if container.Config.Tty {
+		container.cmd.Env = append(container.Config.Env,
+			"TERM=xterm",
+		)
 		err = container.startPty()
 	} else {
 		err = container.start()

+ 5 - 0
docs/Makefile

@@ -64,6 +64,11 @@ push:
 	@cd _build/html/ ; \
 	dotcloud push
 
+github-deploy: docs
+	rm -fr github-deploy
+	git clone ssh://git@github.com/dotcloud/docker github-deploy
+	cd github-deploy && git checkout -f gh-pages && git rm -r * && rsync -avH ../_build/html/ ./ && touch .nojekyll && echo "docker.io" > CNAME && git add * && git commit -m "Updating docs"
+
 $(VERSIONS):
 	@echo "Hello world"
 

+ 4 - 0
docs/sources/documentation/commandline/basecommands.rst

@@ -61,3 +61,7 @@ Expose a service on a TCP port
 
   # Verify that the network connection worked
   echo "Daemon received: $(docker logs $JOB)"
+
+Continue to the complete `Command Line Interface`_
+
+.. _Command Line Interface: ../commandline/cli.html

+ 5 - 1
docs/sources/documentation/examples/python_web_app.rst

@@ -6,7 +6,7 @@
 
 Building a python web app
 =========================
-The goal of this example is to show you how you can author your own docker images using a parent image, making changes to it, and then saving the results as a new image. We will do that by making a simple hello flask web application image. 
+The goal of this example is to show you how you can author your own docker images using a parent image, making changes to it, and then saving the results as a new image. We will do that by making a simple hello flask web application image.
 
 **Steps:**
 
@@ -64,3 +64,7 @@ See the example in action
     <div style="margin-top:10px;">
       <iframe width="720" height="350" src="http://ascii.io/a/2573/raw" frameborder="0"></iframe>
     </div>
+
+Continue to the `base commands`_
+
+.. _base commands: ../commandline/basecommands.html

+ 27 - 9
docs/sources/documentation/faq.rst

@@ -3,27 +3,45 @@ FAQ
 
 
 Most frequently asked questions.
----------------------------------------------
+--------------------------------
 
-1. How much does Docker cost?
+**1. How much does Docker cost?**
 
 Docker is 100% free, it is open source, so you can use it without paying.
 
-2. What open source license are you using?
+**2. What open source license are you using?**
 
 We are using the Apache License Version 2.0, see it here: https://github.com/dotcloud/docker/blob/master/LICENSE
 
-3. Does Docker run on Mac OS X or Windows?
+**3. Does Docker run on Mac OS X or Windows?**
 
-Not at this time, Docker currently only runs on Linux, but you can use VirtualBox to run Docker in a virtual machine on your box, and get the best of both worlds. Check out the getting started guides for help on setting up your machine.
+Not at this time, Docker currently only runs on Linux, but you can use VirtualBox to run Docker in a virtual machine on your box, and get the best of both worlds. Check out the MacOSX_ and Windows_ intallation guides.
 
-4. How do containers compare to virtual machines?
+**4. How do containers compare to virtual machines?**
 
-Containers are more light weight and can start in less then a second, and are great for lots of different tasks, but they aren't as full featured as virtual machines. 
+Containers are more light weight and can start in less then a second, and are great for lots of different tasks, but they aren't as full featured as virtual machines.
 
-5. Can I help by adding some questions and answers?
+**5. Can I help by adding some questions and answers?**
 
-Definitely! You can fork the repo and edit the documentation sources right there.
+Definitely! You can fork `the repo`_ and edit the documentation sources.
+
+
+**42. Where can I find more answers?**
+
+You can find more answers on:
+
+* `IRC: docker on freenode`_
+* `Github`_
+* `Ask questions on Stackoverflow`_
+* `Join the conversation on Twitter`_
+
+.. _Windows: ../documentation/installation/windows.html
+.. _MacOSX: ../documentation/installation/macos.html
+.. _the repo: http://www.github.com/dotcloud/docker
+.. _IRC\: docker on freenode: irc://chat.freenode.net#docker
+.. _Github: http://www.github.com/dotcloud/docker
+.. _Ask questions on Stackoverflow: http://stackoverflow.com/search?q=docker
+.. _Join the conversation on Twitter: http://twitter.com/getdocker
 
 
 Looking for something else to read? Checkout the :ref:`hello_world` example.

+ 4 - 2
docs/sources/gettingstarted.html

@@ -62,13 +62,15 @@
 </div>
 
 <div class="container">
+    <div class="alert alert-info">
+	    <strong>Docker is still under heavy development.</strong> It should not yet be used in production. Check <a href="http://github.com/dotcloud/docker">the repo</a> for recent progress.
+    </div>
     <div class="row">
         <div class="span6">
             <section class="contentblock">
                 <h2>
                     <a name="installing-on-ubuntu-1204-and-1210" class="anchor" href="#installing-on-ubuntu-1204-and-1210"><span class="mini-icon mini-icon-link"></span>
-                    </a>Installing on Ubuntu 12.04 and 12.10</h2>
-                    <p>Please note this project is currently under heavy development. It should not be used in production.</p>
+                    </a>Installing on Ubuntu</h2>
                 <ol>
                     <li>
                         <p>Install dependencies:</p>

+ 10 - 2
docs/sources/index.html

@@ -72,11 +72,19 @@
                 </div>
 
                 <div style="text-align: center; padding: 50px 30px 50px 30px;">
-                    <h1>Docker - the Linux container runtime</h1>
+		    <h1>Docker</h1>
+		    <h2>The Linux container runtime</h2>
                 </div>
 
                 <div style="display: block; text-align: center; padding: 10px 30px 50px 30px;">
-                    <h2 style="font-size: 16px; line-height: 1.5em;">Docker encapsulates heterogeneous payloads in Standard Containers, and runs them on any server with strong guarantees of isolation and repeatability.</h2>
+			<p>
+			Docker complements LXC with a high-level API which operates at the process level.
+			It runs unix processes with strong guarantees of isolation and repeatability across servers.
+			</p>
+
+			<p>
+			Docker is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
+			</p>
                 </div>
 
 

+ 26 - 20
lxc_template.go

@@ -94,36 +94,38 @@ func (graph *Graph) LookupRemoteImage(imgId string, authConfig *auth.AuthConfig)
 
 // Retrieve an image from the Registry.
 // Returns the Image object as well as the layer as an Archive (io.Reader)
-func (graph *Graph) getRemoteImage(imgId string, authConfig *auth.AuthConfig) (*Image, Archive, error) {
+func (graph *Graph) getRemoteImage(stdout io.Writer, imgId string, authConfig *auth.AuthConfig) (*Image, Archive, error) {
 	client := &http.Client{}
 
+	fmt.Fprintf(stdout, "Pulling %s metadata\n", imgId)
 	// Get the Json
 	req, err := http.NewRequest("GET", REGISTRY_ENDPOINT+"/images/"+imgId+"/json", nil)
 	if err != nil {
-		return nil, nil, fmt.Errorf("Error while getting from the server: %s\n", err)
+		return nil, nil, fmt.Errorf("Failed to download json: %s", err)
 	}
 	req.SetBasicAuth(authConfig.Username, authConfig.Password)
 	res, err := client.Do(req)
-	if err != nil || res.StatusCode != 200 {
-		if res != nil {
-			return nil, nil, fmt.Errorf("Internal server error: %d trying to get image %s", res.StatusCode, imgId)
-		}
-		return nil, nil, err
+	if err != nil {
+		return nil, nil, fmt.Errorf("Failed to download json: %s", err)
+	}
+	if res.StatusCode != 200 {
+		return nil, nil, fmt.Errorf("HTTP code %d", res.StatusCode)
 	}
 	defer res.Body.Close()
 
 	jsonString, err := ioutil.ReadAll(res.Body)
 	if err != nil {
-		return nil, nil, fmt.Errorf("Error while reading the http response: %s\n", err)
+		return nil, nil, fmt.Errorf("Failed to download json: %s", err)
 	}
 
 	img, err := NewImgJson(jsonString)
 	if err != nil {
-		return nil, nil, fmt.Errorf("Error while parsing the json: %s\n", err)
+		return nil, nil, fmt.Errorf("Failed to parse json: %s", err)
 	}
 	img.Id = imgId
 
 	// Get the layer
+	fmt.Fprintf(stdout, "Pulling %s fs layer\n", imgId)
 	req, err = http.NewRequest("GET", REGISTRY_ENDPOINT+"/images/"+imgId+"/layer", nil)
 	if err != nil {
 		return nil, nil, fmt.Errorf("Error while getting from the server: %s\n", err)
@@ -136,7 +138,7 @@ func (graph *Graph) getRemoteImage(imgId string, authConfig *auth.AuthConfig) (*
 	return img, res.Body, nil
 }
 
-func (graph *Graph) PullImage(imgId string, authConfig *auth.AuthConfig) error {
+func (graph *Graph) PullImage(stdout io.Writer, imgId string, authConfig *auth.AuthConfig) error {
 	history, err := graph.getRemoteHistory(imgId, authConfig)
 	if err != nil {
 		return err
@@ -145,7 +147,7 @@ func (graph *Graph) PullImage(imgId string, authConfig *auth.AuthConfig) error {
 	// FIXME: Lunch the getRemoteImage() in goroutines
 	for _, j := range history {
 		if !graph.Exists(j.Id) {
-			img, layer, err := graph.getRemoteImage(j.Id, authConfig)
+			img, layer, err := graph.getRemoteImage(stdout, j.Id, authConfig)
 			if err != nil {
 				// FIXME: Keep goging in case of error?
 				return err
@@ -162,7 +164,7 @@ func (graph *Graph) PullImage(imgId string, authConfig *auth.AuthConfig) error {
 func (graph *Graph) PullRepository(stdout io.Writer, remote, askedTag string, repositories *TagStore, authConfig *auth.AuthConfig) error {
 	client := &http.Client{}
 
-	fmt.Fprintf(stdout, "Pulling repo: %s\n", REGISTRY_ENDPOINT+"/users/"+remote)
+	fmt.Fprintf(stdout, "Pulling repository %s\n", remote)
 
 	var repositoryTarget string
 	// If we are asking for 'root' repository, lookup on the Library's registry
@@ -178,12 +180,12 @@ func (graph *Graph) PullRepository(stdout io.Writer, remote, askedTag string, re
 	}
 	req.SetBasicAuth(authConfig.Username, authConfig.Password)
 	res, err := client.Do(req)
-	if err != nil || res.StatusCode != 200 {
-		if res != nil {
-			return fmt.Errorf("Internal server error: %d trying to pull %s", res.StatusCode, remote)
-		}
+	if err != nil {
 		return err
 	}
+	if res.StatusCode != 200 {
+		return fmt.Errorf("HTTP code: %d", res.StatusCode)
+	}
 	defer res.Body.Close()
 	rawJson, err := ioutil.ReadAll(res.Body)
 	if err != nil {
@@ -194,7 +196,8 @@ func (graph *Graph) PullRepository(stdout io.Writer, remote, askedTag string, re
 		return err
 	}
 	for tag, rev := range t {
-		if err = graph.PullImage(rev, authConfig); err != nil {
+		fmt.Fprintf(stdout, "Pulling tag %s:%s\n", remote, tag)
+		if err = graph.PullImage(stdout, rev, authConfig); err != nil {
 			return err
 		}
 		if err = repositories.Set(remote, tag, rev, true); err != nil {
@@ -232,17 +235,20 @@ func (graph *Graph) PushImage(stdout io.Writer, imgOrig *Image, authConfig *auth
 		req.SetBasicAuth(authConfig.Username, authConfig.Password)
 		res, err := client.Do(req)
 		if err != nil {
-			return fmt.Errorf("Failed to upload json: %s", err)
+			return fmt.Errorf("Failed to upload metadata: %s", err)
 		}
 		if res.StatusCode != 200 {
-			Debugf("Pushing return status: %d\n", res.StatusCode)
 			switch res.StatusCode {
 			case 204:
 				// Case where the image is already on the Registry
 				// FIXME: Do not be silent?
 				return nil
 			default:
-				return fmt.Errorf("Received HTTP code %d while uploading json", res.StatusCode)
+				errBody, err := ioutil.ReadAll(res.Body)
+				if err != nil {
+					errBody = []byte(err.Error())
+				}
+				return fmt.Errorf("HTTP code %d while uploading metadata: %s", res.StatusCode, errBody)
 			}
 		}
 

+ 43 - 18
term/termios_linux.go

@@ -1,10 +1,29 @@
 package term
 
 import (
-    "syscall"
-    "unsafe"
+	"syscall"
+	"unsafe"
 )
 
+// #include <termios.h>
+// #include <sys/ioctl.h>
+/*
+void MakeRaw(int fd) {
+  struct termios t;
+
+  // FIXME: Handle errors?
+  ioctl(fd, TCGETS, &t);
+
+  t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
+  t.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+  t.c_cflag &= ~(CSIZE | PARENB);
+  t.c_cflag |= CS8;
+
+  ioctl(fd, TCSETS, &t);
+}
+*/
+import "C"
+
 const (
 	getTermios = syscall.TCGETS
 	setTermios = syscall.TCSETS
@@ -14,19 +33,25 @@ const (
 // mode and returns the previous state of the terminal so that it can be
 // restored.
 func MakeRaw(fd int) (*State, error) {
-    var oldState State
-    if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
-        return nil, err
-    }
-
-    newState := oldState.termios
-    newState.Iflag &^= ISTRIP | IXON | IXOFF
-    newState.Iflag |= ICRNL
-    newState.Oflag |= ONLCR
-    newState.Lflag &^= ECHO | ICANON | ISIG
-    if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
-        return nil, err
-    }
-
-    return &oldState, nil
-}
+	var oldState State
+	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+		return nil, err
+	}
+	C.MakeRaw(C.int(fd))
+	return &oldState, nil
+
+	// FIXME: post on goland issues this: very same as the C function bug non-working
+
+	// newState := oldState.termios
+
+	// newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
+	// newState.Oflag &^= OPOST
+	// newState.Lflag &^= (ECHO | syscall.ECHONL | ICANON | ISIG | IEXTEN)
+	// newState.Cflag &^= (CSIZE | syscall.PARENB)
+	// newState.Cflag |= CS8
+
+	// if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TCSETS, uintptr(unsafe.Pointer(&newState))); err != 0 {
+	// 	return nil, err
+	// }
+	// return &oldState, nil
+}