I want to copy a file from inside of a pod to local. I looked an old example on the Internet and used client-go package and Docker-Desktop for kubernetes environment for that but it throws an error.Also I am not sure is it right way or not. I run this code on my windows 10 local machine and it connects to my local kubernetes. There is one pod in default namespace and there is test.db file inside of it.
That is error: "GroupVersion is required when initializing a RESTClient"
The error throws by RESTClientFor() method in https://github.com/kubernetes/client-go/blob/master/rest/config.go
Actually I set the config it wanted but it keep to give same error.
This is my code:
package main
import (
"bytes"
"fmt"
"log"
"path/filepath"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"k8s.io/kubectl/pkg/cmd/cp"
"k8s.io/kubectl/pkg/cmd/util"
)
const GroupName = "api"
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
func main() {
var kubeConfig string
if home := homedir.HomeDir(); home != "" {
kubeConfig = filepath.Join(home, ".kube", "config")
}
config, err := clientcmd.BuildConfigFromFlags("", kubeConfig)
config.GroupVersion = &SchemeGroupVersion
if err != nil {
fmt.Println(err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err)
}
config.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: scheme.Codecs}
podexec := NewPodExec(*config, clientset)
err = podexec.copyFile()
if err != nil {
panic(err)
}
}
type PodExec struct {
RestConfig *rest.Config
ClientSet *kubernetes.Clientset
}
func NewPodExec(config rest.Config, clientset *kubernetes.Clientset) *PodExec {
return &PodExec{
RestConfig: &config,
ClientSet: clientset,
}
}
func (p *PodExec) CopyFileFromThePod(sourceFilePath string, destinationFilePath string, containername, namespace string) (*bytes.Buffer, *bytes.Buffer, *bytes.Buffer, error) {
ioStreams, in, out, errOut := genericclioptions.NewTestIOStreams()
copyOptions := cp.NewCopyOptions(ioStreams)
copyOptions.Clientset = p.ClientSet
copyOptions.ClientConfig = p.RestConfig
copyOptions.Container = containername
var copt genericclioptions.RESTClientGetter = &genericclioptions.ConfigFlags{}
nf := util.NewFactory(copt)
cobra := cp.NewCmdCp(nf, ioStreams)
sourceFilePath = namespace + "/" + containername + ":" + sourceFilePath
cobra.Run(cobra, []string{sourceFilePath, destinationFilePath})
err := cobra.Execute()
if err != nil {
log.Fatal(err)
}
return in, out, errOut, nil
}
func (podexec *PodExec) copyFile() error {
podExec := NewPodExec(*podexec.RestConfig, podexec.ClientSet)
_, out, _, err := podExec.CopyFileFromThePod("/var/lib/test.db", "/test/test.db", "test-app-sec-deployment-8f769fb8b-dpl9z", "default")
if err != nil {
fmt.Printf("%v\n", err)
return err
}
fmt.Println("out:")
fmt.Printf("%s", out.String())
return nil
}