moby: docker stack deploy failed if volume name with special character like "@" used in the compose file

Description

I am trying to use vSphere Docker Volume Service with “docker stack deploy” command to deploy a stack with the following compose file.

version: '3'

services:
   db:
     image: mariadb
     deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      placement:
        constraints:
          - node.role == worker
     environment:
       MYSQL_ROOT_PASSWORD: rootpasswd
       MYSQL_USER: wp
       MYSQL_PASSWORD: wppasswd
       MYSQL_DATABASE: wp
     volumes:
       - mariadb@sharedVmfs-0:/var/lib/mysql

   web:
     image: wordpress:latest
     deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
     depends_on:
       - db
     ports:
       - "8080:80"
     environment:
       WORDPRESS_DB_USER: wp
       WORDPRESS_DB_PASSWORD: wppasswd
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_NAME: wp

volumes:
   mariadb@sharedVmfs-0:
     driver: vsphere
     driver_opts:
       size: 1Gb
       diskformat: zeroedthick
                                                            

In that compose file, the volume is created by vSphere Docker Volume Service, and has the format like vol_name@datastore (mariadb@sharedVmfs-0 in the compose file). docker stack deploy failed with error like:

“mariadb@sharedVmfs-0 Additional property mariadb@sharedVmfs-0 is not allowed”.

Steps to reproduce the issue:

  1. setup a swarm cluster with three VMs(1 master + 2 worker), each VMs install the vSphere Docker Volume Service
  2. run docker stack deploy -c docker-compose-vsphere.yml wordpress in the master node to deploy the stack
  3. Actually, this problem is not related to the specific volume plugin, and should be reproducible if the name of the volume used in the compose file includes special character like “@”

Describe the results you received:

root@sc-rdops-vm02-dhcp-52-237:~# docker stack deploy -c docker-compose-vsphere.yml wordpress
mariadb@sharedVmfs-0 Additional property mariadb@sharedVmfs-0 is not allowed

It looks to me that volume name including special characters like “@” cannot be used in the compose file.

Describe the results you expected: I expect docker stack deploy works when the name of volume includes special character like “@”.

I know one of the workaround is to pre-create the volume mariadb@sharedVmfs-0 , and then mark the volume as “external” in the compose file like this:

volumes:
   mariadb:
     external:
        name:  mariadb@sharedVmfs-0

It seems that most docker API can support volume name with special characters for volumes created by volume plugin, for example, I can create the volume mariadb@sharedVmfs-0 - using the volume plugin:

root@sc-rdops-vm02-dhcp-52-237:~# docker volume create --driver=vsphere --name=mariadb@sharedVmfs-0 -o size=1gb
mariadb@sharedVmfs-0
root@sc-rdops-vm02-dhcp-52-237:~# 
root@sc-rdops-vm02-dhcp-52-237:~# 
root@sc-rdops-vm02-dhcp-52-237:~# docker volume ls
DRIVER              VOLUME NAME
vsphere:latest      mariadb@sharedVmfs-0

So I think docker stack deploy should also work with volume name which includes special character like “@”.

Additional information you deem important (e.g. issue happens only occasionally):

Output of docker version:

root@sc-rdops-vm02-dhcp-52-237:~# docker version
Client:
 Version:      17.03.1-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Fri Mar 24 00:40:33 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.1-ce
 API version:  1.27 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Fri Mar 24 00:40:33 2017
 OS/Arch:      linux/amd64
 Experimental: false

Output of docker info:

root@sc-rdops-vm02-dhcp-52-237:~# docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 4
Server Version: 17.03.1-ce
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 25
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: bridge host macvlan null overlay
Swarm: active
 NodeID: jov3lt7f7nd6h646zhu08or77
 Is Manager: true
 ClusterID: rzpzvmjzmzfrzy570hc7wwpe6
 Managers: 1
 Nodes: 3
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot Interval: 10000
  Number of Old Snapshots to Retain: 0
  Heartbeat Tick: 1
  Election Tick: 3
 Dispatcher:
  Heartbeat Period: 5 seconds
 CA Configuration:
  Expiry Duration: 3 months
 Node Address: 10.192.88.178
 Manager Addresses:
  10.192.88.178:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 4ab9917febca54791c5f071a9d1f404867857fcc
runc version: 54296cf40ad8143b62dbcaa1d90e520a2136ddfe
init version: 949e6fa
Security Options:
 apparmor
Kernel Version: 4.2.0-27-generic
Operating System: Ubuntu 14.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.86 GiB
Name: sc-rdops-vm02-dhcp-52-237
ID: NINK:HV2F:IRM2:6JJU:XBVA:DW7J:CV5S:OARB:J4UL:O7S3:4LBA:7AVE
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

Additional environment details (AWS, VirtualBox, physical, etc.): Ubuntu VMs running on ESX

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 24 (13 by maintainers)

Most upvoted comments

Another question is say if I modify the schema file, how can I “re-generated” the variable which included in the Go source code? Do I need to use any specific tool to do that?

If I recall correctly; in the docker/cli repository, run;

go generate github.com/docker/cli/cli/compose/schema

@cpuguy83 I have a question about this fix. After removing the restriction in the YAML file, https://github.com/docker/cli/blob/3d58c3feaccc71512e692f27c18c109d7b262281/cli/compose/schema/data/config_schema_v3.3.json#L33-L42, I also want to apply the check to make sure when user uses local driver to create volume in YAML file, the volume name can only be “[a-zA-Z0-9][a-zA-Z0-9_.-]”. So I need to add check if the driver is local, and the volume name specified by user is not “[a-zA-Z0-9][a-zA-Z0-9_.-]”, an error need to be returned.

I mean some check like this

if driver == local && volume_name is not [a-zA-Z0-9][a-zA-Z0-9_.-] {
    return error("create %s includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.", volume_name)
}

My question is where is the right place to put this check?

  1. I have never submit a fix in docker/cli repo, so I need someone to help me with the review/checkin process, such as
  • how to build and install the docker CLI with the fix, and then I can verify in my local setup
  • what is a required test for a PR

Who is the better person from docker/cli maintainer to contact for this issue?

@AkihiroSuda unfortunately it’s not that simple; the a-zA-Z0-9 naming restriction applies only to the “local” volume driver, but not to plugins. So on a standalone daemon, volume names including such characters are allowed for volumes if they are using a plugin (the plugin then determines the accepted characters).

However, I know that for Swarm-mode resources some additional restrictions apply (e.g. overlay networks with a . in their name are not accepted in swarm-mode, because the . is reserved for future namespacing of resources).

I’m not sure if the same applies to volumes in swarm-mode, so will have to check.

ping @cpuguy83 @stevvooe PTAL