mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-05 23:36:59 +08:00
218 lines
5.3 KiB
Go
218 lines
5.3 KiB
Go
package dev
|
|
|
|
import (
|
|
"context"
|
|
"math/rand"
|
|
"sort"
|
|
"time"
|
|
|
|
"github.com/docker/cli/cli/command"
|
|
"github.com/docker/cli/cli/flags"
|
|
"github.com/docker/cli/opts"
|
|
"github.com/docker/docker/api/types"
|
|
containertypes "github.com/docker/docker/api/types/container"
|
|
"github.com/docker/docker/client"
|
|
log "github.com/sirupsen/logrus"
|
|
v1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
|
"k8s.io/kubectl/pkg/util/podutils"
|
|
|
|
"github.com/wencaiwulue/kubevpn/pkg/handler"
|
|
"github.com/wencaiwulue/kubevpn/pkg/mesh"
|
|
"github.com/wencaiwulue/kubevpn/pkg/util"
|
|
)
|
|
|
|
type Options struct {
|
|
Headers map[string]string
|
|
Namespace string
|
|
Workload string
|
|
Factory cmdutil.Factory
|
|
ContainerName string
|
|
|
|
// docker options
|
|
Platform string
|
|
//Pull string // always, missing, never
|
|
PublishAll bool
|
|
Entrypoint string
|
|
DockerImage string
|
|
Publish opts.ListOpts
|
|
Expose opts.ListOpts
|
|
ExtraHosts opts.ListOpts
|
|
ParentContainer string
|
|
Env opts.ListOpts
|
|
Mounts opts.MountOpt
|
|
Volumes opts.ListOpts
|
|
VolumeDriver string
|
|
}
|
|
|
|
func (d Options) Main(ctx context.Context) error {
|
|
rand.Seed(time.Now().UnixNano())
|
|
object, err := util.GetUnstructuredObject(d.Factory, d.Namespace, d.Workload)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
u := object.Object.(*unstructured.Unstructured)
|
|
var templateSpec *v1.PodTemplateSpec
|
|
//var path []string
|
|
templateSpec, _, err = util.GetPodTemplateSpecPath(u)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
set, err := d.Factory.KubernetesClientSet()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
sortBy := func(pods []*v1.Pod) sort.Interface {
|
|
for i := 0; i < len(pods); i++ {
|
|
if pods[i].DeletionTimestamp != nil {
|
|
pods = append(pods[:i], pods[i+1:]...)
|
|
i--
|
|
}
|
|
}
|
|
return sort.Reverse(podutils.ActivePods(pods))
|
|
}
|
|
lab := labels.SelectorFromSet(templateSpec.Labels).String()
|
|
firstPod, _, err := polymorphichelpers.GetFirstPod(set.CoreV1(), d.Namespace, lab, time.Second*60, sortBy)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pod := firstPod.Name
|
|
|
|
env, err := GetEnv(ctx, d.Factory, d.Namespace, pod)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
volume, err := GetVolume(ctx, d.Factory, d.Namespace, pod)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
dns, err := GetDNS(ctx, d.Factory, d.Namespace, pod)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
mesh.RemoveContainers(templateSpec)
|
|
list := ConvertKubeResourceToContainer(d.Namespace, *templateSpec, env, volume, dns)
|
|
err = fillOptions(list, d)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var dockerCli *command.DockerCli
|
|
_, dockerCli, err = GetClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if d.ParentContainer != "" {
|
|
for _, config := range list[:] {
|
|
// remove expose port
|
|
config.config.ExposedPorts = nil
|
|
config.hostConfig.NetworkMode = containertypes.NetworkMode("container:" + d.ParentContainer)
|
|
config.hostConfig.PidMode = containertypes.PidMode("container:" + d.ParentContainer)
|
|
config.hostConfig.PortBindings = nil
|
|
|
|
// remove dns
|
|
config.hostConfig.DNS = nil
|
|
config.hostConfig.DNSOptions = nil
|
|
config.hostConfig.DNSSearch = nil
|
|
config.hostConfig.PublishAllPorts = false
|
|
config.config.Hostname = ""
|
|
}
|
|
} else {
|
|
// skip first
|
|
for _, config := range list[1:] {
|
|
// remove expose port
|
|
config.config.ExposedPorts = nil
|
|
config.hostConfig.NetworkMode = containertypes.NetworkMode("container:" + list[0].containerName)
|
|
config.hostConfig.PidMode = containertypes.PidMode("container:" + list[0].containerName)
|
|
config.hostConfig.PortBindings = nil
|
|
|
|
// remove dns
|
|
config.hostConfig.DNS = nil
|
|
config.hostConfig.DNSOptions = nil
|
|
config.hostConfig.DNSSearch = nil
|
|
config.hostConfig.PublishAllPorts = false
|
|
config.config.Hostname = ""
|
|
}
|
|
}
|
|
|
|
handler.RollbackFuncList = append(handler.RollbackFuncList, func() {
|
|
_ = list.Remove(ctx)
|
|
})
|
|
err = list.Run(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return terminal(list[0].containerName, dockerCli)
|
|
}
|
|
|
|
type Run []*RunConfig
|
|
|
|
func (r Run) Remove(ctx context.Context) error {
|
|
cli, _, err := GetClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, config := range r {
|
|
//err = cli.NetworkDisconnect(ctx, config.networkName, config.containerName, true)
|
|
//if err != nil {
|
|
// log.Errorln(err)
|
|
//}
|
|
err = cli.ContainerRemove(ctx, config.containerName, types.ContainerRemoveOptions{Force: true})
|
|
if err != nil {
|
|
log.Errorln(err)
|
|
}
|
|
}
|
|
//for _, config := range r {
|
|
// _, err = cli.NetworkInspect(ctx, config.networkName, types.NetworkInspectOptions{})
|
|
// if err == nil {
|
|
// err = cli.NetworkRemove(ctx, config.networkName)
|
|
// if err != nil {
|
|
// log.Errorln(err)
|
|
// }
|
|
// }
|
|
//}
|
|
return nil
|
|
}
|
|
|
|
func GetClient() (*client.Client, *command.DockerCli, error) {
|
|
cli, err := client.NewClientWithOpts(
|
|
client.FromEnv,
|
|
client.WithAPIVersionNegotiation(),
|
|
)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
var dockerCli *command.DockerCli
|
|
dockerCli, err = command.NewDockerCli(command.WithAPIClient(cli))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
err = dockerCli.Initialize(flags.NewClientOptions())
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return cli, dockerCli, nil
|
|
}
|
|
|
|
func (r Run) Run(ctx context.Context) error {
|
|
cli, _, err := GetClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, config := range r {
|
|
err = run(ctx, config, cli)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|