cinder-volume-setup revision 2892
286N/A#!/usr/bin/python2.6
286N/A
286N/A# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
286N/A#
286N/A# Licensed under the Apache License, Version 2.0 (the "License"); you may
286N/A# not use this file except in compliance with the License. You may obtain
286N/A# a copy of the License at
286N/A#
286N/A# http://www.apache.org/licenses/LICENSE-2.0
286N/A#
286N/A# Unless required by applicable law or agreed to in writing, software
286N/A# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
286N/A# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
286N/A# License for the specific language governing permissions and limitations
286N/A# under the License.
286N/A
286N/Aimport ConfigParser
286N/Aimport os
286N/Aimport sys
286N/A
286N/Aimport smf_include
286N/A
286N/Afrom subprocess import CalledProcessError, Popen, PIPE, check_call
286N/A
286N/A
286N/Adef start():
286N/A """ retrieves the setting for 'zfs_volume_base' from Cinder's conf file in
286N/A order to set it up properly for Cinder to use.
286N/A
286N/A """
286N/A cinder_conf = "/etc/cinder/cinder.conf"
286N/A if not os.path.exists(cinder_conf):
286N/A print "%s doesn't exist" % cinder_conf
286N/A return smf_include.SMF_EXIT_ERR_CONFIG
286N/A
286N/A parser = ConfigParser.ConfigParser()
286N/A parser.read(cinder_conf)
286N/A
286N/A # retrieve the top-level dataset or just get the default (rpool/cinder)
286N/A try:
286N/A top_ds = parser.get("DEFAULT", "zfs_volume_base")
286N/A except ConfigParser.NoOptionError:
286N/A top_ds = "rpool/cinder"
286N/A
286N/A # look to see if the dataset exists
286N/A cmd = ["/usr/sbin/zfs", "list", top_ds]
286N/A try:
286N/A check_call(cmd, stdout=PIPE, stderr=PIPE)
286N/A except CalledProcessError as err:
286N/A # the dataset doesn't exist, so go create it
286N/A try:
286N/A check_call(["/usr/sbin/zfs", "create", "-p", top_ds])
286N/A except CalledProcessError as err:
286N/A print "unable to create %s: %s" % (top_ds, err)
286N/A return smf_include.SMF_EXIT_ERR_CONFIG
286N/A
286N/A # get the mountpoint
286N/A cmd = ["/usr/sbin/zfs", "get", "-H", "-o", "value", "mountpoint", top_ds]
286N/A p = Popen(cmd, stdout=PIPE, stderr=PIPE)
286N/A mountpoint, error = p.communicate()
286N/A if p.returncode != 0:
286N/A print "unable to determine mountpoint of %s: %s" % (top_ds, error)
286N/A return smf_include.SMF_EXIT_ERR_CONFIG
286N/A
286N/A p = Popen(["/usr/bin/ls", "-dv", mountpoint], stdout=PIPE, stderr=PIPE)
286N/A output, error = p.communicate()
286N/A
286N/A if "user:cinder:add_subdirectory/append_data:allow" not in output:
286N/A # set an ACL to all mountpoint access
286N/A try:
286N/A check_call(["/usr/bin/chmod",
286N/A "A+user:cinder:add_subdirectory:allow",
286N/A mountpoint.strip()])
286N/A except CalledProcessError as err:
286N/A print "ACL creation for mountpoint access of "
286N/A print "%s to 'cinder' failed: %s" % (top_ds, err)
286N/A return smf_include.SMF_EXIT_ERR_CONFIG
286N/A
286N/A # set delegation
286N/A cmd = ["/usr/sbin/zfs", "allow", "cinder",
286N/A "clone,create,destroy,mount,snapshot", top_ds]
286N/A try:
286N/A check_call(cmd)
286N/A except CalledProcessError as err:
286N/A print "delegation of %s to 'cinder' failed: %s" % (top_ds, err)
286N/A return smf_include.SMF_EXIT_ERR_CONFIG
286N/A
286N/A return smf_include.SMF_EXIT_OK
286N/A
286N/Aif __name__ == "__main__":
286N/A os.putenv("LC_ALL", "C")
286N/A smf_include.smf_main()
286N/A