Background:

The Hyper-V hypervisor uses a Windows operating system for it's Dom0 / Parent Partition. This means NFS support is relatively poor. Instead, Windows offers excellent support for CIFS.

To take advantage of CIFS support, a proposal was made to add CIFS to the set of storage types available with CloudStack.

Feature:

Add CIFS secondary storage

Spec:

Allow the user to specify CIFS storage by way of a URI. This URI will follow RFC 2986 syntax (see: http://tools.ietf.org/html/rfc3986#section-3). Specifically, the scheme will be "cifs", the authority will name the server hosting the cifs share, and the path will identify the shared folder. E.g. cifs://192.168.1.128/my_folder

Username and password will be dealt using the current design for NFS secondary storage. Updated, see Design Details below

Implementation:

Use existing secondary storage agent with CIFS secondary storage and deploy using the existing secondary storage workflow. The existing workflow can be
used, because CIFS support is already available on our System VMs. E.g. mount -t cifs //192.168.1.128/CSHV3 /mnt/cifs -o username=administrator,password='my_password' will work in the case of a CIFS share running on a Windows Server 2012 that is not domain joined.

Use existing NfsTO object to represent a CIFS data store. The workflows for CIFS and NFS are identical, because they are both mounted on the local file system. Creating a subclass of NfsTO for CIFS should be avoided. This subclass introduces maintenance problems for conditionals that test for NfsTO. In addition, the database schema would probably be affected by a new data store type. In both cases, additional testing is required without any gains.

Update setup operations responsible for putting mounting the CIFS share on the local operating system. E.g. the implementation of SecStorageSetupCommand must treat a CIFS scheme URI slightly different.

Update validation in API calls and database operations involving NFS URIs. It should be possible to pass a scheme with a CIFS URI.

Note that CIFS cannot be used for primary storage. You would need the latest SMB (3.0) for this.

Development environment:

The work will be done using Quick Cloud secondary storage services. Quick Cloud allows the secondary storage to run as a local service. This makes it quicker to redeploy and to gather feedback such as logs. Quick Cloud would be run local to the management server. This will most likely be a Linux environment.

I propose to use logging for debugging. For the most part, I'm not changing the code.

The Hyper-V hypervisor will be supported in the first phase. I'm using the existing motion service, so the deciding factor is whether the hypervisor can mount CIFS storage. I haven't looked into this for other hypervisor types other than Hyper-V.

Design Details

Expressing CIFS share in a URI: why? how?

Encoding the CIFS share informatin in URI form allows NFS-centric code to be reused. Existing code takes advantage of URI format and data structures in validation code and database code.

Unfortunately, there is no standard for a URI for CIFS. E.g. smb URI never accepted, see https://datatracker.ietf.org/doc/draft-crhertel-smb-url

Our alternative to use the existing URI standard, introduce a "cifs" scheme, and encode mount parameters in query parameters.

The scheme will be "cifs". This allows us to mirror existing NFS validation code, which is triggered when a URI's scheme is "nfs"

The CIFS hostname can be comfortably accommodated in the host subcomponent of the URI authority (see http://tools.ietf.org/html/rfc3986#section-3.2.2)

The CIFS share name can be comfortably accommodated by the path path of URI for the share name see (http://tools.ietf.org/html/rfc3986#section-3.3)

E.g. \\192.168.1.128\CSHV3 becomes cifs://192.168.1.128/CSHV3

The CIFS URI needs to capture additional details not required in NFS. E.g. when using the Linux mount command, the user, password and domain of a CIFS share are specified separately to the remote device path using the '-o' parameter. Http query parameters offer a simple solution to passing this information. Recall that an the URI's query is after the '?' that follows the path, see http://tools.ietf.org/html/rfc3986#section-3.4 In our case, query parameters will be key=value pairs, linked by '&', values are URL encoded. See http://en.wikipedia.org/wiki/Query_string#URL_encoding

E.g. including user=root,password=1pass@word1 would make the URI look like cifs://192.168.1.128/CSHV3?user=root+password=1pass%40word1

Note that username and password are not added to the userinfo section of the URI authority. The URI spec says this is deprecated (see http://tools.ietf.org/html/rfc3986#section-3.2.1 says it's deprecated.)

Note that passing password / username plain text is a short term solution until a secure means of passing the authentication details is introduced.

It is left to the GUI developer to decide how to convert user input to the URI. They will probably hide the encoding from the user.

Sample:

cifs://192.168.1.128/CSHV3?user=root+password=1pass%40word1

corresponds to

mount -t cifs //192.168.1.128/CSHV3 /root/github/cshv3/client/tmp -o 'user=root,password=1pass@word1'

  • No labels