mirror of https://github.com/docker/docs.git
Merge branch 'graph' of github.com:dotcloud/docker into graph
This commit is contained in:
commit
db8f2a1a9d
94
README.md
94
README.md
|
@ -1,9 +1,9 @@
|
||||||
Docker: the Linux container runtime
|
Docker: the Linux container runtime
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
Docker complements LXC with a high-level API with operates at the process level. It runs unix processes with strong guarantees of isolation and repeatability across servers.
|
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.
|
||||||
|
|
||||||
Is is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
|
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.
|
||||||
|
|
||||||
<img src="http://bricks.argz.com/bricksfiles/lego/07000/7823/012.jpg"/>
|
<img src="http://bricks.argz.com/bricksfiles/lego/07000/7823/012.jpg"/>
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ Notable features
|
||||||
|
|
||||||
* Copy-on-write: root filesystems are created using copy-on-write, which makes deployment extremeley fast, memory-cheap and disk-cheap.
|
* Copy-on-write: root filesystems are created using copy-on-write, which makes deployment extremeley fast, memory-cheap and disk-cheap.
|
||||||
|
|
||||||
* Logging: the standard streams (stdout/stderr/stdin) of each process container is collected and logged for real-time or batch retrieval.
|
* Logging: the standard streams (stdout/stderr/stdin) of each process container are collected and logged for real-time or batch retrieval.
|
||||||
|
|
||||||
* Change management: changes to a container's filesystem can be committed into a new image and re-used to create more containers. No templating or manual configuration required.
|
* Change management: changes to a container's filesystem can be committed into a new image and re-used to create more containers. No templating or manual configuration required.
|
||||||
|
|
||||||
|
@ -58,28 +58,28 @@ Installing on Ubuntu 12.04 and 12.10
|
||||||
|
|
||||||
1. Install dependencies:
|
1. Install dependencies:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install lxc wget bsdtar curl
|
sudo apt-get install lxc wget bsdtar curl
|
||||||
sudo apt-get install linux-image-extra-`uname -r`
|
sudo apt-get install linux-image-extra-`uname -r`
|
||||||
```
|
```
|
||||||
|
|
||||||
The `linux-image-extra` package is needed on standard Ubuntu EC2 AMIs in order to install the aufs kernel module.
|
The `linux-image-extra` package is needed on standard Ubuntu EC2 AMIs in order to install the aufs kernel module.
|
||||||
|
|
||||||
2. Install the latest docker binary:
|
2. Install the latest docker binary:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz
|
wget http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz
|
||||||
tar -xf docker-master.tgz
|
tar -xf docker-master.tgz
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Run your first container!
|
3. Run your first container!
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd docker-master
|
cd docker-master
|
||||||
sudo ./docker run -a -i -t base /bin/bash
|
sudo ./docker run -a -i -t base /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
Consider adding docker to your `PATH` for simplicity.
|
Consider adding docker to your `PATH` for simplicity.
|
||||||
|
|
||||||
Installing on other Linux distributions
|
Installing on other Linux distributions
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
@ -99,12 +99,12 @@ with VirtualBox as well as on Amazon EC2. Vagrant 1.1 is required for
|
||||||
EC2, but deploying is as simple as:
|
EC2, but deploying is as simple as:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ export AWS_ACCESS_KEY_ID=xxx \
|
$ export AWS_ACCESS_KEY_ID=xxx \
|
||||||
AWS_SECRET_ACCESS_KEY=xxx \
|
AWS_SECRET_ACCESS_KEY=xxx \
|
||||||
AWS_KEYPAIR_NAME=xxx \
|
AWS_KEYPAIR_NAME=xxx \
|
||||||
AWS_SSH_PRIVKEY=xxx
|
AWS_SSH_PRIVKEY=xxx
|
||||||
$ vagrant plugin install vagrant-aws
|
$ vagrant plugin install vagrant-aws
|
||||||
$ vagrant up --provider=aws
|
$ vagrant up --provider=aws
|
||||||
```
|
```
|
||||||
|
|
||||||
The environment variables are:
|
The environment variables are:
|
||||||
|
@ -115,11 +115,11 @@ The environment variables are:
|
||||||
* `AWS_SSH_PRIVKEY` - The path to the private key for the named keypair
|
* `AWS_SSH_PRIVKEY` - The path to the private key for the named keypair
|
||||||
|
|
||||||
For VirtualBox, you can simply ignore setting any of the environment
|
For VirtualBox, you can simply ignore setting any of the environment
|
||||||
variables and omit the ``provider`` flag. VirtualBox is still supported with
|
variables and omit the `provider` flag. VirtualBox is still supported with
|
||||||
Vagrant <= 1.1:
|
Vagrant <= 1.1:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ vagrant up
|
$ vagrant up
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,12 +131,12 @@ Running an interactive shell
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Download a base image
|
# Download a base image
|
||||||
docker import base
|
docker import base
|
||||||
|
|
||||||
# Run an interactive shell in the base image,
|
# Run an interactive shell in the base image,
|
||||||
# allocate a tty, attach stdin and stdout
|
# allocate a tty, attach stdin and stdout
|
||||||
docker run -a -i -t base /bin/bash
|
docker run -a -i -t base /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,17 +144,17 @@ Starting a long-running worker process
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run docker in daemon mode
|
# Run docker in daemon mode
|
||||||
(docker -d || echo "Docker daemon already running") &
|
(docker -d || echo "Docker daemon already running") &
|
||||||
|
|
||||||
# Start a very useful long-running process
|
# Start a very useful long-running process
|
||||||
JOB=$(docker run base /bin/sh -c "while true; do echo Hello world; sleep 1; done")
|
JOB=$(docker run base /bin/sh -c "while true; do echo Hello world; sleep 1; done")
|
||||||
|
|
||||||
# Collect the output of the job so far
|
# Collect the output of the job so far
|
||||||
docker logs $JOB
|
docker logs $JOB
|
||||||
|
|
||||||
# Kill the job
|
# Kill the job
|
||||||
docker kill $JOB
|
docker kill $JOB
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ Listing all running containers
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker ps
|
docker ps
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,17 +170,17 @@ Expose a service on a TCP port
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Expose port 4444 of this container, and tell netcat to listen on it
|
# Expose port 4444 of this container, and tell netcat to listen on it
|
||||||
JOB=$(docker run -p 4444 base /bin/nc -l -p 4444)
|
JOB=$(docker run -p 4444 base /bin/nc -l -p 4444)
|
||||||
|
|
||||||
# Which public port is NATed to my container?
|
# Which public port is NATed to my container?
|
||||||
PORT=$(docker port $JOB 4444)
|
PORT=$(docker port $JOB 4444)
|
||||||
|
|
||||||
# Connect to the public port via the host's public address
|
# Connect to the public port via the host's public address
|
||||||
echo hello world | nc $(hostname) $PORT
|
echo hello world | nc $(hostname) $PORT
|
||||||
|
|
||||||
# Verify that the network connection worked
|
# Verify that the network connection worked
|
||||||
echo "Daemon received: $(docker logs $JOB)"
|
echo "Daemon received: $(docker logs $JOB)"
|
||||||
```
|
```
|
||||||
|
|
||||||
Contributing to Docker
|
Contributing to Docker
|
||||||
|
@ -195,10 +195,10 @@ Contribution guidelines
|
||||||
|
|
||||||
We are always thrilled to receive pull requests, and do our best to process them as fast as possible. Not sure if that typo is worth a pull request? Do it! We will appreciate it.
|
We are always thrilled to receive pull requests, and do our best to process them as fast as possible. Not sure if that typo is worth a pull request? Do it! We will appreciate it.
|
||||||
|
|
||||||
If your pull request is not accepted on the first try, don't be discouraged! If there's a problen with the implementation, hopefully you received feedback on what to improve.
|
If your pull request is not accepted on the first try, don't be discouraged! If there's a problem with the implementation, hopefully you received feedback on what to improve.
|
||||||
|
|
||||||
We're trying very hard to keep Docker lean and focused. We don't want it to do everything for everybody. This means that we might decide against incorporating a new feature.
|
We're trying very hard to keep Docker lean and focused. We don't want it to do everything for everybody. This means that we might decide against incorporating a new feature.
|
||||||
However there might be a way to implement that feature *on top of* docker.
|
However, there might be a way to implement that feature *on top of* docker.
|
||||||
|
|
||||||
### Discuss your design on the mailing list
|
### Discuss your design on the mailing list
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ you in the right direction, give feedback on your design, and maybe point out if
|
||||||
|
|
||||||
### Create issues...
|
### Create issues...
|
||||||
|
|
||||||
Any significant improvement should be documented as a github issue before anybody start working on it.
|
Any significant improvement should be documented as [a github issue](https://github.com/dotcloud/docker/issues) before anybody starts working on it.
|
||||||
|
|
||||||
### ...but check for existing issues first!
|
### ...but check for existing issues first!
|
||||||
|
|
||||||
|
@ -224,9 +224,9 @@ Golang has a great testing suite built in: use it! Take a look at existing tests
|
||||||
Setting up a dev environment
|
Setting up a dev environment
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
Instructions that is verified to work on Ubuntu 12.10,
|
Instructions that have been verified to work on Ubuntu 12.10,
|
||||||
|
|
||||||
```
|
```bash
|
||||||
sudo apt-get -y install lxc wget bsdtar curl libsqlite3-dev golang git pkg-config
|
sudo apt-get -y install lxc wget bsdtar curl libsqlite3-dev golang git pkg-config
|
||||||
|
|
||||||
export GOPATH=~/go/
|
export GOPATH=~/go/
|
||||||
|
@ -243,7 +243,7 @@ go install -v github.com/dotcloud/docker/...
|
||||||
|
|
||||||
Then run the docker daemon,
|
Then run the docker daemon,
|
||||||
|
|
||||||
```
|
```bash
|
||||||
sudo $GOPATH/bin/docker -d
|
sudo $GOPATH/bin/docker -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -254,9 +254,9 @@ What is a Standard Container?
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
Docker defines a unit of software delivery called a Standard Container. The goal of a Standard Container is to encapsulate a software component and all its dependencies in
|
Docker defines a unit of software delivery called a Standard Container. The goal of a Standard Container is to encapsulate a software component and all its dependencies in
|
||||||
a format that is self-describing and portable, so that any compliant runtime can run it without extra dependency, regardless of the underlying machine and the contents of the container.
|
a format that is self-describing and portable, so that any compliant runtime can run it without extra dependencies, regardless of the underlying machine and the contents of the container.
|
||||||
|
|
||||||
The spec for Standard Containers is currently work in progress, but it is very straightforward. It mostly defines 1) an image format, 2) a set of standard operations, and 3) an execution environment.
|
The spec for Standard Containers is currently a work in progress, but it is very straightforward. It mostly defines 1) an image format, 2) a set of standard operations, and 3) an execution environment.
|
||||||
|
|
||||||
A great analogy for this is the shipping container. Just like Standard Containers are a fundamental unit of software delivery, shipping containers (http://bricks.argz.com/ins/7823-1/12) are a fundamental unit of physical delivery.
|
A great analogy for this is the shipping container. Just like Standard Containers are a fundamental unit of software delivery, shipping containers (http://bricks.argz.com/ins/7823-1/12) are a fundamental unit of physical delivery.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- mode: ruby -*-
|
# -*- mode: ruby -*-
|
||||||
# vi: set ft=ruby :
|
# vi: set ft=ruby :
|
||||||
|
|
||||||
Vagrant.configure("1") do |config|
|
def v10(config)
|
||||||
# All Vagrant configuration is done here. The most common configuration
|
# All Vagrant configuration is done here. The most common configuration
|
||||||
# options are documented and commented below. For a complete reference,
|
# options are documented and commented below. For a complete reference,
|
||||||
# please see the online documentation at vagrantup.com.
|
# please see the online documentation at vagrantup.com.
|
||||||
|
@ -20,7 +20,7 @@ Vagrant.configure("1") do |config|
|
||||||
# via the IP. Host-only networks can talk to the host machine as well as
|
# via the IP. Host-only networks can talk to the host machine as well as
|
||||||
# any other machines on the same network, but cannot be accessed (through this
|
# any other machines on the same network, but cannot be accessed (through this
|
||||||
# network interface) by any external networks.
|
# network interface) by any external networks.
|
||||||
# config.vm.network :hostonly, "192.168.33.10"
|
config.vm.network :hostonly, "192.168.33.10"
|
||||||
|
|
||||||
# Assign this VM to a bridged network, allowing you to connect directly to a
|
# Assign this VM to a bridged network, allowing you to connect directly to a
|
||||||
# network using the host's network device. This makes the VM appear as another
|
# network using the host's network device. This makes the VM appear as another
|
||||||
|
@ -34,6 +34,9 @@ Vagrant.configure("1") do |config|
|
||||||
# Share an additional folder to the guest VM. The first argument is
|
# 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
|
# 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.
|
# folder, and the third is the path on the host to the actual folder.
|
||||||
|
if not File.exist? File.expand_path '~/docker'
|
||||||
|
Dir.mkdir(File.expand_path '~/docker')
|
||||||
|
end
|
||||||
config.vm.share_folder "v-data", "~/docker", "~/docker"
|
config.vm.share_folder "v-data", "~/docker", "~/docker"
|
||||||
|
|
||||||
# Enable provisioning with Puppet stand alone. Puppet manifests
|
# Enable provisioning with Puppet stand alone. Puppet manifests
|
||||||
|
@ -99,7 +102,15 @@ Vagrant.configure("1") do |config|
|
||||||
# chef.validation_client_name = "ORGNAME-validator"
|
# chef.validation_client_name = "ORGNAME-validator"
|
||||||
end
|
end
|
||||||
|
|
||||||
Vagrant.configure("2") do |config|
|
"#{Vagrant::VERSION}" < "1.1.0" and Vagrant::Config.run do |config|
|
||||||
|
v10(config)
|
||||||
|
end
|
||||||
|
|
||||||
|
"#{Vagrant::VERSION}" >= "1.1.0" and Vagrant.configure("1") do |config|
|
||||||
|
v10(config)
|
||||||
|
end
|
||||||
|
|
||||||
|
"#{Vagrant::VERSION}" >= "1.1.0" and Vagrant.configure("2") do |config|
|
||||||
config.vm.provider :aws do |aws|
|
config.vm.provider :aws do |aws|
|
||||||
config.vm.box = "dummy"
|
config.vm.box = "dummy"
|
||||||
config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
|
config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
|
||||||
|
|
15
commands.go
15
commands.go
|
@ -391,7 +391,7 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
||||||
// Optionally register the image at REPO/TAG
|
// Optionally register the image at REPO/TAG
|
||||||
if repository := cmd.Arg(1); repository != "" {
|
if repository := cmd.Arg(1); repository != "" {
|
||||||
tag := cmd.Arg(2) // Repository will handle an empty tag properly
|
tag := cmd.Arg(2) // Repository will handle an empty tag properly
|
||||||
if err := srv.runtime.repositories.Set(repository, tag, img.Id); err != nil {
|
if err := srv.runtime.repositories.Set(repository, tag, img.Id, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -764,6 +764,19 @@ func (p *ports) Set(value string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (srv *Server) CmdTag(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||||
|
cmd := rcli.Subcmd(stdout, "tag", "[OPTIONS] IMAGE REPOSITORY [TAG]", "Tag an image into a repository")
|
||||||
|
force := cmd.Bool("f", false, "Force")
|
||||||
|
if err := cmd.Parse(args); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if cmd.NArg() < 2 {
|
||||||
|
cmd.Usage()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return srv.runtime.repositories.Set(cmd.Arg(1), cmd.Arg(2), cmd.Arg(0), *force)
|
||||||
|
}
|
||||||
|
|
||||||
func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||||
cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
|
cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
|
||||||
fl_user := cmd.String("u", "", "Username or UID")
|
fl_user := cmd.String("u", "", "Username or UID")
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Docs readme
|
||||||
|
===========
|
||||||
|
|
||||||
|
Let's see if this file shows up as we hope it does.
|
|
@ -95,7 +95,8 @@ func getIfaceAddr(name string) (net.Addr, error) {
|
||||||
case len(addrs4) == 0:
|
case len(addrs4) == 0:
|
||||||
return nil, fmt.Errorf("Interface %v has no IP addresses", name)
|
return nil, fmt.Errorf("Interface %v has no IP addresses", name)
|
||||||
case len(addrs4) > 1:
|
case len(addrs4) > 1:
|
||||||
return nil, fmt.Errorf("Interface %v has more than 1 IPv4 address", name)
|
fmt.Printf("Interface %v has more than 1 IPv4 address. Defaulting to using %v\n",
|
||||||
|
name, (addrs4[0].(*net.IPNet)).IP)
|
||||||
}
|
}
|
||||||
return addrs4[0], nil
|
return addrs4[0], nil
|
||||||
}
|
}
|
||||||
|
@ -123,6 +124,9 @@ func (mapper *PortMapper) setup() error {
|
||||||
if err := iptables("-t", "nat", "-A", "PREROUTING", "-j", "DOCKER"); err != nil {
|
if err := iptables("-t", "nat", "-A", "PREROUTING", "-j", "DOCKER"); err != nil {
|
||||||
return errors.New("Unable to setup port networking: Failed to inject docker in PREROUTING chain")
|
return errors.New("Unable to setup port networking: Failed to inject docker in PREROUTING chain")
|
||||||
}
|
}
|
||||||
|
if err := iptables("-t", "nat", "-A", "OUTPUT", "-j", "DOCKER"); err != nil {
|
||||||
|
return errors.New("Unable to setup port networking: Failed to inject docker in OUTPUT chain")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ class docker {
|
||||||
owner => "root",
|
owner => "root",
|
||||||
group => "root",
|
group => "root",
|
||||||
content => template("docker/dockerd.conf"),
|
content => template("docker/dockerd.conf"),
|
||||||
require => Exec["fetch-docker"],
|
require => Exec["copy-docker-bin"],
|
||||||
}
|
}
|
||||||
|
|
||||||
file { "/home/vagrant":
|
file { "/home/vagrant":
|
||||||
|
|
|
@ -8,5 +8,5 @@ respawn
|
||||||
|
|
||||||
script
|
script
|
||||||
test -f /etc/default/locale && . /etc/default/locale || true
|
test -f /etc/default/locale && . /etc/default/locale || true
|
||||||
LANG=$LANG LC_ALL=$LANG /usr/local/bin/docker -d
|
LANG=$LANG LC_ALL=$LANG /usr/local/bin/docker -d >> /var/log/dockerd 2>&1
|
||||||
end script
|
end script
|
||||||
|
|
|
@ -175,7 +175,7 @@ func (graph *Graph) PullRepository(user, repoName, askedTag string, repositories
|
||||||
if err = graph.PullImage(rev, authConfig); err != nil {
|
if err = graph.PullImage(rev, authConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = repositories.Set(repoName, tag, rev); err != nil {
|
if err = repositories.Set(repoName, tag, rev, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ func (runtime *Runtime) Commit(id, repository, tag string) (*Image, error) {
|
||||||
}
|
}
|
||||||
// Register the image if needed
|
// Register the image if needed
|
||||||
if repository != "" {
|
if repository != "" {
|
||||||
if err := runtime.repositories.Set(repository, tag, img.Id); err != nil {
|
if err := runtime.repositories.Set(repository, tag, img.Id, true); err != nil {
|
||||||
return img, err
|
return img, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
tags.go
11
tags.go
|
@ -83,7 +83,11 @@ func (store *TagStore) LookupImage(name string) (*Image, error) {
|
||||||
return img, nil
|
return img, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *TagStore) Set(repoName, tag, revision string) error {
|
func (store *TagStore) Set(repoName, tag, imageName string, force bool) error {
|
||||||
|
img, err := store.LookupImage(imageName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if tag == "" {
|
if tag == "" {
|
||||||
tag = DEFAULT_TAG
|
tag = DEFAULT_TAG
|
||||||
}
|
}
|
||||||
|
@ -101,9 +105,12 @@ func (store *TagStore) Set(repoName, tag, revision string) error {
|
||||||
repo = r
|
repo = r
|
||||||
} else {
|
} else {
|
||||||
repo = make(map[string]string)
|
repo = make(map[string]string)
|
||||||
|
if old, exists := store.Repositories[repoName]; exists && !force {
|
||||||
|
return fmt.Errorf("Tag %s:%s is already set to %s", repoName, tag, old)
|
||||||
|
}
|
||||||
store.Repositories[repoName] = repo
|
store.Repositories[repoName] = repo
|
||||||
}
|
}
|
||||||
repo[tag] = revision
|
repo[tag] = img.Id
|
||||||
return store.Save()
|
return store.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
term/term.go
21
term/term.go
|
@ -114,27 +114,6 @@ func IsTerminal(fd int) bool {
|
||||||
return err == 0
|
return err == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
|
||||||
// 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 | INLCR | IGNCR | 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore restores the terminal connected to the given file descriptor to a
|
// Restore restores the terminal connected to the given file descriptor to a
|
||||||
// previous state.
|
// previous state.
|
||||||
func Restore(fd int, state *State) error {
|
func Restore(fd int, state *State) error {
|
||||||
|
|
|
@ -1,8 +1,32 @@
|
||||||
package term
|
package term
|
||||||
|
|
||||||
import "syscall"
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
getTermios = syscall.TIOCGETA
|
getTermios = syscall.TIOCGETA
|
||||||
setTermios = syscall.TIOCSETA
|
setTermios = syscall.TIOCSETA
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||||
|
// 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 | INLCR | IGNCR | 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
|
||||||
|
}
|
|
@ -1,8 +1,32 @@
|
||||||
package term
|
package term
|
||||||
|
|
||||||
import "syscall"
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
getTermios = syscall.TCGETS
|
getTermios = syscall.TCGETS
|
||||||
setTermios = syscall.TCSETS
|
setTermios = syscall.TCSETS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||||
|
// 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
|
||||||
|
}
|
Loading…
Reference in New Issue