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