@@ -2,9 +2,13 @@ package drivers
22
33import (
44 "errors"
5+ "context"
6+ "strings"
7+
58 log "github.com/sirupsen/logrus"
69 "github.com/docker/go-plugins-helpers/volume"
7- "strings"
10+ "github.com/docker/docker/client"
11+ "github.com/docker/docker/api/types"
812)
913
1014const (
@@ -20,30 +24,30 @@ type mount struct {
2024 managed bool
2125}
2226
23- type mountManager struct {
27+ type MountManager struct {
2428 mounts map [string ]* mount
2529}
2630
27- func NewVolumeManager () * mountManager {
28- return & mountManager {
31+ func NewVolumeManager () * MountManager {
32+ return & MountManager {
2933 mounts : map [string ]* mount {},
3034 }
3135}
3236
33- func (m * mountManager ) HasMount (name string ) bool {
37+ func (m * MountManager ) HasMount (name string ) bool {
3438 _ , found := m .mounts [name ]
3539 return found
3640}
3741
38- func (m * mountManager ) HasOptions (name string ) bool {
42+ func (m * MountManager ) HasOptions (name string ) bool {
3943 c , found := m .mounts [name ]
4044 if found {
4145 return c .opts != nil && len (c .opts ) > 0
4246 }
4347 return false
4448}
4549
46- func (m * mountManager ) HasOption (name , key string ) bool {
50+ func (m * MountManager ) HasOption (name , key string ) bool {
4751 if m .HasOptions (name ) {
4852 if _ , ok := m .mounts [name ].opts [key ]; ok {
4953 return ok
@@ -52,44 +56,44 @@ func (m *mountManager) HasOption(name, key string) bool {
5256 return false
5357}
5458
55- func (m * mountManager ) GetOptions (name string ) map [string ]string {
59+ func (m * MountManager ) GetOptions (name string ) map [string ]string {
5660 if m .HasOptions (name ) {
5761 c , _ := m .mounts [name ]
5862 return c .opts
5963 }
6064 return map [string ]string {}
6165}
6266
63- func (m * mountManager ) GetOption (name , key string ) string {
67+ func (m * MountManager ) GetOption (name , key string ) string {
6468 if m .HasOption (name , key ) {
6569 v , _ := m .mounts [name ].opts [key ]
6670 return v
6771 }
6872 return ""
6973}
7074
71- func (m * mountManager ) GetOptionAsBool (name , key string ) bool {
75+ func (m * MountManager ) GetOptionAsBool (name , key string ) bool {
7276 rv := strings .ToLower (m .GetOption (name , key ))
7377 if rv == "yes" || rv == "true" {
7478 return true
7579 }
7680 return false
7781}
7882
79- func (m * mountManager ) IsActiveMount (name string ) bool {
83+ func (m * MountManager ) IsActiveMount (name string ) bool {
8084 c , found := m .mounts [name ]
8185 return found && c .connections > 0
8286}
8387
84- func (m * mountManager ) Count (name string ) int {
88+ func (m * MountManager ) Count (name string ) int {
8589 c , found := m .mounts [name ]
8690 if found {
8791 return c .connections
8892 }
8993 return 0
9094}
9195
92- func (m * mountManager ) Add (name , hostdir string ) {
96+ func (m * MountManager ) Add (name , hostdir string ) {
9397 _ , found := m .mounts [name ]
9498 if found {
9599 m .Increment (name )
@@ -98,7 +102,7 @@ func (m *mountManager) Add(name, hostdir string) {
98102 }
99103}
100104
101- func (m * mountManager ) Create (name , hostdir string , opts map [string ]string ) * mount {
105+ func (m * MountManager ) Create (name , hostdir string , opts map [string ]string ) * mount {
102106 c , found := m .mounts [name ]
103107 if found && c .connections > 0 {
104108 c .opts = opts
@@ -110,10 +114,13 @@ func (m *mountManager) Create(name, hostdir string, opts map[string]string) *mou
110114 }
111115}
112116
113- func (m * mountManager ) Delete (name string ) error {
114- log .Debugf ("Delete volume: %s, connections: %d" , name , m .Count (name ))
117+ func (m * MountManager ) Delete (name string ) error {
118+ // Check if any stopped containers are having references with volume.
119+ refCount := checkReferences (name )
120+ log .Debugf ("Reference count %d" , refCount )
115121 if m .HasMount (name ) {
116- if m .Count (name ) < 1 {
122+ if m .Count (name ) < 1 && refCount < 1 {
123+ log .Debugf ("Delete volume: %s, connections: %d" , name , m .Count (name ))
117124 delete (m .mounts , name )
118125 return nil
119126 }
@@ -122,32 +129,38 @@ func (m *mountManager) Delete(name string) error {
122129 return nil
123130}
124131
125- func (m * mountManager ) DeleteIfNotManaged (name string ) error {
132+ func (m * MountManager ) DeleteIfNotManaged (name string ) error {
126133 if m .HasMount (name ) && ! m .IsActiveMount (name ) && ! m .mounts [name ].managed {
127134 log .Infof ("Removing un-managed volume" )
128135 return m .Delete (name )
129136 }
130137 return nil
131138}
132139
133- func (m * mountManager ) Increment (name string ) int {
140+ func (m * MountManager ) Increment (name string ) int {
141+ log .Infof ("Incrementing for %s" , name )
134142 c , found := m .mounts [name ]
143+ log .Infof ("Previous connections state : %d" , c .connections )
135144 if found {
136145 c .connections ++
146+ log .Infof ("Current connections state : %d" , c .connections )
137147 return c .connections
138148 }
139149 return 0
140150}
141151
142- func (m * mountManager ) Decrement (name string ) int {
152+ func (m * MountManager ) Decrement (name string ) int {
153+ log .Infof ("Decrementing for %s" , name )
143154 c , found := m .mounts [name ]
155+ log .Infof ("Previous connections state : %d" , c .connections )
144156 if found && c .connections > 0 {
145157 c .connections --
158+ log .Infof ("Current connections state : %d" , c .connections )
146159 }
147160 return 0
148161}
149162
150- func (m * mountManager ) GetVolumes (rootPath string ) []* volume.Volume {
163+ func (m * MountManager ) GetVolumes (rootPath string ) []* volume.Volume {
151164
152165 volumes := []* volume.Volume {}
153166
@@ -156,3 +169,35 @@ func (m *mountManager) GetVolumes(rootPath string) []*volume.Volume {
156169 }
157170 return volumes
158171}
172+
173+ func (m * MountManager ) AddMount (name string , hostdir string , connections int ) {
174+ m .mounts [name ] = & mount {name : name , hostdir : hostdir , managed : true , connections : connections }
175+ }
176+
177+ //Checking volume references with started and stopped containers as well.
178+ func checkReferences (volumeName string ) int {
179+
180+ cli , err := client .NewEnvClient ()
181+ if err != nil {
182+ log .Error (err )
183+ }
184+
185+ var counter = 0
186+ ContainerListResponse , err := cli .ContainerList (context .Background (), types.ContainerListOptions {All : true }) // All : true will return the stopped containers as well.
187+ if err != nil {
188+ log .Fatal (err ,". Use -a flag to setup the DOCKER_API_VERSION. Run 'docker-volume-netshare --help' for usage." )
189+ }
190+
191+ for _ , container := range ContainerListResponse {
192+ if len (container .Mounts ) == 0 {
193+ continue
194+ }
195+ for _ , mounts := range container .Mounts {
196+ if ! (mounts .Name == volumeName ) {
197+ continue
198+ }
199+ counter ++
200+ }
201+ }
202+ return counter
203+ }
0 commit comments