New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move SPICE part from kubectl.sh to own spice.go package #201
Conversation
Can one of the admins verify this patch? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for you contribution. 🍰
I added a few notes on how to better leverege the kubernetes SDK.
Also don't forget to call this code when cluster/kubectl.sh console
is invoked.
pkg/virtctl/spice/spice.go
Outdated
if details { | ||
fmt.Printf("%s", body) | ||
} else { | ||
f, err := os.Create(SPICE_FILENAME) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can improve that a little bit and write it into a temp file which we delete after we are done:
file, err := ioutil.TempFile(os.TempDir(), "console.vv")
defer os.Remove(file.Name())
pkg/virtctl/spice/spice.go
Outdated
|
||
func DownloadSpice(vm, host string) (string, error) { | ||
var path string = fmt.Sprintf(VM_SPICE_URL, host, vm) | ||
req, err := http.NewRequest("GET", path, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use the rest client from kubernetes here:
body, err := restClient.Get().
Resource("vms").SetHeader("Accept", rest.MIME_INI).
SubResource("spice").
Namespace(kubev1.NamespaceDefault).
Name(vm.GetObjectMeta().GetName()).Do().Raw()
You can get a rest client which understands the VM TPR like this:
restClient, err := kubecli.GetRESTClientFromFlags(master, kubeconfig)
This also allows us to reuse the authentication information from kubeconfig.
pkg/virtctl/spice/spice.go
Outdated
} | ||
|
||
func (o *Spice) Usage() string { | ||
usage := "The following options can be passed to any command:\n\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here some usage examples like in virtctl/console/console.go
would be nice here.
pkg/virtctl/spice/spice.go
Outdated
} | ||
vm := flags.Arg(1) | ||
|
||
config, err := clientcmd.BuildConfigFromFlags(server, kubeconfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you can dreate the rest client instead and directly use it.
5a76ec9
to
2b7b08d
Compare
@rmohr fixed comments, please review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there
pkg/virtctl/spice/spice.go
Outdated
log.Fatalf("Can't open file: %s", err.Error()) | ||
return 1 | ||
} | ||
defer f.Close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here we would need a defer os.Remove(f.Name())
too, otherwise the file stays if we return early
pkg/virtctl/spice/spice.go
Outdated
f.Sync() | ||
|
||
cmnd := exec.Command("remote-viewer", f.Name()) | ||
cmnd.Run() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line returns an error, we have to check for it, to return the correct exit code
pkg/virtctl/spice/spice.go
Outdated
|
||
const FLAG = "spice" | ||
const SPICE_FILENAME = "console.vv" | ||
const VM_SPICE_URL = "http://%s/apis/kubevirt.io/v1alpha1/namespaces/default/vms/%s/spice" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That one can be removed
pkg/virtctl/spice/spice.go
Outdated
} | ||
|
||
func (o *Spice) Usage() string { | ||
usage := "Usage: ./virtctl spice vm_name [--details] [common_options]\n\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you give real examples of the usage here? For instance kubectl exec --help gives:
Execute a command in a container.
Examples:
# Get output from running 'date' from pod 123456-7890, using the first container by default
kubectl exec 123456-7890 date
# Get output from running 'date' in ruby-container from pod 123456-7890
kubectl exec 123456-7890 -c ruby-container date
# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890
# and sends stdout/stderr from 'bash' back to the client
kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il
Options:
-c, --container='': Container name. If omitted, the first container in the pod will be chosen
-p, --pod='': Pod name
-i, --stdin=false: Pass stdin to the container
-t, --tty=false: Stdin is a TTY
Usage:
kubectl exec POD [-c CONTAINER] -- COMMAND [args...] [options]
Maybe
Fetch SPICE connections details of a VM and connect via remote-viewer
Examples:
#Show connection details of the VM myvm
virtctl spice myvm --details
# Open a SPICE connection to the VM myvm via remote-viewer
virtctl spice myvm
Options:
The rest will be added by o.FlagSet.FlagUsages()
pkg/virtctl/spice/spice.go
Outdated
} | ||
|
||
func (o *Spice) Usage() string { | ||
usage := "Usage: ./virtctl spice vm_name [--details] [common_options]\n\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
o.FlagSet.FlagUsages()
adds options and the usage for you
4e8c43c
to
0c01246
Compare
Fixed @rmohr please review |
pkg/virtctl/spice/spice.go
Outdated
|
||
cmnd := exec.Command("remote-viewer", f.Name()) | ||
err = cmnd.Run() | ||
defer os.Remove(f.Name()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This defer is too late, it needs to be directly after defer f.Close()
, the rest looks good to me :)
@rmohr fixed =) |
Ups, I suggested the wrong defer order. It is a stack, so we need defer os.Remove(f.Name())
defer f.Close() Also see https://tour.golang.org/flowcontrol/13 for a nice example. |
Fixed @rmohr |
Thx! 👍 |
exit 1 on user abort
MAINTAINERS: add Tom Denham and Gabe Rosenhouse
#181
@rmohr Please review