container-logs/main.go

123 lines
2.7 KiB
Go

package main
import (
"context"
"io"
"os"
"strings"
"git.cryptic.systems/volker.raschek/dockerutils"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/spf13/cobra"
)
var (
version string
allContainers bool
ids []string
names []string
rawLabels []string
printStderr bool
printStdout bool
)
func main() {
rootCmd := &cobra.Command{
Use: "container-log",
Short: "Write logs of containers on stdout",
Version: version,
RunE: runRootCmd,
}
rootCmd.Flags().BoolVarP(&allContainers, "all", "a", false, "All containers, including those that are switched off or aborted")
rootCmd.Flags().StringArrayVarP(&ids, "id", "i", make([]string, 0), "Select container by id")
rootCmd.Flags().StringArrayVarP(&names, "name", "n", make([]string, 0), "Select container by name")
rootCmd.Flags().StringArrayVarP(&rawLabels, "label", "l", make([]string, 0), "Select container by labels")
completionCmd := &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate completion script",
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.ExactValidArgs(1),
Run: func(cmd *cobra.Command, args []string) {
switch args[0] {
case "bash":
cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
cmd.Root().GenFishCompletion(os.Stdout, true)
}
},
}
rootCmd.AddCommand(completionCmd)
rootCmd.Execute()
}
func runRootCmd(cmd *cobra.Command, args []string) error {
dockerClient, err := dockerutils.New()
if err != nil {
return err
}
ctx := context.Background()
filterArgs := filters.NewArgs()
if len(rawLabels) > 0 {
for i := range rawLabels {
filterArgs.Add("label", rawLabels[i])
}
}
if len(names) > 0 {
for i := range names {
filterArgs.Add("name", names[i])
}
}
containers, err := dockerClient.ContainerList(ctx, types.ContainerListOptions{
All: allContainers,
Filters: filterArgs,
})
if err != nil {
return err
}
if len(ids) > 0 {
containers = filterByIDs(containers, ids...)
}
for i := range containers {
rc, err := dockerClient.ContainerLogs(ctx, containers[i].ID, types.ContainerLogsOptions{ShowStderr: true, ShowStdout: true})
if err != nil {
return err
}
defer rc.Close()
_, err = io.Copy(os.Stdout, rc)
if err != nil {
return err
}
}
return nil
}
func filterByIDs(containers []types.Container, ids ...string) []types.Container {
cachedContainers := make([]types.Container, 0)
LOOP:
for i := range containers {
for j := range ids {
if strings.HasPrefix(containers[i].ID, ids[j]) {
cachedContainers = append(cachedContainers, containers[i])
continue LOOP
}
}
}
return cachedContainers
}