mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-12-24 11:51:13 +08:00
feat: optimize code
This commit is contained in:
@@ -65,7 +65,7 @@ func CmdCp(f cmdutil.Factory) *cobra.Command {
|
|||||||
Use: "cp <file-spec-src> <file-spec-dest>",
|
Use: "cp <file-spec-src> <file-spec-dest>",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
Short: i18n.T("Copy files and directories to and from containers"),
|
Short: i18n.T("Copy files and directories to and from containers"),
|
||||||
Long: i18n.T("Copy files and directories to and from containers."),
|
Long: i18n.T("Copy files and directories to and from containers. Different between kubectl cp is it will de-reference symbol link."),
|
||||||
Example: cpExample,
|
Example: cpExample,
|
||||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
cmdutil.CheckErr(handler.SshJump(sshConf, cmd.Flags()))
|
cmdutil.CheckErr(handler.SshJump(sshConf, cmd.Flags()))
|
||||||
|
|||||||
@@ -32,15 +32,22 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
|||||||
Env: opts.NewListOpts(nil),
|
Env: opts.NewListOpts(nil),
|
||||||
Volumes: opts.NewListOpts(nil),
|
Volumes: opts.NewListOpts(nil),
|
||||||
ExtraHosts: opts.NewListOpts(nil),
|
ExtraHosts: opts.NewListOpts(nil),
|
||||||
Aliases: opts.NewListOpts(nil),
|
//Aliases: opts.NewListOpts(nil),
|
||||||
NoProxy: false,
|
NoProxy: false,
|
||||||
ExtraCIDR: []string{},
|
ExtraCIDR: []string{},
|
||||||
}
|
}
|
||||||
var sshConf = &util.SshConfig{}
|
var sshConf = &util.SshConfig{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "dev",
|
Use: "dev",
|
||||||
Short: i18n.T("Startup your workloads in local Docker container use same volume、env、and network with cluster"),
|
Short: i18n.T("Startup your kubernetes workloads in local Docker container with same volume、env、and network"),
|
||||||
Long: templates.LongDesc(i18n.T(`Startup your workloads in local Docker container use same volume、env、and network with cluster`)),
|
Long: templates.LongDesc(i18n.T(`
|
||||||
|
Startup your kubernetes workloads in local Docker container with same volume、env、and network
|
||||||
|
|
||||||
|
## What did i do:
|
||||||
|
- Download volume which MountPath point to, mount to docker container
|
||||||
|
- Connect to cluster network, set network to docker container
|
||||||
|
- Get all environment with command (env), set env to docker container
|
||||||
|
`)),
|
||||||
Example: templates.Examples(i18n.T(`
|
Example: templates.Examples(i18n.T(`
|
||||||
# Develop workloads
|
# Develop workloads
|
||||||
- develop deployment
|
- develop deployment
|
||||||
@@ -150,15 +157,14 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
// docker options
|
// docker options
|
||||||
cmd.Flags().Var(&devOptions.ExtraHosts, "add-host", "Add a custom host-to-IP mapping (host:ip)")
|
cmd.Flags().Var(&devOptions.ExtraHosts, "add-host", "Add a custom host-to-IP mapping (host:ip)")
|
||||||
//cmd.Flags().StringVar(&devOptions.ParentContainer, "parent-container", "", "Parent container name if running in Docker (Docker in Docker)")
|
|
||||||
// We allow for both "--net" and "--network", although the latter is the recommended way.
|
// We allow for both "--net" and "--network", although the latter is the recommended way.
|
||||||
cmd.Flags().Var(&devOptions.NetMode, "net", "Connect a container to a network")
|
cmd.Flags().Var(&devOptions.NetMode, "net", "Connect a container to a network, eg: [default|bridge|host|none|container:$CONTAINER_ID]")
|
||||||
cmd.Flags().Var(&devOptions.NetMode, "network", "Connect a container to a network")
|
cmd.Flags().Var(&devOptions.NetMode, "network", "Connect a container to a network")
|
||||||
cmd.Flags().MarkHidden("net")
|
cmd.Flags().MarkHidden("net")
|
||||||
// We allow for both "--net-alias" and "--network-alias", although the latter is the recommended way.
|
// We allow for both "--net-alias" and "--network-alias", although the latter is the recommended way.
|
||||||
cmd.Flags().Var(&devOptions.Aliases, "net-alias", "Add network-scoped alias for the container")
|
//cmd.Flags().Var(&devOptions.Aliases, "net-alias", "Add network-scoped alias for the container")
|
||||||
cmd.Flags().Var(&devOptions.Aliases, "network-alias", "Add network-scoped alias for the container")
|
//cmd.Flags().Var(&devOptions.Aliases, "network-alias", "Add network-scoped alias for the container")
|
||||||
cmd.Flags().MarkHidden("net-alias")
|
//cmd.Flags().MarkHidden("net-alias")
|
||||||
cmd.Flags().VarP(&devOptions.Volumes, "volume", "v", "Bind mount a volume")
|
cmd.Flags().VarP(&devOptions.Volumes, "volume", "v", "Bind mount a volume")
|
||||||
cmd.Flags().Var(&devOptions.Mounts, "mount", "Attach a filesystem mount to the container")
|
cmd.Flags().Var(&devOptions.Mounts, "mount", "Attach a filesystem mount to the container")
|
||||||
cmd.Flags().Var(&devOptions.Expose, "expose", "Expose a port or a range of ports")
|
cmd.Flags().Var(&devOptions.Expose, "expose", "Expose a port or a range of ports")
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package dev
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@@ -14,12 +17,18 @@ import (
|
|||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
miekgdns "github.com/miekg/dns"
|
miekgdns "github.com/miekg/dns"
|
||||||
|
"github.com/moby/term"
|
||||||
v12 "github.com/opencontainers/image-spec/specs-go/v1"
|
v12 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
v13 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v13 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
"k8s.io/kubectl/pkg/cmd/util"
|
"k8s.io/kubectl/pkg/cmd/util"
|
||||||
|
|
||||||
|
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||||
|
"github.com/wencaiwulue/kubevpn/pkg/cp"
|
||||||
"github.com/wencaiwulue/kubevpn/pkg/dns"
|
"github.com/wencaiwulue/kubevpn/pkg/dns"
|
||||||
|
"github.com/wencaiwulue/kubevpn/pkg/handler"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RunConfig struct {
|
type RunConfig struct {
|
||||||
@@ -143,7 +152,7 @@ func ConvertKubeResourceToContainer(namespace string, temp v1.PodTemplateSpec, e
|
|||||||
r.k8sContainerName = c.Name
|
r.k8sContainerName = c.Name
|
||||||
r.config = config
|
r.config = config
|
||||||
r.hostConfig = hostConfig
|
r.hostConfig = hostConfig
|
||||||
r.networkingConfig = nil
|
r.networkingConfig = &network.NetworkingConfig{EndpointsConfig: make(map[string]*network.EndpointSettings)}
|
||||||
r.platform = /*&v12.Platform{Architecture: "amd64", OS: "linux"}*/ nil
|
r.platform = /*&v12.Platform{Architecture: "amd64", OS: "linux"}*/ nil
|
||||||
|
|
||||||
runConfigList = append(runConfigList, &r)
|
runConfigList = append(runConfigList, &r)
|
||||||
@@ -176,3 +185,63 @@ func GetDNS(ctx context.Context, f util.Factory, ns, pod string) (*miekgdns.Clie
|
|||||||
}
|
}
|
||||||
return fromPod, nil
|
return fromPod, 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)
|
||||||
|
}
|
||||||
|
handler.RollbackFuncList = append(handler.RollbackFuncList, func() {
|
||||||
|
_ = os.RemoveAll(join)
|
||||||
|
})
|
||||||
|
// 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, "failed to download volume %s path %s to %s, err: %v, ignore...\n", volumeMount.Name, remotePath, join, 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
|
||||||
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ type Options struct {
|
|||||||
Expose opts.ListOpts
|
Expose opts.ListOpts
|
||||||
ExtraHosts opts.ListOpts
|
ExtraHosts opts.ListOpts
|
||||||
NetMode opts.NetworkOpt
|
NetMode opts.NetworkOpt
|
||||||
Aliases opts.ListOpts
|
//Aliases opts.ListOpts
|
||||||
Env opts.ListOpts
|
Env opts.ListOpts
|
||||||
Mounts opts.MountOpt
|
Mounts opts.MountOpt
|
||||||
Volumes opts.ListOpts
|
Volumes opts.ListOpts
|
||||||
@@ -99,7 +99,7 @@ func (d Options) Main(ctx context.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
volume, err := util.GetVolume(ctx, d.Factory, d.Namespace, pod)
|
volume, err := GetVolume(ctx, d.Factory, d.Namespace, pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ func (r Run) Run(ctx context.Context, volume map[string][]mount.Mount) error {
|
|||||||
id, err = run(ctx, config, cli)
|
id, err = run(ctx, config, cli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// try another way to startup container
|
// try another way to startup container
|
||||||
log.Info("try another way to startup container")
|
log.Infof("occur err: %v, try another way to startup container...", err)
|
||||||
config.hostConfig.Mounts = nil
|
config.hostConfig.Mounts = nil
|
||||||
id, err = run(ctx, config, cli)
|
id, err = run(ctx, config, cli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -148,11 +148,6 @@ func fillOptions(r Run, copts Options) error {
|
|||||||
|
|
||||||
config.hostConfig.Binds = binds
|
config.hostConfig.Binds = binds
|
||||||
|
|
||||||
// todo
|
|
||||||
if copts.Aliases.Len() != 0 {
|
|
||||||
//config.networkingConfig.EndpointsConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,11 @@ func run(ctx context.Context, runConfig *RunConfig, cli *client.Client) (id stri
|
|||||||
}
|
}
|
||||||
id = create.ID
|
id = create.ID
|
||||||
log.Infof("Created container: %s", name)
|
log.Infof("Created container: %s", name)
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
_ = cli.ContainerRemove(ctx, id, types.ContainerRemoveOptions{Force: true})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
err = cli.ContainerStart(ctx, create.ID, types.ContainerStartOptions{})
|
err = cli.ContainerStart(ctx, create.ID, types.ContainerStartOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func SetupDNS(clientConfig *miekgdns.ClientConfig, _ []string) error {
|
|||||||
|
|
||||||
func CancelDNS() {
|
func CancelDNS() {
|
||||||
updateHosts("")
|
updateHosts("")
|
||||||
getenv := os.Getenv("luid")
|
getenv := os.Getenv(config.EnvTunNameOrLUID)
|
||||||
parseUint, err := strconv.ParseUint(getenv, 10, 64)
|
parseUint, err := strconv.ParseUint(getenv, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningln(err)
|
log.Warningln(err)
|
||||||
@@ -61,6 +61,7 @@ func CancelDNS() {
|
|||||||
}
|
}
|
||||||
luid := winipcfg.LUID(parseUint)
|
luid := winipcfg.LUID(parseUint)
|
||||||
_ = luid.FlushDNS(windows.AF_INET)
|
_ = luid.FlushDNS(windows.AF_INET)
|
||||||
|
_ = luid.FlushRoutes(windows.AF_INET)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateNicMetric(name string) error {
|
func updateNicMetric(name string) error {
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ func InstallWireGuardTunDriver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UninstallWireGuardTunDriver() error {
|
func UninstallWireGuardTunDriver() error {
|
||||||
wd, err := os.Getwd()
|
executable, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
filename := filepath.Join(wd, "wintun.dll")
|
filename := filepath.Join(filepath.Dir(executable), "wintun.dll")
|
||||||
return os.Remove(filename)
|
return os.Remove(filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,34 +27,34 @@ var stopChan = make(chan os.Signal)
|
|||||||
var RollbackFuncList = make([]func(), 2)
|
var RollbackFuncList = make([]func(), 2)
|
||||||
var ctx, cancel = context.WithCancel(context.Background())
|
var ctx, cancel = context.WithCancel(context.Background())
|
||||||
|
|
||||||
func (c *ConnectOptions) addCleanUpResourceHandler(clientset *kubernetes.Clientset, namespace string) {
|
func (c *ConnectOptions) addCleanUpResourceHandler() {
|
||||||
signal.Notify(stopChan, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGKILL /*, syscall.SIGSTOP*/)
|
signal.Notify(stopChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGKILL)
|
||||||
go func() {
|
go func() {
|
||||||
<-stopChan
|
<-stopChan
|
||||||
log.Info("prepare to exit, cleaning up")
|
log.Info("prepare to exit, cleaning up")
|
||||||
dns.CancelDNS()
|
|
||||||
err := c.dhcp.ReleaseIpToDHCP(c.usedIPs...)
|
err := c.dhcp.ReleaseIpToDHCP(c.usedIPs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to release ip to dhcp, err: %v", err)
|
log.Errorf("failed to release ip to dhcp, err: %v", err)
|
||||||
}
|
}
|
||||||
cancel()
|
|
||||||
for _, function := range RollbackFuncList {
|
for _, function := range RollbackFuncList {
|
||||||
if function != nil {
|
if function != nil {
|
||||||
function()
|
function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = clientset.CoreV1().Pods(namespace).Delete(context.Background(), config.CniNetName, v1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)})
|
_ = c.clientset.CoreV1().Pods(c.Namespace).Delete(context.Background(), config.CniNetName, v1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)})
|
||||||
var count int
|
var count int
|
||||||
count, err = updateRefCount(clientset.CoreV1().ConfigMaps(namespace), config.ConfigMapPodTrafficManager, -1)
|
count, err = updateRefCount(c.clientset.CoreV1().ConfigMaps(c.Namespace), config.ConfigMapPodTrafficManager, -1)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// if ref-count is less than zero or equals to zero, means nobody is using this traffic pod, so clean it
|
// if ref-count is less than zero or equals to zero, means nobody is using this traffic pod, so clean it
|
||||||
if count <= 0 {
|
if count <= 0 {
|
||||||
log.Info("ref-count is zero, prepare to clean up resource")
|
log.Info("ref-count is zero, prepare to clean up resource")
|
||||||
cleanup(clientset, namespace, config.ConfigMapPodTrafficManager, true)
|
cleanup(c.clientset, c.Namespace, config.ConfigMapPodTrafficManager, true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
dns.CancelDNS()
|
||||||
|
cancel()
|
||||||
log.Info("clean up successful")
|
log.Info("clean up successful")
|
||||||
util.CleanExtensionLib()
|
util.CleanExtensionLib()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ func (c *ConnectOptions) createRemoteInboundPod(ctx1 context.Context) (err error
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, workload := range c.Workloads {
|
for _, workload := range c.Workloads {
|
||||||
if len(workload) > 0 {
|
|
||||||
configInfo := util.PodRouteConfig{
|
configInfo := util.PodRouteConfig{
|
||||||
LocalTunIP: c.localTunIP.IP.String(),
|
LocalTunIP: c.localTunIP.IP.String(),
|
||||||
TrafficManagerRealIP: c.routerIP.String(),
|
TrafficManagerRealIP: c.routerIP.String(),
|
||||||
@@ -86,7 +85,6 @@ func (c *ConnectOptions) createRemoteInboundPod(ctx1 context.Context) (err error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +113,7 @@ func Rollback(f cmdutil.Factory, ns, workload string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConnectOptions) DoConnect() (err error) {
|
func (c *ConnectOptions) DoConnect() (err error) {
|
||||||
c.addCleanUpResourceHandler(c.clientset, c.Namespace)
|
c.addCleanUpResourceHandler()
|
||||||
trafficMangerNet := net.IPNet{IP: config.RouterIP, Mask: config.CIDR.Mask}
|
trafficMangerNet := net.IPNet{IP: config.RouterIP, Mask: config.CIDR.Mask}
|
||||||
c.dhcp = NewDHCPManager(c.clientset.CoreV1().ConfigMaps(c.Namespace), c.Namespace, &trafficMangerNet)
|
c.dhcp = NewDHCPManager(c.clientset.CoreV1().ConfigMaps(c.Namespace), c.Namespace, &trafficMangerNet)
|
||||||
if err = c.dhcp.InitDHCP(ctx); err != nil {
|
if err = c.dhcp.InitDHCP(ctx); err != nil {
|
||||||
|
|||||||
@@ -5,24 +5,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/mount"
|
|
||||||
"github.com/moby/term"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
|
||||||
"k8s.io/kubectl/pkg/cmd/util"
|
"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) {
|
func PrintStatus(pod *corev1.Pod, writer io.Writer) {
|
||||||
@@ -103,60 +92,3 @@ func GetEnv(ctx context.Context, f util.Factory, ns, pod string) (map[string][]s
|
|||||||
}
|
}
|
||||||
return result, nil
|
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, "failed to download volume %s path %s to %s, err: %v, ignore...\n", volumeMount.Name, remotePath, join, 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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import (
|
|||||||
k8sruntime "k8s.io/apimachinery/pkg/runtime"
|
k8sruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
runtimeresource "k8s.io/cli-runtime/pkg/resource"
|
runtimeresource "k8s.io/cli-runtime/pkg/resource"
|
||||||
@@ -631,19 +632,36 @@ func AllContainerIsRunning(pod *v1.Pod) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CleanExtensionLib() {
|
func CleanExtensionLib() {
|
||||||
if IsWindows() {
|
if !IsWindows() {
|
||||||
err := retry.OnError(retry.DefaultRetry, func(err error) bool {
|
return
|
||||||
return err != nil
|
}
|
||||||
}, func() error {
|
path, err := os.Executable()
|
||||||
return driver.UninstallWireGuardTunDriver()
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
var wd string
|
|
||||||
wd, err = os.Getwd()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
filename := filepath.Join(wd, "wintun.dll")
|
filename := filepath.Join(filepath.Dir(path), "wintun.dll")
|
||||||
|
_ = retry.OnError(
|
||||||
|
// step : 0 13 34 55 100 194 433 661 1384 2689 (ms)
|
||||||
|
// total: 5.57s
|
||||||
|
wait.Backoff{
|
||||||
|
Steps: 10,
|
||||||
|
Duration: 10 * time.Millisecond,
|
||||||
|
Factor: 2.0,
|
||||||
|
Jitter: 0.5,
|
||||||
|
},
|
||||||
|
func(error) bool {
|
||||||
|
_, err = os.Lstat(filename)
|
||||||
|
return !errors.Is(err, os.ErrNotExist)
|
||||||
|
},
|
||||||
|
func() error {
|
||||||
|
err = driver.UninstallWireGuardTunDriver()
|
||||||
|
return fmt.Errorf("%v", err)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
_, err = os.Lstat(filename)
|
||||||
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
return
|
||||||
|
}
|
||||||
var temp *os.File
|
var temp *os.File
|
||||||
if temp, err = os.CreateTemp("", ""); err != nil {
|
if temp, err = os.CreateTemp("", ""); err != nil {
|
||||||
return
|
return
|
||||||
@@ -651,12 +669,13 @@ func CleanExtensionLib() {
|
|||||||
if err = temp.Close(); err != nil {
|
if err = temp.Close(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if err = os.Remove(temp.Name()); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
if err = os.Rename(filename, temp.Name()); err != nil {
|
if err = os.Rename(filename, temp.Name()); err != nil {
|
||||||
log.Debugln(err)
|
log.Debugln(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WaitPodToBeReady(ctx context.Context, podInterface v12.PodInterface, selector metav1.LabelSelector) error {
|
func WaitPodToBeReady(ctx context.Context, podInterface v12.PodInterface, selector metav1.LabelSelector) error {
|
||||||
watchStream, err := podInterface.Watch(ctx, metav1.ListOptions{
|
watchStream, err := podInterface.Watch(ctx, metav1.ListOptions{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package util
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containernetworking/cni/libcni"
|
"github.com/containernetworking/cni/libcni"
|
||||||
@@ -94,6 +95,9 @@ func TestPing(t *testing.T) {
|
|||||||
}
|
}
|
||||||
ipConn, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
|
ipConn, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "operation not permitted") {
|
||||||
|
return
|
||||||
|
}
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
bytes := buf.Bytes()
|
bytes := buf.Bytes()
|
||||||
|
|||||||
Reference in New Issue
Block a user