docker-archive / classicswarm

Swarm Classic: a container clustering system. Not to be confused with Docker Swarm which is at https://github.com/docker/swarmkit
Apache License 2.0
5.75k stars 1.08k forks source link

Problem Creating containers via API #670

Closed lewissw closed 6 years ago

lewissw commented 9 years ago

swarm instance logs the following when I try to create a container:

time="2015-04-24T09:09:36Z" level=info msg="HTTP request received" method=POST uri="/containers/create" time="2015-04-24T09:09:36Z" level=error msg="HTTP error: json: cannot unmarshal string into Go value of type []string" status=400

I'm guessing my json is missing an element that swarm is looking for, but the API doc doesn't say which of the json elements are mandatory. see: https://docs.docker.com/reference/api/docker_remote_api_v1.18/

Any thoughts?

abronan commented 9 years ago

Hi @lewissw,

Can you post more informations about your Swarm instances and Manager? Which version of swarm and docker are you using, etc?

aluzzardi commented 9 years ago

Could you also provide the JSON blog your application is passing to swarm so we may be able to reproduce the issue?

lewissw commented 9 years ago

As requested:

$ docker version
Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8/1.4.1
OS/Arch (client): linux/amd64
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8/1.4.1
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
swarm               latest              96b8c18d1208        10 days ago         7.248 MB

$ docker run -v /tmp:/tmp -i  -p 2222:2375 swarm -debug manage file:///tmp/my_cluster 

The JSON:

{  
    'Env':'[ "HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]',
    'Hostname':'mynginx0',
    'Entrypoint':'',
    'PortSpecs':'',
    'Memory':0,
    'OnBuild':'',
    'OpenStdin':'false',
    'Cpuset':'',
    'User':'',
    'CpuShares':0,
    'AttachStdout':'false',
    'NetworkDisabled':'false',
    'WorkingDir':'',
    'Cmd':'[ "/run-apache.sh" ]',
    'StdinOnce':'false',
    'AttachStdin':'false',
    'Volumes':'',
    'MemorySwap':0,
    'Tty':'false',
    'AttachStderr':'false',
    'Domainname':'mynginx0',
    'Image':'nginx',
    'ExposedPorts':'{"80/tcp": "{}" }'
}

Thanks for your help

abronan commented 9 years ago

A missing element does not seem to be the cause here. Probably just a type mismatch between two elements (thus the unmarshalling exception from string -> []string). But I see nothing wrong with this JSON output (excluding the fact this is not valid JSON due to the use of single quotes).

@lewissw Does docker run fails with this exact same config? This would help if you can give us the complete docker run command so we can try to reproduce.

cc/ @aluzzardi Can you take a look at the JSON output to make sure I didn't miss something obvious?

lewissw commented 9 years ago

Hi the JSON is missing the double quotes, as I have dumped it out from python script, but double quotes should be presented to API.

Yes I can start the container if I go directly to Docker remote API port 2375, but get the error above if accessing swarm on port 2222 (as per my swarm manage command line above). I have simplified the api json playload to the following, but I still get the marshalling error:

time="2015-04-28T08:56:55Z" level=error msg="HTTP error: json: cannot unmarshal string into Go value of type map[string]struct {}" status=400
{  
    'Volumes':'',
    'Tty':'false',
    'MemorySwap':0,
    'Domainname':'mynginx0',
    'WorkingDir':'',
    'Image':'nginx',
    'Hostname':'mynginx0',
    'StdinOnce':'false',
    'PortSpecs':'',
    'AttachStdin':'false',
    'User':'',
    'Env':'',
    'Memory':0,
    'AttachStderr':'false',
    'AttachStdout':'false',
    'OpenStdin':'false'
}
eabay commented 9 years ago

I got the same error when trying to create a container with the following config:

{
   "Image":"nsqio/nsq",
   "Cmd":"/nsqlookupd",
   "HostConfig":{
      "PortBindings":{
         "4160/tcp":[{"HostPort":""}],
         "4161/tcp":[{"HostPort":""}]
      },
      "RestartPolicy":{
         "Name":"always"
      }
   }
}

I changed the Cmd field to an array (["/nsqlookupd"]) and problem solved.

It doesn't return error from docker remote api whether the value is a string or an array of strings as documentation explains:

Cmd - Command to run specified as a string or an array of strings.
daemonza commented 8 years ago

Using the example container create for server API version 1.21 (http://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#create-a-container) I get the exact same json error

using

   {
       "Hostname": "",
       "Domainname": "",
       "User": "",
       "AttachStdin": false,
       "AttachStdout": true,
       "AttachStderr": true,
       "Tty": false,
       "OpenStdin": false,
       "StdinOnce": false,
       "Env": null,
       "Cmd": [
               "date"
       ],
       "Entrypoint": "",
       "Image": "ubuntu",
       "Labels": {
               "com.example.vendor": "Acme",
               "com.example.license": "GPL",
               "com.example.version": "1.0"
       },
       "Mounts": [
         {
           "Source": "/data",
           "Destination": "/data",
           "Mode": "ro,Z",
           "RW": false
         }
       ],
       "WorkingDir": "",
       "NetworkDisabled": false,
       "MacAddress": "12:34:56:78:9a:bc",
       "ExposedPorts": {
               "22/tcp": {}
       },
       "StopSignal": "SIGTERM",
       "HostConfig": {
         "Binds": ["/tmp:/tmp"],
         "Links": ["redis3:redis"],
         "LxcConf": {"lxc.utsname":"docker"},
         "Memory": 0,
         "MemorySwap": 0,
         "MemoryReservation": 0,
         "KernelMemory": 0,
         "CpuShares": 512,
         "CpuPeriod": 100000,
         "CpuQuota": 50000,
         "CpusetCpus": "0,1",
         "CpusetMems": "0,1",
         "BlkioWeight": 300,
         "MemorySwappiness": 60,
         "OomKillDisable": false,
         "PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
         "PublishAllPorts": false,
         "Privileged": false,
         "ReadonlyRootfs": false,
         "Dns": ["8.8.8.8"],
         "DnsOptions": [""],
         "DnsSearch": [""],
         "ExtraHosts": null,
         "VolumesFrom": ["parent", "other:ro"],
         "CapAdd": ["NET_ADMIN"],
         "CapDrop": ["MKNOD"],
         "RestartPolicy": { "Name": "", "MaximumRetryCount": 0 },
         "NetworkMode": "bridge",
         "Devices": [],
         "Ulimits": [{}],
         "LogConfig": { "Type": "json-file", "Config": {} },
         "SecurityOpt": [""],
         "CgroupParent": "",
         "VolumeDriver": ""
      }
  }

response I get back

HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Mon, 09 Nov 2015 14:35:13 GMT
Content-Length: 61
Connection: close

json: cannot unmarshal string into Go value of type []string
viniciushsantana commented 8 years ago

I have the same problem as @daemonza and can't figure out why.

Running Docker Engine 1.9.1, build a34a1d5 on Debian and I got the same responde using the example container or any other.

HTTP/1.1 400 Bad Request
<= Recv data, 61 bytes (0x3d)
0000: json: cannot unmarshal string into Go value of type []string. 

Any ideas?

viniciushsantana commented 8 years ago

I found the problem.

The Docker/Go json parser can't handle empty fields like "Entrypoint": "". The official documentation should alert about that? Or the example should not have empty fields?

nishanttotla commented 6 years ago

Closing due to lack of activity. Please reopen if you wish to continue discussing it.

rizwan92 commented 5 years ago

I am facing the same issue as @daemonza is facing. error is the cause of these two lines

       PortBindings: { '27017/tcp': [{ HostPort: '8000' }] },
          ExposedPorts: { '27017/tcp': {} },
{ message: 'json: cannot unmarshal string into Go struct field ContainerConfigWrapper.ExposedPorts of type nat.PortSet' } } }

I think go lang, not understanding this values "27017/tcp"