github.com/mirantis/virtlet@v1.5.2-0.20191204181327-1659b8a48e9b/pkg/tools/install.go (about) 1 /* 2 Copyright 2018 Mirantis 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package tools 18 19 import ( 20 "errors" 21 "fmt" 22 "io" 23 "io/ioutil" 24 "os" 25 "path/filepath" 26 27 "github.com/renstrom/dedent" 28 "github.com/spf13/cobra" 29 "k8s.io/client-go/util/homedir" 30 ) 31 32 const ( 33 pluginName = "virt" 34 ) 35 36 // installCommand is used to install virtletctl as a kubectl plugin. 37 type installCommand struct { 38 rootCmd *cobra.Command 39 executablePath string 40 homeDir string 41 } 42 43 // NewInstallCmd returns a cobra.Command that installs virtletctl as a kubectl plugin. 44 func NewInstallCmd(rootCmd *cobra.Command, executablePath, homeDir string) *cobra.Command { 45 install := &installCommand{ 46 rootCmd: rootCmd, 47 executablePath: executablePath, 48 homeDir: homeDir, 49 } 50 return &cobra.Command{ 51 Use: "install", 52 Short: "Install virtletctl as a kubectl plugin", 53 Long: dedent.Dedent(` 54 This command install virtletctl as a kubectl plugin. 55 56 After running this command, it becomes possible to run virtletctl 57 via 'kubectl plugin virt'.`), 58 RunE: func(cmd *cobra.Command, args []string) error { 59 if len(args) != 0 { 60 return errors.New("This command does not accept arguments") 61 } 62 return install.Run() 63 }, 64 } 65 } 66 67 // Run executes the command. 68 func (inst *installCommand) Run() error { 69 if inst.executablePath == "" { 70 var err error 71 inst.executablePath, err = os.Executable() 72 if err != nil { 73 return fmt.Errorf("can't get executable path: %v", err) 74 } 75 } 76 if inst.homeDir == "" { 77 inst.homeDir = homedir.HomeDir() 78 } 79 oldUse := inst.rootCmd.Use 80 inst.rootCmd.Use = pluginName 81 defer func() { 82 inst.rootCmd.Use = oldUse 83 }() 84 85 pluginDir := filepath.Join(inst.homeDir, ".kube", "plugins", inst.rootCmd.Name()) 86 if err := os.MkdirAll(pluginDir, 0755); err != nil { 87 return fmt.Errorf("MkdirAll(): %v", err) 88 } 89 90 srcPath := filepath.Clean(inst.executablePath) 91 src, err := os.Open(srcPath) 92 if err != nil { 93 return fmt.Errorf("read opening virtletctl executable file %q: %v", srcPath, err) 94 } 95 defer src.Close() 96 97 dstPath := filepath.Join(pluginDir, inst.rootCmd.Name()) 98 dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) 99 if err != nil { 100 return fmt.Errorf("error creating kubectl plugin binary file %q: %v", dstPath, err) 101 } 102 defer dst.Close() 103 if _, err := io.Copy(dst, src); err != nil { 104 return fmt.Errorf("error copying virtletctl: %q -> %q: %v", srcPath, dstPath, err) 105 } 106 107 pluginYaml := pluginYamlFromCobraCommand(inst.rootCmd) 108 pluginYamlPath := filepath.Join(pluginDir, "plugin.yaml") 109 if err := ioutil.WriteFile(pluginYamlPath, pluginYaml, 0644); err != nil { 110 return fmt.Errorf("error writing plugin.yaml: %v", err) 111 } 112 113 return nil 114 }