Snap is installable.

This commit takes the cookie cutter output and fixes it up into a snap
that builds and installs.

- Added required names and such in openstack-snap.yaml and nginx and
  wsgi config templates.

- Python packages that are declared in setup.cfg and not in
  requirements.txt are now called out explicitly in the
  snapcraft.yaml. (Note: a better fix might be to update snapcraft to
  be able to parse dependencies from setup.cfg.)

- Removed upper constraints files on Python packages (and removed oslo
  patch). Gnocchi does not appear to respect the upper constraints.

- Added gnocchi-config-generator command to apps.

- Used the above to generate a default config.

- Added snapstack tests (though they don't work yet).

There's still plenty to do: snapstack tests need to be fixed up (see
the TODO in tests/gnocchi.sh), and the snap as a whole needs to be
thoroughly tested.
This commit is contained in:
Pete Vander Giessen 2017-08-17 15:18:12 +00:00
parent 09658821ab
commit 78d9683011
11 changed files with 1310 additions and 54 deletions

9
.gitignore vendored
View File

@ -3,3 +3,12 @@ prime
stage stage
*.snap *.snap
.tox .tox
# Snapcraft
.snapcraft
__pycache__
.cache
# emacs
*~
\#*

View File

@ -1,4 +1,584 @@
# The gnocchi snap may need to override default config files. [DEFAULT]
# For example if the default gnocchi.conf file located in
# $SNAP/etc/gnocchi/gnocchi.conf needs to be overridden, #
# it can be done with this file. # From cotyledon
#
# Enables or disables logging values of all registered options when starting a
# service (at DEBUG level). (boolean value)
# Note: This option can be changed without restarting.
#log_options = true
# Specify a timeout after which a gracefully shutdown server will exit. Zero
# value means endless wait. (integer value)
# Note: This option can be changed without restarting.
#graceful_shutdown_timeout = 60
#
# From oslo.log
#
# If set to true, the logging level will be set to DEBUG instead of the default
# INFO level. (boolean value)
# Note: This option can be changed without restarting.
#debug = false
# 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 logging module documentation. Note that when logging
# configuration files are used then all logging configuration is set in the
# configuration file and other logging configuration options are ignored (for
# example, logging_context_format_string). (string value)
# Note: This option can be changed without restarting.
# Deprecated group/name - [DEFAULT]/log_config
#log_config_append = <None>
# Defines the format string for %%(asctime)s in log records. Default:
# %(default)s . This option is ignored if log_config_append is set. (string
# value)
#log_date_format = %Y-%m-%d %H:%M:%S
# (Optional) Name of log file to send logging output to. If no default is set,
# logging will go to stderr as defined by use_stderr. This option is ignored if
# log_config_append is set. (string value)
# Deprecated group/name - [DEFAULT]/logfile
#log_file = <None>
# (Optional) The base directory used for relative log_file paths. This option
# is ignored if log_config_append is set. (string value)
# Deprecated group/name - [DEFAULT]/logdir
#log_dir = <None>
# Uses logging handler designed to watch file system. When log file is moved or
# removed this handler will open a new log file with specified path
# instantaneously. It makes sense only if log_file option is specified and
# Linux platform is used. This option is ignored if log_config_append is set.
# (boolean value)
#watch_log_file = false
# Use syslog for logging. Existing syslog format is DEPRECATED and will be
# changed later to honor RFC5424. This option is 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
# Log output to standard error. This option is ignored if log_config_append is
# set. (boolean value)
#use_stderr = false
# Format string to use for log messages with context. (string value)
#logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s
# Format string to use for log messages when context is undefined. (string
# value)
#logging_default_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s
# Additional data to append to log message when logging level for the message
# is DEBUG. (string value)
#logging_debug_format_suffix = %(funcName)s %(pathname)s:%(lineno)d
# Prefix each line of exception output with this format. (string value)
#logging_exception_prefix = %(asctime)s.%(msecs)03d %(process)d ERROR %(name)s %(instance)s
# Defines the format string for %(user_identity)s that is used in
# logging_context_format_string. (string value)
#logging_user_identity_format = %(user)s %(tenant)s %(domain)s %(user_domain)s %(project_domain)s
# List of package logging levels in logger=LEVEL pairs. This option is ignored
# if log_config_append is set. (list value)
#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,oslo_messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
# Enables or disables publication of error events. (boolean value)
#publish_errors = false
# The format for an instance that is passed with the log message. (string
# value)
#instance_format = "[instance: %(uuid)s] "
# The format for an instance UUID that is passed with the log message. (string
# value)
#instance_uuid_format = "[instance: %(uuid)s] "
# Interval, number of seconds, of log rate limiting. (integer value)
#rate_limit_interval = 0
# Maximum number of logged messages per rate_limit_interval. (integer value)
#rate_limit_burst = 0
# Log level name used by rate limiting: CRITICAL, ERROR, INFO, WARNING, DEBUG
# or empty string. Logs with level greater or equal to rate_limit_except_level
# are not filtered. An empty string means that all levels are filtered. (string
# value)
#rate_limit_except_level = CRITICAL
# Enables or disables fatal status of deprecations. (boolean value)
#fatal_deprecations = false
[api]
#
# From gnocchi
#
# Path to API Paste configuration. (string value)
#paste_config = /snap/gnocchi/x1/lib/python2.7/site-packages/gnocchi/rest/api-paste.ini
# Authentication mode to use. (string value)
# Allowed values: keystone, noauth, basic
#auth_mode = basic
# The maximum number of items returned in a single response from a collection
# resource (integer value)
#max_limit = 1000
[archive_policy]
#
# From gnocchi
#
# Default aggregation methods to use in created archive policies (list value)
#default_aggregation_methods = mean,min,max,sum,std,count
[cors]
#
# From oslo.middleware.cors
#
# Indicate whether this resource may be shared with the domain received in the
# requests "origin" header. Format: "<protocol>://<host>[:<port>]", no trailing
# slash. Example: https://horizon.example.com (list value)
#allowed_origin = <None>
# Indicate that the actual request can include user credentials (boolean value)
#allow_credentials = true
# Indicate which headers are safe to expose to the API. Defaults to HTTP Simple
# Headers. (list value)
#expose_headers =
# Maximum cache age of CORS preflight requests. (integer value)
#max_age = 3600
# Indicate which methods can be used during the actual request. (list value)
#allow_methods = OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,PATCH
# Indicate which header field names may be used during the actual request.
# (list value)
#allow_headers = X-Auth-Token,X-Subject-Token,X-User-Id,X-Domain-Id,X-Project-Id,X-Roles
[database]
#
# From oslo.db
#
# If True, SQLite uses synchronous mode. (boolean value)
#sqlite_synchronous = true
# The back end to use for the database. (string value)
# Deprecated group/name - [DEFAULT]/db_backend
#backend = sqlalchemy
# The SQLAlchemy connection string to use to connect to the database. (string
# value)
# Deprecated group/name - [DEFAULT]/sql_connection
# Deprecated group/name - [DATABASE]/sql_connection
# Deprecated group/name - [sql]/connection
#connection = <None>
# The SQLAlchemy connection string to use to connect to the slave database.
# (string value)
#slave_connection = <None>
# The SQL mode to be used for MySQL sessions. This option, including the
# default, overrides any server-set SQL mode. To use whatever SQL mode is set
# by the server configuration, set this to no value. Example: mysql_sql_mode=
# (string value)
#mysql_sql_mode = TRADITIONAL
# If True, transparently enables support for handling MySQL Cluster (NDB).
# (boolean value)
#mysql_enable_ndb = false
# Timeout before idle SQL connections are reaped. (integer value)
# Deprecated group/name - [DEFAULT]/sql_idle_timeout
# Deprecated group/name - [DATABASE]/sql_idle_timeout
# Deprecated group/name - [sql]/idle_timeout
#idle_timeout = 3600
# Minimum number of SQL connections to keep open in a pool. (integer value)
# Deprecated group/name - [DEFAULT]/sql_min_pool_size
# Deprecated group/name - [DATABASE]/sql_min_pool_size
#min_pool_size = 1
# Maximum number of SQL connections to keep open in a pool. Setting a value of
# 0 indicates no limit. (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_pool_size
# Deprecated group/name - [DATABASE]/sql_max_pool_size
#max_pool_size = 5
# Maximum number of database connection retries during startup. Set to -1 to
# specify an infinite retry count. (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_retries
# Deprecated group/name - [DATABASE]/sql_max_retries
#max_retries = 10
# Interval between retries of opening a SQL connection. (integer value)
# Deprecated group/name - [DEFAULT]/sql_retry_interval
# Deprecated group/name - [DATABASE]/reconnect_interval
#retry_interval = 10
# If set, use this value for max_overflow with SQLAlchemy. (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_overflow
# Deprecated group/name - [DATABASE]/sqlalchemy_max_overflow
#max_overflow = 50
# Verbosity of SQL debugging information: 0=None, 100=Everything. (integer
# value)
# Minimum value: 0
# Maximum value: 100
# Deprecated group/name - [DEFAULT]/sql_connection_debug
#connection_debug = 0
# Add Python stack traces to SQL as comment strings. (boolean value)
# Deprecated group/name - [DEFAULT]/sql_connection_trace
#connection_trace = false
# If set, use this value for pool_timeout with SQLAlchemy. (integer value)
# Deprecated group/name - [DATABASE]/sqlalchemy_pool_timeout
#pool_timeout = <None>
# Enable the experimental use of database reconnect on connection lost.
# (boolean value)
#use_db_reconnect = false
# Seconds between retries of a database transaction. (integer value)
#db_retry_interval = 1
# If True, increases the interval between retries of a database operation up to
# db_max_retry_interval. (boolean value)
#db_inc_retry_interval = true
# If db_inc_retry_interval is set, the maximum seconds between retries of a
# database operation. (integer value)
#db_max_retry_interval = 10
# Maximum retries in case of connection error or deadlock error before error is
# raised. Set to -1 to specify an infinite retry count. (integer value)
#db_max_retries = 20
[healthcheck]
#
# From oslo.middleware.healthcheck
#
# DEPRECATED: The path to respond to healtcheck requests on. (string value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
#path = /healthcheck
# Show more detailed information as part of the response (boolean value)
#detailed = false
# Additional backends that can perform health checks and report that
# information back as part of a request. (list value)
#backends =
# Check the presence of a file to determine if an application is running on a
# port. Used by DisableByFileHealthcheck plugin. (string value)
#disable_by_file_path = <None>
# Check the presence of a file based on a port to determine if an application
# is running on a port. Expects a "port:path" list of strings. Used by
# DisableByFilesPortsHealthcheck plugin. (list value)
#disable_by_file_paths =
[incoming]
#
# From gnocchi
#
# Storage driver to use (string value)
#driver = ${storage.driver}
# Ceph pool name to use. (string value)
#ceph_pool = ${storage.ceph_pool}
# Ceph username (ie: admin without "client." prefix). (string value)
#ceph_username = ${storage.ceph_username}
# Ceph key (string value)
#ceph_secret = ${storage.ceph_secret}
# Ceph keyring path. (string value)
#ceph_keyring = ${storage.ceph_keyring}
# Ceph configuration file. (string value)
#ceph_conffile = ${storage.ceph_conffile}
# Path used to store gnocchi data files. (string value)
#file_basepath = ${storage.file_basepath}
# Swift authentication version to user. (string value)
#swift_auth_version = ${storage.swift_auth_version}
# Swift pre-auth URL. (string value)
#swift_preauthurl = ${storage.swift_preauthurl}
# Swift auth URL. (string value)
#swift_authurl = ${storage.swift_authurl}
# Swift token to user to authenticate. (string value)
#swift_preauthtoken = ${storage.swift_preauthtoken}
# Swift user. (string value)
#swift_user = ${storage.swift_user}
# Swift user domain name. (string value)
#swift_user_domain_name = ${storage.swift_user_domain_name}
# Swift key/password. (string value)
#swift_key = ${storage.swift_key}
# Swift tenant name, only used in v2/v3 auth. (string value)
# Deprecated group/name - [incoming]/swift_tenant_name
#swift_project_name = ${storage.swift_project_name}
# Swift project domain name. (string value)
#swift_project_domain_name = ${storage.swift_project_domain_name}
# Prefix to namespace metric containers. (string value)
#swift_container_prefix = ${storage.swift_container_prefix}
# Endpoint type to connect to Swift (string value)
#swift_endpoint_type = ${storage.swift_endpoint_type}
# Connection timeout in seconds. (integer value)
# Minimum value: 0
#swift_timeout = ${storage.swift_timeout}
# S3 endpoint URL (string value)
#s3_endpoint_url = ${storage.s3_endpoint_url}
# S3 region name (string value)
#s3_region_name = ${storage.s3_region_name}
# S3 access key id (string value)
#s3_access_key_id = ${storage.s3_access_key_id}
# S3 secret access key (string value)
#s3_secret_access_key = ${storage.s3_secret_access_key}
# Prefix to namespace metric bucket. (string value)
#s3_bucket_prefix = ${storage.s3_bucket_prefix}
[indexer]
#
# From gnocchi
#
# Indexer driver to use (string value)
#url = <None>
[metricd]
#
# From gnocchi
#
# Number of workers for Gnocchi metric daemons. By default the available number
# of CPU is used. (integer value)
# Minimum value: 1
#workers = <None>
# How many seconds to wait between scheduling new metrics to process (integer
# value)
#metric_processing_delay = 60
# How many seconds to wait between metric ingestion reporting. Set value to -1
# to disable reporting (integer value)
# Minimum value: -1
#metric_reporting_delay = 120
# How many seconds to wait between cleaning of expired data (integer value)
#metric_cleanup_delay = 300
[oslo_middleware]
#
# From oslo.middleware.http_proxy_to_wsgi
#
# Whether the application is behind a proxy or not. This determines if the
# middleware should parse the headers or not. (boolean value)
#enable_proxy_headers_parsing = false
[oslo_policy]
#
# From oslo.policy
#
# The file that defines policies. (string value)
#policy_file = policy.json
# Default rule. Enforced when a requested rule is not found. (string value)
#policy_default_rule = default
# Directories where policy configuration files are stored. They can be relative
# to any directory in the search path defined by the config_dir option, or
# absolute paths. The file defined by policy_file must exist for these
# directories to be searched. Missing or empty directories are ignored. (multi
# valued)
#policy_dirs = policy.d
[statsd]
#
# From gnocchi
#
# The listen IP for statsd (string value)
#host = 0.0.0.0
# The port for statsd (port value)
# Minimum value: 0
# Maximum value: 65535
#port = 8125
# Resource UUID to use to identify statsd in Gnocchi (unknown value)
#resource_id = <None>
# DEPRECATED: User ID to use to identify statsd in Gnocchi (string value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
#user_id = <None>
# DEPRECATED: Project ID to use to identify statsd in Gnocchi (string value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
#project_id = <None>
# Creator value to use to identify statsd in Gnocchi (string value)
#creator = ${statsd.user_id}:${statsd.project_id}
# Archive policy name to use when creating metrics (string value)
#archive_policy_name = <None>
# Delay between flushes (floating point value)
#flush_delay = 10
[storage]
#
# From gnocchi
#
# Storage driver to use (string value)
#driver = file
# Ceph pool name to use. (string value)
#ceph_pool = gnocchi
# Ceph username (ie: admin without "client." prefix). (string value)
#ceph_username = <None>
# Ceph key (string value)
#ceph_secret = <None>
# Ceph keyring path. (string value)
#ceph_keyring = <None>
# Ceph configuration file. (string value)
#ceph_conffile = /etc/ceph/ceph.conf
# Path used to store gnocchi data files. (string value)
#file_basepath = /var/lib/gnocchi
# Swift authentication version to user. (string value)
#swift_auth_version = 1
# Swift pre-auth URL. (string value)
#swift_preauthurl = <None>
# Swift auth URL. (string value)
#swift_authurl = http://localhost:8080/auth/v1.0
# Swift token to user to authenticate. (string value)
#swift_preauthtoken = <None>
# Swift user. (string value)
#swift_user = admin:admin
# Swift user domain name. (string value)
#swift_user_domain_name = Default
# Swift key/password. (string value)
#swift_key = admin
# Swift tenant name, only used in v2/v3 auth. (string value)
# Deprecated group/name - [storage]/swift_tenant_name
#swift_project_name = <None>
# Swift project domain name. (string value)
#swift_project_domain_name = Default
# Prefix to namespace metric containers. (string value)
#swift_container_prefix = gnocchi
# Endpoint type to connect to Swift (string value)
#swift_endpoint_type = publicURL
# Connection timeout in seconds. (integer value)
# Minimum value: 0
#swift_timeout = 300
# S3 endpoint URL (string value)
#s3_endpoint_url = <None>
# S3 region name (string value)
#s3_region_name = <None>
# S3 access key id (string value)
#s3_access_key_id = <None>
# S3 secret access key (string value)
#s3_secret_access_key = <None>
# Prefix to namespace metric bucket. (string value)
#s3_bucket_prefix = gnocchi
# Number of workers to run during adding new measures for pre-aggregation
# needs. Due to the Python GIL, 1 is usually faster, unless you have high
# latency I/O (integer value)
# Minimum value: 1
#aggregation_workers_number = 1
# Coordination driver URL (string value)
#coordination_url = <None>

View File

@ -5,33 +5,32 @@ setup:
- "{snap_common}/lock" - "{snap_common}/lock"
- "{snap_common}/log" - "{snap_common}/log"
- "{snap_common}/run" - "{snap_common}/run"
# If the OpenStack service has an API that runs behind uwsgi+nginx,
# define uwsgi and nginx etc dirs.
- "{snap_common}/etc/nginx/sites-enabled" - "{snap_common}/etc/nginx/sites-enabled"
- "{snap_common}/etc/nginx/snap/sites-enabled" - "{snap_common}/etc/nginx/snap/sites-enabled"
- "{snap_common}/etc/uwsgi/snap" - "{snap_common}/etc/uwsgi/snap"
templates: templates:
# The gnocchi snap will likely require a template for the corresponding
# OpenStack service(s). For example, you may need to render a template such
# as the following.
gnocchi-snap.conf.j2: "{snap_common}/etc/gnocchi/gnocchi.conf.d/gnocchi-snap.conf" gnocchi-snap.conf.j2: "{snap_common}/etc/gnocchi/gnocchi.conf.d/gnocchi-snap.conf"
# If the OpenStack service has an API that runs behind uwsgi+nginx,
# render nginx config templates.
gnocchi-nginx.conf.j2: "{snap_common}/etc/nginx/snap/sites-enabled/gnocchi.conf" gnocchi-nginx.conf.j2: "{snap_common}/etc/nginx/snap/sites-enabled/gnocchi.conf"
nginx.conf.j2: "{snap_common}/etc/nginx/snap/nginx.conf" nginx.conf.j2: "{snap_common}/etc/nginx/snap/nginx.conf"
entry_points: entry_points:
# This is where entry_points are defined for the OpenStack service. For example, gnocchi-api:
# the service may have a database command-line tool such as the following. binary: "{snap}/bin/gnocchi-api"
gnocchi-manage:
binary: "{snap}/bin/gnocchi-manage"
config-files: config-files:
- "{snap}/etc/gnocchi/gnocchi.conf" - "{snap}/etc/gnocchi/gnocchi.conf"
config-files-override: config-files-override:
- "{snap_common}/etc/gnocchi/gnocchi.conf" - "{snap_common}/etc/gnocchi/gnocchi.conf"
config-dirs: config-dirs:
- "{snap_common}/etc/gnocchi/gnocchi.conf.d" - "{snap_common}/etc/gnocchi/gnocchi.conf.d"
# If the OpenStack service has an API that runs behind uwsgi+nginx, the log-file: "{snap_common}/log/gnocchi-api.log"
# following entry_point must be defined. gnocchi-metricd:
binary: "{snap}/bin/gnocchi-metricd"
config-files:
- "{snap}/etc/gnocchi/gnocchi.conf"
config-files-override:
- "{snap_common}/etc/gnocchi/gnocchi.conf"
config-dirs:
- "{snap_common}/etc/gnocchi/gnocchi.conf.d"
log-file: "{snap_common}/log/gnocchi-metricd.log"
gnocchi-uwsgi: gnocchi-uwsgi:
type: uwsgi type: uwsgi
uwsgi-dir: "{snap_common}/etc/uwsgi/snap" uwsgi-dir: "{snap_common}/etc/uwsgi/snap"
@ -46,8 +45,6 @@ entry_points:
log-file: "{snap_common}/log/gnocchi-api.log" log-file: "{snap_common}/log/gnocchi-api.log"
templates: templates:
gnocchi-api.ini.j2: "{snap_common}/etc/uwsgi/snap/gnocchi-api.ini" gnocchi-api.ini.j2: "{snap_common}/etc/uwsgi/snap/gnocchi-api.ini"
# If the OpenStack service has an API that runs behind uwsgi+nginx, the
# following entry_point must be defined.
gnocchi-nginx: gnocchi-nginx:
type: nginx type: nginx
config-file: "{snap_common}/etc/nginx/snap/nginx.conf" config-file: "{snap_common}/etc/nginx/snap/nginx.conf"

View File

@ -4,8 +4,8 @@
# the service it provides, and you may even need to provide multiple uwsgi files # the service it provides, and you may even need to provide multiple uwsgi files
# if there is more than one wsgi application. # if there is more than one wsgi application.
[uwsgi] [uwsgi]
wsgi-file = {{ snap }}/bin/gnocchi-wsgi-file-name wsgi-file = {{ snap }}/bin/gnocchi-api
uwsgi-socket = {{ snap_common }}/run/api-name.sock uwsgi-socket = {{ snap_common }}/run/gnocchi-api.sock
buffer-size = 65535 buffer-size = 65535
master = true master = true
enable-threads = true enable-threads = true

View File

@ -1,14 +1,11 @@
# If the OpenStack service has an API that runs behind uwsgi+nginx, you'll need # gnocchi-api
# to define this template. Be sure to update "listen" with the port number and
# also update "api-name" for the socket.
server { server {
listen 1234; listen 8041;
access_log {{ snap_common }}/log/nginx-access.log; access_log {{ snap_common }}/log/nginx-access.log;
error_log {{ snap_common }}/log/nginx-error.log; error_log {{ snap_common }}/log/nginx-error.log;
location / { location / {
include uwsgi_params;
include {{ snap }}/usr/conf/uwsgi_params; include {{ snap }}/usr/conf/uwsgi_params;
uwsgi_param SCRIPT_NAME ''; uwsgi_param SCRIPT_NAME '';
uwsgi_pass unix://{{ snap_common }}/run/api-name.sock; uwsgi_pass unix://{{ snap_common }}/run/gnocchi-api.sock;
} }
} }

View File

@ -1,46 +1,55 @@
name: gnocchi name: gnocchi
version: pike version: ocata
summary: Time Series Database as a Service summary: Time Series Database as a Service
description: | description: |
Gnocchi is an open-source, multi-tenant timeseries, metrics and resources database. It provides an HTTP REST interface to create and manipulate the data. It is designed to store metrics at a very large scale while providing access to metrics and resources information and history. Gnocchi is an open-source, multi-tenant timeseries, metrics and
resources database. It provides an HTTP REST interface to create and
manipulate the data. It is designed to store metrics at a very large
scale while providing access to metrics and resources information
and history.
confinement: strict confinement: strict
grade: devel grade: devel
apps: apps:
# If the OpenStack service has an API that runs behind uwsgi+nginx, the folowing api:
# app is required. command: snap-openstack gnocchi-api
daemon: simple
plugs:
- network-bind
metricd:
command: snap-openstack gnocchi-metricd
daemon: simple
plugs:
- network
uwsgi: uwsgi:
command: snap-openstack gnocchi-uwsgi command: snap-openstack gnocchi-uwsgi
daemon: simple daemon: simple
plugs: plugs:
- network-bind - network-bind
# If the OpenStack service has an API that runs behind uwsgi+nginx, the folowing
# app is required.
nginx: nginx:
command: snap-openstack gnocchi-nginx command: snap-openstack gnocchi-nginx
daemon: forking daemon: forking
plugs: plugs:
- network-bind - network-bind
# Following is an example of creating a command app. gnocchi-config-generator:
manage: command: bin/gnocchi-config-generator
command: snap-openstack gnocchi-manage gnocchi-upgrade:
plugs: command: bin/gnocchi-upgrade
- network
parts: parts:
# Following is an example of defining a part to build an OpenStack project
gnocchi: gnocchi:
plugin: python plugin: python
python-version: python2 python-version: python2
source: http://tarballs.openstack.org/gnocchi/gnocchi-stable-pike.tar.gz source: http://tarballs.openstack.org/gnocchi/gnocchi-stable-3.1.tar.gz
python-packages: python-packages:
# You may need to pull in additional python packages - tooz
- oslo.db
- lz4
- python-memcached - python-memcached
- pymysql - pymysql
# If the OpenStack service has an API that runs behind uwsgi+nginx, uwsgi is required.
- uwsgi - uwsgi
- git+https://github.com/openstack/snap.openstack#egg=snap.openstack - git+https://github.com/openstack/snap.openstack#egg=snap.openstack
constraints: https://raw.githubusercontent.com/openstack/requirements/stable/pike/upper-constraints.txt # constraints: https://raw.githubusercontent.com/openstack/requirements/stable/ocata/upper-constraints.txt
build-packages: build-packages:
- gcc - gcc
- libffi-dev - libffi-dev
@ -52,7 +61,7 @@ parts:
touch $SNAPCRAFT_PART_INSTALL/lib/python2.7/site-packages/repoze/__init__.py touch $SNAPCRAFT_PART_INSTALL/lib/python2.7/site-packages/repoze/__init__.py
export SNAP_ROOT="../../.." export SNAP_ROOT="../../.."
export SNAP_SITE_PACKAGES="$SNAPCRAFT_PART_INSTALL/lib/python2.7/site-packages" export SNAP_SITE_PACKAGES="$SNAPCRAFT_PART_INSTALL/lib/python2.7/site-packages"
patch -d $SNAP_SITE_PACKAGES -p1 < $SNAP_ROOT/patches/oslo-config-dirs.patch # patch -d $SNAP_SITE_PACKAGES -p1 < $SNAP_ROOT/patches/oslo-config-dirs.patch
templates: templates:
after: [gnocchi] after: [gnocchi]
plugin: dump plugin: dump
@ -61,7 +70,7 @@ parts:
config: config:
after: [gnocchi] after: [gnocchi]
plugin: dump plugin: dump
source: http://tarballs.openstack.org/gnocchi/gnocchi-stable-pike.tar.gz source: http://tarballs.openstack.org/gnocchi/gnocchi-stable-3.1.tar.gz
organize: organize:
etc/*.conf: etc/gnocchi/ etc/*.conf: etc/gnocchi/
etc/*.ini: etc/gnocchi/ etc/*.ini: etc/gnocchi/
@ -75,8 +84,6 @@ parts:
- etc/gnocchi/*.templates - etc/gnocchi/*.templates
stage: [$etc] stage: [$etc]
prime: [$etc] prime: [$etc]
# If the OpenStack service has an API that runs behind uwsgi+nginx, the following
# part is required.
nginx: nginx:
source: http://www.nginx.org/download/nginx-1.13.0.tar.gz source: http://www.nginx.org/download/nginx-1.13.0.tar.gz
plugin: autotools plugin: autotools
@ -99,8 +106,6 @@ parts:
export SNAP_ROOT="../../.." export SNAP_ROOT="../../.."
export SNAP_SOURCE="$SNAP_ROOT/parts/nginx/build" export SNAP_SOURCE="$SNAP_ROOT/parts/nginx/build"
patch -d $SNAP_SOURCE -p1 < $SNAP_ROOT/patches/drop-nginx-setgroups.patch patch -d $SNAP_SOURCE -p1 < $SNAP_ROOT/patches/drop-nginx-setgroups.patch
# If the OpenStack service has an API that runs behind uwsgi+nginx, the following
# part is required.
libxml2: libxml2:
source: http://xmlsoft.org/sources/libxml2-2.9.4.tar.gz source: http://xmlsoft.org/sources/libxml2-2.9.4.tar.gz
plugin: autotools plugin: autotools

View File

@ -0,0 +1,585 @@
[DEFAULT]
#
# From cotyledon
#
# Enables or disables logging values of all registered options when starting a
# service (at DEBUG level). (boolean value)
# Note: This option can be changed without restarting.
#log_options = true
# Specify a timeout after which a gracefully shutdown server will exit. Zero
# value means endless wait. (integer value)
# Note: This option can be changed without restarting.
#graceful_shutdown_timeout = 60
#
# From oslo.log
#
# If set to true, the logging level will be set to DEBUG instead of the default
# INFO level. (boolean value)
# Note: This option can be changed without restarting.
#debug = false
# 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 logging module documentation. Note that when logging
# configuration files are used then all logging configuration is set in the
# configuration file and other logging configuration options are ignored (for
# example, logging_context_format_string). (string value)
# Note: This option can be changed without restarting.
# Deprecated group/name - [DEFAULT]/log_config
#log_config_append = <None>
# Defines the format string for %%(asctime)s in log records. Default:
# %(default)s . This option is ignored if log_config_append is set. (string
# value)
#log_date_format = %Y-%m-%d %H:%M:%S
# (Optional) Name of log file to send logging output to. If no default is set,
# logging will go to stderr as defined by use_stderr. This option is ignored if
# log_config_append is set. (string value)
# Deprecated group/name - [DEFAULT]/logfile
#log_file = <None>
# (Optional) The base directory used for relative log_file paths. This option
# is ignored if log_config_append is set. (string value)
# Deprecated group/name - [DEFAULT]/logdir
#log_dir = <None>
# Uses logging handler designed to watch file system. When log file is moved or
# removed this handler will open a new log file with specified path
# instantaneously. It makes sense only if log_file option is specified and
# Linux platform is used. This option is ignored if log_config_append is set.
# (boolean value)
#watch_log_file = false
# Use syslog for logging. Existing syslog format is DEPRECATED and will be
# changed later to honor RFC5424. This option is 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
# Log output to standard error. This option is ignored if log_config_append is
# set. (boolean value)
#use_stderr = false
# Format string to use for log messages with context. (string value)
#logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s
# Format string to use for log messages when context is undefined. (string
# value)
#logging_default_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s
# Additional data to append to log message when logging level for the message
# is DEBUG. (string value)
#logging_debug_format_suffix = %(funcName)s %(pathname)s:%(lineno)d
# Prefix each line of exception output with this format. (string value)
#logging_exception_prefix = %(asctime)s.%(msecs)03d %(process)d ERROR %(name)s %(instance)s
# Defines the format string for %(user_identity)s that is used in
# logging_context_format_string. (string value)
#logging_user_identity_format = %(user)s %(tenant)s %(domain)s %(user_domain)s %(project_domain)s
# List of package logging levels in logger=LEVEL pairs. This option is ignored
# if log_config_append is set. (list value)
#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,oslo_messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
# Enables or disables publication of error events. (boolean value)
#publish_errors = false
# The format for an instance that is passed with the log message. (string
# value)
#instance_format = "[instance: %(uuid)s] "
# The format for an instance UUID that is passed with the log message. (string
# value)
#instance_uuid_format = "[instance: %(uuid)s] "
# Interval, number of seconds, of log rate limiting. (integer value)
#rate_limit_interval = 0
# Maximum number of logged messages per rate_limit_interval. (integer value)
#rate_limit_burst = 0
# Log level name used by rate limiting: CRITICAL, ERROR, INFO, WARNING, DEBUG
# or empty string. Logs with level greater or equal to rate_limit_except_level
# are not filtered. An empty string means that all levels are filtered. (string
# value)
#rate_limit_except_level = CRITICAL
# Enables or disables fatal status of deprecations. (boolean value)
#fatal_deprecations = false
[api]
#
# From gnocchi
#
# Path to API Paste configuration. (string value)
#paste_config = /snap/gnocchi/x1/lib/python2.7/site-packages/gnocchi/rest/api-paste.ini
# Authentication mode to use. (string value)
# Allowed values: keystone, noauth, basic
#auth_mode = basic
# The maximum number of items returned in a single response from a collection
# resource (integer value)
#max_limit = 1000
[archive_policy]
#
# From gnocchi
#
# Default aggregation methods to use in created archive policies (list value)
#default_aggregation_methods = mean,min,max,sum,std,count
[cors]
#
# From oslo.middleware.cors
#
# Indicate whether this resource may be shared with the domain received in the
# requests "origin" header. Format: "<protocol>://<host>[:<port>]", no trailing
# slash. Example: https://horizon.example.com (list value)
#allowed_origin = <None>
# Indicate that the actual request can include user credentials (boolean value)
#allow_credentials = true
# Indicate which headers are safe to expose to the API. Defaults to HTTP Simple
# Headers. (list value)
#expose_headers =
# Maximum cache age of CORS preflight requests. (integer value)
#max_age = 3600
# Indicate which methods can be used during the actual request. (list value)
#allow_methods = OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,PATCH
# Indicate which header field names may be used during the actual request.
# (list value)
#allow_headers = X-Auth-Token,X-Subject-Token,X-User-Id,X-Domain-Id,X-Project-Id,X-Roles
[database]
#
# From oslo.db
#
# If True, SQLite uses synchronous mode. (boolean value)
#sqlite_synchronous = true
# The back end to use for the database. (string value)
# Deprecated group/name - [DEFAULT]/db_backend
#backend = sqlalchemy
# The SQLAlchemy connection string to use to connect to the database. (string
# value)
# Deprecated group/name - [DEFAULT]/sql_connection
# Deprecated group/name - [DATABASE]/sql_connection
# Deprecated group/name - [sql]/connection
#connection = <None>
# The SQLAlchemy connection string to use to connect to the slave database.
# (string value)
#slave_connection = <None>
# The SQL mode to be used for MySQL sessions. This option, including the
# default, overrides any server-set SQL mode. To use whatever SQL mode is set
# by the server configuration, set this to no value. Example: mysql_sql_mode=
# (string value)
#mysql_sql_mode = TRADITIONAL
# If True, transparently enables support for handling MySQL Cluster (NDB).
# (boolean value)
#mysql_enable_ndb = false
# Timeout before idle SQL connections are reaped. (integer value)
# Deprecated group/name - [DEFAULT]/sql_idle_timeout
# Deprecated group/name - [DATABASE]/sql_idle_timeout
# Deprecated group/name - [sql]/idle_timeout
#idle_timeout = 3600
# Minimum number of SQL connections to keep open in a pool. (integer value)
# Deprecated group/name - [DEFAULT]/sql_min_pool_size
# Deprecated group/name - [DATABASE]/sql_min_pool_size
#min_pool_size = 1
# Maximum number of SQL connections to keep open in a pool. Setting a value of
# 0 indicates no limit. (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_pool_size
# Deprecated group/name - [DATABASE]/sql_max_pool_size
#max_pool_size = 5
# Maximum number of database connection retries during startup. Set to -1 to
# specify an infinite retry count. (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_retries
# Deprecated group/name - [DATABASE]/sql_max_retries
#max_retries = 10
# Interval between retries of opening a SQL connection. (integer value)
# Deprecated group/name - [DEFAULT]/sql_retry_interval
# Deprecated group/name - [DATABASE]/reconnect_interval
#retry_interval = 10
# If set, use this value for max_overflow with SQLAlchemy. (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_overflow
# Deprecated group/name - [DATABASE]/sqlalchemy_max_overflow
#max_overflow = 50
# Verbosity of SQL debugging information: 0=None, 100=Everything. (integer
# value)
# Minimum value: 0
# Maximum value: 100
# Deprecated group/name - [DEFAULT]/sql_connection_debug
#connection_debug = 0
# Add Python stack traces to SQL as comment strings. (boolean value)
# Deprecated group/name - [DEFAULT]/sql_connection_trace
#connection_trace = false
# If set, use this value for pool_timeout with SQLAlchemy. (integer value)
# Deprecated group/name - [DATABASE]/sqlalchemy_pool_timeout
#pool_timeout = <None>
# Enable the experimental use of database reconnect on connection lost.
# (boolean value)
#use_db_reconnect = false
# Seconds between retries of a database transaction. (integer value)
#db_retry_interval = 1
# If True, increases the interval between retries of a database operation up to
# db_max_retry_interval. (boolean value)
#db_inc_retry_interval = true
# If db_inc_retry_interval is set, the maximum seconds between retries of a
# database operation. (integer value)
#db_max_retry_interval = 10
# Maximum retries in case of connection error or deadlock error before error is
# raised. Set to -1 to specify an infinite retry count. (integer value)
#db_max_retries = 20
[healthcheck]
#
# From oslo.middleware.healthcheck
#
# DEPRECATED: The path to respond to healtcheck requests on. (string value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
#path = /healthcheck
# Show more detailed information as part of the response (boolean value)
#detailed = false
# Additional backends that can perform health checks and report that
# information back as part of a request. (list value)
#backends =
# Check the presence of a file to determine if an application is running on a
# port. Used by DisableByFileHealthcheck plugin. (string value)
#disable_by_file_path = <None>
# Check the presence of a file based on a port to determine if an application
# is running on a port. Expects a "port:path" list of strings. Used by
# DisableByFilesPortsHealthcheck plugin. (list value)
#disable_by_file_paths =
[incoming]
#
# From gnocchi
#
# Storage driver to use (string value)
#driver = ${storage.driver}
# Ceph pool name to use. (string value)
#ceph_pool = ${storage.ceph_pool}
# Ceph username (ie: admin without "client." prefix). (string value)
#ceph_username = ${storage.ceph_username}
# Ceph key (string value)
#ceph_secret = ${storage.ceph_secret}
# Ceph keyring path. (string value)
#ceph_keyring = ${storage.ceph_keyring}
# Ceph configuration file. (string value)
#ceph_conffile = ${storage.ceph_conffile}
# Path used to store gnocchi data files. (string value)
#file_basepath = ${storage.file_basepath}
# Swift authentication version to user. (string value)
#swift_auth_version = ${storage.swift_auth_version}
# Swift pre-auth URL. (string value)
#swift_preauthurl = ${storage.swift_preauthurl}
# Swift auth URL. (string value)
#swift_authurl = ${storage.swift_authurl}
# Swift token to user to authenticate. (string value)
#swift_preauthtoken = ${storage.swift_preauthtoken}
# Swift user. (string value)
#swift_user = ${storage.swift_user}
# Swift user domain name. (string value)
#swift_user_domain_name = ${storage.swift_user_domain_name}
# Swift key/password. (string value)
#swift_key = ${storage.swift_key}
# Swift tenant name, only used in v2/v3 auth. (string value)
# Deprecated group/name - [incoming]/swift_tenant_name
#swift_project_name = ${storage.swift_project_name}
# Swift project domain name. (string value)
#swift_project_domain_name = ${storage.swift_project_domain_name}
# Prefix to namespace metric containers. (string value)
#swift_container_prefix = ${storage.swift_container_prefix}
# Endpoint type to connect to Swift (string value)
#swift_endpoint_type = ${storage.swift_endpoint_type}
# Connection timeout in seconds. (integer value)
# Minimum value: 0
#swift_timeout = ${storage.swift_timeout}
# S3 endpoint URL (string value)
#s3_endpoint_url = ${storage.s3_endpoint_url}
# S3 region name (string value)
#s3_region_name = ${storage.s3_region_name}
# S3 access key id (string value)
#s3_access_key_id = ${storage.s3_access_key_id}
# S3 secret access key (string value)
#s3_secret_access_key = ${storage.s3_secret_access_key}
# Prefix to namespace metric bucket. (string value)
#s3_bucket_prefix = ${storage.s3_bucket_prefix}
[indexer]
#
# From gnocchi
#
# Indexer driver to use (string value)
url = mysql://gnocchi:changeme@localhost/gnocchi
[metricd]
#
# From gnocchi
#
# Number of workers for Gnocchi metric daemons. By default the available number
# of CPU is used. (integer value)
# Minimum value: 1
#workers = <None>
# How many seconds to wait between scheduling new metrics to process (integer
# value)
#metric_processing_delay = 60
# How many seconds to wait between metric ingestion reporting. Set value to -1
# to disable reporting (integer value)
# Minimum value: -1
#metric_reporting_delay = 120
# How many seconds to wait between cleaning of expired data (integer value)
#metric_cleanup_delay = 300
[oslo_middleware]
#
# From oslo.middleware.http_proxy_to_wsgi
#
# Whether the application is behind a proxy or not. This determines if the
# middleware should parse the headers or not. (boolean value)
#enable_proxy_headers_parsing = false
[oslo_policy]
#
# From oslo.policy
#
# The file that defines policies. (string value)
#policy_file = policy.json
# Default rule. Enforced when a requested rule is not found. (string value)
#policy_default_rule = default
# Directories where policy configuration files are stored. They can be relative
# to any directory in the search path defined by the config_dir option, or
# absolute paths. The file defined by policy_file must exist for these
# directories to be searched. Missing or empty directories are ignored. (multi
# valued)
#policy_dirs = policy.d
[statsd]
#
# From gnocchi
#
resource_id = `uuidgen`
# The listen IP for statsd (string value)
#host = 0.0.0.0
# The port for statsd (port value)
# Minimum value: 0
# Maximum value: 65535
#port = 8125
# Resource UUID to use to identify statsd in Gnocchi (unknown value)
#resource_id = <None>
# DEPRECATED: User ID to use to identify statsd in Gnocchi (string value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
#user_id = <None>
# DEPRECATED: Project ID to use to identify statsd in Gnocchi (string value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
#project_id = <None>
# Creator value to use to identify statsd in Gnocchi (string value)
#creator = ${statsd.user_id}:${statsd.project_id}
# Archive policy name to use when creating metrics (string value)
#archive_policy_name = <None>
# Delay between flushes (floating point value)
#flush_delay = 10
[storage]
#
# From gnocchi
#
# Storage driver to use (string value)
#driver = file
# Ceph pool name to use. (string value)
#ceph_pool = gnocchi
# Ceph username (ie: admin without "client." prefix). (string value)
#ceph_username = <None>
# Ceph key (string value)
#ceph_secret = <None>
# Ceph keyring path. (string value)
#ceph_keyring = <None>
# Ceph configuration file. (string value)
#ceph_conffile = /etc/ceph/ceph.conf
# Path used to store gnocchi data files. (string value)
#file_basepath = /var/lib/gnocchi
# Swift authentication version to user. (string value)
#swift_auth_version = 1
# Swift pre-auth URL. (string value)
#swift_preauthurl = <None>
# Swift auth URL. (string value)
#swift_authurl = http://localhost:8080/auth/v1.0
# Swift token to user to authenticate. (string value)
#swift_preauthtoken = <None>
# Swift user. (string value)
#swift_user = admin:admin
# Swift user domain name. (string value)
#swift_user_domain_name = Default
# Swift key/password. (string value)
#swift_key = admin
# Swift tenant name, only used in v2/v3 auth. (string value)
# Deprecated group/name - [storage]/swift_tenant_name
#swift_project_name = <None>
# Swift project domain name. (string value)
#swift_project_domain_name = Default
# Prefix to namespace metric containers. (string value)
#swift_container_prefix = gnocchi
# Endpoint type to connect to Swift (string value)
#swift_endpoint_type = publicURL
# Connection timeout in seconds. (integer value)
# Minimum value: 0
#swift_timeout = 300
# S3 endpoint URL (string value)
#s3_endpoint_url = <None>
# S3 region name (string value)
#s3_region_name = <None>
# S3 access key id (string value)
#s3_access_key_id = <None>
# S3 secret access key (string value)
#s3_secret_access_key = <None>
# Prefix to namespace metric bucket. (string value)
#s3_bucket_prefix = gnocchi
# Number of workers to run during adding new measures for pre-aggregation
# needs. Due to the Python GIL, 1 is usually faster, unless you have high
# latency I/O (integer value)
# Minimum value: 1
#aggregation_workers_number = 1
# Coordination driver URL (string value)
#coordination_url = <None>

43
tests/gnocchi.sh Normal file
View File

@ -0,0 +1,43 @@
#!/bin/bash
set -ex
DAEMONS=('snap.gnocchi.api.service', 'snap.gnocchi.metricd.service')
ret=0
sudo mysql -u root <<EOF
DROP DATABASE IF EXISTS gnocchi;
CREATE DATABASE gnocchi;
GRANT ALL PRIVILEGES ON gnocchi.* TO 'gnocchi'@'localhost' \
IDENTIFIED BY 'changeme';
GRANT ALL PRIVILEGES ON gnocchi.* TO 'gnocchi'@'%' \
IDENTIFIED BY 'changeme';
EOF
while sudo [ ! -d /var/snap/gnocchi/common/etc/gnocchi/ ]; do sleep 0.1; done;
# TODO: this may not be the right dir -- gnocchi doesn't seem to be
# able to see the indexer url that we set (or it might just be the
# wrong file).
sudo cp -r $BASE_DIR/etc/snap-gnocchi/* /var/snap/gnocchi/common/etc/
gnocchi.gnocchi-upgrade
for daemon in "${DAEMONS[@]}"; do
systemctl restart $daemon
TIMEOUT=50
while [ "$TIMEOUT" -gt 0 ]; do
if systemctl is-active $daemon > /dev/null; then
echo "OK"
break
fi
TIMEOUT=$((TIMEOUT - 1))
sleep 0.1
done
if [ "$TIMEOUT" -le 0 ]; then
echo "ERROR: ${daemon} IS NOT RUNNING"
ret=1
fi
done
exit $ret

7
tests/gnocchi_cleanup.sh Normal file
View File

@ -0,0 +1,7 @@
#!/bin/bash
set -ex
sudo mysql -u root <<EOF
DROP DATABASE IF EXISTS gnocchi;
EOF

28
tests/snapstack_test.py Normal file
View File

@ -0,0 +1,28 @@
import unittest
from snapstack import Plan, Setup, Step
class SnapstackTest(unittest.TestCase):
def test_snapstack(self):
'''
_test_snapstack_
Run a basic smoke test, utilizing our snapstack testing harness.
'''
gnocchi = Step(
snap='gnocchi',
script_loc='./tests/',
scripts=['gnocchi.sh'],
files=[
'etc/snap-gnocchi/gnocchi/gnocchi.conf'
],
snap_store=False)
gnocchi_cleanup = Step(
script_loc='./tests/',
scripts=['gnocchi_cleanup.sh'])
plan = Plan(tests=[gnocchi], test_cleanup=[gnocchi_cleanup])
plan.run()

15
tox.ini
View File

@ -5,14 +5,19 @@ skipsdist = True
[testenv] [testenv]
basepython = python3.5 basepython = python3.5
install_command = pip install {opts} {packages} install_command = pip install {opts} {packages}
passenv = HOME TERM passenv =
HOME
TERM
SNAPSTACK_HTTP_PROXY
SNAPSTACK_HTTPS_PROXY
whitelist_externals = whitelist_externals =
sudo sudo
snapcraft snapcraft
[testenv:snap] [testenv:snap]
deps = -r{toxinidir}/requirements.txt deps =
-r{toxinidir}/requirements.txt
git+https://github.com/openstack-snaps/snapstack
pytest
commands = commands =
sudo snap install core py.test -s tests/
snapcraft clean
snapcraft snap