Common cinder interface additional improvements
This is a follow up to 459fe314fa
Minor issues in the code and tests are fixed, the release note is added,
configuration options are described as part of not yet exposed feature.
Change-Id: Ib466ee3970dcc1e141ddac38a54544f6a011549e
Partial-Bug: #1559691
This commit is contained in:
parent
28c48ea68f
commit
3b5aefa0b6
@ -383,13 +383,6 @@
|
||||
# Note: This option can be changed without restarting.
|
||||
#debug = false
|
||||
|
||||
# DEPRECATED: If set to false, the logging level will be set
|
||||
# to WARNING instead of the default INFO level. (boolean
|
||||
# value)
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
#verbose = true
|
||||
|
||||
# The name of a logging configuration file. This file is
|
||||
# appended to any existing logging configuration files. For
|
||||
# details about logging configuration files, see the Python
|
||||
@ -433,6 +426,13 @@
|
||||
# ignored if log_config_append is set. (boolean value)
|
||||
#use_syslog = false
|
||||
|
||||
# Enable journald for logging. If running in a systemd
|
||||
# environment you may wish to enable journal support. Doing so
|
||||
# will use the journal native protocol which includes
|
||||
# structured metadata in addition to log messages.This option
|
||||
# is ignored if log_config_append is set. (boolean value)
|
||||
#use_journal = false
|
||||
|
||||
# Syslog facility to receive log lines. This option is ignored
|
||||
# if log_config_append is set. (string value)
|
||||
#syslog_log_facility = LOG_USER
|
||||
@ -500,7 +500,6 @@
|
||||
#
|
||||
|
||||
# Size of RPC connection pool. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_conn_pool_size
|
||||
#rpc_conn_pool_size = 30
|
||||
|
||||
# The pool size limit for connections expiration policy
|
||||
@ -514,31 +513,25 @@
|
||||
# ZeroMQ bind address. Should be a wildcard (*), an ethernet
|
||||
# interface, or IP. The "host" option should point or resolve
|
||||
# to this address. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_bind_address
|
||||
#rpc_zmq_bind_address = *
|
||||
|
||||
# MatchMaker driver. (string value)
|
||||
# Allowed values: redis, sentinel, dummy
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_matchmaker
|
||||
#rpc_zmq_matchmaker = redis
|
||||
|
||||
# Number of ZeroMQ contexts, defaults to 1. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_contexts
|
||||
#rpc_zmq_contexts = 1
|
||||
|
||||
# Maximum number of ingress messages to locally buffer per
|
||||
# topic. Default is unlimited. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_topic_backlog
|
||||
#rpc_zmq_topic_backlog = <None>
|
||||
|
||||
# Directory for holding IPC sockets. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_ipc_dir
|
||||
#rpc_zmq_ipc_dir = /var/run/openstack
|
||||
|
||||
# Name of this node. Must be a valid hostname, FQDN, or IP
|
||||
# address. Must match "host" option, if running Nova. (string
|
||||
# value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_host
|
||||
#rpc_zmq_host = localhost
|
||||
|
||||
# Number of seconds to wait before all pending messages will
|
||||
@ -554,26 +547,21 @@
|
||||
# The default number of seconds that poll should wait. Poll
|
||||
# raises timeout exception when timeout expired. (integer
|
||||
# value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_poll_timeout
|
||||
#rpc_poll_timeout = 1
|
||||
|
||||
# Expiration timeout in seconds of a name service record about
|
||||
# existing target ( < 0 means no timeout). (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/zmq_target_expire
|
||||
#zmq_target_expire = 300
|
||||
|
||||
# Update period in seconds of a name service record about
|
||||
# existing target. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/zmq_target_update
|
||||
#zmq_target_update = 180
|
||||
|
||||
# Use PUB/SUB pattern for fanout methods. PUB/SUB always uses
|
||||
# proxy. (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/use_pub_sub
|
||||
#use_pub_sub = false
|
||||
|
||||
# Use ROUTER remote proxy. (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/use_router_proxy
|
||||
#use_router_proxy = false
|
||||
|
||||
# This option makes direct connections dynamic or static. It
|
||||
@ -590,25 +578,21 @@
|
||||
# Minimal port number for random ports range. (port value)
|
||||
# Minimum value: 0
|
||||
# Maximum value: 65535
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_min_port
|
||||
#rpc_zmq_min_port = 49153
|
||||
|
||||
# Maximal port number for random ports range. (integer value)
|
||||
# Minimum value: 1
|
||||
# Maximum value: 65536
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_max_port
|
||||
#rpc_zmq_max_port = 65536
|
||||
|
||||
# Number of retries to find free port number before fail with
|
||||
# ZMQBindError. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_bind_port_retries
|
||||
#rpc_zmq_bind_port_retries = 100
|
||||
|
||||
# Default serialization mechanism for
|
||||
# serializing/deserializing outgoing/incoming messages (string
|
||||
# value)
|
||||
# Allowed values: json, msgpack
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_serialization
|
||||
#rpc_zmq_serialization = json
|
||||
|
||||
# This option configures round-robin mode in zmq socket. True
|
||||
@ -684,7 +668,8 @@
|
||||
# taken from the matchmaker. (list value)
|
||||
#subscribe_on =
|
||||
|
||||
# Size of executor thread pool. (integer value)
|
||||
# Size of executor thread pool when executor is threading or
|
||||
# eventlet. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_thread_pool_size
|
||||
#executor_thread_pool_size = 64
|
||||
|
||||
@ -952,15 +937,16 @@
|
||||
#project_domain_name = <None>
|
||||
|
||||
# Project ID to scope to (string value)
|
||||
# Deprecated group/name - [cinder]/tenant-id
|
||||
# Deprecated group/name - [cinder]/tenant_id
|
||||
#project_id = <None>
|
||||
|
||||
# Project name to scope to (string value)
|
||||
# Deprecated group/name - [cinder]/tenant-name
|
||||
# Deprecated group/name - [cinder]/tenant_name
|
||||
#project_name = <None>
|
||||
|
||||
# Client retries in the case of a failed request connection.
|
||||
# (integer value)
|
||||
# This option is part of boot-from-volume work, which is not
|
||||
# currently exposed to users. (integer value)
|
||||
#retries = 3
|
||||
|
||||
# Tenant ID (string value)
|
||||
@ -976,13 +962,11 @@
|
||||
#trust_id = <None>
|
||||
|
||||
# URL for connecting to cinder. If set, the value must start
|
||||
# with either http:// or https://. (string value)
|
||||
# with either http:// or https://. This option is part of
|
||||
# boot-from-volume work, which is not currently exposed to
|
||||
# users. (string value)
|
||||
#url = <None>
|
||||
|
||||
# Timeout value for connecting to cinder in seconds. (integer
|
||||
# value)
|
||||
#url_timeout = 30
|
||||
|
||||
# User's domain id (string value)
|
||||
#user_domain_id = <None>
|
||||
|
||||
@ -993,7 +977,7 @@
|
||||
#user_id = <None>
|
||||
|
||||
# Username (string value)
|
||||
# Deprecated group/name - [cinder]/user-name
|
||||
# Deprecated group/name - [cinder]/user_name
|
||||
#username = <None>
|
||||
|
||||
|
||||
@ -1251,16 +1235,7 @@
|
||||
# From oslo.db
|
||||
#
|
||||
|
||||
# DEPRECATED: The file name to use with SQLite. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/sqlite_db
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Should use config option connection or
|
||||
# slave_connection to connect the database.
|
||||
#sqlite_db = oslo.sqlite
|
||||
|
||||
# If True, SQLite uses synchronous mode. (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/sqlite_synchronous
|
||||
#sqlite_synchronous = true
|
||||
|
||||
# The back end to use for the database. (string value)
|
||||
@ -1591,11 +1566,11 @@
|
||||
#project_domain_name = <None>
|
||||
|
||||
# Project ID to scope to (string value)
|
||||
# Deprecated group/name - [glance]/tenant-id
|
||||
# Deprecated group/name - [glance]/tenant_id
|
||||
#project_id = <None>
|
||||
|
||||
# Project name to scope to (string value)
|
||||
# Deprecated group/name - [glance]/tenant-name
|
||||
# Deprecated group/name - [glance]/tenant_name
|
||||
#project_name = <None>
|
||||
|
||||
# The account that Glance uses to communicate with Swift. The
|
||||
@ -1698,7 +1673,7 @@
|
||||
#user_id = <None>
|
||||
|
||||
# Username (string value)
|
||||
# Deprecated group/name - [glance]/user-name
|
||||
# Deprecated group/name - [glance]/user_name
|
||||
#username = <None>
|
||||
|
||||
|
||||
@ -1840,11 +1815,11 @@
|
||||
#project_domain_name = <None>
|
||||
|
||||
# Project ID to scope to (string value)
|
||||
# Deprecated group/name - [inspector]/tenant-id
|
||||
# Deprecated group/name - [inspector]/tenant_id
|
||||
#project_id = <None>
|
||||
|
||||
# Project name to scope to (string value)
|
||||
# Deprecated group/name - [inspector]/tenant-name
|
||||
# Deprecated group/name - [inspector]/tenant_name
|
||||
#project_name = <None>
|
||||
|
||||
# ironic-inspector HTTP endpoint. If this is not set, the
|
||||
@ -1877,7 +1852,7 @@
|
||||
#user_id = <None>
|
||||
|
||||
# Username (string value)
|
||||
# Deprecated group/name - [inspector]/user-name
|
||||
# Deprecated group/name - [inspector]/user_name
|
||||
#username = <None>
|
||||
|
||||
|
||||
@ -2178,6 +2153,22 @@
|
||||
# Reason: PKI token format is no longer supported.
|
||||
#hash_algorithms = md5
|
||||
|
||||
# A choice of roles that must be present in a service token.
|
||||
# Service tokens are allowed to request that an expired token
|
||||
# can be used and so this check should tightly control that
|
||||
# only actual services should be sending this token. Roles
|
||||
# here are applied as an ANY check so any role in this list
|
||||
# must be present. For backwards compatibility reasons this
|
||||
# currently only affects the allow_expired check. (list value)
|
||||
#service_token_roles = service
|
||||
|
||||
# For backwards compatibility reasons we must let valid
|
||||
# service tokens pass that don't pass the service_token_roles
|
||||
# check as valid. Setting this true will become the default in
|
||||
# a future release and should be enabled if possible. (boolean
|
||||
# value)
|
||||
#service_token_roles_required = false
|
||||
|
||||
# Authentication type to load (string value)
|
||||
# Deprecated group/name - [keystone_authtoken]/auth_plugin
|
||||
#auth_type = <None>
|
||||
@ -2406,11 +2397,11 @@
|
||||
#project_domain_name = <None>
|
||||
|
||||
# Project ID to scope to (string value)
|
||||
# Deprecated group/name - [neutron]/tenant-id
|
||||
# Deprecated group/name - [neutron]/tenant_id
|
||||
#project_id = <None>
|
||||
|
||||
# Project name to scope to (string value)
|
||||
# Deprecated group/name - [neutron]/tenant-name
|
||||
# Deprecated group/name - [neutron]/tenant_name
|
||||
#project_name = <None>
|
||||
|
||||
# Neutron network UUID or name for the ramdisk to be booted
|
||||
@ -2463,7 +2454,7 @@
|
||||
#user_id = <None>
|
||||
|
||||
# Username (string value)
|
||||
# Deprecated group/name - [neutron]/user-name
|
||||
# Deprecated group/name - [neutron]/user_name
|
||||
#username = <None>
|
||||
|
||||
|
||||
@ -2512,7 +2503,6 @@
|
||||
#
|
||||
|
||||
# Enables or disables inter-process locks. (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/disable_process_locking
|
||||
#disable_process_locking = false
|
||||
|
||||
# Directory to use for lock files. For security, the
|
||||
@ -2520,7 +2510,6 @@
|
||||
# running the processes that need locking. Defaults to
|
||||
# environment variable OSLO_LOCK_PATH. If external locks are
|
||||
# used, a lock path must be set. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/lock_path
|
||||
#lock_path = <None>
|
||||
|
||||
|
||||
@ -2532,41 +2521,38 @@
|
||||
|
||||
# Name for the AMQP container. must be globally unique.
|
||||
# Defaults to a generated UUID (string value)
|
||||
# Deprecated group/name - [amqp1]/container_name
|
||||
#container_name = <None>
|
||||
|
||||
# Timeout for inactive connections (in seconds) (integer
|
||||
# value)
|
||||
# Deprecated group/name - [amqp1]/idle_timeout
|
||||
#idle_timeout = 0
|
||||
|
||||
# Debug: dump AMQP frames to stdout (boolean value)
|
||||
# Deprecated group/name - [amqp1]/trace
|
||||
#trace = false
|
||||
|
||||
# Attempt to connect via SSL. If no other ssl-related
|
||||
# parameters are given, it will use the system's CA-bundle to
|
||||
# verify the server's certificate. (boolean value)
|
||||
#ssl = false
|
||||
|
||||
# CA certificate PEM file used to verify the server's
|
||||
# certificate (string value)
|
||||
# Deprecated group/name - [amqp1]/ssl_ca_file
|
||||
#ssl_ca_file =
|
||||
|
||||
# Self-identifying certificate PEM file for client
|
||||
# authentication (string value)
|
||||
# Deprecated group/name - [amqp1]/ssl_cert_file
|
||||
#ssl_cert_file =
|
||||
|
||||
# Private key PEM file used to sign ssl_cert_file certificate
|
||||
# (optional) (string value)
|
||||
# Deprecated group/name - [amqp1]/ssl_key_file
|
||||
#ssl_key_file =
|
||||
|
||||
# Password for decrypting ssl_key_file (if encrypted) (string
|
||||
# value)
|
||||
# Deprecated group/name - [amqp1]/ssl_key_password
|
||||
#ssl_key_password = <None>
|
||||
|
||||
# DEPRECATED: Accept clients using either SSL or plain TCP
|
||||
# (boolean value)
|
||||
# Deprecated group/name - [amqp1]/allow_insecure_clients
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Not applicable - not a SSL server
|
||||
@ -2574,25 +2560,20 @@
|
||||
|
||||
# Space separated list of acceptable SASL mechanisms (string
|
||||
# value)
|
||||
# Deprecated group/name - [amqp1]/sasl_mechanisms
|
||||
#sasl_mechanisms =
|
||||
|
||||
# Path to directory that contains the SASL configuration
|
||||
# (string value)
|
||||
# Deprecated group/name - [amqp1]/sasl_config_dir
|
||||
#sasl_config_dir =
|
||||
|
||||
# Name of configuration file (without .conf suffix) (string
|
||||
# value)
|
||||
# Deprecated group/name - [amqp1]/sasl_config_name
|
||||
#sasl_config_name =
|
||||
|
||||
# User name for message broker authentication (string value)
|
||||
# Deprecated group/name - [amqp1]/username
|
||||
#username =
|
||||
|
||||
# Password for message broker authentication (string value)
|
||||
# Deprecated group/name - [amqp1]/password
|
||||
#password =
|
||||
|
||||
# Seconds to pause before attempting to re-connect. (integer
|
||||
@ -2653,17 +2634,14 @@
|
||||
|
||||
# address prefix used when sending to a specific server
|
||||
# (string value)
|
||||
# Deprecated group/name - [amqp1]/server_request_prefix
|
||||
#server_request_prefix = exclusive
|
||||
|
||||
# address prefix used when broadcasting to all servers (string
|
||||
# value)
|
||||
# Deprecated group/name - [amqp1]/broadcast_prefix
|
||||
#broadcast_prefix = broadcast
|
||||
|
||||
# address prefix when sending to any server in group (string
|
||||
# value)
|
||||
# Deprecated group/name - [amqp1]/group_request_prefix
|
||||
#group_request_prefix = unicast
|
||||
|
||||
# Address prefix for all generated RPC addresses (string
|
||||
@ -2820,7 +2798,6 @@
|
||||
#amqp_durable_queues = false
|
||||
|
||||
# Auto-delete queues in AMQP. (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/amqp_auto_delete
|
||||
#amqp_auto_delete = false
|
||||
|
||||
# Enable SSL (boolean value)
|
||||
@ -2847,7 +2824,6 @@
|
||||
|
||||
# How long to wait before reconnecting in response to an AMQP
|
||||
# consumer cancel notification. (floating point value)
|
||||
# Deprecated group/name - [DEFAULT]/kombu_reconnect_delay
|
||||
#kombu_reconnect_delay = 1.0
|
||||
|
||||
# EXPERIMENTAL: Possible values are: gzip, bz2. If not set
|
||||
@ -2870,7 +2846,6 @@
|
||||
|
||||
# DEPRECATED: The RabbitMQ broker address where a single node
|
||||
# is used. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_host
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Replaced by [DEFAULT]/transport_url
|
||||
@ -2880,7 +2855,6 @@
|
||||
# used. (port value)
|
||||
# Minimum value: 0
|
||||
# Maximum value: 65535
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_port
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Replaced by [DEFAULT]/transport_url
|
||||
@ -2888,21 +2862,18 @@
|
||||
|
||||
# DEPRECATED: RabbitMQ HA cluster host:port pairs. (list
|
||||
# value)
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_hosts
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Replaced by [DEFAULT]/transport_url
|
||||
#rabbit_hosts = $rabbit_host:$rabbit_port
|
||||
|
||||
# DEPRECATED: The RabbitMQ userid. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_userid
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Replaced by [DEFAULT]/transport_url
|
||||
#rabbit_userid = guest
|
||||
|
||||
# DEPRECATED: The RabbitMQ password. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_password
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Replaced by [DEFAULT]/transport_url
|
||||
@ -2910,11 +2881,9 @@
|
||||
|
||||
# The RabbitMQ login method. (string value)
|
||||
# Allowed values: PLAIN, AMQPLAIN, RABBIT-CR-DEMO
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_login_method
|
||||
#rabbit_login_method = AMQPLAIN
|
||||
|
||||
# DEPRECATED: The RabbitMQ virtual host. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_virtual_host
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: Replaced by [DEFAULT]/transport_url
|
||||
@ -2926,7 +2895,6 @@
|
||||
|
||||
# How long to backoff for between retries when connecting to
|
||||
# RabbitMQ. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_retry_backoff
|
||||
#rabbit_retry_backoff = 2
|
||||
|
||||
# Maximum interval of RabbitMQ connection retries. Default is
|
||||
@ -2935,7 +2903,6 @@
|
||||
|
||||
# DEPRECATED: Maximum number of RabbitMQ connection retries.
|
||||
# Default is 0 (infinite retry count). (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_max_retries
|
||||
# This option is deprecated for removal.
|
||||
# Its value may be silently ignored in the future.
|
||||
#rabbit_max_retries = 0
|
||||
@ -2948,7 +2915,6 @@
|
||||
# generated names) are mirrored across all nodes, run:
|
||||
# "rabbitmqctl set_policy HA '^(?!amq\.).*' '{"ha-mode":
|
||||
# "all"}' " (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/rabbit_ha_queues
|
||||
#rabbit_ha_queues = false
|
||||
|
||||
# Positive integer representing duration in seconds for queue
|
||||
@ -2973,7 +2939,6 @@
|
||||
|
||||
# Deprecated, use rpc_backend=kombu+memory or rpc_backend=fake
|
||||
# (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/fake_rabbit
|
||||
#fake_rabbit = false
|
||||
|
||||
# Maximum number of channels to allow (integer value)
|
||||
@ -3099,31 +3064,25 @@
|
||||
# ZeroMQ bind address. Should be a wildcard (*), an ethernet
|
||||
# interface, or IP. The "host" option should point or resolve
|
||||
# to this address. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_bind_address
|
||||
#rpc_zmq_bind_address = *
|
||||
|
||||
# MatchMaker driver. (string value)
|
||||
# Allowed values: redis, sentinel, dummy
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_matchmaker
|
||||
#rpc_zmq_matchmaker = redis
|
||||
|
||||
# Number of ZeroMQ contexts, defaults to 1. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_contexts
|
||||
#rpc_zmq_contexts = 1
|
||||
|
||||
# Maximum number of ingress messages to locally buffer per
|
||||
# topic. Default is unlimited. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_topic_backlog
|
||||
#rpc_zmq_topic_backlog = <None>
|
||||
|
||||
# Directory for holding IPC sockets. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_ipc_dir
|
||||
#rpc_zmq_ipc_dir = /var/run/openstack
|
||||
|
||||
# Name of this node. Must be a valid hostname, FQDN, or IP
|
||||
# address. Must match "host" option, if running Nova. (string
|
||||
# value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_host
|
||||
#rpc_zmq_host = localhost
|
||||
|
||||
# Number of seconds to wait before all pending messages will
|
||||
@ -3139,26 +3098,21 @@
|
||||
# The default number of seconds that poll should wait. Poll
|
||||
# raises timeout exception when timeout expired. (integer
|
||||
# value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_poll_timeout
|
||||
#rpc_poll_timeout = 1
|
||||
|
||||
# Expiration timeout in seconds of a name service record about
|
||||
# existing target ( < 0 means no timeout). (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/zmq_target_expire
|
||||
#zmq_target_expire = 300
|
||||
|
||||
# Update period in seconds of a name service record about
|
||||
# existing target. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/zmq_target_update
|
||||
#zmq_target_update = 180
|
||||
|
||||
# Use PUB/SUB pattern for fanout methods. PUB/SUB always uses
|
||||
# proxy. (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/use_pub_sub
|
||||
#use_pub_sub = false
|
||||
|
||||
# Use ROUTER remote proxy. (boolean value)
|
||||
# Deprecated group/name - [DEFAULT]/use_router_proxy
|
||||
#use_router_proxy = false
|
||||
|
||||
# This option makes direct connections dynamic or static. It
|
||||
@ -3175,25 +3129,21 @@
|
||||
# Minimal port number for random ports range. (port value)
|
||||
# Minimum value: 0
|
||||
# Maximum value: 65535
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_min_port
|
||||
#rpc_zmq_min_port = 49153
|
||||
|
||||
# Maximal port number for random ports range. (integer value)
|
||||
# Minimum value: 1
|
||||
# Maximum value: 65536
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_max_port
|
||||
#rpc_zmq_max_port = 65536
|
||||
|
||||
# Number of retries to find free port number before fail with
|
||||
# ZMQBindError. (integer value)
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_bind_port_retries
|
||||
#rpc_zmq_bind_port_retries = 100
|
||||
|
||||
# Default serialization mechanism for
|
||||
# serializing/deserializing outgoing/incoming messages (string
|
||||
# value)
|
||||
# Allowed values: json, msgpack
|
||||
# Deprecated group/name - [DEFAULT]/rpc_zmq_serialization
|
||||
#rpc_zmq_serialization = json
|
||||
|
||||
# This option configures round-robin mode in zmq socket. True
|
||||
@ -3277,12 +3227,10 @@
|
||||
#
|
||||
|
||||
# The file that defines policies. (string value)
|
||||
# Deprecated group/name - [DEFAULT]/policy_file
|
||||
#policy_file = policy.json
|
||||
|
||||
# Default rule. Enforced when a requested rule is not found.
|
||||
# (string value)
|
||||
# Deprecated group/name - [DEFAULT]/policy_default_rule
|
||||
#policy_default_rule = default
|
||||
|
||||
# Directories where policy configuration files are stored.
|
||||
@ -3291,7 +3239,6 @@
|
||||
# file defined by policy_file must exist for these directories
|
||||
# to be searched. Missing or empty directories are ignored.
|
||||
# (multi valued)
|
||||
# Deprecated group/name - [DEFAULT]/policy_dirs
|
||||
#policy_dirs = policy.d
|
||||
|
||||
|
||||
@ -3438,11 +3385,11 @@
|
||||
#project_domain_name = <None>
|
||||
|
||||
# Project ID to scope to (string value)
|
||||
# Deprecated group/name - [service_catalog]/tenant-id
|
||||
# Deprecated group/name - [service_catalog]/tenant_id
|
||||
#project_id = <None>
|
||||
|
||||
# Project name to scope to (string value)
|
||||
# Deprecated group/name - [service_catalog]/tenant-name
|
||||
# Deprecated group/name - [service_catalog]/tenant_name
|
||||
#project_name = <None>
|
||||
|
||||
# Tenant ID (string value)
|
||||
@ -3467,7 +3414,7 @@
|
||||
#user_id = <None>
|
||||
|
||||
# Username (string value)
|
||||
# Deprecated group/name - [service_catalog]/user-name
|
||||
# Deprecated group/name - [service_catalog]/user_name
|
||||
#username = <None>
|
||||
|
||||
|
||||
@ -3589,11 +3536,11 @@
|
||||
#project_domain_name = <None>
|
||||
|
||||
# Project ID to scope to (string value)
|
||||
# Deprecated group/name - [swift]/tenant-id
|
||||
# Deprecated group/name - [swift]/tenant_id
|
||||
#project_id = <None>
|
||||
|
||||
# Project name to scope to (string value)
|
||||
# Deprecated group/name - [swift]/tenant-name
|
||||
# Deprecated group/name - [swift]/tenant_name
|
||||
#project_name = <None>
|
||||
|
||||
# Maximum number of times to retry a Swift request, before
|
||||
@ -3622,5 +3569,5 @@
|
||||
#user_id = <None>
|
||||
|
||||
# Username (string value)
|
||||
# Deprecated group/name - [swift]/user-name
|
||||
# Deprecated group/name - [swift]/user_name
|
||||
#username = <None>
|
||||
|
@ -104,14 +104,15 @@ def _get_attachment_id(node, volume):
|
||||
# attachment for each node that represents all possible attachment
|
||||
# information as multiple types can be submitted in a single request.
|
||||
attachments = volume.attachments
|
||||
if attachments is not None:
|
||||
for attachment in attachments:
|
||||
if attachment.get('server_id') in (node.instance_uuid, node.uuid):
|
||||
return attachment.get('attachment_id')
|
||||
if attachments is None:
|
||||
return
|
||||
for attachment in attachments:
|
||||
if attachment.get('server_id') in (node.instance_uuid, node.uuid):
|
||||
return attachment.get('attachment_id')
|
||||
|
||||
|
||||
def _create_metadata_dictionary(node, action):
|
||||
"""Create a volume metadata dictionary utilizing the node UUID.
|
||||
"""Create a volume metadata dictionary.
|
||||
|
||||
:param node: Object representing a node.
|
||||
:param action: String value representing the last action.
|
||||
@ -121,12 +122,12 @@ def _create_metadata_dictionary(node, action):
|
||||
label = "ironic_node_%s" % node.uuid
|
||||
return {
|
||||
label: {
|
||||
'instance_uuid': node.instance_uuid,
|
||||
'instance_uuid': node.instance_uuid or node.uuid,
|
||||
'last_seen': datetime.datetime.utcnow().isoformat(),
|
||||
'last_action': action}}
|
||||
|
||||
|
||||
def _init_client_for_operations(task):
|
||||
def _init_client(task):
|
||||
"""Obtain cinder client and return it for use.
|
||||
|
||||
:param task: TaskManager instance representing the operation.
|
||||
@ -138,8 +139,8 @@ def _init_client_for_operations(task):
|
||||
try:
|
||||
return get_client()
|
||||
except Exception as e:
|
||||
msg = (_('Failed to initialize cinder client for node %(uuid)s: %('
|
||||
'err)s') % {'uuid': node.uuid, 'err': e})
|
||||
msg = (_('Failed to initialize cinder client for operations on node '
|
||||
'%(uuid)s: %(err)s') % {'uuid': node.uuid, 'err': e})
|
||||
LOG.error(msg)
|
||||
raise exception.StorageError(msg)
|
||||
|
||||
@ -181,7 +182,6 @@ def attach_volumes(task, volume_list, connector):
|
||||
}
|
||||
|
||||
:raises: StorageError If storage subsystem exception is raised.
|
||||
:raises: TypeError If the supplied volume_list is not a list.
|
||||
:returns: List of connected volumes, including volumes that were
|
||||
already connected to desired nodes. The returned list
|
||||
can be relatively consistent depending on the end storage
|
||||
@ -232,7 +232,7 @@ def attach_volumes(task, volume_list, connector):
|
||||
}]
|
||||
"""
|
||||
node = task.node
|
||||
client = _init_client_for_operations(task)
|
||||
client = _init_client(task)
|
||||
|
||||
connected = []
|
||||
for volume_id in volume_list:
|
||||
@ -271,10 +271,6 @@ def attach_volumes(task, volume_list, connector):
|
||||
# Provide connector information to cinder
|
||||
connection = client.volumes.initialize_connection(volume_id,
|
||||
connector)
|
||||
if 'volume_id' not in connection['data']:
|
||||
connection['data']['volume_id'] = volume_id
|
||||
connection['data']['ironic_volume_uuid'] = volume.uuid
|
||||
connected.append(connection)
|
||||
except cinder_exceptions.ClientException as e:
|
||||
msg = (_('Failed to initialize connection for volume '
|
||||
'%(vol_id)s to node %(node)s: %(err)s') %
|
||||
@ -282,6 +278,11 @@ def attach_volumes(task, volume_list, connector):
|
||||
LOG.error(msg)
|
||||
raise exception.StorageError(msg)
|
||||
|
||||
if 'volume_id' not in connection['data']:
|
||||
connection['data']['volume_id'] = volume_id
|
||||
connection['data']['ironic_volume_uuid'] = volume.uuid
|
||||
connected.append(connection)
|
||||
|
||||
LOG.info('Successfully initialized volume %(vol_id)s for '
|
||||
'node %(node)s.', {'vol_id': volume_id, 'node': node.uuid})
|
||||
|
||||
@ -351,7 +352,6 @@ def detach_volumes(task, volume_list, connector, allow_errors=False):
|
||||
:param allow_errors: Boolean value governing if errors that are returned
|
||||
are treated as warnings instead of exceptions.
|
||||
Default False.
|
||||
:raises: TypeError If the supplied volume_list is not a sequence.
|
||||
:raises: StorageError
|
||||
"""
|
||||
def _handle_errors(msg):
|
||||
@ -361,7 +361,7 @@ def detach_volumes(task, volume_list, connector, allow_errors=False):
|
||||
LOG.error(msg)
|
||||
raise exception.StorageError(msg)
|
||||
|
||||
client = _init_client_for_operations(task)
|
||||
client = _init_client(task)
|
||||
node = task.node
|
||||
|
||||
for volume_id in volume_list:
|
||||
|
@ -20,11 +20,14 @@ opts = [
|
||||
cfg.StrOpt('url',
|
||||
regex='^http(s?):\/\/.+',
|
||||
help=_('URL for connecting to cinder. If set, the value must '
|
||||
'start with either http:// or https://.')),
|
||||
'start with either http:// or https://. This option is '
|
||||
'part of boot-from-volume work, which is not currently '
|
||||
'exposed to users.')),
|
||||
cfg.IntOpt('retries',
|
||||
default=3,
|
||||
help=_('Client retries in the case of a failed request '
|
||||
'connection.')),
|
||||
'connection. This option is part of boot-from-volume '
|
||||
'work, which is not currently exposed to users.')),
|
||||
]
|
||||
|
||||
|
||||
|
@ -11,12 +11,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from cinderclient import exceptions as cinder_exceptions
|
||||
import cinderclient.v3 as cinderclient
|
||||
import mock
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from six.moves import http_client
|
||||
|
||||
from ironic.common import cinder
|
||||
@ -108,10 +107,6 @@ class TestCinderUtils(db_base.DbTestCase):
|
||||
self.context,
|
||||
instance_uuid=uuidutils.generate_uuid())
|
||||
|
||||
def test_cinder_states(self):
|
||||
self.assertEqual('available', cinder.AVAILABLE)
|
||||
self.assertEqual('in-use', cinder.IN_USE)
|
||||
|
||||
def test_is_volume_available(self):
|
||||
available_volumes = [
|
||||
mock.Mock(status=cinder.AVAILABLE, multiattach=False),
|
||||
@ -122,13 +117,13 @@ class TestCinderUtils(db_base.DbTestCase):
|
||||
|
||||
for vol in available_volumes:
|
||||
result = cinder.is_volume_available(vol)
|
||||
self.assertEqual(True, result,
|
||||
message="Failed for status '%s'." % vol.status)
|
||||
self.assertTrue(result,
|
||||
msg="Failed for status '%s'." % vol.status)
|
||||
|
||||
for vol in unavailable_volumes:
|
||||
result = cinder.is_volume_available(vol)
|
||||
self.assertEqual(False, result,
|
||||
message="Failed for status '%s'." % vol.status)
|
||||
self.assertFalse(result,
|
||||
msg="Failed for status '%s'." % vol.status)
|
||||
|
||||
def test_is_volume_attached(self):
|
||||
attached_vol = mock.Mock(id='foo', attachments=[
|
||||
@ -168,12 +163,9 @@ class TestCinderUtils(db_base.DbTestCase):
|
||||
}
|
||||
|
||||
result = cinder._create_metadata_dictionary(self.node, 'meow')
|
||||
self.maxDiff = None
|
||||
# Since datetime is an internal, we can't exactly mock it.
|
||||
# We can however verify it's presence, and replace it.
|
||||
self.assertIsInstance(result[expected_key]['last_seen'], str)
|
||||
result[expected_key]['last_seen'] = 'faked-time'
|
||||
self.assertDictEqual(expected, result)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
|
||||
@mock.patch.object(cinder, '_get_cinder_session', autospec=True)
|
||||
@ -229,7 +221,7 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
attachments = cinder.attach_volumes(task, volumes, connector)
|
||||
|
||||
self.assertDictEqual(expected[0], attachments[0])
|
||||
self.assertEqual(expected, attachments)
|
||||
mock_reserve.assert_called_once_with(mock.ANY, volume_id)
|
||||
mock_init.assert_called_once_with(mock.ANY, volume_id, connector)
|
||||
mock_attach.assert_called_once_with(mock.ANY, volume_id,
|
||||
@ -292,12 +284,13 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
mock_set_meta.assert_called_once_with(mock.ANY, volume_id,
|
||||
{'bar': 'baz'})
|
||||
|
||||
@mock.patch.object(cinderclient.Client, '__init__')
|
||||
@mock.patch.object(cinderclient.Client, '__init__', autospec=True)
|
||||
def test_attach_volumes_client_init_failure(
|
||||
self, mock_client, mock_get, mock_set_meta, mock_session):
|
||||
connector = {'foo': 'bar'}
|
||||
volumes = ['111111111-0000-0000-0000-000000000003']
|
||||
mock_client.side_effect = cinder_exceptions.BadRequest(400)
|
||||
mock_client.side_effect = cinder_exceptions.BadRequest(
|
||||
http_client.BAD_REQUEST)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.StorageError,
|
||||
@ -318,9 +311,10 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
mock_get, mock_set_meta, mock_session):
|
||||
"""Raise an error if the volume lookup fails"""
|
||||
|
||||
def __mock_get_side_effect(*args, **kwargs):
|
||||
if args[1] == 'not_found':
|
||||
raise cinder_exceptions.NotFound(404, message='error')
|
||||
def __mock_get_side_effect(client, volume_id):
|
||||
if volume_id == 'not_found':
|
||||
raise cinder_exceptions.NotFound(
|
||||
http_client.NOT_FOUND, message='error')
|
||||
else:
|
||||
return mock.Mock(attachments=[], uuid='000-000')
|
||||
|
||||
@ -362,7 +356,8 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
volume = mock.Mock(attachments=[])
|
||||
mock_get.return_value = volume
|
||||
mock_is_attached.return_value = False
|
||||
mock_reserve.side_effect = cinder_exceptions.NotAcceptable(406)
|
||||
mock_reserve.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.StorageError,
|
||||
@ -389,7 +384,8 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
mock_create_meta.return_value = {'bar': 'baz'}
|
||||
mock_is_attached.return_value = False
|
||||
mock_get.return_value = mock.Mock(attachments=[])
|
||||
mock_init.side_effect = cinder_exceptions.NotAcceptable(406)
|
||||
mock_init.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.StorageError,
|
||||
@ -426,8 +422,8 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
'target_iqn': 'iqn.2010-10.org.openstack:volume-00000002',
|
||||
'target_portal': '127.0.0.0.1:3260',
|
||||
'target_lun': 2}}
|
||||
mock_attach.side_effect = cinder_exceptions.ClientException(406,
|
||||
'error')
|
||||
mock_attach.side_effect = cinder_exceptions.ClientException(
|
||||
http_client.NOT_ACCEPTABLE, 'error')
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.StorageError, cinder.attach_volumes,
|
||||
@ -476,12 +472,13 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
'target_iqn': 'iqn.2010-10.org.openstack:volume-00000002',
|
||||
'target_portal': '127.0.0.0.1:3260',
|
||||
'target_lun': 2}}
|
||||
mock_set_meta.side_effect = cinder_exceptions.NotAcceptable(406)
|
||||
mock_set_meta.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
attachments = cinder.attach_volumes(task, volumes, connector)
|
||||
|
||||
self.assertDictEqual(expected[0], attachments[0])
|
||||
self.assertEqual(expected, attachments)
|
||||
mock_reserve.assert_called_once_with(mock.ANY, volume_id)
|
||||
mock_init.assert_called_once_with(mock.ANY, volume_id, connector)
|
||||
mock_attach.assert_called_once_with(mock.ANY, volume_id,
|
||||
@ -556,22 +553,28 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
{'bar': 'baz'})
|
||||
|
||||
@mock.patch.object(cinderclient.Client, '__init__', autospec=True)
|
||||
def test_detach_volumes_client_init_failure(
|
||||
def test_detach_volumes_client_init_failure_bad_request(
|
||||
self, mock_client, mock_get, mock_set_meta, mock_session):
|
||||
|
||||
connector = {'foo': 'bar'}
|
||||
volumes = ['111111111-0000-0000-0000-000000000003']
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
mock_client.side_effect = cinder_exceptions.BadRequest(400)
|
||||
mock_client.side_effect = cinder_exceptions.BadRequest(
|
||||
http_client.BAD_REQUEST)
|
||||
self.assertRaises(exception.StorageError,
|
||||
cinder.detach_volumes,
|
||||
task,
|
||||
volumes,
|
||||
connector)
|
||||
# While we would be permitting failures, this is an
|
||||
# exception that must be raised since the client
|
||||
# cannot be initialized.
|
||||
|
||||
@mock.patch.object(cinderclient.Client, '__init__', autospec=True)
|
||||
def test_detach_volumes_client_init_failure_invalid_parameter_value(
|
||||
self, mock_client, mock_get, mock_set_meta, mock_session):
|
||||
connector = {'foo': 'bar'}
|
||||
volumes = ['111111111-0000-0000-0000-000000000003']
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
# While we would be permitting failures, this is an exception that
|
||||
# must be raised since the client cannot be initialized.
|
||||
mock_client.side_effect = exception.InvalidParameterValue('error')
|
||||
self.assertRaises(exception.StorageError,
|
||||
cinder.detach_volumes, task, volumes,
|
||||
@ -583,7 +586,7 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
volumes = ['vol1']
|
||||
connector = {'foo': 'bar'}
|
||||
mock_get.side_effect = cinder_exceptions.NotFound(
|
||||
404, message='error')
|
||||
http_client.NOT_FOUND, message='error')
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.StorageError,
|
||||
@ -616,7 +619,8 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
mock_get.return_value = volume
|
||||
mock_create_meta.return_value = {'bar': 'baz'}
|
||||
mock_is_attached.return_value = True
|
||||
mock_begin.side_effect = cinder_exceptions.NotAcceptable(406)
|
||||
mock_begin.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.StorageError,
|
||||
@ -648,7 +652,8 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
mock_create_meta.return_value = {'bar': 'baz'}
|
||||
mock_is_attached.return_value = True
|
||||
mock_get.return_value = {'id': volume_id, 'attachments': []}
|
||||
mock_term.side_effect = cinder_exceptions.NotAcceptable(406)
|
||||
mock_term.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.StorageError,
|
||||
@ -669,38 +674,21 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
autospec=True)
|
||||
@mock.patch.object(cinder, 'is_volume_attached', autospec=True)
|
||||
@mock.patch.object(cinder, '_create_metadata_dictionary', autospec=True)
|
||||
def test_detach_volumes_detach_meta_failure(
|
||||
def test_detach_volumes_detach_failure_errors_not_allowed(
|
||||
self, mock_create_meta, mock_is_attached, mock_begin, mock_term,
|
||||
mock_detach, mock_get, mock_set_meta, mock_session):
|
||||
|
||||
volume_id = '111111111-0000-0000-0000-000000000003'
|
||||
volumes = [volume_id]
|
||||
|
||||
connector = {'foo': 'bar'}
|
||||
mock_create_meta.return_value = {'bar': 'baz'}
|
||||
mock_is_attached.return_value = True
|
||||
mock_get.return_value = mock.Mock(attachments=[
|
||||
{'server_id': self.node.uuid, 'attachment_id': 'qux'}])
|
||||
mock_detach.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
mock_detach.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
cinder.detach_volumes(task, volumes, connector, allow_errors=True)
|
||||
mock_detach.assert_called_once_with(mock.ANY, volume_id, 'qux')
|
||||
mock_set_meta.assert_called_once_with(mock.ANY, volume_id,
|
||||
{'bar': 'baz'})
|
||||
mock_detach.reset_mock()
|
||||
mock_set_meta.reset_mock()
|
||||
|
||||
mock_set_meta.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
cinder.detach_volumes(task, volumes, connector, allow_errors=True)
|
||||
mock_detach.assert_called_once_with(mock.ANY, volume_id, 'qux')
|
||||
mock_set_meta.assert_called_once_with(mock.ANY, volume_id,
|
||||
{'bar': 'baz'})
|
||||
mock_detach.reset_mock()
|
||||
mock_set_meta.reset_mock()
|
||||
|
||||
self.assertRaises(exception.StorageError,
|
||||
cinder.detach_volumes,
|
||||
task,
|
||||
@ -709,3 +697,59 @@ class TestCinderActions(db_base.DbTestCase):
|
||||
allow_errors=False)
|
||||
mock_detach.assert_called_once_with(mock.ANY, volume_id, 'qux')
|
||||
self.assertFalse(mock_set_meta.called)
|
||||
|
||||
@mock.patch.object(cinderclient.volumes.VolumeManager, 'detach',
|
||||
autospec=True)
|
||||
@mock.patch.object(cinderclient.volumes.VolumeManager,
|
||||
'terminate_connection', autospec=True)
|
||||
@mock.patch.object(cinderclient.volumes.VolumeManager, 'begin_detaching',
|
||||
autospec=True)
|
||||
@mock.patch.object(cinder, 'is_volume_attached', autospec=True)
|
||||
@mock.patch.object(cinder, '_create_metadata_dictionary', autospec=True)
|
||||
def test_detach_volumes_detach_failure_errors_allowed(
|
||||
self, mock_create_meta, mock_is_attached, mock_begin, mock_term,
|
||||
mock_detach, mock_get, mock_set_meta, mock_session):
|
||||
|
||||
volume_id = '111111111-0000-0000-0000-000000000003'
|
||||
volumes = [volume_id]
|
||||
connector = {'foo': 'bar'}
|
||||
mock_create_meta.return_value = {'bar': 'baz'}
|
||||
mock_is_attached.return_value = True
|
||||
mock_get.return_value = mock.Mock(attachments=[
|
||||
{'server_id': self.node.uuid, 'attachment_id': 'qux'}])
|
||||
mock_set_meta.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
cinder.detach_volumes(task, volumes, connector, allow_errors=True)
|
||||
mock_detach.assert_called_once_with(mock.ANY, volume_id, 'qux')
|
||||
mock_set_meta.assert_called_once_with(mock.ANY, volume_id,
|
||||
{'bar': 'baz'})
|
||||
|
||||
@mock.patch.object(cinderclient.volumes.VolumeManager, 'detach',
|
||||
autospec=True)
|
||||
@mock.patch.object(cinderclient.volumes.VolumeManager,
|
||||
'terminate_connection', autospec=True)
|
||||
@mock.patch.object(cinderclient.volumes.VolumeManager, 'begin_detaching',
|
||||
autospec=True)
|
||||
@mock.patch.object(cinder, 'is_volume_attached', autospec=True)
|
||||
@mock.patch.object(cinder, '_create_metadata_dictionary', autospec=True)
|
||||
def test_detach_volumes_detach_meta_failure_errors_not_allowed(
|
||||
self, mock_create_meta, mock_is_attached, mock_begin, mock_term,
|
||||
mock_detach, mock_get, mock_set_meta, mock_session):
|
||||
|
||||
volume_id = '111111111-0000-0000-0000-000000000003'
|
||||
volumes = [volume_id]
|
||||
connector = {'foo': 'bar'}
|
||||
mock_create_meta.return_value = {'bar': 'baz'}
|
||||
mock_is_attached.return_value = True
|
||||
mock_get.return_value = mock.Mock(attachments=[
|
||||
{'server_id': self.node.uuid, 'attachment_id': 'qux'}])
|
||||
mock_set_meta.side_effect = cinder_exceptions.NotAcceptable(
|
||||
http_client.NOT_ACCEPTABLE)
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
cinder.detach_volumes(task, volumes, connector, allow_errors=False)
|
||||
mock_detach.assert_called_once_with(mock.ANY, volume_id, 'qux')
|
||||
mock_set_meta.assert_called_once_with(mock.ANY, volume_id,
|
||||
{'bar': 'baz'})
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
other:
|
||||
- Adds a configuration section ``cinder`` and a requirement of
|
||||
cinder client (python-cinderclient).
|
Loading…
Reference in New Issue
Block a user