| package volumes |
| |
| import ( |
| "encoding/json" |
| "io/ioutil" |
| "os" |
| "path/filepath" |
| "sync" |
| |
| "github.com/docker/docker/pkg/symlink" |
| ) |
| |
| type Volume struct { |
| ID string |
| Path string |
| IsBindMount bool |
| Writable bool |
| containers map[string]struct{} |
| configPath string |
| repository *Repository |
| lock sync.Mutex |
| } |
| |
| func (v *Volume) IsDir() (bool, error) { |
| stat, err := os.Stat(v.Path) |
| if err != nil { |
| return false, err |
| } |
| |
| return stat.IsDir(), nil |
| } |
| |
| func (v *Volume) Containers() []string { |
| v.lock.Lock() |
| |
| var containers []string |
| for c := range v.containers { |
| containers = append(containers, c) |
| } |
| |
| v.lock.Unlock() |
| return containers |
| } |
| |
| func (v *Volume) RemoveContainer(containerId string) { |
| v.lock.Lock() |
| delete(v.containers, containerId) |
| v.lock.Unlock() |
| } |
| |
| func (v *Volume) AddContainer(containerId string) { |
| v.lock.Lock() |
| v.containers[containerId] = struct{}{} |
| v.lock.Unlock() |
| } |
| |
| func (v *Volume) createIfNotExist() error { |
| if stat, err := os.Stat(v.Path); err != nil && os.IsNotExist(err) { |
| if stat.IsDir() { |
| os.MkdirAll(v.Path, 0755) |
| } |
| |
| if err := os.MkdirAll(filepath.Dir(v.Path), 0755); err != nil { |
| return err |
| } |
| f, err := os.OpenFile(v.Path, os.O_CREATE, 0755) |
| if err != nil { |
| return err |
| } |
| f.Close() |
| } |
| return nil |
| } |
| |
| func (v *Volume) initialize() error { |
| v.lock.Lock() |
| defer v.lock.Unlock() |
| |
| if err := v.createIfNotExist(); err != nil { |
| return err |
| } |
| |
| if err := os.MkdirAll(v.configPath, 0755); err != nil { |
| return err |
| } |
| jsonPath, err := v.jsonPath() |
| if err != nil { |
| return err |
| } |
| f, err := os.Create(jsonPath) |
| if err != nil { |
| return err |
| } |
| defer f.Close() |
| |
| return v.toDisk() |
| } |
| |
| func (v *Volume) ToDisk() error { |
| v.lock.Lock() |
| defer v.lock.Unlock() |
| return v.toDisk() |
| } |
| func (v *Volume) toDisk() error { |
| data, err := json.Marshal(v) |
| if err != nil { |
| return err |
| } |
| |
| pth, err := v.jsonPath() |
| if err != nil { |
| return err |
| } |
| |
| return ioutil.WriteFile(pth, data, 0666) |
| } |
| func (v *Volume) FromDisk() error { |
| v.lock.Lock() |
| defer v.lock.Unlock() |
| pth, err := v.jsonPath() |
| if err != nil { |
| return err |
| } |
| |
| data, err := ioutil.ReadFile(pth) |
| if err != nil { |
| return err |
| } |
| |
| return json.Unmarshal(data, v) |
| } |
| |
| func (v *Volume) jsonPath() (string, error) { |
| return v.getRootResourcePath("config.json") |
| } |
| func (v *Volume) getRootResourcePath(path string) (string, error) { |
| cleanPath := filepath.Join("/", path) |
| return symlink.FollowSymlinkInScope(filepath.Join(v.configPath, cleanPath), v.configPath) |
| } |