Sync from k8s directly
Closed this issue · 3 comments
First thank you for the project! I'd like to make a suggestion:
Use case: you want to retrieve all images from one cluster to make it air-gapped.
Let's assume you're already running a cluster. Probably its convenient to get all images from it and then generate the config needed for sinker:
Something like this will get all the images running:
package main
import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func AppendIfMissing(slice []string, i string) []string {
for _, ele := range slice {
if ele == i {
return slice
}
}
return append(slice, i)
}
func homeDir() string {
if h := os.Getenv("HOME"); h != "" {
return h
}
return os.Getenv("USERPROFILE")
}
func main() {
var kubeconfig *string
if home := homeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else {
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
}
flag.Parse()
// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
// create the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
s := []string{}
for _, p := range pods.Items {
for _, c := range p.Spec.Containers {
s = AppendIfMissing(s, c.Image)
}
}
for _, image := range s {
fmt.Println(image)
}
}
From there we'd only need to generate the yaml for sinker and/or filter it. Thoughts?
No problem @pathcl.
I think the use case makes complete sense. Though this should be achievable today:
Get a list of all of the images running in the cluster (https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/)
$ kubectl get pods --all-namespaces -o go-template --template="{{range .items}}{{range .spec.containers}}{{.image}} {{end}}{{end}}"
Then either set the SINKER_IMAGES
environment variable to that list, or pass that list to the command line with --images
. Include --target
to set where you want them to go.
$ export SINKER_IMAGES=imageOne:v1,imageTwo:v1
$ export SINKER_TARGET=internal.com/repo
$ sinker push
--or--
$ sinker push -i imageOne:v1,imageTwo:v1 -t internal.com/repo
Would that work?
edit: If you would like to save that list for future use, I do think it makes sense to have the create
command take similar arguments and create a manifest that way.
@pathcl a fair number of changes have been added to the main branch, but not quite released yet. Standard input is now supported which may solve your request.
$ kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | ./sinker create - --target repo
Standard input has been released in 0.11.0