github.com/vmware/govmomi@v0.43.0/govc/vm/console.go (about) 1 /* 2 Copyright (c) 2017 VMware, Inc. All Rights Reserved. 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 vm 18 19 import ( 20 "context" 21 "flag" 22 "fmt" 23 "io" 24 "net/url" 25 "os" 26 27 "github.com/vmware/govmomi/govc/cli" 28 "github.com/vmware/govmomi/govc/flags" 29 "github.com/vmware/govmomi/object" 30 "github.com/vmware/govmomi/session" 31 "github.com/vmware/govmomi/vim25/soap" 32 "github.com/vmware/govmomi/vim25/types" 33 ) 34 35 type console struct { 36 *flags.VirtualMachineFlag 37 38 h5 bool 39 wss bool 40 capture string 41 } 42 43 func init() { 44 cli.Register("vm.console", &console{}) 45 } 46 47 func (cmd *console) Register(ctx context.Context, f *flag.FlagSet) { 48 cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) 49 cmd.VirtualMachineFlag.Register(ctx, f) 50 51 f.BoolVar(&cmd.h5, "h5", false, "Generate HTML5 UI console link") 52 f.BoolVar(&cmd.wss, "wss", false, "Generate WebSocket console link") 53 f.StringVar(&cmd.capture, "capture", "", "Capture console screen shot to file") 54 } 55 56 func (cmd *console) Process(ctx context.Context) error { 57 if err := cmd.VirtualMachineFlag.Process(ctx); err != nil { 58 return err 59 } 60 return nil 61 } 62 63 func (cmd *console) Usage() string { 64 return "VM" 65 } 66 67 func (cmd *console) Description() string { 68 return `Generate console URL or screen capture for VM. 69 70 One of VMRC, VMware Player, VMware Fusion or VMware Workstation must be installed to 71 open VMRC console URLs. 72 73 Examples: 74 govc vm.console my-vm 75 govc vm.console -capture screen.png my-vm # screen capture 76 govc vm.console -capture - my-vm | display # screen capture to stdout 77 open $(govc vm.console my-vm) # MacOSX VMRC 78 open $(govc vm.console -h5 my-vm) # MacOSX H5 79 xdg-open $(govc vm.console my-vm) # Linux VMRC 80 xdg-open $(govc vm.console -h5 my-vm) # Linux H5` 81 } 82 83 func (cmd *console) Run(ctx context.Context, f *flag.FlagSet) error { 84 vms, err := cmd.VirtualMachines(f.Args()) 85 if err != nil { 86 return err 87 } 88 89 if len(vms) != 1 { 90 return flag.ErrHelp 91 } 92 93 vm := vms[0] 94 95 state, err := vm.PowerState(ctx) 96 if err != nil { 97 return err 98 } 99 100 if (cmd.capture != "" || cmd.wss) && state != types.VirtualMachinePowerStatePoweredOn { 101 return fmt.Errorf("vm is not powered on (%s)", state) 102 } 103 104 c := vm.Client() 105 106 u := c.URL() 107 108 if cmd.capture != "" { 109 u.Path = "/screen" 110 query := url.Values{"id": []string{vm.Reference().Value}} 111 u.RawQuery = query.Encode() 112 113 param := soap.DefaultDownload 114 115 if cmd.capture == "-" { 116 w, _, derr := c.Download(ctx, u, ¶m) 117 if derr != nil { 118 return derr 119 } 120 121 _, err = io.Copy(os.Stdout, w) 122 if err != nil { 123 return err 124 } 125 126 return w.Close() 127 } 128 129 return c.DownloadFile(ctx, cmd.capture, u, ¶m) 130 } 131 132 if cmd.wss { 133 ticket, err := vm.AcquireTicket(ctx, string(types.VirtualMachineTicketTypeWebmks)) 134 if err != nil { 135 return err 136 } 137 138 link := fmt.Sprintf("wss://%s:%d/ticket/%s", ticket.Host, ticket.Port, ticket.Ticket) 139 fmt.Fprintln(cmd.Out, link) 140 return nil 141 } 142 143 m := session.NewManager(c) 144 ticket, err := m.AcquireCloneTicket(ctx) 145 if err != nil { 146 return err 147 } 148 149 var link string 150 151 if cmd.h5 { 152 m := object.NewOptionManager(c, *c.ServiceContent.Setting) 153 154 opt, err := m.Query(ctx, "VirtualCenter.FQDN") 155 if err != nil { 156 return err 157 } 158 159 fqdn := opt[0].GetOptionValue().Value.(string) 160 161 var info object.HostCertificateInfo 162 err = info.FromURL(u, nil) 163 if err != nil { 164 return err 165 } 166 167 u.Path = "/ui/webconsole.html" 168 169 u.RawQuery = url.Values{ 170 "vmId": []string{vm.Reference().Value}, 171 "vmName": []string{vm.Name()}, 172 "serverGuid": []string{c.ServiceContent.About.InstanceUuid}, 173 "host": []string{fqdn}, 174 "sessionTicket": []string{ticket}, 175 "thumbprint": []string{info.ThumbprintSHA1}, 176 }.Encode() 177 178 link = u.String() 179 } else { 180 link = fmt.Sprintf("vmrc://clone:%s@%s/?moid=%s", ticket, u.Hostname(), vm.Reference().Value) 181 } 182 183 fmt.Fprintln(cmd.Out, link) 184 185 return nil 186 }