github.com/dnephin/dobi@v0.15.0/tasks/mount/mount.go (about) 1 package mount 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 8 "github.com/dnephin/dobi/config" 9 "github.com/dnephin/dobi/logging" 10 "github.com/dnephin/dobi/tasks/context" 11 "github.com/dnephin/dobi/tasks/task" 12 "github.com/dnephin/dobi/tasks/types" 13 docker "github.com/fsouza/go-dockerclient" 14 ) 15 16 // Task is a mount task 17 type Task struct { 18 types.NoStop 19 name task.Name 20 config *config.MountConfig 21 run func(*Task, *context.ExecuteContext) (bool, error) 22 } 23 24 // Name returns the name of the task 25 func (t *Task) Name() task.Name { 26 return t.name 27 } 28 29 // Repr formats the task for logging 30 func (t *Task) Repr() string { 31 return fmt.Sprintf("%s %s:%s", t.name.Format("mount"), t.config.Bind, t.config.Path) 32 } 33 34 // Run performs the task action 35 func (t *Task) Run(ctx *context.ExecuteContext, _ bool) (bool, error) { 36 return t.run(t, ctx) 37 } 38 39 type createAction struct { 40 task *Task 41 } 42 43 // Run creates the host path if it doesn't already exist 44 func runCreate(task *Task, ctx *context.ExecuteContext) (bool, error) { 45 c := createAction{task: task} 46 return c.run(ctx) 47 } 48 49 func (t *createAction) run(ctx *context.ExecuteContext) (bool, error) { 50 logger := logging.ForTask(t.task) 51 52 if t.exists(ctx) { 53 logger.Debug("is fresh") 54 return false, nil 55 } 56 57 var err error 58 switch { 59 case t.task.config.IsBind(): 60 err = t.createBind(ctx) 61 default: 62 err = t.createNamed(ctx) 63 } 64 if err != nil { 65 return false, err 66 } 67 logger.Info("Created") 68 return true, nil 69 } 70 71 func (t *createAction) createBind(ctx *context.ExecuteContext) error { 72 path := AbsBindPath(t.task.config, ctx.WorkingDir) 73 mode := os.FileMode(t.task.config.Mode) 74 75 switch t.task.config.File { 76 case true: 77 return ioutil.WriteFile(path, []byte{}, mode) 78 default: 79 return os.MkdirAll(path, mode) 80 } 81 } 82 83 func (t *createAction) createNamed(ctx *context.ExecuteContext) error { 84 _, err := ctx.Client.CreateVolume(docker.CreateVolumeOptions{ 85 Name: t.task.config.Name, 86 }) 87 return err 88 } 89 90 func (t *createAction) exists(ctx *context.ExecuteContext) bool { 91 _, err := os.Stat(AbsBindPath(t.task.config, ctx.WorkingDir)) 92 return err == nil 93 } 94 95 func remove(task *Task, ctx *context.ExecuteContext) (bool, error) { 96 if task.config.Name == "" { 97 logging.ForTask(task).Warn("Bind mounts are not removable") 98 return false, nil 99 } 100 101 return true, ctx.Client.RemoveVolume(task.config.Name) 102 }