1/* 2Copyright 2013 The Perkeep Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17// This file adds the "mount" subcommand to devcam, to run pk-mount against the dev server. 18 19package main 20 21import ( 22 "flag" 23 "fmt" 24 "os" 25 "os/exec" 26 "path/filepath" 27 "runtime" 28 "strconv" 29 "strings" 30 31 "perkeep.org/internal/osutil" 32 "perkeep.org/pkg/cmdmain" 33) 34 35type mountCmd struct { 36 // start of flag vars 37 altkey bool 38 path string 39 port string 40 tls bool 41 debug bool 42 // end of flag vars 43 44 env *Env 45} 46 47const mountpoint = "/tmp/pk-mount-dir" 48 49func init() { 50 cmdmain.RegisterMode("mount", func(flags *flag.FlagSet) cmdmain.CommandRunner { 51 cmd := &mountCmd{ 52 env: NewCopyEnv(), 53 } 54 flags.BoolVar(&cmd.altkey, "altkey", false, "Use different gpg key and password from the server's.") 55 flags.BoolVar(&cmd.tls, "tls", false, "Use TLS.") 56 flags.StringVar(&cmd.path, "path", "/", "Optional URL prefix path.") 57 flags.StringVar(&cmd.port, "port", "3179", "Port perkeep is listening on.") 58 flags.BoolVar(&cmd.debug, "debug", false, "print debugging messages.") 59 return cmd 60 }) 61} 62 63func (c *mountCmd) Usage() { 64 fmt.Fprintf(cmdmain.Stderr, "Usage: devcam mount [mount_opts] [<root-blobref>|<share URL>]\n") 65} 66 67func (c *mountCmd) Examples() []string { 68 return []string{ 69 "", 70 "http://localhost:3169/share/<blobref>", 71 } 72} 73 74func (c *mountCmd) Describe() string { 75 return "run pk-mount in dev mode." 76} 77 78func tryUnmount(dir string) error { 79 if runtime.GOOS == "darwin" { 80 return exec.Command("diskutil", "umount", "force", dir).Run() 81 } 82 return exec.Command("fusermount", "-u", dir).Run() 83} 84 85func (c *mountCmd) RunCommand(args []string) error { 86 err := c.checkFlags(args) 87 if err != nil { 88 return cmdmain.UsageError(fmt.Sprint(err)) 89 } 90 if !*noBuild { 91 if err := build(filepath.Join("cmd", "pk-mount")); err != nil { 92 return fmt.Errorf("Could not build pk-mount: %v", err) 93 } 94 } 95 c.env.SetCamdevVars(c.altkey) 96 // wipeCacheDir needs to be called after SetCamdevVars, because that is 97 // where CAMLI_CACHE_DIR is defined. 98 if *wipeCache { 99 c.env.wipeCacheDir() 100 } 101 102 tryUnmount(mountpoint) 103 if err := os.Mkdir(mountpoint, 0700); err != nil && !os.IsExist(err) { 104 return fmt.Errorf("Could not make mount point: %v", err) 105 } 106 107 blobserver := "http://localhost:" + c.port + c.path 108 if c.tls { 109 blobserver = strings.Replace(blobserver, "http://", "https://", 1) 110 } 111 112 cmdBin, err := osutil.LookPathGopath("pk-mount") 113 if err != nil { 114 return err 115 } 116 cmdArgs := []string{ 117 "-debug=" + strconv.FormatBool(c.debug), 118 "-server=" + blobserver, 119 } 120 cmdArgs = append(cmdArgs, args...) 121 cmdArgs = append(cmdArgs, mountpoint) 122 fmt.Printf("pk-mount running with mountpoint %v. Press 'q' <enter> or ctrl-c to shut down.\n", mountpoint) 123 return runExec(cmdBin, cmdArgs, c.env) 124} 125 126func (c *mountCmd) checkFlags(args []string) error { 127 if _, err := strconv.ParseInt(c.port, 0, 0); err != nil { 128 return fmt.Errorf("Invalid -port value: %q", c.port) 129 } 130 return nil 131} 132