* Config is now runconfig.Config
* HostConfig is now runconfig.HostConfig
* MergeConfig is now runconfig.Merge
* CompareConfig is now runconfig.Compare
* ParseRun is now runconfig.Parse
* ContainerConfigFromJob is now runconfig.ContainerConfigFromJob
* ContainerHostConfigFromJob is now runconfig.ContainerHostConfigFromJob
This facilitates refactoring commands.go and shrinks the core.
Docker-DCO-1.1-Signed-off-by: Solomon Hykes <solomon@docker.com> (github: shykes)
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
"github.com/dotcloud/docker/archive" |
| 10 | 10 |
"github.com/dotcloud/docker/auth" |
| 11 | 11 |
"github.com/dotcloud/docker/registry" |
| 12 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 12 | 13 |
"github.com/dotcloud/docker/utils" |
| 13 | 14 |
"io" |
| 14 | 15 |
"io/ioutil" |
| ... | ... |
@@ -38,7 +39,7 @@ type buildFile struct {
|
| 38 | 38 |
|
| 39 | 39 |
image string |
| 40 | 40 |
maintainer string |
| 41 |
- config *Config |
|
| 41 |
+ config *runconfig.Config |
|
| 42 | 42 |
|
| 43 | 43 |
contextPath string |
| 44 | 44 |
context *utils.TarSum |
| ... | ... |
@@ -101,7 +102,7 @@ func (b *buildFile) CmdFrom(name string) error {
|
| 101 | 101 |
} |
| 102 | 102 |
} |
| 103 | 103 |
b.image = image.ID |
| 104 |
- b.config = &Config{}
|
|
| 104 |
+ b.config = &runconfig.Config{}
|
|
| 105 | 105 |
if image.Config != nil {
|
| 106 | 106 |
b.config = image.Config |
| 107 | 107 |
} |
| ... | ... |
@@ -158,14 +159,14 @@ func (b *buildFile) CmdRun(args string) error {
|
| 158 | 158 |
if b.image == "" {
|
| 159 | 159 |
return fmt.Errorf("Please provide a source image with `from` prior to run")
|
| 160 | 160 |
} |
| 161 |
- config, _, _, err := ParseRun(append([]string{b.image}, b.buildCmdFromJson(args)...), nil)
|
|
| 161 |
+ config, _, _, err := runconfig.Parse(append([]string{b.image}, b.buildCmdFromJson(args)...), nil)
|
|
| 162 | 162 |
if err != nil {
|
| 163 | 163 |
return err |
| 164 | 164 |
} |
| 165 | 165 |
|
| 166 | 166 |
cmd := b.config.Cmd |
| 167 | 167 |
b.config.Cmd = nil |
| 168 |
- MergeConfig(b.config, config) |
|
| 168 |
+ runconfig.Merge(b.config, config) |
|
| 169 | 169 |
|
| 170 | 170 |
defer func(cmd []string) { b.config.Cmd = cmd }(cmd)
|
| 171 | 171 |
|
| ... | ... |
@@ -742,7 +743,7 @@ func NewBuildFile(srv *Server, outStream, errStream io.Writer, verbose, utilizeC |
| 742 | 742 |
return &buildFile{
|
| 743 | 743 |
runtime: srv.runtime, |
| 744 | 744 |
srv: srv, |
| 745 |
- config: &Config{},
|
|
| 745 |
+ config: &runconfig.Config{},
|
|
| 746 | 746 |
outStream: outStream, |
| 747 | 747 |
errStream: errStream, |
| 748 | 748 |
tmpContainers: make(map[string]struct{}),
|
| ... | ... |
@@ -15,10 +15,9 @@ import ( |
| 15 | 15 |
"github.com/dotcloud/docker/engine" |
| 16 | 16 |
"github.com/dotcloud/docker/nat" |
| 17 | 17 |
flag "github.com/dotcloud/docker/pkg/mflag" |
| 18 |
- "github.com/dotcloud/docker/pkg/opts" |
|
| 19 |
- "github.com/dotcloud/docker/pkg/sysinfo" |
|
| 20 | 18 |
"github.com/dotcloud/docker/pkg/term" |
| 21 | 19 |
"github.com/dotcloud/docker/registry" |
| 20 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 22 | 21 |
"github.com/dotcloud/docker/utils" |
| 23 | 22 |
"io" |
| 24 | 23 |
"io/ioutil" |
| ... | ... |
@@ -1449,11 +1448,11 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
|
| 1449 | 1449 |
v.Set("comment", *flComment)
|
| 1450 | 1450 |
v.Set("author", *flAuthor)
|
| 1451 | 1451 |
var ( |
| 1452 |
- config *Config |
|
| 1452 |
+ config *runconfig.Config |
|
| 1453 | 1453 |
env engine.Env |
| 1454 | 1454 |
) |
| 1455 | 1455 |
if *flConfig != "" {
|
| 1456 |
- config = &Config{}
|
|
| 1456 |
+ config = &runconfig.Config{}
|
|
| 1457 | 1457 |
if err := json.Unmarshal([]byte(*flConfig), config); err != nil {
|
| 1458 | 1458 |
return err |
| 1459 | 1459 |
} |
| ... | ... |
@@ -1743,210 +1742,9 @@ func (cli *DockerCli) CmdTag(args ...string) error {
|
| 1743 | 1743 |
return nil |
| 1744 | 1744 |
} |
| 1745 | 1745 |
|
| 1746 |
-//FIXME Only used in tests |
|
| 1747 |
-func ParseRun(args []string, sysInfo *sysinfo.SysInfo) (*Config, *HostConfig, *flag.FlagSet, error) {
|
|
| 1748 |
- cmd := flag.NewFlagSet("run", flag.ContinueOnError)
|
|
| 1749 |
- cmd.SetOutput(ioutil.Discard) |
|
| 1750 |
- cmd.Usage = nil |
|
| 1751 |
- return parseRun(cmd, args, sysInfo) |
|
| 1752 |
-} |
|
| 1753 |
- |
|
| 1754 |
-func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Config, *HostConfig, *flag.FlagSet, error) {
|
|
| 1755 |
- var ( |
|
| 1756 |
- // FIXME: use utils.ListOpts for attach and volumes? |
|
| 1757 |
- flAttach = opts.NewListOpts(opts.ValidateAttach) |
|
| 1758 |
- flVolumes = opts.NewListOpts(opts.ValidatePath) |
|
| 1759 |
- flLinks = opts.NewListOpts(opts.ValidateLink) |
|
| 1760 |
- flEnv = opts.NewListOpts(opts.ValidateEnv) |
|
| 1761 |
- |
|
| 1762 |
- flPublish opts.ListOpts |
|
| 1763 |
- flExpose opts.ListOpts |
|
| 1764 |
- flDns opts.ListOpts |
|
| 1765 |
- flVolumesFrom opts.ListOpts |
|
| 1766 |
- flLxcOpts opts.ListOpts |
|
| 1767 |
- |
|
| 1768 |
- flAutoRemove = cmd.Bool([]string{"#rm", "-rm"}, false, "Automatically remove the container when it exits (incompatible with -d)")
|
|
| 1769 |
- flDetach = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: Run container in the background, print new container id")
|
|
| 1770 |
- flNetwork = cmd.Bool([]string{"n", "-networking"}, true, "Enable networking for this container")
|
|
| 1771 |
- flPrivileged = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container")
|
|
| 1772 |
- flPublishAll = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to the host interfaces")
|
|
| 1773 |
- flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep stdin open even if not attached")
|
|
| 1774 |
- flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-tty")
|
|
| 1775 |
- flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file")
|
|
| 1776 |
- flEntrypoint = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default entrypoint of the image")
|
|
| 1777 |
- flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
|
|
| 1778 |
- flMemoryString = cmd.String([]string{"m", "-memory"}, "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)")
|
|
| 1779 |
- flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID")
|
|
| 1780 |
- flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container")
|
|
| 1781 |
- flCpuShares = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
|
|
| 1782 |
- |
|
| 1783 |
- // For documentation purpose |
|
| 1784 |
- _ = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)")
|
|
| 1785 |
- _ = cmd.String([]string{"#name", "-name"}, "", "Assign a name to the container")
|
|
| 1786 |
- ) |
|
| 1787 |
- |
|
| 1788 |
- cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to stdin, stdout or stderr.")
|
|
| 1789 |
- cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)")
|
|
| 1790 |
- cmd.Var(&flLinks, []string{"#link", "-link"}, "Add link to another container (name:alias)")
|
|
| 1791 |
- cmd.Var(&flEnv, []string{"e", "-env"}, "Set environment variables")
|
|
| 1792 |
- |
|
| 1793 |
- cmd.Var(&flPublish, []string{"p", "-publish"}, fmt.Sprintf("Publish a container's port to the host (format: %s) (use 'docker port' to see the actual mapping)", nat.PortSpecTemplateFormat))
|
|
| 1794 |
- cmd.Var(&flExpose, []string{"#expose", "-expose"}, "Expose a port from the container without publishing it to your host")
|
|
| 1795 |
- cmd.Var(&flDns, []string{"#dns", "-dns"}, "Set custom dns servers")
|
|
| 1796 |
- cmd.Var(&flVolumesFrom, []string{"#volumes-from", "-volumes-from"}, "Mount volumes from the specified container(s)")
|
|
| 1797 |
- cmd.Var(&flLxcOpts, []string{"#lxc-conf", "-lxc-conf"}, "Add custom lxc options -lxc-conf=\"lxc.cgroup.cpuset.cpus = 0,1\"")
|
|
| 1798 |
- |
|
| 1799 |
- if err := cmd.Parse(args); err != nil {
|
|
| 1800 |
- return nil, nil, cmd, err |
|
| 1801 |
- } |
|
| 1802 |
- |
|
| 1803 |
- // Check if the kernel supports memory limit cgroup. |
|
| 1804 |
- if sysInfo != nil && *flMemoryString != "" && !sysInfo.MemoryLimit {
|
|
| 1805 |
- *flMemoryString = "" |
|
| 1806 |
- } |
|
| 1807 |
- |
|
| 1808 |
- // Validate input params |
|
| 1809 |
- if *flDetach && flAttach.Len() > 0 {
|
|
| 1810 |
- return nil, nil, cmd, ErrConflictAttachDetach |
|
| 1811 |
- } |
|
| 1812 |
- if *flWorkingDir != "" && !path.IsAbs(*flWorkingDir) {
|
|
| 1813 |
- return nil, nil, cmd, ErrInvalidWorikingDirectory |
|
| 1814 |
- } |
|
| 1815 |
- if *flDetach && *flAutoRemove {
|
|
| 1816 |
- return nil, nil, cmd, ErrConflictDetachAutoRemove |
|
| 1817 |
- } |
|
| 1818 |
- |
|
| 1819 |
- // If neither -d or -a are set, attach to everything by default |
|
| 1820 |
- if flAttach.Len() == 0 && !*flDetach {
|
|
| 1821 |
- if !*flDetach {
|
|
| 1822 |
- flAttach.Set("stdout")
|
|
| 1823 |
- flAttach.Set("stderr")
|
|
| 1824 |
- if *flStdin {
|
|
| 1825 |
- flAttach.Set("stdin")
|
|
| 1826 |
- } |
|
| 1827 |
- } |
|
| 1828 |
- } |
|
| 1829 |
- |
|
| 1830 |
- var flMemory int64 |
|
| 1831 |
- if *flMemoryString != "" {
|
|
| 1832 |
- parsedMemory, err := utils.RAMInBytes(*flMemoryString) |
|
| 1833 |
- if err != nil {
|
|
| 1834 |
- return nil, nil, cmd, err |
|
| 1835 |
- } |
|
| 1836 |
- flMemory = parsedMemory |
|
| 1837 |
- } |
|
| 1838 |
- |
|
| 1839 |
- var binds []string |
|
| 1840 |
- // add any bind targets to the list of container volumes |
|
| 1841 |
- for bind := range flVolumes.GetMap() {
|
|
| 1842 |
- if arr := strings.Split(bind, ":"); len(arr) > 1 {
|
|
| 1843 |
- if arr[0] == "/" {
|
|
| 1844 |
- return nil, nil, cmd, fmt.Errorf("Invalid bind mount: source can't be '/'")
|
|
| 1845 |
- } |
|
| 1846 |
- dstDir := arr[1] |
|
| 1847 |
- flVolumes.Set(dstDir) |
|
| 1848 |
- binds = append(binds, bind) |
|
| 1849 |
- flVolumes.Delete(bind) |
|
| 1850 |
- } else if bind == "/" {
|
|
| 1851 |
- return nil, nil, cmd, fmt.Errorf("Invalid volume: path can't be '/'")
|
|
| 1852 |
- } |
|
| 1853 |
- } |
|
| 1854 |
- |
|
| 1855 |
- var ( |
|
| 1856 |
- parsedArgs = cmd.Args() |
|
| 1857 |
- runCmd []string |
|
| 1858 |
- entrypoint []string |
|
| 1859 |
- image string |
|
| 1860 |
- ) |
|
| 1861 |
- if len(parsedArgs) >= 1 {
|
|
| 1862 |
- image = cmd.Arg(0) |
|
| 1863 |
- } |
|
| 1864 |
- if len(parsedArgs) > 1 {
|
|
| 1865 |
- runCmd = parsedArgs[1:] |
|
| 1866 |
- } |
|
| 1867 |
- if *flEntrypoint != "" {
|
|
| 1868 |
- entrypoint = []string{*flEntrypoint}
|
|
| 1869 |
- } |
|
| 1870 |
- |
|
| 1871 |
- lxcConf, err := parseLxcConfOpts(flLxcOpts) |
|
| 1872 |
- if err != nil {
|
|
| 1873 |
- return nil, nil, cmd, err |
|
| 1874 |
- } |
|
| 1875 |
- |
|
| 1876 |
- var ( |
|
| 1877 |
- domainname string |
|
| 1878 |
- hostname = *flHostname |
|
| 1879 |
- parts = strings.SplitN(hostname, ".", 2) |
|
| 1880 |
- ) |
|
| 1881 |
- if len(parts) > 1 {
|
|
| 1882 |
- hostname = parts[0] |
|
| 1883 |
- domainname = parts[1] |
|
| 1884 |
- } |
|
| 1885 |
- |
|
| 1886 |
- ports, portBindings, err := nat.ParsePortSpecs(flPublish.GetAll()) |
|
| 1887 |
- if err != nil {
|
|
| 1888 |
- return nil, nil, cmd, err |
|
| 1889 |
- } |
|
| 1890 |
- |
|
| 1891 |
- // Merge in exposed ports to the map of published ports |
|
| 1892 |
- for _, e := range flExpose.GetAll() {
|
|
| 1893 |
- if strings.Contains(e, ":") {
|
|
| 1894 |
- return nil, nil, cmd, fmt.Errorf("Invalid port format for --expose: %s", e)
|
|
| 1895 |
- } |
|
| 1896 |
- p := nat.NewPort(nat.SplitProtoPort(e)) |
|
| 1897 |
- if _, exists := ports[p]; !exists {
|
|
| 1898 |
- ports[p] = struct{}{}
|
|
| 1899 |
- } |
|
| 1900 |
- } |
|
| 1901 |
- |
|
| 1902 |
- config := &Config{
|
|
| 1903 |
- Hostname: hostname, |
|
| 1904 |
- Domainname: domainname, |
|
| 1905 |
- PortSpecs: nil, // Deprecated |
|
| 1906 |
- ExposedPorts: ports, |
|
| 1907 |
- User: *flUser, |
|
| 1908 |
- Tty: *flTty, |
|
| 1909 |
- NetworkDisabled: !*flNetwork, |
|
| 1910 |
- OpenStdin: *flStdin, |
|
| 1911 |
- Memory: flMemory, |
|
| 1912 |
- CpuShares: *flCpuShares, |
|
| 1913 |
- AttachStdin: flAttach.Get("stdin"),
|
|
| 1914 |
- AttachStdout: flAttach.Get("stdout"),
|
|
| 1915 |
- AttachStderr: flAttach.Get("stderr"),
|
|
| 1916 |
- Env: flEnv.GetAll(), |
|
| 1917 |
- Cmd: runCmd, |
|
| 1918 |
- Dns: flDns.GetAll(), |
|
| 1919 |
- Image: image, |
|
| 1920 |
- Volumes: flVolumes.GetMap(), |
|
| 1921 |
- VolumesFrom: strings.Join(flVolumesFrom.GetAll(), ","), |
|
| 1922 |
- Entrypoint: entrypoint, |
|
| 1923 |
- WorkingDir: *flWorkingDir, |
|
| 1924 |
- } |
|
| 1925 |
- |
|
| 1926 |
- hostConfig := &HostConfig{
|
|
| 1927 |
- Binds: binds, |
|
| 1928 |
- ContainerIDFile: *flContainerIDFile, |
|
| 1929 |
- LxcConf: lxcConf, |
|
| 1930 |
- Privileged: *flPrivileged, |
|
| 1931 |
- PortBindings: portBindings, |
|
| 1932 |
- Links: flLinks.GetAll(), |
|
| 1933 |
- PublishAllPorts: *flPublishAll, |
|
| 1934 |
- } |
|
| 1935 |
- |
|
| 1936 |
- if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit {
|
|
| 1937 |
- //fmt.Fprintf(stdout, "WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.\n") |
|
| 1938 |
- config.MemorySwap = -1 |
|
| 1939 |
- } |
|
| 1940 |
- |
|
| 1941 |
- // When allocating stdin in attached mode, close stdin at client disconnect |
|
| 1942 |
- if config.OpenStdin && config.AttachStdin {
|
|
| 1943 |
- config.StdinOnce = true |
|
| 1944 |
- } |
|
| 1945 |
- return config, hostConfig, cmd, nil |
|
| 1946 |
-} |
|
| 1947 |
- |
|
| 1948 | 1746 |
func (cli *DockerCli) CmdRun(args ...string) error {
|
| 1949 |
- config, hostConfig, cmd, err := parseRun(cli.Subcmd("run", "[OPTIONS] IMAGE [COMMAND] [ARG...]", "Run a command in a new container"), args, nil)
|
|
| 1747 |
+ // FIXME: just use runconfig.Parse already |
|
| 1748 |
+ config, hostConfig, cmd, err := runconfig.ParseSubcommand(cli.Subcmd("run", "[OPTIONS] IMAGE [COMMAND] [ARG...]", "Run a command in a new container"), args, nil)
|
|
| 1950 | 1749 |
if err != nil {
|
| 1951 | 1750 |
return err |
| 1952 | 1751 |
} |
| ... | ... |
@@ -1,16 +1,17 @@ |
| 1 | 1 |
package docker |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 4 | 5 |
"strings" |
| 5 | 6 |
"testing" |
| 6 | 7 |
) |
| 7 | 8 |
|
| 8 |
-func parse(t *testing.T, args string) (*Config, *HostConfig, error) {
|
|
| 9 |
- config, hostConfig, _, err := ParseRun(strings.Split(args+" ubuntu bash", " "), nil) |
|
| 9 |
+func parse(t *testing.T, args string) (*runconfig.Config, *runconfig.HostConfig, error) {
|
|
| 10 |
+ config, hostConfig, _, err := runconfig.Parse(strings.Split(args+" ubuntu bash", " "), nil) |
|
| 10 | 11 |
return config, hostConfig, err |
| 11 | 12 |
} |
| 12 | 13 |
|
| 13 |
-func mustParse(t *testing.T, args string) (*Config, *HostConfig) {
|
|
| 14 |
+func mustParse(t *testing.T, args string) (*runconfig.Config, *runconfig.HostConfig) {
|
|
| 14 | 15 |
config, hostConfig, err := parse(t, args) |
| 15 | 16 |
if err != nil {
|
| 16 | 17 |
t.Fatal(err) |
| 17 | 18 |
deleted file mode 100644 |
| ... | ... |
@@ -1,150 +0,0 @@ |
| 1 |
-package docker |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "github.com/dotcloud/docker/nat" |
|
| 5 |
- "testing" |
|
| 6 |
-) |
|
| 7 |
- |
|
| 8 |
-func TestCompareConfig(t *testing.T) {
|
|
| 9 |
- volumes1 := make(map[string]struct{})
|
|
| 10 |
- volumes1["/test1"] = struct{}{}
|
|
| 11 |
- config1 := Config{
|
|
| 12 |
- Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 13 |
- PortSpecs: []string{"1111:1111", "2222:2222"},
|
|
| 14 |
- Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 15 |
- VolumesFrom: "11111111", |
|
| 16 |
- Volumes: volumes1, |
|
| 17 |
- } |
|
| 18 |
- config2 := Config{
|
|
| 19 |
- Dns: []string{"0.0.0.0", "2.2.2.2"},
|
|
| 20 |
- PortSpecs: []string{"1111:1111", "2222:2222"},
|
|
| 21 |
- Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 22 |
- VolumesFrom: "11111111", |
|
| 23 |
- Volumes: volumes1, |
|
| 24 |
- } |
|
| 25 |
- config3 := Config{
|
|
| 26 |
- Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 27 |
- PortSpecs: []string{"0000:0000", "2222:2222"},
|
|
| 28 |
- Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 29 |
- VolumesFrom: "11111111", |
|
| 30 |
- Volumes: volumes1, |
|
| 31 |
- } |
|
| 32 |
- config4 := Config{
|
|
| 33 |
- Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 34 |
- PortSpecs: []string{"0000:0000", "2222:2222"},
|
|
| 35 |
- Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 36 |
- VolumesFrom: "22222222", |
|
| 37 |
- Volumes: volumes1, |
|
| 38 |
- } |
|
| 39 |
- volumes2 := make(map[string]struct{})
|
|
| 40 |
- volumes2["/test2"] = struct{}{}
|
|
| 41 |
- config5 := Config{
|
|
| 42 |
- Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 43 |
- PortSpecs: []string{"0000:0000", "2222:2222"},
|
|
| 44 |
- Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 45 |
- VolumesFrom: "11111111", |
|
| 46 |
- Volumes: volumes2, |
|
| 47 |
- } |
|
| 48 |
- if CompareConfig(&config1, &config2) {
|
|
| 49 |
- t.Fatalf("CompareConfig should return false, Dns are different")
|
|
| 50 |
- } |
|
| 51 |
- if CompareConfig(&config1, &config3) {
|
|
| 52 |
- t.Fatalf("CompareConfig should return false, PortSpecs are different")
|
|
| 53 |
- } |
|
| 54 |
- if CompareConfig(&config1, &config4) {
|
|
| 55 |
- t.Fatalf("CompareConfig should return false, VolumesFrom are different")
|
|
| 56 |
- } |
|
| 57 |
- if CompareConfig(&config1, &config5) {
|
|
| 58 |
- t.Fatalf("CompareConfig should return false, Volumes are different")
|
|
| 59 |
- } |
|
| 60 |
- if !CompareConfig(&config1, &config1) {
|
|
| 61 |
- t.Fatalf("CompareConfig should return true")
|
|
| 62 |
- } |
|
| 63 |
-} |
|
| 64 |
- |
|
| 65 |
-func TestMergeConfig(t *testing.T) {
|
|
| 66 |
- volumesImage := make(map[string]struct{})
|
|
| 67 |
- volumesImage["/test1"] = struct{}{}
|
|
| 68 |
- volumesImage["/test2"] = struct{}{}
|
|
| 69 |
- configImage := &Config{
|
|
| 70 |
- Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 71 |
- PortSpecs: []string{"1111:1111", "2222:2222"},
|
|
| 72 |
- Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 73 |
- VolumesFrom: "1111", |
|
| 74 |
- Volumes: volumesImage, |
|
| 75 |
- } |
|
| 76 |
- |
|
| 77 |
- volumesUser := make(map[string]struct{})
|
|
| 78 |
- volumesUser["/test3"] = struct{}{}
|
|
| 79 |
- configUser := &Config{
|
|
| 80 |
- Dns: []string{"3.3.3.3"},
|
|
| 81 |
- PortSpecs: []string{"3333:2222", "3333:3333"},
|
|
| 82 |
- Env: []string{"VAR2=3", "VAR3=3"},
|
|
| 83 |
- Volumes: volumesUser, |
|
| 84 |
- } |
|
| 85 |
- |
|
| 86 |
- if err := MergeConfig(configUser, configImage); err != nil {
|
|
| 87 |
- t.Error(err) |
|
| 88 |
- } |
|
| 89 |
- |
|
| 90 |
- if len(configUser.Dns) != 3 {
|
|
| 91 |
- t.Fatalf("Expected 3 dns, 1.1.1.1, 2.2.2.2 and 3.3.3.3, found %d", len(configUser.Dns))
|
|
| 92 |
- } |
|
| 93 |
- for _, dns := range configUser.Dns {
|
|
| 94 |
- if dns != "1.1.1.1" && dns != "2.2.2.2" && dns != "3.3.3.3" {
|
|
| 95 |
- t.Fatalf("Expected 1.1.1.1 or 2.2.2.2 or 3.3.3.3, found %s", dns)
|
|
| 96 |
- } |
|
| 97 |
- } |
|
| 98 |
- |
|
| 99 |
- if len(configUser.ExposedPorts) != 3 {
|
|
| 100 |
- t.Fatalf("Expected 3 ExposedPorts, 1111, 2222 and 3333, found %d", len(configUser.ExposedPorts))
|
|
| 101 |
- } |
|
| 102 |
- for portSpecs := range configUser.ExposedPorts {
|
|
| 103 |
- if portSpecs.Port() != "1111" && portSpecs.Port() != "2222" && portSpecs.Port() != "3333" {
|
|
| 104 |
- t.Fatalf("Expected 1111 or 2222 or 3333, found %s", portSpecs)
|
|
| 105 |
- } |
|
| 106 |
- } |
|
| 107 |
- if len(configUser.Env) != 3 {
|
|
| 108 |
- t.Fatalf("Expected 3 env var, VAR1=1, VAR2=3 and VAR3=3, found %d", len(configUser.Env))
|
|
| 109 |
- } |
|
| 110 |
- for _, env := range configUser.Env {
|
|
| 111 |
- if env != "VAR1=1" && env != "VAR2=3" && env != "VAR3=3" {
|
|
| 112 |
- t.Fatalf("Expected VAR1=1 or VAR2=3 or VAR3=3, found %s", env)
|
|
| 113 |
- } |
|
| 114 |
- } |
|
| 115 |
- |
|
| 116 |
- if len(configUser.Volumes) != 3 {
|
|
| 117 |
- t.Fatalf("Expected 3 volumes, /test1, /test2 and /test3, found %d", len(configUser.Volumes))
|
|
| 118 |
- } |
|
| 119 |
- for v := range configUser.Volumes {
|
|
| 120 |
- if v != "/test1" && v != "/test2" && v != "/test3" {
|
|
| 121 |
- t.Fatalf("Expected /test1 or /test2 or /test3, found %s", v)
|
|
| 122 |
- } |
|
| 123 |
- } |
|
| 124 |
- |
|
| 125 |
- if configUser.VolumesFrom != "1111" {
|
|
| 126 |
- t.Fatalf("Expected VolumesFrom to be 1111, found %s", configUser.VolumesFrom)
|
|
| 127 |
- } |
|
| 128 |
- |
|
| 129 |
- ports, _, err := nat.ParsePortSpecs([]string{"0000"})
|
|
| 130 |
- if err != nil {
|
|
| 131 |
- t.Error(err) |
|
| 132 |
- } |
|
| 133 |
- configImage2 := &Config{
|
|
| 134 |
- ExposedPorts: ports, |
|
| 135 |
- } |
|
| 136 |
- |
|
| 137 |
- if err := MergeConfig(configUser, configImage2); err != nil {
|
|
| 138 |
- t.Error(err) |
|
| 139 |
- } |
|
| 140 |
- |
|
| 141 |
- if len(configUser.ExposedPorts) != 4 {
|
|
| 142 |
- t.Fatalf("Expected 4 ExposedPorts, 0000, 1111, 2222 and 3333, found %d", len(configUser.ExposedPorts))
|
|
| 143 |
- } |
|
| 144 |
- for portSpecs := range configUser.ExposedPorts {
|
|
| 145 |
- if portSpecs.Port() != "0000" && portSpecs.Port() != "1111" && portSpecs.Port() != "2222" && portSpecs.Port() != "3333" {
|
|
| 146 |
- t.Fatalf("Expected 0000 or 1111 or 2222 or 3333, found %s", portSpecs)
|
|
| 147 |
- } |
|
| 148 |
- } |
|
| 149 |
- |
|
| 150 |
-} |
| ... | ... |
@@ -11,6 +11,7 @@ import ( |
| 11 | 11 |
"github.com/dotcloud/docker/nat" |
| 12 | 12 |
"github.com/dotcloud/docker/pkg/mount" |
| 13 | 13 |
"github.com/dotcloud/docker/pkg/term" |
| 14 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 14 | 15 |
"github.com/dotcloud/docker/utils" |
| 15 | 16 |
"github.com/kr/pty" |
| 16 | 17 |
"io" |
| ... | ... |
@@ -42,7 +43,7 @@ type Container struct {
|
| 42 | 42 |
Path string |
| 43 | 43 |
Args []string |
| 44 | 44 |
|
| 45 |
- Config *Config |
|
| 45 |
+ Config *runconfig.Config |
|
| 46 | 46 |
State State |
| 47 | 47 |
Image string |
| 48 | 48 |
|
| ... | ... |
@@ -68,109 +69,11 @@ type Container struct {
|
| 68 | 68 |
// Store rw/ro in a separate structure to preserve reverse-compatibility on-disk. |
| 69 | 69 |
// Easier than migrating older container configs :) |
| 70 | 70 |
VolumesRW map[string]bool |
| 71 |
- hostConfig *HostConfig |
|
| 71 |
+ hostConfig *runconfig.HostConfig |
|
| 72 | 72 |
|
| 73 | 73 |
activeLinks map[string]*Link |
| 74 | 74 |
} |
| 75 | 75 |
|
| 76 |
-// Note: the Config structure should hold only portable information about the container. |
|
| 77 |
-// Here, "portable" means "independent from the host we are running on". |
|
| 78 |
-// Non-portable information *should* appear in HostConfig. |
|
| 79 |
-type Config struct {
|
|
| 80 |
- Hostname string |
|
| 81 |
- Domainname string |
|
| 82 |
- User string |
|
| 83 |
- Memory int64 // Memory limit (in bytes) |
|
| 84 |
- MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap |
|
| 85 |
- CpuShares int64 // CPU shares (relative weight vs. other containers) |
|
| 86 |
- AttachStdin bool |
|
| 87 |
- AttachStdout bool |
|
| 88 |
- AttachStderr bool |
|
| 89 |
- PortSpecs []string // Deprecated - Can be in the format of 8080/tcp |
|
| 90 |
- ExposedPorts map[nat.Port]struct{}
|
|
| 91 |
- Tty bool // Attach standard streams to a tty, including stdin if it is not closed. |
|
| 92 |
- OpenStdin bool // Open stdin |
|
| 93 |
- StdinOnce bool // If true, close stdin after the 1 attached client disconnects. |
|
| 94 |
- Env []string |
|
| 95 |
- Cmd []string |
|
| 96 |
- Dns []string |
|
| 97 |
- Image string // Name of the image as it was passed by the operator (eg. could be symbolic) |
|
| 98 |
- Volumes map[string]struct{}
|
|
| 99 |
- VolumesFrom string |
|
| 100 |
- WorkingDir string |
|
| 101 |
- Entrypoint []string |
|
| 102 |
- NetworkDisabled bool |
|
| 103 |
- OnBuild []string |
|
| 104 |
-} |
|
| 105 |
- |
|
| 106 |
-func ContainerConfigFromJob(job *engine.Job) *Config {
|
|
| 107 |
- config := &Config{
|
|
| 108 |
- Hostname: job.Getenv("Hostname"),
|
|
| 109 |
- Domainname: job.Getenv("Domainname"),
|
|
| 110 |
- User: job.Getenv("User"),
|
|
| 111 |
- Memory: job.GetenvInt64("Memory"),
|
|
| 112 |
- MemorySwap: job.GetenvInt64("MemorySwap"),
|
|
| 113 |
- CpuShares: job.GetenvInt64("CpuShares"),
|
|
| 114 |
- AttachStdin: job.GetenvBool("AttachStdin"),
|
|
| 115 |
- AttachStdout: job.GetenvBool("AttachStdout"),
|
|
| 116 |
- AttachStderr: job.GetenvBool("AttachStderr"),
|
|
| 117 |
- Tty: job.GetenvBool("Tty"),
|
|
| 118 |
- OpenStdin: job.GetenvBool("OpenStdin"),
|
|
| 119 |
- StdinOnce: job.GetenvBool("StdinOnce"),
|
|
| 120 |
- Image: job.Getenv("Image"),
|
|
| 121 |
- VolumesFrom: job.Getenv("VolumesFrom"),
|
|
| 122 |
- WorkingDir: job.Getenv("WorkingDir"),
|
|
| 123 |
- NetworkDisabled: job.GetenvBool("NetworkDisabled"),
|
|
| 124 |
- } |
|
| 125 |
- job.GetenvJson("ExposedPorts", &config.ExposedPorts)
|
|
| 126 |
- job.GetenvJson("Volumes", &config.Volumes)
|
|
| 127 |
- if PortSpecs := job.GetenvList("PortSpecs"); PortSpecs != nil {
|
|
| 128 |
- config.PortSpecs = PortSpecs |
|
| 129 |
- } |
|
| 130 |
- if Env := job.GetenvList("Env"); Env != nil {
|
|
| 131 |
- config.Env = Env |
|
| 132 |
- } |
|
| 133 |
- if Cmd := job.GetenvList("Cmd"); Cmd != nil {
|
|
| 134 |
- config.Cmd = Cmd |
|
| 135 |
- } |
|
| 136 |
- if Dns := job.GetenvList("Dns"); Dns != nil {
|
|
| 137 |
- config.Dns = Dns |
|
| 138 |
- } |
|
| 139 |
- if Entrypoint := job.GetenvList("Entrypoint"); Entrypoint != nil {
|
|
| 140 |
- config.Entrypoint = Entrypoint |
|
| 141 |
- } |
|
| 142 |
- |
|
| 143 |
- return config |
|
| 144 |
-} |
|
| 145 |
- |
|
| 146 |
-type HostConfig struct {
|
|
| 147 |
- Binds []string |
|
| 148 |
- ContainerIDFile string |
|
| 149 |
- LxcConf []KeyValuePair |
|
| 150 |
- Privileged bool |
|
| 151 |
- PortBindings nat.PortMap |
|
| 152 |
- Links []string |
|
| 153 |
- PublishAllPorts bool |
|
| 154 |
-} |
|
| 155 |
- |
|
| 156 |
-func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
|
|
| 157 |
- hostConfig := &HostConfig{
|
|
| 158 |
- ContainerIDFile: job.Getenv("ContainerIDFile"),
|
|
| 159 |
- Privileged: job.GetenvBool("Privileged"),
|
|
| 160 |
- PublishAllPorts: job.GetenvBool("PublishAllPorts"),
|
|
| 161 |
- } |
|
| 162 |
- job.GetenvJson("LxcConf", &hostConfig.LxcConf)
|
|
| 163 |
- job.GetenvJson("PortBindings", &hostConfig.PortBindings)
|
|
| 164 |
- if Binds := job.GetenvList("Binds"); Binds != nil {
|
|
| 165 |
- hostConfig.Binds = Binds |
|
| 166 |
- } |
|
| 167 |
- if Links := job.GetenvList("Links"); Links != nil {
|
|
| 168 |
- hostConfig.Links = Links |
|
| 169 |
- } |
|
| 170 |
- |
|
| 171 |
- return hostConfig |
|
| 172 |
-} |
|
| 173 |
- |
|
| 174 | 76 |
type BindMap struct {
|
| 175 | 77 |
SrcPath string |
| 176 | 78 |
DstPath string |
| ... | ... |
@@ -178,18 +81,10 @@ type BindMap struct {
|
| 178 | 178 |
} |
| 179 | 179 |
|
| 180 | 180 |
var ( |
| 181 |
- ErrContainerStart = errors.New("The container failed to start. Unknown error")
|
|
| 182 |
- ErrContainerStartTimeout = errors.New("The container failed to start due to timed out.")
|
|
| 183 |
- ErrInvalidWorikingDirectory = errors.New("The working directory is invalid. It needs to be an absolute path.")
|
|
| 184 |
- ErrConflictAttachDetach = errors.New("Conflicting options: -a and -d")
|
|
| 185 |
- ErrConflictDetachAutoRemove = errors.New("Conflicting options: -rm and -d")
|
|
| 181 |
+ ErrContainerStart = errors.New("The container failed to start. Unknown error")
|
|
| 182 |
+ ErrContainerStartTimeout = errors.New("The container failed to start due to timed out.")
|
|
| 186 | 183 |
) |
| 187 | 184 |
|
| 188 |
-type KeyValuePair struct {
|
|
| 189 |
- Key string |
|
| 190 |
- Value string |
|
| 191 |
-} |
|
| 192 |
- |
|
| 193 | 185 |
// FIXME: move deprecated port stuff to nat to clean up the core. |
| 194 | 186 |
type PortMapping map[string]string // Deprecated |
| 195 | 187 |
|
| ... | ... |
@@ -292,7 +187,7 @@ func (container *Container) ToDisk() (err error) {
|
| 292 | 292 |
} |
| 293 | 293 |
|
| 294 | 294 |
func (container *Container) readHostConfig() error {
|
| 295 |
- container.hostConfig = &HostConfig{}
|
|
| 295 |
+ container.hostConfig = &runconfig.HostConfig{}
|
|
| 296 | 296 |
// If the hostconfig file does not exist, do not read it. |
| 297 | 297 |
// (We still have to initialize container.hostConfig, |
| 298 | 298 |
// but that's OK, since we just did that above.) |
| ... | ... |
@@ -5,23 +5,6 @@ import ( |
| 5 | 5 |
"testing" |
| 6 | 6 |
) |
| 7 | 7 |
|
| 8 |
-func TestParseLxcConfOpt(t *testing.T) {
|
|
| 9 |
- opts := []string{"lxc.utsname=docker", "lxc.utsname = docker "}
|
|
| 10 |
- |
|
| 11 |
- for _, o := range opts {
|
|
| 12 |
- k, v, err := parseLxcOpt(o) |
|
| 13 |
- if err != nil {
|
|
| 14 |
- t.FailNow() |
|
| 15 |
- } |
|
| 16 |
- if k != "lxc.utsname" {
|
|
| 17 |
- t.Fail() |
|
| 18 |
- } |
|
| 19 |
- if v != "docker" {
|
|
| 20 |
- t.Fail() |
|
| 21 |
- } |
|
| 22 |
- } |
|
| 23 |
-} |
|
| 24 |
- |
|
| 25 | 8 |
func TestParseNetworkOptsPrivateOnly(t *testing.T) {
|
| 26 | 9 |
ports, bindings, err := nat.ParsePortSpecs([]string{"192.168.1.100::80"})
|
| 27 | 10 |
if err != nil {
|
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"github.com/dotcloud/docker/archive" |
| 6 | 6 |
"github.com/dotcloud/docker/dockerversion" |
| 7 | 7 |
"github.com/dotcloud/docker/graphdriver" |
| 8 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 8 | 9 |
"github.com/dotcloud/docker/utils" |
| 9 | 10 |
"io" |
| 10 | 11 |
"io/ioutil" |
| ... | ... |
@@ -126,7 +127,7 @@ func (graph *Graph) Get(name string) (*Image, error) {
|
| 126 | 126 |
} |
| 127 | 127 |
|
| 128 | 128 |
// Create creates a new image and registers it in the graph. |
| 129 |
-func (graph *Graph) Create(layerData archive.Archive, container *Container, comment, author string, config *Config) (*Image, error) {
|
|
| 129 |
+func (graph *Graph) Create(layerData archive.Archive, container *Container, comment, author string, config *runconfig.Config) (*Image, error) {
|
|
| 130 | 130 |
img := &Image{
|
| 131 | 131 |
ID: GenerateID(), |
| 132 | 132 |
Comment: comment, |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
"fmt" |
| 8 | 8 |
"github.com/dotcloud/docker/archive" |
| 9 | 9 |
"github.com/dotcloud/docker/graphdriver" |
| 10 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 10 | 11 |
"github.com/dotcloud/docker/utils" |
| 11 | 12 |
"io" |
| 12 | 13 |
"io/ioutil" |
| ... | ... |
@@ -18,17 +19,17 @@ import ( |
| 18 | 18 |
) |
| 19 | 19 |
|
| 20 | 20 |
type Image struct {
|
| 21 |
- ID string `json:"id"` |
|
| 22 |
- Parent string `json:"parent,omitempty"` |
|
| 23 |
- Comment string `json:"comment,omitempty"` |
|
| 24 |
- Created time.Time `json:"created"` |
|
| 25 |
- Container string `json:"container,omitempty"` |
|
| 26 |
- ContainerConfig Config `json:"container_config,omitempty"` |
|
| 27 |
- DockerVersion string `json:"docker_version,omitempty"` |
|
| 28 |
- Author string `json:"author,omitempty"` |
|
| 29 |
- Config *Config `json:"config,omitempty"` |
|
| 30 |
- Architecture string `json:"architecture,omitempty"` |
|
| 31 |
- OS string `json:"os,omitempty"` |
|
| 21 |
+ ID string `json:"id"` |
|
| 22 |
+ Parent string `json:"parent,omitempty"` |
|
| 23 |
+ Comment string `json:"comment,omitempty"` |
|
| 24 |
+ Created time.Time `json:"created"` |
|
| 25 |
+ Container string `json:"container,omitempty"` |
|
| 26 |
+ ContainerConfig runconfig.Config `json:"container_config,omitempty"` |
|
| 27 |
+ DockerVersion string `json:"docker_version,omitempty"` |
|
| 28 |
+ Author string `json:"author,omitempty"` |
|
| 29 |
+ Config *runconfig.Config `json:"config,omitempty"` |
|
| 30 |
+ Architecture string `json:"architecture,omitempty"` |
|
| 31 |
+ OS string `json:"os,omitempty"` |
|
| 32 | 32 |
graph *Graph |
| 33 | 33 |
Size int64 |
| 34 | 34 |
} |
| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
"github.com/dotcloud/docker/api" |
| 11 | 11 |
"github.com/dotcloud/docker/dockerversion" |
| 12 | 12 |
"github.com/dotcloud/docker/engine" |
| 13 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 13 | 14 |
"github.com/dotcloud/docker/utils" |
| 14 | 15 |
"io" |
| 15 | 16 |
"net" |
| ... | ... |
@@ -309,7 +310,7 @@ func TestGetContainersJSON(t *testing.T) {
|
| 309 | 309 |
} |
| 310 | 310 |
beginLen := len(outs.Data) |
| 311 | 311 |
|
| 312 |
- containerID := createTestContainer(eng, &docker.Config{
|
|
| 312 |
+ containerID := createTestContainer(eng, &runconfig.Config{
|
|
| 313 | 313 |
Image: unitTestImageID, |
| 314 | 314 |
Cmd: []string{"echo", "test"},
|
| 315 | 315 |
}, t) |
| ... | ... |
@@ -346,7 +347,7 @@ func TestGetContainersExport(t *testing.T) {
|
| 346 | 346 |
|
| 347 | 347 |
// Create a container and remove a file |
| 348 | 348 |
containerID := createTestContainer(eng, |
| 349 |
- &docker.Config{
|
|
| 349 |
+ &runconfig.Config{
|
|
| 350 | 350 |
Image: unitTestImageID, |
| 351 | 351 |
Cmd: []string{"touch", "/test"},
|
| 352 | 352 |
}, |
| ... | ... |
@@ -394,7 +395,7 @@ func TestGetContainersChanges(t *testing.T) {
|
| 394 | 394 |
|
| 395 | 395 |
// Create a container and remove a file |
| 396 | 396 |
containerID := createTestContainer(eng, |
| 397 |
- &docker.Config{
|
|
| 397 |
+ &runconfig.Config{
|
|
| 398 | 398 |
Image: unitTestImageID, |
| 399 | 399 |
Cmd: []string{"/bin/rm", "/etc/passwd"},
|
| 400 | 400 |
}, |
| ... | ... |
@@ -433,7 +434,7 @@ func TestGetContainersTop(t *testing.T) {
|
| 433 | 433 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 434 | 434 |
|
| 435 | 435 |
containerID := createTestContainer(eng, |
| 436 |
- &docker.Config{
|
|
| 436 |
+ &runconfig.Config{
|
|
| 437 | 437 |
Image: unitTestImageID, |
| 438 | 438 |
Cmd: []string{"/bin/sh", "-c", "cat"},
|
| 439 | 439 |
OpenStdin: true, |
| ... | ... |
@@ -510,7 +511,7 @@ func TestGetContainersByName(t *testing.T) {
|
| 510 | 510 |
|
| 511 | 511 |
// Create a container and remove a file |
| 512 | 512 |
containerID := createTestContainer(eng, |
| 513 |
- &docker.Config{
|
|
| 513 |
+ &runconfig.Config{
|
|
| 514 | 514 |
Image: unitTestImageID, |
| 515 | 515 |
Cmd: []string{"echo", "test"},
|
| 516 | 516 |
}, |
| ... | ... |
@@ -542,7 +543,7 @@ func TestPostCommit(t *testing.T) {
|
| 542 | 542 |
|
| 543 | 543 |
// Create a container and remove a file |
| 544 | 544 |
containerID := createTestContainer(eng, |
| 545 |
- &docker.Config{
|
|
| 545 |
+ &runconfig.Config{
|
|
| 546 | 546 |
Image: unitTestImageID, |
| 547 | 547 |
Cmd: []string{"touch", "/test"},
|
| 548 | 548 |
}, |
| ... | ... |
@@ -578,7 +579,7 @@ func TestPostContainersCreate(t *testing.T) {
|
| 578 | 578 |
eng := NewTestEngine(t) |
| 579 | 579 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 580 | 580 |
|
| 581 |
- configJSON, err := json.Marshal(&docker.Config{
|
|
| 581 |
+ configJSON, err := json.Marshal(&runconfig.Config{
|
|
| 582 | 582 |
Image: unitTestImageID, |
| 583 | 583 |
Memory: 33554432, |
| 584 | 584 |
Cmd: []string{"touch", "/test"},
|
| ... | ... |
@@ -620,7 +621,7 @@ func TestPostContainersKill(t *testing.T) {
|
| 620 | 620 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 621 | 621 |
|
| 622 | 622 |
containerID := createTestContainer(eng, |
| 623 |
- &docker.Config{
|
|
| 623 |
+ &runconfig.Config{
|
|
| 624 | 624 |
Image: unitTestImageID, |
| 625 | 625 |
Cmd: []string{"/bin/cat"},
|
| 626 | 626 |
OpenStdin: true, |
| ... | ... |
@@ -659,7 +660,7 @@ func TestPostContainersRestart(t *testing.T) {
|
| 659 | 659 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 660 | 660 |
|
| 661 | 661 |
containerID := createTestContainer(eng, |
| 662 |
- &docker.Config{
|
|
| 662 |
+ &runconfig.Config{
|
|
| 663 | 663 |
Image: unitTestImageID, |
| 664 | 664 |
Cmd: []string{"/bin/top"},
|
| 665 | 665 |
OpenStdin: true, |
| ... | ... |
@@ -705,7 +706,7 @@ func TestPostContainersStart(t *testing.T) {
|
| 705 | 705 |
|
| 706 | 706 |
containerID := createTestContainer( |
| 707 | 707 |
eng, |
| 708 |
- &docker.Config{
|
|
| 708 |
+ &runconfig.Config{
|
|
| 709 | 709 |
Image: unitTestImageID, |
| 710 | 710 |
Cmd: []string{"/bin/cat"},
|
| 711 | 711 |
OpenStdin: true, |
| ... | ... |
@@ -713,7 +714,7 @@ func TestPostContainersStart(t *testing.T) {
|
| 713 | 713 |
t, |
| 714 | 714 |
) |
| 715 | 715 |
|
| 716 |
- hostConfigJSON, err := json.Marshal(&docker.HostConfig{})
|
|
| 716 |
+ hostConfigJSON, err := json.Marshal(&runconfig.HostConfig{})
|
|
| 717 | 717 |
|
| 718 | 718 |
req, err := http.NewRequest("POST", "/containers/"+containerID+"/start", bytes.NewReader(hostConfigJSON))
|
| 719 | 719 |
if err != nil {
|
| ... | ... |
@@ -758,7 +759,7 @@ func TestRunErrorBindMountRootSource(t *testing.T) {
|
| 758 | 758 |
|
| 759 | 759 |
containerID := createTestContainer( |
| 760 | 760 |
eng, |
| 761 |
- &docker.Config{
|
|
| 761 |
+ &runconfig.Config{
|
|
| 762 | 762 |
Image: unitTestImageID, |
| 763 | 763 |
Cmd: []string{"/bin/cat"},
|
| 764 | 764 |
OpenStdin: true, |
| ... | ... |
@@ -766,7 +767,7 @@ func TestRunErrorBindMountRootSource(t *testing.T) {
|
| 766 | 766 |
t, |
| 767 | 767 |
) |
| 768 | 768 |
|
| 769 |
- hostConfigJSON, err := json.Marshal(&docker.HostConfig{
|
|
| 769 |
+ hostConfigJSON, err := json.Marshal(&runconfig.HostConfig{
|
|
| 770 | 770 |
Binds: []string{"/:/tmp"},
|
| 771 | 771 |
}) |
| 772 | 772 |
|
| ... | ... |
@@ -792,7 +793,7 @@ func TestPostContainersStop(t *testing.T) {
|
| 792 | 792 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 793 | 793 |
|
| 794 | 794 |
containerID := createTestContainer(eng, |
| 795 |
- &docker.Config{
|
|
| 795 |
+ &runconfig.Config{
|
|
| 796 | 796 |
Image: unitTestImageID, |
| 797 | 797 |
Cmd: []string{"/bin/top"},
|
| 798 | 798 |
OpenStdin: true, |
| ... | ... |
@@ -832,7 +833,7 @@ func TestPostContainersWait(t *testing.T) {
|
| 832 | 832 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 833 | 833 |
|
| 834 | 834 |
containerID := createTestContainer(eng, |
| 835 |
- &docker.Config{
|
|
| 835 |
+ &runconfig.Config{
|
|
| 836 | 836 |
Image: unitTestImageID, |
| 837 | 837 |
Cmd: []string{"/bin/sleep", "1"},
|
| 838 | 838 |
OpenStdin: true, |
| ... | ... |
@@ -870,7 +871,7 @@ func TestPostContainersAttach(t *testing.T) {
|
| 870 | 870 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 871 | 871 |
|
| 872 | 872 |
containerID := createTestContainer(eng, |
| 873 |
- &docker.Config{
|
|
| 873 |
+ &runconfig.Config{
|
|
| 874 | 874 |
Image: unitTestImageID, |
| 875 | 875 |
Cmd: []string{"/bin/cat"},
|
| 876 | 876 |
OpenStdin: true, |
| ... | ... |
@@ -948,7 +949,7 @@ func TestPostContainersAttachStderr(t *testing.T) {
|
| 948 | 948 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 949 | 949 |
|
| 950 | 950 |
containerID := createTestContainer(eng, |
| 951 |
- &docker.Config{
|
|
| 951 |
+ &runconfig.Config{
|
|
| 952 | 952 |
Image: unitTestImageID, |
| 953 | 953 |
Cmd: []string{"/bin/sh", "-c", "/bin/cat >&2"},
|
| 954 | 954 |
OpenStdin: true, |
| ... | ... |
@@ -1029,7 +1030,7 @@ func TestDeleteContainers(t *testing.T) {
|
| 1029 | 1029 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 1030 | 1030 |
|
| 1031 | 1031 |
containerID := createTestContainer(eng, |
| 1032 |
- &docker.Config{
|
|
| 1032 |
+ &runconfig.Config{
|
|
| 1033 | 1033 |
Image: unitTestImageID, |
| 1034 | 1034 |
Cmd: []string{"touch", "/test"},
|
| 1035 | 1035 |
}, |
| ... | ... |
@@ -1164,7 +1165,7 @@ func TestPostContainersCopy(t *testing.T) {
|
| 1164 | 1164 |
|
| 1165 | 1165 |
// Create a container and remove a file |
| 1166 | 1166 |
containerID := createTestContainer(eng, |
| 1167 |
- &docker.Config{
|
|
| 1167 |
+ &runconfig.Config{
|
|
| 1168 | 1168 |
Image: unitTestImageID, |
| 1169 | 1169 |
Cmd: []string{"touch", "/test.txt"},
|
| 1170 | 1170 |
}, |
| ... | ... |
@@ -3,7 +3,7 @@ package docker |
| 3 | 3 |
import ( |
| 4 | 4 |
"bufio" |
| 5 | 5 |
"fmt" |
| 6 |
- "github.com/dotcloud/docker" |
|
| 6 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 7 | 7 |
"github.com/dotcloud/docker/utils" |
| 8 | 8 |
"io" |
| 9 | 9 |
"io/ioutil" |
| ... | ... |
@@ -20,7 +20,7 @@ func TestIDFormat(t *testing.T) {
|
| 20 | 20 |
runtime := mkRuntime(t) |
| 21 | 21 |
defer nuke(runtime) |
| 22 | 22 |
container1, _, err := runtime.Create( |
| 23 |
- &docker.Config{
|
|
| 23 |
+ &runconfig.Config{
|
|
| 24 | 24 |
Image: GetTestImage(runtime).ID, |
| 25 | 25 |
Cmd: []string{"/bin/sh", "-c", "echo hello world"},
|
| 26 | 26 |
}, |
| ... | ... |
@@ -234,7 +234,7 @@ func TestCommitAutoRun(t *testing.T) {
|
| 234 | 234 |
t.Errorf("Container shouldn't be running")
|
| 235 | 235 |
} |
| 236 | 236 |
|
| 237 |
- img, err := runtime.Commit(container1, "", "", "unit test commited image", "", &docker.Config{Cmd: []string{"cat", "/world"}})
|
|
| 237 |
+ img, err := runtime.Commit(container1, "", "", "unit test commited image", "", &runconfig.Config{Cmd: []string{"cat", "/world"}})
|
|
| 238 | 238 |
if err != nil {
|
| 239 | 239 |
t.Error(err) |
| 240 | 240 |
} |
| ... | ... |
@@ -415,7 +415,7 @@ func TestOutput(t *testing.T) {
|
| 415 | 415 |
runtime := mkRuntime(t) |
| 416 | 416 |
defer nuke(runtime) |
| 417 | 417 |
container, _, err := runtime.Create( |
| 418 |
- &docker.Config{
|
|
| 418 |
+ &runconfig.Config{
|
|
| 419 | 419 |
Image: GetTestImage(runtime).ID, |
| 420 | 420 |
Cmd: []string{"echo", "-n", "foobar"},
|
| 421 | 421 |
}, |
| ... | ... |
@@ -438,7 +438,7 @@ func TestContainerNetwork(t *testing.T) {
|
| 438 | 438 |
runtime := mkRuntime(t) |
| 439 | 439 |
defer nuke(runtime) |
| 440 | 440 |
container, _, err := runtime.Create( |
| 441 |
- &docker.Config{
|
|
| 441 |
+ &runconfig.Config{
|
|
| 442 | 442 |
Image: GetTestImage(runtime).ID, |
| 443 | 443 |
Cmd: []string{"ping", "-c", "1", "127.0.0.1"},
|
| 444 | 444 |
}, |
| ... | ... |
@@ -460,7 +460,7 @@ func TestKillDifferentUser(t *testing.T) {
|
| 460 | 460 |
runtime := mkRuntime(t) |
| 461 | 461 |
defer nuke(runtime) |
| 462 | 462 |
|
| 463 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 463 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 464 | 464 |
Image: GetTestImage(runtime).ID, |
| 465 | 465 |
Cmd: []string{"cat"},
|
| 466 | 466 |
OpenStdin: true, |
| ... | ... |
@@ -520,7 +520,7 @@ func TestCreateVolume(t *testing.T) {
|
| 520 | 520 |
runtime := mkRuntimeFromEngine(eng, t) |
| 521 | 521 |
defer nuke(runtime) |
| 522 | 522 |
|
| 523 |
- config, hc, _, err := docker.ParseRun([]string{"-v", "/var/lib/data", unitTestImageID, "echo", "hello", "world"}, nil)
|
|
| 523 |
+ config, hc, _, err := runconfig.Parse([]string{"-v", "/var/lib/data", unitTestImageID, "echo", "hello", "world"}, nil)
|
|
| 524 | 524 |
if err != nil {
|
| 525 | 525 |
t.Fatal(err) |
| 526 | 526 |
} |
| ... | ... |
@@ -552,7 +552,7 @@ func TestCreateVolume(t *testing.T) {
|
| 552 | 552 |
func TestKill(t *testing.T) {
|
| 553 | 553 |
runtime := mkRuntime(t) |
| 554 | 554 |
defer nuke(runtime) |
| 555 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 555 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 556 | 556 |
Image: GetTestImage(runtime).ID, |
| 557 | 557 |
Cmd: []string{"sleep", "2"},
|
| 558 | 558 |
}, |
| ... | ... |
@@ -596,7 +596,7 @@ func TestExitCode(t *testing.T) {
|
| 596 | 596 |
runtime := mkRuntime(t) |
| 597 | 597 |
defer nuke(runtime) |
| 598 | 598 |
|
| 599 |
- trueContainer, _, err := runtime.Create(&docker.Config{
|
|
| 599 |
+ trueContainer, _, err := runtime.Create(&runconfig.Config{
|
|
| 600 | 600 |
Image: GetTestImage(runtime).ID, |
| 601 | 601 |
Cmd: []string{"/bin/true"},
|
| 602 | 602 |
}, "") |
| ... | ... |
@@ -611,7 +611,7 @@ func TestExitCode(t *testing.T) {
|
| 611 | 611 |
t.Fatalf("Unexpected exit code %d (expected 0)", code)
|
| 612 | 612 |
} |
| 613 | 613 |
|
| 614 |
- falseContainer, _, err := runtime.Create(&docker.Config{
|
|
| 614 |
+ falseContainer, _, err := runtime.Create(&runconfig.Config{
|
|
| 615 | 615 |
Image: GetTestImage(runtime).ID, |
| 616 | 616 |
Cmd: []string{"/bin/false"},
|
| 617 | 617 |
}, "") |
| ... | ... |
@@ -630,7 +630,7 @@ func TestExitCode(t *testing.T) {
|
| 630 | 630 |
func TestRestart(t *testing.T) {
|
| 631 | 631 |
runtime := mkRuntime(t) |
| 632 | 632 |
defer nuke(runtime) |
| 633 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 633 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 634 | 634 |
Image: GetTestImage(runtime).ID, |
| 635 | 635 |
Cmd: []string{"echo", "-n", "foobar"},
|
| 636 | 636 |
}, |
| ... | ... |
@@ -661,7 +661,7 @@ func TestRestart(t *testing.T) {
|
| 661 | 661 |
func TestRestartStdin(t *testing.T) {
|
| 662 | 662 |
runtime := mkRuntime(t) |
| 663 | 663 |
defer nuke(runtime) |
| 664 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 664 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 665 | 665 |
Image: GetTestImage(runtime).ID, |
| 666 | 666 |
Cmd: []string{"cat"},
|
| 667 | 667 |
|
| ... | ... |
@@ -739,7 +739,7 @@ func TestUser(t *testing.T) {
|
| 739 | 739 |
defer nuke(runtime) |
| 740 | 740 |
|
| 741 | 741 |
// Default user must be root |
| 742 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 742 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 743 | 743 |
Image: GetTestImage(runtime).ID, |
| 744 | 744 |
Cmd: []string{"id"},
|
| 745 | 745 |
}, |
| ... | ... |
@@ -758,7 +758,7 @@ func TestUser(t *testing.T) {
|
| 758 | 758 |
} |
| 759 | 759 |
|
| 760 | 760 |
// Set a username |
| 761 |
- container, _, err = runtime.Create(&docker.Config{
|
|
| 761 |
+ container, _, err = runtime.Create(&runconfig.Config{
|
|
| 762 | 762 |
Image: GetTestImage(runtime).ID, |
| 763 | 763 |
Cmd: []string{"id"},
|
| 764 | 764 |
|
| ... | ... |
@@ -779,7 +779,7 @@ func TestUser(t *testing.T) {
|
| 779 | 779 |
} |
| 780 | 780 |
|
| 781 | 781 |
// Set a UID |
| 782 |
- container, _, err = runtime.Create(&docker.Config{
|
|
| 782 |
+ container, _, err = runtime.Create(&runconfig.Config{
|
|
| 783 | 783 |
Image: GetTestImage(runtime).ID, |
| 784 | 784 |
Cmd: []string{"id"},
|
| 785 | 785 |
|
| ... | ... |
@@ -800,7 +800,7 @@ func TestUser(t *testing.T) {
|
| 800 | 800 |
} |
| 801 | 801 |
|
| 802 | 802 |
// Set a different user by uid |
| 803 |
- container, _, err = runtime.Create(&docker.Config{
|
|
| 803 |
+ container, _, err = runtime.Create(&runconfig.Config{
|
|
| 804 | 804 |
Image: GetTestImage(runtime).ID, |
| 805 | 805 |
Cmd: []string{"id"},
|
| 806 | 806 |
|
| ... | ... |
@@ -823,7 +823,7 @@ func TestUser(t *testing.T) {
|
| 823 | 823 |
} |
| 824 | 824 |
|
| 825 | 825 |
// Set a different user by username |
| 826 |
- container, _, err = runtime.Create(&docker.Config{
|
|
| 826 |
+ container, _, err = runtime.Create(&runconfig.Config{
|
|
| 827 | 827 |
Image: GetTestImage(runtime).ID, |
| 828 | 828 |
Cmd: []string{"id"},
|
| 829 | 829 |
|
| ... | ... |
@@ -844,7 +844,7 @@ func TestUser(t *testing.T) {
|
| 844 | 844 |
} |
| 845 | 845 |
|
| 846 | 846 |
// Test an wrong username |
| 847 |
- container, _, err = runtime.Create(&docker.Config{
|
|
| 847 |
+ container, _, err = runtime.Create(&runconfig.Config{
|
|
| 848 | 848 |
Image: GetTestImage(runtime).ID, |
| 849 | 849 |
Cmd: []string{"id"},
|
| 850 | 850 |
|
| ... | ... |
@@ -866,7 +866,7 @@ func TestMultipleContainers(t *testing.T) {
|
| 866 | 866 |
runtime := mkRuntime(t) |
| 867 | 867 |
defer nuke(runtime) |
| 868 | 868 |
|
| 869 |
- container1, _, err := runtime.Create(&docker.Config{
|
|
| 869 |
+ container1, _, err := runtime.Create(&runconfig.Config{
|
|
| 870 | 870 |
Image: GetTestImage(runtime).ID, |
| 871 | 871 |
Cmd: []string{"sleep", "2"},
|
| 872 | 872 |
}, |
| ... | ... |
@@ -877,7 +877,7 @@ func TestMultipleContainers(t *testing.T) {
|
| 877 | 877 |
} |
| 878 | 878 |
defer runtime.Destroy(container1) |
| 879 | 879 |
|
| 880 |
- container2, _, err := runtime.Create(&docker.Config{
|
|
| 880 |
+ container2, _, err := runtime.Create(&runconfig.Config{
|
|
| 881 | 881 |
Image: GetTestImage(runtime).ID, |
| 882 | 882 |
Cmd: []string{"sleep", "2"},
|
| 883 | 883 |
}, |
| ... | ... |
@@ -921,7 +921,7 @@ func TestMultipleContainers(t *testing.T) {
|
| 921 | 921 |
func TestStdin(t *testing.T) {
|
| 922 | 922 |
runtime := mkRuntime(t) |
| 923 | 923 |
defer nuke(runtime) |
| 924 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 924 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 925 | 925 |
Image: GetTestImage(runtime).ID, |
| 926 | 926 |
Cmd: []string{"cat"},
|
| 927 | 927 |
|
| ... | ... |
@@ -966,7 +966,7 @@ func TestStdin(t *testing.T) {
|
| 966 | 966 |
func TestTty(t *testing.T) {
|
| 967 | 967 |
runtime := mkRuntime(t) |
| 968 | 968 |
defer nuke(runtime) |
| 969 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 969 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 970 | 970 |
Image: GetTestImage(runtime).ID, |
| 971 | 971 |
Cmd: []string{"cat"},
|
| 972 | 972 |
|
| ... | ... |
@@ -1013,7 +1013,7 @@ func TestEnv(t *testing.T) {
|
| 1013 | 1013 |
os.Setenv("TRICKY", "tri\ncky\n")
|
| 1014 | 1014 |
runtime := mkRuntime(t) |
| 1015 | 1015 |
defer nuke(runtime) |
| 1016 |
- config, _, _, err := docker.ParseRun([]string{"-e=FALSE=true", "-e=TRUE", "-e=TRICKY", GetTestImage(runtime).ID, "env"}, nil)
|
|
| 1016 |
+ config, _, _, err := runconfig.Parse([]string{"-e=FALSE=true", "-e=TRUE", "-e=TRICKY", GetTestImage(runtime).ID, "env"}, nil)
|
|
| 1017 | 1017 |
if err != nil {
|
| 1018 | 1018 |
t.Fatal(err) |
| 1019 | 1019 |
} |
| ... | ... |
@@ -1067,7 +1067,7 @@ func TestEntrypoint(t *testing.T) {
|
| 1067 | 1067 |
runtime := mkRuntime(t) |
| 1068 | 1068 |
defer nuke(runtime) |
| 1069 | 1069 |
container, _, err := runtime.Create( |
| 1070 |
- &docker.Config{
|
|
| 1070 |
+ &runconfig.Config{
|
|
| 1071 | 1071 |
Image: GetTestImage(runtime).ID, |
| 1072 | 1072 |
Entrypoint: []string{"/bin/echo"},
|
| 1073 | 1073 |
Cmd: []string{"-n", "foobar"},
|
| ... | ... |
@@ -1091,7 +1091,7 @@ func TestEntrypointNoCmd(t *testing.T) {
|
| 1091 | 1091 |
runtime := mkRuntime(t) |
| 1092 | 1092 |
defer nuke(runtime) |
| 1093 | 1093 |
container, _, err := runtime.Create( |
| 1094 |
- &docker.Config{
|
|
| 1094 |
+ &runconfig.Config{
|
|
| 1095 | 1095 |
Image: GetTestImage(runtime).ID, |
| 1096 | 1096 |
Entrypoint: []string{"/bin/echo", "foobar"},
|
| 1097 | 1097 |
}, |
| ... | ... |
@@ -1114,7 +1114,7 @@ func BenchmarkRunSequencial(b *testing.B) {
|
| 1114 | 1114 |
runtime := mkRuntime(b) |
| 1115 | 1115 |
defer nuke(runtime) |
| 1116 | 1116 |
for i := 0; i < b.N; i++ {
|
| 1117 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 1117 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 1118 | 1118 |
Image: GetTestImage(runtime).ID, |
| 1119 | 1119 |
Cmd: []string{"echo", "-n", "foo"},
|
| 1120 | 1120 |
}, |
| ... | ... |
@@ -1147,7 +1147,7 @@ func BenchmarkRunParallel(b *testing.B) {
|
| 1147 | 1147 |
complete := make(chan error) |
| 1148 | 1148 |
tasks = append(tasks, complete) |
| 1149 | 1149 |
go func(i int, complete chan error) {
|
| 1150 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 1150 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 1151 | 1151 |
Image: GetTestImage(runtime).ID, |
| 1152 | 1152 |
Cmd: []string{"echo", "-n", "foo"},
|
| 1153 | 1153 |
}, |
| ... | ... |
@@ -1301,7 +1301,7 @@ func TestFromVolumesInReadonlyMode(t *testing.T) {
|
| 1301 | 1301 |
runtime := mkRuntime(t) |
| 1302 | 1302 |
defer nuke(runtime) |
| 1303 | 1303 |
container, _, err := runtime.Create( |
| 1304 |
- &docker.Config{
|
|
| 1304 |
+ &runconfig.Config{
|
|
| 1305 | 1305 |
Image: GetTestImage(runtime).ID, |
| 1306 | 1306 |
Cmd: []string{"/bin/echo", "-n", "foobar"},
|
| 1307 | 1307 |
Volumes: map[string]struct{}{"/test": {}},
|
| ... | ... |
@@ -1321,7 +1321,7 @@ func TestFromVolumesInReadonlyMode(t *testing.T) {
|
| 1321 | 1321 |
} |
| 1322 | 1322 |
|
| 1323 | 1323 |
container2, _, err := runtime.Create( |
| 1324 |
- &docker.Config{
|
|
| 1324 |
+ &runconfig.Config{
|
|
| 1325 | 1325 |
Image: GetTestImage(runtime).ID, |
| 1326 | 1326 |
Cmd: []string{"/bin/echo", "-n", "foobar"},
|
| 1327 | 1327 |
VolumesFrom: container.ID + ":ro", |
| ... | ... |
@@ -1362,7 +1362,7 @@ func TestVolumesFromReadonlyMount(t *testing.T) {
|
| 1362 | 1362 |
runtime := mkRuntime(t) |
| 1363 | 1363 |
defer nuke(runtime) |
| 1364 | 1364 |
container, _, err := runtime.Create( |
| 1365 |
- &docker.Config{
|
|
| 1365 |
+ &runconfig.Config{
|
|
| 1366 | 1366 |
Image: GetTestImage(runtime).ID, |
| 1367 | 1367 |
Cmd: []string{"/bin/echo", "-n", "foobar"},
|
| 1368 | 1368 |
Volumes: map[string]struct{}{"/test": {}},
|
| ... | ... |
@@ -1382,7 +1382,7 @@ func TestVolumesFromReadonlyMount(t *testing.T) {
|
| 1382 | 1382 |
} |
| 1383 | 1383 |
|
| 1384 | 1384 |
container2, _, err := runtime.Create( |
| 1385 |
- &docker.Config{
|
|
| 1385 |
+ &runconfig.Config{
|
|
| 1386 | 1386 |
Image: GetTestImage(runtime).ID, |
| 1387 | 1387 |
Cmd: []string{"/bin/echo", "-n", "foobar"},
|
| 1388 | 1388 |
VolumesFrom: container.ID, |
| ... | ... |
@@ -1418,7 +1418,7 @@ func TestRestartWithVolumes(t *testing.T) {
|
| 1418 | 1418 |
runtime := mkRuntime(t) |
| 1419 | 1419 |
defer nuke(runtime) |
| 1420 | 1420 |
|
| 1421 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 1421 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 1422 | 1422 |
Image: GetTestImage(runtime).ID, |
| 1423 | 1423 |
Cmd: []string{"echo", "-n", "foobar"},
|
| 1424 | 1424 |
Volumes: map[string]struct{}{"/test": {}},
|
| ... | ... |
@@ -1462,7 +1462,7 @@ func TestVolumesFromWithVolumes(t *testing.T) {
|
| 1462 | 1462 |
runtime := mkRuntime(t) |
| 1463 | 1463 |
defer nuke(runtime) |
| 1464 | 1464 |
|
| 1465 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 1465 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 1466 | 1466 |
Image: GetTestImage(runtime).ID, |
| 1467 | 1467 |
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
|
| 1468 | 1468 |
Volumes: map[string]struct{}{"/test": {}},
|
| ... | ... |
@@ -1491,7 +1491,7 @@ func TestVolumesFromWithVolumes(t *testing.T) {
|
| 1491 | 1491 |
} |
| 1492 | 1492 |
|
| 1493 | 1493 |
container2, _, err := runtime.Create( |
| 1494 |
- &docker.Config{
|
|
| 1494 |
+ &runconfig.Config{
|
|
| 1495 | 1495 |
Image: GetTestImage(runtime).ID, |
| 1496 | 1496 |
Cmd: []string{"cat", "/test/foo"},
|
| 1497 | 1497 |
VolumesFrom: container.ID, |
| ... | ... |
@@ -1529,7 +1529,7 @@ func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
|
| 1529 | 1529 |
runtime := mkRuntimeFromEngine(eng, t) |
| 1530 | 1530 |
defer nuke(runtime) |
| 1531 | 1531 |
|
| 1532 |
- config, hc, _, err := docker.ParseRun([]string{"-n=false", GetTestImage(runtime).ID, "ip", "addr", "show"}, nil)
|
|
| 1532 |
+ config, hc, _, err := runconfig.Parse([]string{"-n=false", GetTestImage(runtime).ID, "ip", "addr", "show"}, nil)
|
|
| 1533 | 1533 |
if err != nil {
|
| 1534 | 1534 |
t.Fatal(err) |
| 1535 | 1535 |
} |
| ... | ... |
@@ -1617,7 +1617,7 @@ func TestMultipleVolumesFrom(t *testing.T) {
|
| 1617 | 1617 |
runtime := mkRuntime(t) |
| 1618 | 1618 |
defer nuke(runtime) |
| 1619 | 1619 |
|
| 1620 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 1620 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 1621 | 1621 |
Image: GetTestImage(runtime).ID, |
| 1622 | 1622 |
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
|
| 1623 | 1623 |
Volumes: map[string]struct{}{"/test": {}},
|
| ... | ... |
@@ -1646,7 +1646,7 @@ func TestMultipleVolumesFrom(t *testing.T) {
|
| 1646 | 1646 |
} |
| 1647 | 1647 |
|
| 1648 | 1648 |
container2, _, err := runtime.Create( |
| 1649 |
- &docker.Config{
|
|
| 1649 |
+ &runconfig.Config{
|
|
| 1650 | 1650 |
Image: GetTestImage(runtime).ID, |
| 1651 | 1651 |
Cmd: []string{"sh", "-c", "echo -n bar > /other/foo"},
|
| 1652 | 1652 |
Volumes: map[string]struct{}{"/other": {}},
|
| ... | ... |
@@ -1668,7 +1668,7 @@ func TestMultipleVolumesFrom(t *testing.T) {
|
| 1668 | 1668 |
} |
| 1669 | 1669 |
|
| 1670 | 1670 |
container3, _, err := runtime.Create( |
| 1671 |
- &docker.Config{
|
|
| 1671 |
+ &runconfig.Config{
|
|
| 1672 | 1672 |
Image: GetTestImage(runtime).ID, |
| 1673 | 1673 |
Cmd: []string{"/bin/echo", "-n", "foobar"},
|
| 1674 | 1674 |
VolumesFrom: strings.Join([]string{container.ID, container2.ID}, ","),
|
| ... | ... |
@@ -1696,7 +1696,7 @@ func TestRestartGhost(t *testing.T) {
|
| 1696 | 1696 |
defer nuke(runtime) |
| 1697 | 1697 |
|
| 1698 | 1698 |
container, _, err := runtime.Create( |
| 1699 |
- &docker.Config{
|
|
| 1699 |
+ &runconfig.Config{
|
|
| 1700 | 1700 |
Image: GetTestImage(runtime).ID, |
| 1701 | 1701 |
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
|
| 1702 | 1702 |
Volumes: map[string]struct{}{"/test": {}},
|
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"github.com/dotcloud/docker" |
| 7 | 7 |
"github.com/dotcloud/docker/engine" |
| 8 | 8 |
"github.com/dotcloud/docker/nat" |
| 9 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 9 | 10 |
"github.com/dotcloud/docker/sysinit" |
| 10 | 11 |
"github.com/dotcloud/docker/utils" |
| 11 | 12 |
"io" |
| ... | ... |
@@ -200,7 +201,7 @@ func TestRuntimeCreate(t *testing.T) {
|
| 200 | 200 |
t.Errorf("Expected 0 containers, %v found", len(runtime.List()))
|
| 201 | 201 |
} |
| 202 | 202 |
|
| 203 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 203 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 204 | 204 |
Image: GetTestImage(runtime).ID, |
| 205 | 205 |
Cmd: []string{"ls", "-al"},
|
| 206 | 206 |
}, |
| ... | ... |
@@ -243,23 +244,23 @@ func TestRuntimeCreate(t *testing.T) {
|
| 243 | 243 |
|
| 244 | 244 |
// Test that conflict error displays correct details |
| 245 | 245 |
testContainer, _, _ := runtime.Create( |
| 246 |
- &docker.Config{
|
|
| 246 |
+ &runconfig.Config{
|
|
| 247 | 247 |
Image: GetTestImage(runtime).ID, |
| 248 | 248 |
Cmd: []string{"ls", "-al"},
|
| 249 | 249 |
}, |
| 250 | 250 |
"conflictname", |
| 251 | 251 |
) |
| 252 |
- if _, _, err := runtime.Create(&docker.Config{Image: GetTestImage(runtime).ID, Cmd: []string{"ls", "-al"}}, testContainer.Name); err == nil || !strings.Contains(err.Error(), utils.TruncateID(testContainer.ID)) {
|
|
| 252 |
+ if _, _, err := runtime.Create(&runconfig.Config{Image: GetTestImage(runtime).ID, Cmd: []string{"ls", "-al"}}, testContainer.Name); err == nil || !strings.Contains(err.Error(), utils.TruncateID(testContainer.ID)) {
|
|
| 253 | 253 |
t.Fatalf("Name conflict error doesn't include the correct short id. Message was: %s", err.Error())
|
| 254 | 254 |
} |
| 255 | 255 |
|
| 256 | 256 |
// Make sure create with bad parameters returns an error |
| 257 |
- if _, _, err = runtime.Create(&docker.Config{Image: GetTestImage(runtime).ID}, ""); err == nil {
|
|
| 257 |
+ if _, _, err = runtime.Create(&runconfig.Config{Image: GetTestImage(runtime).ID}, ""); err == nil {
|
|
| 258 | 258 |
t.Fatal("Builder.Create should throw an error when Cmd is missing")
|
| 259 | 259 |
} |
| 260 | 260 |
|
| 261 | 261 |
if _, _, err := runtime.Create( |
| 262 |
- &docker.Config{
|
|
| 262 |
+ &runconfig.Config{
|
|
| 263 | 263 |
Image: GetTestImage(runtime).ID, |
| 264 | 264 |
Cmd: []string{},
|
| 265 | 265 |
}, |
| ... | ... |
@@ -268,7 +269,7 @@ func TestRuntimeCreate(t *testing.T) {
|
| 268 | 268 |
t.Fatal("Builder.Create should throw an error when Cmd is empty")
|
| 269 | 269 |
} |
| 270 | 270 |
|
| 271 |
- config := &docker.Config{
|
|
| 271 |
+ config := &runconfig.Config{
|
|
| 272 | 272 |
Image: GetTestImage(runtime).ID, |
| 273 | 273 |
Cmd: []string{"/bin/ls"},
|
| 274 | 274 |
PortSpecs: []string{"80"},
|
| ... | ... |
@@ -281,7 +282,7 @@ func TestRuntimeCreate(t *testing.T) {
|
| 281 | 281 |
} |
| 282 | 282 |
|
| 283 | 283 |
// test expose 80:8000 |
| 284 |
- container, warnings, err := runtime.Create(&docker.Config{
|
|
| 284 |
+ container, warnings, err := runtime.Create(&runconfig.Config{
|
|
| 285 | 285 |
Image: GetTestImage(runtime).ID, |
| 286 | 286 |
Cmd: []string{"ls", "-al"},
|
| 287 | 287 |
PortSpecs: []string{"80:8000"},
|
| ... | ... |
@@ -300,7 +301,7 @@ func TestDestroy(t *testing.T) {
|
| 300 | 300 |
runtime := mkRuntime(t) |
| 301 | 301 |
defer nuke(runtime) |
| 302 | 302 |
|
| 303 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 303 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 304 | 304 |
Image: GetTestImage(runtime).ID, |
| 305 | 305 |
Cmd: []string{"ls", "-al"},
|
| 306 | 306 |
}, "") |
| ... | ... |
@@ -712,7 +713,7 @@ func TestDefaultContainerName(t *testing.T) {
|
| 712 | 712 |
runtime := mkRuntimeFromEngine(eng, t) |
| 713 | 713 |
defer nuke(runtime) |
| 714 | 714 |
|
| 715 |
- config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
|
| 715 |
+ config, _, _, err := runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
|
|
| 716 | 716 |
if err != nil {
|
| 717 | 717 |
t.Fatal(err) |
| 718 | 718 |
} |
| ... | ... |
@@ -736,7 +737,7 @@ func TestRandomContainerName(t *testing.T) {
|
| 736 | 736 |
runtime := mkRuntimeFromEngine(eng, t) |
| 737 | 737 |
defer nuke(runtime) |
| 738 | 738 |
|
| 739 |
- config, _, _, err := docker.ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
|
|
| 739 |
+ config, _, _, err := runconfig.Parse([]string{GetTestImage(runtime).ID, "echo test"}, nil)
|
|
| 740 | 740 |
if err != nil {
|
| 741 | 741 |
t.Fatal(err) |
| 742 | 742 |
} |
| ... | ... |
@@ -767,7 +768,7 @@ func TestContainerNameValidation(t *testing.T) {
|
| 767 | 767 |
{"abc-123_AAA.1", true},
|
| 768 | 768 |
{"\000asdf", false},
|
| 769 | 769 |
} {
|
| 770 |
- config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
|
| 770 |
+ config, _, _, err := runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
|
|
| 771 | 771 |
if err != nil {
|
| 772 | 772 |
if !test.Valid {
|
| 773 | 773 |
continue |
| ... | ... |
@@ -808,7 +809,7 @@ func TestLinkChildContainer(t *testing.T) {
|
| 808 | 808 |
runtime := mkRuntimeFromEngine(eng, t) |
| 809 | 809 |
defer nuke(runtime) |
| 810 | 810 |
|
| 811 |
- config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
|
| 811 |
+ config, _, _, err := runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
|
|
| 812 | 812 |
if err != nil {
|
| 813 | 813 |
t.Fatal(err) |
| 814 | 814 |
} |
| ... | ... |
@@ -824,7 +825,7 @@ func TestLinkChildContainer(t *testing.T) {
|
| 824 | 824 |
t.Fatalf("Expect webapp id to match container id: %s != %s", webapp.ID, container.ID)
|
| 825 | 825 |
} |
| 826 | 826 |
|
| 827 |
- config, _, _, err = docker.ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
|
|
| 827 |
+ config, _, _, err = runconfig.Parse([]string{GetTestImage(runtime).ID, "echo test"}, nil)
|
|
| 828 | 828 |
if err != nil {
|
| 829 | 829 |
t.Fatal(err) |
| 830 | 830 |
} |
| ... | ... |
@@ -850,7 +851,7 @@ func TestGetAllChildren(t *testing.T) {
|
| 850 | 850 |
runtime := mkRuntimeFromEngine(eng, t) |
| 851 | 851 |
defer nuke(runtime) |
| 852 | 852 |
|
| 853 |
- config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
|
| 853 |
+ config, _, _, err := runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
|
|
| 854 | 854 |
if err != nil {
|
| 855 | 855 |
t.Fatal(err) |
| 856 | 856 |
} |
| ... | ... |
@@ -866,7 +867,7 @@ func TestGetAllChildren(t *testing.T) {
|
| 866 | 866 |
t.Fatalf("Expect webapp id to match container id: %s != %s", webapp.ID, container.ID)
|
| 867 | 867 |
} |
| 868 | 868 |
|
| 869 |
- config, _, _, err = docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
|
| 869 |
+ config, _, _, err = runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
|
|
| 870 | 870 |
if err != nil {
|
| 871 | 871 |
t.Fatal(err) |
| 872 | 872 |
} |
| ... | ... |
@@ -903,7 +904,7 @@ func TestDestroyWithInitLayer(t *testing.T) {
|
| 903 | 903 |
runtime := mkRuntime(t) |
| 904 | 904 |
defer nuke(runtime) |
| 905 | 905 |
|
| 906 |
- container, _, err := runtime.Create(&docker.Config{
|
|
| 906 |
+ container, _, err := runtime.Create(&runconfig.Config{
|
|
| 907 | 907 |
Image: GetTestImage(runtime).ID, |
| 908 | 908 |
Cmd: []string{"ls", "-al"},
|
| 909 | 909 |
}, "") |
| ... | ... |
@@ -3,6 +3,7 @@ package docker |
| 3 | 3 |
import ( |
| 4 | 4 |
"github.com/dotcloud/docker" |
| 5 | 5 |
"github.com/dotcloud/docker/engine" |
| 6 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 6 | 7 |
"strings" |
| 7 | 8 |
"testing" |
| 8 | 9 |
"time" |
| ... | ... |
@@ -71,7 +72,7 @@ func TestCreateRm(t *testing.T) {
|
| 71 | 71 |
eng := NewTestEngine(t) |
| 72 | 72 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 73 | 73 |
|
| 74 |
- config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
|
| 74 |
+ config, _, _, err := runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
|
|
| 75 | 75 |
if err != nil {
|
| 76 | 76 |
t.Fatal(err) |
| 77 | 77 |
} |
| ... | ... |
@@ -118,7 +119,7 @@ func TestCreateNumberHostname(t *testing.T) {
|
| 118 | 118 |
eng := NewTestEngine(t) |
| 119 | 119 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 120 | 120 |
|
| 121 |
- config, _, _, err := docker.ParseRun([]string{"-h", "web.0", unitTestImageID, "echo test"}, nil)
|
|
| 121 |
+ config, _, _, err := runconfig.Parse([]string{"-h", "web.0", unitTestImageID, "echo test"}, nil)
|
|
| 122 | 122 |
if err != nil {
|
| 123 | 123 |
t.Fatal(err) |
| 124 | 124 |
} |
| ... | ... |
@@ -130,7 +131,7 @@ func TestCreateNumberUsername(t *testing.T) {
|
| 130 | 130 |
eng := NewTestEngine(t) |
| 131 | 131 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 132 | 132 |
|
| 133 |
- config, _, _, err := docker.ParseRun([]string{"-u", "1002", unitTestImageID, "echo test"}, nil)
|
|
| 133 |
+ config, _, _, err := runconfig.Parse([]string{"-u", "1002", unitTestImageID, "echo test"}, nil)
|
|
| 134 | 134 |
if err != nil {
|
| 135 | 135 |
t.Fatal(err) |
| 136 | 136 |
} |
| ... | ... |
@@ -142,7 +143,7 @@ func TestCreateRmVolumes(t *testing.T) {
|
| 142 | 142 |
eng := NewTestEngine(t) |
| 143 | 143 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 144 | 144 |
|
| 145 |
- config, hostConfig, _, err := docker.ParseRun([]string{"-v", "/srv", unitTestImageID, "echo", "test"}, nil)
|
|
| 145 |
+ config, hostConfig, _, err := runconfig.Parse([]string{"-v", "/srv", unitTestImageID, "echo", "test"}, nil)
|
|
| 146 | 146 |
if err != nil {
|
| 147 | 147 |
t.Fatal(err) |
| 148 | 148 |
} |
| ... | ... |
@@ -202,7 +203,7 @@ func TestCommit(t *testing.T) {
|
| 202 | 202 |
eng := NewTestEngine(t) |
| 203 | 203 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 204 | 204 |
|
| 205 |
- config, _, _, err := docker.ParseRun([]string{unitTestImageID, "/bin/cat"}, nil)
|
|
| 205 |
+ config, _, _, err := runconfig.Parse([]string{unitTestImageID, "/bin/cat"}, nil)
|
|
| 206 | 206 |
if err != nil {
|
| 207 | 207 |
t.Fatal(err) |
| 208 | 208 |
} |
| ... | ... |
@@ -224,7 +225,7 @@ func TestRestartKillWait(t *testing.T) {
|
| 224 | 224 |
runtime := mkRuntimeFromEngine(eng, t) |
| 225 | 225 |
defer runtime.Nuke() |
| 226 | 226 |
|
| 227 |
- config, hostConfig, _, err := docker.ParseRun([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
|
|
| 227 |
+ config, hostConfig, _, err := runconfig.Parse([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
|
|
| 228 | 228 |
if err != nil {
|
| 229 | 229 |
t.Fatal(err) |
| 230 | 230 |
} |
| ... | ... |
@@ -302,7 +303,7 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
| 302 | 302 |
srv := mkServerFromEngine(eng, t) |
| 303 | 303 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 304 | 304 |
|
| 305 |
- config, hostConfig, _, err := docker.ParseRun([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
|
|
| 305 |
+ config, hostConfig, _, err := runconfig.Parse([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
|
|
| 306 | 306 |
if err != nil {
|
| 307 | 307 |
t.Fatal(err) |
| 308 | 308 |
} |
| ... | ... |
@@ -401,7 +402,7 @@ func TestRmi(t *testing.T) {
|
| 401 | 401 |
|
| 402 | 402 |
initialImages := getAllImages(eng, t) |
| 403 | 403 |
|
| 404 |
- config, hostConfig, _, err := docker.ParseRun([]string{unitTestImageID, "echo", "test"}, nil)
|
|
| 404 |
+ config, hostConfig, _, err := runconfig.Parse([]string{unitTestImageID, "echo", "test"}, nil)
|
|
| 405 | 405 |
if err != nil {
|
| 406 | 406 |
t.Fatal(err) |
| 407 | 407 |
} |
| ... | ... |
@@ -548,7 +549,7 @@ func TestListContainers(t *testing.T) {
|
| 548 | 548 |
srv := mkServerFromEngine(eng, t) |
| 549 | 549 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 550 | 550 |
|
| 551 |
- config := docker.Config{
|
|
| 551 |
+ config := runconfig.Config{
|
|
| 552 | 552 |
Image: unitTestImageID, |
| 553 | 553 |
Cmd: []string{"/bin/sh", "-c", "cat"},
|
| 554 | 554 |
OpenStdin: true, |
| ... | ... |
@@ -671,7 +672,7 @@ func TestDeleteTagWithExistingContainers(t *testing.T) {
|
| 671 | 671 |
} |
| 672 | 672 |
|
| 673 | 673 |
// Create a container from the image |
| 674 |
- config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
|
| 674 |
+ config, _, _, err := runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
|
|
| 675 | 675 |
if err != nil {
|
| 676 | 676 |
t.Fatal(err) |
| 677 | 677 |
} |
| ... | ... |
@@ -16,6 +16,7 @@ import ( |
| 16 | 16 |
|
| 17 | 17 |
"github.com/dotcloud/docker" |
| 18 | 18 |
"github.com/dotcloud/docker/engine" |
| 19 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 19 | 20 |
"github.com/dotcloud/docker/utils" |
| 20 | 21 |
) |
| 21 | 22 |
|
| ... | ... |
@@ -48,7 +49,7 @@ func mkRuntime(f utils.Fataler) *docker.Runtime {
|
| 48 | 48 |
return r |
| 49 | 49 |
} |
| 50 | 50 |
|
| 51 |
-func createNamedTestContainer(eng *engine.Engine, config *docker.Config, f utils.Fataler, name string) (shortId string) {
|
|
| 51 |
+func createNamedTestContainer(eng *engine.Engine, config *runconfig.Config, f utils.Fataler, name string) (shortId string) {
|
|
| 52 | 52 |
job := eng.Job("create", name)
|
| 53 | 53 |
if err := job.ImportEnv(config); err != nil {
|
| 54 | 54 |
f.Fatal(err) |
| ... | ... |
@@ -60,7 +61,7 @@ func createNamedTestContainer(eng *engine.Engine, config *docker.Config, f utils |
| 60 | 60 |
return |
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 |
-func createTestContainer(eng *engine.Engine, config *docker.Config, f utils.Fataler) (shortId string) {
|
|
| 63 |
+func createTestContainer(eng *engine.Engine, config *runconfig.Config, f utils.Fataler) (shortId string) {
|
|
| 64 | 64 |
return createNamedTestContainer(eng, config, f, "") |
| 65 | 65 |
} |
| 66 | 66 |
|
| ... | ... |
@@ -252,8 +253,8 @@ func readFile(src string, t *testing.T) (content string) {
|
| 252 | 252 |
// dynamically replaced by the current test image. |
| 253 | 253 |
// The caller is responsible for destroying the container. |
| 254 | 254 |
// Call t.Fatal() at the first error. |
| 255 |
-func mkContainer(r *docker.Runtime, args []string, t *testing.T) (*docker.Container, *docker.HostConfig, error) {
|
|
| 256 |
- config, hc, _, err := docker.ParseRun(args, nil) |
|
| 255 |
+func mkContainer(r *docker.Runtime, args []string, t *testing.T) (*docker.Container, *runconfig.HostConfig, error) {
|
|
| 256 |
+ config, hc, _, err := runconfig.Parse(args, nil) |
|
| 257 | 257 |
defer func() {
|
| 258 | 258 |
if err != nil && t != nil {
|
| 259 | 259 |
t.Fatal(err) |
| ... | ... |
@@ -2,13 +2,14 @@ package docker |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"github.com/dotcloud/docker/nat" |
| 5 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 5 | 6 |
"strings" |
| 6 | 7 |
"testing" |
| 7 | 8 |
) |
| 8 | 9 |
|
| 9 | 10 |
func newMockLinkContainer(id string, ip string) *Container {
|
| 10 | 11 |
return &Container{
|
| 11 |
- Config: &Config{},
|
|
| 12 |
+ Config: &runconfig.Config{},
|
|
| 12 | 13 |
ID: id, |
| 13 | 14 |
NetworkSettings: &NetworkSettings{
|
| 14 | 15 |
IPAddress: ip, |
| 15 | 16 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,67 @@ |
| 0 |
+package runconfig |
|
| 1 |
+ |
|
| 2 |
+// Compare two Config struct. Do not compare the "Image" nor "Hostname" fields |
|
| 3 |
+// If OpenStdin is set, then it differs |
|
| 4 |
+func Compare(a, b *Config) bool {
|
|
| 5 |
+ if a == nil || b == nil || |
|
| 6 |
+ a.OpenStdin || b.OpenStdin {
|
|
| 7 |
+ return false |
|
| 8 |
+ } |
|
| 9 |
+ if a.AttachStdout != b.AttachStdout || |
|
| 10 |
+ a.AttachStderr != b.AttachStderr || |
|
| 11 |
+ a.User != b.User || |
|
| 12 |
+ a.Memory != b.Memory || |
|
| 13 |
+ a.MemorySwap != b.MemorySwap || |
|
| 14 |
+ a.CpuShares != b.CpuShares || |
|
| 15 |
+ a.OpenStdin != b.OpenStdin || |
|
| 16 |
+ a.Tty != b.Tty || |
|
| 17 |
+ a.VolumesFrom != b.VolumesFrom {
|
|
| 18 |
+ return false |
|
| 19 |
+ } |
|
| 20 |
+ if len(a.Cmd) != len(b.Cmd) || |
|
| 21 |
+ len(a.Dns) != len(b.Dns) || |
|
| 22 |
+ len(a.Env) != len(b.Env) || |
|
| 23 |
+ len(a.PortSpecs) != len(b.PortSpecs) || |
|
| 24 |
+ len(a.ExposedPorts) != len(b.ExposedPorts) || |
|
| 25 |
+ len(a.Entrypoint) != len(b.Entrypoint) || |
|
| 26 |
+ len(a.Volumes) != len(b.Volumes) {
|
|
| 27 |
+ return false |
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ for i := 0; i < len(a.Cmd); i++ {
|
|
| 31 |
+ if a.Cmd[i] != b.Cmd[i] {
|
|
| 32 |
+ return false |
|
| 33 |
+ } |
|
| 34 |
+ } |
|
| 35 |
+ for i := 0; i < len(a.Dns); i++ {
|
|
| 36 |
+ if a.Dns[i] != b.Dns[i] {
|
|
| 37 |
+ return false |
|
| 38 |
+ } |
|
| 39 |
+ } |
|
| 40 |
+ for i := 0; i < len(a.Env); i++ {
|
|
| 41 |
+ if a.Env[i] != b.Env[i] {
|
|
| 42 |
+ return false |
|
| 43 |
+ } |
|
| 44 |
+ } |
|
| 45 |
+ for i := 0; i < len(a.PortSpecs); i++ {
|
|
| 46 |
+ if a.PortSpecs[i] != b.PortSpecs[i] {
|
|
| 47 |
+ return false |
|
| 48 |
+ } |
|
| 49 |
+ } |
|
| 50 |
+ for k := range a.ExposedPorts {
|
|
| 51 |
+ if _, exists := b.ExposedPorts[k]; !exists {
|
|
| 52 |
+ return false |
|
| 53 |
+ } |
|
| 54 |
+ } |
|
| 55 |
+ for i := 0; i < len(a.Entrypoint); i++ {
|
|
| 56 |
+ if a.Entrypoint[i] != b.Entrypoint[i] {
|
|
| 57 |
+ return false |
|
| 58 |
+ } |
|
| 59 |
+ } |
|
| 60 |
+ for key := range a.Volumes {
|
|
| 61 |
+ if _, exists := b.Volumes[key]; !exists {
|
|
| 62 |
+ return false |
|
| 63 |
+ } |
|
| 64 |
+ } |
|
| 65 |
+ return true |
|
| 66 |
+} |
| 0 | 67 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,76 @@ |
| 0 |
+package runconfig |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/dotcloud/docker/engine" |
|
| 4 |
+ "github.com/dotcloud/docker/nat" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+// Note: the Config structure should hold only portable information about the container. |
|
| 8 |
+// Here, "portable" means "independent from the host we are running on". |
|
| 9 |
+// Non-portable information *should* appear in HostConfig. |
|
| 10 |
+type Config struct {
|
|
| 11 |
+ Hostname string |
|
| 12 |
+ Domainname string |
|
| 13 |
+ User string |
|
| 14 |
+ Memory int64 // Memory limit (in bytes) |
|
| 15 |
+ MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap |
|
| 16 |
+ CpuShares int64 // CPU shares (relative weight vs. other containers) |
|
| 17 |
+ AttachStdin bool |
|
| 18 |
+ AttachStdout bool |
|
| 19 |
+ AttachStderr bool |
|
| 20 |
+ PortSpecs []string // Deprecated - Can be in the format of 8080/tcp |
|
| 21 |
+ ExposedPorts map[nat.Port]struct{}
|
|
| 22 |
+ Tty bool // Attach standard streams to a tty, including stdin if it is not closed. |
|
| 23 |
+ OpenStdin bool // Open stdin |
|
| 24 |
+ StdinOnce bool // If true, close stdin after the 1 attached client disconnects. |
|
| 25 |
+ Env []string |
|
| 26 |
+ Cmd []string |
|
| 27 |
+ Dns []string |
|
| 28 |
+ Image string // Name of the image as it was passed by the operator (eg. could be symbolic) |
|
| 29 |
+ Volumes map[string]struct{}
|
|
| 30 |
+ VolumesFrom string |
|
| 31 |
+ WorkingDir string |
|
| 32 |
+ Entrypoint []string |
|
| 33 |
+ NetworkDisabled bool |
|
| 34 |
+ OnBuild []string |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+func ContainerConfigFromJob(job *engine.Job) *Config {
|
|
| 38 |
+ config := &Config{
|
|
| 39 |
+ Hostname: job.Getenv("Hostname"),
|
|
| 40 |
+ Domainname: job.Getenv("Domainname"),
|
|
| 41 |
+ User: job.Getenv("User"),
|
|
| 42 |
+ Memory: job.GetenvInt64("Memory"),
|
|
| 43 |
+ MemorySwap: job.GetenvInt64("MemorySwap"),
|
|
| 44 |
+ CpuShares: job.GetenvInt64("CpuShares"),
|
|
| 45 |
+ AttachStdin: job.GetenvBool("AttachStdin"),
|
|
| 46 |
+ AttachStdout: job.GetenvBool("AttachStdout"),
|
|
| 47 |
+ AttachStderr: job.GetenvBool("AttachStderr"),
|
|
| 48 |
+ Tty: job.GetenvBool("Tty"),
|
|
| 49 |
+ OpenStdin: job.GetenvBool("OpenStdin"),
|
|
| 50 |
+ StdinOnce: job.GetenvBool("StdinOnce"),
|
|
| 51 |
+ Image: job.Getenv("Image"),
|
|
| 52 |
+ VolumesFrom: job.Getenv("VolumesFrom"),
|
|
| 53 |
+ WorkingDir: job.Getenv("WorkingDir"),
|
|
| 54 |
+ NetworkDisabled: job.GetenvBool("NetworkDisabled"),
|
|
| 55 |
+ } |
|
| 56 |
+ job.GetenvJson("ExposedPorts", &config.ExposedPorts)
|
|
| 57 |
+ job.GetenvJson("Volumes", &config.Volumes)
|
|
| 58 |
+ if PortSpecs := job.GetenvList("PortSpecs"); PortSpecs != nil {
|
|
| 59 |
+ config.PortSpecs = PortSpecs |
|
| 60 |
+ } |
|
| 61 |
+ if Env := job.GetenvList("Env"); Env != nil {
|
|
| 62 |
+ config.Env = Env |
|
| 63 |
+ } |
|
| 64 |
+ if Cmd := job.GetenvList("Cmd"); Cmd != nil {
|
|
| 65 |
+ config.Cmd = Cmd |
|
| 66 |
+ } |
|
| 67 |
+ if Dns := job.GetenvList("Dns"); Dns != nil {
|
|
| 68 |
+ config.Dns = Dns |
|
| 69 |
+ } |
|
| 70 |
+ if Entrypoint := job.GetenvList("Entrypoint"); Entrypoint != nil {
|
|
| 71 |
+ config.Entrypoint = Entrypoint |
|
| 72 |
+ } |
|
| 73 |
+ |
|
| 74 |
+ return config |
|
| 75 |
+} |
| 0 | 76 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,150 @@ |
| 0 |
+package runconfig |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/dotcloud/docker/nat" |
|
| 4 |
+ "testing" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+func TestCompare(t *testing.T) {
|
|
| 8 |
+ volumes1 := make(map[string]struct{})
|
|
| 9 |
+ volumes1["/test1"] = struct{}{}
|
|
| 10 |
+ config1 := Config{
|
|
| 11 |
+ Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 12 |
+ PortSpecs: []string{"1111:1111", "2222:2222"},
|
|
| 13 |
+ Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 14 |
+ VolumesFrom: "11111111", |
|
| 15 |
+ Volumes: volumes1, |
|
| 16 |
+ } |
|
| 17 |
+ config2 := Config{
|
|
| 18 |
+ Dns: []string{"0.0.0.0", "2.2.2.2"},
|
|
| 19 |
+ PortSpecs: []string{"1111:1111", "2222:2222"},
|
|
| 20 |
+ Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 21 |
+ VolumesFrom: "11111111", |
|
| 22 |
+ Volumes: volumes1, |
|
| 23 |
+ } |
|
| 24 |
+ config3 := Config{
|
|
| 25 |
+ Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 26 |
+ PortSpecs: []string{"0000:0000", "2222:2222"},
|
|
| 27 |
+ Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 28 |
+ VolumesFrom: "11111111", |
|
| 29 |
+ Volumes: volumes1, |
|
| 30 |
+ } |
|
| 31 |
+ config4 := Config{
|
|
| 32 |
+ Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 33 |
+ PortSpecs: []string{"0000:0000", "2222:2222"},
|
|
| 34 |
+ Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 35 |
+ VolumesFrom: "22222222", |
|
| 36 |
+ Volumes: volumes1, |
|
| 37 |
+ } |
|
| 38 |
+ volumes2 := make(map[string]struct{})
|
|
| 39 |
+ volumes2["/test2"] = struct{}{}
|
|
| 40 |
+ config5 := Config{
|
|
| 41 |
+ Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 42 |
+ PortSpecs: []string{"0000:0000", "2222:2222"},
|
|
| 43 |
+ Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 44 |
+ VolumesFrom: "11111111", |
|
| 45 |
+ Volumes: volumes2, |
|
| 46 |
+ } |
|
| 47 |
+ if Compare(&config1, &config2) {
|
|
| 48 |
+ t.Fatalf("Compare should return false, Dns are different")
|
|
| 49 |
+ } |
|
| 50 |
+ if Compare(&config1, &config3) {
|
|
| 51 |
+ t.Fatalf("Compare should return false, PortSpecs are different")
|
|
| 52 |
+ } |
|
| 53 |
+ if Compare(&config1, &config4) {
|
|
| 54 |
+ t.Fatalf("Compare should return false, VolumesFrom are different")
|
|
| 55 |
+ } |
|
| 56 |
+ if Compare(&config1, &config5) {
|
|
| 57 |
+ t.Fatalf("Compare should return false, Volumes are different")
|
|
| 58 |
+ } |
|
| 59 |
+ if !Compare(&config1, &config1) {
|
|
| 60 |
+ t.Fatalf("Compare should return true")
|
|
| 61 |
+ } |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+func TestMerge(t *testing.T) {
|
|
| 65 |
+ volumesImage := make(map[string]struct{})
|
|
| 66 |
+ volumesImage["/test1"] = struct{}{}
|
|
| 67 |
+ volumesImage["/test2"] = struct{}{}
|
|
| 68 |
+ configImage := &Config{
|
|
| 69 |
+ Dns: []string{"1.1.1.1", "2.2.2.2"},
|
|
| 70 |
+ PortSpecs: []string{"1111:1111", "2222:2222"},
|
|
| 71 |
+ Env: []string{"VAR1=1", "VAR2=2"},
|
|
| 72 |
+ VolumesFrom: "1111", |
|
| 73 |
+ Volumes: volumesImage, |
|
| 74 |
+ } |
|
| 75 |
+ |
|
| 76 |
+ volumesUser := make(map[string]struct{})
|
|
| 77 |
+ volumesUser["/test3"] = struct{}{}
|
|
| 78 |
+ configUser := &Config{
|
|
| 79 |
+ Dns: []string{"3.3.3.3"},
|
|
| 80 |
+ PortSpecs: []string{"3333:2222", "3333:3333"},
|
|
| 81 |
+ Env: []string{"VAR2=3", "VAR3=3"},
|
|
| 82 |
+ Volumes: volumesUser, |
|
| 83 |
+ } |
|
| 84 |
+ |
|
| 85 |
+ if err := Merge(configUser, configImage); err != nil {
|
|
| 86 |
+ t.Error(err) |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ if len(configUser.Dns) != 3 {
|
|
| 90 |
+ t.Fatalf("Expected 3 dns, 1.1.1.1, 2.2.2.2 and 3.3.3.3, found %d", len(configUser.Dns))
|
|
| 91 |
+ } |
|
| 92 |
+ for _, dns := range configUser.Dns {
|
|
| 93 |
+ if dns != "1.1.1.1" && dns != "2.2.2.2" && dns != "3.3.3.3" {
|
|
| 94 |
+ t.Fatalf("Expected 1.1.1.1 or 2.2.2.2 or 3.3.3.3, found %s", dns)
|
|
| 95 |
+ } |
|
| 96 |
+ } |
|
| 97 |
+ |
|
| 98 |
+ if len(configUser.ExposedPorts) != 3 {
|
|
| 99 |
+ t.Fatalf("Expected 3 ExposedPorts, 1111, 2222 and 3333, found %d", len(configUser.ExposedPorts))
|
|
| 100 |
+ } |
|
| 101 |
+ for portSpecs := range configUser.ExposedPorts {
|
|
| 102 |
+ if portSpecs.Port() != "1111" && portSpecs.Port() != "2222" && portSpecs.Port() != "3333" {
|
|
| 103 |
+ t.Fatalf("Expected 1111 or 2222 or 3333, found %s", portSpecs)
|
|
| 104 |
+ } |
|
| 105 |
+ } |
|
| 106 |
+ if len(configUser.Env) != 3 {
|
|
| 107 |
+ t.Fatalf("Expected 3 env var, VAR1=1, VAR2=3 and VAR3=3, found %d", len(configUser.Env))
|
|
| 108 |
+ } |
|
| 109 |
+ for _, env := range configUser.Env {
|
|
| 110 |
+ if env != "VAR1=1" && env != "VAR2=3" && env != "VAR3=3" {
|
|
| 111 |
+ t.Fatalf("Expected VAR1=1 or VAR2=3 or VAR3=3, found %s", env)
|
|
| 112 |
+ } |
|
| 113 |
+ } |
|
| 114 |
+ |
|
| 115 |
+ if len(configUser.Volumes) != 3 {
|
|
| 116 |
+ t.Fatalf("Expected 3 volumes, /test1, /test2 and /test3, found %d", len(configUser.Volumes))
|
|
| 117 |
+ } |
|
| 118 |
+ for v := range configUser.Volumes {
|
|
| 119 |
+ if v != "/test1" && v != "/test2" && v != "/test3" {
|
|
| 120 |
+ t.Fatalf("Expected /test1 or /test2 or /test3, found %s", v)
|
|
| 121 |
+ } |
|
| 122 |
+ } |
|
| 123 |
+ |
|
| 124 |
+ if configUser.VolumesFrom != "1111" {
|
|
| 125 |
+ t.Fatalf("Expected VolumesFrom to be 1111, found %s", configUser.VolumesFrom)
|
|
| 126 |
+ } |
|
| 127 |
+ |
|
| 128 |
+ ports, _, err := nat.ParsePortSpecs([]string{"0000"})
|
|
| 129 |
+ if err != nil {
|
|
| 130 |
+ t.Error(err) |
|
| 131 |
+ } |
|
| 132 |
+ configImage2 := &Config{
|
|
| 133 |
+ ExposedPorts: ports, |
|
| 134 |
+ } |
|
| 135 |
+ |
|
| 136 |
+ if err := Merge(configUser, configImage2); err != nil {
|
|
| 137 |
+ t.Error(err) |
|
| 138 |
+ } |
|
| 139 |
+ |
|
| 140 |
+ if len(configUser.ExposedPorts) != 4 {
|
|
| 141 |
+ t.Fatalf("Expected 4 ExposedPorts, 0000, 1111, 2222 and 3333, found %d", len(configUser.ExposedPorts))
|
|
| 142 |
+ } |
|
| 143 |
+ for portSpecs := range configUser.ExposedPorts {
|
|
| 144 |
+ if portSpecs.Port() != "0000" && portSpecs.Port() != "1111" && portSpecs.Port() != "2222" && portSpecs.Port() != "3333" {
|
|
| 145 |
+ t.Fatalf("Expected 0000 or 1111 or 2222 or 3333, found %s", portSpecs)
|
|
| 146 |
+ } |
|
| 147 |
+ } |
|
| 148 |
+ |
|
| 149 |
+} |
| 0 | 150 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,39 @@ |
| 0 |
+package runconfig |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/dotcloud/docker/engine" |
|
| 4 |
+ "github.com/dotcloud/docker/nat" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+type HostConfig struct {
|
|
| 8 |
+ Binds []string |
|
| 9 |
+ ContainerIDFile string |
|
| 10 |
+ LxcConf []KeyValuePair |
|
| 11 |
+ Privileged bool |
|
| 12 |
+ PortBindings nat.PortMap |
|
| 13 |
+ Links []string |
|
| 14 |
+ PublishAllPorts bool |
|
| 15 |
+} |
|
| 16 |
+ |
|
| 17 |
+type KeyValuePair struct {
|
|
| 18 |
+ Key string |
|
| 19 |
+ Value string |
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
|
|
| 23 |
+ hostConfig := &HostConfig{
|
|
| 24 |
+ ContainerIDFile: job.Getenv("ContainerIDFile"),
|
|
| 25 |
+ Privileged: job.GetenvBool("Privileged"),
|
|
| 26 |
+ PublishAllPorts: job.GetenvBool("PublishAllPorts"),
|
|
| 27 |
+ } |
|
| 28 |
+ job.GetenvJson("LxcConf", &hostConfig.LxcConf)
|
|
| 29 |
+ job.GetenvJson("PortBindings", &hostConfig.PortBindings)
|
|
| 30 |
+ if Binds := job.GetenvList("Binds"); Binds != nil {
|
|
| 31 |
+ hostConfig.Binds = Binds |
|
| 32 |
+ } |
|
| 33 |
+ if Links := job.GetenvList("Links"); Links != nil {
|
|
| 34 |
+ hostConfig.Links = Links |
|
| 35 |
+ } |
|
| 36 |
+ |
|
| 37 |
+ return hostConfig |
|
| 38 |
+} |
| 0 | 39 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,119 @@ |
| 0 |
+package runconfig |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/dotcloud/docker/nat" |
|
| 4 |
+ "github.com/dotcloud/docker/utils" |
|
| 5 |
+ "strings" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+func Merge(userConf, imageConf *Config) error {
|
|
| 9 |
+ if userConf.User == "" {
|
|
| 10 |
+ userConf.User = imageConf.User |
|
| 11 |
+ } |
|
| 12 |
+ if userConf.Memory == 0 {
|
|
| 13 |
+ userConf.Memory = imageConf.Memory |
|
| 14 |
+ } |
|
| 15 |
+ if userConf.MemorySwap == 0 {
|
|
| 16 |
+ userConf.MemorySwap = imageConf.MemorySwap |
|
| 17 |
+ } |
|
| 18 |
+ if userConf.CpuShares == 0 {
|
|
| 19 |
+ userConf.CpuShares = imageConf.CpuShares |
|
| 20 |
+ } |
|
| 21 |
+ if userConf.ExposedPorts == nil || len(userConf.ExposedPorts) == 0 {
|
|
| 22 |
+ userConf.ExposedPorts = imageConf.ExposedPorts |
|
| 23 |
+ } else if imageConf.ExposedPorts != nil {
|
|
| 24 |
+ if userConf.ExposedPorts == nil {
|
|
| 25 |
+ userConf.ExposedPorts = make(nat.PortSet) |
|
| 26 |
+ } |
|
| 27 |
+ for port := range imageConf.ExposedPorts {
|
|
| 28 |
+ if _, exists := userConf.ExposedPorts[port]; !exists {
|
|
| 29 |
+ userConf.ExposedPorts[port] = struct{}{}
|
|
| 30 |
+ } |
|
| 31 |
+ } |
|
| 32 |
+ } |
|
| 33 |
+ |
|
| 34 |
+ if userConf.PortSpecs != nil && len(userConf.PortSpecs) > 0 {
|
|
| 35 |
+ if userConf.ExposedPorts == nil {
|
|
| 36 |
+ userConf.ExposedPorts = make(nat.PortSet) |
|
| 37 |
+ } |
|
| 38 |
+ ports, _, err := nat.ParsePortSpecs(userConf.PortSpecs) |
|
| 39 |
+ if err != nil {
|
|
| 40 |
+ return err |
|
| 41 |
+ } |
|
| 42 |
+ for port := range ports {
|
|
| 43 |
+ if _, exists := userConf.ExposedPorts[port]; !exists {
|
|
| 44 |
+ userConf.ExposedPorts[port] = struct{}{}
|
|
| 45 |
+ } |
|
| 46 |
+ } |
|
| 47 |
+ userConf.PortSpecs = nil |
|
| 48 |
+ } |
|
| 49 |
+ if imageConf.PortSpecs != nil && len(imageConf.PortSpecs) > 0 {
|
|
| 50 |
+ // FIXME: I think we can safely remove this. Leaving it for now for the sake of reverse-compat paranoia. |
|
| 51 |
+ utils.Debugf("Migrating image port specs to containter: %s", strings.Join(imageConf.PortSpecs, ", "))
|
|
| 52 |
+ if userConf.ExposedPorts == nil {
|
|
| 53 |
+ userConf.ExposedPorts = make(nat.PortSet) |
|
| 54 |
+ } |
|
| 55 |
+ |
|
| 56 |
+ ports, _, err := nat.ParsePortSpecs(imageConf.PortSpecs) |
|
| 57 |
+ if err != nil {
|
|
| 58 |
+ return err |
|
| 59 |
+ } |
|
| 60 |
+ for port := range ports {
|
|
| 61 |
+ if _, exists := userConf.ExposedPorts[port]; !exists {
|
|
| 62 |
+ userConf.ExposedPorts[port] = struct{}{}
|
|
| 63 |
+ } |
|
| 64 |
+ } |
|
| 65 |
+ } |
|
| 66 |
+ if !userConf.Tty {
|
|
| 67 |
+ userConf.Tty = imageConf.Tty |
|
| 68 |
+ } |
|
| 69 |
+ if !userConf.OpenStdin {
|
|
| 70 |
+ userConf.OpenStdin = imageConf.OpenStdin |
|
| 71 |
+ } |
|
| 72 |
+ if !userConf.StdinOnce {
|
|
| 73 |
+ userConf.StdinOnce = imageConf.StdinOnce |
|
| 74 |
+ } |
|
| 75 |
+ if userConf.Env == nil || len(userConf.Env) == 0 {
|
|
| 76 |
+ userConf.Env = imageConf.Env |
|
| 77 |
+ } else {
|
|
| 78 |
+ for _, imageEnv := range imageConf.Env {
|
|
| 79 |
+ found := false |
|
| 80 |
+ imageEnvKey := strings.Split(imageEnv, "=")[0] |
|
| 81 |
+ for _, userEnv := range userConf.Env {
|
|
| 82 |
+ userEnvKey := strings.Split(userEnv, "=")[0] |
|
| 83 |
+ if imageEnvKey == userEnvKey {
|
|
| 84 |
+ found = true |
|
| 85 |
+ } |
|
| 86 |
+ } |
|
| 87 |
+ if !found {
|
|
| 88 |
+ userConf.Env = append(userConf.Env, imageEnv) |
|
| 89 |
+ } |
|
| 90 |
+ } |
|
| 91 |
+ } |
|
| 92 |
+ if userConf.Cmd == nil || len(userConf.Cmd) == 0 {
|
|
| 93 |
+ userConf.Cmd = imageConf.Cmd |
|
| 94 |
+ } |
|
| 95 |
+ if userConf.Dns == nil || len(userConf.Dns) == 0 {
|
|
| 96 |
+ userConf.Dns = imageConf.Dns |
|
| 97 |
+ } else {
|
|
| 98 |
+ //duplicates aren't an issue here |
|
| 99 |
+ userConf.Dns = append(userConf.Dns, imageConf.Dns...) |
|
| 100 |
+ } |
|
| 101 |
+ if userConf.Entrypoint == nil || len(userConf.Entrypoint) == 0 {
|
|
| 102 |
+ userConf.Entrypoint = imageConf.Entrypoint |
|
| 103 |
+ } |
|
| 104 |
+ if userConf.WorkingDir == "" {
|
|
| 105 |
+ userConf.WorkingDir = imageConf.WorkingDir |
|
| 106 |
+ } |
|
| 107 |
+ if userConf.VolumesFrom == "" {
|
|
| 108 |
+ userConf.VolumesFrom = imageConf.VolumesFrom |
|
| 109 |
+ } |
|
| 110 |
+ if userConf.Volumes == nil || len(userConf.Volumes) == 0 {
|
|
| 111 |
+ userConf.Volumes = imageConf.Volumes |
|
| 112 |
+ } else {
|
|
| 113 |
+ for k, v := range imageConf.Volumes {
|
|
| 114 |
+ userConf.Volumes[k] = v |
|
| 115 |
+ } |
|
| 116 |
+ } |
|
| 117 |
+ return nil |
|
| 118 |
+} |
| 0 | 119 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,246 @@ |
| 0 |
+package runconfig |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "github.com/dotcloud/docker/nat" |
|
| 5 |
+ flag "github.com/dotcloud/docker/pkg/mflag" |
|
| 6 |
+ "github.com/dotcloud/docker/pkg/opts" |
|
| 7 |
+ "github.com/dotcloud/docker/pkg/sysinfo" |
|
| 8 |
+ "github.com/dotcloud/docker/utils" |
|
| 9 |
+ "io/ioutil" |
|
| 10 |
+ "path" |
|
| 11 |
+ "strings" |
|
| 12 |
+) |
|
| 13 |
+ |
|
| 14 |
+var ( |
|
| 15 |
+ ErrInvalidWorikingDirectory = fmt.Errorf("The working directory is invalid. It needs to be an absolute path.")
|
|
| 16 |
+ ErrConflictAttachDetach = fmt.Errorf("Conflicting options: -a and -d")
|
|
| 17 |
+ ErrConflictDetachAutoRemove = fmt.Errorf("Conflicting options: -rm and -d")
|
|
| 18 |
+) |
|
| 19 |
+ |
|
| 20 |
+//FIXME Only used in tests |
|
| 21 |
+func Parse(args []string, sysInfo *sysinfo.SysInfo) (*Config, *HostConfig, *flag.FlagSet, error) {
|
|
| 22 |
+ cmd := flag.NewFlagSet("run", flag.ContinueOnError)
|
|
| 23 |
+ cmd.SetOutput(ioutil.Discard) |
|
| 24 |
+ cmd.Usage = nil |
|
| 25 |
+ return parseRun(cmd, args, sysInfo) |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+// FIXME: this maps the legacy commands.go code. It should be merged with Parse to only expose a single parse function. |
|
| 29 |
+func ParseSubcommand(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Config, *HostConfig, *flag.FlagSet, error) {
|
|
| 30 |
+ return parseRun(cmd, args, sysInfo) |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Config, *HostConfig, *flag.FlagSet, error) {
|
|
| 34 |
+ var ( |
|
| 35 |
+ // FIXME: use utils.ListOpts for attach and volumes? |
|
| 36 |
+ flAttach = opts.NewListOpts(opts.ValidateAttach) |
|
| 37 |
+ flVolumes = opts.NewListOpts(opts.ValidatePath) |
|
| 38 |
+ flLinks = opts.NewListOpts(opts.ValidateLink) |
|
| 39 |
+ flEnv = opts.NewListOpts(opts.ValidateEnv) |
|
| 40 |
+ |
|
| 41 |
+ flPublish opts.ListOpts |
|
| 42 |
+ flExpose opts.ListOpts |
|
| 43 |
+ flDns opts.ListOpts |
|
| 44 |
+ flVolumesFrom opts.ListOpts |
|
| 45 |
+ flLxcOpts opts.ListOpts |
|
| 46 |
+ |
|
| 47 |
+ flAutoRemove = cmd.Bool([]string{"#rm", "-rm"}, false, "Automatically remove the container when it exits (incompatible with -d)")
|
|
| 48 |
+ flDetach = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: Run container in the background, print new container id")
|
|
| 49 |
+ flNetwork = cmd.Bool([]string{"n", "-networking"}, true, "Enable networking for this container")
|
|
| 50 |
+ flPrivileged = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container")
|
|
| 51 |
+ flPublishAll = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to the host interfaces")
|
|
| 52 |
+ flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep stdin open even if not attached")
|
|
| 53 |
+ flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-tty")
|
|
| 54 |
+ flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file")
|
|
| 55 |
+ flEntrypoint = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default entrypoint of the image")
|
|
| 56 |
+ flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
|
|
| 57 |
+ flMemoryString = cmd.String([]string{"m", "-memory"}, "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)")
|
|
| 58 |
+ flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID")
|
|
| 59 |
+ flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container")
|
|
| 60 |
+ flCpuShares = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
|
|
| 61 |
+ |
|
| 62 |
+ // For documentation purpose |
|
| 63 |
+ _ = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)")
|
|
| 64 |
+ _ = cmd.String([]string{"#name", "-name"}, "", "Assign a name to the container")
|
|
| 65 |
+ ) |
|
| 66 |
+ |
|
| 67 |
+ cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to stdin, stdout or stderr.")
|
|
| 68 |
+ cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)")
|
|
| 69 |
+ cmd.Var(&flLinks, []string{"#link", "-link"}, "Add link to another container (name:alias)")
|
|
| 70 |
+ cmd.Var(&flEnv, []string{"e", "-env"}, "Set environment variables")
|
|
| 71 |
+ |
|
| 72 |
+ cmd.Var(&flPublish, []string{"p", "-publish"}, fmt.Sprintf("Publish a container's port to the host (format: %s) (use 'docker port' to see the actual mapping)", nat.PortSpecTemplateFormat))
|
|
| 73 |
+ cmd.Var(&flExpose, []string{"#expose", "-expose"}, "Expose a port from the container without publishing it to your host")
|
|
| 74 |
+ cmd.Var(&flDns, []string{"#dns", "-dns"}, "Set custom dns servers")
|
|
| 75 |
+ cmd.Var(&flVolumesFrom, []string{"#volumes-from", "-volumes-from"}, "Mount volumes from the specified container(s)")
|
|
| 76 |
+ cmd.Var(&flLxcOpts, []string{"#lxc-conf", "-lxc-conf"}, "Add custom lxc options -lxc-conf=\"lxc.cgroup.cpuset.cpus = 0,1\"")
|
|
| 77 |
+ |
|
| 78 |
+ if err := cmd.Parse(args); err != nil {
|
|
| 79 |
+ return nil, nil, cmd, err |
|
| 80 |
+ } |
|
| 81 |
+ |
|
| 82 |
+ // Check if the kernel supports memory limit cgroup. |
|
| 83 |
+ if sysInfo != nil && *flMemoryString != "" && !sysInfo.MemoryLimit {
|
|
| 84 |
+ *flMemoryString = "" |
|
| 85 |
+ } |
|
| 86 |
+ |
|
| 87 |
+ // Validate input params |
|
| 88 |
+ if *flDetach && flAttach.Len() > 0 {
|
|
| 89 |
+ return nil, nil, cmd, ErrConflictAttachDetach |
|
| 90 |
+ } |
|
| 91 |
+ if *flWorkingDir != "" && !path.IsAbs(*flWorkingDir) {
|
|
| 92 |
+ return nil, nil, cmd, ErrInvalidWorikingDirectory |
|
| 93 |
+ } |
|
| 94 |
+ if *flDetach && *flAutoRemove {
|
|
| 95 |
+ return nil, nil, cmd, ErrConflictDetachAutoRemove |
|
| 96 |
+ } |
|
| 97 |
+ |
|
| 98 |
+ // If neither -d or -a are set, attach to everything by default |
|
| 99 |
+ if flAttach.Len() == 0 && !*flDetach {
|
|
| 100 |
+ if !*flDetach {
|
|
| 101 |
+ flAttach.Set("stdout")
|
|
| 102 |
+ flAttach.Set("stderr")
|
|
| 103 |
+ if *flStdin {
|
|
| 104 |
+ flAttach.Set("stdin")
|
|
| 105 |
+ } |
|
| 106 |
+ } |
|
| 107 |
+ } |
|
| 108 |
+ |
|
| 109 |
+ var flMemory int64 |
|
| 110 |
+ if *flMemoryString != "" {
|
|
| 111 |
+ parsedMemory, err := utils.RAMInBytes(*flMemoryString) |
|
| 112 |
+ if err != nil {
|
|
| 113 |
+ return nil, nil, cmd, err |
|
| 114 |
+ } |
|
| 115 |
+ flMemory = parsedMemory |
|
| 116 |
+ } |
|
| 117 |
+ |
|
| 118 |
+ var binds []string |
|
| 119 |
+ // add any bind targets to the list of container volumes |
|
| 120 |
+ for bind := range flVolumes.GetMap() {
|
|
| 121 |
+ if arr := strings.Split(bind, ":"); len(arr) > 1 {
|
|
| 122 |
+ if arr[0] == "/" {
|
|
| 123 |
+ return nil, nil, cmd, fmt.Errorf("Invalid bind mount: source can't be '/'")
|
|
| 124 |
+ } |
|
| 125 |
+ dstDir := arr[1] |
|
| 126 |
+ flVolumes.Set(dstDir) |
|
| 127 |
+ binds = append(binds, bind) |
|
| 128 |
+ flVolumes.Delete(bind) |
|
| 129 |
+ } else if bind == "/" {
|
|
| 130 |
+ return nil, nil, cmd, fmt.Errorf("Invalid volume: path can't be '/'")
|
|
| 131 |
+ } |
|
| 132 |
+ } |
|
| 133 |
+ |
|
| 134 |
+ var ( |
|
| 135 |
+ parsedArgs = cmd.Args() |
|
| 136 |
+ runCmd []string |
|
| 137 |
+ entrypoint []string |
|
| 138 |
+ image string |
|
| 139 |
+ ) |
|
| 140 |
+ if len(parsedArgs) >= 1 {
|
|
| 141 |
+ image = cmd.Arg(0) |
|
| 142 |
+ } |
|
| 143 |
+ if len(parsedArgs) > 1 {
|
|
| 144 |
+ runCmd = parsedArgs[1:] |
|
| 145 |
+ } |
|
| 146 |
+ if *flEntrypoint != "" {
|
|
| 147 |
+ entrypoint = []string{*flEntrypoint}
|
|
| 148 |
+ } |
|
| 149 |
+ |
|
| 150 |
+ lxcConf, err := parseLxcConfOpts(flLxcOpts) |
|
| 151 |
+ if err != nil {
|
|
| 152 |
+ return nil, nil, cmd, err |
|
| 153 |
+ } |
|
| 154 |
+ |
|
| 155 |
+ var ( |
|
| 156 |
+ domainname string |
|
| 157 |
+ hostname = *flHostname |
|
| 158 |
+ parts = strings.SplitN(hostname, ".", 2) |
|
| 159 |
+ ) |
|
| 160 |
+ if len(parts) > 1 {
|
|
| 161 |
+ hostname = parts[0] |
|
| 162 |
+ domainname = parts[1] |
|
| 163 |
+ } |
|
| 164 |
+ |
|
| 165 |
+ ports, portBindings, err := nat.ParsePortSpecs(flPublish.GetAll()) |
|
| 166 |
+ if err != nil {
|
|
| 167 |
+ return nil, nil, cmd, err |
|
| 168 |
+ } |
|
| 169 |
+ |
|
| 170 |
+ // Merge in exposed ports to the map of published ports |
|
| 171 |
+ for _, e := range flExpose.GetAll() {
|
|
| 172 |
+ if strings.Contains(e, ":") {
|
|
| 173 |
+ return nil, nil, cmd, fmt.Errorf("Invalid port format for --expose: %s", e)
|
|
| 174 |
+ } |
|
| 175 |
+ p := nat.NewPort(nat.SplitProtoPort(e)) |
|
| 176 |
+ if _, exists := ports[p]; !exists {
|
|
| 177 |
+ ports[p] = struct{}{}
|
|
| 178 |
+ } |
|
| 179 |
+ } |
|
| 180 |
+ |
|
| 181 |
+ config := &Config{
|
|
| 182 |
+ Hostname: hostname, |
|
| 183 |
+ Domainname: domainname, |
|
| 184 |
+ PortSpecs: nil, // Deprecated |
|
| 185 |
+ ExposedPorts: ports, |
|
| 186 |
+ User: *flUser, |
|
| 187 |
+ Tty: *flTty, |
|
| 188 |
+ NetworkDisabled: !*flNetwork, |
|
| 189 |
+ OpenStdin: *flStdin, |
|
| 190 |
+ Memory: flMemory, |
|
| 191 |
+ CpuShares: *flCpuShares, |
|
| 192 |
+ AttachStdin: flAttach.Get("stdin"),
|
|
| 193 |
+ AttachStdout: flAttach.Get("stdout"),
|
|
| 194 |
+ AttachStderr: flAttach.Get("stderr"),
|
|
| 195 |
+ Env: flEnv.GetAll(), |
|
| 196 |
+ Cmd: runCmd, |
|
| 197 |
+ Dns: flDns.GetAll(), |
|
| 198 |
+ Image: image, |
|
| 199 |
+ Volumes: flVolumes.GetMap(), |
|
| 200 |
+ VolumesFrom: strings.Join(flVolumesFrom.GetAll(), ","), |
|
| 201 |
+ Entrypoint: entrypoint, |
|
| 202 |
+ WorkingDir: *flWorkingDir, |
|
| 203 |
+ } |
|
| 204 |
+ |
|
| 205 |
+ hostConfig := &HostConfig{
|
|
| 206 |
+ Binds: binds, |
|
| 207 |
+ ContainerIDFile: *flContainerIDFile, |
|
| 208 |
+ LxcConf: lxcConf, |
|
| 209 |
+ Privileged: *flPrivileged, |
|
| 210 |
+ PortBindings: portBindings, |
|
| 211 |
+ Links: flLinks.GetAll(), |
|
| 212 |
+ PublishAllPorts: *flPublishAll, |
|
| 213 |
+ } |
|
| 214 |
+ |
|
| 215 |
+ if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit {
|
|
| 216 |
+ //fmt.Fprintf(stdout, "WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.\n") |
|
| 217 |
+ config.MemorySwap = -1 |
|
| 218 |
+ } |
|
| 219 |
+ |
|
| 220 |
+ // When allocating stdin in attached mode, close stdin at client disconnect |
|
| 221 |
+ if config.OpenStdin && config.AttachStdin {
|
|
| 222 |
+ config.StdinOnce = true |
|
| 223 |
+ } |
|
| 224 |
+ return config, hostConfig, cmd, nil |
|
| 225 |
+} |
|
| 226 |
+ |
|
| 227 |
+func parseLxcConfOpts(opts opts.ListOpts) ([]KeyValuePair, error) {
|
|
| 228 |
+ out := make([]KeyValuePair, opts.Len()) |
|
| 229 |
+ for i, o := range opts.GetAll() {
|
|
| 230 |
+ k, v, err := parseLxcOpt(o) |
|
| 231 |
+ if err != nil {
|
|
| 232 |
+ return nil, err |
|
| 233 |
+ } |
|
| 234 |
+ out[i] = KeyValuePair{Key: k, Value: v}
|
|
| 235 |
+ } |
|
| 236 |
+ return out, nil |
|
| 237 |
+} |
|
| 238 |
+ |
|
| 239 |
+func parseLxcOpt(opt string) (string, string, error) {
|
|
| 240 |
+ parts := strings.SplitN(opt, "=", 2) |
|
| 241 |
+ if len(parts) != 2 {
|
|
| 242 |
+ return "", "", fmt.Errorf("Unable to parse lxc conf option: %s", opt)
|
|
| 243 |
+ } |
|
| 244 |
+ return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil |
|
| 245 |
+} |
| 0 | 246 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,22 @@ |
| 0 |
+package runconfig |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "testing" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+func TestParseLxcConfOpt(t *testing.T) {
|
|
| 7 |
+ opts := []string{"lxc.utsname=docker", "lxc.utsname = docker "}
|
|
| 8 |
+ |
|
| 9 |
+ for _, o := range opts {
|
|
| 10 |
+ k, v, err := parseLxcOpt(o) |
|
| 11 |
+ if err != nil {
|
|
| 12 |
+ t.FailNow() |
|
| 13 |
+ } |
|
| 14 |
+ if k != "lxc.utsname" {
|
|
| 15 |
+ t.Fail() |
|
| 16 |
+ } |
|
| 17 |
+ if v != "docker" {
|
|
| 18 |
+ t.Fail() |
|
| 19 |
+ } |
|
| 20 |
+ } |
|
| 21 |
+} |
| ... | ... |
@@ -18,6 +18,7 @@ import ( |
| 18 | 18 |
"github.com/dotcloud/docker/networkdriver/portallocator" |
| 19 | 19 |
"github.com/dotcloud/docker/pkg/graphdb" |
| 20 | 20 |
"github.com/dotcloud/docker/pkg/sysinfo" |
| 21 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 21 | 22 |
"github.com/dotcloud/docker/utils" |
| 22 | 23 |
"io" |
| 23 | 24 |
"io/ioutil" |
| ... | ... |
@@ -329,7 +330,7 @@ func (runtime *Runtime) restore() error {
|
| 329 | 329 |
} |
| 330 | 330 |
|
| 331 | 331 |
// Create creates a new container from the given configuration with a given name. |
| 332 |
-func (runtime *Runtime) Create(config *Config, name string) (*Container, []string, error) {
|
|
| 332 |
+func (runtime *Runtime) Create(config *runconfig.Config, name string) (*Container, []string, error) {
|
|
| 333 | 333 |
// Lookup image |
| 334 | 334 |
img, err := runtime.repositories.LookupImage(config.Image) |
| 335 | 335 |
if err != nil {
|
| ... | ... |
@@ -347,7 +348,7 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin |
| 347 | 347 |
return nil, nil, fmt.Errorf("Cannot create container with more than %d parents", MaxImageDepth)
|
| 348 | 348 |
} |
| 349 | 349 |
|
| 350 |
- checkDeprecatedExpose := func(config *Config) bool {
|
|
| 350 |
+ checkDeprecatedExpose := func(config *runconfig.Config) bool {
|
|
| 351 | 351 |
if config != nil {
|
| 352 | 352 |
if config.PortSpecs != nil {
|
| 353 | 353 |
for _, p := range config.PortSpecs {
|
| ... | ... |
@@ -366,7 +367,7 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin |
| 366 | 366 |
} |
| 367 | 367 |
|
| 368 | 368 |
if img.Config != nil {
|
| 369 |
- if err := MergeConfig(config, img.Config); err != nil {
|
|
| 369 |
+ if err := runconfig.Merge(config, img.Config); err != nil {
|
|
| 370 | 370 |
return nil, nil, err |
| 371 | 371 |
} |
| 372 | 372 |
} |
| ... | ... |
@@ -441,7 +442,7 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin |
| 441 | 441 |
Path: entrypoint, |
| 442 | 442 |
Args: args, //FIXME: de-duplicate from config |
| 443 | 443 |
Config: config, |
| 444 |
- hostConfig: &HostConfig{},
|
|
| 444 |
+ hostConfig: &runconfig.HostConfig{},
|
|
| 445 | 445 |
Image: img.ID, // Always use the resolved image id |
| 446 | 446 |
NetworkSettings: &NetworkSettings{},
|
| 447 | 447 |
Name: name, |
| ... | ... |
@@ -518,7 +519,7 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin |
| 518 | 518 |
|
| 519 | 519 |
// Commit creates a new filesystem image from the current state of a container. |
| 520 | 520 |
// The image can optionally be tagged into a repository |
| 521 |
-func (runtime *Runtime) Commit(container *Container, repository, tag, comment, author string, config *Config) (*Image, error) {
|
|
| 521 |
+func (runtime *Runtime) Commit(container *Container, repository, tag, comment, author string, config *runconfig.Config) (*Image, error) {
|
|
| 522 | 522 |
// FIXME: freeze the container before copying it to avoid data corruption? |
| 523 | 523 |
// FIXME: this shouldn't be in commands. |
| 524 | 524 |
if err := container.Mount(); err != nil {
|
| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
"github.com/dotcloud/docker/engine" |
| 11 | 11 |
"github.com/dotcloud/docker/pkg/graphdb" |
| 12 | 12 |
"github.com/dotcloud/docker/registry" |
| 13 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 13 | 14 |
"github.com/dotcloud/docker/utils" |
| 14 | 15 |
"io" |
| 15 | 16 |
"io/ioutil" |
| ... | ... |
@@ -662,7 +663,7 @@ func (srv *Server) ImageInsert(job *engine.Job) engine.Status {
|
| 662 | 662 |
} |
| 663 | 663 |
defer file.Body.Close() |
| 664 | 664 |
|
| 665 |
- config, _, _, err := ParseRun([]string{img.ID, "echo", "insert", url, path}, srv.runtime.sysInfo)
|
|
| 665 |
+ config, _, _, err := runconfig.Parse([]string{img.ID, "echo", "insert", url, path}, srv.runtime.sysInfo)
|
|
| 666 | 666 |
if err != nil {
|
| 667 | 667 |
return job.Error(err) |
| 668 | 668 |
} |
| ... | ... |
@@ -1043,7 +1044,7 @@ func (srv *Server) ContainerCommit(job *engine.Job) engine.Status {
|
| 1043 | 1043 |
if container == nil {
|
| 1044 | 1044 |
return job.Errorf("No such container: %s", name)
|
| 1045 | 1045 |
} |
| 1046 |
- var config Config |
|
| 1046 |
+ var config runconfig.Config |
|
| 1047 | 1047 |
if err := job.GetenvJson("config", &config); err != nil {
|
| 1048 | 1048 |
return job.Error(err) |
| 1049 | 1049 |
} |
| ... | ... |
@@ -1623,7 +1624,7 @@ func (srv *Server) ContainerCreate(job *engine.Job) engine.Status {
|
| 1623 | 1623 |
} else if len(job.Args) > 1 {
|
| 1624 | 1624 |
return job.Errorf("Usage: %s", job.Name)
|
| 1625 | 1625 |
} |
| 1626 |
- config := ContainerConfigFromJob(job) |
|
| 1626 |
+ config := runconfig.ContainerConfigFromJob(job) |
|
| 1627 | 1627 |
if config.Memory != 0 && config.Memory < 524288 {
|
| 1628 | 1628 |
return job.Errorf("Minimum memory limit allowed is 512k")
|
| 1629 | 1629 |
} |
| ... | ... |
@@ -1989,7 +1990,7 @@ func (srv *Server) canDeleteImage(imgID string) error {
|
| 1989 | 1989 |
return nil |
| 1990 | 1990 |
} |
| 1991 | 1991 |
|
| 1992 |
-func (srv *Server) ImageGetCached(imgID string, config *Config) (*Image, error) {
|
|
| 1992 |
+func (srv *Server) ImageGetCached(imgID string, config *runconfig.Config) (*Image, error) {
|
|
| 1993 | 1993 |
|
| 1994 | 1994 |
// Retrieve all images |
| 1995 | 1995 |
images, err := srv.runtime.graph.Map() |
| ... | ... |
@@ -2013,7 +2014,7 @@ func (srv *Server) ImageGetCached(imgID string, config *Config) (*Image, error) |
| 2013 | 2013 |
if err != nil {
|
| 2014 | 2014 |
return nil, err |
| 2015 | 2015 |
} |
| 2016 |
- if CompareConfig(&img.ContainerConfig, config) {
|
|
| 2016 |
+ if runconfig.Compare(&img.ContainerConfig, config) {
|
|
| 2017 | 2017 |
if match == nil || match.Created.Before(img.Created) {
|
| 2018 | 2018 |
match = img |
| 2019 | 2019 |
} |
| ... | ... |
@@ -2022,7 +2023,7 @@ func (srv *Server) ImageGetCached(imgID string, config *Config) (*Image, error) |
| 2022 | 2022 |
return match, nil |
| 2023 | 2023 |
} |
| 2024 | 2024 |
|
| 2025 |
-func (srv *Server) RegisterLinks(container *Container, hostConfig *HostConfig) error {
|
|
| 2025 |
+func (srv *Server) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
|
|
| 2026 | 2026 |
runtime := srv.runtime |
| 2027 | 2027 |
|
| 2028 | 2028 |
if hostConfig != nil && hostConfig.Links != nil {
|
| ... | ... |
@@ -2066,7 +2067,7 @@ func (srv *Server) ContainerStart(job *engine.Job) engine.Status {
|
| 2066 | 2066 |
} |
| 2067 | 2067 |
// If no environment was set, then no hostconfig was passed. |
| 2068 | 2068 |
if len(job.Environ()) > 0 {
|
| 2069 |
- hostConfig := ContainerHostConfigFromJob(job) |
|
| 2069 |
+ hostConfig := runconfig.ContainerHostConfigFromJob(job) |
|
| 2070 | 2070 |
// Validate the HostConfig binds. Make sure that: |
| 2071 | 2071 |
// 1) the source of a bind mount isn't / |
| 2072 | 2072 |
// The bind mount "/:/foo" isn't allowed. |
| ... | ... |
@@ -2310,7 +2311,7 @@ func (srv *Server) JobInspect(job *engine.Job) engine.Status {
|
| 2310 | 2310 |
} |
| 2311 | 2311 |
object = &struct {
|
| 2312 | 2312 |
*Container |
| 2313 |
- HostConfig *HostConfig |
|
| 2313 |
+ HostConfig *runconfig.HostConfig |
|
| 2314 | 2314 |
}{container, container.hostConfig}
|
| 2315 | 2315 |
default: |
| 2316 | 2316 |
return job.Errorf("Unknown kind: %s", kind)
|
| ... | ... |
@@ -1,14 +1,12 @@ |
| 1 | 1 |
package docker |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "fmt" |
|
| 5 | 4 |
"github.com/dotcloud/docker/archive" |
| 6 | 5 |
"github.com/dotcloud/docker/nat" |
| 7 | 6 |
"github.com/dotcloud/docker/pkg/namesgenerator" |
| 8 |
- "github.com/dotcloud/docker/pkg/opts" |
|
| 7 |
+ "github.com/dotcloud/docker/runconfig" |
|
| 9 | 8 |
"github.com/dotcloud/docker/utils" |
| 10 | 9 |
"io" |
| 11 |
- "strings" |
|
| 12 | 10 |
"sync/atomic" |
| 13 | 11 |
) |
| 14 | 12 |
|
| ... | ... |
@@ -16,204 +14,7 @@ type Change struct {
|
| 16 | 16 |
archive.Change |
| 17 | 17 |
} |
| 18 | 18 |
|
| 19 |
-// Compare two Config struct. Do not compare the "Image" nor "Hostname" fields |
|
| 20 |
-// If OpenStdin is set, then it differs |
|
| 21 |
-func CompareConfig(a, b *Config) bool {
|
|
| 22 |
- if a == nil || b == nil || |
|
| 23 |
- a.OpenStdin || b.OpenStdin {
|
|
| 24 |
- return false |
|
| 25 |
- } |
|
| 26 |
- if a.AttachStdout != b.AttachStdout || |
|
| 27 |
- a.AttachStderr != b.AttachStderr || |
|
| 28 |
- a.User != b.User || |
|
| 29 |
- a.Memory != b.Memory || |
|
| 30 |
- a.MemorySwap != b.MemorySwap || |
|
| 31 |
- a.CpuShares != b.CpuShares || |
|
| 32 |
- a.OpenStdin != b.OpenStdin || |
|
| 33 |
- a.Tty != b.Tty || |
|
| 34 |
- a.VolumesFrom != b.VolumesFrom {
|
|
| 35 |
- return false |
|
| 36 |
- } |
|
| 37 |
- if len(a.Cmd) != len(b.Cmd) || |
|
| 38 |
- len(a.Dns) != len(b.Dns) || |
|
| 39 |
- len(a.Env) != len(b.Env) || |
|
| 40 |
- len(a.PortSpecs) != len(b.PortSpecs) || |
|
| 41 |
- len(a.ExposedPorts) != len(b.ExposedPorts) || |
|
| 42 |
- len(a.Entrypoint) != len(b.Entrypoint) || |
|
| 43 |
- len(a.Volumes) != len(b.Volumes) {
|
|
| 44 |
- return false |
|
| 45 |
- } |
|
| 46 |
- |
|
| 47 |
- for i := 0; i < len(a.Cmd); i++ {
|
|
| 48 |
- if a.Cmd[i] != b.Cmd[i] {
|
|
| 49 |
- return false |
|
| 50 |
- } |
|
| 51 |
- } |
|
| 52 |
- for i := 0; i < len(a.Dns); i++ {
|
|
| 53 |
- if a.Dns[i] != b.Dns[i] {
|
|
| 54 |
- return false |
|
| 55 |
- } |
|
| 56 |
- } |
|
| 57 |
- for i := 0; i < len(a.Env); i++ {
|
|
| 58 |
- if a.Env[i] != b.Env[i] {
|
|
| 59 |
- return false |
|
| 60 |
- } |
|
| 61 |
- } |
|
| 62 |
- for i := 0; i < len(a.PortSpecs); i++ {
|
|
| 63 |
- if a.PortSpecs[i] != b.PortSpecs[i] {
|
|
| 64 |
- return false |
|
| 65 |
- } |
|
| 66 |
- } |
|
| 67 |
- for k := range a.ExposedPorts {
|
|
| 68 |
- if _, exists := b.ExposedPorts[k]; !exists {
|
|
| 69 |
- return false |
|
| 70 |
- } |
|
| 71 |
- } |
|
| 72 |
- for i := 0; i < len(a.Entrypoint); i++ {
|
|
| 73 |
- if a.Entrypoint[i] != b.Entrypoint[i] {
|
|
| 74 |
- return false |
|
| 75 |
- } |
|
| 76 |
- } |
|
| 77 |
- for key := range a.Volumes {
|
|
| 78 |
- if _, exists := b.Volumes[key]; !exists {
|
|
| 79 |
- return false |
|
| 80 |
- } |
|
| 81 |
- } |
|
| 82 |
- return true |
|
| 83 |
-} |
|
| 84 |
- |
|
| 85 |
-func MergeConfig(userConf, imageConf *Config) error {
|
|
| 86 |
- if userConf.User == "" {
|
|
| 87 |
- userConf.User = imageConf.User |
|
| 88 |
- } |
|
| 89 |
- if userConf.Memory == 0 {
|
|
| 90 |
- userConf.Memory = imageConf.Memory |
|
| 91 |
- } |
|
| 92 |
- if userConf.MemorySwap == 0 {
|
|
| 93 |
- userConf.MemorySwap = imageConf.MemorySwap |
|
| 94 |
- } |
|
| 95 |
- if userConf.CpuShares == 0 {
|
|
| 96 |
- userConf.CpuShares = imageConf.CpuShares |
|
| 97 |
- } |
|
| 98 |
- if userConf.ExposedPorts == nil || len(userConf.ExposedPorts) == 0 {
|
|
| 99 |
- userConf.ExposedPorts = imageConf.ExposedPorts |
|
| 100 |
- } else if imageConf.ExposedPorts != nil {
|
|
| 101 |
- if userConf.ExposedPorts == nil {
|
|
| 102 |
- userConf.ExposedPorts = make(nat.PortSet) |
|
| 103 |
- } |
|
| 104 |
- for port := range imageConf.ExposedPorts {
|
|
| 105 |
- if _, exists := userConf.ExposedPorts[port]; !exists {
|
|
| 106 |
- userConf.ExposedPorts[port] = struct{}{}
|
|
| 107 |
- } |
|
| 108 |
- } |
|
| 109 |
- } |
|
| 110 |
- |
|
| 111 |
- if userConf.PortSpecs != nil && len(userConf.PortSpecs) > 0 {
|
|
| 112 |
- if userConf.ExposedPorts == nil {
|
|
| 113 |
- userConf.ExposedPorts = make(nat.PortSet) |
|
| 114 |
- } |
|
| 115 |
- ports, _, err := nat.ParsePortSpecs(userConf.PortSpecs) |
|
| 116 |
- if err != nil {
|
|
| 117 |
- return err |
|
| 118 |
- } |
|
| 119 |
- for port := range ports {
|
|
| 120 |
- if _, exists := userConf.ExposedPorts[port]; !exists {
|
|
| 121 |
- userConf.ExposedPorts[port] = struct{}{}
|
|
| 122 |
- } |
|
| 123 |
- } |
|
| 124 |
- userConf.PortSpecs = nil |
|
| 125 |
- } |
|
| 126 |
- if imageConf.PortSpecs != nil && len(imageConf.PortSpecs) > 0 {
|
|
| 127 |
- utils.Debugf("Migrating image port specs to containter: %s", strings.Join(imageConf.PortSpecs, ", "))
|
|
| 128 |
- if userConf.ExposedPorts == nil {
|
|
| 129 |
- userConf.ExposedPorts = make(nat.PortSet) |
|
| 130 |
- } |
|
| 131 |
- |
|
| 132 |
- ports, _, err := nat.ParsePortSpecs(imageConf.PortSpecs) |
|
| 133 |
- if err != nil {
|
|
| 134 |
- return err |
|
| 135 |
- } |
|
| 136 |
- for port := range ports {
|
|
| 137 |
- if _, exists := userConf.ExposedPorts[port]; !exists {
|
|
| 138 |
- userConf.ExposedPorts[port] = struct{}{}
|
|
| 139 |
- } |
|
| 140 |
- } |
|
| 141 |
- } |
|
| 142 |
- if !userConf.Tty {
|
|
| 143 |
- userConf.Tty = imageConf.Tty |
|
| 144 |
- } |
|
| 145 |
- if !userConf.OpenStdin {
|
|
| 146 |
- userConf.OpenStdin = imageConf.OpenStdin |
|
| 147 |
- } |
|
| 148 |
- if !userConf.StdinOnce {
|
|
| 149 |
- userConf.StdinOnce = imageConf.StdinOnce |
|
| 150 |
- } |
|
| 151 |
- if userConf.Env == nil || len(userConf.Env) == 0 {
|
|
| 152 |
- userConf.Env = imageConf.Env |
|
| 153 |
- } else {
|
|
| 154 |
- for _, imageEnv := range imageConf.Env {
|
|
| 155 |
- found := false |
|
| 156 |
- imageEnvKey := strings.Split(imageEnv, "=")[0] |
|
| 157 |
- for _, userEnv := range userConf.Env {
|
|
| 158 |
- userEnvKey := strings.Split(userEnv, "=")[0] |
|
| 159 |
- if imageEnvKey == userEnvKey {
|
|
| 160 |
- found = true |
|
| 161 |
- } |
|
| 162 |
- } |
|
| 163 |
- if !found {
|
|
| 164 |
- userConf.Env = append(userConf.Env, imageEnv) |
|
| 165 |
- } |
|
| 166 |
- } |
|
| 167 |
- } |
|
| 168 |
- if userConf.Cmd == nil || len(userConf.Cmd) == 0 {
|
|
| 169 |
- userConf.Cmd = imageConf.Cmd |
|
| 170 |
- } |
|
| 171 |
- if userConf.Dns == nil || len(userConf.Dns) == 0 {
|
|
| 172 |
- userConf.Dns = imageConf.Dns |
|
| 173 |
- } else {
|
|
| 174 |
- //duplicates aren't an issue here |
|
| 175 |
- userConf.Dns = append(userConf.Dns, imageConf.Dns...) |
|
| 176 |
- } |
|
| 177 |
- if userConf.Entrypoint == nil || len(userConf.Entrypoint) == 0 {
|
|
| 178 |
- userConf.Entrypoint = imageConf.Entrypoint |
|
| 179 |
- } |
|
| 180 |
- if userConf.WorkingDir == "" {
|
|
| 181 |
- userConf.WorkingDir = imageConf.WorkingDir |
|
| 182 |
- } |
|
| 183 |
- if userConf.VolumesFrom == "" {
|
|
| 184 |
- userConf.VolumesFrom = imageConf.VolumesFrom |
|
| 185 |
- } |
|
| 186 |
- if userConf.Volumes == nil || len(userConf.Volumes) == 0 {
|
|
| 187 |
- userConf.Volumes = imageConf.Volumes |
|
| 188 |
- } else {
|
|
| 189 |
- for k, v := range imageConf.Volumes {
|
|
| 190 |
- userConf.Volumes[k] = v |
|
| 191 |
- } |
|
| 192 |
- } |
|
| 193 |
- return nil |
|
| 194 |
-} |
|
| 195 |
- |
|
| 196 |
-func parseLxcConfOpts(opts opts.ListOpts) ([]KeyValuePair, error) {
|
|
| 197 |
- out := make([]KeyValuePair, opts.Len()) |
|
| 198 |
- for i, o := range opts.GetAll() {
|
|
| 199 |
- k, v, err := parseLxcOpt(o) |
|
| 200 |
- if err != nil {
|
|
| 201 |
- return nil, err |
|
| 202 |
- } |
|
| 203 |
- out[i] = KeyValuePair{Key: k, Value: v}
|
|
| 204 |
- } |
|
| 205 |
- return out, nil |
|
| 206 |
-} |
|
| 207 |
- |
|
| 208 |
-func parseLxcOpt(opt string) (string, string, error) {
|
|
| 209 |
- parts := strings.SplitN(opt, "=", 2) |
|
| 210 |
- if len(parts) != 2 {
|
|
| 211 |
- return "", "", fmt.Errorf("Unable to parse lxc conf option: %s", opt)
|
|
| 212 |
- } |
|
| 213 |
- return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil |
|
| 214 |
-} |
|
| 215 |
- |
|
| 216 |
-func migratePortMappings(config *Config, hostConfig *HostConfig) error {
|
|
| 19 |
+func migratePortMappings(config *runconfig.Config, hostConfig *runconfig.HostConfig) error {
|
|
| 217 | 20 |
if config.PortSpecs != nil {
|
| 218 | 21 |
ports, bindings, err := nat.ParsePortSpecs(config.PortSpecs) |
| 219 | 22 |
if err != nil {
|
| ... | ... |
@@ -222,7 +23,7 @@ func migratePortMappings(config *Config, hostConfig *HostConfig) error {
|
| 222 | 222 |
config.PortSpecs = nil |
| 223 | 223 |
if len(bindings) > 0 {
|
| 224 | 224 |
if hostConfig == nil {
|
| 225 |
- hostConfig = &HostConfig{}
|
|
| 225 |
+ hostConfig = &runconfig.HostConfig{}
|
|
| 226 | 226 |
} |
| 227 | 227 |
hostConfig.PortBindings = bindings |
| 228 | 228 |
} |