| ... | ... |
@@ -1730,60 +1730,59 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig, |
| 1730 | 1730 |
} |
| 1731 | 1731 |
|
| 1732 | 1732 |
func parseRun(cmd *flag.FlagSet, args []string, capabilities *Capabilities) (*Config, *HostConfig, *flag.FlagSet, error) {
|
| 1733 |
- |
|
| 1734 |
- flHostname := cmd.String("h", "", "Container host name")
|
|
| 1735 |
- flWorkingDir := cmd.String("w", "", "Working directory inside the container")
|
|
| 1736 |
- flUser := cmd.String("u", "", "Username or UID")
|
|
| 1737 |
- flDetach := cmd.Bool("d", false, "Detached mode: Run container in the background, print new container id")
|
|
| 1738 |
- flAttach := NewAttachOpts() |
|
| 1733 |
+ var ( |
|
| 1734 |
+ // FIXME: use utils.ListOpts for attach and volumes? |
|
| 1735 |
+ flAttach = NewAttachOpts() |
|
| 1736 |
+ flVolumes = NewPathOpts() |
|
| 1737 |
+ |
|
| 1738 |
+ flPublish utils.ListOpts |
|
| 1739 |
+ flExpose utils.ListOpts |
|
| 1740 |
+ flEnv utils.ListOpts |
|
| 1741 |
+ flDns utils.ListOpts |
|
| 1742 |
+ flVolumesFrom utils.ListOpts |
|
| 1743 |
+ flLxcOpts utils.ListOpts |
|
| 1744 |
+ flLinks utils.ListOpts |
|
| 1745 |
+ |
|
| 1746 |
+ flAutoRemove = cmd.Bool("rm", false, "Automatically remove the container when it exits (incompatible with -d)")
|
|
| 1747 |
+ flDetach = cmd.Bool("d", false, "Detached mode: Run container in the background, print new container id")
|
|
| 1748 |
+ flNetwork = cmd.Bool("n", true, "Enable networking for this container")
|
|
| 1749 |
+ flPrivileged = cmd.Bool("privileged", false, "Give extended privileges to this container")
|
|
| 1750 |
+ flPublishAll = cmd.Bool("P", false, "Publish all exposed ports to the host interfaces")
|
|
| 1751 |
+ flStdin = cmd.Bool("i", false, "Keep stdin open even if not attached")
|
|
| 1752 |
+ flTty = cmd.Bool("t", false, "Allocate a pseudo-tty")
|
|
| 1753 |
+ flContainerIDFile = cmd.String("cidfile", "", "Write the container ID to the file")
|
|
| 1754 |
+ flEntrypoint = cmd.String("entrypoint", "", "Overwrite the default entrypoint of the image")
|
|
| 1755 |
+ flHostname = cmd.String("h", "", "Container host name")
|
|
| 1756 |
+ flMemoryString = cmd.String("m", "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)")
|
|
| 1757 |
+ flUser = cmd.String("u", "", "Username or UID")
|
|
| 1758 |
+ flWorkingDir = cmd.String("w", "", "Working directory inside the container")
|
|
| 1759 |
+ flCpuShares = cmd.Int64("c", 0, "CPU shares (relative weight)")
|
|
| 1760 |
+ |
|
| 1761 |
+ // For documentation purpose |
|
| 1762 |
+ _ = cmd.Bool("sig-proxy", true, "Proxify all received signal to the process (even in non-tty mode)")
|
|
| 1763 |
+ _ = cmd.String("name", "", "Assign a name to the container")
|
|
| 1764 |
+ ) |
|
| 1739 | 1765 |
cmd.Var(flAttach, "a", "Attach to stdin, stdout or stderr.") |
| 1740 |
- flStdin := cmd.Bool("i", false, "Keep stdin open even if not attached")
|
|
| 1741 |
- flTty := cmd.Bool("t", false, "Allocate a pseudo-tty")
|
|
| 1742 |
- flMemoryString := cmd.String("m", "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)")
|
|
| 1743 |
- flContainerIDFile := cmd.String("cidfile", "", "Write the container ID to the file")
|
|
| 1744 |
- flNetwork := cmd.Bool("n", true, "Enable networking for this container")
|
|
| 1745 |
- flPrivileged := cmd.Bool("privileged", false, "Give extended privileges to this container")
|
|
| 1746 |
- flAutoRemove := cmd.Bool("rm", false, "Automatically remove the container when it exits (incompatible with -d)")
|
|
| 1747 |
- cmd.Bool("sig-proxy", true, "Proxify all received signal to the process (even in non-tty mode)")
|
|
| 1748 |
- cmd.String("name", "", "Assign a name to the container")
|
|
| 1749 |
- flPublishAll := cmd.Bool("P", false, "Publish all exposed ports to the host interfaces")
|
|
| 1750 |
- |
|
| 1751 |
- if capabilities != nil && *flMemoryString != "" && !capabilities.MemoryLimit {
|
|
| 1752 |
- //fmt.Fprintf(stdout, "WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n") |
|
| 1753 |
- *flMemoryString = "" |
|
| 1754 |
- } |
|
| 1755 |
- |
|
| 1756 |
- flCpuShares := cmd.Int64("c", 0, "CPU shares (relative weight)")
|
|
| 1766 |
+ cmd.Var(flVolumes, "v", "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)") |
|
| 1757 | 1767 |
|
| 1758 |
- var flPublish utils.ListOpts |
|
| 1759 | 1768 |
cmd.Var(&flPublish, "p", "Publish a container's port to the host (use 'docker port' to see the actual mapping)") |
| 1760 |
- |
|
| 1761 |
- var flExpose utils.ListOpts |
|
| 1762 | 1769 |
cmd.Var(&flExpose, "expose", "Expose a port from the container without publishing it to your host") |
| 1763 |
- |
|
| 1764 |
- var flEnv utils.ListOpts |
|
| 1765 | 1770 |
cmd.Var(&flEnv, "e", "Set environment variables") |
| 1766 |
- |
|
| 1767 |
- var flDns utils.ListOpts |
|
| 1768 | 1771 |
cmd.Var(&flDns, "dns", "Set custom dns servers") |
| 1769 |
- |
|
| 1770 |
- flVolumes := NewPathOpts() |
|
| 1771 |
- cmd.Var(flVolumes, "v", "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)") |
|
| 1772 |
- |
|
| 1773 |
- var flVolumesFrom utils.ListOpts |
|
| 1774 | 1772 |
cmd.Var(&flVolumesFrom, "volumes-from", "Mount volumes from the specified container(s)") |
| 1775 |
- |
|
| 1776 |
- flEntrypoint := cmd.String("entrypoint", "", "Overwrite the default entrypoint of the image")
|
|
| 1777 |
- |
|
| 1778 |
- var flLxcOpts utils.ListOpts |
|
| 1779 | 1773 |
cmd.Var(&flLxcOpts, "lxc-conf", "Add custom lxc options -lxc-conf=\"lxc.cgroup.cpuset.cpus = 0,1\"") |
| 1780 |
- |
|
| 1781 |
- var flLinks utils.ListOpts |
|
| 1782 | 1774 |
cmd.Var(&flLinks, "link", "Add link to another container (name:alias)") |
| 1783 | 1775 |
|
| 1784 | 1776 |
if err := cmd.Parse(args); err != nil {
|
| 1785 | 1777 |
return nil, nil, cmd, err |
| 1786 | 1778 |
} |
| 1779 |
+ |
|
| 1780 |
+ // Check if the kernel supports memory limit cgroup. |
|
| 1781 |
+ if capabilities != nil && *flMemoryString != "" && !capabilities.MemoryLimit {
|
|
| 1782 |
+ *flMemoryString = "" |
|
| 1783 |
+ } |
|
| 1784 |
+ |
|
| 1785 |
+ // Validate input params |
|
| 1787 | 1786 |
if *flDetach && len(flAttach) > 0 {
|
| 1788 | 1787 |
return nil, nil, cmd, ErrConflictAttachDetach |
| 1789 | 1788 |
} |
| ... | ... |
@@ -1805,8 +1804,7 @@ func parseRun(cmd *flag.FlagSet, args []string, capabilities *Capabilities) (*Co |
| 1805 | 1805 |
} |
| 1806 | 1806 |
} |
| 1807 | 1807 |
|
| 1808 |
- envs := []string{}
|
|
| 1809 |
- |
|
| 1808 |
+ var envs []string |
|
| 1810 | 1809 |
for _, env := range flEnv {
|
| 1811 | 1810 |
arr := strings.Split(env, "=") |
| 1812 | 1811 |
if len(arr) > 1 {
|
| ... | ... |
@@ -1818,19 +1816,15 @@ func parseRun(cmd *flag.FlagSet, args []string, capabilities *Capabilities) (*Co |
| 1818 | 1818 |
} |
| 1819 | 1819 |
|
| 1820 | 1820 |
var flMemory int64 |
| 1821 |
- |
|
| 1822 | 1821 |
if *flMemoryString != "" {
|
| 1823 | 1822 |
parsedMemory, err := utils.RAMInBytes(*flMemoryString) |
| 1824 |
- |
|
| 1825 | 1823 |
if err != nil {
|
| 1826 | 1824 |
return nil, nil, cmd, err |
| 1827 | 1825 |
} |
| 1828 |
- |
|
| 1829 | 1826 |
flMemory = parsedMemory |
| 1830 | 1827 |
} |
| 1831 | 1828 |
|
| 1832 | 1829 |
var binds []string |
| 1833 |
- |
|
| 1834 | 1830 |
// add any bind targets to the list of container volumes |
| 1835 | 1831 |
for bind := range flVolumes {
|
| 1836 | 1832 |
arr := strings.Split(bind, ":") |
| ... | ... |
@@ -1845,10 +1839,12 @@ func parseRun(cmd *flag.FlagSet, args []string, capabilities *Capabilities) (*Co |
| 1845 | 1845 |
} |
| 1846 | 1846 |
} |
| 1847 | 1847 |
|
| 1848 |
- parsedArgs := cmd.Args() |
|
| 1849 |
- runCmd := []string{}
|
|
| 1850 |
- entrypoint := []string{}
|
|
| 1851 |
- image := "" |
|
| 1848 |
+ var ( |
|
| 1849 |
+ parsedArgs = cmd.Args() |
|
| 1850 |
+ runCmd []string |
|
| 1851 |
+ entrypoint []string |
|
| 1852 |
+ image string |
|
| 1853 |
+ ) |
|
| 1852 | 1854 |
if len(parsedArgs) >= 1 {
|
| 1853 | 1855 |
image = cmd.Arg(0) |
| 1854 | 1856 |
} |
| ... | ... |
@@ -1859,16 +1855,16 @@ func parseRun(cmd *flag.FlagSet, args []string, capabilities *Capabilities) (*Co |
| 1859 | 1859 |
entrypoint = []string{*flEntrypoint}
|
| 1860 | 1860 |
} |
| 1861 | 1861 |
|
| 1862 |
- var lxcConf []KeyValuePair |
|
| 1863 | 1862 |
lxcConf, err := parseLxcConfOpts(flLxcOpts) |
| 1864 | 1863 |
if err != nil {
|
| 1865 | 1864 |
return nil, nil, cmd, err |
| 1866 | 1865 |
} |
| 1867 | 1866 |
|
| 1868 |
- hostname := *flHostname |
|
| 1869 |
- domainname := "" |
|
| 1870 |
- |
|
| 1871 |
- parts := strings.SplitN(hostname, ".", 2) |
|
| 1867 |
+ var ( |
|
| 1868 |
+ domainname string |
|
| 1869 |
+ hostname = *flHostname |
|
| 1870 |
+ parts = strings.SplitN(hostname, ".", 2) |
|
| 1871 |
+ ) |
|
| 1872 | 1872 |
if len(parts) > 1 {
|
| 1873 | 1873 |
hostname = parts[0] |
| 1874 | 1874 |
domainname = parts[1] |
| ... | ... |
@@ -209,11 +209,14 @@ func parseLxcOpt(opt string) (string, string, error) {
|
| 209 | 209 |
// We will receive port specs in the format of ip:public:private/proto and these need to be |
| 210 | 210 |
// parsed in the internal types |
| 211 | 211 |
func parsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding, error) {
|
| 212 |
- exposedPorts := make(map[Port]struct{}, len(ports))
|
|
| 213 |
- bindings := make(map[Port][]PortBinding) |
|
| 212 |
+ var ( |
|
| 213 |
+ exposedPorts = make(map[Port]struct{}, len(ports))
|
|
| 214 |
+ bindings = make(map[Port][]PortBinding) |
|
| 215 |
+ ) |
|
| 214 | 216 |
|
| 215 | 217 |
for _, rawPort := range ports {
|
| 216 | 218 |
proto := "tcp" |
| 219 |
+ |
|
| 217 | 220 |
if i := strings.LastIndex(rawPort, "/"); i != -1 {
|
| 218 | 221 |
proto = rawPort[i+1:] |
| 219 | 222 |
rawPort = rawPort[:i] |
| ... | ... |
@@ -228,9 +231,12 @@ func parsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding,
|
| 228 | 228 |
if err != nil {
|
| 229 | 229 |
return nil, nil, err |
| 230 | 230 |
} |
| 231 |
- containerPort := parts["containerPort"] |
|
| 232 |
- rawIp := parts["ip"] |
|
| 233 |
- hostPort := parts["hostPort"] |
|
| 231 |
+ |
|
| 232 |
+ var ( |
|
| 233 |
+ containerPort = parts["containerPort"] |
|
| 234 |
+ rawIp = parts["ip"] |
|
| 235 |
+ hostPort = parts["hostPort"] |
|
| 236 |
+ ) |
|
| 234 | 237 |
|
| 235 | 238 |
if containerPort == "" {
|
| 236 | 239 |
return nil, nil, fmt.Errorf("No port specified: %s<empty>", rawPort)
|
| ... | ... |
@@ -1237,12 +1237,14 @@ func IsClosedError(err error) bool {
|
| 1237 | 1237 |
|
| 1238 | 1238 |
func PartParser(template, data string) (map[string]string, error) {
|
| 1239 | 1239 |
// ip:public:private |
| 1240 |
- templateParts := strings.Split(template, ":") |
|
| 1241 |
- parts := strings.Split(data, ":") |
|
| 1240 |
+ var ( |
|
| 1241 |
+ templateParts = strings.Split(template, ":") |
|
| 1242 |
+ parts = strings.Split(data, ":") |
|
| 1243 |
+ out = make(map[string]string, len(templateParts)) |
|
| 1244 |
+ ) |
|
| 1242 | 1245 |
if len(parts) != len(templateParts) {
|
| 1243 | 1246 |
return nil, fmt.Errorf("Invalid format to parse. %s should match template %s", data, template)
|
| 1244 | 1247 |
} |
| 1245 |
- out := make(map[string]string, len(templateParts)) |
|
| 1246 | 1248 |
|
| 1247 | 1249 |
for i, t := range templateParts {
|
| 1248 | 1250 |
value := "" |