mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-11-02 11:34:28 +08:00
feat: optimize code
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
defaultlog "log"
|
||||
"net/http"
|
||||
@@ -20,8 +19,8 @@ import (
|
||||
)
|
||||
|
||||
func CmdConnect(f cmdutil.Factory) *cobra.Command {
|
||||
var connect = handler.ConnectOptions{}
|
||||
var sshConf = util.SshConfig{}
|
||||
var connect = &handler.ConnectOptions{}
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "connect",
|
||||
Short: i18n.T("Connect to kubernetes cluster network, or proxy kubernetes workloads inbound traffic into local PC"),
|
||||
@@ -58,11 +57,7 @@ func CmdConnect(f cmdutil.Factory) *cobra.Command {
|
||||
log.Errorln(err)
|
||||
handler.Cleanup(syscall.SIGQUIT)
|
||||
} else {
|
||||
fmt.Println()
|
||||
fmt.Println(`---------------------------------------------------------------------------`)
|
||||
fmt.Println(` Now you can access resources in the kubernetes cluster, enjoy it :) `)
|
||||
fmt.Println(`---------------------------------------------------------------------------`)
|
||||
fmt.Println()
|
||||
util.Print(os.Stdout, "Now you can access resources in the kubernetes cluster, enjoy it :)")
|
||||
}
|
||||
select {}
|
||||
},
|
||||
@@ -70,11 +65,6 @@ func CmdConnect(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().BoolVar(&config.Debug, "debug", false, "enable debug mode or not, true or false")
|
||||
cmd.Flags().StringVar(&config.Image, "image", config.Image, "use this image to startup container")
|
||||
|
||||
// for ssh jumper host
|
||||
cmd.Flags().StringVar(&sshConf.Addr, "ssh-addr", "", "Optional ssh jump server address to dial as <hostname>:<port>, eg: 127.0.0.1:22")
|
||||
cmd.Flags().StringVar(&sshConf.User, "ssh-username", "", "Optional username for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Password, "ssh-password", "", "Optional password for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Keyfile, "ssh-keyfile", "", "Optional file with private key for SSH authentication")
|
||||
cmd.Flags().StringVar(&sshConf.ConfigAlias, "ssh-alias", "", "Optional config alias with ~/.ssh/config for SSH authentication")
|
||||
addSshFlag(cmd, sshConf)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ var cpExample = templates.Examples(i18n.T(`
|
||||
kubectl cp <some-namespace>/<some-pod>:/tmp/foo /tmp/bar
|
||||
|
||||
# copy reverse proxy api-server behind of bastion host or ssh jump host
|
||||
kubevpn dev deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile /Users/naison/.ssh/ssh.pem
|
||||
kubevpn cp deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile /Users/naison/.ssh/ssh.pem
|
||||
|
||||
# it also support ProxyJump, like
|
||||
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────────┐
|
||||
@@ -60,7 +60,7 @@ func CmdCp(f cmdutil.Factory) *cobra.Command {
|
||||
Out: os.Stdout,
|
||||
ErrOut: os.Stderr,
|
||||
})
|
||||
var sshConf = util.SshConfig{}
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "cp <file-spec-src> <file-spec-dest>",
|
||||
DisableFlagsInUseLine: true,
|
||||
|
||||
@@ -34,7 +34,7 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
||||
ExtraHosts: opts.NewListOpts(nil),
|
||||
NoProxy: false,
|
||||
}
|
||||
var sshConf = util.SshConfig{}
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "dev",
|
||||
Short: i18n.T("Proxy kubernetes workloads inbound traffic into local PC and dev in docker container"),
|
||||
@@ -156,11 +156,6 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().StringVar(&devOptions.VolumeDriver, "volume-driver", "", "Optional volume driver for the container")
|
||||
_ = cmd.Flags().SetAnnotation("platform", "version", []string{"1.32"})
|
||||
|
||||
// for ssh jumper host
|
||||
cmd.Flags().StringVar(&sshConf.Addr, "ssh-addr", "", "Optional ssh jump server address to dial as <hostname>:<port>, eg: 127.0.0.1:22")
|
||||
cmd.Flags().StringVar(&sshConf.User, "ssh-username", "", "Optional username for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Password, "ssh-password", "", "Optional password for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Keyfile, "ssh-keyfile", "", "Optional file with private key for SSH authentication")
|
||||
cmd.Flags().StringVar(&sshConf.ConfigAlias, "ssh-alias", "", "Optional config alias with ~/.ssh/config for SSH authentication")
|
||||
addSshFlag(cmd, sshConf)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
// kubectl exec POD_NAME -c CONTAINER_NAME /sbin/killall5 or ephemeralcontainers
|
||||
func CmdDuplicate(f cmdutil.Factory) *cobra.Command {
|
||||
var duplicateOptions = handler.DuplicateOptions{}
|
||||
var sshConf = util.SshConfig{}
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "duplicate",
|
||||
Short: i18n.T("Connect to kubernetes cluster network, or proxy kubernetes workloads inbound traffic into local PC"),
|
||||
@@ -102,11 +102,7 @@ func CmdDuplicate(f cmdutil.Factory) *cobra.Command {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println(`----------------------------------------------------------------------------------`)
|
||||
fmt.Println(` Now duplicate workloads running successfully on other cluster, enjoy it :) `)
|
||||
fmt.Println(`----------------------------------------------------------------------------------`)
|
||||
fmt.Println()
|
||||
util.Print(os.Stdout, "Now duplicate workloads running successfully on other cluster, enjoy it :)")
|
||||
}
|
||||
select {}
|
||||
},
|
||||
@@ -119,13 +115,7 @@ func CmdDuplicate(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().StringVar(&duplicateOptions.TargetNamespace, "target-namespace", "", "Duplicate workloads in this namespace, if not special, use origin namespace")
|
||||
cmd.Flags().StringVar(&duplicateOptions.TargetKubeconfig, "target-kubeconfig", "", "Duplicate workloads will create in this cluster, if not special, use origin cluster")
|
||||
|
||||
// for ssh jumper host
|
||||
cmd.Flags().StringVar(&sshConf.Addr, "ssh-addr", "", "Optional ssh jump server address to dial as <hostname>:<port>, eg: 127.0.0.1:22")
|
||||
cmd.Flags().StringVar(&sshConf.User, "ssh-username", "", "Optional username for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Password, "ssh-password", "", "Optional password for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Keyfile, "ssh-keyfile", "", "Optional file with private key for SSH authentication")
|
||||
cmd.Flags().StringVar(&sshConf.ConfigAlias, "ssh-alias", "", "Optional config alias with ~/.ssh/config for SSH authentication")
|
||||
|
||||
addSshFlag(cmd, sshConf)
|
||||
cmd.ValidArgsFunction = utilcomp.ResourceTypeAndNameCompletionFunc(f)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
func CmdProxy(f cmdutil.Factory) *cobra.Command {
|
||||
var connect = handler.ConnectOptions{}
|
||||
var sshConf = util.SshConfig{}
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "proxy",
|
||||
Short: i18n.T("Connect to kubernetes cluster network, or proxy kubernetes workloads inbound traffic into local PC"),
|
||||
@@ -85,11 +85,7 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
|
||||
log.Errorln(err)
|
||||
handler.Cleanup(syscall.SIGQUIT)
|
||||
} else {
|
||||
fmt.Println()
|
||||
fmt.Println(`---------------------------------------------------------------------------`)
|
||||
fmt.Println(` Now you can access resources in the kubernetes cluster, enjoy it :) `)
|
||||
fmt.Println(`---------------------------------------------------------------------------`)
|
||||
fmt.Println()
|
||||
util.Print(os.Stdout, "Now you can access resources in the kubernetes cluster, enjoy it :)")
|
||||
}
|
||||
select {}
|
||||
},
|
||||
@@ -98,13 +94,16 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().BoolVar(&config.Debug, "debug", false, "Enable debug mode or not, true or false")
|
||||
cmd.Flags().StringVar(&config.Image, "image", config.Image, "Use this image to startup container")
|
||||
|
||||
addSshFlag(cmd, sshConf)
|
||||
cmd.ValidArgsFunction = utilcomp.ResourceTypeAndNameCompletionFunc(f)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func addSshFlag(cmd *cobra.Command, sshConf *util.SshConfig) {
|
||||
// for ssh jumper host
|
||||
cmd.Flags().StringVar(&sshConf.Addr, "ssh-addr", "", "Optional ssh jump server address to dial as <hostname>:<port>, eg: 127.0.0.1:22")
|
||||
cmd.Flags().StringVar(&sshConf.User, "ssh-username", "", "Optional username for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Password, "ssh-password", "", "Optional password for ssh jump server")
|
||||
cmd.Flags().StringVar(&sshConf.Keyfile, "ssh-keyfile", "", "Optional file with private key for SSH authentication")
|
||||
cmd.Flags().StringVar(&sshConf.ConfigAlias, "ssh-alias", "", "Optional config alias with ~/.ssh/config for SSH authentication")
|
||||
|
||||
cmd.ValidArgsFunction = utilcomp.ResourceTypeAndNameCompletionFunc(f)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
func CmdReset(factory cmdutil.Factory) *cobra.Command {
|
||||
var connect = handler.ConnectOptions{}
|
||||
var sshConf = util.SshConfig{}
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "reset",
|
||||
Short: "Reset KubeVPN",
|
||||
|
||||
@@ -3,9 +3,6 @@ package dev
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
@@ -17,18 +14,12 @@ import (
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/google/uuid"
|
||||
miekgdns "github.com/miekg/dns"
|
||||
dockerterm "github.com/moby/term"
|
||||
v12 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/api/core/v1"
|
||||
v13 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/kubectl/pkg/cmd/util"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/cp"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/dns"
|
||||
util2 "github.com/wencaiwulue/kubevpn/pkg/util"
|
||||
)
|
||||
|
||||
type RunConfig struct {
|
||||
@@ -160,92 +151,6 @@ func ConvertKubeResourceToContainer(namespace string, temp v1.PodTemplateSpec, e
|
||||
return runConfigList
|
||||
}
|
||||
|
||||
func GetEnv(ctx context.Context, f util.Factory, ns, pod string) (map[string][]string, error) {
|
||||
set, err2 := f.KubernetesClientSet()
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
client, err2 := f.RESTClient()
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
config, err2 := f.ToRESTConfig()
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
get, err := set.CoreV1().Pods(ns).Get(ctx, pod, v13.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := map[string][]string{}
|
||||
for _, c := range get.Spec.Containers {
|
||||
env, err := util2.Shell(set, client, config, pod, c.Name, ns, []string{"env"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
split := strings.Split(env, "\n")
|
||||
result[c.Name] = split
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetVolume key format: [container name]-[volume mount name]
|
||||
func GetVolume(ctx context.Context, f util.Factory, ns, pod string) (map[string][]mount.Mount, error) {
|
||||
clientSet, err := f.KubernetesClientSet()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var get *v1.Pod
|
||||
get, err = clientSet.CoreV1().Pods(ns).Get(ctx, pod, v13.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := map[string][]mount.Mount{}
|
||||
for _, c := range get.Spec.Containers {
|
||||
// if container name is vpn or envoy-proxy, not need to download volume
|
||||
if c.Name == config.ContainerSidecarVPN || c.Name == config.ContainerSidecarEnvoyProxy {
|
||||
continue
|
||||
}
|
||||
var m []mount.Mount
|
||||
for _, volumeMount := range c.VolumeMounts {
|
||||
if volumeMount.MountPath == "/tmp" {
|
||||
continue
|
||||
}
|
||||
join := filepath.Join(os.TempDir(), strconv.Itoa(rand.Int()))
|
||||
err = os.MkdirAll(join, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if volumeMount.SubPath != "" {
|
||||
join = filepath.Join(join, volumeMount.SubPath)
|
||||
}
|
||||
// pod-namespace/pod-name:path
|
||||
remotePath := fmt.Sprintf("%s/%s:%s", ns, pod, volumeMount.MountPath)
|
||||
stdIn, stdOut, stdErr := dockerterm.StdStreams()
|
||||
copyOptions := cp.NewCopyOptions(genericclioptions.IOStreams{In: stdIn, Out: stdOut, ErrOut: stdErr})
|
||||
copyOptions.Container = c.Name
|
||||
copyOptions.MaxTries = 10
|
||||
err = copyOptions.Complete(f, &cobra.Command{}, []string{remotePath, join})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = copyOptions.Run()
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "Can not download volume %s path %s, err: %v, ignore...\n", volumeMount.Name, volumeMount.MountPath, err)
|
||||
continue
|
||||
}
|
||||
m = append(m, mount.Mount{
|
||||
Type: mount.TypeBind,
|
||||
Source: join,
|
||||
Target: volumeMount.MountPath,
|
||||
})
|
||||
fmt.Printf("%s:%s\n", join, volumeMount.MountPath)
|
||||
}
|
||||
result[c.Name] = m
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func GetDNS(ctx context.Context, f util.Factory, ns, pod string) (*miekgdns.ClientConfig, error) {
|
||||
clientSet, err := f.KubernetesClientSet()
|
||||
if err != nil {
|
||||
|
||||
@@ -92,11 +92,11 @@ func (d Options) Main(ctx context.Context) error {
|
||||
|
||||
pod := firstPod.Name
|
||||
|
||||
env, err := GetEnv(ctx, d.Factory, d.Namespace, pod)
|
||||
env, err := util.GetEnv(ctx, d.Factory, d.Namespace, pod)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
volume, err := GetVolume(ctx, d.Factory, d.Namespace, pod)
|
||||
volume, err := util.GetVolume(ctx, d.Factory, d.Namespace, pod)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ func (c *ConnectOptions) InitClient(f cmdutil.Factory) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func SshJump(conf util.SshConfig, flags *pflag.FlagSet) (err error) {
|
||||
func SshJump(conf *util.SshConfig, flags *pflag.FlagSet) (err error) {
|
||||
if conf.Addr == "" && conf.ConfigAlias == "" {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/dev"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/mesh"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -35,6 +33,7 @@ import (
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/mesh"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/util"
|
||||
)
|
||||
|
||||
@@ -532,7 +531,7 @@ func (d DuplicateOptions) setEnv(u *unstructured.Unstructured) error {
|
||||
}
|
||||
|
||||
var envMap map[string][]string
|
||||
envMap, err = dev.GetEnv(context.Background(), d.factory, d.Namespace, pod.Name)
|
||||
envMap, err = util.GetEnv(context.Background(), d.factory, d.Namespace, pod.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -595,7 +594,7 @@ func (d DuplicateOptions) setEnv(u *unstructured.Unstructured) error {
|
||||
}
|
||||
|
||||
for _, envVar := range container.Env {
|
||||
println(envVar)
|
||||
fmt.Print(envVar)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
101
pkg/util/pod.go
101
pkg/util/pod.go
@@ -2,12 +2,27 @@ package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/moby/term"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/exp/constraints"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/kubectl/pkg/cmd/util"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/cp"
|
||||
)
|
||||
|
||||
func PrintStatus(pod *corev1.Pod, writer io.Writer) {
|
||||
@@ -59,3 +74,89 @@ func max[T constraints.Ordered](a T, b T) T {
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func GetEnv(ctx context.Context, f util.Factory, ns, pod string) (map[string][]string, error) {
|
||||
set, err2 := f.KubernetesClientSet()
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
client, err2 := f.RESTClient()
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
config, err2 := f.ToRESTConfig()
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
get, err := set.CoreV1().Pods(ns).Get(ctx, pod, v1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := map[string][]string{}
|
||||
for _, c := range get.Spec.Containers {
|
||||
env, err := Shell(set, client, config, pod, c.Name, ns, []string{"env"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
split := strings.Split(env, "\n")
|
||||
result[c.Name] = split
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetVolume key format: [container name]-[volume mount name]
|
||||
func GetVolume(ctx context.Context, f util.Factory, ns, pod string) (map[string][]mount.Mount, error) {
|
||||
clientSet, err := f.KubernetesClientSet()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var get *corev1.Pod
|
||||
get, err = clientSet.CoreV1().Pods(ns).Get(ctx, pod, v1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := map[string][]mount.Mount{}
|
||||
for _, c := range get.Spec.Containers {
|
||||
// if container name is vpn or envoy-proxy, not need to download volume
|
||||
if c.Name == config.ContainerSidecarVPN || c.Name == config.ContainerSidecarEnvoyProxy {
|
||||
continue
|
||||
}
|
||||
var m []mount.Mount
|
||||
for _, volumeMount := range c.VolumeMounts {
|
||||
if volumeMount.MountPath == "/tmp" {
|
||||
continue
|
||||
}
|
||||
join := filepath.Join(os.TempDir(), strconv.Itoa(rand.Int()))
|
||||
err = os.MkdirAll(join, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if volumeMount.SubPath != "" {
|
||||
join = filepath.Join(join, volumeMount.SubPath)
|
||||
}
|
||||
// pod-namespace/pod-name:path
|
||||
remotePath := fmt.Sprintf("%s/%s:%s", ns, pod, volumeMount.MountPath)
|
||||
stdIn, stdOut, stdErr := term.StdStreams()
|
||||
copyOptions := cp.NewCopyOptions(genericclioptions.IOStreams{In: stdIn, Out: stdOut, ErrOut: stdErr})
|
||||
copyOptions.Container = c.Name
|
||||
copyOptions.MaxTries = 10
|
||||
err = copyOptions.Complete(f, &cobra.Command{}, []string{remotePath, join})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = copyOptions.Run()
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "Can not download volume %s path %s, err: %v, ignore...\n", volumeMount.Name, volumeMount.MountPath, err)
|
||||
continue
|
||||
}
|
||||
m = append(m, mount.Mount{
|
||||
Type: mount.TypeBind,
|
||||
Source: join,
|
||||
Target: volumeMount.MountPath,
|
||||
})
|
||||
fmt.Printf("%s:%s\n", join, volumeMount.MountPath)
|
||||
}
|
||||
result[c.Name] = m
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ type SshConfig struct {
|
||||
ConfigAlias string
|
||||
}
|
||||
|
||||
func Main(remoteEndpoint, localEndpoint *netip.AddrPort, conf SshConfig, done chan struct{}) error {
|
||||
func Main(remoteEndpoint, localEndpoint *netip.AddrPort, conf *SshConfig, done chan struct{}) error {
|
||||
var remote *ssh.Client
|
||||
var err error
|
||||
if conf.ConfigAlias != "" {
|
||||
|
||||
@@ -701,3 +701,23 @@ func WaitPodToBeReady(ctx context.Context, podInterface v12.PodInterface, select
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Print(writer io.Writer, slogan string) {
|
||||
length := len(slogan) + 4 + 4
|
||||
var sb strings.Builder
|
||||
|
||||
sb.WriteByte('\n')
|
||||
sb.WriteString("+" + strings.Repeat("-", length) + "+")
|
||||
sb.WriteByte('\n')
|
||||
sb.WriteString("╎")
|
||||
sb.WriteString(strings.Repeat(" ", 4))
|
||||
sb.WriteString(slogan)
|
||||
sb.WriteString(strings.Repeat(" ", 4))
|
||||
sb.WriteString("╎")
|
||||
sb.WriteByte('\n')
|
||||
sb.WriteString("+" + strings.Repeat("-", length) + "+")
|
||||
sb.WriteByte('\n')
|
||||
sb.WriteByte('\n')
|
||||
|
||||
_, _ = writer.Write([]byte(sb.String()))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user