mirror of https://github.com/helm/helm
parent
f51170ed35
commit
dd4477d9b7
@ -0,0 +1,134 @@
|
|||||||
|
package kube
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/portforward"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
|
)
|
||||||
|
|
||||||
|
type tunnel interface {
|
||||||
|
Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tunnel struct {
|
||||||
|
name string
|
||||||
|
stopCh chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tunnel) Close() {
|
||||||
|
close(t.stopCh)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTunnel(c *Client, namespace, podName string) (*Tunnel, error) {
|
||||||
|
client, err := c.factory().Client()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := isPodRunning(client, namespace, podName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := c.factory().ClientConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req := client.RESTClient.Post().
|
||||||
|
Resource("pods").
|
||||||
|
Namespace(namespace).
|
||||||
|
Name(podName).
|
||||||
|
SubResource("portforward")
|
||||||
|
|
||||||
|
stopCh := make(chan struct{}, 1)
|
||||||
|
|
||||||
|
ports := []string{"44134"}
|
||||||
|
|
||||||
|
dialer, err := remotecommand.NewExecutor(config, "POST", req.URL())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fw, err := portforward.New(dialer, ports, stopCh)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
err = fw.ForwardPorts()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to forward ports %v on pod %s: %v\n", ports, podName, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return &Tunnel{stopCh: stopCh}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPodRunning(client *unversioned.Client, namespace, podName string) error {
|
||||||
|
pod, err := client.Pods(namespace).Get(podName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if pod.Status.Phase != api.PodRunning {
|
||||||
|
return fmt.Errorf("Unable to execute command because pod is not running. Current status=%v", pod.Status.Phase)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type portForwarder interface {
|
||||||
|
ForwardPorts(url *url.URL, config *restclient.Config, ports []string, stopChan <-chan struct{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type defaultPortForwarder struct{}
|
||||||
|
|
||||||
|
func (f *defaultPortForwarder) ForwardPorts(url *url.URL, config *restclient.Config, ports []string, stopChan <-chan struct{}) error {
|
||||||
|
dialer, err := remotecommand.NewExecutor(config, "POST", url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fw, err := portforward.New(dialer, ports, stopChan)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fw.ForwardPorts()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunPortForward(f *cmdutil.Factory, namespace, podName string, args []string, fw portForwarder) error {
|
||||||
|
|
||||||
|
client, err := f.Client()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := isPodRunning(client, namespace, podName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := f.ClientConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
signals := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(signals, os.Interrupt)
|
||||||
|
defer signal.Stop(signals)
|
||||||
|
|
||||||
|
stopCh := make(chan struct{}, 1)
|
||||||
|
go func() {
|
||||||
|
<-signals
|
||||||
|
close(stopCh)
|
||||||
|
}()
|
||||||
|
|
||||||
|
req := client.RESTClient.Post().
|
||||||
|
Resource("pods").
|
||||||
|
Namespace(namespace).
|
||||||
|
Name(pod.Name).
|
||||||
|
SubResource("portforward")
|
||||||
|
|
||||||
|
return fw.ForwardPorts(req.URL(), config, args, stopCh)
|
||||||
|
}
|
Loading…
Reference in new issue