├── tests ├── __init__.py ├── test.conf.template ├── config.py ├── utils.py └── test_plugin_monitor.py ├── debian ├── compat ├── copyright ├── calamari-server.install ├── source │ └── format ├── calamari-server.docs ├── calamari-server.prerm ├── rules ├── changelog ├── calamari-server.postrm ├── control └── calamari-server.postinst ├── minion-sim ├── __init__.py ├── minion_sim │ ├── __init__.py │ ├── log.py │ └── load_gen.py └── setup.py ├── rest-api ├── __init__.py ├── tests │ ├── __init__.py │ ├── test_crushmap.py │ ├── test_saltkey.py │ ├── test_keys.py │ ├── rest_api_unit_test.py │ └── test_osd.py ├── calamari_rest │ ├── __init__.py │ ├── parsers │ │ ├── __init__.py │ │ └── v2.py │ ├── urls │ │ └── __init__.py │ ├── views │ │ ├── __init__.py │ │ ├── exceptions.py │ │ ├── crush_node.py │ │ ├── database_view_set.py │ │ └── paginated_mixin.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ └── __init__.py │ ├── serializers │ │ ├── __init__.py │ │ └── fields.py │ ├── models.py │ ├── viewsets │ │ └── __init__.py │ ├── fixtures │ │ └── ceph_fake.json │ ├── renderers │ │ └── __init__.py │ └── permissions │ │ └── __init__.py └── setup.py ├── rlyeh ├── rlyeh │ ├── __init__.py │ ├── manager │ │ └── __init__.py │ ├── log.py │ ├── util.py │ └── gevent_util.py └── setup.py ├── calamari-common ├── __init__.py ├── calamari_common │ ├── __init__.py │ ├── db │ │ ├── __init__.py │ │ ├── base.py │ │ └── event.py │ ├── util.py │ ├── remote │ │ └── __init__.py │ └── config.py └── setup.py ├── cthulhu ├── cthulhu │ ├── __init__.py │ ├── persistence │ │ ├── __init__.py │ │ ├── sync_objects.py │ │ └── servers.py │ ├── manager │ │ ├── __init__.py │ │ ├── crush_request_factory.py │ │ └── request_factory.py │ ├── log.py │ ├── util.py │ └── gevent_util.py ├── tests │ ├── __init__.py │ ├── plugins │ │ ├── __init__.py │ │ ├── acmeplugin │ │ │ ├── __init__.py │ │ │ └── status_processor.py │ │ └── wilyplugin │ │ │ └── __init__.py │ ├── test_persist.py │ ├── util.py │ ├── mon_map_1_removed.json │ ├── mds1_services.json │ ├── mds2_services.json │ ├── gravel1.rockery_services.json │ ├── mon_map.json │ ├── config.py │ ├── gravel2.rockery_services.json │ ├── gravel1.rockery_services_migrated.json │ ├── test_plugin_monitor.py │ ├── test_rpc.py │ ├── test_pg_progress.py │ ├── mds_map_1_removed.json │ ├── test_manager.py │ └── mds_map.json └── setup.py ├── doc ├── calamari_rest │ ├── .gitignore │ ├── resources │ │ ├── api_example_api_v2_auth_login.rst │ │ ├── api_example_api_v2_server__fqdn__log.rst │ │ ├── api_example_api_v2_user__pk_.rst │ │ ├── api_example_api_v2_key__minion_id_.rst │ │ ├── api_example_api_v2_cluster.rst │ │ ├── api_example_api_v2_cluster__fsid__osd _command.rst │ │ ├── api_example_api_v2_cluster__fsid__crush_type__type_id_.rst │ │ ├── api_example_api_v2_cluster__pk_.rst │ │ ├── api_example_api_v2_user.rst │ │ ├── api_example_api_v2_cluster__fsid__config__key_.rst │ │ ├── api_example_api_v2_cluster__fsid__derived_object.rst │ │ ├── api_example_api_v2_cluster__fsid__sync_object.rst │ │ ├── api_example_api_v2_cluster__fsid__mon__mon_id_.rst │ │ ├── api_example_api_v2_cluster__fsid__osd__osd_id__command.rst │ │ ├── api_example_api_v2_cluster__fsid__osd_config.rst │ │ ├── api_example_api_v2_info.rst │ │ ├── api_example_api_v2_request__request_id_.rst │ │ ├── api_example_api_v2_cluster__fsid__pool__pool_id_.rst │ │ ├── api_example_api_v2_request.rst │ │ ├── api_example_api_v2_cluster__fsid__request__request_id_.rst │ │ ├── api_example_api_v2_key.rst │ │ ├── api_example_api_v2_cluster__fsid__osd__osd_id_.rst │ │ ├── api_example_api_v2_cluster__fsid__request.rst │ │ ├── api_example_api_v2_cluster__fsid__crush_type.rst │ │ ├── api_example_api_v2_cluster__fsid__mon.rst │ │ ├── api_example_api_v2_cluster__fsid__osd__osd_id__command__command_.rst │ │ ├── api_example_api_v2_cluster__fsid__crush_node__node_id_.rst │ │ ├── api_example_api_v2_cluster__fsid__event.rst │ │ ├── api_example_api_v2_cluster__fsid__mon__mon_id__status.rst │ │ ├── api_example_api_v2_server__fqdn_.rst │ │ ├── api_example_api_v2_cluster__fsid__server__fqdn_.rst │ │ ├── api_example_api_v2_cluster__fsid__log.rst │ │ ├── api_example_api_v2_cluster__fsid__pool.rst │ │ ├── api_example_api_v2_server__fqdn__log__log_path_.rst │ │ ├── api_example_api_v2_cluster__fsid__crush_map.rst │ │ └── api_example_api_v2_cluster__fsid__crush_rule.rst │ ├── authentication.rst │ └── index.rst ├── plugin │ ├── backend.rst │ ├── frontend.rst │ ├── _themes │ │ └── ceph │ │ │ ├── theme.conf │ │ │ └── static │ │ │ └── font │ │ │ ├── ApexSans-Book.eot │ │ │ ├── ApexSans-Book.ttf │ │ │ ├── ApexSans-Book.woff │ │ │ ├── ApexSans-Medium.eot │ │ │ ├── ApexSans-Medium.ttf │ │ │ └── ApexSans-Medium.woff │ └── index.rst ├── _themes │ └── ceph │ │ ├── theme.conf │ │ └── static │ │ └── font │ │ ├── ApexSans-Book.eot │ │ ├── ApexSans-Book.ttf │ │ ├── ApexSans-Book.woff │ │ ├── ApexSans-Medium.eot │ │ ├── ApexSans-Medium.ttf │ │ └── ApexSans-Medium.woff ├── requirements.txt ├── contents.rst ├── operations │ ├── index.rst │ ├── configuring_ceph.rst │ ├── reporting_bugs.rst │ ├── troubleshooting.rst │ └── users.rst ├── development │ ├── OSX.rst │ ├── index.rst │ ├── coding_style.rst │ ├── logging.rst │ ├── communications.rst │ ├── cthulhu_components.rst │ ├── coverage.rst │ ├── cthulhu_locking.rst │ └── debugging.rst ├── index.rst └── calamari.conf ├── calamari-web ├── calamari_web │ ├── __init__.py │ ├── middleware.py │ └── wsgi.py └── setup.py ├── calamari-lite ├── calamari_lite │ └── __init__.py └── setup.py ├── webapp └── calamari │ ├── .gitignore │ └── manage.py ├── requirements ├── 2.7 │ ├── requirements.force.txt │ ├── requirements.production.force.txt │ ├── requirements.production.txt │ └── requirements.txt ├── devel.txt └── lite.txt ├── alembic ├── README ├── versions │ └── README.rst └── script.py.mako ├── repobuild └── conf │ ├── precise │ ├── trusty.packages │ ├── upstream.packages │ ├── distributions │ └── updates │ ├── wheezy │ ├── jessie.packages │ ├── upstream.packages │ ├── updates │ └── distributions │ └── trusty │ ├── upstream.packages │ ├── distributions │ └── updates ├── vagrant ├── devmode │ ├── salt │ │ ├── minion │ │ ├── pillar │ │ │ ├── top.sls │ │ │ └── info.sls │ │ └── roots │ │ │ ├── git_clone.sls │ │ │ ├── start_calamari.sls │ │ │ ├── top.sls │ │ │ ├── build_deps.sls │ │ │ ├── sensible_editor_vim.sls │ │ │ ├── init_calamari.sls │ │ │ ├── postgres.sls │ │ │ ├── configs.sls │ │ │ ├── virtualenv.sls │ │ │ ├── test_calamari.sls │ │ │ └── install_mods.sls │ ├── pip_cache │ │ └── README │ └── Vagrantfile ├── centos7-build │ ├── salt │ │ ├── minion │ │ └── roots │ │ │ ├── top.sls │ │ │ ├── git_clone.sls │ │ │ ├── setvars │ │ │ ├── build_deps.sls │ │ │ └── make_packages.sls │ └── Vagrantfile ├── rhel-build │ ├── salt │ │ ├── minion │ │ └── roots │ │ │ ├── top.sls │ │ │ ├── setvars │ │ │ ├── git_clone.sls │ │ │ ├── build_deps.sls │ │ │ └── make_packages.sls │ └── Vagrantfile ├── rhel7-build │ ├── salt │ │ ├── minion │ │ ├── roots │ │ │ ├── top.sls │ │ │ ├── setvars │ │ │ ├── git_clone.sls │ │ │ ├── build_deps.sls │ │ │ └── make_packages.sls │ │ └── develop-bootstrap-salt.sh │ └── Vagrantfile ├── wheezy-build │ ├── salt │ │ ├── minion │ │ └── roots │ │ │ ├── top.sls │ │ │ ├── setvars │ │ │ ├── git_clone.sls │ │ │ ├── build_deps.sls │ │ │ └── make_packages.sls │ └── Vagrantfile ├── trusty-build │ ├── salt │ │ ├── minion │ │ └── roots │ │ │ ├── top.sls │ │ │ ├── setvars │ │ │ ├── git_clone.sls │ │ │ ├── build_deps.sls │ │ │ └── make_packages.sls │ └── Vagrantfile ├── urllib-bootstrap-salt.sh └── production │ └── Vagrantfile ├── dev ├── .gitignore ├── coverage.conf ├── README.rst ├── teuthology.yaml ├── supervisord.conf ├── etc │ └── graphite │ │ └── storage-schemas.conf ├── alembic.ini.template ├── calamari.conf.template └── configure.py ├── conf ├── logrotate.d │ └── calamari ├── calamari.service ├── salt.master.conf ├── supervisord.production.conf ├── carbon │ ├── storage-schemas.conf │ └── carbon.conf ├── upstart │ └── kraken.conf ├── calamari │ ├── suse │ │ └── calamari.conf │ ├── el6 │ │ └── calamari.conf │ ├── rhel7 │ │ └── calamari.conf │ └── debian │ │ └── calamari.conf ├── alembic.ini └── httpd │ └── calamari.conf ├── replicated_rule_crush_repr.txt ├── COPYING ├── erasure_rule_crush_repr.txt ├── calamari.service ├── pre-commit.py ├── .gitignore ├── vps_bootstrap.sh ├── calamari.te ├── selinux └── calamari-server.te ├── salt └── local │ └── services.sls ├── get-flavor.sh ├── tox.ini ├── get-versions.sh ├── crush_map_repr_before.txt ├── crush_map_repr_after.txt ├── crush_map_repr_after_update.txt ├── crush_map_repr_before_update.txt ├── .travis.yml └── README.rst /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /minion-sim/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest-api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rlyeh/rlyeh/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /calamari-common/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cthulhu/cthulhu/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cthulhu/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | ../COPYING -------------------------------------------------------------------------------- /doc/calamari_rest/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest-api/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cthulhu/tests/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cthulhu/tests/test_persist.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/calamari-server.install: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /minion-sim/minion_sim/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /calamari-web/calamari_web/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /calamari-common/calamari_common/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /calamari-lite/calamari_lite/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cthulhu/cthulhu/persistence/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/calamari-server.docs: -------------------------------------------------------------------------------- 1 | README.rst 2 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/parsers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/urls/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/views/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /webapp/calamari/.gitignore: -------------------------------------------------------------------------------- 1 | db.sqlite3 2 | -------------------------------------------------------------------------------- /calamari-common/calamari_common/db/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cthulhu/tests/plugins/acmeplugin/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cthulhu/tests/plugins/wilyplugin/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements/2.7/requirements.force.txt: -------------------------------------------------------------------------------- 1 | six 2 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/management/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/serializers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /repobuild/conf/precise/trusty.packages: -------------------------------------------------------------------------------- 1 | libzmq3 install 2 | -------------------------------------------------------------------------------- /repobuild/conf/wheezy/jessie.packages: -------------------------------------------------------------------------------- 1 | libzmq3 install 2 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements/2.7/requirements.production.force.txt: -------------------------------------------------------------------------------- 1 | six 2 | Mako 3 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/minion: -------------------------------------------------------------------------------- 1 | master: localhost 2 | file_client: local -------------------------------------------------------------------------------- /alembic/versions/README.rst: -------------------------------------------------------------------------------- 1 | This folder contains alembic migrations 2 | -------------------------------------------------------------------------------- /vagrant/centos7-build/salt/minion: -------------------------------------------------------------------------------- 1 | master: localhost 2 | file_client: local -------------------------------------------------------------------------------- /vagrant/rhel-build/salt/minion: -------------------------------------------------------------------------------- 1 | master: localhost 2 | file_client: local -------------------------------------------------------------------------------- /vagrant/rhel7-build/salt/minion: -------------------------------------------------------------------------------- 1 | master: localhost 2 | file_client: local -------------------------------------------------------------------------------- /vagrant/wheezy-build/salt/minion: -------------------------------------------------------------------------------- 1 | master: localhost 2 | file_client: local -------------------------------------------------------------------------------- /requirements/devel.txt: -------------------------------------------------------------------------------- 1 | django-nose 2 | mock 3 | pytz 4 | flake8 5 | psutil 6 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/pillar/top.sls: -------------------------------------------------------------------------------- 1 | 2 | base: 3 | '*': 4 | - info 5 | -------------------------------------------------------------------------------- /vagrant/trusty-build/salt/minion: -------------------------------------------------------------------------------- 1 | master: localhost 2 | file_client: local 3 | -------------------------------------------------------------------------------- /doc/plugin/backend.rst: -------------------------------------------------------------------------------- 1 | 2 | Backend Plugin Guide 3 | ==================== 4 | 5 | *TBD* 6 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/models.py: -------------------------------------------------------------------------------- 1 | 2 | # This file just exists to make manage.py happy 3 | -------------------------------------------------------------------------------- /doc/plugin/frontend.rst: -------------------------------------------------------------------------------- 1 | 2 | Front End Plugin Guide 3 | ====================== 4 | 5 | *TBD* 6 | -------------------------------------------------------------------------------- /dev/.gitignore: -------------------------------------------------------------------------------- 1 | calamari.conf 2 | alembic.ini 3 | etc/salt/master 4 | etc/salt/pki 5 | secret.key 6 | 7 | -------------------------------------------------------------------------------- /doc/_themes/ceph/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = basic 3 | stylesheet = nature.css 4 | pygments_style = tango 5 | -------------------------------------------------------------------------------- /doc/plugin/_themes/ceph/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = basic 3 | stylesheet = nature.css 4 | pygments_style = tango 5 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | Django==1.5.1 2 | gevent>=1.0 3 | python-dateutil==2.2 4 | pytz==2013.8 5 | sqlalchemy==0.8.3 6 | 7 | -------------------------------------------------------------------------------- /dev/coverage.conf: -------------------------------------------------------------------------------- 1 | 2 | [run] 3 | parallel = True 4 | source = cthulhu,ceph 5 | 6 | [html] 7 | omit = *site-packages*,/usr* 8 | -------------------------------------------------------------------------------- /vagrant/centos7-build/salt/roots/top.sls: -------------------------------------------------------------------------------- 1 | base: 2 | '*': 3 | - build_deps 4 | - git_clone 5 | - make_packages 6 | -------------------------------------------------------------------------------- /vagrant/rhel-build/salt/roots/top.sls: -------------------------------------------------------------------------------- 1 | base: 2 | '*': 3 | - build_deps 4 | - git_clone 5 | - make_packages 6 | -------------------------------------------------------------------------------- /vagrant/rhel7-build/salt/roots/top.sls: -------------------------------------------------------------------------------- 1 | base: 2 | '*': 3 | - build_deps 4 | - git_clone 5 | - make_packages 6 | -------------------------------------------------------------------------------- /vagrant/trusty-build/salt/roots/top.sls: -------------------------------------------------------------------------------- 1 | base: 2 | '*': 3 | - build_deps 4 | - git_clone 5 | - make_packages 6 | -------------------------------------------------------------------------------- /vagrant/wheezy-build/salt/roots/top.sls: -------------------------------------------------------------------------------- 1 | base: 2 | '*': 3 | - build_deps 4 | - git_clone 5 | - make_packages 6 | -------------------------------------------------------------------------------- /dev/README.rst: -------------------------------------------------------------------------------- 1 | 2 | This directory contains files for running an unprivileged 3 | calamari server instance for development purposes. 4 | -------------------------------------------------------------------------------- /calamari-common/calamari_common/db/base.py: -------------------------------------------------------------------------------- 1 | 2 | from sqlalchemy.ext.declarative import declarative_base 3 | 4 | Base = declarative_base() 5 | -------------------------------------------------------------------------------- /conf/logrotate.d/calamari: -------------------------------------------------------------------------------- 1 | /var/log/calamari/*.log { 2 | rotate 7 3 | daily 4 | compress 5 | dateext 6 | copytruncate 7 | } -------------------------------------------------------------------------------- /doc/_themes/ceph/static/font/ApexSans-Book.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/_themes/ceph/static/font/ApexSans-Book.eot -------------------------------------------------------------------------------- /doc/_themes/ceph/static/font/ApexSans-Book.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/_themes/ceph/static/font/ApexSans-Book.ttf -------------------------------------------------------------------------------- /doc/_themes/ceph/static/font/ApexSans-Book.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/_themes/ceph/static/font/ApexSans-Book.woff -------------------------------------------------------------------------------- /doc/_themes/ceph/static/font/ApexSans-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/_themes/ceph/static/font/ApexSans-Medium.eot -------------------------------------------------------------------------------- /doc/_themes/ceph/static/font/ApexSans-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/_themes/ceph/static/font/ApexSans-Medium.ttf -------------------------------------------------------------------------------- /doc/_themes/ceph/static/font/ApexSans-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/_themes/ceph/static/font/ApexSans-Medium.woff -------------------------------------------------------------------------------- /doc/plugin/_themes/ceph/static/font/ApexSans-Book.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/plugin/_themes/ceph/static/font/ApexSans-Book.eot -------------------------------------------------------------------------------- /doc/plugin/_themes/ceph/static/font/ApexSans-Book.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/plugin/_themes/ceph/static/font/ApexSans-Book.ttf -------------------------------------------------------------------------------- /vagrant/devmode/pip_cache/README: -------------------------------------------------------------------------------- 1 | This is where the VMs cache pip packages, so that they don't 2 | re-download everything when you do a new 'vagrant up' 3 | -------------------------------------------------------------------------------- /doc/plugin/_themes/ceph/static/font/ApexSans-Book.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/plugin/_themes/ceph/static/font/ApexSans-Book.woff -------------------------------------------------------------------------------- /doc/plugin/_themes/ceph/static/font/ApexSans-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/plugin/_themes/ceph/static/font/ApexSans-Medium.eot -------------------------------------------------------------------------------- /doc/plugin/_themes/ceph/static/font/ApexSans-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/plugin/_themes/ceph/static/font/ApexSans-Medium.ttf -------------------------------------------------------------------------------- /doc/plugin/_themes/ceph/static/font/ApexSans-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceph/calamari/master/doc/plugin/_themes/ceph/static/font/ApexSans-Medium.woff -------------------------------------------------------------------------------- /cthulhu/cthulhu/manager/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from calamari_common.config import CalamariConfig 3 | 4 | # A config instance for use from within the manager service 5 | config = CalamariConfig() 6 | -------------------------------------------------------------------------------- /repobuild/conf/trusty/upstream.packages: -------------------------------------------------------------------------------- 1 | python-m2crypto install 2 | python-yaml install 3 | python-msgpack install 4 | python-zmq install 5 | python-jinja2 install 6 | python-crypto install 7 | -------------------------------------------------------------------------------- /repobuild/conf/wheezy/upstream.packages: -------------------------------------------------------------------------------- 1 | python-m2crypto install 2 | python-yaml install 3 | python-msgpack install 4 | python-zmq install 5 | python-jinja2 install 6 | python-crypto install 7 | -------------------------------------------------------------------------------- /rlyeh/rlyeh/manager/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from calamari_common.config import CalamariConfig 3 | 4 | # A config instance for use from within the manager service 5 | config = CalamariConfig() 6 | -------------------------------------------------------------------------------- /cthulhu/tests/util.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | 5 | def load_fixture(name): 6 | return json.load( 7 | open(os.path.join(os.path.dirname(__file__), name), 'r') 8 | ) 9 | -------------------------------------------------------------------------------- /repobuild/conf/precise/upstream.packages: -------------------------------------------------------------------------------- 1 | python-m2crypto install 2 | python-yaml install 3 | python-msgpack install 4 | python-zmq install 5 | python-jinja2 install 6 | python-crypto install 7 | -------------------------------------------------------------------------------- /replicated_rule_crush_repr.txt: -------------------------------------------------------------------------------- 1 | rule racky { 2 | ruleset 1 3 | type replicated 4 | min_size 1 5 | max_size 10 6 | step take default 7 | step chooseleaf firstn 0 type rack 8 | step emit 9 | } 10 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_auth_login.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/auth/login 2 | ============================== 3 | 4 | api/v2/auth/login 5 | ----------------- 6 | 7 | .. code-block:: json 8 | 9 | {} 10 | 11 | -------------------------------------------------------------------------------- /doc/contents.rst: -------------------------------------------------------------------------------- 1 | Content Index 2 | ============= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | index.rst 8 | calamari_rest/index.rst 9 | development/index.rst 10 | operations/index.rst 11 | plugin/index.rst 12 | -------------------------------------------------------------------------------- /repobuild/conf/trusty/distributions: -------------------------------------------------------------------------------- 1 | Origin: Ubuntu 2 | Label: Ubuntu Trusty 3 | Suite: stable 4 | Codename: trusty 5 | Version: 14.04 6 | Architectures: amd64 7 | Components: main 8 | Description: Ubuntu trusty 9 | Update: upstream salt 10 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/roots/git_clone.sls: -------------------------------------------------------------------------------- 1 | git_clone: 2 | git: 3 | - latest 4 | - user: {{ pillar['username'] }} 5 | - target: {{ pillar['home'] }}/calamari 6 | - name: /calamari.git 7 | - require: 8 | - pkg: build_deps 9 | -------------------------------------------------------------------------------- /conf/calamari.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Calamari REST API 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/usr/bin/calamari-lite 8 | Restart=on-failure 9 | RestartSec=30 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/pillar/info.sls: -------------------------------------------------------------------------------- 1 | infoyaml: | 2 | master_fqdn: 3 | vagrant-ubuntu-trusty-64:8000 4 | 5 | cluster: 6 | vagrant@vagrant-ubuntu-trusty-64: 7 | roles: 8 | - mon.1 9 | - osd.1 10 | - client.0 11 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/roots/start_calamari.sls: -------------------------------------------------------------------------------- 1 | supervisord: 2 | cmd.run: 3 | - user: root 4 | - name: source env/bin/activate; supervisord -c dev/supervisord.conf 5 | - cwd: {{ pillar['home'] }}/calamari 6 | - unless: pgrep supervisord 7 | -------------------------------------------------------------------------------- /cthulhu/tests/mon_map_1_removed.json: -------------------------------------------------------------------------------- 1 | { 2 | "quorum": [ 3 | 4 | ], 5 | "created": "0.000000", 6 | "modified": "2014-01-06 23:17:20.438779", 7 | "epoch": 5, 8 | "mons": [ 9 | 10 | ], 11 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25" 12 | } -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Contact: calamari@ceph.com 3 | License: LGPL2.1 or later (see COPYING-LGPL2.1) 4 | 5 | Files: * 6 | Copyright 2013-2014 Red Hat, Inc. 7 | License: LGPL2.1 or later (see COPYING-LGPL2.1) 8 | 9 | -------------------------------------------------------------------------------- /erasure_rule_crush_repr.txt: -------------------------------------------------------------------------------- 1 | rule ecruleset { 2 | ruleset 2 3 | type erasure 4 | min_size 3 5 | max_size 3 6 | step set_chooseleaf_tries 5 7 | step set_choose_tries 100 8 | step take default 9 | step chooseleaf indep 0 type host 10 | step emit 11 | } 12 | -------------------------------------------------------------------------------- /calamari.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Monitoring and Managment API for Ceph 3 | After=rc-local.service 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/opt/calamari/venv/bin/calamari-lite 8 | Restart=on-failure 9 | RestartSec=30 10 | 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /minion-sim/minion_sim/log.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | log = logging.getLogger("minion_sim") 4 | log.setLevel(logging.DEBUG) 5 | handler = logging.FileHandler("minion_sim.log") 6 | handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(name)s %(message)s")) 7 | log.addHandler(handler) 8 | -------------------------------------------------------------------------------- /vagrant/centos7-build/salt/roots/git_clone.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | calamari_clone: 4 | git: 5 | - latest 6 | - user: {{vars.username}} 7 | - target: {{vars.builddir}}/calamari 8 | - name: {{vars.gitpath}}/calamari 9 | - require: 10 | - pkg: build_deps 11 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/roots/top.sls: -------------------------------------------------------------------------------- 1 | 2 | base: 3 | '*': 4 | - build_deps 5 | - postgres 6 | - git_clone 7 | - virtualenv 8 | - configs 9 | - install_mods 10 | - init_calamari 11 | - start_calamari 12 | - install_ceph 13 | - test_calamari 14 | -------------------------------------------------------------------------------- /debian/calamari-server.prerm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "$1" in 4 | remove) 5 | service supervisor restart 6 | ;; 7 | upgrade|deconfigure) 8 | : 9 | ;; 10 | *) 11 | echo "prerm called with unknown argument $1" >&2 12 | exit 1 13 | ;; 14 | esac 15 | 16 | #DEBHELPER# 17 | 18 | exit 0 19 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/viewsets/__init__.py: -------------------------------------------------------------------------------- 1 | from rest_framework.permissions import IsAuthenticated 2 | from rest_framework.viewsets import ViewSet 3 | 4 | from calamari_rest.permissions import IsRoleAllowed 5 | 6 | 7 | class RoleLimitedViewSet(ViewSet): 8 | permission_classes = [IsAuthenticated, IsRoleAllowed] 9 | -------------------------------------------------------------------------------- /calamari-common/calamari_common/util.py: -------------------------------------------------------------------------------- 1 | def memoize(function): 2 | memo = {} 3 | 4 | def wrapper(*args): 5 | if args in memo: 6 | return memo[args] 7 | else: 8 | rv = function(*args) 9 | memo[args] = rv 10 | return rv 11 | return wrapper 12 | -------------------------------------------------------------------------------- /repobuild/conf/trusty/updates: -------------------------------------------------------------------------------- 1 | Name: salt 2 | Method: http://ppa.launchpad.net/saltstack/salt/ubuntu 3 | VerifyRelease: blindtrust 4 | GetInRelease: no 5 | 6 | Name: upstream 7 | Method: http://archive.ubuntu.com/ubuntu/ 8 | FilterList: purge upstream.packages 9 | VerifyRelease: blindtrust 10 | GetInRelease: no 11 | 12 | -------------------------------------------------------------------------------- /dev/teuthology.yaml: -------------------------------------------------------------------------------- 1 | roles: 2 | - [mon.0, osd.0, client.0] 3 | - [mon.1, osd.1] 4 | - [mon.2, osd.3] 5 | 6 | interactive-on-error: true 7 | 8 | tasks: 9 | - install: 10 | branch: 11 | dumpling 12 | extras: yes 13 | - ssh_keys: 14 | - ceph-deploy: 15 | branch: 16 | stable: dumpling 17 | - interactive: 18 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_server__fqdn__log.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/server//log 2 | ===================================== 3 | 4 | api/v2/server/figment000.cluster0.com/log 5 | ----------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | "ceph/ceph.log" 11 | ] 12 | 13 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_user__pk_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/user/ 2 | ============================= 3 | 4 | api/v2/user/2 5 | ------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "username": "default", 11 | "id": 2, 12 | "email": "default@localhost.localdomain" 13 | } 14 | 15 | -------------------------------------------------------------------------------- /calamari-common/calamari_common/remote/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from calamari_common.remote.mon_remote import MonRemote 3 | from calamari_common.remote.base import Unavailable # noqa 4 | 5 | 6 | # This is where we would be switching between different Remote 7 | # implementations based on configuration. 8 | def get_remote(): 9 | return MonRemote() 10 | -------------------------------------------------------------------------------- /vagrant/rhel7-build/salt/develop-bootstrap-salt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh - 2 | 3 | # Get the 'develop' version of bootstrap (necessary for rhel7 as of 4 | # 28 May 14) 5 | 6 | python \ 7 | -c 'import urllib; print urllib.urlopen("https://raw.githubusercontent.com/saltstack/salt-bootstrap/develop/bootstrap-salt.sh").read()' \ 8 | | sh -s -- "$@" 9 | 10 | -------------------------------------------------------------------------------- /calamari-web/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from setuptools import setup 3 | 4 | setup( 5 | name="calamari-web", 6 | version="0.1", 7 | packages=['calamari_web'], 8 | url="http://www.inktank.com/enterprise/", 9 | author="Inktank Storage Inc.", 10 | author_email="info@inktank.com", 11 | license="LGPL-2.1+", 12 | zip_safe=False, 13 | ) 14 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_key__minion_id_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/key/ 2 | =================================== 3 | 4 | api/v2/key/figment000.cluster0.com 5 | ---------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "status": "accepted", 11 | "id": "figment000.cluster0.com" 12 | } 13 | 14 | -------------------------------------------------------------------------------- /cthulhu/tests/mds1_services.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": { 3 | "ceph-mds.gravel1": { 4 | "cluster": "ceph", 5 | "type": "mds", 6 | "id": "gravel1", 7 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25", 8 | "status": null 9 | } 10 | }, 11 | "ceph_version": "foo", 12 | "boot_time": 123 13 | } -------------------------------------------------------------------------------- /cthulhu/tests/mds2_services.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": { 3 | "ceph-mds.gravel2": { 4 | "cluster": "ceph", 5 | "type": "mds", 6 | "id": "gravel2", 7 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25", 8 | "status": null 9 | } 10 | }, 11 | "ceph_version": "foo", 12 | "boot_time": 123 13 | } -------------------------------------------------------------------------------- /cthulhu/tests/gravel1.rockery_services.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": { 3 | "ceph-mon.gravel1": { 4 | "cluster": "ceph", 5 | "type": "mon", 6 | "id": "gravel1", 7 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25", 8 | "status": null 9 | } 10 | }, 11 | "ceph_version": "foo", 12 | "boot_time": 123 13 | } -------------------------------------------------------------------------------- /pre-commit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | from flake8.hooks import git_hook 4 | 5 | COMPLEXITY = -1 6 | STRICT = True 7 | 8 | if __name__ == '__main__': 9 | sys.exit(git_hook(complexity=COMPLEXITY, strict=STRICT, ignore='E501')) 10 | # Alternatively 11 | # sys.exit(git_hook(complexity=COMPLEXITY, strict=STRICT, 12 | # ignore=['E501'])) 13 | -------------------------------------------------------------------------------- /calamari-web/calamari_web/middleware.py: -------------------------------------------------------------------------------- 1 | class AngularCSRFRename(object): 2 | ANGULAR_HEADER_NAME = 'HTTP_X_XSRF_TOKEN' 3 | 4 | def process_request(self, request): 5 | if self.ANGULAR_HEADER_NAME in request.META: 6 | request.META['HTTP_X_CSRFTOKEN'] = request.META[self.ANGULAR_HEADER_NAME] 7 | del request.META[self.ANGULAR_HEADER_NAME] 8 | return None 9 | -------------------------------------------------------------------------------- /cthulhu/tests/mon_map.json: -------------------------------------------------------------------------------- 1 | { 2 | "quorum": [ 3 | 0 4 | ], 5 | "created": "0.000000", 6 | "modified": "2014-01-06 23:17:20.438779", 7 | "epoch": 4, 8 | "mons": [ 9 | { 10 | "name": "gravel1", 11 | "rank": 0, 12 | "addr": "192.168.18.1:6789/0" 13 | } 14 | ], 15 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25" 16 | } -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster 2 | =========================== 3 | 4 | api/v2/cluster 5 | -------------- 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | { 11 | "update_time": "2014-11-06T21:15:15.168126+00:00", 12 | "id": "dce20d46-f010-4883-988c-4a6d8bd15793", 13 | "name": "ceph_fake" 14 | } 15 | ] 16 | 17 | -------------------------------------------------------------------------------- /vagrant/urllib-bootstrap-salt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh - 2 | 3 | # just use urllib; tired of curl failing mid-bootstrap. urllib always works. 4 | # Save a copy of the downloaded script. 5 | 6 | URL=https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.sh 7 | 8 | python -c 'import urllib; print urllib.urlopen("'${URL}'").read()' \ 9 | | tee /tmp/salt-bootstrap-script | sh -s -- "$@" 10 | 11 | -------------------------------------------------------------------------------- /doc/operations/index.rst: -------------------------------------------------------------------------------- 1 | 2 | Calamari Operations 3 | =================== 4 | 5 | Purpose 6 | ------- 7 | 8 | This documentation is for system administrators setting up and 9 | using Calamari. 10 | 11 | Contents 12 | -------- 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | 17 | server_install 18 | users 19 | minion_connect 20 | configuring_ceph 21 | troubleshooting 22 | reporting_bugs 23 | 24 | -------------------------------------------------------------------------------- /tests/test.conf.template: -------------------------------------------------------------------------------- 1 | 2 | [testing] 3 | 4 | calamari_control = external 5 | ceph_control = converged 6 | bootstrap = False 7 | 8 | cluster_distro = ubuntu 9 | 10 | api_url = https://localhost:8002/api/v2/ 11 | api_username = admin 12 | api_password = admin 13 | 14 | embedded_timeout_factor = 1 15 | external_timeout_factor = 3 16 | 17 | external_cluster_path = {{calamari_root}}/../teuthology/archive/info.yaml 18 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/roots/build_deps.sls: -------------------------------------------------------------------------------- 1 | build_deps: 2 | pkg.installed: 3 | - pkgs: 4 | - python-virtualenv 5 | - git 6 | - python-dev 7 | - swig 8 | - libzmq3-dev 9 | - g++ 10 | - python-cairo 11 | - python-m2crypto 12 | - make 13 | - python-pip 14 | - libevent-dev 15 | - libssl-dev 16 | - postgresql 17 | - postgresql-server-dev-all 18 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/parsers/v2.py: -------------------------------------------------------------------------------- 1 | from rest_framework.parsers import BaseParser 2 | 3 | 4 | class CrushMapParser(BaseParser): 5 | """ 6 | Plain text parser. 7 | """ 8 | 9 | media_type = 'text/plain' 10 | 11 | def parse(self, stream, media_type=None, parser_context=None): 12 | """ 13 | Simply return a string representing the body of the request. 14 | """ 15 | return stream.read() 16 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/fixtures/ceph_fake.json: -------------------------------------------------------------------------------- 1 | [{"pk": 1, "model": "ceph.cluster", "fields": {"name": "ceph"}}, {"pk": 1, "model": "ceph.clusterspace", "fields": {"total_used": 5000, "cluster": 1, "total_space": 12345, "added_date": "2013-07-08T20:48:14.502Z", "total_avail": 1234}}, {"pk": 2, "model": "ceph.clusterspace", "fields": {"total_used": 4, "cluster": 1, "total_space": 344444, "added_date": "2013-07-08T21:12:42.061Z", "total_avail": 4}}] -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__osd _command.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//osd /command 2 | =============================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/osd /command 5 | ---------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | "scrub", 11 | "deep_scrub", 12 | "repair" 13 | ] 14 | 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.orig 3 | *.rej 4 | .idea 5 | .vagrant 6 | .tox 7 | webapp/content/ 8 | *.log 9 | *.pyc 10 | env 11 | venv 12 | virtualenv 13 | .git 14 | *.swp 15 | *.swo 16 | **/.sass-cache 17 | **/.tmp 18 | **/dist 19 | **/node_modules 20 | .coverage* 21 | _build 22 | htmlcov 23 | pip_cache 24 | *.egg-info 25 | *.db 26 | *.pid 27 | build/ 28 | dev/var/ 29 | figment*/ 30 | repobuild/lists 31 | repobuild/dists 32 | repobuild/pool 33 | repobuild/db 34 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__crush_type__type_id_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//crush_type/ 2 | ======================================================= 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/crush_type/1 5 | ---------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "id": 1, 11 | "name": "host" 12 | } 13 | 14 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/views/exceptions.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | Convenience classes for raising HTTP status codes as exceptions, 4 | in addition to rest_framework's builtin exception classes 5 | """ 6 | 7 | from rest_framework import status 8 | from rest_framework.exceptions import APIException 9 | 10 | 11 | class ServiceUnavailable(APIException): 12 | status_code = status.HTTP_503_SERVICE_UNAVAILABLE 13 | default_detail = "Service unavailable" 14 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__pk_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster/ 2 | ================================ 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793 5 | --------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "update_time": "2014-11-06T21:15:15.168126+00:00", 11 | "id": "dce20d46-f010-4883-988c-4a6d8bd15793", 12 | "name": "ceph_fake" 13 | } 14 | 15 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/roots/sensible_editor_vim.sls: -------------------------------------------------------------------------------- 1 | install_vim: 2 | pkg.installed: 3 | - pkgs: 4 | - vim 5 | 6 | 7 | get_vimconf: 8 | git: 9 | - latest 10 | - user: vagrant 11 | - target: /home/vagrant/dotfiles 12 | - name: https://github.com/gregmeno/dotfiles.git 13 | 14 | setup_vimconf: 15 | cmd.run: 16 | - name: ./runme.sh 17 | - cwd: /home/vagrant/dotfiles 18 | - require: 19 | - git: get_vimconf 20 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_user.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/user 2 | ======================== 3 | 4 | api/v2/user 5 | ----------- 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | { 11 | "username": "default", 12 | "id": 2, 13 | "email": "default@localhost.localdomain" 14 | }, 15 | { 16 | "username": "admin", 17 | "id": 1, 18 | "email": "admin@admin.com" 19 | } 20 | ] 21 | 22 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__config__key_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//config/ 2 | =============================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/config/mds_bal_interval 5 | --------------------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "value": "10", 11 | "key": "mds_bal_interval" 12 | } 13 | 14 | -------------------------------------------------------------------------------- /webapp/calamari/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | # Load gevent so that runserver will behave itself when zeroRPC is used 7 | from gevent import monkey 8 | monkey.patch_all() 9 | 10 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "calamari_web.settings") 11 | 12 | from django.core.management import execute_from_command_line 13 | 14 | execute_from_command_line(sys.argv) 15 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__derived_object.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//derived_object 2 | ================================================= 3 | 4 | api/v2/cluster/cad0935f-e105-41db-8c71-4aa7c4602fb3/derived_object 5 | ------------------------------------------------------------------ 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | "osds", 11 | "pgs", 12 | "osds_by_pg_state", 13 | "counters" 14 | ] 15 | 16 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/renderers/__init__.py: -------------------------------------------------------------------------------- 1 | from rest_framework.renderers import BrowsableAPIRenderer, StaticHTMLRenderer 2 | 3 | 4 | class CalamariBrowsableAPIRenderer(BrowsableAPIRenderer): 5 | def get_default_renderer(self, view): 6 | if view.get_view_name() == 'Crush Map': 7 | return StaticHTMLRenderer() 8 | else: 9 | renderer = super(CalamariBrowsableAPIRenderer, self).get_default_renderer(view) 10 | return renderer 11 | -------------------------------------------------------------------------------- /calamari-lite/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name="calamari_lite", 5 | version="0.1", 6 | packages=['calamari_lite'], 7 | url="http://www.inktank.com/enterprise/", 8 | author="Red Hat, Inc.", 9 | author_email="info@inktank.com", 10 | license="LGPL2.1 or later", 11 | zip_safe=False, 12 | entry_points={ 13 | 'console_scripts': [ 14 | 'calamari-lite = calamari_lite.server:main' 15 | ] 16 | } 17 | ) 18 | -------------------------------------------------------------------------------- /rlyeh/rlyeh/log.py: -------------------------------------------------------------------------------- 1 | import logging 2 | logging.captureWarnings(True) 3 | 4 | from calamari_common.config import CalamariConfig 5 | config = CalamariConfig() 6 | 7 | 8 | FORMAT = "%(asctime)s - %(levelname)s - %(name)s %(message)s" 9 | log = logging.getLogger('calamari') 10 | handler = logging.FileHandler(config.get('rlyeh', 'log_path')) 11 | handler.setFormatter(logging.Formatter(FORMAT)) 12 | log.addHandler(handler) 13 | log.setLevel(logging.getLevelName(config.get('rlyeh', 'log_level'))) 14 | -------------------------------------------------------------------------------- /cthulhu/cthulhu/log.py: -------------------------------------------------------------------------------- 1 | import logging 2 | logging.captureWarnings(True) 3 | 4 | from calamari_common.config import CalamariConfig 5 | config = CalamariConfig() 6 | 7 | 8 | FORMAT = "%(asctime)s - %(levelname)s - %(name)s %(message)s" 9 | log = logging.getLogger('calamari') 10 | handler = logging.FileHandler(config.get('cthulhu', 'log_path')) 11 | handler.setFormatter(logging.Formatter(FORMAT)) 12 | log.addHandler(handler) 13 | log.setLevel(logging.getLevelName(config.get('cthulhu', 'log_level'))) 14 | -------------------------------------------------------------------------------- /repobuild/conf/precise/distributions: -------------------------------------------------------------------------------- 1 | Origin: Ubuntu 2 | Label: Ubuntu Precise 3 | Suite: stable 4 | Codename: precise 5 | Version: 12.04 6 | Architectures: amd64 7 | Components: main 8 | Description: Ubuntu precise 9 | Update: upstream salt 10 | 11 | # we will get libzmq3 from trusty 12 | Origin: Ubuntu 13 | Label: Ubuntu Trusty 14 | Suite: stable 15 | Codename: trusty 16 | Version: 14.04 17 | Architectures: amd64 18 | Components: main universe 19 | Description: Ubuntu trusty 20 | Update: trusty 21 | -------------------------------------------------------------------------------- /vagrant/centos7-build/salt/roots/setvars: -------------------------------------------------------------------------------- 1 | {% set username = salt['environ.get']('SUDO_USER', 'vagrant') %} 2 | 3 | {% if username == 'vagrant' %} 4 | 5 | {% set gitpath = '/git' %} 6 | {% set builddir = '/home/vagrant' %} 7 | {% set pkgdest = gitpath %} 8 | 9 | {% else %} 10 | 11 | {% set gitpath = 'git://github.com/ceph' %} 12 | {% set builddir = salt['environ.get']('WORKSPACE', salt['user.info'](username)['home']) %} 13 | {% set pkgdest = builddir %} 14 | 15 | {% endif %} 16 | 17 | -------------------------------------------------------------------------------- /conf/salt.master.conf: -------------------------------------------------------------------------------- 1 | 2 | file_roots: 3 | base: 4 | - /opt/calamari/salt/salt/ 5 | 6 | pillar_roots: 7 | base: 8 | - /opt/calamari/salt/pillar/ 9 | 10 | reactor: 11 | - 'salt/minion/*/start': 12 | - /opt/calamari/salt/reactor/start.sls 13 | 14 | # add the Debian, RedHat and SUSE default apache users to 15 | # avoid making this file distro-dependent 16 | 17 | client_acl: 18 | www-data: 19 | - log_tail.* 20 | apache: 21 | - log_tail.* 22 | wwwrun: 23 | - log_tail.* 24 | -------------------------------------------------------------------------------- /repobuild/conf/wheezy/updates: -------------------------------------------------------------------------------- 1 | Name: salt 2 | Method: http://debian.saltstack.com/debian 3 | FilterFormula: Package (!% libzmq*) 4 | VerifyRelease: blindtrust 5 | GetInRelease: no 6 | 7 | Name: upstream 8 | Method: http://ftp.debian.org/debian 9 | FilterList: purge upstream.packages 10 | VerifyRelease: blindtrust 11 | GetInRelease: no 12 | 13 | Name: jessie 14 | Method: http://ftp.debian.org/debian 15 | Suite: jessie 16 | FilterList: purge jessie.packages 17 | VerifyRelease: blindtrust 18 | GetInRelease: no 19 | -------------------------------------------------------------------------------- /vagrant/rhel-build/salt/roots/setvars: -------------------------------------------------------------------------------- 1 | {% set username = salt['environ.get']('SUDO_USER', 'vagrant') %} 2 | 3 | {% if username == 'vagrant' %} 4 | 5 | {% set gitpath = '/git' %} 6 | {% set builddir = '/home/vagrant' %} 7 | {% set pkgdest = gitpath %} 8 | 9 | {% else %} 10 | 11 | {% set gitpath = 'git://github.com/ceph' %} 12 | {% set builddir = salt['environ.get']('WORKSPACE', salt['user.info'](username)['home']) %} 13 | {% set pkgdest = builddir + '/pkgs' %} 14 | 15 | {% endif %} 16 | 17 | -------------------------------------------------------------------------------- /vagrant/rhel7-build/salt/roots/setvars: -------------------------------------------------------------------------------- 1 | {% set username = salt['environ.get']('SUDO_USER', 'vagrant') %} 2 | 3 | {% if username == 'vagrant' %} 4 | 5 | {% set gitpath = '/git' %} 6 | {% set builddir = '/home/vagrant' %} 7 | {% set pkgdest = gitpath %} 8 | 9 | {% else %} 10 | 11 | {% set gitpath = 'git://github.com/ceph' %} 12 | {% set builddir = salt['environ.get']('WORKSPACE', salt['user.info'](username)['home']) %} 13 | {% set pkgdest = builddir + '/pkgs' %} 14 | 15 | {% endif %} 16 | 17 | -------------------------------------------------------------------------------- /vagrant/trusty-build/salt/roots/setvars: -------------------------------------------------------------------------------- 1 | {% set username = salt['environ.get']('SUDO_USER', 'vagrant') %} 2 | 3 | {% if username == 'vagrant' %} 4 | 5 | {% set gitpath = '/git' %} 6 | {% set builddir = '/home/vagrant' %} 7 | {% set pkgdest = gitpath %} 8 | 9 | {% else %} 10 | 11 | {% set gitpath = 'git://github.com/ceph' %} 12 | {% set builddir = salt['environ.get']('WORKSPACE', salt['user.info'](username)['home']) %} 13 | {% set pkgdest = builddir + '/pkgs' %} 14 | 15 | {% endif %} 16 | 17 | -------------------------------------------------------------------------------- /vagrant/wheezy-build/salt/roots/setvars: -------------------------------------------------------------------------------- 1 | {% set username = salt['environ.get']('SUDO_USER', 'vagrant') %} 2 | 3 | {% if username == 'vagrant' %} 4 | 5 | {% set gitpath = '/git' %} 6 | {% set builddir = '/home/vagrant' %} 7 | {% set pkgdest = gitpath %} 8 | 9 | {% else %} 10 | 11 | {% set gitpath = 'git://github.com/ceph' %} 12 | {% set builddir = salt['environ.get']('WORKSPACE', salt['user.info'](username)['home']) %} 13 | {% set pkgdest = builddir + '/pkgs' %} 14 | 15 | {% endif %} 16 | 17 | -------------------------------------------------------------------------------- /conf/supervisord.production.conf: -------------------------------------------------------------------------------- 1 | 2 | [supervisord] 3 | loglevel=info 4 | logfile=dev/supervisord.log 5 | childlogdir=/tmp 6 | environment=CALAMARI_CONFIG="/etc/calamari/calamari.conf", PYTHONPATH="/opt/calamari/venv/lib64/python2.7/" 7 | 8 | [supervisorctl] 9 | 10 | [inet_http_server] 11 | port=127.0.0.1:9001 12 | 13 | [rpcinterface:supervisor] 14 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 15 | 16 | [program:calamari-lite] 17 | command = /opt/calamari/venv/bin/calamari-lite 18 | -------------------------------------------------------------------------------- /dev/supervisord.conf: -------------------------------------------------------------------------------- 1 | 2 | [supervisord] 3 | loglevel=info 4 | logfile=dev/supervisord.log 5 | childlogdir=/tmp 6 | environment=CALAMARI_CONFIG="dev/calamari.conf",LD_LIBRARY_PATH="/home/john/git/ceph/src/.libs", PYTHONPATH="/home/john/git/ceph/src/pybind" 7 | 8 | [supervisorctl] 9 | 10 | [inet_http_server] 11 | port=127.0.0.1:9001 12 | 13 | [rpcinterface:supervisor] 14 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 15 | 16 | [program:calamari-lite] 17 | command = calamari-lite 18 | -------------------------------------------------------------------------------- /vagrant/rhel-build/salt/roots/git_clone.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | calamari_clone: 4 | git: 5 | - latest 6 | - user: {{vars.username}} 7 | - target: {{vars.builddir}}/calamari 8 | - name: {{vars.gitpath}}/calamari 9 | - require: 10 | - pkg: build_deps 11 | 12 | diamond_clone: 13 | git: 14 | - latest 15 | - user: {{vars.username}} 16 | - target: {{vars.builddir}}/Diamond 17 | - name: {{vars.gitpath}}/Diamond 18 | - require: 19 | - pkg: build_deps 20 | -------------------------------------------------------------------------------- /vagrant/rhel7-build/salt/roots/git_clone.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | calamari_clone: 4 | git: 5 | - latest 6 | - user: {{vars.username}} 7 | - target: {{vars.builddir}}/calamari 8 | - name: {{vars.gitpath}}/calamari 9 | - require: 10 | - pkg: build_deps 11 | 12 | diamond_clone: 13 | git: 14 | - latest 15 | - user: {{vars.username}} 16 | - target: {{vars.builddir}}/Diamond 17 | - name: {{vars.gitpath}}/Diamond 18 | - require: 19 | - pkg: build_deps 20 | -------------------------------------------------------------------------------- /vagrant/trusty-build/salt/roots/git_clone.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | calamari_clone: 4 | git: 5 | - latest 6 | - user: {{vars.username}} 7 | - target: {{vars.builddir}}/calamari 8 | - name: {{vars.gitpath}}/calamari 9 | - require: 10 | - pkg: build_deps 11 | 12 | diamond_clone: 13 | git: 14 | - latest 15 | - user: {{vars.username}} 16 | - target: {{vars.builddir}}/Diamond 17 | - name: {{vars.gitpath}}/Diamond 18 | - require: 19 | - pkg: build_deps 20 | -------------------------------------------------------------------------------- /vagrant/wheezy-build/salt/roots/git_clone.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | calamari_clone: 4 | git: 5 | - latest 6 | - user: {{vars.username}} 7 | - target: {{vars.builddir}}/calamari 8 | - name: {{vars.gitpath}}/calamari 9 | - require: 10 | - pkg: build_deps 11 | 12 | diamond_clone: 13 | git: 14 | - latest 15 | - user: {{vars.username}} 16 | - target: {{vars.builddir}}/Diamond 17 | - name: {{vars.gitpath}}/Diamond 18 | - require: 19 | - pkg: build_deps 20 | -------------------------------------------------------------------------------- /alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__sync_object.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//sync_object 2 | ============================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/sync_object 5 | --------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | "mds_map", 11 | "osd_map", 12 | "mon_map", 13 | "mon_status", 14 | "pg_summary", 15 | "health", 16 | "config" 17 | ] 18 | 19 | -------------------------------------------------------------------------------- /doc/plugin/index.rst: -------------------------------------------------------------------------------- 1 | .. Copied from development 2 | 3 | Calamari Plugin 4 | =============== 5 | 6 | Purpose 7 | ------- 8 | 9 | This sphinx tree is for information about how to work with the Calamari 10 | plugin front and back ends. It is intended for sharing with OEM partners. 11 | 12 | Contents 13 | -------- 14 | 15 | .. toctree:: 16 | :maxdepth: 2 17 | 18 | frontend 19 | backend 20 | 21 | Indices and tables 22 | ================== 23 | 24 | * :ref:`genindex` 25 | * :ref:`modindex` 26 | * :ref:`search` 27 | 28 | -------------------------------------------------------------------------------- /minion-sim/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name="minion_sim", 5 | version="0.1", 6 | packages=['minion_sim'], 7 | url="http://www.inktank.com/enterprise/", 8 | author="Inktank Storage Inc.", 9 | author_email="info@inktank.com", 10 | license="LGPL-2.1+", 11 | zip_safe=False, 12 | entry_points={ 13 | 'console_scripts': [ 14 | 'minion-sim = minion_sim.sim:main', 15 | 'minion-child = minion_sim.child:main' 16 | ] 17 | } 18 | ) 19 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__mon__mon_id_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//mon/ 2 | =============================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/mon/figment000 5 | ------------------------------------------------------------------ 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "addr": "", 11 | "in_quorum": true, 12 | "name": "figment000", 13 | "rank": 0, 14 | "server": "figment000.cluster0.com" 15 | } 16 | 17 | -------------------------------------------------------------------------------- /repobuild/conf/precise/updates: -------------------------------------------------------------------------------- 1 | Name: salt 2 | Method: http://ppa.launchpad.net/saltstack/salt/ubuntu 3 | # get everything but libzmq3; it comes from trusty.packages 4 | FilterFormula: Package (!% libzmq3*) 5 | VerifyRelease: blindtrust 6 | 7 | Name: upstream 8 | Method: http://archive.ubuntu.com/ubuntu/ 9 | FilterList: purge upstream.packages 10 | VerifyRelease: blindtrust 11 | 12 | Name: trusty 13 | Method: http://archive.ubuntu.com/ubuntu/ 14 | Suite: trusty 15 | FilterList: purge trusty.packages 16 | VerifyRelease: blindtrust 17 | 18 | -------------------------------------------------------------------------------- /calamari-common/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name="calamari_common", 5 | version="0.1", 6 | packages=['calamari_common', 7 | 'calamari_common.db', 8 | 'calamari_common.remote', 9 | ], 10 | url="http://www.inktank.com/enterprise/", 11 | author="Inktank Storage Inc.", 12 | author_email="info@inktank.com", 13 | license="LGPL-2.1+", 14 | zip_safe=False, 15 | entry_points={ 16 | 'console_scripts': [ 17 | ] 18 | } 19 | ) 20 | -------------------------------------------------------------------------------- /requirements/lite.txt: -------------------------------------------------------------------------------- 1 | Django==1.5.1 2 | Markdown==2.3.1 3 | argparse==1.2.1 4 | django-filter==0.6 5 | django-jsonfield==0.9.10 6 | djangorestframework==2.3.12 7 | requests==1.2.3 8 | wsgiref==0.1.2 9 | supervisor 10 | meld3 11 | 12 | # Gevent 1.0.x requires cython but doesn't do a good job of depending on it 13 | setuptools 14 | cython 15 | gevent==1.1.1 16 | greenlet>=0.3.2 17 | 18 | # Cthulhu 19 | M2crypto==0.22.3 20 | pyzmq>=14.2.0 21 | python-dateutil==2.2 22 | zerorpc==0.4.4 23 | jinja2 24 | pytz 25 | psutil 26 | alembic 27 | psycopg2 28 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | export DH_VERBOSE=1 3 | export DEB_BUILD_OPTIONS=nocheck 4 | 5 | DH_PYTHON2_ARGS="" 6 | 7 | %: 8 | dh $@ --with python2 9 | 10 | # if --no-shebang-rewrite is available, we need it: 11 | # Don't allow dh_python2 to rewrite the #! lines in the console 12 | # scripts (just calamari-ctl at this point). 13 | 14 | override_dh_python2: 15 | if dh_python2 --help 2>&1 | grep -s -- --no-shebang-rewrite ; \ 16 | then \ 17 | DH_PYTHON2_ARGS="--no-shebang-rewrite"; \ 18 | fi ; \ 19 | dh_python2 $$DH_PYTHON2_ARGS 20 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__osd__osd_id__command.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//osd//command 2 | ======================================================= 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/osd/0/command 5 | ----------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "0": { 11 | "valid_commands": [ 12 | "scrub", 13 | "deep_scrub", 14 | "repair" 15 | ] 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /cthulhu/cthulhu/manager/crush_request_factory.py: -------------------------------------------------------------------------------- 1 | from cthulhu.manager.request_factory import RequestFactory 2 | from cthulhu.manager.user_request import OsdMapModifyingRequest 3 | 4 | 5 | class CrushRequestFactory(RequestFactory): 6 | def update(self, osd_id, attributes): 7 | commands = [('osd setcrushmap', {'data': attributes})] 8 | message = "Replacing CRUSH map in {cluster_name}".format(cluster_name=self._cluster_monitor.name) 9 | return OsdMapModifyingRequest(message, self._cluster_monitor.fsid, self._cluster_monitor.name, commands) 10 | -------------------------------------------------------------------------------- /tests/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | import ConfigParser 3 | 4 | DEFAULT_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "test.conf") 5 | 6 | 7 | class ConfigNotFound(Exception): 8 | pass 9 | 10 | 11 | class TestConfig(ConfigParser.SafeConfigParser): 12 | def __init__(self): 13 | ConfigParser.SafeConfigParser.__init__(self) 14 | 15 | self.path = DEFAULT_CONFIG_PATH 16 | 17 | if not os.path.exists(self.path): 18 | raise ConfigNotFound("Configuration not found at %s" % self.path) 19 | 20 | self.read(self.path) 21 | -------------------------------------------------------------------------------- /rlyeh/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name="calamari_rlyeh", 5 | version="0.1", 6 | packages=['rlyeh', 'rlyeh.manager', 'rlyeh.persistence'], 7 | url="http://www.inktank.com/enterprise/", 8 | author="Inktank Storage Inc.", 9 | author_email="info@inktank.com", 10 | license="LGPL-2.1+", 11 | zip_safe=False, 12 | entry_points={ 13 | 'console_scripts': [ 14 | 'rlyeh-manager = rlyeh.manager.manager:main', 15 | 'calamari-ctl = rlyeh.calamari_ctl:main' 16 | ] 17 | } 18 | ) 19 | -------------------------------------------------------------------------------- /conf/carbon/storage-schemas.conf: -------------------------------------------------------------------------------- 1 | # Schema definitions for Whisper files. Entries are scanned in order, 2 | # and first match wins. This file is scanned for changes every 60 seconds. 3 | # 4 | # [name] 5 | # pattern = regex 6 | # retentions = timePerPoint:timeToStore, timePerPoint:timeToStore, ... 7 | 8 | # Carbon's internal metrics. This entry should match what is specified in 9 | # CARBON_METRIC_PREFIX and CARBON_METRIC_INTERVAL settings 10 | [carbon] 11 | pattern = ^carbon\. 12 | retentions = 60:90d 13 | 14 | [calamari] 15 | pattern = .* 16 | retentions = 60s:1d,15m:7d 17 | -------------------------------------------------------------------------------- /vagrant/wheezy-build/salt/roots/build_deps.sls: -------------------------------------------------------------------------------- 1 | build_deps: 2 | pkg.installed: 3 | - pkgs: 4 | - build-essential 5 | - python-virtualenv 6 | - git 7 | - python-dev 8 | - swig 9 | - libzmq-dev 10 | - g++ 11 | - python-cairo 12 | - make 13 | - devscripts 14 | - libpq-dev 15 | - cython 16 | - debhelper 17 | - python-mock 18 | - python-configobj 19 | - cdbs 20 | - python-sphinx 21 | - libcairo2-dev 22 | - python-m2crypto 23 | - python-crypto 24 | - reprepro 25 | -------------------------------------------------------------------------------- /cthulhu/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name="calamari_cthulhu", 5 | version="0.1", 6 | packages=['cthulhu', 'cthulhu.manager', 'cthulhu.persistence'], 7 | url="http://www.inktank.com/enterprise/", 8 | author="Inktank Storage Inc.", 9 | author_email="info@inktank.com", 10 | license="LGPL-2.1+", 11 | zip_safe=False, 12 | entry_points={ 13 | 'console_scripts': [ 14 | 'cthulhu-manager = cthulhu.manager.manager:main', 15 | 'calamari-ctl = cthulhu.calamari_ctl:main' 16 | ] 17 | } 18 | ) 19 | -------------------------------------------------------------------------------- /cthulhu/tests/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | import ConfigParser 3 | 4 | DEFAULT_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "../../tests/test.conf") 5 | 6 | 7 | class ConfigNotFound(Exception): 8 | pass 9 | 10 | 11 | class TestConfig(ConfigParser.SafeConfigParser): 12 | def __init__(self): 13 | ConfigParser.SafeConfigParser.__init__(self) 14 | 15 | self.path = DEFAULT_CONFIG_PATH 16 | 17 | if not os.path.exists(self.path): 18 | raise ConfigNotFound("Configuration not found at %s" % self.path) 19 | 20 | self.read(self.path) 21 | -------------------------------------------------------------------------------- /vps_bootstrap.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | set -e 3 | 4 | echo "as user: "$1" deploying calamari to "$2 5 | if [ -x $(which wget) ] 6 | then 7 | wget -O install_salt.sh https://bootstrap.saltstack.com 8 | else 9 | curl -o install_salt.sh -L https://bootstrap.saltstack.com 10 | fi 11 | 12 | sudo apt-get update 13 | sudo sh install_salt.sh 14 | 15 | pushd /calamari.git 16 | pillar_data="{"\"username\":\"$1\"", "\"home\":\"$2\""}" 17 | sudo salt-call --local --file-root=$(pwd)/vagrant/devmode/salt/roots --pillar=$(pwd)/vagrant/devmode/salt/pillar state.highstate pillar="$pillar_data" 18 | popd 19 | -------------------------------------------------------------------------------- /cthulhu/tests/gravel2.rockery_services.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": { 3 | "ceph-osd.0": { 4 | "cluster": "ceph", 5 | "type": "osd", 6 | "id": "0", 7 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25", 8 | "status": null 9 | }, 10 | "ceph-osd.1": { 11 | "cluster": "ceph", 12 | "type": "osd", 13 | "id": "1", 14 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25", 15 | "status": null 16 | } 17 | }, 18 | "ceph_version": "foo", 19 | "boot_time": 123 20 | } -------------------------------------------------------------------------------- /doc/development/OSX.rst: -------------------------------------------------------------------------------- 1 | 2 | OS X development tips 3 | ===================== 4 | 5 | Things to know: 6 | 7 | - You've gotta use brew's python, not the one that comes with OSX, that 8 | means setting --python=/usr/local/bin/python2.7 when creating your 9 | virtualenv 10 | - You've gotta enable site-packages in order to get a brew-built 11 | pycairo, that means setting --site-packages when creating 12 | your virtualenv 13 | - Use brew to install cairo and pycairo 14 | - To use nodeenv to install a local node setup, you must have 15 | the 'full' XCode installed, not just the 'Command Line' version. 16 | -------------------------------------------------------------------------------- /vagrant/centos7-build/salt/roots/build_deps.sls: -------------------------------------------------------------------------------- 1 | build_deps: 2 | pkg.installed: 3 | - pkgs: 4 | - git 5 | - createrepo 6 | - rpm-build 7 | - gcc 8 | - gcc-c++ 9 | - python-virtualenv 10 | - python-devel 11 | - swig 12 | - zeromq3-devel 13 | - pycairo-devel 14 | - make 15 | - postgresql-devel 16 | - Cython 17 | - python-configobj 18 | - python-sphinx 19 | - cairo-devel 20 | - m2crypto 21 | - redhat-lsb-core 22 | - httpd 23 | - selinux-policy-devel 24 | - selinux-policy-doc 25 | 26 | -------------------------------------------------------------------------------- /vagrant/rhel7-build/salt/roots/build_deps.sls: -------------------------------------------------------------------------------- 1 | build_deps: 2 | pkg.installed: 3 | - pkgs: 4 | - git 5 | - createrepo 6 | - rpm-build 7 | - gcc 8 | - gcc-c++ 9 | - python-virtualenv 10 | - python-devel 11 | - swig 12 | - zeromq3-devel 13 | - pycairo-devel 14 | - make 15 | - postgresql-devel 16 | - Cython 17 | - python-mock 18 | - python-configobj 19 | - python-sphinx 20 | - cairo-devel 21 | - m2crypto 22 | - python-crypto 23 | - redhat-lsb-core 24 | - hardlink 25 | - httpd 26 | -------------------------------------------------------------------------------- /vagrant/production/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure("2") do |config| 5 | 6 | config.vm.box = "centos64" 7 | config.vm.box_url = "http://ceph.com/noah/vagrant-centos-6-4.box" 8 | 9 | config.vm.provision :shell, :path => "bootstrap.sh" 10 | 11 | # config.vm.network :forwarded_port, guest: 80, host: 8080 12 | config.vm.network :public_network, :bridge => 'eth0' 13 | 14 | config.vm.provider "virtualbox" do |v| 15 | v.customize ["modifyvm", :id, "--memory", "1024"] 16 | v.customize ["modifyvm", :id, "--cpus", "2"] 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /calamari.te: -------------------------------------------------------------------------------- 1 | 2 | module calamari 1.0; 3 | 4 | require { 5 | type var_log_t; 6 | type postgresql_port_t; 7 | type httpd_t; 8 | type mmcc_port_t; 9 | class tcp_socket name_connect; 10 | class file open; 11 | } 12 | 13 | #============= httpd_t ============== 14 | 15 | #!!!! This avc can be allowed using the boolean 'httpd_can_network_connect' 16 | allow httpd_t mmcc_port_t:tcp_socket name_connect; 17 | 18 | #!!!! This avc is allowed in the current policy 19 | allow httpd_t postgresql_port_t:tcp_socket name_connect; 20 | 21 | #!!!! This avc is allowed in the current policy 22 | allow httpd_t var_log_t:file open; 23 | -------------------------------------------------------------------------------- /cthulhu/tests/gravel1.rockery_services_migrated.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": { 3 | "ceph-mon.gravel1": { 4 | "cluster": "ceph", 5 | "type": "mon", 6 | "id": "gravel1", 7 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25", 8 | "status": null 9 | }, 10 | "ceph-osd.1": { 11 | "cluster": "ceph", 12 | "type": "osd", 13 | "id": "1", 14 | "fsid": "d530413f-9030-4daa-aba5-dfe3b6c4bb25", 15 | "status": null 16 | } 17 | }, 18 | "ceph_version": "foo", 19 | "boot_time": 123 20 | } -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__osd_config.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//osd_config 2 | ============================================= 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/osd_config 5 | -------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "pause": false, 11 | "nobackfill": false, 12 | "noout": false, 13 | "nodeep-scrub": false, 14 | "noscrub": false, 15 | "noin": false, 16 | "noup": false, 17 | "norecover": false, 18 | "nodown": false 19 | } 20 | 21 | -------------------------------------------------------------------------------- /requirements/2.7/requirements.production.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | # This is the production requirements.txt. It excludes 4 | # anything we will be installing an upstream package, 5 | # and anything that is only used for development/build. 6 | 7 | Django==1.5.1 8 | argparse==1.2.1 9 | django-filter==0.6 10 | djangorestframework==2.3.12 11 | wsgiref==0.1.2 12 | sqlalchemy==0.8.3 13 | alembic==0.6.3 14 | setuptools 15 | cython 16 | gevent==1.1.1 17 | greenlet 18 | manhole==0.6.0 19 | 20 | Twisted==11.1.0 21 | django-tagging==0.3.1 22 | pytz==2013.8 23 | 24 | # Cthulhu 25 | pyzmq==14.2.0 26 | python-dateutil==2.2 27 | zerorpc==0.4.4 28 | -------------------------------------------------------------------------------- /vagrant/trusty-build/salt/roots/build_deps.sls: -------------------------------------------------------------------------------- 1 | build_deps: 2 | pkg.installed: 3 | - pkgs: 4 | - build-essential 5 | - python-virtualenv 6 | - git 7 | - python-dev 8 | - swig 9 | - libzmq-dev 10 | - g++ 11 | - python-cairo 12 | - make 13 | - devscripts 14 | - libpq-dev 15 | - cython 16 | - debhelper 17 | - python-mock 18 | - python-configobj 19 | - cdbs 20 | - python-sphinx 21 | - libcairo2-dev 22 | - python-m2crypto 23 | - python-crypto 24 | - reprepro 25 | - python-support 26 | 27 | 28 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_info.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/info 2 | ======================== 3 | 4 | api/v2/info 5 | ----------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "bootstrap_rhel": "curl http://localhost:8000/bootstrap | sudo python", 11 | "license": "N/A", 12 | "registered": "N/A", 13 | "hostname": "localhost", 14 | "ipaddr": "127.0.0.1", 15 | "fqdn": "localhost", 16 | "version": "dev", 17 | "bootstrap_ubuntu": "wget -O - http://localhost:8000/bootstrap | sudo python", 18 | "bootstrap_url": "http://localhost:8000/bootstrap" 19 | } 20 | 21 | -------------------------------------------------------------------------------- /vagrant/rhel-build/salt/roots/build_deps.sls: -------------------------------------------------------------------------------- 1 | build_deps: 2 | pkg.installed: 3 | - pkgs: 4 | - git 5 | - createrepo 6 | - rpm-build 7 | - gcc 8 | - gcc-c++ 9 | - python-virtualenv 10 | - python-devel 11 | - swig 12 | - zeromq-devel 13 | - pycairo-devel 14 | - make 15 | - postgresql-devel 16 | - Cython 17 | - python-mock 18 | - python-configobj 19 | - python-sphinx 20 | - cairo-devel 21 | - m2crypto 22 | - python-crypto 23 | - redhat-lsb-core 24 | - hardlink 25 | - httpd 26 | - selinux-policy-core 27 | -------------------------------------------------------------------------------- /selinux/calamari-server.te: -------------------------------------------------------------------------------- 1 | 2 | module calamari-server 1.0; 3 | 4 | require { 5 | type var_log_t; 6 | type postgresql_port_t; 7 | type httpd_t; 8 | type mmcc_port_t; 9 | class tcp_socket name_connect; 10 | class file open; 11 | } 12 | 13 | #============= httpd_t ============== 14 | 15 | #!!!! This avc can be allowed using the boolean 'httpd_can_network_connect' 16 | allow httpd_t mmcc_port_t:tcp_socket name_connect; 17 | 18 | #!!!! This avc is allowed in the current policy 19 | allow httpd_t postgresql_port_t:tcp_socket name_connect; 20 | 21 | #!!!! This avc is allowed in the current policy 22 | allow httpd_t var_log_t:file open; 23 | -------------------------------------------------------------------------------- /vagrant/centos7-build/salt/roots/make_packages.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | build-calamari-server: 4 | cmd.run: 5 | - user: {{vars.username}} 6 | - name: ./build-rpm.sh 7 | - cwd: {{vars.builddir}}/calamari 8 | - require: 9 | - git: {{vars.gitpath}}/calamari 10 | 11 | {% for path in ('calamari/repobuild/calamari-repo-*.tar.gz', 12 | 'rpmbuild/RPMS/*/calamari-server-*.rpm', 13 | 'Diamond/dist/diamond-*.rpm') %} 14 | 15 | cp-artifacts-up {{ path }}: 16 | cmd.run: 17 | - name: cp {{ path }} {{vars.pkgdest}} 18 | - cwd: {{vars.builddir}} 19 | 20 | {% endfor %} 21 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/roots/init_calamari.sls: -------------------------------------------------------------------------------- 1 | 2 | 3 | init_config: 4 | cmd.run: 5 | - user: {{ pillar['username'] }} 6 | - name: "source {{ pillar['home'] }}/calamari/env/bin/activate && dev/configure.py" 7 | - cwd: "{{ pillar['home'] }}/calamari" 8 | 9 | 10 | init_rest_db: 11 | cmd.run: 12 | - user: {{ pillar['username'] }} 13 | - name: "source {{ pillar['home'] }}/calamari/env/bin/activate && CALAMARI_CONFIG=dev/calamari.conf calamari-ctl initialize --admin-username admin --admin-password admin --admin-email admin@admin.com" 14 | - cwd: "{{ pillar['home'] }}/calamari" 15 | require: 16 | - cmd: init_config 17 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | calamari (1.0.0-1) precise; urgency=low 2 | 3 | * New upstream release 4 | 5 | -- Gary Lowell Wed, 30 Oct 2013 21:30:21 -0700 6 | 7 | calamari (0.5.1) experimental; urgency=low 8 | 9 | * Beta refresh 1. 10 | 11 | -- Dan Mick Fri, 11 Oct 2013 19:31:11 -0700 12 | 13 | calamari (0.5) experimental; urgency=low 14 | 15 | * Beta release. 16 | 17 | -- Dan Mick Mon, 30 Sep 2013 12:35:21 -0700 18 | 19 | calamari (0.1) UNRELEASED; urgency=low 20 | 21 | * Initial release. 22 | 23 | -- Dan Mick Tue, 10 Sep 2013 20:37:53 -0700 24 | -------------------------------------------------------------------------------- /repobuild/conf/wheezy/distributions: -------------------------------------------------------------------------------- 1 | Origin: Saltstack 2 | Label: Saltstack Wheezy 3 | Suite: stable 4 | Codename: wheezy-saltstack 5 | Version: 7.2 6 | Architectures: amd64 7 | Components: main 8 | Description: Saltstack wheezy repo 9 | Update: salt 10 | 11 | Origin: Debian 12 | Label: Debian Wheezy 13 | Suite: stable 14 | Codename: wheezy 15 | Version: 7.2 16 | Architectures: amd64 17 | Components: main 18 | Description: Debian wheezy repo 19 | update: upstream 20 | 21 | Origin: Debian 22 | Label: Debian Jessie 23 | Suite: testing 24 | Codename: jessie 25 | Architectures: amd64 26 | Components: main 27 | Description: Debian jessie repo 28 | Update: jessie 29 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_request__request_id_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/request/ 2 | ======================================== 3 | 4 | api/v2/request/34b86742-c026-484c-bba6-a60e71e06275 5 | --------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "status": "Waiting for OSD map epoch 2", 11 | "requested_at": "2014-11-06T21:15:15.547623+00:00", 12 | "headline": "Creating pool 'newname'", 13 | "error_message": "", 14 | "completed_at": null, 15 | "state": "submitted", 16 | "error": false, 17 | "id": "34b86742-c026-484c-bba6-a60e71e06275" 18 | } 19 | 20 | -------------------------------------------------------------------------------- /rest-api/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from setuptools import setup 3 | 4 | setup( 5 | name="calamari-rest-api", 6 | version="0.1", 7 | packages=['calamari_rest', 8 | 'calamari_rest.urls', 9 | 'calamari_rest.views', 10 | 'calamari_rest.viewsets', 11 | 'calamari_rest.serializers', 12 | 'calamari_rest.renderers', 13 | 'calamari_rest.parsers', 14 | 'calamari_rest.permissions', 15 | ], 16 | url="http://www.inktank.com/enterprise/", 17 | author="Inktank Storage Inc.", 18 | author_email="info@inktank.com", 19 | license="LGPL-2.1+", 20 | zip_safe=False, 21 | ) 22 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/permissions/__init__.py: -------------------------------------------------------------------------------- 1 | from rest_framework.permissions import BasePermission, SAFE_METHODS 2 | 3 | 4 | class IsRoleAllowed(BasePermission): 5 | 6 | def has_permission(self, request, view): 7 | has_permission = False 8 | if request.user.groups.filter(name='readonly').exists(): 9 | has_permission = request.method in SAFE_METHODS 10 | view.headers['Allow'] = ', '.join(SAFE_METHODS) 11 | elif request.user.groups.filter(name='read/write').exists(): 12 | has_permission = True 13 | elif request.user.is_superuser: 14 | has_permission = True 15 | 16 | return has_permission 17 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/roots/postgres.sls: -------------------------------------------------------------------------------- 1 | postgresql: 2 | service.running: 3 | - enable: True 4 | 5 | calamariuser: 6 | postgres_user.present: 7 | - name: calamari 8 | - password: 27HbZwr*g 9 | - createdb: true 10 | - user: postgres 11 | - require: 12 | - service: postgresql 13 | 14 | calamaridb: 15 | postgres_database.present: 16 | - name: 'calamari' 17 | - encoding: UTF8 18 | - lc_ctype: en_US.UTF8 19 | - lc_collate: en_US.UTF8 20 | - template: template0 21 | - owner: calamari 22 | - user: postgres 23 | - require: 24 | - postgres_user: calamariuser 25 | -------------------------------------------------------------------------------- /salt/local/services.sls: -------------------------------------------------------------------------------- 1 | {% if grains['os_family'] == 'RedHat' and grains['osrelease'].startswith('7') %} 2 | {% set supervisor_service = 'supervisord.service' %} 3 | {% else %} 4 | {% set supervisor_service = 'supervisor.service' %} 5 | {% endif %} 6 | 7 | # Work around https://github.com/saltstack/salt/pull/12316 8 | {{supervisor_service}}: 9 | cmd: 10 | - run 11 | - user: root 12 | - name: systemctl enable {{supervisor_service}} && systemctl start {{supervisor_service}} 13 | 14 | limit-memory: 15 | cmd: 16 | - run 17 | - user: root 18 | - name: systemctl set-property {{supervisor_service}} MemoryLimit=300M 19 | - require: 20 | - cmd: {{supervisor_service}} 21 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__pool__pool_id_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//pool/ 2 | ================================================= 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/pool/0 5 | ---------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "full": false, 11 | "name": "data", 12 | "quota_max_objects": 0, 13 | "hashpspool": false, 14 | "min_size": 1, 15 | "crash_replay_interval": 0, 16 | "pg_num": 64, 17 | "pgp_num": 64, 18 | "quota_max_bytes": 0, 19 | "size": 2, 20 | "id": 0, 21 | "crush_ruleset": 2 22 | } 23 | 24 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/views/crush_node.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | log = logging.getLogger(__name__) 4 | 5 | 6 | def lookup_ancestry(osd_id, parent_map): 7 | log.info('lookup' + str(parent_map)) 8 | ancestries = [] 9 | for parent in parent_map.get(osd_id, []): 10 | parent_id = parent.get('id') 11 | ancestry = [parent_id] 12 | while(parent and parent_id is not None): 13 | parent = parent_map.get(parent_id, []) 14 | if parent: 15 | parent_id = parent[0].get('id') 16 | if parent_id is not None: 17 | ancestry.append(parent_id) 18 | ancestries.append(ancestry) 19 | 20 | return ancestries 21 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_request.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/request 2 | =========================== 3 | 4 | api/v2/request 5 | -------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "count": 1, 11 | "previous": null, 12 | "results": [ 13 | { 14 | "status": "Waiting for OSD map epoch 2", 15 | "requested_at": "2014-11-06T21:15:15.547623+00:00", 16 | "headline": "Creating pool 'newname'", 17 | "error_message": "", 18 | "completed_at": null, 19 | "state": "submitted", 20 | "error": false, 21 | "id": "34b86742-c026-484c-bba6-a60e71e06275" 22 | } 23 | ], 24 | "next": null 25 | } 26 | 27 | -------------------------------------------------------------------------------- /cthulhu/tests/plugins/acmeplugin/status_processor.py: -------------------------------------------------------------------------------- 1 | class StatusProcessor(object): 2 | 3 | @property 4 | def period(self): 5 | """ 6 | How often the Plugin runs in seconds 7 | """ 8 | return 1 9 | 10 | def run(self, check_data): 11 | """ 12 | status_check_data is expected to be a dict that is (minion_id to whatever is output by the status_check) 13 | return of this function is JSON 14 | """ 15 | 16 | state = "OK" 17 | for node, data in check_data.iteritems(): 18 | for key, value in data.iteritems(): 19 | if key == 'SMART Health Status' and value != "OK": 20 | state = "FAIL" 21 | 22 | return {'SMART Health Status': state} 23 | -------------------------------------------------------------------------------- /get-flavor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ID=$(lsb_release -i -s) 4 | if [ $? != 0 ] ; then echo "$0: lsb_release failed..."; exit 1; fi 5 | VERSION=$(lsb_release -r -s) 6 | 7 | # ID is: 8 | # Centos6.4: CentOS 9 | # RHEL6: RedHatEnterpriseServer 10 | # precise, trusty: Ubuntu 11 | # wheezy: Debian 12 | # SLES: SUSE Linux 13 | # openSUSE: openSUSE project 14 | 15 | 16 | case $ID in 17 | "CentOS"|"RedHatEnterpriseServer") 18 | case $VERSION in 19 | 7.*) ret="rhel7" ;; 20 | 6.*) ret="el6" ;; 21 | *) echo "$0: unhandled EL version $VERSION"; exit 1 ;; 22 | esac ;; 23 | "Ubuntu"|"Debian") ret="debian" ;; 24 | *SUSE*) ret="suse" ;; 25 | *) echo "$0: unhandled id $ID"; exit 1 ;; 26 | esac 27 | 28 | echo $ret 29 | exit 0 30 | -------------------------------------------------------------------------------- /doc/development/index.rst: -------------------------------------------------------------------------------- 1 | .. Calamari Development documentation master file, created by 2 | sphinx-quickstart on Thu Nov 21 18:07:57 2013. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Calamari for Developers 7 | ======================= 8 | 9 | Purpose 10 | ------- 11 | 12 | The information in this section is for people doing development on 13 | Calamari itself. 14 | 15 | Contents 16 | -------- 17 | 18 | .. toctree:: 19 | :maxdepth: 2 20 | 21 | dev_env 22 | building_packages 23 | logging 24 | debugging 25 | testing 26 | coding_style 27 | coverage 28 | cthulhu_components 29 | communications 30 | cthulhu_locking 31 | persistence 32 | requests 33 | OSX -------------------------------------------------------------------------------- /rlyeh/rlyeh/util.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from dateutil import tz 4 | import gevent.greenlet 5 | import gevent.event 6 | 7 | 8 | def now(): 9 | """ 10 | A tz-aware now 11 | """ 12 | return datetime.datetime.utcnow().replace(tzinfo=tz.tzutc()) 13 | 14 | 15 | class Ticker(gevent.greenlet.Greenlet): 16 | def __init__(self, period, callback, *args, **kwargs): 17 | super(Ticker, self).__init__(*args, **kwargs) 18 | self._period = period 19 | self._callback = callback 20 | self._complete = gevent.event.Event() 21 | 22 | def stop(self): 23 | self._complete.set() 24 | 25 | def _run(self): 26 | while not self._complete.is_set(): 27 | self._callback() 28 | self._complete.wait(self._period) 29 | -------------------------------------------------------------------------------- /cthulhu/cthulhu/util.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from dateutil import tz 4 | import gevent.greenlet 5 | import gevent.event 6 | 7 | 8 | def now(): 9 | """ 10 | A tz-aware now 11 | """ 12 | return datetime.datetime.utcnow().replace(tzinfo=tz.tzutc()) 13 | 14 | 15 | class Ticker(gevent.greenlet.Greenlet): 16 | def __init__(self, period, callback, *args, **kwargs): 17 | super(Ticker, self).__init__(*args, **kwargs) 18 | self._period = period 19 | self._callback = callback 20 | self._complete = gevent.event.Event() 21 | 22 | def stop(self): 23 | self._complete.set() 24 | 25 | def _run(self): 26 | while not self._complete.is_set(): 27 | self._callback() 28 | self._complete.wait(self._period) 29 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__request__request_id_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//request/ 2 | ======================================================= 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/request/34b86742-c026-484c-bba6-a60e71e06275 5 | ------------------------------------------------------------------------------------------------ 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "status": "Waiting for OSD map epoch 2", 11 | "requested_at": "2014-11-06T21:15:15.547623+00:00", 12 | "headline": "Creating pool 'newname'", 13 | "error_message": "", 14 | "completed_at": null, 15 | "state": "submitted", 16 | "error": false, 17 | "id": "34b86742-c026-484c-bba6-a60e71e06275" 18 | } 19 | 20 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_key.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/key 2 | ======================= 3 | 4 | api/v2/key 5 | ---------- 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | { 11 | "status": "pre", 12 | "id": "vpm061.front.sepia.ceph.com" 13 | }, 14 | { 15 | "status": "pre", 16 | "id": "vpm113.front.sepia.ceph.com" 17 | }, 18 | { 19 | "status": "pre", 20 | "id": "vpm145.front.sepia.ceph.com" 21 | }, 22 | { 23 | "status": "accepted", 24 | "id": "figment000.cluster0.com" 25 | }, 26 | { 27 | "status": "accepted", 28 | "id": "figment001.cluster0.com" 29 | }, 30 | { 31 | "status": "accepted", 32 | "id": "figment002.cluster0.com" 33 | } 34 | ] 35 | 36 | -------------------------------------------------------------------------------- /debian/calamari-server.postrm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CLEANUP_SUBDIRS="alembic conf salt salt-local venv" 4 | 5 | case "$1" in 6 | remove) 7 | # clean up .pyc and other detritus 8 | for subdir in $CLEANUP_SUBDIRS ; do 9 | rm -rf /opt/calamari/$subdir 10 | done 11 | ;; 12 | 13 | purge) 14 | # as above, plus logs and whisper data 15 | for subdir in $CLEANUP_SUBDIRS ; do 16 | rm -rf /opt/calamari/$subdir 17 | done 18 | rm -rf /var/log/graphite 19 | rm -rf /var/log/calamari 20 | rm -rf /var/lib/graphite 21 | ;; 22 | 23 | upgrade|disappear|abort-install|abort-upgrade|disappear|failed-upgrade|abort-install|abort-upgrade) 24 | # just...no. 25 | ;; 26 | 27 | *) 28 | echo "postrm called with unknown argument $1" >&2 29 | exit 1 30 | ;; 31 | esac 32 | 33 | #DEBHELPER# 34 | 35 | exit 0 36 | -------------------------------------------------------------------------------- /doc/calamari_rest/authentication.rst: -------------------------------------------------------------------------------- 1 | 2 | Authentication 3 | ============== 4 | 5 | The Calamari REST API uses the same username/password authentication method as the Calamari 6 | user interface. 7 | 8 | At a high level, given an HTTP client that supports cookies, the process is: 9 | 10 | * GET any url, for example ``/api/v2/auth/login`` and use the XSRF-TOKEN cookie in the response 11 | as a the X-XSRF-TOKEN header on subsequent POSTs 12 | * POST to ``/api/v2/auth/login``, with a JSON content of ``{'username': ..., 'password': ...}`` 13 | * Subsequent requests will be authenticated with a session cookie 14 | 15 | For an example of how to authenticate with the API, please see the AuthenticatedHttpClient 16 | class defined in the Calamari test suite: https://github.com/ceph/calamari/blob/master/tests/http_client.py 17 | 18 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__osd__osd_id_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//osd/ 2 | =============================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/osd/0 5 | --------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "uuid": "9b2e324f-109d-449e-af60-f5f0b8fa5af0", 11 | "reweight": 1.0, 12 | "up": true, 13 | "server": "figment000.cluster0.com", 14 | "public_addr": "", 15 | "in": true, 16 | "pools": [ 17 | 0, 18 | 1, 19 | 2, 20 | 3 21 | ], 22 | "valid_commands": [ 23 | "scrub", 24 | "deep_scrub", 25 | "repair" 26 | ], 27 | "cluster_addr": "", 28 | "id": 0 29 | } 30 | 31 | -------------------------------------------------------------------------------- /minion-sim/minion_sim/load_gen.py: -------------------------------------------------------------------------------- 1 | import random 2 | import threading 3 | 4 | 5 | class LoadGenerator(threading.Thread): 6 | def __init__(self, cluster): 7 | super(LoadGenerator, self).__init__() 8 | 9 | self._cluster = cluster 10 | self._complete = threading.Event() 11 | 12 | def run(self): 13 | interval = 2 14 | 15 | while not self._complete.is_set(): 16 | # Some 'data' 17 | self._cluster.rados_write(0, random.randint(10, 20), 1024 * 1024 * 4) 18 | # Some 'metadata' 19 | self._cluster.rados_write(1, random.randint(10, 20), 1024) 20 | 21 | # Give the cluster a chance to update 22 | self._cluster.advance(interval) 23 | 24 | self._complete.wait(interval) 25 | 26 | def stop(self): 27 | self._complete.set() 28 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__request.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//request 2 | ========================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/request 5 | ----------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "count": 1, 11 | "previous": null, 12 | "results": [ 13 | { 14 | "status": "Waiting for OSD map epoch 2", 15 | "requested_at": "2014-11-06T21:15:15.547623+00:00", 16 | "headline": "Creating pool 'newname'", 17 | "error_message": "", 18 | "completed_at": null, 19 | "state": "submitted", 20 | "error": false, 21 | "id": "34b86742-c026-484c-bba6-a60e71e06275" 22 | } 23 | ], 24 | "next": null 25 | } 26 | 27 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__crush_type.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//crush_type 2 | ============================================= 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/crush_type 5 | -------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | { 11 | "id": 0, 12 | "name": "osd" 13 | }, 14 | { 15 | "id": 1, 16 | "name": "host" 17 | }, 18 | { 19 | "id": 2, 20 | "name": "rack" 21 | }, 22 | { 23 | "id": 3, 24 | "name": "row" 25 | }, 26 | { 27 | "id": 4, 28 | "name": "room" 29 | }, 30 | { 31 | "id": 5, 32 | "name": "datacenter" 33 | }, 34 | { 35 | "id": 6, 36 | "name": "root" 37 | } 38 | ] 39 | 40 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__mon.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//mon 2 | ====================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/mon 5 | ------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | [ 10 | { 11 | "addr": "", 12 | "in_quorum": true, 13 | "name": "figment000", 14 | "rank": 0, 15 | "server": "figment000.cluster0.com" 16 | }, 17 | { 18 | "addr": "", 19 | "in_quorum": true, 20 | "name": "figment001", 21 | "rank": 1, 22 | "server": "figment001.cluster0.com" 23 | }, 24 | { 25 | "addr": "", 26 | "in_quorum": true, 27 | "name": "figment002", 28 | "rank": 2, 29 | "server": "figment002.cluster0.com" 30 | } 31 | ] 32 | 33 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py26, py27, flake8 3 | skipsdist=true 4 | 5 | # XXX the `-W` flag treats warnings as errors, so this will currently fail. The 6 | # `resources.rst` file # contains generated docs that point to non-existent 7 | # documents. The following command *is* what we need to use at some point when 8 | # the failures have been fixed: 9 | # sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html 10 | 11 | 12 | [testenv:docs] 13 | deps = -r{toxinidir}/requirements/2.7/requirements.txt 14 | basepython=python 15 | changedir=doc 16 | commands= 17 | sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html 18 | 19 | # At some point we should enable `F` type errors, but this will make 20 | # the builds fail right now. 21 | # 22 | # [testenv:flake8] 23 | # deps=flake8 24 | # commands=flake8 --select=F --exclude=vendor {posargs:calamari-common calamari-web} 25 | -------------------------------------------------------------------------------- /cthulhu/cthulhu/persistence/sync_objects.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from sqlalchemy import Column, String, Text, DateTime, Integer, LargeBinary 4 | from calamari_common.db.base import Base 5 | 6 | 7 | class SyncObject(Base): 8 | """ 9 | A table for storing a FIFO of ClusterMonitor 'sync objects', i.e. 10 | cluster maps. 11 | """ 12 | __tablename__ = 'cthulhu_sync_object' 13 | 14 | # TODO: composite PK 15 | fsid = Column(Text, primary_key=True) 16 | cluster_name = Column(Text) # FIXME this is denormalized because currently there isn't a cluster table 17 | sync_type = Column(String, primary_key=True) 18 | version = Column(Integer, nullable=True, primary_key=True) 19 | when = Column(DateTime, index=True) 20 | data = Column(LargeBinary) 21 | 22 | def __repr__(self): 23 | return "" % (self.fsid, self.sync_type, self.version if self.version else self.when) 24 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | 2 | Calamari 3 | ======== 4 | 5 | Calamari is a management and monitoring service for Ceph, exposing a high level REST API. 6 | 7 | Calamari source: https://github.com/ceph/calamari 8 | 9 | Calamari mailing list: http://lists.ceph.com/listinfo.cgi/ceph-calamari-ceph.com 10 | 11 | Calamari issue tracker: http://tracker.ceph.com/projects/calamari 12 | 13 | **For users**: :doc:`operations/index` 14 | 15 | **For developers working on Calamari**: :doc:`development/index` 16 | 17 | **For developers using the Calamari REST API**: :doc:`calamari_rest/index` 18 | 19 | This documentation is built using Sphinx. The sources are in git 20 | at https://github.com/ceph/calamari/tree/master/doc. To contribute fixes 21 | or additions, please sent pull requests via that git repository. 22 | 23 | Indices and tables 24 | ================== 25 | 26 | * :ref:`genindex` 27 | * :ref:`modindex` 28 | * :ref:`search` 29 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__osd__osd_id__command__command_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//osd//command/ 2 | ================================================================= 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/osd/0/command/scrub 5 | ----------------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "valid": true 11 | } 12 | 13 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/osd/0/command/deep_scrub 14 | ---------------------------------------------------------------------------- 15 | 16 | .. code-block:: json 17 | 18 | { 19 | "valid": true 20 | } 21 | 22 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/osd/0/command/repair 23 | ------------------------------------------------------------------------ 24 | 25 | .. code-block:: json 26 | 27 | { 28 | "valid": true 29 | } 30 | 31 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__crush_node__node_id_.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//crush_node/ 2 | ======================================================= 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/crush_node/-1 5 | ----------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "bucket_type": "root", 11 | "hash": "rjenkins1", 12 | "name": "default", 13 | "weight": 4.8399505615234375, 14 | "alg": "straw", 15 | "items": [ 16 | { 17 | "id": -2, 18 | "weight": 3.0199737548828125, 19 | "pos": 0 20 | }, 21 | { 22 | "id": -3, 23 | "weight": 0.9099884033203125, 24 | "pos": 1 25 | }, 26 | { 27 | "id": -4, 28 | "weight": 0.9099884033203125, 29 | "pos": 2 30 | } 31 | ], 32 | "id": -1 33 | } 34 | 35 | -------------------------------------------------------------------------------- /doc/development/coding_style.rst: -------------------------------------------------------------------------------- 1 | 2 | Coding style 3 | ============ 4 | 5 | All the python code we write should pass two checks: 6 | 7 | - PEP8 (http://www.python.org/dev/peps/pep-0008/), except E501 (line length) 8 | - PyFlakes 9 | 10 | Pre-commit hook 11 | --------------- 12 | 13 | To automatically check your code before committing, a 14 | script is provided for use as a git hook: 15 | 16 | :: 17 | 18 | calamari $ cd .git/hooks 19 | hooks $ ln -s ../../pre-commit.py pre-commit 20 | 21 | 22 | Docstrings 23 | ---------- 24 | 25 | Docstrings in the REST API code are pulled up into the REST API documentation, with 26 | two consequences for developers: 27 | 28 | - It is very much worth writing good ``help_text`` attributes on fields and good 29 | docstrings on ``ViewSet`` classes. 30 | - It is important not to write offhand or overly technical (or profane!) comments 31 | in the docstrings. TODOs and FIXMEs should go in comments rather than docstrings. 32 | 33 | -------------------------------------------------------------------------------- /cthulhu/tests/test_plugin_monitor.py: -------------------------------------------------------------------------------- 1 | from django.utils.unittest import TestCase 2 | import os 3 | import sys 4 | 5 | from cthulhu.manager import plugin_monitor, config 6 | 7 | plugin_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "plugins/")) 8 | config.set('cthulhu', 'plugin_path', plugin_path) 9 | sys.path.append(plugin_path) 10 | 11 | 12 | class TestPluginLoading(TestCase): 13 | def setUp(self): 14 | self.plugin_monitor = plugin_monitor.PluginMonitor(None) 15 | 16 | def testImportStatusProcessor(self): 17 | plugins = self.plugin_monitor.load_plugins()[0] 18 | self.assertEqual(plugins[0], 'acmeplugin') 19 | self.assertEqual(plugins[1].period, 1) 20 | 21 | def testImportError(self): 22 | # TODO this is a little cryptic since I don't feel like patching the config object right now 23 | plugins = self.plugin_monitor.load_plugins() 24 | self.assertEqual(len(plugins), 1) # wilyplugin should bomb 25 | -------------------------------------------------------------------------------- /conf/upstart/kraken.conf: -------------------------------------------------------------------------------- 1 | # Kraken Service 2 | 3 | description "Kraken is a periodic task that refreshes the Calamari database 4 | with state from one or more Ceph clusters." 5 | 6 | author "Inktank, Inc. " 7 | 8 | start on runlevel [2345] 9 | stop on runlevel [06] 10 | 11 | # 12 | # TODO: logging should be added to kraken, and the 13 | # redirection of stderr/stdout currently being used for 14 | # debugging should be removed. 15 | # 16 | 17 | # these settings can be changed here 18 | env CALAMARI_ROOT=/opt/calamari 19 | env CALAMARI_REFRESH_FREQ=30 20 | 21 | script 22 | while [ 1 ] 23 | do 24 | 25 | # run command in the Calamari virtualenv 26 | pybin=$CALAMARI_ROOT/venv/bin/python 27 | 28 | # run Django custom command `manage.py ceph_refresh` 29 | managepy=$CALAMARI_ROOT/webapp/calamari/manage.py 30 | $pybin $managepy ceph_refresh >> /var/log/kraken.log 2>&1 || true 31 | 32 | sleep $CALAMARI_REFRESH_FREQ 33 | done 34 | end script 35 | -------------------------------------------------------------------------------- /dev/etc/graphite/storage-schemas.conf: -------------------------------------------------------------------------------- 1 | # Schema definitions for Whisper files. Entries are scanned in order, 2 | # and first match wins. This file is scanned for changes every 60 seconds. 3 | # 4 | # Definition Syntax: 5 | # 6 | # [name] 7 | # pattern = regex 8 | # retentions = timePerPoint:timeToStore, timePerPoint:timeToStore, ... 9 | # 10 | # Remember: To support accurate aggregation from higher to lower resolution 11 | # archives, the precision of a longer retention archive must be 12 | # cleanly divisible by precision of next lower retention archive. 13 | # 14 | # Valid: 60s:7d,300s:30d (300/60 = 5) 15 | # Invalid: 180s:7d,300s:30d (300/180 = 3.333) 16 | # 17 | 18 | # Carbon's internal metrics. This entry should match what is specified in 19 | # CARBON_METRIC_PREFIX and CARBON_METRIC_INTERVAL settings 20 | [carbon] 21 | pattern = ^carbon\. 22 | retentions = 60:90d 23 | 24 | [calamari] 25 | pattern = .* 26 | retentions = 60s:1d,15m:7d -------------------------------------------------------------------------------- /vagrant/wheezy-build/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | config.vm.box = "debian/wheezy64" 9 | 10 | config.vm.provider "virtualbox" do |v| 11 | v.memory = 1024 12 | end 13 | 14 | config.vm.provider :virtualbox do |vb| 15 | vb.customize ["modifyvm", :id, "--memory", "1024"] 16 | vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate//git", "1"] 17 | end 18 | 19 | config.vm.synced_folder "../../../", "/git" 20 | config.vm.synced_folder "salt/roots/", "/srv/salt/" 21 | config.vm.provision :salt do |salt| 22 | salt.bootstrap_options = "-F -c /tmp -P" 23 | salt.minion_config = "salt/minion" 24 | salt.run_highstate = false 25 | end 26 | config.vm.network :forwarded_port, guest: 22, host: 2206, id: "ssh", auto_correct: true 27 | end 28 | -------------------------------------------------------------------------------- /rest-api/tests/test_crushmap.py: -------------------------------------------------------------------------------- 1 | import mock 2 | import logging 3 | 4 | from django.utils.unittest import TestCase 5 | from calamari_rest.views.v2 import CrushMapViewSet 6 | 7 | log = logging.getLogger(__name__) 8 | 9 | 10 | class TestCrushMap(TestCase): 11 | 12 | def setUp(self): 13 | self.request = mock.Mock() 14 | 15 | with mock.patch('calamari_rest.views.v2.RPCViewSet'): 16 | self.cmvs = CrushMapViewSet() 17 | self.cmvs.client = mock.MagicMock() 18 | self.cmvs.client.update.return_value = {} 19 | 20 | def test_retrieve_crushmap(self): 21 | self.request.method = 'GET' 22 | response = self.cmvs.retrieve(self.request, 12345) 23 | self.assertEqual(response.status_code, 200) 24 | 25 | def test_replace_crushmap_passes(self): 26 | self.request.method = 'POST' 27 | self.request.DATA = {} 28 | response = self.cmvs.replace(self.request, 12345) 29 | self.assertEqual(response.status_code, 200) 30 | -------------------------------------------------------------------------------- /get-versions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Output version, revision for package builds derived from git. 4 | # 5 | # -r: change revision to be suitable for rpm 6 | # VERSION: output X only 7 | # REVISION: output Y only 8 | # no more args: output VERSION=X REVISION=Y suitable for eval 9 | # 10 | 11 | RPM='n' 12 | if [ "$1" == "-r" ] ; then RPM='y' ; shift ; fi 13 | 14 | # GITVER is the version from the current git branch, less the first char ('v') 15 | GITVER=$(git describe | cut -c 2-) 16 | 17 | # if GITVER contains a '-', separate at the first one into version and revision 18 | if [[ $GITVER == *-* ]]; then 19 | VERSION=$(echo $GITVER | sed 's/-.*//') 20 | REVISION=$(echo $GITVER | sed 's/'${VERSION}'-//') 21 | if [ $RPM == 'y' ] ; then 22 | REVISION=$(echo $REVISION | sed 's/-/_/g') 23 | fi 24 | else 25 | VERSION=$GITVER 26 | REVISION="0" 27 | fi 28 | 29 | case "$1" in 30 | VERSION) echo $VERSION; exit ;; 31 | REVISION) echo $REVISION; exit ;; 32 | *) echo "VERSION=$VERSION REVISION=$REVISION"; exit ;; 33 | esac 34 | -------------------------------------------------------------------------------- /cthulhu/cthulhu/manager/request_factory.py: -------------------------------------------------------------------------------- 1 | 2 | class RequestFactory(object): 3 | """ 4 | A class to generate UserRequests with commands (e.g. Ceph RADOS admin 5 | commands) in response to C[r]UD operations. 6 | 7 | The mapping is sometimes very simple (e.g. delete on a pool is 8 | just a 'ceph osd pool delete'), and sometimes more complex (e.g. 9 | pool creation requires a 'pool create' followed by a series of 10 | 'pool set' and/or 'pool set-quota' commands). 11 | 12 | """ 13 | def __init__(self, cluster_monitor): 14 | # The parent ClusterMonitor, we need a reference to see its 15 | # cluster maps 16 | self._cluster_monitor = cluster_monitor 17 | 18 | def delete(self, obj_id): 19 | raise NotImplementedError() 20 | 21 | def update(self, obj_id, attributes): 22 | raise NotImplementedError() 23 | 24 | def create(self, attributes): 25 | raise NotImplementedError() 26 | 27 | def get_valid_commands(self, obj_ids): 28 | return {} 29 | -------------------------------------------------------------------------------- /vagrant/trusty-build/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | config.vm.box = "ubuntu/trusty64" 9 | 10 | config.vm.provider "virtualbox" do |v| 11 | v.memory = 1024 12 | end 13 | 14 | config.vm.provider :virtualbox do |vb| 15 | vb.customize ["modifyvm", :id, "--memory", "1024"] 16 | vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate//git", "1"] 17 | end 18 | 19 | config.vm.synced_folder "../../../", "/git" 20 | config.vm.synced_folder "salt/roots/", "/srv/salt/" 21 | config.vm.provision :salt do |salt| 22 | salt.bootstrap_options = "-F -c /tmp -P" 23 | salt.minion_config = "salt/minion" 24 | salt.verbose = true 25 | salt.run_highstate = false 26 | end 27 | config.vm.network :forwarded_port, guest: 22, host: 2205, id: "ssh", auto_correct: true 28 | end 29 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: calamari 2 | Section: misc 3 | Priority: extra 4 | Homepage: http://www.inktank.com/ 5 | Vcs-Browser: https://github.com/ceph/calamari.git 6 | Maintainer: Dan Mick 7 | Standards-Version: 3.9.3 8 | Build-Depends: debhelper (>= 9), 9 | git, 10 | libcairo2-dev, 11 | libpq-dev, 12 | lsb-release, 13 | python-dev, 14 | python-pip, 15 | virtualenv | python-virtualenv 16 | 17 | Package: calamari-server 18 | Architecture: any 19 | Depends: libcairo2, 20 | libpq5, 21 | logrotate, 22 | openssl, 23 | python-cairo, 24 | sqlite3, 25 | python:any, 26 | python-twisted, 27 | python-txamqp, 28 | python-pkg-resources, 29 | python-six, 30 | ${misc:Depends} 31 | Description: Inktank package containing the Calamari management server 32 | Calamari is a webapp to monitor and control a Ceph cluster via a web 33 | browser. 34 | -------------------------------------------------------------------------------- /cthulhu/tests/test_rpc.py: -------------------------------------------------------------------------------- 1 | from django.utils.unittest import TestCase 2 | from mock import MagicMock 3 | from cthulhu.manager.rpc import RpcInterface 4 | 5 | 6 | class TestRpc(TestCase): 7 | 8 | def setUp(self): 9 | fake_manager = MagicMock() 10 | 11 | mock_attribs = {'name': 'I am a fake', 12 | 'fsid': 12345, 13 | 'clusters': fake_manager, 14 | 'osd_tree_node_by_id': {1: 'a node'}, 15 | 'get_sync_object.return_value': fake_manager, 16 | '__getitem__.return_value': fake_manager, 17 | 'osds_by_id': {0: {'up': True}, 1: {'up': False}}} 18 | 19 | fake_manager.configure_mock(**mock_attribs) 20 | fake_manager[12345] = fake_manager 21 | 22 | self.rpc = RpcInterface(fake_manager) 23 | 24 | def test_get_sync_object_happy_path(self): 25 | osd_map = self.rpc.get_sync_object(12345, 'osd_map', ['osd_tree_node_by_id']) 26 | assert osd_map == {1: 'a node'} 27 | -------------------------------------------------------------------------------- /rest-api/tests/test_saltkey.py: -------------------------------------------------------------------------------- 1 | import mock 2 | import logging 3 | 4 | from django.utils.unittest import TestCase 5 | from calamari_rest.views.v2 import SaltKeyViewSet, ParseError 6 | 7 | log = logging.getLogger(__name__) 8 | 9 | 10 | def fake_list(*args, **kwargs): 11 | return [{'id': 'ubuntu', 12 | 'status': 'pre'} 13 | ] 14 | 15 | 16 | class TestSaltKeyValidation(TestCase): 17 | 18 | def setUp(self): 19 | self.request = mock.Mock() 20 | self.request.method = 'POST' 21 | 22 | with mock.patch('calamari_rest.views.v2.RPCViewSet'): 23 | self.viewset = SaltKeyViewSet() 24 | self.viewset.client = mock.MagicMock() 25 | self.viewset.client.list = fake_list 26 | self.viewset.client.get.return_value = fake_list()[0] 27 | 28 | def test_passing_one_to_list_bulk_update_fails_validation(self): 29 | self.request.DATA = {'id': 'ubuntu', 'status': 'accepted'} 30 | self.assertRaises(ParseError, self.viewset.list_partial_update, self.request) 31 | -------------------------------------------------------------------------------- /vagrant/devmode/salt/roots/configs.sls: -------------------------------------------------------------------------------- 1 | carbon.conf: 2 | file: 3 | - copy 4 | - user: {{ pillar['username'] }} 5 | - name: {{ pillar['home'] }}/calamari/env/conf/carbon.conf 6 | - source: {{ pillar['home'] }}/calamari/env/conf/carbon.conf.example 7 | require: 8 | - sls: virtualenv 9 | 10 | storage-schemas.conf: 11 | file: 12 | - copy 13 | - user: {{ pillar['username'] }} 14 | - name: {{ pillar['home'] }}/calamari/env/conf/storage-schemas.conf 15 | - source: {{ pillar['home'] }}/calamari/env/conf/storage-schemas.conf.example 16 | require: 17 | - sls: virtualenv 18 | 19 | storage_log_webapp: 20 | file: 21 | - directory 22 | - user: {{ pillar['username'] }} 23 | - makedirs: true 24 | - name: {{ pillar['home'] }}/calamari/env/storage/log/webapp 25 | require: 26 | - sls: virtualenv 27 | 28 | storage: 29 | file: 30 | - directory 31 | - user: {{ pillar['username'] }} 32 | - makedirs: true 33 | - name: {{ pillar['home'] }}/calamari/env/storage 34 | require: 35 | - sls: virtualenv 36 | -------------------------------------------------------------------------------- /debian/calamari-server.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | calamari_httpd() 4 | { 5 | d=$(pwd) 6 | # allow apache access to all 7 | chown -R www-data:www-data /opt/calamari/webapp/calamari 8 | 9 | # www-data shouldn't need to write, but it does because graphite creates index on read 10 | chown -R www-data:www-data /var/lib/graphite 11 | 12 | chown -R www-data:www-data /var/log/calamari 13 | cd $d 14 | 15 | } 16 | 17 | case "$1" in 18 | configure) 19 | calamari_httpd 20 | 21 | # Prompt the user to proceed with the final script-driven 22 | # part of the installation process 23 | echo "Thank you for installing Calamari." 24 | echo "" 25 | echo "Please run 'sudo calamari-ctl initialize' to complete the installation." 26 | 27 | # rpm/centos 28 | # service httpd restart 29 | # chkconfig httpd on 30 | ;; 31 | 32 | abort-upgrade|abort-remove|abort-deconfigure) 33 | ;; 34 | *) 35 | echo "postinst called with unknown argument $1" >&2 36 | exit 1 37 | ;; 38 | esac 39 | 40 | 41 | exit 0 42 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/views/database_view_set.py: -------------------------------------------------------------------------------- 1 | 2 | from calamari_rest.viewsets import RoleLimitedViewSet 3 | from calamari_web.settings import config 4 | 5 | try: 6 | import sqlalchemy 7 | except ImportError: 8 | sqlalchemy = None 9 | else: 10 | from sqlalchemy import create_engine 11 | from sqlalchemy.orm import sessionmaker 12 | Session = sessionmaker() 13 | 14 | 15 | class DatabaseViewSet(RoleLimitedViewSet): 16 | @property 17 | def serializer_class(self): 18 | raise NotImplementedError() 19 | 20 | def __init__(self, *args, **kwargs): 21 | super(DatabaseViewSet, self).__init__(*args, **kwargs) 22 | 23 | if sqlalchemy is not None: 24 | if not hasattr(DatabaseViewSet, 'engine'): 25 | DatabaseViewSet.engine = create_engine(config.get('cthulhu', 'db_path')) 26 | Session.configure(bind=self.engine) 27 | 28 | self.session = Session() 29 | else: 30 | class NullSession(object): 31 | def query(self, *args, **kwargs): 32 | return [] 33 | 34 | self.session = NullSession() 35 | -------------------------------------------------------------------------------- /doc/calamari.conf: -------------------------------------------------------------------------------- 1 | 2 | [cthulhu] 3 | 4 | plugin_path = 5 | salt_config_path = 6 | alembic_config_path = 7 | db_path = 8 | log_path = /tmp/cthulhu.log 9 | log_level = DEBUG 10 | rpc_url = 11 | crush_host_type = host 12 | crush_osd_type = osd 13 | cluster_map_retention = 3600 14 | db_log_level = WARN 15 | favorite_timeout_factor = 3 16 | server_timeout_factor = 3 17 | cluster_contact_threshold = 60 18 | emit_events_to_salt_event_bus = False 19 | event_tag_prefix = calamari/ 20 | 21 | [calamari_web] 22 | 23 | log_path = /Users/john/git/calamari/dev/calamari.log 24 | log_level = DEBUG 25 | db_engine = django.db.backends.postgresql_psycopg2 26 | db_name = calamari 27 | db_user = calamari 28 | db_password = 27HbZwr*g 29 | db_host = localhost 30 | secret_key_path = /Users/john/git/calamari/dev/secret.key 31 | username = john 32 | static_root = /Users/john/git/calamari/webapp/content/ 33 | 34 | [graphite] 35 | 36 | root = /Users/john/git/calamari/env 37 | storage_path = /Users/john/git/calamari/env/storage 38 | 39 | [testing] 40 | 41 | calamari_control = embedded 42 | ceph_control = embedded 43 | external_cluster_path = /Users/john/git/calamari/cluster.yaml 44 | -------------------------------------------------------------------------------- /doc/operations/configuring_ceph.rst: -------------------------------------------------------------------------------- 1 | 2 | Configuring Ceph 3 | ================ 4 | 5 | Calamari will configure Ceph to use our osd CRUSH location hook. 6 | We do this to preserve an OSDs location in the CRUSH map when the osd restarts 7 | if we've moved the OSD crush node with Calamari. 8 | 9 | 10 | How it Works 11 | ------------ 12 | 13 | Our hook operates using the OSD cephx key and uses it to contact a Ceph MON. 14 | Calamari stores information in the MON config-key store. 15 | 16 | 17 | Failure Modes 18 | ------------- 19 | 20 | If we detect that the hostname where an OSD is starting has changed from last reported location 21 | we report the parent CRUSH node as host=current_hostname. This allows OSD hotplugging to work. 22 | 23 | If we cannot get a MON to answer withing a short time period we report the parent CRUSH node as 24 | host=current_hostname. This allows OSDs to start without depending on the MON node. 25 | 26 | 27 | Restoring Configuration 28 | ----------------------- 29 | 30 | We preserve a copy of the cluster config on each node in /etc/ceph/{cluster_name}.conf.orig 31 | Should you experince issues you can restore the config from there. 32 | -------------------------------------------------------------------------------- /doc/operations/reporting_bugs.rst: -------------------------------------------------------------------------------- 1 | 2 | Reporting Issues 3 | ================ 4 | 5 | The Calamari issue tracker is at http://tracker.ceph.com/projects/calamari 6 | 7 | .. note:: 8 | 9 | These instructions are for community users. If you are an Inktank Ceph Enterprise 10 | customer, please contact support directly via the same channels you would 11 | use for Ceph issues. 12 | 13 | Before opening an issue, please gather all available diagnostic information, especially 14 | the log files from the Calamari server. The Calamari server logs are stored in 15 | ``/var/log/calamari``. 16 | 17 | Please ensure that you mention which versions of Calamari and Ceph you are using, 18 | how you built or obtained packages, and the name and version of the Linux 19 | distribution you are using. 20 | 21 | If you are reporting an issue involving the user interface, please include screenshots 22 | of the relevant parts. If the user interface appears to be exhibiting a bug itself, 23 | please check the Javascript console in your web browser for error messages and 24 | include these as well. Please mention the name and version of the web browser you 25 | are using. 26 | 27 | -------------------------------------------------------------------------------- /conf/calamari/suse/calamari.conf: -------------------------------------------------------------------------------- 1 | 2 | [cthulhu] 3 | 4 | plugin_path = /opt/calamari/plugins # TODO add to packaging, not a problem now since we check os.path.exists 5 | salt_config_path = /etc/salt/master 6 | alembic_config_path = /etc/calamari/alembic.ini 7 | db_path = postgresql://calamari:27HbZwr*g@localhost/calamari 8 | log_path = /var/log/calamari/cthulhu.log 9 | log_level = WARN 10 | rpc_url = tcp://127.0.0.1:5050 11 | crush_host_type = host 12 | crush_osd_type = osd 13 | cluster_map_retention = 3600 14 | db_log_level = WARN 15 | favorite_timeout_factor = 3 16 | server_timeout_factor = 3 17 | cluster_contact_threshold = 60 18 | emit_events_to_salt_event_bus = True 19 | event_tag_prefix = calamari/ 20 | 21 | [calamari_web] 22 | 23 | log_path = /var/log/calamari/calamari.log 24 | log_level = WARN 25 | db_engine = django.db.backends.postgresql_psycopg2 26 | db_name = calamari 27 | db_user = calamari 28 | db_password = 27HbZwr*g 29 | db_host = localhost 30 | db_port = 5432 31 | secret_key_path = /etc/calamari/secret.key 32 | username = root 33 | static_root = /srv/www/calamari/content/ 34 | 35 | [graphite] 36 | 37 | storage_path = /var/lib/graphite 38 | root = /usr/share/graphite 39 | 40 | -------------------------------------------------------------------------------- /conf/calamari/el6/calamari.conf: -------------------------------------------------------------------------------- 1 | 2 | [cthulhu] 3 | 4 | plugin_path = /opt/calamari/plugins # TODO add to packaging, not a problem now since we check os.path.exists 5 | salt_config_path = /etc/salt/master 6 | alembic_config_path = /etc/calamari/alembic.ini 7 | db_path = postgresql://calamari:27HbZwr*g@localhost/calamari 8 | log_path = /var/log/calamari/cthulhu.log 9 | log_level = WARN 10 | rpc_url = tcp://127.0.0.1:5050 11 | crush_host_type = host 12 | crush_osd_type = osd 13 | cluster_map_retention = 3600 14 | db_log_level = WARN 15 | favorite_timeout_factor = 3 16 | server_timeout_factor = 3 17 | cluster_contact_threshold = 60 18 | emit_events_to_salt_event_bus = True 19 | event_tag_prefix = calamari/ 20 | 21 | [calamari_web] 22 | 23 | log_path = /var/log/calamari/calamari.log 24 | log_level = WARN 25 | db_engine = django.db.backends.postgresql_psycopg2 26 | db_name = calamari 27 | db_user = calamari 28 | db_password = 27HbZwr*g 29 | db_host = localhost 30 | db_port = 5432 31 | secret_key_path = /opt/calamari/webapp/secret.key 32 | username = root 33 | static_root = /opt/calamari/webapp/content/ 34 | 35 | [graphite] 36 | 37 | storage_path = /var/lib/graphite 38 | root = /opt/calamari/venv 39 | 40 | -------------------------------------------------------------------------------- /vagrant/rhel-build/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | if ENV['RHEL64_BOX_PATH'] == nil 9 | box_url = "file:/home/jenkins-build/rhel64.box" 10 | else 11 | box_url = ENV['RHEL64_BOX_PATH'] 12 | end 13 | config.vm.box_url = box_url 14 | config.vm.box = "rhel64" 15 | 16 | config.vm.provider "virtualbox" do |v| 17 | v.memory = 1024 18 | end 19 | 20 | config.vm.provider :virtualbox do |vb| 21 | vb.customize ["modifyvm", :id, "--memory", "1024"] 22 | vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate//git", "1"] 23 | end 24 | 25 | config.vm.synced_folder "../../../", "/git" 26 | config.vm.synced_folder "salt/roots/", "/srv/salt/" 27 | config.vm.provision :salt do |salt| 28 | salt.minion_config = "salt/minion" 29 | salt.run_highstate = false 30 | salt.bootstrap_script = "../urllib-bootstrap-salt.sh" 31 | end 32 | config.vm.network :forwarded_port, guest: 22, host: 2204, id: "ssh", auto_correct: true 33 | end 34 | -------------------------------------------------------------------------------- /vagrant/rhel7-build/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | if ENV['RHEL7_BOX_PATH'] == nil 9 | box_url = "file:/home/jenkins-build/rhel7.box" 10 | else 11 | box_url = ENV['RHEL7_BOX_PATH'] 12 | end 13 | config.vm.box_url = box_url 14 | config.vm.box = "rhel7" 15 | 16 | config.vm.provider "virtualbox" do |v| 17 | v.memory = 1024 18 | end 19 | 20 | config.vm.provider :virtualbox do |vb| 21 | vb.customize ["modifyvm", :id, "--memory", "1024"] 22 | vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate//git", "1"] 23 | end 24 | 25 | config.vm.synced_folder "../../../", "/git" 26 | config.vm.synced_folder "salt/roots/", "/srv/salt/" 27 | config.vm.provision :salt do |salt| 28 | salt.minion_config = "salt/minion" 29 | salt.run_highstate = false 30 | salt.bootstrap_script = "../urllib-bootstrap-salt.sh" 31 | end 32 | config.vm.network :forwarded_port, guest: 22, host: 2203, id: "ssh", auto_correct: true 33 | end 34 | -------------------------------------------------------------------------------- /conf/calamari/rhel7/calamari.conf: -------------------------------------------------------------------------------- 1 | 2 | [cthulhu] 3 | 4 | plugin_path = /opt/calamari/plugins # TODO add to packaging, not a problem now since we check os.path.exists 5 | salt_config_path = /etc/salt/master 6 | alembic_config_path = /etc/calamari/alembic.ini 7 | db_path = sqlite:////var/lib/calamari/calamari.sqlite3 8 | log_path = /var/log/calamari/cthulhu.log 9 | log_level = WARN 10 | rpc_url = tcp://127.0.0.1:5050 11 | crush_host_type = host 12 | crush_osd_type = osd 13 | cluster_map_retention = 3600 14 | db_log_level = WARN 15 | favorite_timeout_factor = 3 16 | server_timeout_factor = 3 17 | cluster_contact_threshold = 60 18 | emit_events_to_salt_event_bus = True 19 | event_tag_prefix = calamari/ 20 | 21 | [calamari_web] 22 | 23 | log_path = /var/log/calamari/calamari.log 24 | log_level = WARN 25 | db_engine = django.db.backends.sqlite3 26 | db_name = /var/lib/calamari/calamari.sqlite3 27 | db_user = calamari 28 | db_password = 27HbZwr*g 29 | db_host = localhost 30 | db_port = 5432 31 | secret_key_path = /opt/calamari/webapp/secret.key 32 | username = root 33 | static_root = /opt/calamari/webapp/content/ 34 | 35 | [graphite] 36 | 37 | storage_path = /var/lib/graphite 38 | root = /opt/calamari/venv 39 | 40 | -------------------------------------------------------------------------------- /conf/calamari/debian/calamari.conf: -------------------------------------------------------------------------------- 1 | 2 | [cthulhu] 3 | 4 | plugin_path = /opt/calamari/plugins # TODO add to packaging, not a problem now since we check os.path.exists 5 | salt_config_path = /etc/salt/master 6 | alembic_config_path = /etc/calamari/alembic.ini 7 | db_path = sqlite:////var/lib/calamari/calamari.sqlite3 8 | log_path = /var/log/calamari/cthulhu.log 9 | log_level = WARN 10 | rpc_url = tcp://127.0.0.1:5050 11 | crush_host_type = host 12 | crush_osd_type = osd 13 | cluster_map_retention = 3600 14 | db_log_level = WARN 15 | favorite_timeout_factor = 3 16 | server_timeout_factor = 3 17 | cluster_contact_threshold = 60 18 | emit_events_to_salt_event_bus = True 19 | event_tag_prefix = calamari/ 20 | 21 | [calamari_web] 22 | 23 | log_path = /var/log/calamari/calamari.log 24 | log_level = WARN 25 | db_engine = django.db.backends.sqlite3 26 | db_name = /var/lib/calamari/calamari.sqlite3 27 | db_user = calamari 28 | db_password = 27HbZwr*g 29 | db_host = localhost 30 | db_port = 5432 31 | secret_key_path = /opt/calamari/webapp/secret.key 32 | username = root 33 | static_root = /opt/calamari/webapp/content/ 34 | 35 | [graphite] 36 | 37 | storage_path = /var/lib/graphite 38 | root = /opt/calamari/venv 39 | 40 | -------------------------------------------------------------------------------- /cthulhu/tests/test_pg_progress.py: -------------------------------------------------------------------------------- 1 | 2 | from django.utils.unittest.case import TestCase 3 | from cthulhu.manager.user_request import PgProgress 4 | 5 | 6 | class TestPgProgress(TestCase): 7 | def test_single_block(self): 8 | pg_progress = PgProgress(10, 20, 10) 9 | self.assertTrue(pg_progress.is_final_block()) 10 | self.assertEqual(pg_progress.goal, 20) 11 | 12 | with self.assertRaises(AssertionError): 13 | pg_progress.advance_goal() 14 | 15 | def test_multiple_blocks(self): 16 | pg_progress = PgProgress(10, 30, 10) 17 | 18 | self.assertFalse(pg_progress.is_final_block()) 19 | self.assertEqual(pg_progress.goal, 20) 20 | 21 | self.assertEqual(pg_progress.get_status(), "Waiting for PG creation (0/20), currently creating PGs 10-20") 22 | 23 | pg_progress.set_created_pg_count(20) 24 | pg_progress.advance_goal() 25 | self.assertTrue(pg_progress.is_final_block()) 26 | self.assertEqual(pg_progress.goal, 30) 27 | 28 | self.assertEqual(pg_progress.get_status(), "Waiting for PG creation (10/20)") 29 | 30 | with self.assertRaises(AssertionError): 31 | pg_progress.advance_goal() 32 | -------------------------------------------------------------------------------- /vagrant/centos7-build/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | config.vm.box = "centos/7" 9 | 10 | config.vm.provider "virtualbox" do |v| 11 | v.memory = 1024 12 | end 13 | 14 | config.vm.provider :virtualbox do |vb| 15 | vb.customize ["modifyvm", :id, "--memory", "1024"] 16 | vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate//git", "1"] 17 | end 18 | 19 | config.vm.synced_folder "../../../", "/git" 20 | config.vm.synced_folder "salt/roots/", "/srv/salt/" 21 | config.vm.provision :salt do |salt| 22 | salt.bootstrap_options = "-F -c /tmp -P" 23 | salt.minion_config = "salt/minion" 24 | salt.run_highstate = false 25 | end 26 | # Use a bridged network so that external Ceph servers can connect to 27 | # salt master on this VM. 28 | config.vm.network "public_network", bridge: [ 29 | "en0: Wi-Fi (AirPort)", # without this `vagrant up` will pause for interface selection 30 | ] 31 | 32 | config.vm.hostname = 'vagrant-centos-7' 33 | end 34 | -------------------------------------------------------------------------------- /conf/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # path to migration scripts 5 | script_location = /opt/calamari/alembic 6 | 7 | # template used to generate migration files 8 | # file_template = %%(rev)s_%%(slug)s 9 | 10 | # max length of characters to apply to the 11 | # "slug" field 12 | #truncate_slug_length = 40 13 | 14 | # set to 'true' to run the environment during 15 | # the 'revision' command, regardless of autogenerate 16 | # revision_environment = false 17 | 18 | sqlalchemy.url = sqlite:////var/lib/calamari/calamari.sqlite3 19 | 20 | 21 | # Logging configuration 22 | [loggers] 23 | keys = root,sqlalchemy,alembic 24 | 25 | [handlers] 26 | keys = console 27 | 28 | [formatters] 29 | keys = generic 30 | 31 | [logger_root] 32 | level = WARN 33 | handlers = console 34 | qualname = 35 | 36 | [logger_sqlalchemy] 37 | level = WARN 38 | handlers = 39 | qualname = sqlalchemy.engine 40 | 41 | [logger_alembic] 42 | level = WARN 43 | handlers = 44 | qualname = alembic 45 | 46 | [handler_console] 47 | class = StreamHandler 48 | args = (sys.stderr,) 49 | level = NOTSET 50 | formatter = generic 51 | 52 | [formatter_generic] 53 | format = %(levelname)-5.5s [%(name)s] %(message)s 54 | datefmt = %H:%M:%S 55 | -------------------------------------------------------------------------------- /dev/alembic.ini.template: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # path to migration scripts 5 | script_location = {{calamari_root}}/alembic 6 | 7 | # template used to generate migration files 8 | # file_template = %%(rev)s_%%(slug)s 9 | 10 | # max length of characters to apply to the 11 | # "slug" field 12 | #truncate_slug_length = 40 13 | 14 | # set to 'true' to run the environment during 15 | # the 'revision' command, regardless of autogenerate 16 | # revision_environment = false 17 | 18 | sqlalchemy.url = postgresql://calamari:27HbZwr*g@localhost/calamari 19 | 20 | 21 | # Logging configuration 22 | [loggers] 23 | keys = root,sqlalchemy,alembic 24 | 25 | [handlers] 26 | keys = console 27 | 28 | [formatters] 29 | keys = generic 30 | 31 | [logger_root] 32 | level = WARN 33 | handlers = console 34 | qualname = 35 | 36 | [logger_sqlalchemy] 37 | level = WARN 38 | handlers = 39 | qualname = sqlalchemy.engine 40 | 41 | [logger_alembic] 42 | level = INFO 43 | handlers = 44 | qualname = alembic 45 | 46 | [handler_console] 47 | class = StreamHandler 48 | args = (sys.stderr,) 49 | level = NOTSET 50 | formatter = generic 51 | 52 | [formatter_generic] 53 | format = %(levelname)-5.5s [%(name)s] %(message)s 54 | datefmt = %H:%M:%S 55 | -------------------------------------------------------------------------------- /rest-api/calamari_rest/serializers/fields.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | 4 | class BooleanField(serializers.BooleanField): 5 | """ 6 | Version of BooleanField which handles fields which are 1,0 7 | """ 8 | def to_native(self, value): 9 | if isinstance(value, int) and value in [0, 1]: 10 | return bool(value) 11 | else: 12 | super(BooleanField, self).to_native(value) 13 | 14 | 15 | class UuidField(serializers.CharField): 16 | """ 17 | For strings like Ceph service UUIDs and Ceph cluster FSIDs 18 | """ 19 | type_name = "UuidField" 20 | type_label = "uuid string" 21 | 22 | 23 | class EnumField(serializers.CharField): 24 | def __init__(self, mapping, *args, **kwargs): 25 | super(EnumField, self).__init__(*args, **kwargs) 26 | self.mapping = mapping 27 | self.reverse_mapping = dict([(v, k) for (k, v) in self.mapping.items()]) 28 | if self.help_text: 29 | self.help_text += " (one of %s)" % ", ".join(self.mapping.values()) 30 | 31 | def from_native(self, value): 32 | return self.reverse_mapping.get(value, value) 33 | 34 | def to_native(self, value): 35 | return self.mapping.get(value, value) 36 | -------------------------------------------------------------------------------- /vagrant/trusty-build/salt/roots/make_packages.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | build-diamond: 4 | cmd.run: 5 | - user: {{vars.username}} 6 | - name: make deb 7 | - cwd: {{vars.builddir}}/Diamond 8 | - require: 9 | - git: {{vars.gitpath}}/Diamond 10 | 11 | build-repo: 12 | cmd.run: 13 | - user: {{vars.username}} 14 | - name: make trusty 15 | - cwd: {{vars.builddir}}/calamari/repobuild 16 | - require: 17 | - git: {{vars.gitpath}}/calamari 18 | - cmd: build-diamond 19 | 20 | build-calamari-server: 21 | cmd.run: 22 | - user: {{vars.username}} 23 | - name: make dpkg 24 | - cwd: {{vars.builddir}}/calamari 25 | - require: 26 | - git: {{vars.gitpath}}/calamari 27 | 28 | {% if vars.username != 'vagrant' %} 29 | ensure-pkgdest-present: 30 | file.directory: 31 | - user: {{vars.username}} 32 | - name: {{vars.pkgdest}} 33 | {% endif %} 34 | 35 | {% for path in ('calamari/repobuild/calamari-repo-*.tar.gz', 36 | 'calamari-server_*.deb', 37 | 'Diamond/build/diamond_*.deb') %} 38 | 39 | cp-artifacts-to-share {{ path }}: 40 | cmd.run: 41 | - name: cp {{ path }} {{vars.pkgdest}} 42 | - cwd: {{vars.builddir}} 43 | 44 | {% endfor %} 45 | -------------------------------------------------------------------------------- /vagrant/wheezy-build/salt/roots/make_packages.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | build-diamond: 4 | cmd.run: 5 | - user: {{vars.username}} 6 | - name: make deb 7 | - cwd: {{vars.builddir}}/Diamond 8 | - require: 9 | - git: {{vars.gitpath}}/Diamond 10 | 11 | build-repo: 12 | cmd.run: 13 | - user: {{vars.username}} 14 | - name: make wheezy 15 | - cwd: {{vars.builddir}}/calamari/repobuild 16 | - require: 17 | - git: {{vars.gitpath}}/calamari 18 | - cmd: build-diamond 19 | 20 | build-calamari-server: 21 | cmd.run: 22 | - user: {{vars.username}} 23 | - name: make dpkg 24 | - cwd: {{vars.builddir}}/calamari 25 | - require: 26 | - git: {{vars.gitpath}}/calamari 27 | 28 | {% if vars.username != 'vagrant' %} 29 | ensure-pkgdest-present: 30 | file.directory: 31 | - user: {{vars.username}} 32 | - name: {{vars.pkgdest}} 33 | {% endif %} 34 | 35 | {% for path in ('calamari/repobuild/calamari-repo-*.tar.gz', 36 | 'calamari-server_*.deb', 37 | 'Diamond/build/diamond_*.deb') %} 38 | 39 | cp-artifacts-to-share {{ path }}: 40 | cmd.run: 41 | - name: cp {{ path }} {{vars.pkgdest}} 42 | - cwd: {{vars.builddir}} 43 | 44 | {% endfor %} 45 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__event.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//event 2 | ======================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/event 5 | --------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "count": 4, 11 | "previous": null, 12 | "results": [ 13 | { 14 | "message": "Started: Creating pool 'newname'", 15 | "when": "2014-11-06T13:15:15.600-08:00", 16 | "severity": "INFO" 17 | }, 18 | { 19 | "message": "Added server figment002.cluster0.com with 1 monitor service, 4 OSDs", 20 | "when": "2014-11-06T13:15:15.156-08:00", 21 | "severity": "INFO" 22 | }, 23 | { 24 | "message": "Added server figment001.cluster0.com with 1 monitor service, 4 OSDs", 25 | "when": "2014-11-06T13:15:15.116-08:00", 26 | "severity": "INFO" 27 | }, 28 | { 29 | "message": "Added server figment000.cluster0.com with 4 OSDs, 1 monitor service", 30 | "when": "2014-11-06T13:15:05.925-08:00", 31 | "severity": "INFO" 32 | } 33 | ], 34 | "next": null 35 | } 36 | 37 | -------------------------------------------------------------------------------- /vagrant/rhel-build/salt/roots/make_packages.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | build-diamond: 4 | cmd.run: 5 | - user: {{vars.username}} 6 | - name: make rpm 7 | - cwd: {{vars.builddir}}/Diamond 8 | - require: 9 | - git: {{vars.gitpath}}/Diamond 10 | 11 | build-repo: 12 | cmd.run: 13 | - user: {{vars.username}} 14 | - name: make rhel6 15 | - cwd: {{vars.builddir}}/calamari/repobuild 16 | - require: 17 | - git: {{vars.gitpath}}/calamari 18 | - cmd: build-diamond 19 | 20 | build-calamari-server: 21 | cmd.run: 22 | - user: {{vars.username}} 23 | - name: ./build-rpm.sh 24 | - cwd: {{vars.builddir}}/calamari 25 | - require: 26 | - git: {{vars.gitpath}}/calamari 27 | 28 | {% if vars.username != 'vagrant' %} 29 | ensure-pkgdest-present: 30 | file.directory: 31 | - user: {{vars.username}} 32 | - name: {{vars.pkgdest}} 33 | {% endif %} 34 | 35 | {% for path in ('calamari/repobuild/calamari-repo-*.tar.gz', 36 | 'rpmbuild/RPMS/*/calamari-server-*.rpm', 37 | 'Diamond/dist/diamond-*.rpm') %} 38 | 39 | cp-artifacts-to-share {{ path }}: 40 | cmd.run: 41 | - name: cp {{ path }} {{vars.pkgdest}} 42 | - cwd: {{vars.builddir}} 43 | 44 | {% endfor %} 45 | -------------------------------------------------------------------------------- /vagrant/rhel7-build/salt/roots/make_packages.sls: -------------------------------------------------------------------------------- 1 | {% import 'setvars' as vars %} 2 | 3 | build-diamond: 4 | cmd.run: 5 | - user: {{vars.username}} 6 | - name: make rpm 7 | - cwd: {{vars.builddir}}/Diamond 8 | - require: 9 | - git: {{vars.gitpath}}/Diamond 10 | 11 | build-repo: 12 | cmd.run: 13 | - user: {{vars.username}} 14 | - name: make rhel7 15 | - cwd: {{vars.builddir}}/calamari/repobuild 16 | - require: 17 | - git: {{vars.gitpath}}/calamari 18 | - cmd: build-diamond 19 | 20 | build-calamari-server: 21 | cmd.run: 22 | - user: {{vars.username}} 23 | - name: ./build-rpm.sh 24 | - cwd: {{vars.builddir}}/calamari 25 | - require: 26 | - git: {{vars.gitpath}}/calamari 27 | 28 | {% if vars.username != 'vagrant' %} 29 | ensure-pkgdest-present: 30 | file.directory: 31 | - user: {{vars.username}} 32 | - name: {{vars.pkgdest}} 33 | {% endif %} 34 | 35 | {% for path in ('calamari/repobuild/calamari-repo-*.tar.gz', 36 | 'rpmbuild/RPMS/*/calamari-server-*.rpm', 37 | 'Diamond/dist/diamond-*.rpm') %} 38 | 39 | cp-artifacts-to-share {{ path }}: 40 | cmd.run: 41 | - name: cp {{ path }} {{vars.pkgdest}} 42 | - cwd: {{vars.builddir}} 43 | 44 | {% endfor %} 45 | -------------------------------------------------------------------------------- /dev/calamari.conf.template: -------------------------------------------------------------------------------- 1 | 2 | [cthulhu] 3 | 4 | plugin_path = {{calamari_root}}/cthulhu/tests/plugins 5 | salt_config_path = {{calamari_root}}/dev/etc/salt/master 6 | alembic_config_path = {{calamari_root}}/dev/alembic.ini 7 | db_path = postgresql://calamari:27HbZwr*g@localhost/calamari 8 | log_path = {{calamari_root}}/dev/cthulhu.log 9 | log_level = DEBUG 10 | rpc_url = tcp://127.0.0.1:5050 11 | crush_host_type = host 12 | crush_osd_type = osd 13 | cluster_map_retention = 3600 14 | db_log_level = WARN 15 | favorite_timeout_factor = 3 16 | server_timeout_factor = 3 17 | cluster_contact_threshold = 60 18 | emit_events_to_salt_event_bus = True 19 | event_tag_prefix = calamari/ 20 | 21 | [calamari_web] 22 | 23 | log_path = {{calamari_root}}/dev/calamari.log 24 | log_level = DEBUG 25 | db_engine = django.db.backends.postgresql_psycopg2 26 | db_name = calamari 27 | db_user = calamari 28 | db_password = 27HbZwr*g 29 | db_host = localhost 30 | db_port = 5432 31 | secret_key_path = {{calamari_root}}/dev/secret.key 32 | username = {{calamari_user}} 33 | static_root = {{calamari_root}}/webapp/content/ 34 | ssl_key = {{calamari_root}}/dev/calamari-lite.key 35 | ssl_cert = {{calamari_root}}/dev/calamari-lite-bundled.crt 36 | 37 | [graphite] 38 | 39 | root = {{venv}} 40 | storage_path = {{venv}}/storage 41 | -------------------------------------------------------------------------------- /calamari-common/calamari_common/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | import ConfigParser 3 | 4 | try: 5 | import alembic 6 | except ImportError: 7 | alembic = None 8 | else: 9 | import alembic.config 10 | 11 | 12 | class ConfigNotFound(Exception): 13 | pass 14 | 15 | 16 | DEFAULT_CONFIG_PATH = "/etc/calamari/calamari.conf" 17 | CONFIG_PATH_VAR = "CALAMARI_CONFIG" 18 | 19 | 20 | class CalamariConfig(ConfigParser.SafeConfigParser): 21 | def __init__(self): 22 | defaults = {'ssl_key': '/etc/calamari/ssl/private/calamari-lite.key', 23 | 'ssl_cert': '/etc/calamari/ssl/certs/calamari-lite-bundled.crt'} 24 | ConfigParser.SafeConfigParser.__init__(self, defaults=defaults) 25 | 26 | try: 27 | self.path = os.environ[CONFIG_PATH_VAR] 28 | except KeyError: 29 | self.path = DEFAULT_CONFIG_PATH 30 | 31 | if not os.path.exists(self.path): 32 | raise ConfigNotFound("Configuration not found at %s" % self.path) 33 | 34 | self.read(self.path) 35 | 36 | 37 | if alembic is not None: 38 | class AlembicConfig(alembic.config.Config): 39 | def __init__(self): 40 | path = CalamariConfig().get('cthulhu', 'alembic_config_path') 41 | super(AlembicConfig, self).__init__(path) 42 | -------------------------------------------------------------------------------- /doc/calamari_rest/resources/api_example_api_v2_cluster__fsid__mon__mon_id__status.rst: -------------------------------------------------------------------------------- 1 | Examples for api/v2/cluster//mon//status 2 | ====================================================== 3 | 4 | api/v2/cluster/dce20d46-f010-4883-988c-4a6d8bd15793/mon/figment000/status 5 | ------------------------------------------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "election_epoch": 77, 11 | "state": "leader", 12 | "monmap": { 13 | "quorum": [ 14 | 0, 15 | 1, 16 | 2 17 | ], 18 | "created": "2014-11-06T15:14:34.316557", 19 | "modified": "2014-11-06T15:14:34.316541", 20 | "epoch": 0, 21 | "mons": [ 22 | { 23 | "name": "figment000", 24 | "rank": 0, 25 | "addr": "" 26 | }, 27 | { 28 | "name": "figment001", 29 | "rank": 1, 30 | "addr": "" 31 | }, 32 | { 33 | "name": "figment002", 34 | "rank": 2, 35 | "addr": "" 36 | } 37 | ], 38 | "fsid": "dce20d46-f010-4883-988c-4a6d8bd15793" 39 | }, 40 | "rank": 0, 41 | "quorum": [ 42 | 0, 43 | 1, 44 | 2 45 | ] 46 | } 47 | 48 | -------------------------------------------------------------------------------- /doc/development/logging.rst: -------------------------------------------------------------------------------- 1 | 2 | Logging 3 | ======= 4 | 5 | Location of logs 6 | ---------------- 7 | 8 | Logs for calamari and supporting components are located in /var/log/calamari 9 | 10 | How long logs are kept 11 | ---------------------- 12 | In production logs are rotated daily and kept for seven days. 13 | 14 | Summary of log file contents 15 | ---------------------------- 16 | 17 | - http_access.log - information about http requests 18 | - http_error.log - what errors the http server handles 19 | - calamari.log - contains information about cluster monitors and errors in the API layer 20 | - cthulhu.log - contains information about the state of the ceph-clusters that it has been configured to know about 21 | 22 | 23 | Troubleshooting 24 | --------------- 25 | 26 | Increase the log level of services in ``/etc/calamari/calamari.conf`` with the ``cthulhu.log_level`` 27 | and ``calamari_web.log_level`` settings. You can see the log paths in the same config file. You usually 28 | want 'debug' level, but don't forget to turn it back to 'warn' when you're done. 29 | 30 | After changing the level, restart the services: 31 | 32 | :: 33 | 34 | sudo supervisorctl restart cthulhu 35 | sudo service apache2 restart 36 | 37 | For ultra-mega SQL verbosity you can also set cthulhu.db_log_level 38 | -------------------------------------------------------------------------------- /doc/operations/troubleshooting.rst: -------------------------------------------------------------------------------- 1 | 2 | Troubleshooting Calamari Server 3 | =============================== 4 | 5 | Note: the guidance here is about troubleshooting the Calamari monitoring layer, not 6 | Ceph in general, see the `ceph documentation `_ for 7 | more general issues. 8 | 9 | **I have followed the instructions in :doc:`minion_connect`, but my servers are 10 | not appearing in the Calamari User Interface** 11 | 12 | * Check that ``/etc/salt/minion.d/calamari.conf`` on the Ceph server specifies 13 | the correct address for the Calamari server. 14 | * Check for errors in ``/var/log/salt/minion`` on the Ceph server. 15 | 16 | **My Ceph cluster has been detected by Calamari, but some of the dashboard 17 | widgets like IOPs and Usage are blank** 18 | 19 | * Check that the Calamari version of diamond is installed on all the Ceph 20 | servers acting as mons. 21 | * Using your web browser, visit the graphite dashboard at ``/graphite/dashboard/`` 22 | on the Calamari server. Check that statistics with paths starting ``ceph.cluster`` 23 | are present. 24 | 25 | **The Calamari user interface is displaying a 500 error** 26 | 27 | * Check ``/var/log/calamari/calamari.log`` for a detailed error message and 28 | backtrace, and seek help via the mailing list or issue tracker. 29 | 30 | -------------------------------------------------------------------------------- /crush_map_repr_before.txt: -------------------------------------------------------------------------------- 1 | # begin crush map 2 | tunable choose_local_tries 0 3 | tunable choose_local_fallback_tries 0 4 | tunable choose_total_tries 50 5 | tunable chooseleaf_descend_once 1 6 | tunable straw_calc_version 1 7 | 8 | # devices 9 | device 0 osd.0 10 | 11 | # types 12 | type 0 osd 13 | type 1 host 14 | type 2 chassis 15 | type 3 rack 16 | type 4 row 17 | type 5 pdu 18 | type 6 pod 19 | type 7 room 20 | type 8 datacenter 21 | type 9 region 22 | type 10 root 23 | 24 | # buckets 25 | host vagrant-ubuntu-trusty-64 { 26 | id -2 # do not change unnecessarily 27 | # weight 0.038 28 | alg straw 29 | hash 0 # rjenkins1 30 | item osd.0 weight 0.038 31 | } 32 | root default { 33 | id -1 # do not change unnecessarily 34 | # weight 0.038 35 | alg straw 36 | hash 0 # rjenkins1 37 | item vagrant-ubuntu-trusty-64 weight 0.038 38 | } 39 | 40 | # rules 41 | rule replicated_ruleset { 42 | ruleset 0 43 | type replicated 44 | min_size 1 45 | max_size 10 46 | step take default 47 | step chooseleaf firstn 0 type host 48 | step emit 49 | } 50 | rule racky { 51 | ruleset 1 52 | type replicated 53 | min_size 1 54 | max_size 10 55 | step take default 56 | step chooseleaf firstn 0 type rack 57 | step emit 58 | } 59 | 60 | # end crush map 61 | -------------------------------------------------------------------------------- /dev/configure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Helper script to populate config file paths 5 | with the location of this script. 6 | """ 7 | import getpass 8 | import os 9 | from jinja2 import Template 10 | 11 | TEMPLATES = ["dev/etc/salt/master.template", 12 | "dev/calamari.conf.template", 13 | "dev/alembic.ini.template", 14 | "tests/test.conf.template"] 15 | 16 | calamari_root = "/" + os.path.join(*(os.path.abspath(__file__).split(os.sep)[0:-2])) 17 | calamari_user = getpass.getuser() 18 | venv = os.environ.get('VIRTUAL_ENV', os.path.join(calamari_root, 'env')) 19 | 20 | print "Calamari repo is at: %s, user is %s, venv %s" % \ 21 | (calamari_root, calamari_user, venv) 22 | 23 | for template in TEMPLATES: 24 | template = os.path.join(calamari_root, template) 25 | output_file = template[0:-len(".template")] 26 | print "Writing %s" % output_file 27 | template_str = open(template).read() 28 | output_str = Template(template_str).render( 29 | calamari_root=calamari_root, 30 | calamari_user=calamari_user, 31 | venv=venv, 32 | ) 33 | open(output_file, 'w').write(output_str) 34 | 35 | print """Complete. Now run: 36 | 1. `CALAMARI_CONFIG=dev/calamari.conf calamari-ctl --devmode initialize` 37 | 2. supervisord -c dev/supervisord.conf -n 38 | """ 39 | -------------------------------------------------------------------------------- /doc/development/communications.rst: -------------------------------------------------------------------------------- 1 | 2 | Communication between Ceph servers and Calamari server 3 | ====================================================== 4 | 5 | This page is about the messages/events we send via salt, from the salt minions 6 | running on Ceph servers to the salt master running on the Calamari server. Cthulhu 7 | listens to these events. This isn't a syntax specification, it isn't that formal. 8 | 9 | The TLDR is: 10 | 11 | - All Ceph servers send a periodic heartbeat describing which Ceph services 12 | are running, and other properties of the server like the Ceph version installed. 13 | This is the ``ceph/server/`` event tag. 14 | - Servers running the mon service send a periodic heartbeat describing the Ceph 15 | cluster, primarily giving a vector of versions for the cluster maps. This is 16 | the ``ceph/cluster/`` event tag. 17 | - When Cthulhu sees mention of a cluster map version more recent than the 18 | one it has in hand, it executes a job on one of the mons to retrieve 19 | the full copy of that version of the cluster map. This is the ``ceph.get_cluster_object`` 20 | function. 21 | - When Cthulhu is executing a :doc:`user request 2 | ================================= 3 | 4 | api/v2/server/figment000.cluster0.com 5 | ------------------------------------- 6 | 7 | .. code-block:: json 8 | 9 | { 10 | "managed": true, 11 | "last_contact": "2014-11-06T21:15:15.156841+00:00", 12 | "hostname": "figment000", 13 | "fqdn": "figment000.cluster0.com", 14 | "boot_time": "1970-01-02T10:17:36+00:00", 15 | "services": [ 16 | { 17 | "running": true, 18 | "type": "osd", 19 | "id": "3", 20 | "fsid": "dce20d46-f010-4883-988c-4a6d8bd15793" 21 | }, 22 | { 23 | "running": true, 24 | "type": "osd", 25 | "id": "0", 26 | "fsid": "dce20d46-f010-4883-988c-4a6d8bd15793" 27 | }, 28 | { 29 | "running": true, 30 | "type": "mon", 31 | "id": "figment000", 32 | "fsid": "dce20d46-f010-4883-988c-4a6d8bd15793" 33 | }, 34 | { 35 | "running": true, 36 | "type": "osd", 37 | "id": "1", 38 | "fsid": "dce20d46-f010-4883-988c-4a6d8bd15793" 39 | }, 40 | { 41 | "running": true, 42 | "type": "osd", 43 | "id": "2", 44 | "fsid": "dce20d46-f010-4883-988c-4a6d8bd15793" 45 | } 46 | ], 47 | "ceph_version": "0.67.8-simulator" 48 | } 49 | 50 | -------------------------------------------------------------------------------- /doc/development/coverage.rst: -------------------------------------------------------------------------------- 1 | 2 | Code coverage 3 | ============= 4 | 5 | Procedure 6 | --------- 7 | 8 | 1. Ensure that you have the `coverage` module installed. 9 | 2. Create a `sitecustomize.py` file in your virtualenv's site-packages folder, containing: 10 | 11 | :: 12 | 13 | import coverage 14 | coverage.process_startup() 15 | 16 | 3. Set the `COVERAGE_PROCESS_START` environment variable 17 | 18 | :: 19 | 20 | calamari $ export COVERAGE_PROCESS_START=`pwd`/coverage.conf 21 | 22 | 4. Run your Calamari server in the shell where you've got `COVERAGE_PROCESS_START` set: 23 | 24 | :: 25 | 26 | calamari $ supervisord -c ./supervisord.conf -n 27 | 28 | 5. At some point in the future, Ctrl-C your supervisor instance. Coverage should have 29 | left a bunch of `.coverage...