Skip to content

Instantly share code, notes, and snippets.

@thaJeztah
Last active September 10, 2015 22:55
Show Gist options
  • Save thaJeztah/6185659e4978789fb2b2 to your computer and use it in GitHub Desktop.
Save thaJeztah/6185659e4978789fb2b2 to your computer and use it in GitHub Desktop.
Quick testing of regexes for Windows volumes

Quick 'n dirty testing regexes for Windows volumes

See docker issue moby/moby#16140

This regex captures Windows paths nicely;

^[a-zA-Z]:(\\[^\:\\]+)*\\?$

And long paths (e.g. \\?\C:\Program files (x86)\notepad.exe):

^(?P<completepath>(?:\\\\\?\\)?(?P<drive>[a-zA-Z]):(?P<path>(?:\\[^\:\\]+)*\\?))$

Named volumes;

^[a-zA-Z0-9][a-zA-Z0-9_.-]+$

Combined <volumename>|<path1> (using named capture groups);

^((?P<volumename>[a-zA-Z0-9][a-zA-Z0-9_.-]+)|(?P<path1>[a-zA-Z]:(\\[^\:\\]+)*\\?)))$

Adding path2 (container path or, just the single path); <volumename>|<path1>[:<path2>]

^((?P<volumename>[a-zA-Z0-9][a-zA-Z0-9_.-]+)|(?P<path1>[a-zA-Z]:(\\[^\:\\]+)*\\?))(:(?P<path2>[a-zA-Z]:(\\[^\:\\]+)*\\?))?$

Read/Write options [ro|rw];

(:(?P<readwrite>ro|rw))?

Relabel options [,[z|Z]]

(,(?P<relabel>z|Z))?

And, all of the above: <volumename>|<path1>[:<path2>[:<readwrite>][,[<relabel>]]

^((?P<volumename>[a-zA-Z0-9][a-zA-Z0-9_.-]+)|(?P<path1>[a-zA-Z]:(\\[^\:\\]+)*\\?))(:(?P<path2>[a-zA-Z]:(\\[^\:\\]+)*\\?)(:(?P<readwrite>ro|rw))?(,(?P<relabel>z|Z))?)?$

Try out the above on https://regex-golang.appspot.com/assets/html/index.html

Feeding this with;

myvolume:C:\Program files(x86)\Docker\:rw,z

Gives:

part value
volumename myvolume
path1 null
path2 C:\Program files(x86)\Docker\
readwrite rw
relabel z

Feeding this with;

D:\Documents and Settings\thajeztah\application data\:C:\Program files(x86)\Docker\:rw,z

Gives:

part value
volumename null
path1 D:\Documents and Settings\thajeztah\application data\
path2 C:\Program files(x86)\Docker\
readwrite rw
relabel z
@lowenna
Copy link

lowenna commented Sep 9, 2015

This is close :) Thank you @thaJeztah 👍

If you look at opts.go function validatePath, this is where the client does validation. I'd need to make a common function that's used by both the daemon and the client. validatePath is unfortunately also used to validate both device and volume paths.

The syntax of a user supplied string is one of
containerPath [no hostdir or mode specified]
containerPath:mode [no hostdir specified]
hostdir:containerPath [no mode specified]
hostdir:containerPath:mode

where mode is readwrite[,relabel](brackets are optional, not brackets as per IRC discussion :) )

containerPath on Windows can be one of:

  • a drive (eg d:)
  • a path (eg c:\mymountpoint or c:\mymountpoint\ with the trailing )

a hostDir is similar to containerPath, except that it cannot be a drive.

For now, Windows will not support any relabel, so mode will always be empty or rw|ro. (In fact, we might only support rw for TP4)

Paths can contain spaces
Paths and drive letters are case insensitive.
Paths cannot be UNC paths such as \server\something
Paths can optionally be specified as long filepaths prefixed \?\ such as \?\c:\my\very\long\path (greater than 160 chars), but \?\my\very\long\path is not valid as it isn't qualified with a drive letter

If this can be done in regex, I'll make the client and server side validation common.

@lowenna
Copy link

lowenna commented Sep 9, 2015

I was also looking at volume\volume.go for the mode/relabel bits. In Linux, it appears that the z|Z can both follow and prepend the rw|ro. Yikes, that one is horrible, and is probably better just to parse the mode in its entirety in regex, and use code that's there currently to split it into its one or two elements.

@lowenna
Copy link

lowenna commented Sep 10, 2015

@thaJeztah - I think there's one more update to what I put. In Windows, at least for TP4, we're only going to be supporting bind mounts, which means that the hostdir must be supplied. So the only valid syntaxes of the user supplied string I put above is incorrect. It can only be one of these:

hostdir:containerPath [no mode specified]
hostdir:containerPath:mode

@lowenna
Copy link

lowenna commented Sep 10, 2015

Looks like this works.

^(?P[a-zA-Z]:(?:[^\/:_?"<>|\r\n]+)):(?P([a-zA-Z]):((?:[^/:?"<>\r\n]+)_?))(:(?Pro|rw))?$

Only thing is hostdir will at a future date in Windows become optional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment