How to extract kubernetes pod command execution result attributes

Issue

I am connecting to pod via client-Go and I want to get the properties of the file directory

func GetPodFiles(c *gin.Context)  {
    client, _ := Init.ClusterID(c)
    path := c.DefaultQuery("path", "/")
    cmd := []string{
        "sh",
        "-c",
        fmt.Sprintf("ls -l %s", path),
    }
    config, _ := Init.ClusterCfg(c)
    req := client.CoreV1().RESTClient().Post().
        Resource("pods").
        Name("nacos-0").
        Namespace("default").SubResource("exec").Param("container", "nacos")
    req.VersionedParams(
        &v1.PodExecOptions{
            Command: cmd,
            Stdin:   false,
            Stdout:  true,
            Stderr:  true,
            TTY:     false,
        },
        scheme.ParameterCodec,
    )

    var stdout, stderr bytes.Buffer
    exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
    if err != nil {
        response.FailWithMessage(response.InternalServerError, err.Error(), c)
        return
    }
    err = exec.Stream(remotecommand.StreamOptions{
        Stdin:  nil,
        Stdout: &stdout,
        Stderr: &stderr,
    })
    if err != nil {
        response.FailWithMessage(response.InternalServerError, "Error obtaining file", c)
        return
    }

    fmt.Println(stdout.String())
}

Execution Result Output

total 0
lrwxrwxrwx   1 root root   7 Jun  1  2018 bin -> usr/bin
drwxr-xr-x   5 root root 360 Feb 16 16:39 dev
lrwxrwxrwx   1 root root   8 Jun  1  2018 sbin -> usr/sbin
drwxr-xr-x   2 root root   6 Apr 11  2018 srv

Expect the result

"data": [
        {
            "perm": "drwxr-xr-x",
            "mod_time": "2022-03-02 15:02:15",
            "kind": "d",
            "name": "temp",
            "size": ""
        },
]

Is there a good way or a golang third-party library to handle it. Please let me know. Thank you

Solution

In a Kubernetes pod you can execute the stat linux command instead of ls command.

$ stat yourFileOrDirName

The output of this command by default is like this:

  File: yourFileOrDirName
  Size: 346             Blocks: 0          IO Block: 4096   directory
Device: 51h/82d Inode: 40431       Links: 1
Access: (0755/drwxr-xr-x)  Uid: ( 1000/ username)   Gid: ( 1000/ groupname)
Access: 2022-03-02 11:59:07.384821351 +0100
Modify: 2022-03-02 11:58:48.733821177 +0100
Change: 2022-03-02 11:58:48.733821177 +0100
 Birth: 2021-12-21 11:12:05.571841723 +0100

But you can tweak its output like this:

$ stat --printf="%n,%A,%y,%s" yourFileOrDirName

where %n – file name, %A – permission bits and file type in human readable form, %y – time of last data modification human-readable, %s – total size, in bytes. You can also choose any character as a delimiter instead of comma.

the output will be:

yourFileOrDirName,drwxr-xr-x,2022-03-02 11:58:48.733821177 +0100,346

See more info about the stat command here.

After you get such output, I believe you can easily ‘convert’ it to json format if you really need it.

Furthermore, you can run the stat command like this:

$ stat --printf="{\"data\":[{\"name\":\"%n\",\"perm\":\"%A\",\"mod_time\":\"%y\",\"size\":\"%s\"}]}" yourFileOrDirName

Or as @mdaniel suggested, since the command does not contain any shell variables, nor a ', the cleaner command is:

stat --printf='{"data":[{"name":"%n","perm":"%A","mod_time":"%y","size":"%s"}]}' yourFileOrDirName

and get the DIY json output:

{"data":[{"name":"yourFileOrDirName","perm":"drwxrwxr-x","mod_time":"2022-02-04 15:17:27.000000000 +0000","size":"4096"}]}

Answered By – mozello

Answer Checked By – Jay B. (GoLangFix Admin)

Leave a Reply

Your email address will not be published.