func (d *RcloneDriver) Remove(r *volume.RemoveRequest) error {
	log.Debug().Msgf("Entering Remove: name: %s", r.Name)
	d.Lock()
	defer d.Unlock()
	v, ok := d.volumes[r.Name]
	if !ok {
		return fmt.Errorf("volume %s not found", r.Name)
	}
	log.Debug().Msgf("Volume found: %v", v)
	m, ok := d.mounts[v.Mount]
	if !ok {
		return fmt.Errorf("volume mount %s not found for %s", v.Mount, r.Name)
	}
	log.Debug().Msgf("Mount found: %v", m)
	mounted, err := m.isMounted()
	if err != nil {
		return err
	}
	if mounted {  
		if _, err := d.runCmd(fmt.Sprintf(`umount -l "%s"`, m.Path)); err != nil {
			time.Sleep(15 * time.Second)  
			if _, err := d.runCmd(fmt.Sprintf(`umount -f "%s"`, m.Path)); err != nil {
				return err
			}
		}
		if m.Context != nil {
			m.Context.Done()
		}
	}
	if _, err := os.Stat(m.Path); !os.IsNotExist(err) {
		if err := os.Remove(m.Path); err != nil {
			return err
		}
	}
	delete(d.mounts, v.Mount)
	delete(d.volumes, r.Name)
	return d.saveConfig()
}
Remove remove the requested volume
package driver
import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
	"github.com/docker/go-plugins-helpers/volume"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"github.com/spf13/viper"
	"github.com/sapk/docker-volume-helpers/tools"
)
var (
	MountTimeout = 30
	CfgVersion = 1
	CfgFolder = "/etc/docker-volumes/rclone/"
)
type rcloneMountpoint struct {
	Path        string          `json:"path"`
	Connections int             `json:"connections"`
	Context     context.Context `json:"-"`
}
func (m *rcloneMountpoint) isMounted() (bool, error) {
	buf, err := ioutil.ReadFile("/proc/mounts")
	if err != nil {
		return false, err
	}
	log.Debug().Msgf("isMounted Path: path: %s %v", m.Path, strings.Contains(string(buf), " "+m.Path+" fuse.rclone"))
	return strings.Contains(string(buf), " "+m.Path+" fuse.rclone"), nil
}
type rcloneVolume struct {
	Config      string `json:"config"`
	Args        string `json:"args"`
	Remote      string `json:"remote"`
	Mount       string `json:"mount"`
	Connections int    `json:"connections"`
	CreatedAt   string `json:"created_at"`
}
type RcloneDriver struct {
	sync.RWMutex
	root       string
	persitence *viper.Viper
	volumes    map[string]*rcloneVolume
	mounts     map[string]*rcloneMountpoint
}
func Init(root string) *RcloneDriver {
	d := &RcloneDriver{
		root:       root,
		persitence: viper.New(),
		volumes:    make(map[string]*rcloneVolume),
		mounts:     make(map[string]*rcloneMountpoint),
	}
	d.persitence.SetDefault("volumes", map[string]*rcloneVolume{})
	d.persitence.SetConfigName("persistence")
	d.persitence.SetConfigType("json")
	d.persitence.AddConfigPath(CfgFolder)
	if err := d.persitence.ReadInConfig(); err != nil {  
		log.Warn().Err(err).Msg("No persistence file found, I will start with a empty list of volume")
	} else {
		log.Debug().Msg("Retrieving volume list from persistence file.")
		var version int
		err := d.persitence.UnmarshalKey("version", &version)
		if err != nil || version != CfgVersion {
			log.Warn().Err(err).Msg("Unable to decode version of persistence")
			d.volumes = make(map[string]*rcloneVolume)
			d.mounts = make(map[string]*rcloneMountpoint)
		} else {  
			err := d.persitence.UnmarshalKey("volumes", &d.volumes)
			if err != nil {
				log.Warn().Err(err).Msg("Unable to decode into struct -> start with empty list")
				d.volumes = make(map[string]*rcloneVolume)
			}
			err = d.persitence.UnmarshalKey("mounts", &d.mounts)
			if err != nil {
				log.Warn().Err(err).Msg("Unable to decode into struct -> start with empty list")
				d.mounts = make(map[string]*rcloneMountpoint)
			}
		}
	}
	return d
}
func (d *RcloneDriver) Create(r *volume.CreateRequest) error {
	log.Debug().Msgf("Entering Create: name: %s, options %v", r.Name, r.Options)
	d.Lock()
	defer d.Unlock()
	if r.Options == nil || r.Options["config"] == "" || r.Options["remote"] == "" {
		return fmt.Errorf("config and remote option required")
	}
	v := &rcloneVolume{
		Config:      r.Options["config"],
		Remote:      r.Options["remote"],
		Args:        r.Options["args"],
		Mount:       GetMountName(d, r),
		Connections: 0,
		CreatedAt:   time.Now().Format(time.RFC3339),
	}
	if _, ok := d.mounts[v.Mount]; !ok {  
		m := &rcloneMountpoint{
			Path:        filepath.Join(d.root, v.Mount),
			Connections: 0,
		}
		_, err := os.Lstat(m.Path)  
		if os.IsNotExist(err) {
			if err = os.MkdirAll(m.Path, 0700); err != nil {
				return err
			}
		} else if err != nil {
			return err
		}
		isempty, err := tools.FolderIsEmpty(m.Path)
		if err != nil {
			return err
		}
		if !isempty {
			return fmt.Errorf("%v already exist and is not empty", m.Path)
		}
		d.mounts[v.Mount] = m
	}
	d.volumes[r.Name] = v
	log.Debug().Msgf("Volume Created: %v", v)
	return d.saveConfig()
}
func (d *RcloneDriver) List() (*volume.ListResponse, error) {
	log.Debug().Msgf("Entering List")
	d.Lock()
	defer d.Unlock()
	var vols []*volume.Volume
	for name, v := range d.volumes {
		log.Debug().Msgf("Volume found: %v", v)
		m, ok := d.mounts[v.Mount]
		if !ok {
			return nil, fmt.Errorf("volume mount %s not found for %s", v.Mount, v.Remote)
		}
		log.Debug().Msgf("Mount found: %v", m)
		vols = append(vols, &volume.Volume{Name: name, Mountpoint: m.Path, CreatedAt: v.CreatedAt})
	}
	return &volume.ListResponse{Volumes: vols}, nil
}
func (d *RcloneDriver) Get(r *volume.GetRequest) (*volume.GetResponse, error) {
	log.Debug().Msgf("Entering Get: name: %s", r.Name)
	d.Lock()
	defer d.Unlock()
	v, ok := d.volumes[r.Name]
	if !ok {
		return nil, fmt.Errorf("volume %s not found", r.Name)
	}
	log.Debug().Msgf("Volume found: %v", v)
	m, ok := d.mounts[v.Mount]
	if !ok {
		return nil, fmt.Errorf("volume mount %s not found for %s", v.Mount, r.Name)
	}
	log.Debug().Msgf("Mount found: %v", m)
	return &volume.GetResponse{Volume: &volume.Volume{Name: r.Name, Mountpoint: m.Path, CreatedAt: v.CreatedAt}}, nil
}