jsonappendyq

How to append proxies items to an existing /etc/docker/daemon.json file with yq


I have the following /etc/docker/daemon.json file :

$ yq . /etc/docker/daemon.json
{
  "dns": [
    "a.b.c.d1"
  ]
}
$

I tried this command to append proxy lines to this file with yq :

$ yq '. + { proxies : {  "http-proxy":env($http_proxy) , "https-proxy":env($https_proxy) , "no-proxy":env($no_proxy)} }' /etc/docker/daemon.json
Error: 1:7: invalid input text "proxies : {  \"ht..."
$

I also tried this yq command :

$ yq '. + { .proxies = {  .http-proxy=env($http_proxy) , .https-proxy=env($https_proxy) , .no-proxy=env($no_proxy)} }' /etc/docker/daemon.json
Error: !!str () cannot be added to a !!map ()
$

I expect this json :

{
  "dns": [
    "a.b.c.d1"
  ],
  "proxies": {
    "http-proxy": "http://x.y.z.t:8080",
    "https-proxy": "http://x.y.z.t:8080",
    "no-proxy": "localhost,127.0.0.1,localaddress,.localdomain.com"
  }
}

How can I do that with yq ?


Solution

  • Apparently, you're using mikefarah/yq, which requires object keys to be wrapped in quotes (unlike kislyuk/yq, for example), so change proxies: to "proxies": to resolve Error: 1:7: invalid input text "proxies: {\"ht...". Also, env expects its parameter without a $ sign. So, as an example, this would work:

    http_proxy=a https_proxy=b no_proxy=c yq '. + {"proxies": {
      "http-proxy": env(http_proxy),
      "https-proxy": env(https_proxy),
      "no-proxy": env(no_proxy)
    }}' /etc/docker/daemon.json
    

    Alternatively, use the .proxies = syntax from your second attempt, which doesn't require the quotes but as an expression it needs to be outside the curly braces:

    http_proxy=a https_proxy=b no_proxy=c yq '.proxies = {
      "http-proxy": env(http_proxy),
      "https-proxy": env(https_proxy),
      "no-proxy": env(no_proxy)
    }' /etc/docker/daemon.json
    

    Both examples produce (tested with mikefarah/yq v4.44.6):

    {
      "dns": [
        "a.b.c.d1"
      ],
      "proxies": {
        "http-proxy": "a",
        "https-proxy": "b",
        "no-proxy": "c"
      }
    }
    

    Note: If you don't want the environment variables be parsed as YAML nodes, use envstr instead which always parses the values as strings.