diff --git a/go/rfswift/cli/rfcli.go b/go/rfswift/cli/rfcli.go index 059e75c..0b14afb 100644 --- a/go/rfswift/cli/rfcli.go +++ b/go/rfswift/cli/rfcli.go @@ -82,7 +82,9 @@ var lastCmd = &cobra.Command{ Short: "last container run", Long: `Display the latest container that was run`, Run: func(cmd *cobra.Command, args []string) { - rfdock.DockerLast(FilterLast) + labelKey := "org.container.project" + labelValue := "rfswift" + rfdock.DockerLast(FilterLast, labelKey, labelValue) }, } @@ -175,6 +177,27 @@ var winusbdetachCmd = &cobra.Command{ }, } +var ImagesCmd = &cobra.Command{ + Use: "images", + Short: "show rfswift images", + Long: `Display images build for RF Swift`, + Run: func(cmd *cobra.Command, args []string) { + labelKey := "org.container.project" + labelValue := "rfswift" + images_list, err := rfdock.ListImages(labelKey, labelValue) + if err != nil { + fmt.Println("Error:", err) + os.Exit(1) + } + for _, image := range images_list { + fmt.Println("ID:", image.ID) + fmt.Println("RepoTags:", image.RepoTags) + fmt.Println("Labels:", image.Labels) + fmt.Println() + } + }, +} + func init() { rootCmd.AddCommand(runCmd) rootCmd.AddCommand(lastCmd) @@ -184,6 +207,7 @@ func init() { rootCmd.AddCommand(renameCmd) rootCmd.AddCommand(installCmd) rootCmd.AddCommand(removeCmd) + rootCmd.AddCommand(ImagesCmd) // Adding special commands for Windows os := runtime.GOOS @@ -202,7 +226,7 @@ func init() { pullCmd.Flags().StringVarP(&ImageRef, "image", "i", "", "image reference") pullCmd.Flags().StringVarP(&ImageTag, "tag", "t", "", "rename to target tag") pullCmd.MarkFlagRequired("image") - pullCmd.MarkFlagRequired("tag") + //pullCmd.MarkFlagRequired("tag") renameCmd.Flags().StringVarP(&ImageRef, "image", "i", "", "image reference") renameCmd.Flags().StringVarP(&ImageTag, "tag", "t", "", "rename to target tag") commitCmd.Flags().StringVarP(&ContID, "container", "c", "", "container to run") @@ -210,15 +234,15 @@ func init() { commitCmd.MarkFlagRequired("container") commitCmd.MarkFlagRequired("image") execCmd.Flags().StringVarP(&ContID, "container", "c", "", "container to run") - execCmd.Flags().StringVarP(&ExecCmd, "command", "e", "", "command to exec (required!)") + execCmd.Flags().StringVarP(&ExecCmd, "command", "e", "/bin/bash", "command to exec (by default: /bin/bash)") execCmd.Flags().StringVarP(&SInstall, "install", "i", "", "install from function script (e.g: 'sdrpp_soft_install')") - execCmd.MarkFlagRequired("command") + //execCmd.MarkFlagRequired("command") runCmd.Flags().StringVarP(&ExtraHost, "extrahosts", "x", "", "set extra hosts (default: 'pluto.local:192.168.1.2', and separate them with commas)") runCmd.Flags().StringVarP(&XDisplay, "display", "d", "", "set X Display (by default: 'DISPLAY=:0', and separate them with commas)") runCmd.Flags().StringVarP(&ExecCmd, "command", "e", "", "command to exec (by default: '/bin/bash')") runCmd.Flags().StringVarP(&ExtraBind, "bind", "b", "", "extra bindings (separate them with commas)") runCmd.Flags().StringVarP(&DImage, "image", "i", "", "image (default: 'myrfswift:latest')") - runCmd.Flags().StringVarP(&PulseServer, "pulseserver", "p", "tcp:localhost:34567", "PULSE SERVER TCP address (by default: tcp:localhost:34567)") + runCmd.Flags().StringVarP(&PulseServer, "pulseserver", "p", "tcp:127.0.0.1:34567", "PULSE SERVER TCP address (by default: tcp:127.0.0.1:34567)") lastCmd.Flags().StringVarP(&FilterLast, "filter", "f", "", "filter by image name") } diff --git a/go/rfswift/dock/rfdock.go b/go/rfswift/dock/rfdock.go index 7baa1df..a5185fd 100644 --- a/go/rfswift/dock/rfdock.go +++ b/go/rfswift/dock/rfdock.go @@ -9,6 +9,7 @@ import ( "io" "os" "strings" + "encoding/json" "context" "github.com/docker/docker/api/types" @@ -18,6 +19,9 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" "golang.org/x/crypto/ssh/terminal" + "github.com/docker/docker/pkg/jsonmessage" + "github.com/moby/term" + "github.com/docker/docker/api/types/filters" ) var inout chan []byte @@ -53,61 +57,78 @@ var dockerObj = DockerInst{net: "host", pulse_server: "tcp:localhost:34567", shell: "/bin/bash"} // Instance with default values -func DockerLast(ifilter string) { - /* Lists 10 last Docker containers - in(1): string optional filter for image name - */ - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - panic(err) - } - defer cli.Close() +func DockerLast(ifilter string, labelKey string, labelValue string) { + /* Lists 10 last Docker containers + in(1): string optional filter for image name + */ + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() - containers, err := cli.ContainerList(ctx, container.ListOptions{Latest: true, All: true, Limit: 10}) - if err != nil { - panic(err) - } + // Create filters + containerFilters := filters.NewArgs() + if ifilter != "" { + containerFilters.Add("ancestor", ifilter) + } - for _, container := range containers { - if ifilter != "" { - if container.Image == ifilter { - fmt.Println("[", container.Created, "][", container.Image, "] Container: ", container.ID, ", Command: ", container.Command) - } - } else { - fmt.Println("[", container.Created, "][", container.Image, "] Container: ", container.ID, ", Command: ", container.Command) - } - } + containerFilters.Add("label", fmt.Sprintf("%s=%s", labelKey, labelValue)) // filter by label + + // List containers with the specified filter + containers, err := cli.ContainerList(ctx, container.ListOptions{ + All: true, + Limit: 10, + Filters: containerFilters, + }) + if err != nil { + panic(err) + } + + for _, container := range containers { + fmt.Println("[", container.Created, "][", container.Image, "] Container: ", container.ID, ", Command: ", container.Command) + } } -func latestDockerID() string { - /* Get latest Docker container ID by image name - out: string container ID - */ - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - panic(err) - } - defer cli.Close() +func latestDockerID(labelKey string, labelValue string) string { + /* Get latest Docker container ID by image label + in(1): string label key + in(2): string label value + out: string container ID + */ + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() - containers, err := cli.ContainerList(ctx, container.ListOptions{All: true}) - if err != nil { - panic(err) - } + // Filter containers by the specified image label + containerFilters := filters.NewArgs() + containerFilters.Add("label", fmt.Sprintf("%s=%s", labelKey, labelValue)) - var latestContainer types.Container - for _, container := range containers { - if latestContainer.ID == "" || container.Created > latestContainer.Created { - latestContainer = container - } - } + containers, err := cli.ContainerList(ctx, container.ListOptions{ + All: true, + Filters: containerFilters, + }) + if err != nil { + panic(err) + } - if latestContainer.ID == "" { - fmt.Println("No container found with the specified image name.") - } + var latestContainer types.Container + for _, container := range containers { + if latestContainer.ID == "" || container.Created > latestContainer.Created { + latestContainer = container + } + } - return latestContainer.ID + if latestContainer.ID == "" { + fmt.Println("No container found with the specified image label.") + return "" + } + + return latestContainer.ID } func DockerExec(contid string, WorkingDir string) { @@ -123,7 +144,9 @@ func DockerExec(contid string, WorkingDir string) { defer cli.Close() if contid == "" { - contid = latestDockerID() + labelKey := "org.container.project" // TODO: maybe to move in global + labelValue := "rfswift" // TODO: maybe to move in global + contid = latestDockerID(labelKey, labelValue) } if err := cli.ContainerStart(ctx, contid, container.StartOptions{}); err != nil { @@ -345,35 +368,50 @@ func DockerCommit(contid string) { } func DockerPull(imageref string, imagetag string) { - /* Pulls an image from a registry - in(1): string Image reference - in(2): string Image tag target - */ + /* Pulls an image from a registry + in(1): string Image reference + in(2): string Image tag target + */ - if imagetag == "" { // if tag is empty, keep same tag - imagetag = imageref - } + if imagetag == "" { // if tag is empty, keep same tag + imagetag = imageref + } - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - panic(err) - } - defer cli.Close() + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() - out, err := cli.ImagePull(ctx, imageref, image.PullOptions{}) - if err != nil { - panic(err) - } + out, err := cli.ImagePull(ctx, imageref, image.PullOptions{}) + if err != nil { + panic(err) + } + defer out.Close() - defer out.Close() + fd, isTerminal := term.GetFdInfo(os.Stdout) + jsonDecoder := json.NewDecoder(out) - io.Copy(os.Stdout, out) + for { + var msg jsonmessage.JSONMessage + if err := jsonDecoder.Decode(&msg); err == io.EOF { + break + } else if err != nil { + panic(err) + } - err = cli.ImageTag(ctx, imageref, imagetag) - if err != nil { - panic(err) - } + if isTerminal { + _ = jsonmessage.DisplayJSONMessagesStream(out, os.Stdout, fd, isTerminal, nil) + } else { + fmt.Println(msg) + } + } + + err = cli.ImageTag(ctx, imageref, imagetag) + if err != nil { + panic(err) + } } func DockerRename(imageref string, imagetag string) { @@ -413,3 +451,60 @@ func DockerRemove(contid string) { fmt.Println("[+] Container removed!") } } + +func ListImages(labelKey string, labelValue string) ([]image.Summary, error) { + /* List RF Swift Images + in(1): string labelKey + in(2): string labelValue + out: Tuple ImageSummary, error + */ + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return nil, err + } + defer cli.Close() + + // Filter images by the specified image label + imagesFilters := filters.NewArgs() + imagesFilters.Add("label", fmt.Sprintf("%s=%s", labelKey, labelValue)) + + images, err := cli.ImageList(ctx, image.ListOptions{ + All: true, + Filters: imagesFilters, + }) + if err != nil { + return nil, err + } + + // Only display images with RepoTags + var filteredImages []image.Summary + for _, image := range images { + if len(image.RepoTags) > 0 { + filteredImages = append(filteredImages, image) + } + } + + return filteredImages, nil +} + +func DeleteImage(imageIDOrTag string) error { + /* Delete an image + in(1): string image ID or tag + out: error + */ + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return err + } + defer cli.Close() + + _, err = cli.ImageRemove(ctx, imageIDOrTag, types.ImageRemoveOptions{Force: true, PruneChildren: true}) + if err != nil { + return err + } + + fmt.Printf("Successfully deleted image: %s\n", imageIDOrTag) + return nil +} \ No newline at end of file diff --git a/scripts/telecom_software.sh b/scripts/telecom_software.sh new file mode 100644 index 0000000..f39266c --- /dev/null +++ b/scripts/telecom_software.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +function yatebts_blade2_soft_install() { # TODO: make few tests with new Nuand libs, if unstable: fetch 3a411c87c2416dc68030d5823d73ebf3f797a145 + goodecho "[+] Feching YateBTS from Nuand" + [ -d /root/thirdparty ] || mkdir /root/thirdparty + cd /root/thirdparty + installfromnet "wget https://nuand.com/downloads/yate-rc-3.tar.gz" + goodecho "[+] Installing Yate" + cd yate + ./autogen.sh + ./configure --prefix=/usr/local + make -j$(nproc) + make install + ldconfig + cd .. + goodecho "[+] Installing YateBTS" + cd yatebts + ./autogen.sh + ./configure --prefix=/usr/local + make -j$(nproc) + make install + ldconfig + goodecho "[+] Creating some confs" + touch /usr/local/etc/yate/snmp_data.conf /usr/local/etc/yate/tmsidata.conf + # chown root:yate /usr/local/etc/yate/*.conf # TODO: next when dropping root privs + chmod g+w /usr/local/etc/yate/*.conf + colorecho "[+] Now it's time for you to configure ;)" +} + + + +### TODO: more More! \ No newline at end of file