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