| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
"log" |
| 11 | 11 |
"net/http" |
| 12 | 12 |
"net/url" |
| 13 |
+ "path/filepath" |
|
| 13 | 14 |
"runtime" |
| 14 | 15 |
"strconv" |
| 15 | 16 |
"strings" |
| ... | ... |
@@ -913,6 +914,25 @@ func (opts AttachOpts) Get(val string) bool {
|
| 913 | 913 |
return false |
| 914 | 914 |
} |
| 915 | 915 |
|
| 916 |
+// PathOpts stores a unique set of absolute paths |
|
| 917 |
+type PathOpts map[string]struct{}
|
|
| 918 |
+ |
|
| 919 |
+func NewPathOpts() PathOpts {
|
|
| 920 |
+ return make(PathOpts) |
|
| 921 |
+} |
|
| 922 |
+ |
|
| 923 |
+func (opts PathOpts) String() string {
|
|
| 924 |
+ return fmt.Sprintf("%v", map[string]struct{}(opts))
|
|
| 925 |
+} |
|
| 926 |
+ |
|
| 927 |
+func (opts PathOpts) Set(val string) error {
|
|
| 928 |
+ if !filepath.IsAbs(val) {
|
|
| 929 |
+ return fmt.Errorf("%s is not an absolute path", val)
|
|
| 930 |
+ } |
|
| 931 |
+ opts[filepath.Clean(val)] = struct{}{}
|
|
| 932 |
+ return nil |
|
| 933 |
+} |
|
| 934 |
+ |
|
| 916 | 935 |
func (srv *Server) CmdTag(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
| 917 | 936 |
cmd := rcli.Subcmd(stdout, "tag", "[OPTIONS] IMAGE REPOSITORY [TAG]", "Tag an image into a repository") |
| 918 | 937 |
force := cmd.Bool("f", false, "Force")
|
| ... | ... |
@@ -66,6 +66,7 @@ type Config struct {
|
| 66 | 66 |
Cmd []string |
| 67 | 67 |
Dns []string |
| 68 | 68 |
Image string // Name of the image as it was passed by the operator (eg. could be symbolic) |
| 69 |
+ Volumes map[string]struct{}
|
|
| 69 | 70 |
} |
| 70 | 71 |
|
| 71 | 72 |
func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Config, error) {
|
| ... | ... |
@@ -97,6 +98,9 @@ func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Con |
| 97 | 97 |
var flDns ListOpts |
| 98 | 98 |
cmd.Var(&flDns, "dns", "Set custom dns servers") |
| 99 | 99 |
|
| 100 |
+ flVolumes := NewPathOpts() |
|
| 101 |
+ cmd.Var(flVolumes, "v", "Attach a data volume") |
|
| 102 |
+ |
|
| 100 | 103 |
if err := cmd.Parse(args); err != nil {
|
| 101 | 104 |
return nil, err |
| 102 | 105 |
} |
| ... | ... |
@@ -136,6 +140,7 @@ func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Con |
| 136 | 136 |
Cmd: runCmd, |
| 137 | 137 |
Dns: flDns, |
| 138 | 138 |
Image: image, |
| 139 |
+ Volumes: flVolumes, |
|
| 139 | 140 |
} |
| 140 | 141 |
|
| 141 | 142 |
if *flMemory > 0 && !capabilities.SwapLimit {
|
| ... | ... |
@@ -32,6 +32,7 @@ type Runtime struct {
|
| 32 | 32 |
capabilities *Capabilities |
| 33 | 33 |
kernelVersion *KernelVersionInfo |
| 34 | 34 |
autoRestart bool |
| 35 |
+ volumes *Graph |
|
| 35 | 36 |
} |
| 36 | 37 |
|
| 37 | 38 |
var sysInitPath string |
| ... | ... |
@@ -405,6 +406,10 @@ func NewRuntimeFromDirectory(root string, autoRestart bool) (*Runtime, error) {
|
| 405 | 405 |
if err != nil {
|
| 406 | 406 |
return nil, err |
| 407 | 407 |
} |
| 408 |
+ volumes, err := NewGraph(path.Join(root, "volumes")) |
|
| 409 |
+ if err != nil {
|
|
| 410 |
+ return nil, err |
|
| 411 |
+ } |
|
| 408 | 412 |
repositories, err := NewTagStore(path.Join(root, "repositories"), g) |
| 409 | 413 |
if err != nil {
|
| 410 | 414 |
return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
|
| ... | ... |
@@ -432,6 +437,7 @@ func NewRuntimeFromDirectory(root string, autoRestart bool) (*Runtime, error) {
|
| 432 | 432 |
idIndex: NewTruncIndex(), |
| 433 | 433 |
capabilities: &Capabilities{},
|
| 434 | 434 |
autoRestart: autoRestart, |
| 435 |
+ volumes: volumes, |
|
| 435 | 436 |
} |
| 436 | 437 |
|
| 437 | 438 |
if err := runtime.restore(); err != nil {
|