diff options
| author | Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> | 2016-09-27 11:20:29 +0200 |
|---|---|---|
| committer | Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> | 2016-09-27 11:20:29 +0200 |
| commit | 25de0db933521881673c3889865815abc82b75e7 (patch) | |
| tree | a182ea38e97faed13bc0ea94a9bbe641b3377dcf | |
| parent | e7ae83f5cf81b103f3f1e46a64a1e0053dc4ba74 (diff) | |
| parent | a40b517c4f20be94bc007e83541e18a3da85b5f5 (diff) | |
| download | rabbitmq-server-git-25de0db933521881673c3889865815abc82b75e7.tar.gz | |
Merge branch 'stable' into rabbitmq-management-236
86 files changed, 1280 insertions, 7613 deletions
diff --git a/.gitignore b/.gitignore index 7582deb64e..52a0257b62 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,6 @@ /test/ct.cover.spec /xrefr -PACKAGES/ - rabbit.d # Generated sources files. @@ -35,13 +33,6 @@ docs/rabbitmq-service.man.xml docs/rabbitmqctl.1 docs/rabbitmqctl.1.man.xml -# Source distribution. -rabbitmq-server-*/ -rabbitmq-server-*.tar.gz -rabbitmq-server-*.tar.bz2 -rabbitmq-server-*.tar.xz -rabbitmq-server-*.zip - # Dialyzer *.plt @@ -1,10 +1,8 @@ PROJECT = rabbit VERSION ?= $(call get_app_version,src/$(PROJECT).app.src) -# Release artifacts are put in $(PACKAGES_DIR). -PACKAGES_DIR ?= $(abspath PACKAGES) - -DEPS = ranch $(PLUGINS) +DEPS = ranch rabbit_common +TEST_DEPS = rabbitmq_ct_helpers amqp_client meck proper define usage_xml_to_erl $(subst __,_,$(patsubst $(DOCS_DIR)/rabbitmq%.1.xml, src/rabbit_%_usage.erl, $(subst -,_,$(1)))) @@ -33,44 +31,6 @@ ERLANG_MK_REPO = https://github.com/rabbitmq/erlang.mk.git ERLANG_MK_COMMIT = rabbitmq-tmp include rabbitmq-components.mk - -# List of plugins to include in a RabbitMQ release. -DISTRIBUTED_DEPS := rabbitmq_amqp1_0 \ - rabbitmq_auth_backend_ldap \ - rabbitmq_auth_mechanism_ssl \ - rabbitmq_consistent_hash_exchange \ - rabbitmq_event_exchange \ - rabbitmq_federation \ - rabbitmq_federation_management \ - rabbitmq_jms_topic_exchange \ - rabbitmq_management \ - rabbitmq_management_agent \ - rabbitmq_management_visualiser \ - rabbitmq_mqtt \ - rabbitmq_recent_history_exchange \ - rabbitmq_sharding \ - rabbitmq_shovel \ - rabbitmq_shovel_management \ - rabbitmq_stomp \ - rabbitmq_top \ - rabbitmq_tracing \ - rabbitmq_trust_store \ - rabbitmq_web_dispatch \ - rabbitmq_web_stomp \ - rabbitmq_web_stomp_examples - -ifneq ($(IS_DEP),1) -ifneq ($(filter source-dist packages package-%,$(MAKECMDGOALS)),) -DEPS += $(DISTRIBUTED_DEPS) -endif -ifneq ($(wildcard git-revisions.txt),) -DEPS += $(DISTRIBUTED_DEPS) -endif -endif - -# FIXME: Remove rabbitmq_test as TEST_DEPS from here for now. -TEST_DEPS := amqp_client meck proper $(filter-out rabbitmq_test,$(TEST_DEPS)) - include erlang.mk # -------------------------------------------------------------------- @@ -156,280 +116,3 @@ distclean:: distclean-manpages distclean-manpages:: $(gen_verbose) rm -f $(MANPAGES) $(WEB_MANPAGES) - -# -------------------------------------------------------------------- -# Distribution. -# -------------------------------------------------------------------- - -.PHONY: source-dist clean-source-dist - -SOURCE_DIST_BASE ?= rabbitmq-server -SOURCE_DIST_SUFFIXES ?= tar.xz zip -SOURCE_DIST ?= $(PACKAGES_DIR)/$(SOURCE_DIST_BASE)-$(VERSION) - -# The first source distribution file is used by packages: if the archive -# type changes, you must update all packages' Makefile. -SOURCE_DIST_FILES = $(addprefix $(SOURCE_DIST).,$(SOURCE_DIST_SUFFIXES)) - -.PHONY: $(SOURCE_DIST_FILES) - -source-dist: $(SOURCE_DIST_FILES) - @: - -RSYNC ?= rsync -RSYNC_V_0 = -RSYNC_V_1 = -v -RSYNC_V_2 = -v -RSYNC_V = $(RSYNC_V_$(V)) -RSYNC_FLAGS += -a $(RSYNC_V) \ - --exclude '.sw?' --exclude '.*.sw?' \ - --exclude '*.beam' \ - --exclude '*.pyc' \ - --exclude '.git*' \ - --exclude '.hg*' \ - --exclude '.travis.yml' \ - --exclude '.*.plt' \ - --exclude '$(notdir $(ERLANG_MK_TMP))' \ - --exclude 'ebin' \ - --exclude 'packaging' \ - --exclude 'erl_crash.dump' \ - --exclude 'MnesiaCore.*' \ - --exclude 'cover/' \ - --exclude 'deps/' \ - --exclude '$(notdir $(DEPS_DIR))/' \ - --exclude 'plugins/' \ - --exclude '$(notdir $(DIST_DIR))/' \ - --exclude '/$(notdir $(PACKAGES_DIR))/' \ - --exclude '/PACKAGES/' \ - --exclude '/cowboy/doc/' \ - --exclude '/cowboy/examples/' \ - --exclude '/rabbitmq_amqp1_0/test/swiftmq/build/'\ - --exclude '/rabbitmq_amqp1_0/test/swiftmq/swiftmq*'\ - --exclude '/rabbitmq_mqtt/test/build/' \ - --exclude '/rabbitmq_mqtt/test/test_client/'\ - --delete \ - --delete-excluded - -TAR ?= tar -TAR_V_0 = -TAR_V_1 = -v -TAR_V_2 = -v -TAR_V = $(TAR_V_$(V)) - -GZIP ?= gzip -BZIP2 ?= bzip2 -XZ ?= xz - -ZIP ?= zip -ZIP_V_0 = -q -ZIP_V_1 = -ZIP_V_2 = -ZIP_V = $(ZIP_V_$(V)) - -.PHONY: $(SOURCE_DIST) - -$(SOURCE_DIST): $(ERLANG_MK_RECURSIVE_DEPS_LIST) - $(verbose) mkdir -p $(dir $@) - $(gen_verbose) $(RSYNC) $(RSYNC_FLAGS) ./ $@/ - $(verbose) sed -E -i.bak \ - -e 's/[{]vsn[[:blank:]]*,[^}]+}/{vsn, "$(VERSION)"}/' \ - $@/src/$(PROJECT).app.src && \ - rm $@/src/$(PROJECT).app.src.bak - $(verbose) cat packaging/common/LICENSE.head > $@/LICENSE - $(verbose) mkdir -p $@/deps/licensing - $(verbose) for dep in $$(cat $(ERLANG_MK_RECURSIVE_DEPS_LIST) | grep -v '/$(PROJECT)$$' | LC_COLLATE=C sort); do \ - $(RSYNC) $(RSYNC_FLAGS) \ - $$dep \ - $@/deps; \ - if test -f $@/deps/$$(basename $$dep)/erlang.mk && \ - test "$$(wc -l $@/deps/$$(basename $$dep)/erlang.mk | awk '{print $$1;}')" = "1" && \ - grep -qs -E "^[[:blank:]]*include[[:blank:]]+(erlang\.mk|.*/erlang\.mk)$$" $@/deps/$$(basename $$dep)/erlang.mk; then \ - echo "include ../../erlang.mk" > $@/deps/$$(basename $$dep)/erlang.mk; \ - fi; \ - sed -E -i.bak "s|^[[:blank:]]*include[[:blank:]]+\.\./.*erlang.mk$$|include ../../erlang.mk|" \ - $@/deps/$$(basename $$dep)/Makefile && \ - rm $@/deps/$$(basename $$dep)/Makefile.bak; \ - if test -f "$$dep/license_info"; then \ - cp "$$dep/license_info" "$@/deps/licensing/license_info_$$(basename "$$dep")"; \ - cat "$$dep/license_info" >> $@/LICENSE; \ - fi; \ - find "$$dep" -maxdepth 1 -name 'LICENSE-*' -exec cp '{}' $@/deps/licensing \; ; \ - done - $(verbose) cat packaging/common/LICENSE.tail >> $@/LICENSE - $(verbose) find $@/deps/licensing -name 'LICENSE-*' -exec cp '{}' $@ \; - $(verbose) for file in $$(find $@ -name '*.app.src'); do \ - sed -E -i.bak -e 's/[{]vsn[[:blank:]]*,[[:blank:]]*""[[:blank:]]*}/{vsn, "$(VERSION)"}/' $$file; \ - rm $$file.bak; \ - done - $(verbose) echo "$(PROJECT) $$(git rev-parse HEAD) $$(git describe --tags --exact-match 2>/dev/null || git symbolic-ref -q --short HEAD)" > $@/git-revisions.txt - $(verbose) for dep in $$(cat $(ERLANG_MK_RECURSIVE_DEPS_LIST)); do \ - (cd $$dep; echo "$$(basename "$$dep") $$(git rev-parse HEAD) $$(git describe --tags --exact-match 2>/dev/null || git symbolic-ref -q --short HEAD)") >> $@/git-revisions.txt; \ - done - -# TODO: Fix file timestamps to have reproducible source archives. -# $(verbose) find $@ -not -name 'git-revisions.txt' -print0 | xargs -0 touch -r $@/git-revisions.txt - -$(SOURCE_DIST).tar.gz: $(SOURCE_DIST) - $(gen_verbose) cd $(dir $(SOURCE_DIST)) && \ - find $(notdir $(SOURCE_DIST)) -print0 | LC_COLLATE=C sort -z | \ - xargs -0 $(TAR) $(TAR_V) --no-recursion -cf - | \ - $(GZIP) --best > $@ - -$(SOURCE_DIST).tar.bz2: $(SOURCE_DIST) - $(gen_verbose) cd $(dir $(SOURCE_DIST)) && \ - find $(notdir $(SOURCE_DIST)) -print0 | LC_COLLATE=C sort -z | \ - xargs -0 $(TAR) $(TAR_V) --no-recursion -cf - | \ - $(BZIP2) > $@ - -$(SOURCE_DIST).tar.xz: $(SOURCE_DIST) - $(gen_verbose) cd $(dir $(SOURCE_DIST)) && \ - find $(notdir $(SOURCE_DIST)) -print0 | LC_COLLATE=C sort -z | \ - xargs -0 $(TAR) $(TAR_V) --no-recursion -cf - | \ - $(XZ) > $@ - -$(SOURCE_DIST).zip: $(SOURCE_DIST) - $(verbose) rm -f $@ - $(gen_verbose) cd $(dir $(SOURCE_DIST)) && \ - find $(notdir $(SOURCE_DIST)) -print0 | LC_COLLATE=C sort -z | \ - xargs -0 $(ZIP) $(ZIP_V) $@ - -clean:: clean-source-dist - -clean-source-dist: - $(gen_verbose) rm -rf -- $(SOURCE_DIST_BASE)-* - -# -------------------------------------------------------------------- -# Installation. -# -------------------------------------------------------------------- - -.PHONY: install install-erlapp install-scripts install-bin install-man -.PHONY: install-windows install-windows-erlapp install-windows-scripts install-windows-docs - -DESTDIR ?= - -PREFIX ?= /usr/local -WINDOWS_PREFIX ?= rabbitmq-server-windows-$(VERSION) - -MANDIR ?= $(PREFIX)/share/man -RMQ_ROOTDIR ?= $(PREFIX)/lib/erlang -RMQ_BINDIR ?= $(RMQ_ROOTDIR)/bin -RMQ_LIBDIR ?= $(RMQ_ROOTDIR)/lib -RMQ_ERLAPP_DIR ?= $(RMQ_LIBDIR)/rabbitmq_server-$(VERSION) - -SCRIPTS = rabbitmq-defaults \ - rabbitmq-env \ - rabbitmq-server \ - rabbitmqctl \ - rabbitmq-plugins - -WINDOWS_SCRIPTS = rabbitmq-defaults.bat \ - rabbitmq-echopid.bat \ - rabbitmq-env.bat \ - rabbitmq-plugins.bat \ - rabbitmq-server.bat \ - rabbitmq-service.bat \ - rabbitmqctl.bat - -UNIX_TO_DOS ?= todos - -inst_verbose_0 = @echo " INST " $@; -inst_verbose = $(inst_verbose_$(V)) - -install: install-erlapp install-scripts - -install-erlapp: dist - $(verbose) mkdir -p $(DESTDIR)$(RMQ_ERLAPP_DIR) - $(inst_verbose) cp -r include ebin plugins LICENSE* INSTALL \ - $(DESTDIR)$(RMQ_ERLAPP_DIR) - $(verbose) echo "Put your EZs here and use rabbitmq-plugins to enable them." \ - > $(DESTDIR)$(RMQ_ERLAPP_DIR)/plugins/README - - @# rabbitmq-common provides headers too: copy them to - @# rabbitmq_server/include. - $(verbose) cp -r $(DEPS_DIR)/rabbit_common/include $(DESTDIR)$(RMQ_ERLAPP_DIR) - -install-scripts: - $(verbose) mkdir -p $(DESTDIR)$(RMQ_ERLAPP_DIR)/sbin - $(inst_verbose) for script in $(SCRIPTS); do \ - cp "scripts/$$script" "$(DESTDIR)$(RMQ_ERLAPP_DIR)/sbin"; \ - chmod 0755 "$(DESTDIR)$(RMQ_ERLAPP_DIR)/sbin/$$script"; \ - done - -# FIXME: We do symlinks to scripts in $(RMQ_ERLAPP_DIR))/sbin but this -# code assumes a certain hierarchy to make relative symlinks. -install-bin: install-scripts - $(verbose) mkdir -p $(DESTDIR)$(RMQ_BINDIR) - $(inst_verbose) for script in $(SCRIPTS); do \ - test -e $(DESTDIR)$(RMQ_BINDIR)/$$script || \ - ln -sf ../lib/$(notdir $(RMQ_ERLAPP_DIR))/sbin/$$script \ - $(DESTDIR)$(RMQ_BINDIR)/$$script; \ - done - -install-man: manpages - $(inst_verbose) sections=$$(ls -1 docs/*.[1-9] \ - | sed -E 's/.*\.([1-9])$$/\1/' | uniq | sort); \ - for section in $$sections; do \ - mkdir -p $(DESTDIR)$(MANDIR)/man$$section; \ - for manpage in $(DOCS_DIR)/*.$$section; do \ - gzip < $$manpage \ - > $(DESTDIR)$(MANDIR)/man$$section/$$(basename $$manpage).gz; \ - done; \ - done - -install-windows: install-windows-erlapp install-windows-scripts install-windows-docs - -install-windows-erlapp: dist - $(verbose) mkdir -p $(DESTDIR)$(WINDOWS_PREFIX) - $(inst_verbose) cp -r include ebin plugins LICENSE* INSTALL \ - $(DESTDIR)$(WINDOWS_PREFIX) - $(verbose) echo "Put your EZs here and use rabbitmq-plugins.bat to enable them." \ - > $(DESTDIR)$(WINDOWS_PREFIX)/plugins/README.txt - $(verbose) $(UNIX_TO_DOS) $(DESTDIR)$(WINDOWS_PREFIX)/plugins/README.txt - -# rabbitmq-common provides headers too: copy them to -# rabbitmq_server/include. - $(verbose) cp -r $(DEPS_DIR)/rabbit_common/include $(DESTDIR)$(WINDOWS_PREFIX) - -install-windows-scripts: - $(verbose) mkdir -p $(DESTDIR)$(WINDOWS_PREFIX)/sbin - $(inst_verbose) for script in $(WINDOWS_SCRIPTS); do \ - cp "scripts/$$script" "$(DESTDIR)$(WINDOWS_PREFIX)/sbin"; \ - chmod 0755 "$(DESTDIR)$(WINDOWS_PREFIX)/sbin/$$script"; \ - done - -install-windows-docs: install-windows-erlapp - $(verbose) mkdir -p $(DESTDIR)$(WINDOWS_PREFIX)/etc - $(inst_verbose) xmlto -o . xhtml-nochunks docs/rabbitmq-service.xml - $(verbose) elinks -dump -no-references -no-numbering rabbitmq-service.html \ - > $(DESTDIR)$(WINDOWS_PREFIX)/readme-service.txt - $(verbose) rm rabbitmq-service.html - $(verbose) cp docs/rabbitmq.config.example $(DESTDIR)$(WINDOWS_PREFIX)/etc - $(verbose) for file in $(DESTDIR)$(WINDOWS_PREFIX)/readme-service.txt \ - $(DESTDIR)$(WINDOWS_PREFIX)/LICENSE* $(DESTDIR)$(WINDOWS_PREFIX)/INSTALL \ - $(DESTDIR)$(WINDOWS_PREFIX)/etc/rabbitmq.config.example; do \ - $(UNIX_TO_DOS) "$$file"; \ - case "$$file" in \ - *.txt) ;; \ - *.example) ;; \ - *) mv "$$file" "$$file.txt" ;; \ - esac; \ - done - -# -------------------------------------------------------------------- -# Packaging. -# -------------------------------------------------------------------- - -.PHONY: packages package-deb \ - package-rpm package-rpm-fedora package-rpm-suse \ - package-windows package-standalone-macosx \ - package-generic-unix - -# This variable is exported so sub-make instances know where to find the -# archive. -PACKAGES_SOURCE_DIST_FILE ?= $(firstword $(SOURCE_DIST_FILES)) - -packages package-deb package-rpm package-rpm-fedora \ -package-rpm-suse package-windows package-standalone-macosx \ -package-generic-unix: $(PACKAGES_SOURCE_DIST_FILE) - $(verbose) $(MAKE) -C packaging $@ \ - SOURCE_DIST_FILE=$(abspath $(PACKAGES_SOURCE_DIST_FILE)) diff --git a/docs/rabbitmq.config.example b/docs/rabbitmq.config.example index f7477abe61..4d376d953a 100644 --- a/docs/rabbitmq.config.example +++ b/docs/rabbitmq.config.example @@ -161,7 +161,7 @@ %% Set the default AMQP heartbeat delay (in seconds). %% - %% {heartbeat, 600}, + %% {heartbeat, 60}, %% Set the max permissible size of an AMQP frame (in bytes). %% diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml index ec864af6cf..d9a9991ea3 100644 --- a/docs/rabbitmqctl.1.xml +++ b/docs/rabbitmqctl.1.xml @@ -749,9 +749,7 @@ <varlistentry> <term> - <cmdsynopsis> - <command>authenticate_user</command> <arg choice="req"><replaceable>username</replaceable></arg> <arg choice="req"><replaceable>password</replaceable></arg> - </cmdsynopsis> + <cmdsynopsis><command>authenticate_user</command> <arg choice="req"><replaceable>username</replaceable></arg> <arg choice="req"><replaceable>password</replaceable></arg></cmdsynopsis> </term> <listitem> <variablelist> @@ -1237,7 +1235,9 @@ <variablelist> <varlistentry role="usage-has-option-list"> - <term><cmdsynopsis><command>list_queues</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="opt" role="usage-option-list"><replaceable>queueinfoitem</replaceable> ...</arg></cmdsynopsis></term> + <term> + <cmdsynopsis><command>list_queues</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <group choice="opt"><arg>--offline</arg><arg>--online</arg><arg>--local</arg></group> <arg choice="opt" role="usage-option-list"><replaceable>queueinfoitem</replaceable> ...</arg></cmdsynopsis> + </term> <listitem> <para> Returns queue details. Queue details of the <command>/</command> virtual host @@ -1245,6 +1245,39 @@ override this default. </para> <para> + Displayed queues can be filtered by their status or + location using one of the following mutually exclusive + options: + <variablelist> + <varlistentry> + <term><cmdsynopsis><arg choice="opt">--offline</arg></cmdsynopsis></term> + <listitem> + <para> + List only those durable queues that are not + currently available (more specifically, their master node isn't). + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><cmdsynopsis><arg choice="opt">--online</arg></cmdsynopsis></term> + <listitem> + <para> + List queues that are currently available (their master node is). + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><cmdsynopsis><arg choice="opt">--local</arg></cmdsynopsis></term> + <listitem> + <para> + List only those queues whose master process is + located on the current node. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + <para> The <command>queueinfoitem</command> parameter is used to indicate which queue information items to include in the results. The column order in the results will match the order of the parameters. diff --git a/docs/usage.xsl b/docs/usage.xsl index 586f830327..0d3cb6f235 100644 --- a/docs/usage.xsl +++ b/docs/usage.xsl @@ -8,7 +8,7 @@ encoding="UTF-8" indent="no"/> <xsl:strip-space elements="*"/> -<xsl:preserve-space elements="cmdsynopsis arg" /> +<xsl:preserve-space elements="cmdsynopsis arg group" /> <xsl:template match="/"> <!-- Pull out cmdsynopsis to show the command usage line. -->%% Generated, do not edit! @@ -68,6 +68,14 @@ usage() -> %QUOTE%Usage: <!-- Don't show anything else in command usage --> <xsl:template match="text()" mode="command-usage"/> +<xsl:template match="group[@choice='opt']"> + <xsl:text>[</xsl:text> + <xsl:for-each select="arg"> + <xsl:apply-templates/> + <xsl:if test="not(position() = last())"><xsl:text>|</xsl:text></xsl:if> + </xsl:for-each> + <xsl:text>]</xsl:text> +</xsl:template> <xsl:template match="arg[@choice='opt']">[<xsl:apply-templates/>]</xsl:template> <xsl:template match="replaceable"><<xsl:value-of select="."/>></xsl:template> @@ -12,11 +12,11 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.PHONY: all app deps search rel docs install-docs check tests clean distclean help erlang-mk +.PHONY: all app apps deps search rel docs install-docs check tests clean distclean help erlang-mk ERLANG_MK_FILENAME := $(realpath $(lastword $(MAKEFILE_LIST))) -ERLANG_MK_VERSION = 2.0.0-pre.2-76-g427cfb8 +ERLANG_MK_VERSION = 2.0.0-pre.2-144-g647ffd1 # Core configuration. @@ -24,6 +24,7 @@ PROJECT ?= $(notdir $(CURDIR)) PROJECT := $(strip $(PROJECT)) PROJECT_VERSION ?= rolling +PROJECT_MOD ?= $(PROJECT)_app # Verbosity. @@ -109,8 +110,8 @@ help:: " all Run deps, app and rel targets in that order" \ " app Compile the project" \ " deps Fetch dependencies (if needed) and compile them" \ - " fetch-deps Fetch dependencies (if needed) without compiling them" \ - " list-deps Fetch dependencies (if needed) and list them" \ + " fetch-deps Fetch dependencies recursively (if needed) without compiling them" \ + " list-deps List dependencies recursively on stdout" \ " search q=... Search for a package in the built-in index" \ " rel Build a release for this project, if applicable" \ " docs Build the documentation for this project" \ @@ -283,7 +284,7 @@ pkg_apns_description = Apple Push Notification Server for Erlang pkg_apns_homepage = http://inaka.github.com/apns4erl pkg_apns_fetch = git pkg_apns_repo = https://github.com/inaka/apns4erl -pkg_apns_commit = 1.0.4 +pkg_apns_commit = master PACKAGES += azdht pkg_azdht_name = azdht @@ -387,7 +388,7 @@ pkg_bitcask_description = because you need another a key/value storage engine pkg_bitcask_homepage = https://github.com/basho/bitcask pkg_bitcask_fetch = git pkg_bitcask_repo = https://github.com/basho/bitcask -pkg_bitcask_commit = master +pkg_bitcask_commit = develop PACKAGES += bitstore pkg_bitstore_name = bitstore @@ -405,14 +406,6 @@ pkg_bootstrap_fetch = git pkg_bootstrap_repo = https://github.com/schlagert/bootstrap pkg_bootstrap_commit = master -PACKAGES += boss -pkg_boss_name = boss -pkg_boss_description = Erlang web MVC, now featuring Comet -pkg_boss_homepage = https://github.com/ChicagoBoss/ChicagoBoss -pkg_boss_fetch = git -pkg_boss_repo = https://github.com/ChicagoBoss/ChicagoBoss -pkg_boss_commit = master - PACKAGES += boss_db pkg_boss_db_name = boss_db pkg_boss_db_description = BossDB: a sharded, caching, pooling, evented ORM for Erlang @@ -421,6 +414,14 @@ pkg_boss_db_fetch = git pkg_boss_db_repo = https://github.com/ErlyORM/boss_db pkg_boss_db_commit = master +PACKAGES += boss +pkg_boss_name = boss +pkg_boss_description = Erlang web MVC, now featuring Comet +pkg_boss_homepage = https://github.com/ChicagoBoss/ChicagoBoss +pkg_boss_fetch = git +pkg_boss_repo = https://github.com/ChicagoBoss/ChicagoBoss +pkg_boss_commit = master + PACKAGES += brod pkg_brod_name = brod pkg_brod_description = Kafka client in Erlang @@ -459,7 +460,7 @@ pkg_cake_description = Really simple terminal colorization pkg_cake_homepage = https://github.com/darach/cake-erl pkg_cake_fetch = git pkg_cake_repo = https://github.com/darach/cake-erl -pkg_cake_commit = v0.1.2 +pkg_cake_commit = master PACKAGES += carotene pkg_carotene_name = carotene @@ -517,6 +518,14 @@ pkg_chronos_fetch = git pkg_chronos_repo = https://github.com/lehoff/chronos pkg_chronos_commit = master +PACKAGES += chumak +pkg_chumak_name = chumak +pkg_chumak_description = Pure Erlang implementation of ZeroMQ Message Transport Protocol. +pkg_chumak_homepage = http://choven.ca +pkg_chumak_fetch = git +pkg_chumak_repo = https://github.com/chovencorp/chumak +pkg_chumak_commit = master + PACKAGES += cl pkg_cl_name = cl pkg_cl_description = OpenCL binding for Erlang @@ -557,13 +566,13 @@ pkg_cloudi_service_api_requests_fetch = git pkg_cloudi_service_api_requests_repo = https://github.com/CloudI/cloudi_service_api_requests pkg_cloudi_service_api_requests_commit = master -PACKAGES += cloudi_service_db -pkg_cloudi_service_db_name = cloudi_service_db -pkg_cloudi_service_db_description = CloudI Database (in-memory/testing/generic) -pkg_cloudi_service_db_homepage = http://cloudi.org/ -pkg_cloudi_service_db_fetch = git -pkg_cloudi_service_db_repo = https://github.com/CloudI/cloudi_service_db -pkg_cloudi_service_db_commit = master +PACKAGES += cloudi_service_db_cassandra_cql +pkg_cloudi_service_db_cassandra_cql_name = cloudi_service_db_cassandra_cql +pkg_cloudi_service_db_cassandra_cql_description = Cassandra CQL CloudI Service +pkg_cloudi_service_db_cassandra_cql_homepage = http://cloudi.org/ +pkg_cloudi_service_db_cassandra_cql_fetch = git +pkg_cloudi_service_db_cassandra_cql_repo = https://github.com/CloudI/cloudi_service_db_cassandra_cql +pkg_cloudi_service_db_cassandra_cql_commit = master PACKAGES += cloudi_service_db_cassandra pkg_cloudi_service_db_cassandra_name = cloudi_service_db_cassandra @@ -573,14 +582,6 @@ pkg_cloudi_service_db_cassandra_fetch = git pkg_cloudi_service_db_cassandra_repo = https://github.com/CloudI/cloudi_service_db_cassandra pkg_cloudi_service_db_cassandra_commit = master -PACKAGES += cloudi_service_db_cassandra_cql -pkg_cloudi_service_db_cassandra_cql_name = cloudi_service_db_cassandra_cql -pkg_cloudi_service_db_cassandra_cql_description = Cassandra CQL CloudI Service -pkg_cloudi_service_db_cassandra_cql_homepage = http://cloudi.org/ -pkg_cloudi_service_db_cassandra_cql_fetch = git -pkg_cloudi_service_db_cassandra_cql_repo = https://github.com/CloudI/cloudi_service_db_cassandra_cql -pkg_cloudi_service_db_cassandra_cql_commit = master - PACKAGES += cloudi_service_db_couchdb pkg_cloudi_service_db_couchdb_name = cloudi_service_db_couchdb pkg_cloudi_service_db_couchdb_description = CouchDB CloudI Service @@ -637,6 +638,14 @@ pkg_cloudi_service_db_tokyotyrant_fetch = git pkg_cloudi_service_db_tokyotyrant_repo = https://github.com/CloudI/cloudi_service_db_tokyotyrant pkg_cloudi_service_db_tokyotyrant_commit = master +PACKAGES += cloudi_service_db +pkg_cloudi_service_db_name = cloudi_service_db +pkg_cloudi_service_db_description = CloudI Database (in-memory/testing/generic) +pkg_cloudi_service_db_homepage = http://cloudi.org/ +pkg_cloudi_service_db_fetch = git +pkg_cloudi_service_db_repo = https://github.com/CloudI/cloudi_service_db +pkg_cloudi_service_db_commit = master + PACKAGES += cloudi_service_filesystem pkg_cloudi_service_filesystem_name = cloudi_service_filesystem pkg_cloudi_service_filesystem_description = Filesystem CloudI Service @@ -795,7 +804,7 @@ pkg_cowboy_description = Small, fast and modular HTTP server. pkg_cowboy_homepage = http://ninenines.eu pkg_cowboy_fetch = git pkg_cowboy_repo = https://github.com/ninenines/cowboy -pkg_cowboy_commit = 1.0.1 +pkg_cowboy_commit = 1.0.4 PACKAGES += cowdb pkg_cowdb_name = cowdb @@ -811,7 +820,7 @@ pkg_cowlib_description = Support library for manipulating Web protocols. pkg_cowlib_homepage = http://ninenines.eu pkg_cowlib_fetch = git pkg_cowlib_repo = https://github.com/ninenines/cowlib -pkg_cowlib_commit = 1.0.1 +pkg_cowlib_commit = 1.0.2 PACKAGES += cpg pkg_cpg_name = cpg @@ -1029,14 +1038,6 @@ pkg_edown_fetch = git pkg_edown_repo = https://github.com/uwiger/edown pkg_edown_commit = master -PACKAGES += eep -pkg_eep_name = eep -pkg_eep_description = Erlang Easy Profiling (eep) application provides a way to analyze application performance and call hierarchy -pkg_eep_homepage = https://github.com/virtan/eep -pkg_eep_fetch = git -pkg_eep_repo = https://github.com/virtan/eep -pkg_eep_commit = master - PACKAGES += eep_app pkg_eep_app_name = eep_app pkg_eep_app_description = Embedded Event Processing @@ -1045,6 +1046,14 @@ pkg_eep_app_fetch = git pkg_eep_app_repo = https://github.com/darach/eep-erl pkg_eep_app_commit = master +PACKAGES += eep +pkg_eep_name = eep +pkg_eep_description = Erlang Easy Profiling (eep) application provides a way to analyze application performance and call hierarchy +pkg_eep_homepage = https://github.com/virtan/eep +pkg_eep_fetch = git +pkg_eep_repo = https://github.com/virtan/eep +pkg_eep_commit = master + PACKAGES += efene pkg_efene_name = efene pkg_efene_description = Alternative syntax for the Erlang Programming Language focusing on simplicity, ease of use and programmer UX @@ -1053,14 +1062,6 @@ pkg_efene_fetch = git pkg_efene_repo = https://github.com/efene/efene pkg_efene_commit = master -PACKAGES += eganglia -pkg_eganglia_name = eganglia -pkg_eganglia_description = Erlang library to interact with Ganglia -pkg_eganglia_homepage = https://github.com/inaka/eganglia -pkg_eganglia_fetch = git -pkg_eganglia_repo = https://github.com/inaka/eganglia -pkg_eganglia_commit = v0.9.1 - PACKAGES += egeoip pkg_egeoip_name = egeoip pkg_egeoip_description = Erlang IP Geolocation module, currently supporting the MaxMind GeoLite City Database. @@ -1075,7 +1076,7 @@ pkg_ehsa_description = Erlang HTTP server basic and digest authentication module pkg_ehsa_homepage = https://bitbucket.org/a12n/ehsa pkg_ehsa_fetch = hg pkg_ehsa_repo = https://bitbucket.org/a12n/ehsa -pkg_ehsa_commit = 2.0.4 +pkg_ehsa_commit = default PACKAGES += ej pkg_ej_name = ej @@ -1237,14 +1238,6 @@ pkg_eqm_fetch = git pkg_eqm_repo = https://github.com/loucash/eqm pkg_eqm_commit = master -PACKAGES += eredis -pkg_eredis_name = eredis -pkg_eredis_description = Erlang Redis client -pkg_eredis_homepage = https://github.com/wooga/eredis -pkg_eredis_fetch = git -pkg_eredis_repo = https://github.com/wooga/eredis -pkg_eredis_commit = master - PACKAGES += eredis_pool pkg_eredis_pool_name = eredis_pool pkg_eredis_pool_description = eredis_pool is Pool of Redis clients, using eredis and poolboy. @@ -1253,6 +1246,14 @@ pkg_eredis_pool_fetch = git pkg_eredis_pool_repo = https://github.com/hiroeorz/eredis_pool pkg_eredis_pool_commit = master +PACKAGES += eredis +pkg_eredis_name = eredis +pkg_eredis_description = Erlang Redis client +pkg_eredis_homepage = https://github.com/wooga/eredis +pkg_eredis_fetch = git +pkg_eredis_repo = https://github.com/wooga/eredis +pkg_eredis_commit = master + PACKAGES += erl_streams pkg_erl_streams_name = erl_streams pkg_erl_streams_description = Streams in Erlang @@ -1515,7 +1516,7 @@ pkg_erwa_description = A WAMP router and client written in Erlang. pkg_erwa_homepage = https://github.com/bwegh/erwa pkg_erwa_fetch = git pkg_erwa_repo = https://github.com/bwegh/erwa -pkg_erwa_commit = 0.1.1 +pkg_erwa_commit = master PACKAGES += espec pkg_espec_name = espec @@ -1541,14 +1542,6 @@ pkg_etap_fetch = git pkg_etap_repo = https://github.com/ngerakines/etap pkg_etap_commit = master -PACKAGES += etest -pkg_etest_name = etest -pkg_etest_description = A lightweight, convention over configuration test framework for Erlang -pkg_etest_homepage = https://github.com/wooga/etest -pkg_etest_fetch = git -pkg_etest_repo = https://github.com/wooga/etest -pkg_etest_commit = master - PACKAGES += etest_http pkg_etest_http_name = etest_http pkg_etest_http_description = etest Assertions around HTTP (client-side) @@ -1557,6 +1550,14 @@ pkg_etest_http_fetch = git pkg_etest_http_repo = https://github.com/wooga/etest_http pkg_etest_http_commit = master +PACKAGES += etest +pkg_etest_name = etest +pkg_etest_description = A lightweight, convention over configuration test framework for Erlang +pkg_etest_homepage = https://github.com/wooga/etest +pkg_etest_fetch = git +pkg_etest_repo = https://github.com/wooga/etest +pkg_etest_commit = master + PACKAGES += etoml pkg_etoml_name = etoml pkg_etoml_description = TOML language erlang parser @@ -1565,14 +1566,6 @@ pkg_etoml_fetch = git pkg_etoml_repo = https://github.com/kalta/etoml pkg_etoml_commit = master -PACKAGES += eunit -pkg_eunit_name = eunit -pkg_eunit_description = The EUnit lightweight unit testing framework for Erlang - this is the canonical development repository. -pkg_eunit_homepage = https://github.com/richcarl/eunit -pkg_eunit_fetch = git -pkg_eunit_repo = https://github.com/richcarl/eunit -pkg_eunit_commit = master - PACKAGES += eunit_formatters pkg_eunit_formatters_name = eunit_formatters pkg_eunit_formatters_description = Because eunit's output sucks. Let's make it better. @@ -1581,6 +1574,14 @@ pkg_eunit_formatters_fetch = git pkg_eunit_formatters_repo = https://github.com/seancribbs/eunit_formatters pkg_eunit_formatters_commit = master +PACKAGES += eunit +pkg_eunit_name = eunit +pkg_eunit_description = The EUnit lightweight unit testing framework for Erlang - this is the canonical development repository. +pkg_eunit_homepage = https://github.com/richcarl/eunit +pkg_eunit_fetch = git +pkg_eunit_repo = https://github.com/richcarl/eunit +pkg_eunit_commit = master + PACKAGES += euthanasia pkg_euthanasia_name = euthanasia pkg_euthanasia_description = Merciful killer for your Erlang processes @@ -1619,7 +1620,7 @@ pkg_exometer_description = Basic measurement objects and probe behavior pkg_exometer_homepage = https://github.com/Feuerlabs/exometer pkg_exometer_fetch = git pkg_exometer_repo = https://github.com/Feuerlabs/exometer -pkg_exometer_commit = 1.2 +pkg_exometer_commit = master PACKAGES += exs1024 pkg_exs1024_name = exs1024 @@ -1683,7 +1684,15 @@ pkg_feeder_description = Stream parse RSS and Atom formatted XML feeds. pkg_feeder_homepage = https://github.com/michaelnisi/feeder pkg_feeder_fetch = git pkg_feeder_repo = https://github.com/michaelnisi/feeder -pkg_feeder_commit = v1.4.6 +pkg_feeder_commit = master + +PACKAGES += find_crate +pkg_find_crate_name = find_crate +pkg_find_crate_description = Find Rust libs and exes in Erlang application priv directory +pkg_find_crate_homepage = https://github.com/goertzenator/find_crate +pkg_find_crate_fetch = git +pkg_find_crate_repo = https://github.com/goertzenator/find_crate +pkg_find_crate_commit = master PACKAGES += fix pkg_fix_name = fix @@ -1709,14 +1718,6 @@ pkg_fn_fetch = git pkg_fn_repo = https://github.com/reiddraper/fn pkg_fn_commit = master -PACKAGES += folsom -pkg_folsom_name = folsom -pkg_folsom_description = Expose Erlang Events and Metrics -pkg_folsom_homepage = https://github.com/boundary/folsom -pkg_folsom_fetch = git -pkg_folsom_repo = https://github.com/boundary/folsom -pkg_folsom_commit = master - PACKAGES += folsom_cowboy pkg_folsom_cowboy_name = folsom_cowboy pkg_folsom_cowboy_description = A Cowboy based Folsom HTTP Wrapper. @@ -1725,6 +1726,14 @@ pkg_folsom_cowboy_fetch = git pkg_folsom_cowboy_repo = https://github.com/boundary/folsom_cowboy pkg_folsom_cowboy_commit = master +PACKAGES += folsom +pkg_folsom_name = folsom +pkg_folsom_description = Expose Erlang Events and Metrics +pkg_folsom_homepage = https://github.com/boundary/folsom +pkg_folsom_fetch = git +pkg_folsom_repo = https://github.com/boundary/folsom +pkg_folsom_commit = master + PACKAGES += folsomite pkg_folsomite_name = folsomite pkg_folsomite_description = blow up your graphite / riemann server with folsom metrics @@ -1845,6 +1854,14 @@ pkg_gen_unix_fetch = git pkg_gen_unix_repo = https://github.com/msantos/gen_unix pkg_gen_unix_commit = master +PACKAGES += geode +pkg_geode_name = geode +pkg_geode_description = geohash/proximity lookup in pure, uncut erlang. +pkg_geode_homepage = https://github.com/bradfordw/geode +pkg_geode_fetch = git +pkg_geode_repo = https://github.com/bradfordw/geode +pkg_geode_commit = master + PACKAGES += getopt pkg_getopt_name = getopt pkg_getopt_description = Module to parse command line arguments using the GNU getopt syntax @@ -2003,7 +2020,7 @@ pkg_ibrowse_description = Erlang HTTP client pkg_ibrowse_homepage = https://github.com/cmullaparthi/ibrowse pkg_ibrowse_fetch = git pkg_ibrowse_repo = https://github.com/cmullaparthi/ibrowse -pkg_ibrowse_commit = v4.1.1 +pkg_ibrowse_commit = master PACKAGES += ierlang pkg_ierlang_name = ierlang @@ -2059,7 +2076,7 @@ pkg_jamdb_sybase_description = Erlang driver for SAP Sybase ASE pkg_jamdb_sybase_homepage = https://github.com/erlangbureau/jamdb_sybase pkg_jamdb_sybase_fetch = git pkg_jamdb_sybase_repo = https://github.com/erlangbureau/jamdb_sybase -pkg_jamdb_sybase_commit = 0.6.0 +pkg_jamdb_sybase_commit = master PACKAGES += jerg pkg_jerg_name = jerg @@ -2072,11 +2089,19 @@ pkg_jerg_commit = master PACKAGES += jesse pkg_jesse_name = jesse pkg_jesse_description = jesse (JSon Schema Erlang) is an implementation of a json schema validator for Erlang. -pkg_jesse_homepage = https://github.com/klarna/jesse +pkg_jesse_homepage = https://github.com/for-GET/jesse pkg_jesse_fetch = git -pkg_jesse_repo = https://github.com/klarna/jesse +pkg_jesse_repo = https://github.com/for-GET/jesse pkg_jesse_commit = master +PACKAGES += jiffy_v +pkg_jiffy_v_name = jiffy_v +pkg_jiffy_v_description = JSON validation utility +pkg_jiffy_v_homepage = https://github.com/shizzard/jiffy-v +pkg_jiffy_v_fetch = git +pkg_jiffy_v_repo = https://github.com/shizzard/jiffy-v +pkg_jiffy_v_commit = master + PACKAGES += jiffy pkg_jiffy_name = jiffy pkg_jiffy_description = JSON NIFs for Erlang. @@ -2085,21 +2110,13 @@ pkg_jiffy_fetch = git pkg_jiffy_repo = https://github.com/davisp/jiffy pkg_jiffy_commit = master -PACKAGES += jiffy_v -pkg_jiffy_v_name = jiffy_v -pkg_jiffy_v_description = JSON validation utility -pkg_jiffy_v_homepage = https://github.com/shizzard/jiffy-v -pkg_jiffy_v_fetch = git -pkg_jiffy_v_repo = https://github.com/shizzard/jiffy-v -pkg_jiffy_v_commit = 0.3.3 - PACKAGES += jobs pkg_jobs_name = jobs pkg_jobs_description = a Job scheduler for load regulation pkg_jobs_homepage = https://github.com/esl/jobs pkg_jobs_fetch = git pkg_jobs_repo = https://github.com/esl/jobs -pkg_jobs_commit = 0.3 +pkg_jobs_commit = master PACKAGES += joxa pkg_joxa_name = joxa @@ -2109,6 +2126,14 @@ pkg_joxa_fetch = git pkg_joxa_repo = https://github.com/joxa/joxa pkg_joxa_commit = master +PACKAGES += json_rec +pkg_json_rec_name = json_rec +pkg_json_rec_description = JSON to erlang record +pkg_json_rec_homepage = https://github.com/justinkirby/json_rec +pkg_json_rec_fetch = git +pkg_json_rec_repo = https://github.com/justinkirby/json_rec +pkg_json_rec_commit = master + PACKAGES += json pkg_json_name = json pkg_json_description = a high level json library for erlang (17.0+) @@ -2117,13 +2142,13 @@ pkg_json_fetch = git pkg_json_repo = https://github.com/talentdeficit/json pkg_json_commit = master -PACKAGES += json_rec -pkg_json_rec_name = json_rec -pkg_json_rec_description = JSON to erlang record -pkg_json_rec_homepage = https://github.com/justinkirby/json_rec -pkg_json_rec_fetch = git -pkg_json_rec_repo = https://github.com/justinkirby/json_rec -pkg_json_rec_commit = master +PACKAGES += jsone +pkg_jsone_name = jsone +pkg_jsone_description = An Erlang library for encoding, decoding JSON data. +pkg_jsone_homepage = https://github.com/sile/jsone.git +pkg_jsone_fetch = git +pkg_jsone_repo = https://github.com/sile/jsone.git +pkg_jsone_commit = master PACKAGES += jsonerl pkg_jsonerl_name = jsonerl @@ -2157,6 +2182,14 @@ pkg_jsx_fetch = git pkg_jsx_repo = https://github.com/talentdeficit/jsx pkg_jsx_commit = master +PACKAGES += kafka_protocol +pkg_kafka_protocol_name = kafka_protocol +pkg_kafka_protocol_description = Kafka protocol Erlang library +pkg_kafka_protocol_homepage = https://github.com/klarna/kafka_protocol +pkg_kafka_protocol_fetch = git +pkg_kafka_protocol_repo = https://github.com/klarna/kafka_protocol.git +pkg_kafka_protocol_commit = master + PACKAGES += kafka pkg_kafka_name = kafka pkg_kafka_description = Kafka consumer and producer in Erlang @@ -2261,14 +2294,6 @@ pkg_kvs_fetch = git pkg_kvs_repo = https://github.com/synrc/kvs pkg_kvs_commit = master -PACKAGES += lager -pkg_lager_name = lager -pkg_lager_description = A logging framework for Erlang/OTP. -pkg_lager_homepage = https://github.com/basho/lager -pkg_lager_fetch = git -pkg_lager_repo = https://github.com/basho/lager -pkg_lager_commit = master - PACKAGES += lager_amqp_backend pkg_lager_amqp_backend_name = lager_amqp_backend pkg_lager_amqp_backend_description = AMQP RabbitMQ Lager backend @@ -2285,6 +2310,14 @@ pkg_lager_syslog_fetch = git pkg_lager_syslog_repo = https://github.com/basho/lager_syslog pkg_lager_syslog_commit = master +PACKAGES += lager +pkg_lager_name = lager +pkg_lager_description = A logging framework for Erlang/OTP. +pkg_lager_homepage = https://github.com/basho/lager +pkg_lager_fetch = git +pkg_lager_repo = https://github.com/basho/lager +pkg_lager_commit = master + PACKAGES += lambdapad pkg_lambdapad_name = lambdapad pkg_lambdapad_description = Static site generator using Erlang. Yes, Erlang. @@ -2307,7 +2340,7 @@ pkg_lasse_description = SSE handler for Cowboy pkg_lasse_homepage = https://github.com/inaka/lasse pkg_lasse_fetch = git pkg_lasse_repo = https://github.com/inaka/lasse -pkg_lasse_commit = 0.1.0 +pkg_lasse_commit = master PACKAGES += ldap pkg_ldap_name = ldap @@ -2541,14 +2574,6 @@ pkg_mixer_fetch = git pkg_mixer_repo = https://github.com/chef/mixer pkg_mixer_commit = master -PACKAGES += mochiweb -pkg_mochiweb_name = mochiweb -pkg_mochiweb_description = MochiWeb is an Erlang library for building lightweight HTTP servers. -pkg_mochiweb_homepage = https://github.com/mochi/mochiweb -pkg_mochiweb_fetch = git -pkg_mochiweb_repo = https://github.com/mochi/mochiweb -pkg_mochiweb_commit = master - PACKAGES += mochiweb_xpath pkg_mochiweb_xpath_name = mochiweb_xpath pkg_mochiweb_xpath_description = XPath support for mochiweb's html parser @@ -2557,6 +2582,14 @@ pkg_mochiweb_xpath_fetch = git pkg_mochiweb_xpath_repo = https://github.com/retnuh/mochiweb_xpath pkg_mochiweb_xpath_commit = master +PACKAGES += mochiweb +pkg_mochiweb_name = mochiweb +pkg_mochiweb_description = MochiWeb is an Erlang library for building lightweight HTTP servers. +pkg_mochiweb_homepage = https://github.com/mochi/mochiweb +pkg_mochiweb_fetch = git +pkg_mochiweb_repo = https://github.com/mochi/mochiweb +pkg_mochiweb_commit = master + PACKAGES += mockgyver pkg_mockgyver_name = mockgyver pkg_mockgyver_description = A mocking library for Erlang @@ -2763,7 +2796,7 @@ pkg_octopus_description = Small and flexible pool manager written in Erlang pkg_octopus_homepage = https://github.com/erlangbureau/octopus pkg_octopus_fetch = git pkg_octopus_repo = https://github.com/erlangbureau/octopus -pkg_octopus_commit = 1.0.0 +pkg_octopus_commit = master PACKAGES += of_protocol pkg_of_protocol_name = of_protocol @@ -2835,7 +2868,7 @@ pkg_pegjs_description = An implementation of PEG.js grammar for Erlang. pkg_pegjs_homepage = https://github.com/dmitriid/pegjs pkg_pegjs_fetch = git pkg_pegjs_repo = https://github.com/dmitriid/pegjs -pkg_pegjs_commit = 0.3 +pkg_pegjs_commit = master PACKAGES += percept2 pkg_percept2_name = percept2 @@ -3003,7 +3036,7 @@ pkg_qdate_description = Date, time, and timezone parsing, formatting, and conver pkg_qdate_homepage = https://github.com/choptastic/qdate pkg_qdate_fetch = git pkg_qdate_repo = https://github.com/choptastic/qdate -pkg_qdate_commit = 0.4.0 +pkg_qdate_commit = master PACKAGES += qrcode pkg_qrcode_name = qrcode @@ -3029,14 +3062,6 @@ pkg_quickrand_fetch = git pkg_quickrand_repo = https://github.com/okeuday/quickrand pkg_quickrand_commit = master -PACKAGES += rabbit -pkg_rabbit_name = rabbit -pkg_rabbit_description = RabbitMQ Server -pkg_rabbit_homepage = https://www.rabbitmq.com/ -pkg_rabbit_fetch = git -pkg_rabbit_repo = https://github.com/rabbitmq/rabbitmq-server.git -pkg_rabbit_commit = master - PACKAGES += rabbit_exchange_type_riak pkg_rabbit_exchange_type_riak_name = rabbit_exchange_type_riak pkg_rabbit_exchange_type_riak_description = Custom RabbitMQ exchange type for sticking messages in Riak @@ -3045,6 +3070,14 @@ pkg_rabbit_exchange_type_riak_fetch = git pkg_rabbit_exchange_type_riak_repo = https://github.com/jbrisbin/riak-exchange pkg_rabbit_exchange_type_riak_commit = master +PACKAGES += rabbit +pkg_rabbit_name = rabbit +pkg_rabbit_description = RabbitMQ Server +pkg_rabbit_homepage = https://www.rabbitmq.com/ +pkg_rabbit_fetch = git +pkg_rabbit_repo = https://github.com/rabbitmq/rabbitmq-server.git +pkg_rabbit_commit = master + PACKAGES += rack pkg_rack_name = rack pkg_rack_description = Rack handler for erlang @@ -3075,7 +3108,7 @@ pkg_ranch_description = Socket acceptor pool for TCP protocols. pkg_ranch_homepage = http://ninenines.eu pkg_ranch_fetch = git pkg_ranch_repo = https://github.com/ninenines/ranch -pkg_ranch_commit = 1.1.0 +pkg_ranch_commit = 1.2.1 PACKAGES += rbeacon pkg_rbeacon_name = rbeacon @@ -3115,7 +3148,7 @@ pkg_recon_description = Collection of functions and scripts to debug Erlang in p pkg_recon_homepage = https://github.com/ferd/recon pkg_recon_fetch = git pkg_recon_repo = https://github.com/ferd/recon -pkg_recon_commit = 2.2.1 +pkg_recon_commit = master PACKAGES += record_info pkg_record_info_name = record_info @@ -3309,6 +3342,14 @@ pkg_rlimit_fetch = git pkg_rlimit_repo = https://github.com/jlouis/rlimit pkg_rlimit_commit = master +PACKAGES += rust_mk +pkg_rust_mk_name = rust_mk +pkg_rust_mk_description = Build Rust crates in an Erlang application +pkg_rust_mk_homepage = https://github.com/goertzenator/rust.mk +pkg_rust_mk_fetch = git +pkg_rust_mk_repo = https://github.com/goertzenator/rust.mk +pkg_rust_mk_commit = master + PACKAGES += safetyvalve pkg_safetyvalve_name = safetyvalve pkg_safetyvalve_description = A safety valve for your erlang node @@ -3379,7 +3420,7 @@ pkg_shotgun_description = better than just a gun pkg_shotgun_homepage = https://github.com/inaka/shotgun pkg_shotgun_fetch = git pkg_shotgun_repo = https://github.com/inaka/shotgun -pkg_shotgun_commit = 0.1.0 +pkg_shotgun_commit = master PACKAGES += sidejob pkg_sidejob_name = sidejob @@ -3437,6 +3478,14 @@ pkg_skel_fetch = git pkg_skel_repo = https://github.com/ParaPhrase/skel pkg_skel_commit = master +PACKAGES += slack +pkg_slack_name = slack +pkg_slack_description = Minimal slack notification OTP library. +pkg_slack_homepage = https://github.com/DonBranson/slack +pkg_slack_fetch = git +pkg_slack_repo = https://github.com/DonBranson/slack.git +pkg_slack_commit = master + PACKAGES += smother pkg_smother_name = smother pkg_smother_description = Extended code coverage metrics for Erlang. @@ -3493,14 +3542,6 @@ pkg_stable_fetch = git pkg_stable_repo = https://github.com/dvv/stable pkg_stable_commit = master -PACKAGES += statebox -pkg_statebox_name = statebox -pkg_statebox_description = Erlang state monad with merge/conflict-resolution capabilities. Useful for Riak. -pkg_statebox_homepage = https://github.com/mochi/statebox -pkg_statebox_fetch = git -pkg_statebox_repo = https://github.com/mochi/statebox -pkg_statebox_commit = master - PACKAGES += statebox_riak pkg_statebox_riak_name = statebox_riak pkg_statebox_riak_description = Convenience library that makes it easier to use statebox with riak, extracted from best practices in our production code at Mochi Media. @@ -3509,6 +3550,14 @@ pkg_statebox_riak_fetch = git pkg_statebox_riak_repo = https://github.com/mochi/statebox_riak pkg_statebox_riak_commit = master +PACKAGES += statebox +pkg_statebox_name = statebox +pkg_statebox_description = Erlang state monad with merge/conflict-resolution capabilities. Useful for Riak. +pkg_statebox_homepage = https://github.com/mochi/statebox +pkg_statebox_fetch = git +pkg_statebox_repo = https://github.com/mochi/statebox +pkg_statebox_commit = master + PACKAGES += statman pkg_statman_name = statman pkg_statman_description = Efficiently collect massive volumes of metrics inside the Erlang VM @@ -3591,7 +3640,7 @@ pkg_switchboard_commit = master PACKAGES += syn pkg_syn_name = syn -pkg_syn_description = A global process registry for Erlang. +pkg_syn_description = A global Process Registry and Process Group manager for Erlang. pkg_syn_homepage = https://github.com/ostinelli/syn pkg_syn_fetch = git pkg_syn_repo = https://github.com/ostinelli/syn @@ -3763,7 +3812,7 @@ pkg_unicorn_description = Generic configuration server pkg_unicorn_homepage = https://github.com/shizzard/unicorn pkg_unicorn_fetch = git pkg_unicorn_repo = https://github.com/shizzard/unicorn -pkg_unicorn_commit = 0.3.0 +pkg_unicorn_commit = master PACKAGES += unsplit pkg_unsplit_name = unsplit @@ -3779,7 +3828,7 @@ pkg_uuid_description = Erlang UUID Implementation pkg_uuid_homepage = https://github.com/okeuday/uuid pkg_uuid_fetch = git pkg_uuid_repo = https://github.com/okeuday/uuid -pkg_uuid_commit = v1.4.0 +pkg_uuid_commit = master PACKAGES += ux pkg_ux_name = ux @@ -3899,7 +3948,7 @@ pkg_worker_pool_description = a simple erlang worker pool pkg_worker_pool_homepage = https://github.com/inaka/worker_pool pkg_worker_pool_fetch = git pkg_worker_pool_repo = https://github.com/inaka/worker_pool -pkg_worker_pool_commit = 1.0.3 +pkg_worker_pool_commit = master PACKAGES += wrangler pkg_wrangler_name = wrangler @@ -3931,7 +3980,7 @@ pkg_xref_runner_description = Erlang Xref Runner (inspired in rebar xref) pkg_xref_runner_homepage = https://github.com/inaka/xref_runner pkg_xref_runner_fetch = git pkg_xref_runner_repo = https://github.com/inaka/xref_runner -pkg_xref_runner_commit = 0.2.3 +pkg_xref_runner_commit = master PACKAGES += yamerl pkg_yamerl_name = yamerl @@ -3965,13 +4014,21 @@ pkg_zab_engine_fetch = git pkg_zab_engine_repo = https://github.com/xinmingyao/zab_engine pkg_zab_engine_commit = master +PACKAGES += zabbix_sender +pkg_zabbix_sender_name = zabbix_sender +pkg_zabbix_sender_description = Zabbix trapper for sending data to Zabbix in pure Erlang +pkg_zabbix_sender_homepage = https://github.com/stalkermn/zabbix_sender +pkg_zabbix_sender_fetch = git +pkg_zabbix_sender_repo = https://github.com/stalkermn/zabbix_sender.git +pkg_zabbix_sender_commit = master + PACKAGES += zeta pkg_zeta_name = zeta pkg_zeta_description = HTTP access log parser in Erlang pkg_zeta_homepage = https://github.com/s1n4/zeta pkg_zeta_fetch = git pkg_zeta_repo = https://github.com/s1n4/zeta -pkg_zeta_commit = +pkg_zeta_commit = master PACKAGES += zippers pkg_zippers_name = zippers @@ -4082,16 +4139,35 @@ dep_verbose = $(dep_verbose_$(V)) # Core targets. -ifneq ($(SKIP_DEPS),) -deps:: +ifdef IS_APP +apps:: else -deps:: $(ALL_DEPS_DIRS) -ifndef IS_APP +apps:: $(ALL_APPS_DIRS) +ifeq ($(IS_APP)$(IS_DEP),) + $(verbose) rm -f $(ERLANG_MK_TMP)/apps.log +endif + $(verbose) mkdir -p $(ERLANG_MK_TMP) +# Create ebin directory for all apps to make sure Erlang recognizes them +# as proper OTP applications when using -include_lib. This is a temporary +# fix, a proper fix would be to compile apps/* in the right order. + $(verbose) for dep in $(ALL_APPS_DIRS) ; do \ + mkdir -p $$dep/ebin || exit $$?; \ + done $(verbose) for dep in $(ALL_APPS_DIRS) ; do \ - $(MAKE) -C $$dep IS_APP=1 || exit $$?; \ + if grep -qs ^$$dep$$ $(ERLANG_MK_TMP)/apps.log; then \ + :; \ + else \ + echo $$dep >> $(ERLANG_MK_TMP)/apps.log; \ + $(MAKE) -C $$dep IS_APP=1 || exit $$?; \ + fi \ done endif -ifneq ($(IS_DEP),1) + +ifneq ($(SKIP_DEPS),) +deps:: +else +deps:: $(ALL_DEPS_DIRS) apps +ifeq ($(IS_APP)$(IS_DEP),) $(verbose) rm -f $(ERLANG_MK_TMP)/deps.log endif $(verbose) mkdir -p $(ERLANG_MK_TMP) @@ -4348,9 +4424,9 @@ define dep_autopatch_rebar.erl [] -> ok; _ -> Write("\npre-app::\n\t$$\(MAKE) -f c_src/Makefile.erlang.mk\n"), - PortSpecWrite(io_lib:format("ERL_CFLAGS = -finline-functions -Wall -fPIC -I ~s/erts-~s/include -I ~s\n", + PortSpecWrite(io_lib:format("ERL_CFLAGS = -finline-functions -Wall -fPIC -I \\"~s/erts-~s/include\\" -I \\"~s\\"\n", [code:root_dir(), erlang:system_info(version), code:lib_dir(erl_interface, include)])), - PortSpecWrite(io_lib:format("ERL_LDFLAGS = -L ~s -lerl_interface -lei\n", + PortSpecWrite(io_lib:format("ERL_LDFLAGS = -L \\"~s\\" -lerl_interface -lei\n", [code:lib_dir(erl_interface, lib)])), [PortSpecWrite(["\n", E, "\n"]) || E <- OsEnv], FilterEnv = fun(Env) -> @@ -4620,11 +4696,11 @@ endif # Forward-declare variables used in core/deps-tools.mk. This is required # in case plugins use them. -ERLANG_MK_RECURSIVE_DEPS_LIST = $(ERLANG_MK_TMP)/list-deps.log -ERLANG_MK_RECURSIVE_DOC_DEPS_LIST = $(ERLANG_MK_TMP)/list-doc-deps.log -ERLANG_MK_RECURSIVE_REL_DEPS_LIST = $(ERLANG_MK_TMP)/list-rel-deps.log -ERLANG_MK_RECURSIVE_TEST_DEPS_LIST = $(ERLANG_MK_TMP)/list-test-deps.log -ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST = $(ERLANG_MK_TMP)/list-shell-deps.log +ERLANG_MK_RECURSIVE_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-deps-list.log +ERLANG_MK_RECURSIVE_DOC_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-doc-deps-list.log +ERLANG_MK_RECURSIVE_REL_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-rel-deps-list.log +ERLANG_MK_RECURSIVE_TEST_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-test-deps-list.log +ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST = $(ERLANG_MK_TMP)/recursive-shell-deps-list.log # External plugins. @@ -4649,6 +4725,7 @@ $(foreach p,$(DEP_PLUGINS),\ DTL_FULL_PATH ?= DTL_PATH ?= templates/ DTL_SUFFIX ?= _dtl +DTL_OPTS ?= # Verbosity. @@ -4689,7 +4766,7 @@ define erlydtl_compile.erl re:replace(F2, "/", "_", [{return, list}, global]) end, Module = list_to_atom(string:to_lower(Module0) ++ "$(DTL_SUFFIX)"), - case erlydtl:compile(F, Module, [{out_dir, "ebin/"}, return_errors, {doc_root, "templates"}]) of + case erlydtl:compile(F, Module, [$(DTL_OPTS)] ++ [{out_dir, "ebin/"}, return_errors, {doc_root, "templates"}]) of ok -> ok; {ok, _} -> ok end @@ -4796,7 +4873,7 @@ app:: clean deps $(PROJECT).d $(verbose) $(MAKE) --no-print-directory app-build endif -ifeq ($(wildcard src/$(PROJECT)_app.erl),) +ifeq ($(wildcard src/$(PROJECT_MOD).erl),) define app_file {application, $(PROJECT), [ {description, "$(PROJECT_DESCRIPTION)"}, @@ -4816,7 +4893,7 @@ define app_file {modules, [$(call comma_list,$(2))]}, {registered, [$(call comma_list,$(PROJECT)_sup $(PROJECT_REGISTERED))]}, {applications, [$(call comma_list,kernel stdlib $(OTP_DEPS) $(LOCAL_DEPS) $(DEPS))]}, - {mod, {$(PROJECT)_app, []}} + {mod, {$(PROJECT_MOD), []}} ]}. endef endif @@ -4991,13 +5068,13 @@ ifeq ($(wildcard src/$(PROJECT).app.src),) $(app_verbose) printf "$(subst $(newline),\n,$(subst ",\",$(call app_file,$(GITDESCRIBE),$(MODULES))))" \ > ebin/$(PROJECT).app else - $(verbose) if [ -z "$$(grep -E '^[^%]*{\s*modules\s*,' src/$(PROJECT).app.src)" ]; then \ + $(verbose) if [ -z "$$(grep -e '^[^%]*{\s*modules\s*,' src/$(PROJECT).app.src)" ]; then \ echo "Empty modules entry not found in $(PROJECT).app.src. Please consult the erlang.mk README for instructions." >&2; \ exit 1; \ fi $(appsrc_verbose) cat src/$(PROJECT).app.src \ | sed "s/{[[:space:]]*modules[[:space:]]*,[[:space:]]*\[\]}/{modules, \[$(call comma_list,$(MODULES))\]}/" \ - | sed "s/{id,[[:space:]]*\"git\"}/{id, \"$(GITDESCRIBE)\"}/" \ + | sed "s/{id,[[:space:]]*\"git\"}/{id, \"$(subst /,\/,$(GITDESCRIBE))\"}/" \ > ebin/$(PROJECT).app endif @@ -5115,7 +5192,7 @@ endif # We strip out -Werror because we don't want to fail due to # warnings when used as a dependency. -compat_prepare_erlc_opts = $(shell echo "$1" | sed 's/, */,/') +compat_prepare_erlc_opts = $(shell echo "$1" | sed 's/, */,/g') define compat_convert_erlc_opts $(if $(filter-out -Werror,$1),\ @@ -5124,12 +5201,16 @@ $(if $(filter-out -Werror,$1),\ endef define compat_erlc_opts_to_list - [$(call comma_list,$(foreach o,$(call compat_prepare_erlc_opts,$1),$(call compat_convert_erlc_opts,$o)))] +[$(call comma_list,$(foreach o,$(call compat_prepare_erlc_opts,$1),$(call compat_convert_erlc_opts,$o)))] endef define compat_rebar_config -{deps, [$(call comma_list,$(foreach d,$(DEPS),\ - {$(call dep_name,$d),".*",{git,"$(call dep_repo,$d)","$(call dep_commit,$d)"}}))]}. +{deps, [ +$(call comma_list,$(foreach d,$(DEPS),\ + $(if $(filter hex,$(call dep_fetch,$d)),\ + {$(call dep_name,$d)$(comma)"$(call dep_repo,$d)"},\ + {$(call dep_name,$d)$(comma)".*"$(comma){git,"$(call dep_repo,$d)"$(comma)"$(call dep_commit,$d)"}}))) +]}. {erl_opts, $(call compat_erlc_opts_to_list,$(ERLC_OPTS))}. endef @@ -5199,8 +5280,8 @@ help:: " bootstrap Generate a skeleton of an OTP application" \ " bootstrap-lib Generate a skeleton of an OTP library" \ " bootstrap-rel Generate the files needed to build a release" \ - " new-app n=NAME Create a new local OTP application NAME" \ - " new-lib n=NAME Create a new local OTP library NAME" \ + " new-app in=NAME Create a new local OTP application NAME" \ + " new-lib in=NAME Create a new local OTP library NAME" \ " new t=TPL n=NAME Generate a module NAME based on the template TPL" \ " new t=T n=N in=APP Generate a module NAME based on the template TPL in APP" \ " list-templates List available templates" @@ -5360,6 +5441,11 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. endef +define tpl_module +-module($(n)). +-export([]). +endef + define tpl_cowboy_http -module($(n)). -behaviour(cowboy_http_handler). @@ -5674,6 +5760,7 @@ ifeq ($(PLATFORM),msys2) # We hardcode the compiler used on MSYS2. The default CC=cc does # not produce working code. The "gcc" MSYS2 package also doesn't. CC = /mingw64/bin/gcc + export CC CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes CXXFLAGS ?= -O3 -finline-functions -Wall else ifeq ($(PLATFORM),darwin) @@ -5975,7 +6062,7 @@ help:: CT_RUN = ct_run \ -no_auto_compile \ -noinput \ - -pa $(CURDIR)/ebin $(DEPS_DIR)/*/ebin $(TEST_DIR) \ + -pa $(CURDIR)/ebin $(DEPS_DIR)/*/ebin $(APPS_DIR)/*/ebin $(TEST_DIR) \ -dir $(TEST_DIR) \ -logdir $(CURDIR)/logs @@ -5984,12 +6071,18 @@ ct: $(if $(IS_APP),,apps-ct) else ct: test-build $(if $(IS_APP),,apps-ct) $(verbose) mkdir -p $(CURDIR)/logs/ - $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) + $(gen_verbose) $(CT_RUN) -sname ct_$(PROJECT) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) endif ifneq ($(ALL_APPS_DIRS),) -apps-ct: - $(verbose) for app in $(ALL_APPS_DIRS); do $(MAKE) -C $$app ct IS_APP=1; done +define ct_app_target +apps-ct-$1: + $(MAKE) -C $1 ct IS_APP=1 +endef + +$(foreach app,$(ALL_APPS_DIRS),$(eval $(call ct_app_target,$(app)))) + +apps-ct: test-build $(addprefix apps-ct-,$(ALL_APPS_DIRS)) endif ifndef t @@ -6006,7 +6099,7 @@ endif define ct_suite_target ct-$(1): test-build $(verbose) mkdir -p $(CURDIR)/logs/ - $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(1)) $(CT_EXTRA) $(CT_OPTS) + $(gen_verbose) $(CT_RUN) -sname ct_$(PROJECT) -suite $(addsuffix _SUITE,$(1)) $(CT_EXTRA) $(CT_OPTS) endef $(foreach test,$(CT_SUITES),$(eval $(call ct_suite_target,$(test)))) @@ -6043,14 +6136,17 @@ help:: # Plugin-specific targets. define filter_opts.erl - Opts = binary:split(<<"$1">>, <<"-">>, [global]), - Filtered = lists:reverse(lists:foldl(fun - (O = <<"pa ", _/bits>>, Acc) -> [O|Acc]; - (O = <<"D ", _/bits>>, Acc) -> [O|Acc]; - (O = <<"I ", _/bits>>, Acc) -> [O|Acc]; - (_, Acc) -> Acc - end, [], Opts)), - io:format("~s~n", [[["-", O] || O <- Filtered]]), + Opts = init:get_plain_arguments(), + {Filtered, _} = lists:foldl(fun + (O, {Os, true}) -> {[O|Os], false}; + (O = "-D", {Os, _}) -> {[O|Os], true}; + (O = [\\$$-, \\$$D, _ | _], {Os, _}) -> {[O|Os], false}; + (O = "-I", {Os, _}) -> {[O|Os], true}; + (O = [\\$$-, \\$$I, _ | _], {Os, _}) -> {[O|Os], false}; + (O = "-pa", {Os, _}) -> {[O|Os], true}; + (_, Acc) -> Acc + end, {[], false}, Opts), + io:format("~s~n", [string:join(lists:reverse(Filtered), " ")]), halt(). endef @@ -6067,7 +6163,7 @@ dialyze: else dialyze: $(DIALYZER_PLT) endif - $(verbose) dialyzer --no_native `$(call erlang,$(call filter_opts.erl,$(ERLC_OPTS)))` $(DIALYZER_DIRS) $(DIALYZER_OPTS) + $(verbose) dialyzer --no_native `$(ERL) -eval "$(subst $(newline),,$(subst ",\",$(call filter_opts.erl)))" -extra $(ERLC_OPTS)` $(DIALYZER_DIRS) $(DIALYZER_OPTS) # Copyright (c) 2013-2015, Loïc Hoguin <essen@ninenines.eu> # This file is part of erlang.mk and subject to the terms of the ISC License. @@ -6102,6 +6198,8 @@ distclean-edoc: # Configuration. ESCRIPT_NAME ?= $(PROJECT) +ESCRIPT_FILE ?= $(ESCRIPT_NAME) + ESCRIPT_COMMENT ?= This is an -*- erlang -*- file ESCRIPT_BEAMS ?= "ebin/*", "deps/*/ebin/*" @@ -6147,7 +6245,7 @@ define ESCRIPT_RAW ' ]),'\ ' file:change_mode(Escript, 8#755)'\ 'end,'\ -'Ez("$(ESCRIPT_NAME)"),'\ +'Ez("$(ESCRIPT_FILE)"),'\ 'halt().' endef @@ -6202,7 +6300,7 @@ define eunit.erl halt() endef -EUNIT_ERL_OPTS += -pa $(TEST_DIR) $(DEPS_DIR)/*/ebin $(APPS_DIR)/*/ebin ebin +EUNIT_ERL_OPTS += -pa $(TEST_DIR) $(DEPS_DIR)/*/ebin $(APPS_DIR)/*/ebin $(CURDIR)/ebin ifdef t ifeq (,$(findstring :,$(t))) @@ -6213,8 +6311,9 @@ eunit: test-build $(gen_verbose) $(call erlang,$(call eunit.erl,fun $(t)/0),$(EUNIT_ERL_OPTS)) endif else -EUNIT_EBIN_MODS = $(notdir $(basename $(call core_find,ebin/,*.beam))) -EUNIT_TEST_MODS = $(notdir $(basename $(call core_find,$(TEST_DIR)/,*.beam))) +EUNIT_EBIN_MODS = $(notdir $(basename $(ERL_FILES) $(BEAM_FILES))) +EUNIT_TEST_MODS = $(notdir $(basename $(call core_find,$(TEST_DIR)/,*.erl))) + EUNIT_MODS = $(foreach mod,$(EUNIT_EBIN_MODS) $(filter-out \ $(patsubst %,%_tests,$(EUNIT_EBIN_MODS)),$(EUNIT_TEST_MODS)),'$(mod)') @@ -6237,7 +6336,7 @@ endif RELX ?= $(CURDIR)/relx RELX_CONFIG ?= $(CURDIR)/relx.config -RELX_URL ?= https://github.com/erlware/relx/releases/download/v3.5.0/relx +RELX_URL ?= https://github.com/erlware/relx/releases/download/v3.19.0/relx RELX_OPTS ?= RELX_OUTPUT_DIR ?= _rel @@ -6379,9 +6478,9 @@ endif # Configuration. ifeq ($(XREF_CONFIG),) - XREF_ARGS := + XREFR_ARGS := else - XREF_ARGS := -c $(XREF_CONFIG) + XREFR_ARGS := -c $(XREF_CONFIG) endif XREFR ?= $(CURDIR)/xrefr @@ -6505,7 +6604,8 @@ define cover_report.erl true -> N - 1; false -> N end}} || {M, {Y, N}} <- Report], TotalY = lists:sum([Y || {_, {Y, _}} <- Report1]), TotalN = lists:sum([N || {_, {_, N}} <- Report1]), - TotalPerc = round(100 * TotalY / (TotalY + TotalN)), + Perc = fun(Y, N) -> case Y + N of 0 -> 100; S -> round(100 * Y / S) end end, + TotalPerc = Perc(TotalY, TotalN), {ok, F} = file:open("$(COVER_REPORT_DIR)/index.html", [write]), io:format(F, "<!DOCTYPE html><html>~n" "<head><meta charset=\"UTF-8\">~n" @@ -6515,7 +6615,7 @@ define cover_report.erl io:format(F, "<table><tr><th>Module</th><th>Coverage</th></tr>~n", []), [io:format(F, "<tr><td><a href=\"~p.COVER.html\">~p</a></td>" "<td>~p%</td></tr>~n", - [M, M, round(100 * Y / (Y + N))]) || {M, {Y, N}} <- Report1], + [M, M, Perc(Y, N)]) || {M, {Y, N}} <- Report1], How = "$(subst $(space),$(comma)$(space),$(basename $(COVERDATA)))", Date = "$(shell date -u "+%Y-%m-%dT%H:%M:%SZ")", io:format(F, "</table>~n" @@ -6532,62 +6632,95 @@ endif endif # ifneq ($(COVER_REPORT_DIR),) # Copyright (c) 2013-2015, Loïc Hoguin <essen@ninenines.eu> -# Copyright (c) 2015, Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> +# Copyright (c) 2015-2016, Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> # This file is part of erlang.mk and subject to the terms of the ISC License. -# Fetch dependencies (without building them). +# Fetch dependencies recursively (without building them). .PHONY: fetch-deps fetch-doc-deps fetch-rel-deps fetch-test-deps \ fetch-shell-deps +.PHONY: $(ERLANG_MK_RECURSIVE_DEPS_LIST) \ + $(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) \ + $(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) \ + $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \ + $(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST) + +fetch-deps: $(ERLANG_MK_RECURSIVE_DEPS_LIST) +fetch-doc-deps: $(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) +fetch-rel-deps: $(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) +fetch-test-deps: $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) +fetch-shell-deps: $(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST) + ifneq ($(SKIP_DEPS),) -fetch-deps fetch-doc-deps fetch-rel-deps fetch-test-deps fetch-shell-deps: - @: +$(ERLANG_MK_RECURSIVE_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): + $(verbose) :> $@ else # By default, we fetch "normal" dependencies. They are also included no # matter the type of requested dependencies. # # $(ALL_DEPS_DIRS) includes $(BUILD_DEPS). -fetch-deps: $(ALL_DEPS_DIRS) -fetch-doc-deps: $(ALL_DEPS_DIRS) $(ALL_DOC_DEPS_DIRS) -fetch-rel-deps: $(ALL_DEPS_DIRS) $(ALL_REL_DEPS_DIRS) -fetch-test-deps: $(ALL_DEPS_DIRS) $(ALL_TEST_DEPS_DIRS) -fetch-shell-deps: $(ALL_DEPS_DIRS) $(ALL_SHELL_DEPS_DIRS) + +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST): $(ALL_DEPS_DIRS) $(ALL_DOC_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST): $(ALL_DEPS_DIRS) $(ALL_REL_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST): $(ALL_DEPS_DIRS) $(ALL_TEST_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): $(ALL_DEPS_DIRS) $(ALL_SHELL_DEPS_DIRS) # Allow to use fetch-deps and $(DEP_TYPES) to fetch multiple types of # dependencies with a single target. ifneq ($(filter doc,$(DEP_TYPES)),) -fetch-deps: $(ALL_DOC_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_DOC_DEPS_DIRS) endif ifneq ($(filter rel,$(DEP_TYPES)),) -fetch-deps: $(ALL_REL_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_REL_DEPS_DIRS) endif ifneq ($(filter test,$(DEP_TYPES)),) -fetch-deps: $(ALL_TEST_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_TEST_DEPS_DIRS) endif ifneq ($(filter shell,$(DEP_TYPES)),) -fetch-deps: $(ALL_SHELL_DEPS_DIRS) +$(ERLANG_MK_RECURSIVE_DEPS_LIST): $(ALL_SHELL_DEPS_DIRS) endif -fetch-deps fetch-doc-deps fetch-rel-deps fetch-test-deps fetch-shell-deps: +ERLANG_MK_RECURSIVE_TMP_LIST := $(abspath $(ERLANG_MK_TMP)/recursive-tmp-deps.log) + +$(ERLANG_MK_RECURSIVE_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \ +$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): +ifeq ($(IS_APP)$(IS_DEP),) + $(verbose) mkdir -p $(ERLANG_MK_TMP) + $(verbose) rm -f $(ERLANG_MK_RECURSIVE_TMP_LIST) +endif ifndef IS_APP $(verbose) for dep in $(ALL_APPS_DIRS) ; do \ - $(MAKE) -C $$dep $@ IS_APP=1 || exit $$?; \ + $(MAKE) -C $$dep $@ \ + IS_APP=1 \ + ERLANG_MK_RECURSIVE_TMP_LIST=$(ERLANG_MK_RECURSIVE_TMP_LIST) \ + || exit $$?; \ done endif -ifneq ($(IS_DEP),1) - $(verbose) rm -f $(ERLANG_MK_TMP)/$@.log -endif - $(verbose) mkdir -p $(ERLANG_MK_TMP) $(verbose) for dep in $^ ; do \ - if ! grep -qs ^$$dep$$ $(ERLANG_MK_TMP)/$@.log; then \ - echo $$dep >> $(ERLANG_MK_TMP)/$@.log; \ + if ! grep -qs ^$$dep$$ $(ERLANG_MK_RECURSIVE_TMP_LIST); then \ + echo $$dep >> $(ERLANG_MK_RECURSIVE_TMP_LIST); \ if grep -qs -E "^[[:blank:]]*include[[:blank:]]+(erlang\.mk|.*/erlang\.mk)$$" \ $$dep/GNUmakefile $$dep/makefile $$dep/Makefile; then \ - $(MAKE) -C $$dep fetch-deps IS_DEP=1 || exit $$?; \ + $(MAKE) -C $$dep fetch-deps \ + IS_DEP=1 \ + ERLANG_MK_RECURSIVE_TMP_LIST=$(ERLANG_MK_RECURSIVE_TMP_LIST) \ + || exit $$?; \ fi \ fi \ done +ifeq ($(IS_APP)$(IS_DEP),) + $(verbose) sort < $(ERLANG_MK_RECURSIVE_TMP_LIST) | uniq > $@ + $(verbose) rm $(ERLANG_MK_RECURSIVE_TMP_LIST) +endif endif # ifneq ($(SKIP_DEPS),) # List dependencies recursively. @@ -6595,108 +6728,11 @@ endif # ifneq ($(SKIP_DEPS),) .PHONY: list-deps list-doc-deps list-rel-deps list-test-deps \ list-shell-deps -ifneq ($(SKIP_DEPS),) -$(ERLANG_MK_RECURSIVE_DEPS_LIST) \ -$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) \ -$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) \ -$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \ -$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): - $(verbose) :> $@ -else -LIST_DIRS = $(ALL_DEPS_DIRS) -LIST_DEPS = $(BUILD_DEPS) $(DEPS) - -$(ERLANG_MK_RECURSIVE_DEPS_LIST): fetch-deps - -ifneq ($(IS_DEP),1) -$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST): LIST_DIRS += $(ALL_DOC_DEPS_DIRS) -$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST): LIST_DEPS += $(DOC_DEPS) -$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST): fetch-doc-deps -else -$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST): fetch-deps -endif - -ifneq ($(IS_DEP),1) -$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST): LIST_DIRS += $(ALL_REL_DEPS_DIRS) -$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST): LIST_DEPS += $(REL_DEPS) -$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST): fetch-rel-deps -else -$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST): fetch-deps -endif - -ifneq ($(IS_DEP),1) -$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST): LIST_DIRS += $(ALL_TEST_DEPS_DIRS) -$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST): LIST_DEPS += $(TEST_DEPS) -$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST): fetch-test-deps -else -$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST): fetch-deps -endif - -ifneq ($(IS_DEP),1) -$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): LIST_DIRS += $(ALL_SHELL_DEPS_DIRS) -$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): LIST_DEPS += $(SHELL_DEPS) -$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): fetch-shell-deps -else -$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): fetch-deps -endif - -$(ERLANG_MK_RECURSIVE_DEPS_LIST) \ -$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) \ -$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) \ -$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \ -$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST): -ifneq ($(IS_DEP),1) - $(verbose) rm -f $@.orig -endif -ifndef IS_APP - $(verbose) for app in $(filter-out $(CURDIR),$(ALL_APPS_DIRS)); do \ - $(MAKE) -C "$$app" --no-print-directory $@ IS_APP=1 || :; \ - done -endif - $(verbose) for dep in $(filter-out $(CURDIR),$(LIST_DIRS)); do \ - if grep -qs -E "^[[:blank:]]*include[[:blank:]]+(erlang\.mk|.*/erlang\.mk)$$" \ - $$dep/GNUmakefile $$dep/makefile $$dep/Makefile; then \ - $(MAKE) -C "$$dep" --no-print-directory $@ IS_DEP=1; \ - fi; \ - done - $(verbose) for dep in $(LIST_DEPS); do \ - echo $(DEPS_DIR)/$$dep; \ - done >> $@.orig -ifndef IS_APP -ifneq ($(IS_DEP),1) - $(verbose) sort < $@.orig | uniq > $@ - $(verbose) rm -f $@.orig -endif -endif -endif # ifneq ($(SKIP_DEPS),) - -ifneq ($(SKIP_DEPS),) -list-deps list-doc-deps list-rel-deps list-test-deps list-shell-deps: - @: -else list-deps: $(ERLANG_MK_RECURSIVE_DEPS_LIST) list-doc-deps: $(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) list-rel-deps: $(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) list-test-deps: $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) list-shell-deps: $(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST) -# Allow to use fetch-deps and $(DEP_TYPES) to fetch multiple types of -# dependencies with a single target. -ifneq ($(IS_DEP),1) -ifneq ($(filter doc,$(DEP_TYPES)),) -list-deps: $(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST) -endif -ifneq ($(filter rel,$(DEP_TYPES)),) -list-deps: $(ERLANG_MK_RECURSIVE_REL_DEPS_LIST) -endif -ifneq ($(filter test,$(DEP_TYPES)),) -list-deps: $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) -endif -ifneq ($(filter shell,$(DEP_TYPES)),) -list-deps: $(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST) -endif -endif - list-deps list-doc-deps list-rel-deps list-test-deps list-shell-deps: - $(verbose) cat $^ | sort | uniq -endif # ifneq ($(SKIP_DEPS),) + $(verbose) cat $^ diff --git a/include/rabbit_cli.hrl b/include/rabbit_cli.hrl index a0d1ecfdd5..b1cf41261f 100644 --- a/include/rabbit_cli.hrl +++ b/include/rabbit_cli.hrl @@ -29,6 +29,7 @@ -define(RAM_OPT, "--ram"). -define(OFFLINE_OPT, "--offline"). -define(ONLINE_OPT, "--online"). +-define(LOCAL_OPT, "--local"). -define(NODE_DEF(Node), {?NODE_OPT, {option, Node}}). @@ -46,6 +47,7 @@ -define(RAM_DEF, {?RAM_OPT, flag}). -define(OFFLINE_DEF, {?OFFLINE_OPT, flag}). -define(ONLINE_DEF, {?ONLINE_OPT, flag}). +-define(LOCAL_DEF, {?LOCAL_OPT, flag}). %% Subset of standartized exit codes from sysexits.h, see %% https://github.com/rabbitmq/rabbitmq-server/issues/396 for discussion. diff --git a/packaging/Makefile b/packaging/Makefile deleted file mode 100644 index 31b85d9c1f..0000000000 --- a/packaging/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -# Platform detection. - -ifeq ($(PLATFORM),) -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Linux) -PLATFORM = linux -else ifeq ($(UNAME_S),Darwin) -PLATFORM = darwin -else ifeq ($(UNAME_S),SunOS) -PLATFORM = solaris -else ifeq ($(UNAME_S),GNU) -PLATFORM = gnu -else ifeq ($(UNAME_S),FreeBSD) -PLATFORM = freebsd -else ifeq ($(UNAME_S),NetBSD) -PLATFORM = netbsd -else ifeq ($(UNAME_S),OpenBSD) -PLATFORM = openbsd -else ifeq ($(UNAME_S),DragonFly) -PLATFORM = dragonfly -else ifeq ($(shell uname -o),Msys) -PLATFORM = msys2 -else -$(error Unable to detect platform. Please open a ticket with the output of uname -a.) -endif -endif - -all: packages - @: - -# -------------------------------------------------------------------- -# Packaging. -# -------------------------------------------------------------------- - -.PHONY: packages package-deb \ - package-rpm package-rpm-fedora package-rpm-suse \ - package-windows package-standalone-macosx \ - package-generic-unix - -PACKAGES_DIR ?= ../PACKAGES -SOURCE_DIST_FILE ?= $(wildcard $(PACKAGES_DIR)/rabbitmq-server-*.tar.xz) - -ifneq ($(filter-out clean,$(MAKECMDGOALS)),) -ifeq ($(SOURCE_DIST_FILE),) -$(error Cannot find source archive; please specify SOURCE_DIST_FILE) -endif -ifneq ($(words $(SOURCE_DIST_FILE)),1) -$(error Multile source archives found; please specify SOURCE_DIST_FILE) -endif -ifeq ($(filter %.tar.xz %.txz,$(SOURCE_DIST_FILE)),) -$(error The source archive must a tar.xz archive) -endif -ifeq ($(wildcard $(SOURCE_DIST_FILE)),) -$(error The source archive must exist) -endif -endif - -ifndef NO_CLEAN -DO_CLEAN := clean -endif - -VARS = SOURCE_DIST_FILE="$(abspath $(SOURCE_DIST_FILE))" \ - PACKAGES_DIR="$(abspath $(PACKAGES_DIR))" \ - SIGNING_KEY="$(SIGNING_KEY)" - -packages: package-deb package-rpm package-windows package-generic-unix - @: - -package-deb: $(SOURCE_DIST_FILE) - $(gen_verbose) $(MAKE) -C debs/Debian $(VARS) all $(DO_CLEAN) - -package-rpm: package-rpm-fedora package-rpm-suse - @: - -package-rpm-fedora: $(SOURCE_DIST_FILE) - $(gen_verbose) $(MAKE) -C RPMS/Fedora $(VARS) all $(DO_CLEAN) - -package-rpm-suse: $(SOURCE_DIST_FILE) - $(gen_verbose) $(MAKE) -C RPMS/Fedora $(VARS) RPM_OS=suse all $(DO_CLEAN) - -package-windows: $(SOURCE_DIST_FILE) - $(gen_verbose) $(MAKE) -C windows $(VARS) all $(DO_CLEAN) - $(verbose) $(MAKE) -C windows-exe $(VARS) all $(DO_CLEAN) - -package-generic-unix: $(SOURCE_DIST_FILE) - $(gen_verbose) $(MAKE) -C generic-unix $(VARS) all $(DO_CLEAN) - -ifeq ($(PLATFORM),darwin) -packages: package-standalone-macosx - -package-standalone-macosx: $(SOURCE_DIST_FILE) - $(gen_verbose) $(MAKE) -C standalone $(VARS) OS=mac all $(DO_CLEAN) -endif - -.PHONY: clean - -clean: - for subdir in debs/Debian RPMS/Fedora windows windows-exe generic-unix standalone; do \ - $(MAKE) -C "$$subdir" clean; \ - done diff --git a/packaging/RPMS/Fedora/Makefile b/packaging/RPMS/Fedora/Makefile deleted file mode 100644 index 5763cadf04..0000000000 --- a/packaging/RPMS/Fedora/Makefile +++ /dev/null @@ -1,78 +0,0 @@ -SOURCE_DIST_FILE ?= $(wildcard ../../../rabbitmq-server-*.tar.xz) - -ifneq ($(filter-out clean,$(MAKECMDGOALS)),) -ifeq ($(SOURCE_DIST_FILE),) -$(error Cannot find source archive; please specify SOURCE_DIST_FILE) -endif -ifneq ($(words $(SOURCE_DIST_FILE)),1) -$(error Multile source archives found; please specify SOURCE_DIST_FILE) -endif - -VERSION ?= $(patsubst rabbitmq-server-%.tar.xz,%,$(notdir $(SOURCE_DIST_FILE))) -ifeq ($(VERSION),) -$(error Cannot determine version; please specify VERSION) -endif -endif - -TOP_DIR = $(shell pwd) -# Under debian we do not want to check build dependencies, since that -# only checks build-dependencies using rpms, not debs -DEFINES = --define '_topdir $(TOP_DIR)' --define '_tmppath $(TOP_DIR)/tmp' \ - --define '_sysconfdir /etc' --define '_localstatedir /var' - -ifndef RPM_OS -RPM_OS = fedora -endif - -ifeq "$(RPM_OS)" "suse" -FUNCTION_LIBRARY= -REQUIRES=/sbin/chkconfig /sbin/service -OS_DEFINES=--define '_initrddir /etc/init.d' --define 'dist .suse' -SPEC_DEFINES=--define 'group_tag Productivity/Networking/Other' -START_PROG=startproc -else -FUNCTION_LIBRARY=\# Source function library.\n. /etc/init.d/functions -REQUIRES=chkconfig initscripts -OS_DEFINES=--define '_initrddir /etc/rc.d/init.d' -SPEC_DEFINES=--define 'group_tag Development/Libraries' -START_PROG=daemon -endif - -unexport DEPS_DIR -unexport ERL_LIBS - -.PHONY: all prepare server clean - -all: clean server - @: - -prepare: - mkdir -p BUILD SOURCES SPECS SRPMS RPMS tmp - cp $(SOURCE_DIST_FILE) SOURCES - cp rabbitmq-server.spec SPECS - sed -i 's|%%VERSION%%|$(VERSION)|;s|%%REQUIRES%%|$(REQUIRES)|' \ - SPECS/rabbitmq-server.spec - - cp rabbitmq-server.init SOURCES/rabbitmq-server.init - sed -i \ - -e 's|^START_PROG=.*$$|START_PROG="$(START_PROG)"|' \ - -e 's|^@FUNCTION_LIBRARY@|$(FUNCTION_LIBRARY)|' \ - SOURCES/rabbitmq-server.init -ifeq "$(RPM_OS)" "fedora" -# Fedora says that only vital services should have Default-Start - sed -i -e '/^# Default-Start:/d;/^# Default-Stop:/d' \ - SOURCES/rabbitmq-server.init -endif - - cp rabbitmq-server.logrotate SOURCES/rabbitmq-server.logrotate - -server: prepare - rpmbuild -ba --nodeps SPECS/rabbitmq-server.spec $(DEFINES) $(OS_DEFINES) $(SPEC_DEFINES) - - if test "$(PACKAGES_DIR)"; then \ - mkdir -p "$(PACKAGES_DIR)"; \ - mv SRPMS/*.rpm RPMS/noarch/*.rpm "$(PACKAGES_DIR)"; \ - fi - -clean: - rm -rf SOURCES SPECS RPMS SRPMS BUILD tmp diff --git a/packaging/RPMS/Fedora/rabbitmq-server.init b/packaging/RPMS/Fedora/rabbitmq-server.init deleted file mode 100644 index 15929108b5..0000000000 --- a/packaging/RPMS/Fedora/rabbitmq-server.init +++ /dev/null @@ -1,184 +0,0 @@ -#!/bin/sh -# -# rabbitmq-server RabbitMQ broker -# -# chkconfig: - 80 05 -# description: Enable AMQP service provided by RabbitMQ -# - -### BEGIN INIT INFO -# Provides: rabbitmq-server -# Required-Start: $remote_fs $network -# Required-Stop: $remote_fs $network -# Default-Start: 3 5 -# Default-Stop: 0 1 2 6 -# Description: RabbitMQ broker -# Short-Description: Enable AMQP service provided by RabbitMQ broker -### END INIT INFO - -@FUNCTION_LIBRARY@ - -PATH=/sbin:/usr/sbin:/bin:/usr/bin -NAME=rabbitmq-server -DAEMON=/usr/sbin/${NAME} -CONTROL=/usr/sbin/rabbitmqctl -DESC=rabbitmq-server -USER=rabbitmq -ROTATE_SUFFIX= -PID_FILE=/var/run/rabbitmq/pid -RABBITMQ_ENV=/usr/lib/rabbitmq/bin/rabbitmq-env - -START_PROG= # Set when building package -LOCK_FILE=/var/lock/subsys/$NAME - -test -x $DAEMON || exit 0 -test -x $CONTROL || exit 0 - -RETVAL=0 -set -e - -[ -f /etc/default/${NAME} ] && . /etc/default/${NAME} - -RABBITMQ_SCRIPTS_DIR=$(dirname "$RABBITMQ_ENV") -. "$RABBITMQ_ENV" - -ensure_pid_dir () { - PID_DIR=`dirname ${PID_FILE}` - if [ ! -d ${PID_DIR} ] ; then - mkdir -p ${PID_DIR} - chown -R ${USER}:${USER} ${PID_DIR} - chmod 755 ${PID_DIR} - fi -} - -remove_pid () { - rm -f ${PID_FILE} - rmdir `dirname ${PID_FILE}` || : -} - -start_rabbitmq () { - status_rabbitmq quiet - if [ $RETVAL = 0 ] ; then - echo RabbitMQ is currently running - else - RETVAL=0 - ensure_pid_dir - set +e - RABBITMQ_PID_FILE=$PID_FILE $START_PROG $DAEMON \ - > "${RABBITMQ_LOG_BASE}/startup_log" \ - 2> "${RABBITMQ_LOG_BASE}/startup_err" \ - 0<&- & - $CONTROL wait $PID_FILE >/dev/null 2>&1 - RETVAL=$? - set -e - case "$RETVAL" in - 0) - echo SUCCESS - if [ -n "$LOCK_FILE" ] ; then - touch $LOCK_FILE - fi - ;; - *) - remove_pid - echo FAILED - check ${RABBITMQ_LOG_BASE}/startup_\{log, _err\} - RETVAL=1 - ;; - esac - fi -} - -stop_rabbitmq () { - status_rabbitmq quiet - if [ $RETVAL = 0 ] ; then - set +e - $CONTROL stop ${PID_FILE} \ - > ${RABBITMQ_LOG_BASE}/shutdown_log \ - 2> ${RABBITMQ_LOG_BASE}/shutdown_err - RETVAL=$? - set -e - if [ $RETVAL = 0 ] ; then - remove_pid - if [ -n "$LOCK_FILE" ] ; then - rm -f $LOCK_FILE - fi - else - echo FAILED - check ${RABBITMQ_LOG_BASE}/shutdown_log, _err - fi - else - echo RabbitMQ is not running - RETVAL=0 - fi -} - -status_rabbitmq() { - set +e - if [ "$1" != "quiet" ] ; then - $CONTROL status 2>&1 - else - $CONTROL status > /dev/null 2>&1 - fi - if [ $? != 0 ] ; then - RETVAL=3 - fi - set -e -} - -rotate_logs_rabbitmq() { - set +e - $CONTROL rotate_logs ${ROTATE_SUFFIX} - if [ $? != 0 ] ; then - RETVAL=1 - fi - set -e -} - -restart_running_rabbitmq () { - status_rabbitmq quiet - if [ $RETVAL = 0 ] ; then - restart_rabbitmq - else - echo RabbitMQ is not runnning - RETVAL=0 - fi -} - -restart_rabbitmq() { - stop_rabbitmq - start_rabbitmq -} - -case "$1" in - start) - echo -n "Starting $DESC: " - start_rabbitmq - echo "$NAME." - ;; - stop) - echo -n "Stopping $DESC: " - stop_rabbitmq - echo "$NAME." - ;; - status) - status_rabbitmq - ;; - rotate-logs) - echo -n "Rotating log files for $DESC: " - rotate_logs_rabbitmq - ;; - force-reload|reload|restart) - echo -n "Restarting $DESC: " - restart_rabbitmq - echo "$NAME." - ;; - try-restart) - echo -n "Restarting $DESC: " - restart_running_rabbitmq - echo "$NAME." - ;; - *) - echo "Usage: $0 {start|stop|status|rotate-logs|restart|condrestart|try-restart|reload|force-reload}" >&2 - RETVAL=1 - ;; -esac - -exit $RETVAL diff --git a/packaging/RPMS/Fedora/rabbitmq-server.logrotate b/packaging/RPMS/Fedora/rabbitmq-server.logrotate deleted file mode 100644 index f902ed185f..0000000000 --- a/packaging/RPMS/Fedora/rabbitmq-server.logrotate +++ /dev/null @@ -1,12 +0,0 @@ -/var/log/rabbitmq/*.log { - weekly - missingok - rotate 20 - compress - delaycompress - notifempty - sharedscripts - postrotate - /usr/sbin/rabbitmqctl rotate_logs > /dev/null - endscript -} diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec deleted file mode 100644 index 22def97243..0000000000 --- a/packaging/RPMS/Fedora/rabbitmq-server.spec +++ /dev/null @@ -1,334 +0,0 @@ -%define debug_package %{nil} - -Name: rabbitmq-server -Version: %%VERSION%% -Release: 1%{?dist} -License: MPLv1.1 and MIT and ASL 2.0 and BSD -Group: %{group_tag} -Source: http://www.rabbitmq.com/releases/rabbitmq-server/v%{version}/%{name}-%{version}.tar.xz -Source1: rabbitmq-server.init -Source2: rabbitmq-server.logrotate -URL: http://www.rabbitmq.com/ -BuildArch: noarch -BuildRequires: erlang >= R16B-03, python-simplejson, xmlto, libxslt, gzip, sed, zip, rsync -Requires: erlang >= R16B-03, logrotate, socat -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%{_arch}-root -Summary: The RabbitMQ server -Requires(post): %%REQUIRES%% -Requires(pre): %%REQUIRES%% - -%description -RabbitMQ is an open source multi-protocol messaging broker. - -# We want to install into /usr/lib, even on 64-bit platforms -%define _rabbit_libdir %{_exec_prefix}/lib/rabbitmq -%define _rabbit_erllibdir %{_rabbit_libdir}/lib/rabbitmq_server-%{version} -%define _rabbit_server_ocf scripts/rabbitmq-server.ocf -%define _plugins_state_dir %{_localstatedir}/lib/rabbitmq/plugins -%define _rabbit_server_ha_ocf scripts/rabbitmq-server-ha.ocf - - -%define _maindir %{buildroot}%{_rabbit_erllibdir} - - -%prep -%setup -q - -%build -cp -a docs/README-for-packages %{_builddir}/rabbitmq-server-%{version}/README -make %{?_smp_mflags} dist manpages - -%install -rm -rf %{buildroot} - -make install install-bin install-man DESTDIR=%{buildroot} PREFIX=%{_exec_prefix} RMQ_ROOTDIR=%{_rabbit_libdir} MANDIR=%{_mandir} - -mkdir -p %{buildroot}%{_localstatedir}/lib/rabbitmq/mnesia -mkdir -p %{buildroot}%{_localstatedir}/log/rabbitmq - -#Copy all necessary lib files etc. -install -p -D -m 0755 %{S:1} %{buildroot}%{_initrddir}/rabbitmq-server -install -p -D -m 0755 %{_rabbit_server_ocf} %{buildroot}%{_exec_prefix}/lib/ocf/resource.d/rabbitmq/rabbitmq-server -install -p -D -m 0755 %{_rabbit_server_ha_ocf} %{buildroot}%{_exec_prefix}/lib/ocf/resource.d/rabbitmq/rabbitmq-server-ha -install -p -D -m 0644 %{S:2} %{buildroot}%{_sysconfdir}/logrotate.d/rabbitmq-server - -mkdir -p %{buildroot}%{_sysconfdir}/rabbitmq - -mkdir -p %{buildroot}%{_sbindir} -sed -e 's|@SU_RABBITMQ_SH_C@|su rabbitmq -s /bin/sh -c|' \ - -e 's|@STDOUT_STDERR_REDIRECTION@||' \ - < scripts/rabbitmq-script-wrapper \ - > %{buildroot}%{_sbindir}/rabbitmqctl -chmod 0755 %{buildroot}%{_sbindir}/rabbitmqctl -for script in rabbitmq-server rabbitmq-plugins; do \ - cp -a %{buildroot}%{_sbindir}/rabbitmqctl \ - %{buildroot}%{_sbindir}/$script; \ -done - -rm %{_maindir}/LICENSE* %{_maindir}/INSTALL - -#Build the list of files -echo '%defattr(-,root,root, -)' >%{_builddir}/%{name}.files -find %{buildroot} -path %{buildroot}%{_sysconfdir} -prune -o '!' -type d -printf "/%%P\n" >>%{_builddir}/%{name}.files - -%pre - -if [ $1 -gt 1 ]; then - # Upgrade - stop previous instance of rabbitmq-server init.d script - /sbin/service rabbitmq-server stop -fi - -# create rabbitmq group -if ! getent group rabbitmq >/dev/null; then - groupadd -r rabbitmq -fi - -# create rabbitmq user -if ! getent passwd rabbitmq >/dev/null; then - useradd -r -g rabbitmq -d %{_localstatedir}/lib/rabbitmq rabbitmq \ - -c "RabbitMQ messaging server" -fi - -%post -/sbin/chkconfig --add %{name} -if [ -f %{_sysconfdir}/rabbitmq/rabbitmq.conf ] && [ ! -f %{_sysconfdir}/rabbitmq/rabbitmq-env.conf ]; then - mv %{_sysconfdir}/rabbitmq/rabbitmq.conf %{_sysconfdir}/rabbitmq/rabbitmq-env.conf -fi -chmod -R o-rwx,g-w %{_localstatedir}/lib/rabbitmq/mnesia - -%preun -if [ $1 = 0 ]; then - #Complete uninstall - /sbin/service rabbitmq-server stop - /sbin/chkconfig --del rabbitmq-server - - # We do not remove /var/log and /var/lib directories - # Leave rabbitmq user and group -fi - -# Clean out plugin activation state, both on uninstall and upgrade -rm -rf %{_plugins_state_dir} -for ext in rel script boot ; do - rm -f %{_rabbit_erllibdir}/ebin/rabbit.$ext -done - -%files -f ../%{name}.files -%defattr(-,root,root,-) -%attr(0755, rabbitmq, rabbitmq) %dir %{_localstatedir}/lib/rabbitmq -%attr(0750, rabbitmq, rabbitmq) %dir %{_localstatedir}/lib/rabbitmq/mnesia -%attr(0755, rabbitmq, rabbitmq) %dir %{_localstatedir}/log/rabbitmq -%dir %{_sysconfdir}/rabbitmq -%{_initrddir}/rabbitmq-server -%config(noreplace) %{_sysconfdir}/logrotate.d/rabbitmq-server -%doc LICENSE* -%doc README -%doc docs/rabbitmq.config.example -%doc docs/set_rabbitmq_policy.sh.example - -%clean -rm -rf %{buildroot} - -%changelog -* Wed Jul 6 2016 michael@rabbitmq.com 3.6.3-1 -- New Upstream Release - -* Thu May 19 2016 michael@rabbitmq.com 3.6.2-1 -- New Upstream Release - -* Tue Mar 1 2016 michael@rabbitmq.com 3.6.1-1 -- New Upstream Release - -* Tue Dec 22 2015 michael@rabbitmq.com 3.6.0-1 -- New Upstream Release - -* Tue Dec 15 2015 michael@rabbitmq.com 3.5.7-1 -- New Upstream Release - -* Wed Oct 7 2015 michael@rabbitmq.com 3.5.6-1 -- New Upstream Release - -* Thu Sep 24 2015 jean-sebastien@rabbitmq.com 3.5.5-3 -- Fix bashism in rabbitmq-script-wrapper - -* Thu Sep 24 2015 jean-sebastien@rabbitmq.com 3.5.5-1 -- New Upstream Release - -* Tue Jul 21 2015 michael@rabbitmq.com 3.5.4-1 -- New Upstream Release - -* Fri May 22 2015 jean-sebastien@rabbitmq.com 3.5.3-1 -- New Upstream Release - -* Tue May 12 2015 jean-sebastien@rabbitmq.com 3.5.2-1 -- New Upstream Release - -* Thu Apr 2 2015 michael@rabbitmq.com 3.5.1-1 -- New Upstream Release - -* Wed Mar 11 2015 jean-sebastien@rabbitmq.com 3.5.0-1 -- New Upstream Release - -* Wed Feb 11 2015 michael@rabbitmq.com 3.4.4-1 -- New Upstream Release - -* Tue Jan 6 2015 jean-sebastien@rabbitmq.com 3.4.3-1 -- New Upstream Release - -* Wed Nov 26 2014 simon@rabbitmq.com 3.4.2-1 -- New Upstream Release - -* Wed Oct 29 2014 simon@rabbitmq.com 3.4.1-1 -- New Upstream Release - -* Tue Oct 21 2014 simon@rabbitmq.com 3.4.0-1 -- New Upstream Release - -* Mon Aug 11 2014 simon@rabbitmq.com 3.3.5-1 -- New Upstream Release - -* Tue Jun 24 2014 simon@rabbitmq.com 3.3.4-1 -- New Upstream Release - -* Mon Jun 16 2014 simon@rabbitmq.com 3.3.3-1 -- New Upstream Release - -* Mon Jun 9 2014 simon@rabbitmq.com 3.3.2-1 -- New Upstream Release - -* Tue Apr 29 2014 simon@rabbitmq.com 3.3.1-1 -- New Upstream Release - -* Wed Apr 2 2014 simon@rabbitmq.com 3.3.0-1 -- New Upstream Release - -* Mon Mar 3 2014 simon@rabbitmq.com 3.2.4-1 -- New Upstream Release - -* Thu Jan 23 2014 emile@rabbitmq.com 3.2.3-1 -- New Upstream Release - -* Tue Dec 10 2013 emile@rabbitmq.com 3.2.2-1 -- New Upstream Release - -* Wed Oct 23 2013 emile@rabbitmq.com 3.2.0-1 -- New Upstream Release - -* Thu Aug 15 2013 simon@rabbitmq.com 3.1.5-1 -- New Upstream Release - -* Tue Jun 25 2013 tim@rabbitmq.com 3.1.3-1 -- New Upstream Release - -* Mon Jun 24 2013 tim@rabbitmq.com 3.1.2-1 -- New Upstream Release - -* Mon May 20 2013 tim@rabbitmq.com 3.1.1-1 -- Test release - -* Wed May 1 2013 simon@rabbitmq.com 3.1.0-1 -- New Upstream Release - -* Tue Dec 11 2012 simon@rabbitmq.com 3.0.1-1 -- New Upstream Release - -* Fri Nov 16 2012 simon@rabbitmq.com 3.0.0-1 -- New Upstream Release - -* Fri Dec 16 2011 steve@rabbitmq.com 2.7.1-1 -- New Upstream Release - -* Tue Nov 8 2011 steve@rabbitmq.com 2.7.0-1 -- New Upstream Release - -* Fri Sep 9 2011 tim@rabbitmq.com 2.6.1-1 -- New Upstream Release - -* Fri Aug 26 2011 tim@rabbitmq.com 2.6.0-1 -- New Upstream Release - -* Mon Jun 27 2011 simon@rabbitmq.com 2.5.1-1 -- New Upstream Release - -* Thu Jun 9 2011 jerryk@vmware.com 2.5.0-1 -- New Upstream Release - -* Thu Apr 7 2011 Alexandru Scvortov <alexandru@rabbitmq.com> 2.4.1-1 -- New Upstream Release - -* Tue Mar 22 2011 Alexandru Scvortov <alexandru@rabbitmq.com> 2.4.0-1 -- New Upstream Release - -* Thu Feb 3 2011 simon@rabbitmq.com 2.3.1-1 -- New Upstream Release - -* Tue Feb 1 2011 simon@rabbitmq.com 2.3.0-1 -- New Upstream Release - -* Mon Nov 29 2010 rob@rabbitmq.com 2.2.0-1 -- New Upstream Release - -* Tue Oct 19 2010 vlad@rabbitmq.com 2.1.1-1 -- New Upstream Release - -* Tue Sep 14 2010 marek@rabbitmq.com 2.1.0-1 -- New Upstream Release - -* Mon Aug 23 2010 mikeb@rabbitmq.com 2.0.0-1 -- New Upstream Release - -* Wed Jul 14 2010 Emile Joubert <emile@rabbitmq.com> 1.8.1-1 -- New Upstream Release - -* Tue Jun 15 2010 Matthew Sackman <matthew@rabbitmq.com> 1.8.0-1 -- New Upstream Release - -* Mon Feb 15 2010 Matthew Sackman <matthew@lshift.net> 1.7.2-1 -- New Upstream Release - -* Fri Jan 22 2010 Matthew Sackman <matthew@lshift.net> 1.7.1-1 -- New Upstream Release - -* Mon Oct 5 2009 David Wragg <dpw@lshift.net> 1.7.0-1 -- New upstream release - -* Wed Jun 17 2009 Matthias Radestock <matthias@lshift.net> 1.6.0-1 -- New upstream release - -* Tue May 19 2009 Matthias Radestock <matthias@lshift.net> 1.5.5-1 -- Maintenance release for the 1.5.x series - -* Mon Apr 6 2009 Matthias Radestock <matthias@lshift.net> 1.5.4-1 -- Maintenance release for the 1.5.x series - -* Tue Feb 24 2009 Tony Garnock-Jones <tonyg@lshift.net> 1.5.3-1 -- Maintenance release for the 1.5.x series - -* Mon Feb 23 2009 Tony Garnock-Jones <tonyg@lshift.net> 1.5.2-1 -- Maintenance release for the 1.5.x series - -* Mon Jan 19 2009 Ben Hood <0x6e6562@gmail.com> 1.5.1-1 -- Maintenance release for the 1.5.x series - -* Wed Dec 17 2008 Matthias Radestock <matthias@lshift.net> 1.5.0-1 -- New upstream release - -* Thu Jul 24 2008 Tony Garnock-Jones <tonyg@lshift.net> 1.4.0-1 -- New upstream release - -* Mon Mar 3 2008 Adrien Pierard <adrian@lshift.net> 1.3.0-1 -- New upstream release - -* Wed Sep 26 2007 Simon MacMullen <simon@lshift.net> 1.2.0-1 -- New upstream release - -* Wed Aug 29 2007 Simon MacMullen <simon@lshift.net> 1.1.1-1 -- New upstream release - -* Mon Jul 30 2007 Simon MacMullen <simon@lshift.net> 1.1.0-1.alpha -- New upstream release - -* Tue Jun 12 2007 Hubert Plociniczak <hubert@lshift.net> 1.0.0-1.20070607 -- Building from source tarball, added starting script, stopping - -* Mon May 21 2007 Hubert Plociniczak <hubert@lshift.net> 1.0.0-1.alpha -- Initial build of server library of RabbitMQ package diff --git a/packaging/common/LICENSE.head b/packaging/common/LICENSE.head deleted file mode 100644 index 2b5a17ee46..0000000000 --- a/packaging/common/LICENSE.head +++ /dev/null @@ -1,5 +0,0 @@ -This package, the RabbitMQ server is licensed under the MPL. - -If you have any questions regarding licensing, please contact us at -info@rabbitmq.com. - diff --git a/packaging/common/LICENSE.tail b/packaging/common/LICENSE.tail deleted file mode 100644 index 73c8e987fb..0000000000 --- a/packaging/common/LICENSE.tail +++ /dev/null @@ -1,516 +0,0 @@ - -The MIT license is as follows: - - "Permission is hereby granted, free of charge, to any person - obtaining a copy of this file (the Software), to deal in the - Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, - sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE." - - -The BSD 2-Clause license is as follows: - - "Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the - following conditions are met: - - 1. Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - - 2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." - - -The rest of this package is licensed under the Mozilla Public License 1.1 -Authors and Copyright are as described below: - - The Initial Developer of the Original Code is GoPivotal, Inc. - Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. - - - MOZILLA PUBLIC LICENSE - Version 1.1 - - --------------- - -1. Definitions. - - 1.0.1. "Commercial Use" means distribution or otherwise making the - Covered Code available to a third party. - - 1.1. "Contributor" means each entity that creates or contributes to - the creation of Modifications. - - 1.2. "Contributor Version" means the combination of the Original - Code, prior Modifications used by a Contributor, and the Modifications - made by that particular Contributor. - - 1.3. "Covered Code" means the Original Code or Modifications or the - combination of the Original Code and Modifications, in each case - including portions thereof. - - 1.4. "Electronic Distribution Mechanism" means a mechanism generally - accepted in the software development community for the electronic - transfer of data. - - 1.5. "Executable" means Covered Code in any form other than Source - Code. - - 1.6. "Initial Developer" means the individual or entity identified - as the Initial Developer in the Source Code notice required by Exhibit - A. - - 1.7. "Larger Work" means a work which combines Covered Code or - portions thereof with code not governed by the terms of this License. - - 1.8. "License" means this document. - - 1.8.1. "Licensable" means having the right to grant, to the maximum - extent possible, whether at the time of the initial grant or - subsequently acquired, any and all of the rights conveyed herein. - - 1.9. "Modifications" means any addition to or deletion from the - substance or structure of either the Original Code or any previous - Modifications. When Covered Code is released as a series of files, a - Modification is: - A. Any addition to or deletion from the contents of a file - containing Original Code or previous Modifications. - - B. Any new file that contains any part of the Original Code or - previous Modifications. - - 1.10. "Original Code" means Source Code of computer software code - which is described in the Source Code notice required by Exhibit A as - Original Code, and which, at the time of its release under this - License is not already Covered Code governed by this License. - - 1.10.1. "Patent Claims" means any patent claim(s), now owned or - hereafter acquired, including without limitation, method, process, - and apparatus claims, in any patent Licensable by grantor. - - 1.11. "Source Code" means the preferred form of the Covered Code for - making modifications to it, including all modules it contains, plus - any associated interface definition files, scripts used to control - compilation and installation of an Executable, or source code - differential comparisons against either the Original Code or another - well known, available Covered Code of the Contributor's choice. The - Source Code can be in a compressed or archival form, provided the - appropriate decompression or de-archiving software is widely available - for no charge. - - 1.12. "You" (or "Your") means an individual or a legal entity - exercising rights under, and complying with all of the terms of, this - License or a future version of this License issued under Section 6.1. - For legal entities, "You" includes any entity which controls, is - controlled by, or is under common control with You. For purposes of - this definition, "control" means (a) the power, direct or indirect, - to cause the direction or management of such entity, whether by - contract or otherwise, or (b) ownership of more than fifty percent - (50%) of the outstanding shares or beneficial ownership of such - entity. - -2. Source Code License. - - 2.1. The Initial Developer Grant. - The Initial Developer hereby grants You a world-wide, royalty-free, - non-exclusive license, subject to third party intellectual property - claims: - (a) under intellectual property rights (other than patent or - trademark) Licensable by Initial Developer to use, reproduce, - modify, display, perform, sublicense and distribute the Original - Code (or portions thereof) with or without Modifications, and/or - as part of a Larger Work; and - - (b) under Patents Claims infringed by the making, using or - selling of Original Code, to make, have made, use, practice, - sell, and offer for sale, and/or otherwise dispose of the - Original Code (or portions thereof). - - (c) the licenses granted in this Section 2.1(a) and (b) are - effective on the date Initial Developer first distributes - Original Code under the terms of this License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is - granted: 1) for code that You delete from the Original Code; 2) - separate from the Original Code; or 3) for infringements caused - by: i) the modification of the Original Code or ii) the - combination of the Original Code with other software or devices. - - 2.2. Contributor Grant. - Subject to third party intellectual property claims, each Contributor - hereby grants You a world-wide, royalty-free, non-exclusive license - - (a) under intellectual property rights (other than patent or - trademark) Licensable by Contributor, to use, reproduce, modify, - display, perform, sublicense and distribute the Modifications - created by such Contributor (or portions thereof) either on an - unmodified basis, with other Modifications, as Covered Code - and/or as part of a Larger Work; and - - (b) under Patent Claims infringed by the making, using, or - selling of Modifications made by that Contributor either alone - and/or in combination with its Contributor Version (or portions - of such combination), to make, use, sell, offer for sale, have - made, and/or otherwise dispose of: 1) Modifications made by that - Contributor (or portions thereof); and 2) the combination of - Modifications made by that Contributor with its Contributor - Version (or portions of such combination). - - (c) the licenses granted in Sections 2.2(a) and 2.2(b) are - effective on the date Contributor first makes Commercial Use of - the Covered Code. - - (d) Notwithstanding Section 2.2(b) above, no patent license is - granted: 1) for any code that Contributor has deleted from the - Contributor Version; 2) separate from the Contributor Version; - 3) for infringements caused by: i) third party modifications of - Contributor Version or ii) the combination of Modifications made - by that Contributor with other software (except as part of the - Contributor Version) or other devices; or 4) under Patent Claims - infringed by Covered Code in the absence of Modifications made by - that Contributor. - -3. Distribution Obligations. - - 3.1. Application of License. - The Modifications which You create or to which You contribute are - governed by the terms of this License, including without limitation - Section 2.2. The Source Code version of Covered Code may be - distributed only under the terms of this License or a future version - of this License released under Section 6.1, and You must include a - copy of this License with every copy of the Source Code You - distribute. You may not offer or impose any terms on any Source Code - version that alters or restricts the applicable version of this - License or the recipients' rights hereunder. However, You may include - an additional document offering the additional rights described in - Section 3.5. - - 3.2. Availability of Source Code. - Any Modification which You create or to which You contribute must be - made available in Source Code form under the terms of this License - either on the same media as an Executable version or via an accepted - Electronic Distribution Mechanism to anyone to whom you made an - Executable version available; and if made available via Electronic - Distribution Mechanism, must remain available for at least twelve (12) - months after the date it initially became available, or at least six - (6) months after a subsequent version of that particular Modification - has been made available to such recipients. You are responsible for - ensuring that the Source Code version remains available even if the - Electronic Distribution Mechanism is maintained by a third party. - - 3.3. Description of Modifications. - You must cause all Covered Code to which You contribute to contain a - file documenting the changes You made to create that Covered Code and - the date of any change. You must include a prominent statement that - the Modification is derived, directly or indirectly, from Original - Code provided by the Initial Developer and including the name of the - Initial Developer in (a) the Source Code, and (b) in any notice in an - Executable version or related documentation in which You describe the - origin or ownership of the Covered Code. - - 3.4. Intellectual Property Matters - (a) Third Party Claims. - If Contributor has knowledge that a license under a third party's - intellectual property rights is required to exercise the rights - granted by such Contributor under Sections 2.1 or 2.2, - Contributor must include a text file with the Source Code - distribution titled "LEGAL" which describes the claim and the - party making the claim in sufficient detail that a recipient will - know whom to contact. If Contributor obtains such knowledge after - the Modification is made available as described in Section 3.2, - Contributor shall promptly modify the LEGAL file in all copies - Contributor makes available thereafter and shall take other steps - (such as notifying appropriate mailing lists or newsgroups) - reasonably calculated to inform those who received the Covered - Code that new knowledge has been obtained. - - (b) Contributor APIs. - If Contributor's Modifications include an application programming - interface and Contributor has knowledge of patent licenses which - are reasonably necessary to implement that API, Contributor must - also include this information in the LEGAL file. - - (c) Representations. - Contributor represents that, except as disclosed pursuant to - Section 3.4(a) above, Contributor believes that Contributor's - Modifications are Contributor's original creation(s) and/or - Contributor has sufficient rights to grant the rights conveyed by - this License. - - 3.5. Required Notices. - You must duplicate the notice in Exhibit A in each file of the Source - Code. If it is not possible to put such notice in a particular Source - Code file due to its structure, then You must include such notice in a - location (such as a relevant directory) where a user would be likely - to look for such a notice. If You created one or more Modification(s) - You may add your name as a Contributor to the notice described in - Exhibit A. You must also duplicate this License in any documentation - for the Source Code where You describe recipients' rights or ownership - rights relating to Covered Code. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability - obligations to one or more recipients of Covered Code. However, You - may do so only on Your own behalf, and not on behalf of the Initial - Developer or any Contributor. You must make it absolutely clear than - any such warranty, support, indemnity or liability obligation is - offered by You alone, and You hereby agree to indemnify the Initial - Developer and every Contributor for any liability incurred by the - Initial Developer or such Contributor as a result of warranty, - support, indemnity or liability terms You offer. - - 3.6. Distribution of Executable Versions. - You may distribute Covered Code in Executable form only if the - requirements of Section 3.1-3.5 have been met for that Covered Code, - and if You include a notice stating that the Source Code version of - the Covered Code is available under the terms of this License, - including a description of how and where You have fulfilled the - obligations of Section 3.2. The notice must be conspicuously included - in any notice in an Executable version, related documentation or - collateral in which You describe recipients' rights relating to the - Covered Code. You may distribute the Executable version of Covered - Code or ownership rights under a license of Your choice, which may - contain terms different from this License, provided that You are in - compliance with the terms of this License and that the license for the - Executable version does not attempt to limit or alter the recipient's - rights in the Source Code version from the rights set forth in this - License. If You distribute the Executable version under a different - license You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial - Developer or any Contributor. You hereby agree to indemnify the - Initial Developer and every Contributor for any liability incurred by - the Initial Developer or such Contributor as a result of any such - terms You offer. - - 3.7. Larger Works. - You may create a Larger Work by combining Covered Code with other code - not governed by the terms of this License and distribute the Larger - Work as a single product. In such a case, You must make sure the - requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Code due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description - must be included in the LEGAL file described in Section 3.4 and must - be included with all distributions of the Source Code. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Application of this License. - - This License applies to code to which the Initial Developer has - attached the notice in Exhibit A and to related Covered Code. - -6. Versions of the License. - - 6.1. New Versions. - Netscape Communications Corporation ("Netscape") may publish revised - and/or new versions of the License from time to time. Each version - will be given a distinguishing version number. - - 6.2. Effect of New Versions. - Once Covered Code has been published under a particular version of the - License, You may always continue to use it under the terms of that - version. You may also choose to use such Covered Code under the terms - of any subsequent version of the License published by Netscape. No one - other than Netscape has the right to modify the terms applicable to - Covered Code created under this License. - - 6.3. Derivative Works. - If You create or use a modified version of this License (which you may - only do in order to apply it to code which is not already Covered Code - governed by this License), You must (a) rename Your license so that - the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", - "MPL", "NPL" or any confusingly similar phrase do not appear in your - license (except to note that your license differs from this License) - and (b) otherwise make it clear that Your version of the license - contains terms which differ from the Mozilla Public License and - Netscape Public License. (Filling in the name of the Initial - Developer, Original Code or Contributor in the notice described in - Exhibit A shall not of themselves be deemed to be modifications of - this License.) - -7. DISCLAIMER OF WARRANTY. - - COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF - DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE - IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, - YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE - COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER - OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF - ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - - 8.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to cure - such breach within 30 days of becoming aware of the breach. All - sublicenses to the Covered Code which are properly granted shall - survive any termination of this License. Provisions which, by their - nature, must remain in effect beyond the termination of this License - shall survive. - - 8.2. If You initiate litigation by asserting a patent infringement - claim (excluding declatory judgment actions) against Initial Developer - or a Contributor (the Initial Developer or Contributor against whom - You file such action is referred to as "Participant") alleging that: - - (a) such Participant's Contributor Version directly or indirectly - infringes any patent, then any and all rights granted by such - Participant to You under Sections 2.1 and/or 2.2 of this License - shall, upon 60 days notice from Participant terminate prospectively, - unless if within 60 days after receipt of notice You either: (i) - agree in writing to pay Participant a mutually agreeable reasonable - royalty for Your past and future use of Modifications made by such - Participant, or (ii) withdraw Your litigation claim with respect to - the Contributor Version against such Participant. If within 60 days - of notice, a reasonable royalty and payment arrangement are not - mutually agreed upon in writing by the parties or the litigation claim - is not withdrawn, the rights granted by Participant to You under - Sections 2.1 and/or 2.2 automatically terminate at the expiration of - the 60 day notice period specified above. - - (b) any software, hardware, or device, other than such Participant's - Contributor Version, directly or indirectly infringes any patent, then - any rights granted to You by such Participant under Sections 2.1(b) - and 2.2(b) are revoked effective as of the date You first made, used, - sold, distributed, or had made, Modifications made by that - Participant. - - 8.3. If You assert a patent infringement claim against Participant - alleging that such Participant's Contributor Version directly or - indirectly infringes any patent where such claim is resolved (such as - by license or settlement) prior to the initiation of patent - infringement litigation, then the reasonable value of the licenses - granted by such Participant under Sections 2.1 or 2.2 shall be taken - into account in determining the amount or value of any payment or - license. - - 8.4. In the event of termination under Sections 8.1 or 8.2 above, - all end user license agreements (excluding distributors and resellers) - which have been validly granted by You or any distributor hereunder - prior to termination shall survive termination. - -9. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT - (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL - DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, - OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR - ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY - CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, - WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER - COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN - INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF - LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY - RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW - PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO - THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - - The Covered Code is a "commercial item," as that term is defined in - 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer - software" and "commercial computer software documentation," as such - terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 - C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), - all U.S. Government End Users acquire Covered Code with only those - rights set forth herein. - -11. MISCELLANEOUS. - - This License represents the complete agreement concerning subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. This License shall be governed by - California law provisions (except to the extent applicable law, if - any, provides otherwise), excluding its conflict-of-law provisions. - With respect to disputes in which at least one party is a citizen of, - or an entity chartered or registered to do business in the United - States of America, any litigation relating to this License shall be - subject to the jurisdiction of the Federal Courts of the Northern - District of California, with venue lying in Santa Clara County, - California, with the losing party responsible for costs, including - without limitation, court costs and reasonable attorneys' fees and - expenses. The application of the United Nations Convention on - Contracts for the International Sale of Goods is expressly excluded. - Any law or regulation which provides that the language of a contract - shall be construed against the drafter shall not apply to this - License. - -12. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is - responsible for claims and damages arising, directly or indirectly, - out of its utilization of rights under this License and You agree to - work with Initial Developer and Contributors to distribute such - responsibility on an equitable basis. Nothing herein is intended or - shall be deemed to constitute any admission of liability. - -13. MULTIPLE-LICENSED CODE. - - Initial Developer may designate portions of the Covered Code as - "Multiple-Licensed". "Multiple-Licensed" means that the Initial - Developer permits you to utilize portions of the Covered Code under - Your choice of the NPL or the alternative licenses, if any, specified - by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. - - ``The contents of this file are subject to the Mozilla Public License - Version 1.1 (the "License"); you may not use this file except in - compliance with the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - License for the specific language governing rights and limitations - under the License. - - The Original Code is RabbitMQ. - - The Initial Developer of the Original Code is GoPivotal, Inc. - Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved.'' - - [NOTE: The text of this Exhibit A may differ slightly from the text of - the notices in the Source Code files of the Original Code. You should - use the text of this Exhibit A rather than the text found in the - Original Code Source Code for Your Modifications.] diff --git a/packaging/debs/Debian/.gitignore b/packaging/debs/Debian/.gitignore deleted file mode 100644 index 6a4aec11b5..0000000000 --- a/packaging/debs/Debian/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/debian/postrm -/debian/stamp-makefile-build -/rabbitmq-server_* diff --git a/packaging/debs/Debian/Makefile b/packaging/debs/Debian/Makefile deleted file mode 100644 index df01eee588..0000000000 --- a/packaging/debs/Debian/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -SOURCE_DIST_FILE ?= $(wildcard ../../../rabbitmq-server-*.tar.xz) - -ifneq ($(filter-out clean,$(MAKECMDGOALS)),) -ifeq ($(SOURCE_DIST_FILE),) -$(error Cannot find source archive; please specify SOURCE_DIST_FILE) -endif -ifneq ($(words $(SOURCE_DIST_FILE)),1) -$(error Multile source archives found; please specify SOURCE_DIST_FILE) -endif - -VERSION ?= $(patsubst rabbitmq-server-%.tar.xz,%,$(notdir $(SOURCE_DIST_FILE))) -ifeq ($(VERSION),) -$(error Cannot determine version; please specify VERSION) -endif -endif - -DEBIAN_ORIG_TARBALL = rabbitmq-server_$(VERSION).orig.tar.xz -UNPACKED_DIR = rabbitmq-server-$(VERSION) -PACKAGENAME = rabbitmq-server - -ifneq "$(UNOFFICIAL_RELEASE)" "" - SIGNING=-us -uc -else - SIGNING=-k$(SIGNING_KEY) -endif - -unexport DEPS_DIR -unexport ERL_LIBS - -all: package - @: - -package: clean - cp -a $(SOURCE_DIST_FILE) $(DEBIAN_ORIG_TARBALL) - xzcat $(DEBIAN_ORIG_TARBALL) | tar -xf - - cp -a debian $(UNPACKED_DIR) - rsync -a \ - --exclude '.sw?' --exclude '.*.sw?' \ - --exclude '.git*' \ - --delete --delete-excluded \ - debian/ $(UNPACKED_DIR)/debian/ - UNOFFICIAL_RELEASE=$(UNOFFICIAL_RELEASE) VERSION=$(VERSION) ./check-changelog.sh rabbitmq-server $(UNPACKED_DIR) - cd $(UNPACKED_DIR); GNUPGHOME=$(GNUPG_PATH)/.gnupg dpkg-buildpackage -sa $(SIGNING) - rm -rf $(UNPACKED_DIR) - - if test "$(PACKAGES_DIR)"; then \ - mkdir -p "$(PACKAGES_DIR)"; \ - mv $(PACKAGENAME)_$(VERSION)* "$(PACKAGES_DIR)"; \ - fi - -clean: - rm -rf $(UNPACKED_DIR) - rm -f $(DEBIAN_ORIG_TARBALL) - rm -f $(PACKAGENAME)_*.debian.tar.gz - rm -f $(PACKAGENAME)_*.dsc - rm -f $(PACKAGENAME)_*_*.changes - rm -f $(PACKAGENAME)_*_*.deb diff --git a/packaging/debs/Debian/changelog_comments/additional_changelog_comments_3.3.5 b/packaging/debs/Debian/changelog_comments/additional_changelog_comments_3.3.5 deleted file mode 100644 index b9a9551c6b..0000000000 --- a/packaging/debs/Debian/changelog_comments/additional_changelog_comments_3.3.5 +++ /dev/null @@ -1,9 +0,0 @@ -# This file contains additional comments for the debian/changelog to be -# appended within the current version's changelog entry. -# Each line will be a separate comment. Do not begin with an *, dch will -# add that. -# For comments longer than one line do not put a line break and dch will -# neatly format it. -# Shell comments are ignored. -# -Changed Uploaders from Emile Joubert to Blair Hester diff --git a/packaging/debs/Debian/changelog_comments/additional_changelog_comments_x.x.x b/packaging/debs/Debian/changelog_comments/additional_changelog_comments_x.x.x deleted file mode 100644 index bbab75965e..0000000000 --- a/packaging/debs/Debian/changelog_comments/additional_changelog_comments_x.x.x +++ /dev/null @@ -1,11 +0,0 @@ -# This file contains additional comments for the debian/changelog to be -# appended within the current version's changelog entry. -# Each line will be a separate comment. Do not begin with an *, dch will -# add that. -# For comments longer than one line do not put a line break and dch will -# neatly format it. -# Shell comments are ignored. -# -# Examples: -#Remove parts made of undercooked chicken -#This is a long line which is the beginning of a long two line comment which I am sure is going to be needed if the script cannot handle it diff --git a/packaging/debs/Debian/check-changelog.sh b/packaging/debs/Debian/check-changelog.sh deleted file mode 100755 index ff25e648fc..0000000000 --- a/packaging/debs/Debian/check-changelog.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -PACKAGE_NAME=$1 -cd $2 - -CHANGELOG_VERSION=$(dpkg-parsechangelog | sed -n 's/^Version: \(.*\)-[^-]*$/\1/p') - -if [ "${CHANGELOG_VERSION}" != "${VERSION}" ]; then - if [ -n "${UNOFFICIAL_RELEASE}" ]; then - echo "${PACKAGE_NAME} (${VERSION}-1) unstable; urgency=low" > debian/changelog.tmp - echo >> debian/changelog.tmp - echo " * Unofficial release" >> debian/changelog.tmp - echo >> debian/changelog.tmp - echo " -- Nobody <nobody@example.com> $(date -R)" >> debian/changelog.tmp - echo >> debian/changelog.tmp - cat debian/changelog >> debian/changelog.tmp - mv -f debian/changelog.tmp debian/changelog - - exit 0 - else - echo - echo There is no entry in debian/changelog for version ${VERSION}! - echo Please create a changelog entry, or set the variable - echo UNOFFICIAL_RELEASE to automatically create one. - echo - - exit 1 - fi -fi diff --git a/packaging/debs/Debian/debian/changelog b/packaging/debs/Debian/debian/changelog deleted file mode 100644 index 72f7116e66..0000000000 --- a/packaging/debs/Debian/debian/changelog +++ /dev/null @@ -1,415 +0,0 @@ -rabbitmq-server (3.6.3-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Wed, 06 Jul 2016 19:19:21 +0100 - -rabbitmq-server (3.6.2-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Thu, 19 May 2016 09:20:06 +0100 - -rabbitmq-server (3.6.1-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Tue, 01 Mar 2016 13:19:57 +0000 - -rabbitmq-server (3.6.0-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Tue, 22 Dec 2015 13:21:56 +0000 - -rabbitmq-server (3.5.7-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Tue, 15 Dec 2015 10:10:46 +0000 - -rabbitmq-server (3.5.6-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Wed, 07 Oct 2015 13:31:24 +0100 - -rabbitmq-server (3.5.5-3) unstable; urgency=low - - * Fix bashism in rabbitmq-script-wrapper - - -- Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> Thu, 24 Sep 2015 19:18:17 +0100 - -rabbitmq-server (3.5.5-1) unstable; urgency=low - - * New Upstream Release - - -- Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> Thu, 24 Sep 2015 10:57:25 +0100 - -rabbitmq-server (3.5.4-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Tue, 21 Jul 2015 20:25:48 +0100 - -rabbitmq-server (3.5.3-1) unstable; urgency=low - - * New Upstream Release - - -- Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> Fri, 22 May 2015 11:04:17 +0100 - -rabbitmq-server (3.5.2-1) unstable; urgency=low - - * New Upstream Release - - -- Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> Tue, 12 May 2015 16:21:44 +0100 - -rabbitmq-server (3.5.1-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Thu, 02 Apr 2015 10:17:30 +0100 - -rabbitmq-server (3.5.0-1) unstable; urgency=low - - * New Upstream Release - - -- Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> Wed, 11 Mar 2015 13:56:19 +0000 - -rabbitmq-server (3.4.4-1) unstable; urgency=low - - * New Upstream Release - - -- Michael Klishin <michael@rabbitmq.com> Wed, 11 Feb 2015 12:05:01 +0000 - -rabbitmq-server (3.4.3-1) unstable; urgency=low - - * New Upstream Release - - -- Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> Tue, 06 Jan 2015 15:58:45 +0000 - -rabbitmq-server (3.4.2-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Wed, 26 Nov 2014 12:11:12 +0000 - -rabbitmq-server (3.4.1-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Wed, 29 Oct 2014 13:31:10 +0000 - -rabbitmq-server (3.4.0-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Tue, 21 Oct 2014 14:21:36 +0100 - -rabbitmq-server (3.3.5-1) unstable; urgency=low - - * New Upstream Release - * Changed Uploaders from Emile Joubert to Blair Hester - - -- Simon MacMullen <simon@rabbitmq.com> Mon, 11 Aug 2014 12:23:31 +0100 - -rabbitmq-server (3.3.4-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Tue, 24 Jun 2014 12:50:29 +0100 - -rabbitmq-server (3.3.3-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Mon, 16 Jun 2014 13:00:00 +0100 - -rabbitmq-server (3.3.2-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Mon, 09 Jun 2014 10:25:22 +0100 - -rabbitmq-server (3.3.1-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Tue, 29 Apr 2014 11:49:23 +0100 - -rabbitmq-server (3.3.0-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Wed, 02 Apr 2014 14:23:14 +0100 - -rabbitmq-server (3.2.4-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Mon, 03 Mar 2014 14:50:18 +0000 - -rabbitmq-server (3.2.3-1) unstable; urgency=low - - * New Upstream Release - - -- Emile Joubert <emile@rabbitmq.com> Thu, 23 Jan 2014 14:46:37 +0000 - -rabbitmq-server (3.2.2-1) unstable; urgency=low - - * New Upstream Release - - -- Emile Joubert <emile@rabbitmq.com> Tue, 10 Dec 2013 16:08:08 +0000 - -rabbitmq-server (3.2.0-1) unstable; urgency=low - - * New Upstream Release - - -- Emile Joubert <emile@rabbitmq.com> Wed, 23 Oct 2013 12:44:10 +0100 - -rabbitmq-server (3.1.5-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Thu, 15 Aug 2013 11:03:13 +0100 - -rabbitmq-server (3.1.3-1) unstable; urgency=low - - * New Upstream Release - - -- Tim Watson <tim@rabbitmq.com> Tue, 25 Jun 2013 15:01:12 +0100 - -rabbitmq-server (3.1.2-1) unstable; urgency=low - - * New Upstream Release - - -- Tim Watson <tim@rabbitmq.com> Mon, 24 Jun 2013 11:16:41 +0100 - -rabbitmq-server (3.1.1-1) unstable; urgency=low - - * Test release - - -- Tim Watson <tim@rabbitmq.com> Mon, 20 May 2013 16:21:20 +0100 - -rabbitmq-server (3.1.0-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Wed, 01 May 2013 11:57:58 +0100 - -rabbitmq-server (3.0.1-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Tue, 11 Dec 2012 11:29:55 +0000 - -rabbitmq-server (3.0.0-1) unstable; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Fri, 16 Nov 2012 14:15:29 +0000 - -rabbitmq-server (2.7.1-1) natty; urgency=low - - * New Upstream Release - - -- Steve Powell <steve@rabbitmq.com> Fri, 16 Dec 2011 12:12:36 +0000 - -rabbitmq-server (2.7.0-1) natty; urgency=low - - * New Upstream Release - - -- Steve Powell <steve@rabbitmq.com> Tue, 08 Nov 2011 16:47:50 +0000 - -rabbitmq-server (2.6.1-1) natty; urgency=low - - * New Upstream Release - - -- Tim <tim@rabbitmq.com> Fri, 09 Sep 2011 14:38:45 +0100 - -rabbitmq-server (2.6.0-1) natty; urgency=low - - * New Upstream Release - - -- Tim <tim@rabbitmq.com> Fri, 26 Aug 2011 16:29:40 +0100 - -rabbitmq-server (2.5.1-1) lucid; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Mon, 27 Jun 2011 11:21:49 +0100 - -rabbitmq-server (2.5.0-1) lucid; urgency=low - - * New Upstream Release - - -- <jerryk@vmware.com> Thu, 09 Jun 2011 07:20:29 -0700 - -rabbitmq-server (2.4.1-1) lucid; urgency=low - - * New Upstream Release - - -- Alexandru Scvortov <alexandru@rabbitmq.com> Thu, 07 Apr 2011 16:49:22 +0100 - -rabbitmq-server (2.4.0-1) lucid; urgency=low - - * New Upstream Release - - -- Alexandru Scvortov <alexandru@rabbitmq.com> Tue, 22 Mar 2011 17:34:31 +0000 - -rabbitmq-server (2.3.1-1) lucid; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Thu, 03 Feb 2011 12:43:56 +0000 - -rabbitmq-server (2.3.0-1) lucid; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@rabbitmq.com> Tue, 01 Feb 2011 12:52:16 +0000 - -rabbitmq-server (2.2.0-1) lucid; urgency=low - - * New Upstream Release - - -- Rob Harrop <rob@rabbitmq.com> Mon, 29 Nov 2010 12:24:48 +0000 - -rabbitmq-server (2.1.1-1) lucid; urgency=low - - * New Upstream Release - - -- Vlad Alexandru Ionescu <vlad@rabbitmq.com> Tue, 19 Oct 2010 17:20:10 +0100 - -rabbitmq-server (2.1.0-1) lucid; urgency=low - - * New Upstream Release - - -- Marek Majkowski <marek@rabbitmq.com> Tue, 14 Sep 2010 14:20:17 +0100 - -rabbitmq-server (2.0.0-1) karmic; urgency=low - - * New Upstream Release - - -- Michael Bridgen <mikeb@rabbitmq.com> Mon, 23 Aug 2010 14:55:39 +0100 - -rabbitmq-server (1.8.1-1) lucid; urgency=low - - * New Upstream Release - - -- Emile Joubert <emile@rabbitmq.com> Wed, 14 Jul 2010 15:05:24 +0100 - -rabbitmq-server (1.8.0-1) intrepid; urgency=low - - * New Upstream Release - - -- Matthew Sackman <matthew@rabbitmq.com> Tue, 15 Jun 2010 12:48:48 +0100 - -rabbitmq-server (1.7.2-1) intrepid; urgency=low - - * New Upstream Release - - -- Matthew Sackman <matthew@lshift.net> Mon, 15 Feb 2010 15:54:47 +0000 - -rabbitmq-server (1.7.1-1) intrepid; urgency=low - - * New Upstream Release - - -- Matthew Sackman <matthew@lshift.net> Fri, 22 Jan 2010 14:14:29 +0000 - -rabbitmq-server (1.7.0-1) intrepid; urgency=low - - * New Upstream Release - - -- David Wragg <dpw@lshift.net> Mon, 05 Oct 2009 13:44:41 +0100 - -rabbitmq-server (1.6.0-1) hardy; urgency=low - - * New Upstream Release - - -- Matthias Radestock <matthias@lshift.net> Tue, 16 Jun 2009 15:02:58 +0100 - -rabbitmq-server (1.5.5-1) hardy; urgency=low - - * New Upstream Release - - -- Matthias Radestock <matthias@lshift.net> Tue, 19 May 2009 09:57:54 +0100 - -rabbitmq-server (1.5.4-1) hardy; urgency=low - - * New Upstream Release - - -- Matthias Radestock <matthias@lshift.net> Mon, 06 Apr 2009 09:19:32 +0100 - -rabbitmq-server (1.5.3-1) hardy; urgency=low - - * New Upstream Release - - -- Tony Garnock-Jones <tonyg@lshift.net> Tue, 24 Feb 2009 18:23:33 +0000 - -rabbitmq-server (1.5.2-1) hardy; urgency=low - - * New Upstream Release - - -- Tony Garnock-Jones <tonyg@lshift.net> Mon, 23 Feb 2009 16:03:38 +0000 - -rabbitmq-server (1.5.1-1) hardy; urgency=low - - * New Upstream Release - - -- Simon MacMullen <simon@lshift.net> Mon, 19 Jan 2009 15:46:13 +0000 - -rabbitmq-server (1.5.0-1) testing; urgency=low - - * New Upstream Release - - -- Matthias Radestock <matthias@lshift.net> Wed, 17 Dec 2008 18:23:47 +0000 - -rabbitmq-server (1.4.0-1) testing; urgency=low - - * New Upstream Release - - -- Tony Garnock-Jones <tonyg@lshift.net> Thu, 24 Jul 2008 13:21:48 +0100 - -rabbitmq-server (1.3.0-1) testing; urgency=low - - * New Upstream Release - - -- Adrien Pierard <adrien@lshift.net> Mon, 03 Mar 2008 15:34:38 +0000 - -rabbitmq-server (1.2.0-2) testing; urgency=low - - * Fixed rabbitmqctl wrapper script - - -- Simon MacMullen <simon@lshift.net> Fri, 05 Oct 2007 11:55:00 +0100 - -rabbitmq-server (1.2.0-1) testing; urgency=low - - * New upstream release - - -- Simon MacMullen <simon@lshift.net> Wed, 26 Sep 2007 11:49:26 +0100 - -rabbitmq-server (1.1.1-1) testing; urgency=low - - * New upstream release - - -- Simon MacMullen <simon@lshift.net> Wed, 29 Aug 2007 12:03:15 +0100 - -rabbitmq-server (1.1.0-alpha-2) testing; urgency=low - - * Fixed erlang-nox dependency - - -- Simon MacMullen <simon@lshift.net> Thu, 02 Aug 2007 11:27:13 +0100 - -rabbitmq-server (1.1.0-alpha-1) testing; urgency=low - - * New upstream release - - -- Simon MacMullen <simon@lshift.net> Fri, 20 Jul 2007 18:17:33 +0100 - -rabbitmq-server (1.0.0-alpha-1) unstable; urgency=low - - * Initial release - - -- Tony Garnock-Jones <tonyg@shortstop.lshift.net> Wed, 31 Jan 2007 19:06:33 +0000 - diff --git a/packaging/debs/Debian/debian/compat b/packaging/debs/Debian/debian/compat deleted file mode 100644 index ec635144f6..0000000000 --- a/packaging/debs/Debian/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/packaging/debs/Debian/debian/control b/packaging/debs/Debian/debian/control deleted file mode 100644 index 050051ba3f..0000000000 --- a/packaging/debs/Debian/debian/control +++ /dev/null @@ -1,24 +0,0 @@ -Source: rabbitmq-server -Section: net -Priority: extra -Maintainer: RabbitMQ Team <info@rabbitmq.com> -Uploaders: Michael Klishin <michael@rabbitmq.com>, - Karl Nilsson <knilsson@rabbitmq.com>, - Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> -Build-Depends: debhelper (>= 9), - dh-systemd (>= 1.5), - erlang-dev, - python-simplejson, - xmlto, - xsltproc, - erlang-nox (>= 1:16.b.3) | esl-erlang, - zip, - rsync -Standards-Version: 3.9.4 - -Package: rabbitmq-server -Architecture: all -Depends: erlang-nox (>= 1:16.b.3) | esl-erlang, adduser, logrotate, socat, init-system-helpers (>= 1.13~) -Description: Multi-protocol messaging broker - RabbitMQ is an open source multi-protocol messaging broker. -Homepage: http://www.rabbitmq.com/ diff --git a/packaging/debs/Debian/debian/copyright b/packaging/debs/Debian/debian/copyright deleted file mode 100644 index 521b903754..0000000000 --- a/packaging/debs/Debian/debian/copyright +++ /dev/null @@ -1,52 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: rabbitmq-server -Upstream-Contact: Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> -Source: https://github.com/rabbitmq/rabbitmq-server - -Files: * -Copyright: 2007-2015 Pivotal Software, Inc. -License: MPL-1.1 - -Files: src/mochinum.erl deps/rabbit_common/src/mochijson2.erl -Copyright: 2007 Mochi Media, Inc. -License: MIT - -License: MPL-1.1 - The contents of this file are subject to the Mozilla Public License - Version 1.1 (the "License"); you may not use this file except in - compliance with the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - . - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License - . - The Original Code is RabbitMQ - . - The Initial Developer of the Original Code is Pivotal Software, Inc. - Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. - -License: MIT - This is the MIT license - . - Copyright (c) 2007 Mochi Media, Inc - . - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions - : - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software - . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packaging/debs/Debian/debian/dirs b/packaging/debs/Debian/debian/dirs deleted file mode 100644 index 625b7d41f5..0000000000 --- a/packaging/debs/Debian/debian/dirs +++ /dev/null @@ -1,9 +0,0 @@ -usr/lib/rabbitmq/bin -usr/lib/erlang/lib -usr/sbin -usr/share/man -var/lib/rabbitmq/mnesia -var/log/rabbitmq -etc/logrotate.d -etc/rabbitmq - diff --git a/packaging/debs/Debian/debian/postinst b/packaging/debs/Debian/debian/postinst deleted file mode 100644 index c83881e6ba..0000000000 --- a/packaging/debs/Debian/debian/postinst +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh -# postinst script for rabbitmq -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * <postinst> `configure' <most-recently-configured-version> -# * <old-postinst> `abort-upgrade' <new version> -# * <conflictor's-postinst> `abort-remove' `in-favour' <package> -# <new-version> -# * <postinst> `abort-remove' -# * <deconfigured's-postinst> `abort-deconfigure' `in-favour' -# <failed-install-package> <version> `removing' -# <conflicting-package> <version> -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -# create rabbitmq group -if ! getent group rabbitmq >/dev/null; then - addgroup --system rabbitmq -fi - -# create rabbitmq user -if ! getent passwd rabbitmq >/dev/null; then - adduser --system --ingroup rabbitmq --home /var/lib/rabbitmq \ - --no-create-home --gecos "RabbitMQ messaging server" \ - --disabled-login rabbitmq -fi - -chown -R rabbitmq:rabbitmq /var/lib/rabbitmq -chown -R rabbitmq:rabbitmq /var/log/rabbitmq -chmod 750 /var/lib/rabbitmq/mnesia -chmod -R o-rwx,g-w /var/lib/rabbitmq/mnesia - -case "$1" in - configure) - if [ -f /etc/rabbitmq/rabbitmq.conf ] && \ - [ ! -f /etc/rabbitmq/rabbitmq-env.conf ]; then - mv /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq-env.conf - fi - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff --git a/packaging/debs/Debian/debian/postrm.in b/packaging/debs/Debian/debian/postrm.in deleted file mode 100644 index c2e9bbfedc..0000000000 --- a/packaging/debs/Debian/debian/postrm.in +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/sh -# postrm script for rabbitmq -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * <postrm> `remove' -# * <postrm> `purge' -# * <old-postrm> `upgrade' <new-version> -# * <new-postrm> `failed-upgrade' <old-version> -# * <new-postrm> `abort-install' -# * <new-postrm> `abort-install' <old-version> -# * <new-postrm> `abort-upgrade' <old-version> -# * <disappearer's-postrm> `disappear' <overwriter> -# <overwriter-version> -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - -remove_plugin_traces() { - # Remove traces of plugins - rm -rf /var/lib/rabbitmq/plugins-scratch -} - -case "$1" in - purge) - rm -f /etc/default/rabbitmq - if [ -d /var/lib/rabbitmq ]; then - rm -r /var/lib/rabbitmq - fi - if [ -d /var/log/rabbitmq ]; then - rm -r /var/log/rabbitmq - fi - if [ -d /etc/rabbitmq ]; then - rm -r /etc/rabbitmq - fi - remove_plugin_traces - if getent passwd rabbitmq >/dev/null; then - # Stop epmd if run by the rabbitmq user - pkill -u rabbitmq epmd || : - fi - ;; - - remove|upgrade) - remove_plugin_traces - ;; - - failed-upgrade|abort-install|abort-upgrade|disappear) - ;; - - *) - echo "postrm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff --git a/packaging/debs/Debian/debian/rabbitmq-server.default b/packaging/debs/Debian/debian/rabbitmq-server.default deleted file mode 100644 index bde5e30895..0000000000 --- a/packaging/debs/Debian/debian/rabbitmq-server.default +++ /dev/null @@ -1,9 +0,0 @@ -# This file is sourced by /etc/init.d/rabbitmq-server. Its primary -# reason for existing is to allow adjustment of system limits for the -# rabbitmq-server process. -# -# Maximum number of open file handles. This will need to be increased -# to handle many simultaneous connections. Refer to the system -# documentation for ulimit (in man bash) for more information. -# -#ulimit -n 1024 diff --git a/packaging/debs/Debian/debian/rabbitmq-server.docs b/packaging/debs/Debian/debian/rabbitmq-server.docs deleted file mode 100644 index fbe9f95a05..0000000000 --- a/packaging/debs/Debian/debian/rabbitmq-server.docs +++ /dev/null @@ -1,2 +0,0 @@ -docs/rabbitmq.config.example -docs/set_rabbitmq_policy.sh.example diff --git a/packaging/debs/Debian/debian/rabbitmq-server.init b/packaging/debs/Debian/debian/rabbitmq-server.init deleted file mode 100644 index fce2d16401..0000000000 --- a/packaging/debs/Debian/debian/rabbitmq-server.init +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/sh -# -# rabbitmq-server RabbitMQ broker -# -# chkconfig: - 80 05 -# description: Manages RabbitMQ server -# - -### BEGIN INIT INFO -# Provides: rabbitmq-server -# Required-Start: $remote_fs $network -# Required-Stop: $remote_fs $network -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Description: RabbitMQ broker -# Short-Description: Manages RabbitMQ server -### END INIT INFO - -PATH=/sbin:/usr/sbin:/bin:/usr/bin -NAME=rabbitmq-server -DAEMON=/usr/sbin/${NAME} -CONTROL=/usr/sbin/rabbitmqctl -DESC="message broker" -USER=rabbitmq -ROTATE_SUFFIX= -PID_FILE=/var/run/rabbitmq/pid -RABBITMQ_ENV=/usr/lib/rabbitmq/bin/rabbitmq-env - -test -x $DAEMON || exit 0 -test -x $CONTROL || exit 0 - -RETVAL=0 -set -e - -[ -f /etc/default/${NAME} ] && . /etc/default/${NAME} - -RABBITMQ_SCRIPTS_DIR=$(dirname "$RABBITMQ_ENV") -. "$RABBITMQ_ENV" - -. /lib/lsb/init-functions -. /lib/init/vars.sh - -ensure_pid_dir () { - PID_DIR=`dirname ${PID_FILE}` - if [ ! -d ${PID_DIR} ] ; then - mkdir -p ${PID_DIR} - chown -R ${USER}:${USER} ${PID_DIR} - chmod 755 ${PID_DIR} - fi -} - -remove_pid () { - rm -f ${PID_FILE} - rmdir `dirname ${PID_FILE}` || : -} - -start_rabbitmq () { - status_rabbitmq quiet - if [ $RETVAL != 0 ] ; then - RETVAL=0 - ensure_pid_dir - set +e - RABBITMQ_PID_FILE=$PID_FILE start-stop-daemon --quiet \ - --chuid rabbitmq --start --exec $DAEMON \ - --pidfile "$PID_FILE" --background - $CONTROL wait $PID_FILE >/dev/null 2>&1 - RETVAL=$? - set -e - if [ $RETVAL != 0 ] ; then - remove_pid - fi - else - RETVAL=3 - fi -} - -stop_rabbitmq () { - status_rabbitmq quiet - if [ $RETVAL = 0 ] ; then - set +e - $CONTROL stop ${PID_FILE} \ - > ${RABBITMQ_LOG_BASE}/shutdown_log \ - 2> ${RABBITMQ_LOG_BASE}/shutdown_err - RETVAL=$? - set -e - if [ $RETVAL = 0 ] ; then - remove_pid - fi - else - RETVAL=3 - fi -} - -status_rabbitmq() { - set +e - if [ "$1" != "quiet" ] ; then - $CONTROL status 2>&1 - else - $CONTROL status > /dev/null 2>&1 - fi - if [ $? != 0 ] ; then - RETVAL=3 - fi - set -e -} - -rotate_logs_rabbitmq() { - set +e - $CONTROL -q rotate_logs ${ROTATE_SUFFIX} - if [ $? != 0 ] ; then - RETVAL=1 - fi - set -e -} - -restart_running_rabbitmq () { - status_rabbitmq quiet - if [ $RETVAL = 0 ] ; then - restart_rabbitmq - else - log_warning_msg "${DESC} not running" - fi -} - -restart_rabbitmq() { - stop_rabbitmq - start_rabbitmq -} - -restart_end() { - if [ $RETVAL = 0 ] ; then - log_end_msg 0 - else - log_end_msg 1 - fi -} - -start_stop_end() { - case "$RETVAL" in - 0) - [ -x /sbin/initctl ] && /sbin/initctl emit --no-wait "${NAME}-${1}" - log_end_msg 0 - ;; - 3) - log_warning_msg "${DESC} already ${1}" - log_end_msg 0 - RETVAL=0 - ;; - *) - log_warning_msg "FAILED - check ${RABBITMQ_LOG_BASE}/startup_\{log, _err\}" - log_end_msg 1 - ;; - esac -} - -case "$1" in - start) - log_daemon_msg "Starting ${DESC}" $NAME - start_rabbitmq - start_stop_end "running" - ;; - stop) - log_daemon_msg "Stopping ${DESC}" $NAME - stop_rabbitmq - start_stop_end "stopped" - ;; - status) - status_rabbitmq - ;; - rotate-logs) - log_action_begin_msg "Rotating log files for ${DESC}: ${NAME}" - rotate_logs_rabbitmq - log_action_end_msg $RETVAL - ;; - force-reload|reload|restart) - log_daemon_msg "Restarting ${DESC}" $NAME - restart_rabbitmq - restart_end - ;; - try-restart) - log_daemon_msg "Restarting ${DESC}" $NAME - restart_running_rabbitmq - restart_end - ;; - *) - echo "Usage: $0 {start|stop|status|rotate-logs|restart|condrestart|try-restart|reload|force-reload}" >&2 - RETVAL=1 - ;; -esac - -exit $RETVAL diff --git a/packaging/debs/Debian/debian/rabbitmq-server.logrotate b/packaging/debs/Debian/debian/rabbitmq-server.logrotate deleted file mode 100644 index c786df77b2..0000000000 --- a/packaging/debs/Debian/debian/rabbitmq-server.logrotate +++ /dev/null @@ -1,12 +0,0 @@ -/var/log/rabbitmq/*.log { - weekly - missingok - rotate 20 - compress - delaycompress - notifempty - sharedscripts - postrotate - /etc/init.d/rabbitmq-server rotate-logs > /dev/null - endscript -} diff --git a/packaging/debs/Debian/debian/rabbitmq-server.manpages b/packaging/debs/Debian/debian/rabbitmq-server.manpages deleted file mode 100644 index e0220b47c3..0000000000 --- a/packaging/debs/Debian/debian/rabbitmq-server.manpages +++ /dev/null @@ -1,4 +0,0 @@ -docs/rabbitmq-env.conf.5 -docs/rabbitmq-plugins.1 -docs/rabbitmq-server.1 -docs/rabbitmqctl.1 diff --git a/packaging/debs/Debian/debian/rabbitmq-server.service b/packaging/debs/Debian/debian/rabbitmq-server.service deleted file mode 100644 index 1aa6549b64..0000000000 --- a/packaging/debs/Debian/debian/rabbitmq-server.service +++ /dev/null @@ -1,18 +0,0 @@ -# systemd unit example -[Unit] -Description=RabbitMQ broker -After=network.target epmd@0.0.0.0.socket -Wants=network.target epmd@0.0.0.0.socket - -[Service] -Type=notify -User=rabbitmq -Group=rabbitmq -NotifyAccess=all -TimeoutStartSec=3600 -WorkingDirectory=/var/lib/rabbitmq -ExecStart=/usr/lib/rabbitmq/bin/rabbitmq-server -ExecStop=/usr/lib/rabbitmq/bin/rabbitmqctl stop - -[Install] -WantedBy=multi-user.target diff --git a/packaging/debs/Debian/debian/rules b/packaging/debs/Debian/debian/rules deleted file mode 100755 index 770eeb0ea5..0000000000 --- a/packaging/debs/Debian/debian/rules +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -DEB_DESTDIR = debian/rabbitmq-server -VERSION = $(shell dpkg-parsechangelog | awk '/^Version:/ {version=$$0; sub(/Version: /, "", version); sub(/-.*/, "", version); print version;}') - -%: - dh $@ --parallel --with systemd - -override_dh_auto_clean: - $(MAKE) clean distclean-manpages - -override_dh_auto_build: - $(MAKE) dist manpages - -override_dh_auto_test: - @: - -export PREFIX RMQ_ROOTDIR - -override_dh_auto_install: PREFIX = /usr -override_dh_auto_install: RMQ_ROOTDIR = $(PREFIX)/lib/rabbitmq -override_dh_auto_install: RMQ_ERLAPP_DIR = $(RMQ_ROOTDIR)/lib/rabbitmq_server-$(VERSION) -override_dh_auto_install: - dh_auto_install - - $(MAKE) install-bin DESTDIR=$(DEB_DESTDIR) - - sed -e 's|@RABBIT_LIB@|$(RMQ_ERLAPP_DIR)|g' \ - < debian/postrm.in > debian/postrm - - sed -e 's|@SU_RABBITMQ_SH_C@|su rabbitmq -s /bin/sh -c|' \ - -e 's|@STDOUT_STDERR_REDIRECTION@|> "$$RABBITMQ_LOG_BASE/startup_log" 2> "$$RABBITMQ_LOG_BASE/startup_err"|' \ - < scripts/rabbitmq-script-wrapper \ - > $(DEB_DESTDIR)$(PREFIX)/sbin/rabbitmqctl - chmod 0755 $(DEB_DESTDIR)$(PREFIX)/sbin/rabbitmqctl - for script in rabbitmq-server rabbitmq-plugins; do \ - cp -a $(DEB_DESTDIR)$(PREFIX)/sbin/rabbitmqctl \ - $(DEB_DESTDIR)$(PREFIX)/sbin/$$script; \ - done - - install -p -D -m 0644 debian/rabbitmq-server.default \ - $(DEB_DESTDIR)/etc/default/rabbitmq-server - - install -p -D -m 0755 scripts/rabbitmq-server.ocf \ - $(DEB_DESTDIR)$(PREFIX)/lib/ocf/resource.d/rabbitmq/rabbitmq-server - install -p -D -m 0755 scripts/rabbitmq-server-ha.ocf \ - $(DEB_DESTDIR)$(PREFIX)/lib/ocf/resource.d/rabbitmq/rabbitmq-server-ha - - rm $(DEB_DESTDIR)$(RMQ_ERLAPP_DIR)/LICENSE* \ - $(DEB_DESTDIR)$(RMQ_ERLAPP_DIR)/INSTALL - - rmdir $(DEB_DESTDIR)$(PREFIX)/lib/erlang/lib \ - $(DEB_DESTDIR)$(PREFIX)/lib/erlang diff --git a/packaging/debs/Debian/debian/source/format b/packaging/debs/Debian/debian/source/format deleted file mode 100644 index 163aaf8d82..0000000000 --- a/packaging/debs/Debian/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/packaging/debs/Debian/debian/watch b/packaging/debs/Debian/debian/watch deleted file mode 100644 index b41aff9aed..0000000000 --- a/packaging/debs/Debian/debian/watch +++ /dev/null @@ -1,4 +0,0 @@ -version=3 - -http://www.rabbitmq.com/releases/rabbitmq-server/v(.*)/rabbitmq-server-(\d.*)\.tar\.gz \ - debian uupdate diff --git a/packaging/debs/apt-repository/Makefile b/packaging/debs/apt-repository/Makefile deleted file mode 100644 index dbf8871a51..0000000000 --- a/packaging/debs/apt-repository/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -PACKAGES_DIR ?= ../../../PACKAGES -REPO_DIR ?= debian - -SIGNING_KEY ?= default - -ifeq "$(UNOFFICIAL_RELEASE)" "" -HOME_ARG = HOME=$(GNUPG_PATH) -endif - -all: debian_apt_repository - -clean: - rm -rf $(REPO_DIR) - -CAN_HAS_REPREPRO=$(shell [ -f /usr/bin/reprepro ] && echo true) -ifeq ($(CAN_HAS_REPREPRO), true) -debian_apt_repository: clean - mkdir -p $(REPO_DIR)/conf - cp -a distributions $(REPO_DIR)/conf -ifeq "$(UNOFFICIAL_RELEASE)" "" - echo SignWith: $(SIGNING_KEY) >> $(REPO_DIR)/conf/distributions -endif - for FILE in $(PACKAGES_DIR)/*.changes ; do \ - $(HOME_ARG) reprepro --ignore=wrongdistribution \ - -Vb $(REPO_DIR) include kitten $${FILE} ; \ - done - reprepro -Vb $(REPO_DIR) createsymlinks -else -debian_apt_repository: - @echo Not building APT repository as reprepro could not be found -endif diff --git a/packaging/debs/apt-repository/README b/packaging/debs/apt-repository/README deleted file mode 100644 index 514a37f33e..0000000000 --- a/packaging/debs/apt-repository/README +++ /dev/null @@ -1,17 +0,0 @@ -APT repository for RabbitMQ - -Previously we've attempted to run a repository in the same way that -Debian would: have repository management software installed on the -server, and upload new packages to the repository as and when they're -ready. - -This turned out to be both fiddly and annoying to do (and more -particularly to automate) so since our repository is always going to be -small it's easier just to create the entire repository as part of the -build process, just like a package. It can then be moved into place as a -single unit. The make target "debian_apt_repository" (invoked by "dist") -will create it, and it can get moved onto the server with the rest of -the packages. - -Read "README-real-repository" for information on how we used to do -this. diff --git a/packaging/debs/apt-repository/README-real-repository b/packaging/debs/apt-repository/README-real-repository deleted file mode 100644 index 189852eb60..0000000000 --- a/packaging/debs/apt-repository/README-real-repository +++ /dev/null @@ -1,130 +0,0 @@ -APT Repository for RabbitMQ in Debian -===================================== - -First, a note on what we're trying to do. We want a single "testing" -repository. When RabbitMQ is more stable we will also want a -"stable" repository. It is very important to understand that these refer -to the state of the rabbit code, *NOT* which Debian distribution they go -with. At the moment our dependencies are very simple so our packages can -be used with any current Debian version (etch, lenny, sid) as well as -with Ubuntu. So although we have a "testing" distribution, this is not -codenamed "lenny". Instead it's currently codenamed "kitten" since -that's a baby rabbit. - -Secondly, a note on software. We need a tool to manage the repository, -and a tool to perform uploads to the repository. Debian being Debian -there are quite a few of each. We will use "reprepro" to manage the -repository since it's modern, maintained, and fairly simple. We will use -"dupload" to perform the uploads since it gives us the ability to run -arbitrary commands after the upload, which means we don't need to run a -cron job on the web server to process uploads. - -Creating a repository -===================== - -Much of this was cribbed from: -http://www.debian-administration.org/articles/286 - -The repository is fundamentally just some files in a folder, served over -HTTP (or FTP etc). So let's make it "debian" in the root of -www.rabbitmq.com. - -This means the repository will be at http://www.rabbitmq.com/debian/ and -can be added to a sources.list as: - -deb http://www.rabbitmq.com/debian/ testing main -deb-src http://www.rabbitmq.com/debian/ testing main - -Inside this folder we need a "conf" folder, and in -that we need a "distributions" configuration file - see the file in this -folder. Note that: - -* We list all architectures so that people can install rabbitmq-server - on to anything. -* We don't list the "all" architecture even though we use it; it's - implied. -* We only have a "main" component, we could have non-free and contrib - here if it was relevant. -* We list the email address associated with the key we want to use to - sign the repository. Yes, even after signing packages we still want to - sign the repository. - -We're now ready to go. Assuming the path to our repository is /path, -(and hence configuration is in /path/conf) we can upload a file to the -repository (creating it in the process) by doing something like this on -the repository host: - -$ reprepro --ignore=wrongdistribution -Vb /path include kitten \ - rabbitmq-server_1.0.0-alpha-1_i386.changes - -Note that we upload to the distribution "kitten" rather than "testing". -We also pass --ignore=wrongdistribution since the current packages are -built to go in "unstable" (this will be changed obviously). - -Note also that the .changes file claims to be for i386 even though the -package is for architecture "all". This is a bug in debhelper. - -Finally, if you've just created a repository, you want to run: - -$ reprepro -Vb /path createsymlinks - -since this will create "kitten" -> "testing" symlinks. You only need to -do this once. - -Removing packages -================= - -Fairly simple: - -$ reprepro --ignore=wrongdistribution -Vb /path remove kitten \ - rabbitmq-server - -Subsequent updates and "dupload" -================================ - -You can run the "reprepro" command above again to update the versions of -software in the repository. Since we probably don't want to have to log -into the machine in question to do this, we can use "dupload". This is a -tool which uploads Debian packages. The supplied file "dupload.conf" can -be renamed to ~/.dupload.conf. If you then run: - -$ dupload -to rabbit --nomail . - -in the folder with the .changes file, dupload will: - -* create an incoming folder in your home directory on the repository -machine -* upload everything there -* run reprepro to move the packages into the repository -* "rm -rf" the uploads folder - -This is a bit cheesy but should be enough for our purposes. The -dupload.conf uses scp and ssh so you need a public-key login (or type -your password lots). - -There's still an open question as to whether dupload is really needed -for our case. - -Keys and signing -================ - -We currently sign the package as we build it; but we also need to sign -the repository. The key is currently on my machine (mrforgetful) and has -ID 056E8E56. We should put it on CDs though. - -reprepro will automatically sign the repository if we have the right -SignWith line in the configuration, AND the secret key is installed on -the repository server. This is obviously not ideal; not sure what the -solution is right now. - -You can export the public key with: - -$ gpg --export --armor 056E8E56 > rabbit.pub - -(Open question: do we want to get our key on subkeys.pgp.net?) - -We can then add this key to the website and tell our users to import the -key into apt with: - -# apt-key add rabbit.pub - diff --git a/packaging/debs/apt-repository/distributions b/packaging/debs/apt-repository/distributions deleted file mode 100644 index 75b9fe4670..0000000000 --- a/packaging/debs/apt-repository/distributions +++ /dev/null @@ -1,7 +0,0 @@ -Origin: RabbitMQ -Label: RabbitMQ Repository for Debian / Ubuntu etc -Suite: testing -Codename: kitten -Architectures: AVR32 alpha amd64 arm armel armhf hppa hurd-i386 i386 ia64 kfreebsd-amd64 kfreebsd-i386 m32 m68k mips mipsel netbsd-alpha netbsd-i386 powerpc s390 s390x sh sparc source -Components: main -Description: RabbitMQ Repository for Debian / Ubuntu etc diff --git a/packaging/debs/apt-repository/dupload.conf b/packaging/debs/apt-repository/dupload.conf deleted file mode 100644 index 9ceed76000..0000000000 --- a/packaging/debs/apt-repository/dupload.conf +++ /dev/null @@ -1,16 +0,0 @@ -package config; - -$rabbit_user = "simon"; -$rabbit_host = "mrforgetful.lshift.net"; -$rabbit_repo_path = "/srv/debian"; -$rabbit_reprepro_extra_args = "--ignore=wrongdistribution"; - -$cfg{'rabbit'} = { - fqdn => "$rabbit_host", - login => "$rabbit_user", - method => "scp", - incoming => "incoming", -}; - -$preupload{'deb'} = "ssh ${rabbit_host} mkdir incoming"; -$postupload{'deb'} = "ssh ${rabbit_host} \"cd incoming && reprepro ${$rabbit_reprepro_extra_args} -Vb ${rabbit_repo_path} include kitten *.changes && cd .. && rm -r incoming\""; diff --git a/packaging/generic-unix/Makefile b/packaging/generic-unix/Makefile deleted file mode 100644 index 66aeff9071..0000000000 --- a/packaging/generic-unix/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -SOURCE_DIST_FILE ?= $(wildcard ../../../rabbitmq-server-*.tar.xz) - -ifneq ($(filter-out clean,$(MAKECMDGOALS)),) -ifeq ($(SOURCE_DIST_FILE),) -$(error Cannot find source archive; please specify SOURCE_DIST_FILE) -endif -ifneq ($(words $(SOURCE_DIST_FILE)),1) -$(error Multile source archives found; please specify SOURCE_DIST_FILE) -endif - -VERSION ?= $(patsubst rabbitmq-server-%.tar.xz,%,$(notdir $(SOURCE_DIST_FILE))) -ifeq ($(VERSION),) -$(error Cannot determine version; please specify VERSION) -endif -endif - -SOURCE_DIR = rabbitmq-server-$(VERSION) -TARGET_DIR = rabbitmq_server-$(VERSION) -TARGET_TARBALL = rabbitmq-server-generic-unix-$(VERSION) - -unexport DEPS_DIR -unexport ERL_LIBS - -all: dist - @: - -dist: - xzcat $(SOURCE_DIST_FILE) | tar -xf - - -# web-manpages are not used by generic-unix but by `make release` in the. -# Umbrella. Those manpages are copied to www.rabbitmq.com - $(MAKE) -C $(SOURCE_DIR) \ - PREFIX= RMQ_ROOTDIR= \ - RMQ_ERLAPP_DIR=`pwd`/$(TARGET_DIR) \ - MANDIR=`pwd`/$(TARGET_DIR)/share/man \ - manpages web-manpages install install-man - - sed -e 's:^SYS_PREFIX=$$:SYS_PREFIX=\$${RABBITMQ_HOME}:' \ - $(TARGET_DIR)/sbin/rabbitmq-defaults >$(TARGET_DIR)/sbin/rabbitmq-defaults.tmp \ - && mv $(TARGET_DIR)/sbin/rabbitmq-defaults.tmp $(TARGET_DIR)/sbin/rabbitmq-defaults - chmod 0755 $(TARGET_DIR)/sbin/rabbitmq-defaults - - mkdir -p $(TARGET_DIR)/etc/rabbitmq - - find $(TARGET_DIR) -print0 | LC_COLLATE=C sort -z | \ - xargs -0 tar --no-recursion -cf - | \ - xz > $(CURDIR)/$(TARGET_TARBALL).tar.xz - - if test "$(PACKAGES_DIR)"; then \ - mkdir -p "$(PACKAGES_DIR)"; \ - mv $(TARGET_TARBALL).tar.xz "$(PACKAGES_DIR)"; \ - fi - -clean: clean_partial - rm -f rabbitmq-server-generic-unix-*.tar.xz - -clean_partial: - rm -rf rabbitmq-server-* rabbitmq_server-* diff --git a/packaging/standalone/Makefile b/packaging/standalone/Makefile deleted file mode 100644 index aa8660ce38..0000000000 --- a/packaging/standalone/Makefile +++ /dev/null @@ -1,123 +0,0 @@ -SOURCE_DIST_FILE ?= $(wildcard ../../rabbitmq-server-*.tar.xz) - -ifneq ($(filter-out clean,$(MAKECMDGOALS)),) -ifeq ($(SOURCE_DIST_FILE),) -$(error Cannot find source archive; please specify SOURCE_DIST_FILE) -endif -ifneq ($(words $(SOURCE_DIST_FILE)),1) -$(error Multile source archives found; please specify SOURCE_DIST_FILE) -endif - -VERSION ?= $(patsubst rabbitmq-server-%.tar.xz,%,$(notdir $(SOURCE_DIST_FILE))) -ifeq ($(VERSION),) -$(error Cannot determine version; please specify VERSION) -endif -endif - -SOURCE_DIR=rabbitmq-server-$(VERSION) -TARGET_DIR=rabbitmq_server-$(VERSION) -TARGET_TARBALL=rabbitmq-server-$(OS)-standalone-$(VERSION) -RLS_DIR=$(TARGET_DIR)/release/$(TARGET_DIR) - -ERTS_VSN=$(shell erl -noshell -eval 'io:format("~s", [erlang:system_info(version)]), halt().') -ERTS_ROOT_DIR=$(shell erl -noshell -eval 'io:format("~s", [code:root_dir()]), halt().') -OTP_RELEASE=$(shell erl -noshell -eval 'io:format("~s", [erlang:system_info(otp_release)]), halt().') - -# used to generate the erlang release -RABBITMQ_HOME=$(TARGET_DIR) -RABBITMQ_EBIN_ROOT=$(RABBITMQ_HOME)/ebin -RABBITMQ_PLUGINS_DIR=$(RABBITMQ_HOME)/plugins -RABBITMQ_PLUGINS_EXPAND_DIR=$(RABBITMQ_PLUGINS_DIR)/expand - -RABBITMQ_DEFAULTS=$(TARGET_DIR)/sbin/rabbitmq-defaults -fix_defaults = sed -e $(1) $(RABBITMQ_DEFAULTS) > $(RABBITMQ_DEFAULTS).tmp \ - && mv $(RABBITMQ_DEFAULTS).tmp $(RABBITMQ_DEFAULTS) - -unexport DEPS_DIR -unexport ERL_LIBS - -all: dist - @: - -dist: - rm -rf $(SOURCE_DIR) $(TARGET_DIR) - xzcat $(SOURCE_DIST_FILE) | tar -xf - - - $(MAKE) -C $(SOURCE_DIR) \ - PREFIX= RMQ_ROOTDIR= \ - RMQ_ERLAPP_DIR=$(abspath $(TARGET_DIR)) \ - MANDIR=$(abspath $(TARGET_DIR))/share/man \ - manpages install install-man - - mkdir -p $(TARGET_DIR)/etc/rabbitmq - cp $(SOURCE_DIR)/docs/rabbitmq.config.example $(TARGET_DIR)/etc/rabbitmq - -## Here we set the RABBITMQ_HOME variable, -## then we make ERL_DIR point to our released erl -## and we add the paths to our released start_clean and start_sasl boot scripts - $(call fix_defaults,'s:^SYS_PREFIX=$$:SYS_PREFIX=\$${RABBITMQ_HOME}:') - $(call fix_defaults,'s:^ERL_DIR=$$:ERL_DIR=\$${RABBITMQ_HOME}/erts-$(ERTS_VSN)/bin/:') - $(call fix_defaults,'s:start_clean$$:"\$${SYS_PREFIX}/releases/$(VERSION)/start_clean":') - $(call fix_defaults,'s:start_sasl:"\$${SYS_PREFIX}/releases/$(VERSION)/start_sasl":') - - chmod 0755 $(RABBITMQ_DEFAULTS) - - mkdir -p $(TARGET_DIR)/etc/rabbitmq - - $(MAKE) generate_release - - mkdir -p $(RLS_DIR) - tar -C $(RLS_DIR) -xzf $(RABBITMQ_HOME)/rabbit.tar.gz - -# add minimal boot file - cp $(ERTS_ROOT_DIR)/bin/start_clean.boot $(RLS_DIR)/releases/$(VERSION) - cp $(ERTS_ROOT_DIR)/bin/start_sasl.boot $(RLS_DIR)/releases/$(VERSION) - -# add OTP_VERSION file - mkdir -p $(RLS_DIR)/releases/$(OTP_RELEASE) - cp $(ERTS_ROOT_DIR)/releases/$(OTP_RELEASE)/OTP_VERSION $(RLS_DIR)/releases/$(OTP_RELEASE)/OTP_VERSION - -# copy start.boot to bin folder as Erlang does. -# Required by rabbit_nodes:ensure_epmd/0 - mkdir -p $(RLS_DIR)/bin/ - cp $(ERTS_ROOT_DIR)/bin/start.boot $(RLS_DIR)/bin/ - -# move rabbitmq files to top level folder - mv $(RLS_DIR)/lib/rabbit-$(VERSION)/* $(RLS_DIR) - -# remove empty lib/rabbit-$(VERSION) folder - rm -rf $(RLS_DIR)/lib/rabbit-$(VERSION) - -# fix Erlang ROOTDIR - patch -o $(RLS_DIR)/erts-$(ERTS_VSN)/bin/erl $(RLS_DIR)/erts-$(ERTS_VSN)/bin/erl.src < erl.diff - rm -f $(RLS_DIR)/erts-$(ERTS_VSN)/bin/erl.orig - - cd $(TARGET_DIR)/release && \ - find $(TARGET_DIR) -print0 | LC_COLLATE=C sort -z | \ - xargs -0 tar --no-recursion -cf - | \ - xz > $(CURDIR)/$(TARGET_TARBALL).tar.xz - - if test "$(PACKAGES_DIR)"; then \ - mkdir -p "$(PACKAGES_DIR)"; \ - mv $(TARGET_TARBALL).tar.xz "$(PACKAGES_DIR)"; \ - fi - -clean: - rm -rf rabbitmq-server-* rabbitmq_server-* - -.PHONY : generate_release -generate_release: - erlc \ - -I $(TARGET_DIR)/include/ -o src -Wall \ - -v +debug_info -Duse_proper_qc \ - -pa $(TARGET_DIR)/ebin/ src/rabbit_release.erl - ERL_LIBS="$(TARGET_DIR)/plugins:$$ERL_LIBS" \ - erl \ - -pa "$(RABBITMQ_EBIN_ROOT)" \ - -pa src \ - -noinput \ - -hidden \ - -s rabbit_release \ - -extra "$(RABBITMQ_PLUGINS_DIR)" "$(RABBITMQ_PLUGINS_EXPAND_DIR)" "$(RABBITMQ_HOME)" - test -f $(RABBITMQ_HOME)/rabbit.tar.gz - rm src/rabbit_release.beam diff --git a/packaging/standalone/erl.diff b/packaging/standalone/erl.diff deleted file mode 100644 index 13b7d328d6..0000000000 --- a/packaging/standalone/erl.diff +++ /dev/null @@ -1,4 +0,0 @@ -21c21 -< ROOTDIR="%FINAL_ROOTDIR%" ---- -> ROOTDIR="$(cd $(dirname "$0") && pwd)/../.." diff --git a/packaging/standalone/src/rabbit_release.erl b/packaging/standalone/src/rabbit_release.erl deleted file mode 100644 index 9eed1a59fa..0000000000 --- a/packaging/standalone/src/rabbit_release.erl +++ /dev/null @@ -1,160 +0,0 @@ -%% The contents of this file are subject to the Mozilla Public License -%% Version 1.1 (the "License"); you may not use this file except in -%% compliance with the License. You may obtain a copy of the License -%% at http://www.mozilla.org/MPL/ -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and -%% limitations under the License. -%% -%% The Original Code is RabbitMQ. -%% -%% The Initial Developer of the Original Code is GoPivotal, Inc. -%% Copyright (c) 2007-2012 GoPivotal, Inc. All rights reserved. -%% --module(rabbit_release). - --export([start/0]). - --include("rabbit.hrl"). - --define(BaseApps, [rabbit]). --define(ERROR_CODE, 1). - -%% We need to calculate all the ERTS apps we need to ship with a -%% standalone rabbit. To acomplish that we need to unpack and load the plugins -%% apps that are shiped with rabbit. -%% Once we get that we generate an erlang release inside a tarball. -%% Our make file will work with that release to generate our final rabbitmq -%% package. -start() -> - %% Determine our various directories - [PluginsDistDir, UnpackedPluginDir, RabbitHome] = - init:get_plain_arguments(), - RootName = UnpackedPluginDir ++ "/rabbit", - - %% extract the plugins so we can load their apps later - prepare_plugins(PluginsDistDir, UnpackedPluginDir), - - %% add the plugin ebin folder to the code path. - add_plugins_to_path(UnpackedPluginDir), - - PluginAppNames = [P#plugin.name || - P <- rabbit_plugins:list(PluginsDistDir, false)], - - %% Build the entire set of dependencies - this will load the - %% applications along the way - AllApps = case catch sets:to_list(expand_dependencies(PluginAppNames)) of - {failed_to_load_app, App, Err} -> - terminate("failed to load application ~s:~n~p", - [App, Err]); - AppList -> - AppList - end, - - %% we need a list of ERTS apps we need to ship with rabbit - RabbitMQAppNames = [rabbit | [P#plugin.name || - P <- rabbit_plugins:list(PluginsDistDir, true)]] - -- PluginAppNames, - {ok, SslAppsConfig} = application:get_env(rabbit, ssl_apps), - - BaseApps = lists:umerge([ - lists:sort(RabbitMQAppNames), - lists:sort(SslAppsConfig), - lists:sort(AllApps -- PluginAppNames)]), - - AppVersions = [determine_version(App) || App <- BaseApps], - RabbitVersion = proplists:get_value(rabbit, AppVersions), - - %% Build the overall release descriptor - RDesc = {release, - {"rabbit", RabbitVersion}, - {erts, erlang:system_info(version)}, - AppVersions}, - - %% Write it out to $RABBITMQ_PLUGINS_EXPAND_DIR/rabbit.rel - rabbit_file:write_file(RootName ++ ".rel", io_lib:format("~p.~n", [RDesc])), - - %% Compile the script - systools:make_script(RootName), - systools:script2boot(RootName), - %% Make release tarfile - make_tar(RootName, RabbitHome), - rabbit_misc:quit(0). - -make_tar(Release, RabbitHome) -> - systools:make_tar(Release, - [ - {dirs, [docs, etc, include, plugins, sbin, share]}, - {erts, code:root_dir()}, - {outdir, RabbitHome} - ]). - -determine_version(App) -> - application:load(App), - {ok, Vsn} = application:get_key(App, vsn), - {App, Vsn}. - -delete_recursively(Fn) -> - case rabbit_file:recursive_delete([Fn]) of - ok -> ok; - {error, {Path, E}} -> {error, {cannot_delete, Path, E}}; - Error -> Error - end. - -prepare_plugins(PluginsDistDir, DestDir) -> - %% Eliminate the contents of the destination directory - case delete_recursively(DestDir) of - ok -> ok; - {error, E} -> terminate("Could not delete dir ~s (~p)", [DestDir, E]) - end, - case filelib:ensure_dir(DestDir ++ "/") of - ok -> ok; - {error, E2} -> terminate("Could not create dir ~s (~p)", [DestDir, E2]) - end, - - [prepare_plugin(Plugin, DestDir) || - Plugin <- rabbit_plugins:list(PluginsDistDir, true)]. - -prepare_plugin(#plugin{type = ez, location = Location}, PluginDestDir) -> - zip:unzip(Location, [{cwd, PluginDestDir}]); -prepare_plugin(#plugin{type = dir, name = Name, location = Location}, - PluginsDestDir) -> - rabbit_file:recursive_copy(Location, - filename:join([PluginsDestDir, Name])). - -expand_dependencies(Pending) -> - expand_dependencies(sets:new(), Pending). -expand_dependencies(Current, []) -> - Current; -expand_dependencies(Current, [Next|Rest]) -> - case sets:is_element(Next, Current) of - true -> - expand_dependencies(Current, Rest); - false -> - case application:load(Next) of - ok -> - ok; - {error, {already_loaded, _}} -> - ok; - {error, Reason} -> - throw({failed_to_load_app, Next, Reason}) - end, - {ok, Required} = application:get_key(Next, applications), - Unique = [A || A <- Required, not(sets:is_element(A, Current))], - expand_dependencies(sets:add_element(Next, Current), Rest ++ Unique) - end. - -add_plugins_to_path(PluginDir) -> - [add_plugin_to_path(PluginName) || - PluginName <- filelib:wildcard(PluginDir ++ "/*/ebin/*.app")]. - -add_plugin_to_path(PluginAppDescFn) -> - %% Add the plugin ebin directory to the load path - PluginEBinDirN = filename:dirname(PluginAppDescFn), - code:add_path(PluginEBinDirN). - -terminate(Fmt, Args) -> - io:format("ERROR: " ++ Fmt ++ "~n", Args), - rabbit_misc:quit(?ERROR_CODE). diff --git a/packaging/windows-exe/Makefile b/packaging/windows-exe/Makefile deleted file mode 100644 index 26ef4585c3..0000000000 --- a/packaging/windows-exe/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -ifeq ($(PACKAGES_DIR),) -ZIP_DIR = ../windows -else -ZIP_DIR = $(PACKAGES_DIR) -endif -ZIP = $(notdir $(wildcard $(ZIP_DIR)/rabbitmq-server-windows-*.zip)) - -VERSION = $(patsubst rabbitmq-server-windows-%.zip,%,$(ZIP)) - -unexport DEPS_DIR -unexport ERL_LIBS - -all: dist - @: - -dist: rabbitmq-$(VERSION).nsi rabbitmq_server-$(VERSION) - makensis -V2 rabbitmq-$(VERSION).nsi - - if test "$(PACKAGES_DIR)"; then \ - mkdir -p "$(PACKAGES_DIR)"; \ - mv rabbitmq-server-$(VERSION).exe "$(PACKAGES_DIR)"; \ - fi - -rabbitmq-$(VERSION).nsi: rabbitmq_nsi.in - sed \ - -e 's|%%VERSION%%|$(VERSION)|' \ - $< > $@ - -rabbitmq_server-$(VERSION): - unzip -q $(ZIP_DIR)/$(ZIP) - -clean: - rm -rf rabbitmq-*.nsi rabbitmq_server-* rabbitmq-server-*.exe diff --git a/packaging/windows-exe/plugins/ExecDos.dll b/packaging/windows-exe/plugins/ExecDos.dll Binary files differdeleted file mode 100644 index 0d8a871a9d..0000000000 --- a/packaging/windows-exe/plugins/ExecDos.dll +++ /dev/null diff --git a/packaging/windows-exe/rabbitmq.ico b/packaging/windows-exe/rabbitmq.ico Binary files differdeleted file mode 100644 index 5e169a7996..0000000000 --- a/packaging/windows-exe/rabbitmq.ico +++ /dev/null diff --git a/packaging/windows-exe/rabbitmq_nsi.in b/packaging/windows-exe/rabbitmq_nsi.in deleted file mode 100644 index 4c47e86628..0000000000 --- a/packaging/windows-exe/rabbitmq_nsi.in +++ /dev/null @@ -1,272 +0,0 @@ -; Use the "Modern" UI -!include MUI2.nsh -!include LogicLib.nsh -!include WinMessages.nsh -!include FileFunc.nsh -!include WordFunc.nsh -!include x64.nsh - -!addplugindir plugins - -!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' -!define uninstall "Software\Microsoft\Windows\CurrentVersion\Uninstall\RabbitMQ" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_UNFINISHPAGE_NOAUTOCLOSE - -;-------------------------------- - -; The name of the installer -Name "RabbitMQ Server %%VERSION%%" - -; The file to write -OutFile "rabbitmq-server-%%VERSION%%.exe" - -; Icons -!define MUI_ICON "rabbitmq.ico" - -; The default installation directory is empty. The .onInit function -; below takes care of selecting the appropriate (32-bit vs. 64-bit) -; "Program Files". -InstallDir "" - -; Registry key to check for directory (so if you install again, it will -; overwrite the old one automatically) -InstallDirRegKey HKLM "Software\VMware, Inc.\RabbitMQ Server" "Install_Dir" - -; Request application privileges for Windows Vista -RequestExecutionLevel admin - -SetCompressor /solid lzma - -;-------------------------------- - -; Pages - - -; !insertmacro MUI_PAGE_LICENSE "..\..\LICENSE-MPL-RabbitMQ" - !insertmacro MUI_PAGE_COMPONENTS - !insertmacro MUI_PAGE_DIRECTORY - !insertmacro MUI_PAGE_INSTFILES - !insertmacro MUI_PAGE_FINISH - - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - !define MUI_FINISHPAGE_TEXT "RabbitMQ Server %%VERSION%% has been uninstalled from your computer.$\n$\nPlease note that the log and database directories located at $APPDATA\RabbitMQ have not been removed. You can remove them manually if desired." - !insertmacro MUI_UNPAGE_FINISH - -;-------------------------------- -;Languages - - !insertmacro MUI_LANGUAGE "English" - -;-------------------------------- - -VIProductVersion "%%VERSION%%.0" -VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "%%VERSION%%" -VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "RabbitMQ Server" -;VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "" -VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "Pivotal Software, Inc" -;VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" "" ; TODO ? -VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved." -VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "RabbitMQ Server" -VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "%%VERSION%%" - -; The stuff to install -Section "RabbitMQ Server (required)" Rabbit - - SectionIn RO - - ; Set output path to the installation directory. - SetOutPath $INSTDIR - - ; Put files there - File /r "rabbitmq_server-%%VERSION%%" - File "rabbitmq.ico" - - ; Set output path to the user's data directory - SetOutPath $APPDATA\RabbitMQ - - ; ...And put the example config file there - File "rabbitmq_server-%%VERSION%%\etc\rabbitmq.config.example" - - ; Write the installation path into the registry - WriteRegStr HKLM "SOFTWARE\VMware, Inc.\RabbitMQ Server" "Install_Dir" "$INSTDIR" - - ; Write the uninstall keys for Windows - WriteRegStr HKLM ${uninstall} "DisplayName" "RabbitMQ Server %%VERSION%%" - WriteRegStr HKLM ${uninstall} "UninstallString" "$INSTDIR\uninstall.exe" - WriteRegStr HKLM ${uninstall} "DisplayIcon" "$INSTDIR\rabbitmq.ico" - WriteRegStr HKLM ${uninstall} "Publisher" "Pivotal Software, Inc." - WriteRegStr HKLM ${uninstall} "DisplayVersion" "%%VERSION%%" - WriteRegDWORD HKLM ${uninstall} "NoModify" 1 - WriteRegDWORD HKLM ${uninstall} "NoRepair" 1 - - ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 - IntFmt $0 "0x%08X" $0 - WriteRegDWORD HKLM "${uninstall}" "EstimatedSize" "$0" - - WriteUninstaller "uninstall.exe" -SectionEnd - -;-------------------------------- - -Section "RabbitMQ Service" RabbitService - DetailPrint "Installing RabbitMQ service..." - ExecDos::exec /DETAILED '"$INSTDIR\rabbitmq_server-%%VERSION%%\sbin\rabbitmq-service.bat" install' "" - DetailPrint "Starting RabbitMQ service..." - ExecDos::exec /DETAILED '"$INSTDIR\rabbitmq_server-%%VERSION%%\sbin\rabbitmq-service.bat" start' "" - ReadEnvStr $1 "HOMEDRIVE" - ReadEnvStr $2 "HOMEPATH" - CopyFiles "$WINDIR\.erlang.cookie" "$1$2\.erlang.cookie" -SectionEnd - -;-------------------------------- - -Section "Start Menu" RabbitStartMenu - ; In case the service is not installed, or the service installation fails, - ; make sure these exist or Explorer will get confused. - CreateDirectory "$APPDATA\RabbitMQ\log" - CreateDirectory "$APPDATA\RabbitMQ\db" - - CreateDirectory "$SMPROGRAMS\RabbitMQ Server" - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\Uninstall RabbitMQ.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\RabbitMQ Plugins.lnk" "$INSTDIR\rabbitmq_server-%%VERSION%%\plugins" - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\RabbitMQ Logs.lnk" "$APPDATA\RabbitMQ\log" - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\RabbitMQ Database Directory.lnk" "$APPDATA\RabbitMQ\db" - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\RabbitMQ Service - (re)install.lnk" "$INSTDIR\rabbitmq_server-%%VERSION%%\sbin\rabbitmq-service.bat" "install" "$INSTDIR\rabbitmq.ico" - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\RabbitMQ Service - remove.lnk" "$INSTDIR\rabbitmq_server-%%VERSION%%\sbin\rabbitmq-service.bat" "remove" "$INSTDIR\rabbitmq.ico" - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\RabbitMQ Service - start.lnk" "$INSTDIR\rabbitmq_server-%%VERSION%%\sbin\rabbitmq-service.bat" "start" "$INSTDIR\rabbitmq.ico" - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\RabbitMQ Service - stop.lnk" "$INSTDIR\rabbitmq_server-%%VERSION%%\sbin\rabbitmq-service.bat" "stop" "$INSTDIR\rabbitmq.ico" - - SetOutPath "$INSTDIR\rabbitmq_server-%%VERSION%%\sbin" - CreateShortCut "$SMPROGRAMS\RabbitMQ Server\RabbitMQ Command Prompt (sbin dir).lnk" "$WINDIR\system32\cmd.exe" "" "$WINDIR\system32\cmd.exe" - SetOutPath $INSTDIR -SectionEnd - -;-------------------------------- - -; Section descriptions - -LangString DESC_Rabbit ${LANG_ENGLISH} "The RabbitMQ Server." -LangString DESC_RabbitService ${LANG_ENGLISH} "Set up RabbitMQ as a Windows Service." -LangString DESC_RabbitStartMenu ${LANG_ENGLISH} "Add some useful links to the start menu." - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${Rabbit} $(DESC_Rabbit) - !insertmacro MUI_DESCRIPTION_TEXT ${RabbitService} $(DESC_RabbitService) - !insertmacro MUI_DESCRIPTION_TEXT ${RabbitStartMenu} $(DESC_RabbitStartMenu) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;-------------------------------- - -; Uninstaller - -Section "Uninstall" - - ; Remove registry keys - DeleteRegKey HKLM ${uninstall} - DeleteRegKey HKLM "SOFTWARE\VMware, Inc.\RabbitMQ Server" - - ; TODO these will fail if the service is not installed - do we care? - DetailPrint "Stopping RabbitMQ service..." - ExecDos::exec /DETAILED '"$INSTDIR\rabbitmq_server-%%VERSION%%\sbin\rabbitmq-service.bat" stop' "" - DetailPrint "Removing RabbitMQ service..." - ExecDos::exec /DETAILED '"$INSTDIR\rabbitmq_server-%%VERSION%%\sbin\rabbitmq-service.bat" remove' "" - - ; Remove files and uninstaller - RMDir /r "$INSTDIR\rabbitmq_server-%%VERSION%%" - Delete "$INSTDIR\rabbitmq.ico" - Delete "$INSTDIR\uninstall.exe" - RMDir "$INSTDIR" - - ; Remove start menu items - RMDir /r "$SMPROGRAMS\RabbitMQ Server" - - DeleteRegValue ${env_hklm} ERLANG_HOME - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - -SectionEnd - -;-------------------------------- - -; Functions - -Function .onInit - ; By default, always install in "\Program Files", not matter if we run - ; on a 32-bit or 64-bit Windows. - ${If} $INSTDIR == ""; - ${If} ${RunningX64} - StrCpy $INSTDIR "$PROGRAMFILES64\RabbitMQ Server" - ${Else} - StrCpy $INSTDIR "$PROGRAMFILES\RabbitMQ Server" - ${EndIf} - ${EndIf} - - Call findErlang - - ReadRegStr $0 HKLM ${uninstall} "UninstallString" - ${If} $0 != "" - MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "RabbitMQ is already installed. $\n$\nClick 'OK' to remove the previous version or 'Cancel' to cancel this installation." /SD IDOK IDOK rununinstall IDCANCEL norun - - norun: - Abort - - rununinstall: - ;Run the uninstaller - ClearErrors - ExecWait '"$INSTDIR\uninstall.exe" /S _?=$INSTDIR' - Delete "$INSTDIR\uninstall.exe" - RMDir "$INSTDIR" - ; the unistaller removes the ERLANG_HOME. - ; called again since this is an update - Call findErlang - - ${EndIf} -FunctionEnd - -Function findErlang - - StrCpy $0 0 - StrCpy $2 "not-found" - ${Do} - EnumRegKey $1 HKLM Software\Ericsson\Erlang $0 - ${If} $1 = "" - ${Break} - ${EndIf} - ${If} $1 <> "ErlSrv" - StrCpy $2 $1 - ${EndIf} - - IntOp $0 $0 + 1 - ${Loop} - - ${If} $2 = "not-found" - MessageBox MB_YESNO|MB_ICONEXCLAMATION "Erlang could not be detected.$\nYou must install Erlang before installing RabbitMQ. Would you like the installer to open a browser window to the Erlang download site?" IDNO abort - ExecShell "open" "http://www.erlang.org/download.html" - abort: - Abort - ${Else} - ${VersionCompare} $2 "5.7.4" $0 - ${VersionCompare} $2 "5.8.1" $1 - - ${If} $0 = 2 - MessageBox MB_OK|MB_ICONEXCLAMATION "Your installed version of Erlang ($2) is too old. Please install a more recent version." - Abort - ${ElseIf} $1 = 2 - MessageBox MB_YESNO|MB_ICONEXCLAMATION "Your installed version of Erlang ($2) is comparatively old.$\nFor best results, please install a newer version.$\nDo you wish to continue?" IDYES no_abort - Abort - no_abort: - ${EndIf} - - ReadRegStr $0 HKLM "Software\Ericsson\Erlang\$2" "" - - ; See http://nsis.sourceforge.net/Setting_Environment_Variables - WriteRegExpandStr ${env_hklm} ERLANG_HOME $0 - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - ; On Windows XP changing the permanent environment does not change *our* - ; environment, so do that as well. - System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("ERLANG_HOME", "$0").r0' - ${EndIf} - -FunctionEnd diff --git a/packaging/windows/Makefile b/packaging/windows/Makefile deleted file mode 100644 index 52b6531c3c..0000000000 --- a/packaging/windows/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -SOURCE_DIST_FILE ?= $(wildcard ../../../rabbitmq-server-*.tar.xz) - -ifneq ($(filter-out clean,$(MAKECMDGOALS)),) -ifeq ($(SOURCE_DIST_FILE),) -$(error Cannot find source archive; please specify SOURCE_DIST_FILE) -endif -ifneq ($(words $(SOURCE_DIST_FILE)),1) -$(error Multile source archives found; please specify SOURCE_DIST_FILE) -endif - -VERSION ?= $(patsubst rabbitmq-server-%.tar.xz,%,$(notdir $(SOURCE_DIST_FILE))) -ifeq ($(VERSION),) -$(error Cannot determine version; please specify VERSION) -endif -endif - -SOURCE_DIR = rabbitmq-server-$(VERSION) -TARGET_DIR = rabbitmq_server-$(VERSION) -TARGET_ZIP = rabbitmq-server-windows-$(VERSION) - -unexport DEPS_DIR -unexport ERL_LIBS - -all: dist - @: - -dist: - xzcat $(SOURCE_DIST_FILE) | tar -xf - - $(MAKE) -C $(SOURCE_DIR) install-windows \ - DESTDIR=$(abspath $(TARGET_DIR)) \ - WINDOWS_PREFIX= - - cp -a README-etc $(TARGET_DIR)/etc/README.txt - - zip -q -r $(TARGET_ZIP).zip $(TARGET_DIR) - - if test "$(PACKAGES_DIR)"; then \ - mkdir -p "$(PACKAGES_DIR)"; \ - mv $(TARGET_ZIP).zip "$(PACKAGES_DIR)"; \ - fi - -clean: - rm -rf rabbitmq-server-* rabbitmq_server-* diff --git a/packaging/windows/README-etc b/packaging/windows/README-etc deleted file mode 100644 index b431247c6b..0000000000 --- a/packaging/windows/README-etc +++ /dev/null @@ -1,7 +0,0 @@ -In this directory you can find an example configuration file for RabbitMQ.
-
-Note that this directory is *not* where the real RabbitMQ
-configuration lives. The default location for the real configuration
-file is %APPDATA%\RabbitMQ\rabbitmq.config.
-
-%APPDATA% usually expands to C:\Users\%USERNAME%\AppData\Roaming or similar.
diff --git a/rabbitmq-components.mk b/rabbitmq-components.mk index e3417856f8..05986d82ce 100644 --- a/rabbitmq-components.mk +++ b/rabbitmq-components.mk @@ -5,16 +5,6 @@ ifeq ($(.DEFAULT_GOAL),) .DEFAULT_GOAL = all endif -# Automatically add rabbitmq-common to the dependencies, at least for -# the Makefiles. -ifneq ($(PROJECT),rabbit_common) -ifneq ($(PROJECT),rabbitmq_public_umbrella) -ifeq ($(filter rabbit_common,$(DEPS)),) -DEPS += rabbit_common -endif -endif -endif - # -------------------------------------------------------------------- # RabbitMQ components. # -------------------------------------------------------------------- @@ -38,6 +28,7 @@ dep_rabbitmq_boot_steps_visualiser = git_rmq rabbitmq-boot-steps-visualiser $ dep_rabbitmq_clusterer = git_rmq rabbitmq-clusterer $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_codegen = git_rmq rabbitmq-codegen $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_consistent_hash_exchange = git_rmq rabbitmq-consistent-hash-exchange $(current_rmq_ref) $(base_rmq_ref) master +dep_rabbitmq_ct_helpers = git_rmq rabbitmq-ct-helpers $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_delayed_message_exchange = git_rmq rabbitmq-delayed-message-exchange $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_dotnet_client = git_rmq rabbitmq-dotnet-client $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_event_exchange = git_rmq rabbitmq-event-exchange $(current_rmq_ref) $(base_rmq_ref) master @@ -59,6 +50,7 @@ dep_rabbitmq_objc_client = git_rmq rabbitmq-objc-client $(current_r dep_rabbitmq_recent_history_exchange = git_rmq rabbitmq-recent-history-exchange $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_routing_node_stamp = git_rmq rabbitmq-routing-node-stamp $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_rtopic_exchange = git_rmq rabbitmq-rtopic-exchange $(current_rmq_ref) $(base_rmq_ref) master +dep_rabbitmq_server_release = git_rmq rabbitmq-server-release $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_sharding = git_rmq rabbitmq-sharding $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_shovel = git_rmq rabbitmq-shovel $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_shovel_management = git_rmq rabbitmq-shovel-management $(current_rmq_ref) $(base_rmq_ref) master @@ -98,6 +90,7 @@ RABBITMQ_COMPONENTS = amqp_client \ rabbitmq_clusterer \ rabbitmq_codegen \ rabbitmq_consistent_hash_exchange \ + rabbitmq_ct_helpers \ rabbitmq_delayed_message_exchange \ rabbitmq_dotnet_client \ rabbitmq_event_exchange \ @@ -119,6 +112,7 @@ RABBITMQ_COMPONENTS = amqp_client \ rabbitmq_recent_history_exchange \ rabbitmq_routing_node_stamp \ rabbitmq_rtopic_exchange \ + rabbitmq_server_release \ rabbitmq_sharding \ rabbitmq_shovel \ rabbitmq_shovel_management \ @@ -246,55 +240,9 @@ prepare-dist:: @: # -------------------------------------------------------------------- -# Run a RabbitMQ node (moved from rabbitmq-run.mk as a workaround). -# -------------------------------------------------------------------- - -# Add "rabbit" to the build dependencies when the user wants to start -# a broker or to the test dependencies when the user wants to test a -# project. -# -# NOTE: This should belong to rabbitmq-run.mk. Unfortunately, it is -# loaded *after* erlang.mk which is too late to add a dependency. That's -# why rabbitmq-components.mk knows the list of targets which start a -# broker and add "rabbit" to the dependencies in this case. - -ifneq ($(PROJECT),rabbit) -ifeq ($(filter rabbit,$(DEPS) $(BUILD_DEPS)),) -RUN_RMQ_TARGETS = run-broker \ - run-tls-broker \ - run-background-broker \ - run-node \ - run-background-node \ - start-background-node \ - start-background-broker \ - start-rabbit-on-node - -ifneq ($(filter $(RUN_RMQ_TARGETS),$(MAKECMDGOALS)),) -BUILD_DEPS += rabbit -endif -endif - -ifeq ($(filter rabbit,$(DEPS) $(BUILD_DEPS) $(TEST_DEPS)),) -ifneq ($(filter check tests,$(MAKECMDGOALS)),) -TEST_DEPS += rabbit -endif -endif -endif - -# -------------------------------------------------------------------- # rabbitmq-components.mk checks. # -------------------------------------------------------------------- -ifeq ($(PROJECT),rabbit_common) -else ifdef SKIP_RMQCOMP_CHECK -else ifeq ($(IS_DEP),1) -else ifneq ($(filter co up,$(MAKECMDGOALS)),) -else -# In all other cases, rabbitmq-components.mk must be in sync. -deps:: check-rabbitmq-components.mk -fetch-deps: check-rabbitmq-components.mk -endif - # If this project is under the Umbrella project, we override $(DEPS_DIR) # to point to the Umbrella's one. We also disable `make distclean` so # $(DEPS_DIR) is not accidentally removed. @@ -308,11 +256,6 @@ endif ifeq ($(UNDER_UMBRELLA),1) ifneq ($(PROJECT),rabbitmq_public_umbrella) DEPS_DIR ?= $(abspath ..) - -distclean:: distclean-components - @: - -distclean-components: endif ifneq ($(filter distclean distclean-deps,$(MAKECMDGOALS)),) diff --git a/scripts/rabbitmq-env b/scripts/rabbitmq-env index 2f9e796f35..8c33e7c0b7 100755 --- a/scripts/rabbitmq-env +++ b/scripts/rabbitmq-env @@ -65,8 +65,11 @@ RABBITMQ_HOME="$(rmq_realpath "${RABBITMQ_SCRIPTS_DIR}/..")" DEFAULT_SCHEDULER_BIND_TYPE="db" [ "x" = "x$RABBITMQ_SCHEDULER_BIND_TYPE" ] && RABBITMQ_SCHEDULER_BIND_TYPE=${DEFAULT_SCHEDULER_BIND_TYPE} +DEFAULT_DISTRIBUTION_BUFFER_SIZE=32000 +[ "x" = "x$RABBITMQ_DISTRIBUTION_BUFFER_SIZE" ] && RABBITMQ_DISTRIBUTION_BUFFER_SIZE=${DEFAULT_DISTRIBUTION_BUFFER_SIZE} + ## Common defaults -SERVER_ERL_ARGS="+P 1048576 +stbt $RABBITMQ_SCHEDULER_BIND_TYPE " +SERVER_ERL_ARGS="+P 1048576 +t 5000000 +stbt $RABBITMQ_SCHEDULER_BIND_TYPE +zdbbl $RABBITMQ_DISTRIBUTION_BUFFER_SIZE" # We save the current value of $RABBITMQ_PID_FILE in case it was set by # an init script. If $CONF_ENV_FILE overrides it again, we must ignore @@ -183,6 +186,8 @@ DEFAULT_NODE_PORT=5672 [ "x" = "x$RABBITMQ_SERVER_CODE_PATH" ] && RABBITMQ_SERVER_CODE_PATH=${SERVER_CODE_PATH} [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${MNESIA_DIR} [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME} +[ "x" = "x$RABBITMQ_IGNORE_SIGINT" ] && RABBITMQ_IGNORE_SIGINT="true" +[ "xtrue" = "x$RABBITMQ_IGNORE_SIGINT" ] && RABBITMQ_IGNORE_SIGINT_FLAG="+B i" rmq_normalize_path_var \ RABBITMQ_CONFIG_FILE \ diff --git a/scripts/rabbitmq-env.bat b/scripts/rabbitmq-env.bat index 7587faaa62..3c84351d52 100644 --- a/scripts/rabbitmq-env.bat +++ b/scripts/rabbitmq-env.bat @@ -38,6 +38,14 @@ if "!RABBITMQ_SCHEDULER_BIND_TYPE!"=="" ( set RABBITMQ_SCHEDULER_BIND_TYPE=!DEFAULT_SCHEDULER_BIND_TYPE!
)
+REM DEFAULT_DISTRIBUTION_BUFFER_SIZE=32000
+REM set the VM distribution buffer size
+REM [ "x" = "x$RABBITMQ_DISTRIBUTION_BUFFER_SIZE" ] && RABBITMQ_DISTRIBUTION_BUFFER_SIZE=${DEFAULT_DISTRIBUTION_BUFFER_SIZE}
+set DEFAULT_DISTRIBUTION_BUFFER_SIZE=32000
+if "!RABBITMQ_DISTRIBUTION_BUFFER_SIZE!"=="" (
+ set RABBITMQ_DISTRIBUTION_BUFFER_SIZE=!DEFAULT_DISTRIBUTION_BUFFER_SIZE!
+)
+
REM # warn about old rabbitmq.conf file, if no new one
REM if [ -f /etc/rabbitmq/rabbitmq.conf ] && \
REM [ ! -f ${CONF_ENV_FILE} ] ; then
@@ -46,7 +54,7 @@ REM echo "location has moved to ${CONF_ENV_FILE}" REM fi
REM Common defaults
-set SERVER_ERL_ARGS=+P 1048576 +stbt !RABBITMQ_SCHEDULER_BIND_TYPE!
+set SERVER_ERL_ARGS=+P 1048576 +t 5000000 +stbt !RABBITMQ_SCHEDULER_BIND_TYPE! +zdbbl !RABBITMQ_DISTRIBUTION_BUFFER_SIZE!
REM ## Get configuration variables from the configure environment file
REM [ -f ${CONF_ENV_FILE} ] && . ${CONF_ENV_FILE} || true
diff --git a/scripts/rabbitmq-script-wrapper b/scripts/rabbitmq-script-wrapper deleted file mode 100644 index 9623f01709..0000000000 --- a/scripts/rabbitmq-script-wrapper +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -## The contents of this file are subject to the Mozilla Public License -## Version 1.1 (the "License"); you may not use this file except in -## compliance with the License. You may obtain a copy of the License -## at http://www.mozilla.org/MPL/ -## -## Software distributed under the License is distributed on an "AS IS" -## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -## the License for the specific language governing rights and -## limitations under the License. -## -## The Original Code is RabbitMQ. -## -## The Initial Developer of the Original Code is GoPivotal, Inc. -## Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. -## - -for arg in "$@" ; do - # Wrap each arg in single quotes and wrap single quotes in double quotes, so that they're passed through cleanly. - arg=`printf %s "$arg" | sed -e "s#'#'\"'\"'#g"` - CMDLINE="${CMDLINE} '${arg}'" -done - -cd /var/lib/rabbitmq - -SCRIPT=`basename $0` - -if [ `id -u` = `id -u rabbitmq` -a "$SCRIPT" = "rabbitmq-server" ] ; then - RABBITMQ_ENV=/usr/lib/rabbitmq/bin/rabbitmq-env - RABBITMQ_SCRIPTS_DIR=$(dirname "$RABBITMQ_ENV") - . "$RABBITMQ_ENV" - - exec /usr/lib/rabbitmq/bin/rabbitmq-server "$@" @STDOUT_STDERR_REDIRECTION@ -elif [ `id -u` = `id -u rabbitmq` -o "$SCRIPT" = "rabbitmq-plugins" ] ; then - if [ -f $PWD/.erlang.cookie ] ; then - export HOME=. - fi - exec /usr/lib/rabbitmq/bin/${SCRIPT} "$@" -elif [ `id -u` = 0 ] ; then - @SU_RABBITMQ_SH_C@ "/usr/lib/rabbitmq/bin/${SCRIPT} ${CMDLINE}" -else - /usr/lib/rabbitmq/bin/${SCRIPT} - echo - echo "Only root or rabbitmq should run ${SCRIPT}" - echo - exit 1 -fi diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server index 74337311cd..7b0599e88f 100755 --- a/scripts/rabbitmq-server +++ b/scripts/rabbitmq-server @@ -62,6 +62,17 @@ RABBITMQ_EBIN_ROOT="${RABBITMQ_HOME}/ebin" set +e +# `net_kernel:start/1` will fail in `longnames` mode when erlang is +# unable to determine FQDN of a node (with a dot in it). But `erl` +# itself has some magic that still allow it to start when you +# explicitly specify host (a.la `erl -name test@localhost`). +# +# It's not possible to communicate with this node, unless it's a +# connection initiator. But as prelaunch IS an initiator, it doesn't +# matter what we actually put here. But `localhost` sounds good +# enough. +RABBITMQ_PRELAUNCH_NODENAME="rabbitmqprelaunch${$}@localhost" + # NOTIFY_SOCKET is needed here to prevent epmd from impersonating the # success of our startup sequence to systemd. NOTIFY_SOCKET= \ @@ -72,7 +83,7 @@ RABBITMQ_DIST_PORT=$RABBITMQ_DIST_PORT \ -noinput \ -hidden \ -s rabbit_prelaunch \ - ${RABBITMQ_NAME_TYPE} rabbitmqprelaunch$$ \ + ${RABBITMQ_NAME_TYPE} ${RABBITMQ_PRELAUNCH_NODENAME} \ -extra "${RABBITMQ_NODENAME}" PRELAUNCH_RESULT=$? @@ -213,9 +224,8 @@ else # When RabbitMQ runs in the foreground but the Erlang shell is # disabled, we setup signal handlers to stop RabbitMQ properly. This # is at least useful in the case of Docker. - # The Erlang VM should ignore SIGINT. - RABBITMQ_SERVER_START_ARGS="${RABBITMQ_SERVER_START_ARGS} +B i" + RABBITMQ_SERVER_START_ARGS="${RABBITMQ_SERVER_START_ARGS} ${RABBITMQ_IGNORE_SIGINT_FLAG}" # Signal handlers. They all stop RabbitMQ properly (using # rabbitmqctl stop). Depending on the signal, this script will exit diff --git a/scripts/rabbitmq-server-ha.ocf b/scripts/rabbitmq-server-ha.ocf deleted file mode 100755 index cd07d0c1b0..0000000000 --- a/scripts/rabbitmq-server-ha.ocf +++ /dev/null @@ -1,2299 +0,0 @@ -#!/bin/sh -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# See usage() function below for more details ... -# -# Note that the script uses an external file to setup RabbitMQ policies -# so make sure to create it from an example shipped with the package. -# -####################################################################### -# Initialization: - -: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} -. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs - -####################################################################### - -# Fill in some defaults if no values are specified - -PATH=/sbin:/usr/sbin:/bin:/usr/bin - -OCF_RESKEY_binary_default="/usr/sbin/rabbitmq-server" -OCF_RESKEY_ctl_default="/usr/sbin/rabbitmqctl" -OCF_RESKEY_debug_default=false -OCF_RESKEY_username_default="rabbitmq" -OCF_RESKEY_groupname_default="rabbitmq" -OCF_RESKEY_admin_user_default="guest" -OCF_RESKEY_admin_password_default="guest" -OCF_RESKEY_definitions_dump_file_default="/etc/rabbitmq/definitions" -OCF_RESKEY_pid_file_default="/var/run/rabbitmq/pid" -OCF_RESKEY_log_dir_default="/var/log/rabbitmq" -OCF_RESKEY_mnesia_base_default="/var/lib/rabbitmq/mnesia" -OCF_RESKEY_host_ip_default="127.0.0.1" -OCF_RESKEY_node_port_default=5672 -OCF_RESKEY_erlang_cookie_default=false -OCF_RESKEY_erlang_cookie_file_default="/var/lib/rabbitmq/.erlang.cookie" -OCF_RESKEY_use_fqdn_default=false -OCF_RESKEY_fqdn_prefix_default="" -OCF_RESKEY_max_rabbitmqctl_timeouts_default=3 -OCF_RESKEY_policy_file_default="/usr/local/sbin/set_rabbitmq_policy" - -: ${HA_LOGTAG="lrmd"} -: ${HA_LOGFACILITY="daemon"} -: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} -: ${OCF_RESKEY_ctl=${OCF_RESKEY_ctl_default}} -: ${OCF_RESKEY_debug=${OCF_RESKEY_debug_default}} -: ${OCF_RESKEY_username=${OCF_RESKEY_username_default}} -: ${OCF_RESKEY_groupname=${OCF_RESKEY_groupname_default}} -: ${OCF_RESKEY_admin_user=${OCF_RESKEY_admin_user_default}} -: ${OCF_RESKEY_admin_password=${OCF_RESKEY_admin_password_default}} -: ${OCF_RESKEY_definitions_dump_file=${OCF_RESKEY_definitions_dump_file_default}} -: ${OCF_RESKEY_log_dir=${OCF_RESKEY_log_dir_default}} -: ${OCF_RESKEY_mnesia_base=${OCF_RESKEY_mnesia_base_default}} -: ${OCF_RESKEY_pid_file=${OCF_RESKEY_pid_file_default}} -: ${OCF_RESKEY_node_port=${OCF_RESKEY_node_port_default}} -: ${OCF_RESKEY_erlang_cookie=${OCF_RESKEY_erlang_cookie_default}} -: ${OCF_RESKEY_erlang_cookie_file=${OCF_RESKEY_erlang_cookie_file_default}} -: ${OCF_RESKEY_use_fqdn=${OCF_RESKEY_use_fqdn_default}} -: ${OCF_RESKEY_fqdn_prefix=${OCF_RESKEY_fqdn_prefix_default}} -: ${OCF_RESKEY_max_rabbitmqctl_timeouts=${OCF_RESKEY_max_rabbitmqctl_timeouts_default}} -: ${OCF_RESKEY_policy_file=${OCF_RESKEY_policy_file_default}} - -####################################################################### - -OCF_RESKEY_start_time_default=$((OCF_RESKEY_CRM_meta_timeout / 6000 + 2)) -: ${OCF_RESKEY_start_time=${OCF_RESKEY_start_time_default}} -OCF_RESKEY_stop_time_default=${OCF_RESKEY_start_time_default} -: ${OCF_RESKEY_stop_time=${OCF_RESKEY_start_time_default}} -OCF_RESKEY_command_timeout_default="" -: ${OCF_RESKEY_command_timeout=${OCF_RESKEY_command_timeout_default}} -TIMEOUT_ARG=$((OCF_RESKEY_CRM_meta_timeout / 6000 + 30)) -COMMAND_TIMEOUT="/usr/bin/timeout ${OCF_RESKEY_command_timeout} ${TIMEOUT_ARG}" - -####################################################################### - -usage() { - cat <<UEND - usage: $0 (start|stop|validate-all|meta-data|status|monitor) - - $0 manages an ${OCF_RESKEY_binary} process as an HA resource - - The 'start' operation starts the networking service. - The 'stop' operation stops the networking service. - The 'validate-all' operation reports whether the parameters are valid - The 'meta-data' operation reports this RA's meta-data information - The 'status' operation reports whether the networking service is running - The 'monitor' operation reports whether the networking service seems to be working - -UEND -} - -meta_data() { - # The EXTENDED_OCF_PARAMS parameter below does not exist by default - # and hence converted to an empty string unless overridden. It - # could be used by an extention script to add new parameters. For - # example see https://review.openstack.org/#/c/249180/10 - - cat <<END -<?xml version="1.0"?> -<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> -<resource-agent name="${OCF_RESKEY_binary}"> -<version>1.0</version> - -<longdesc lang="en"> -Resource agent for ${OCF_RESKEY_binary} -</longdesc> -<shortdesc lang="en">Resource agent for ${OCF_RESKEY_binary}</shortdesc> -<parameters> - -<parameter name="binary" unique="0" required="0"> -<longdesc lang="en"> -RabbitMQ binary -</longdesc> -<shortdesc lang="en">RabbitMQ binary</shortdesc> -<content type="string" default="${OCF_RESKEY_binary_default}" /> -</parameter> - -<parameter name="ctl" unique="0" required="0"> -<longdesc lang="en"> -rabbitctl binary -</longdesc> -<shortdesc lang="en">rabbitctl binary binary</shortdesc> -<content type="string" default="${OCF_RESKEY_ctl_default}" /> -</parameter> - -<parameter name="pid_file" unique="0" required="0"> -<longdesc lang="en"> -RabbitMQ PID file -</longdesc> -<shortdesc lang="en">RabbitMQ PID file</shortdesc> -<content type="string" default="${OCF_RESKEY_pid_file_default}" /> -</parameter> - -<parameter name="log_dir" unique="0" required="0"> -<longdesc lang="en"> -RabbitMQ log directory -</longdesc> -<shortdesc lang="en">RabbitMQ log directory</shortdesc> -<content type="string" default="${OCF_RESKEY_log_dir_default}" /> -</parameter> - -<parameter name="username" unique="0" required="0"> -<longdesc lang="en"> -RabbitMQ user name -</longdesc> -<shortdesc lang="en">RabbitMQ user name</shortdesc> -<content type="string" default="${OCF_RESKEY_username_default}" /> -</parameter> - -<parameter name="groupname" unique="0" required="0"> -<longdesc lang="en"> -RabbitMQ group name -</longdesc> -<shortdesc lang="en">RabbitMQ group name</shortdesc> -<content type="string" default="${OCF_RESKEY_groupname_default}" /> -</parameter> - -<parameter name="admin_user" unique="0" required="0"> -<longdesc lang="en"> -RabbitMQ default admin user for API -</longdesc> -<shortdesc lang="en">RabbitMQ admin user</shortdesc> -<content type="string" default="${OCF_RESKEY_admin_user_default}" /> -</parameter> - -<parameter name="admin_password" unique="0" required="0"> -<longdesc lang="en"> -RabbitMQ default admin user password for API -</longdesc> -<shortdesc lang="en">RabbitMQ admin password</shortdesc> -<content type="string" default="${OCF_RESKEY_admin_password_default}" /> -</parameter> - -<parameter name="definitions_dump_file" unique="0" required="0"> -<longdesc lang="en"> -RabbitMQ default definitions dump file -</longdesc> -<shortdesc lang="en">RabbitMQ definitions dump file</shortdesc> -<content type="string" default="${OCF_RESKEY_definitions_dump_file}" /> -</parameter> - -<parameter name="command_timeout" unique="0" required="0"> -<longdesc lang="en"> -Timeout command arguments for issued commands termination (value is auto evaluated) -</longdesc> -<shortdesc lang="en">Arguments for timeout wrapping command</shortdesc> -<content type="string" default="${OCF_RESKEY_command_timeout_default}" /> -</parameter> - -<parameter name="start_time" unique="0" required="0"> -<longdesc lang="en"> -Timeout for start rabbitmq server -</longdesc> -<shortdesc lang="en">Timeout for start rabbitmq server</shortdesc> -<content type="string" default="${OCF_RESKEY_start_time_default}" /> -</parameter> - -<parameter name="stop_time" unique="0" required="0"> -<longdesc lang="en"> -Timeout for stopping rabbitmq server -</longdesc> -<shortdesc lang="en">Timeout for stopping rabbitmq server</shortdesc> -<content type="string" default="${OCF_RESKEY_stop_time_default}" /> -</parameter> - -<parameter name="debug" unique="0" required="0"> -<longdesc lang="en"> -The debug flag for agent (${OCF_RESKEY_binary}) instance. -In the /tmp/ directory will be created rmq-* files for log -some operations and ENV values inside OCF-script. -</longdesc> -<shortdesc lang="en">AMQP server (${OCF_RESKEY_binary}) debug flag</shortdesc> -<content type="boolean" default="${OCF_RESKEY_debug_default}" /> -</parameter> - -<parameter name="mnesia_base" unique="0" required="0"> -<longdesc lang="en"> -Base directory for storing Mnesia files -</longdesc> -<shortdesc lang="en">Base directory for storing Mnesia files</shortdesc> -<content type="boolean" default="${OCF_RESKEY_mnesia_base_default}" /> -</parameter> - -<parameter name="host_ip" unique="0" required="0"> -<longdesc lang="en"> -${OCF_RESKEY_binary} should listen on this IP address -</longdesc> -<shortdesc lang="en">${OCF_RESKEY_binary} should listen on this IP address</shortdesc> -<content type="boolean" default="${OCF_RESKEY_host_ip_default}" /> -</parameter> - -<parameter name="node_port" unique="0" required="0"> -<longdesc lang="en"> -${OCF_RESKEY_binary} should listen on this port -</longdesc> -<shortdesc lang="en">${OCF_RESKEY_binary} should listen on this port</shortdesc> -<content type="boolean" default="${OCF_RESKEY_node_port_default}" /> -</parameter> - -<parameter name="erlang_cookie" unique="0" required="0"> -<longdesc lang="en"> -Erlang cookie for clustering. If specified, will be updated at the mnesia reset -</longdesc> -<shortdesc lang="en">Erlang cookie</shortdesc> -<content type="boolean" default="${OCF_RESKEY_erlang_cookie_default}" /> -</parameter> - -<parameter name="erlang_cookie_file" unique="0" required="0"> -<longdesc lang="en"> -Erlang cookie file path where the cookie will be put, if requested -</longdesc> -<shortdesc lang="en">Erlang cookie file</shortdesc> -<content type="boolean" default="${OCF_RESKEY_erlang_cookie_file_default}" /> -</parameter> - -<parameter name="use_fqdn" unique="0" required="0"> -<longdesc lang="en"> -Either to use FQDN or a shortname for the rabbitmq node -</longdesc> -<shortdesc lang="en">Use FQDN</shortdesc> -<content type="boolean" default="${OCF_RESKEY_use_fqdn_default}" /> -</parameter> - -<parameter name="fqdn_prefix" unique="0" required="0"> -<longdesc lang="en"> -Optional FQDN prefix for RabbitMQ nodes in cluster. -FQDN prefix can be specified to host multiple RabbitMQ instances on a node or -in case of RabbitMQ running in dedicated network/interface. -</longdesc> -<shortdesc lang="en">FQDN prefix</shortdesc> -<content type="string" default="${OCF_RESKEY_fqdn_prefix_default}" /> -</parameter> - -<parameter name="max_rabbitmqctl_timeouts" unique="0" required="0"> -<longdesc lang="en"> -If during monitor call rabbitmqctl times out, the timeout is ignored -unless it is Nth timeout in a row. Here N is the value of the current parameter. -If too many timeouts happen in a raw, the monitor call will return with error. -</longdesc> -<shortdesc lang="en">Fail only if that many rabbitmqctl timeouts in a row occurred</shortdesc> -<content type="string" default="${OCF_RESKEY_max_rabbitmqctl_timeouts_default}" /> -</parameter> - -<parameter name="policy_file" unique="0" required="0"> -<longdesc lang="en"> -A path to the shell script to setup RabbitMQ policies -</longdesc> -<shortdesc lang="en">A policy file path</shortdesc> -<content type="string" default="${OCF_RESKEY_policy_file_default}" /> -</parameter> - -$EXTENDED_OCF_PARAMS - -</parameters> - -<actions> -<action name="start" timeout="20" /> -<action name="stop" timeout="20" /> -<action name="status" timeout="20" /> -<action name="monitor" depth="0" timeout="30" interval="5" /> -<action name="monitor" depth="0" timeout="30" interval="3" role="Master"/> -<action name="monitor" depth="30" timeout="60" interval="103" /> -<action name="promote" timeout="30" /> -<action name="demote" timeout="30" /> -<action name="notify" timeout="20" /> -<action name="validate-all" timeout="5" /> -<action name="meta-data" timeout="5" /> -</actions> -</resource-agent> -END -} - -####################################################################### -# Functions invoked by resource manager actions - -#TODO(bogdando) move proc_kill, proc_stop to shared OCF functions -# to be shipped with HA cluster packages -########################################################### -# Attempts to kill a process with retries and checks procfs -# to make sure the process is stopped. -# -# Globals: -# LL -# Arguments: -# $1 - pid of the process to try and kill -# $2 - service name used for logging and match-based kill, if the pid is "none" -# $3 - signal to use, defaults to SIGTERM -# $4 - number of retries, defaults to 5 -# $5 - time to sleep between retries, defaults to 2 -# Returns: -# 0 - if successful -# 1 - if process is still running according to procfs -# 2 - if invalid parameters passed in -########################################################### -proc_kill() -{ - local pid="${1}" - local service_name="${2}" - local signal="${3:-SIGTERM}" - local count="${4:-5}" - local process_sleep="${5:-2}" - local LH="${LL} proc_kill():" - local pgrp="$(ps -o pgid= ${pid} 2>/dev/null | tr -d '[[:space:]]')" - - if [ "${pid}" -a "${pgrp}" = "1" ] ; then - ocf_log err "${LH} shall not kill by the bad pid 1 (init)!" - return 2 - fi - - if [ "${pid}" = "none" ]; then - local matched - matched="$(pgrep -fla ${service_name})" - if [ -z "${matched}" ] ; then - ocf_log err "${LH} cannot find any processes matching the ${service_name}!" - return 2 - fi - ocf_log debug "${LH} no pid provided, will try the ${service_name}, matched list: ${matched}" - while [ $count -gt 0 ]; do - if [ -z "${matched}" ]; then - break - else - matched="$(pgrep -fla ${service_name})" - ocf_log debug "${LH} Stopping ${service_name} with ${signal}..." - ocf_run pkill -f -"${signal}" "${service_name}" - fi - sleep $process_sleep - count=$(( count-1 )) - done - pgrep -f "${service_name}" > /dev/null - if [ $? -ne 0 ] ; then - ocf_log debug "${LH} Stopped ${service_name} with ${signal}" - return 0 - else - ocf_log warn "${LH} Failed to stop ${service_name} with ${signal}" - return 1 - fi - else - # pid is not none - while [ $count -gt 0 ]; do - if [ ! -d "/proc/${pid}" ]; then - break - else - ocf_log debug "${LH} Stopping ${service_name} with ${signal}..." - ocf_run pkill -"${signal}" -g "${pgrp}" - fi - sleep $process_sleep - count=$(( count-1 )) - done - - # Check if the process ended after the last sleep - if [ ! -d "/proc/${pid}" ] ; then - ocf_log debug "${LH} Stopped ${service_name} with ${signal}" - return 0 - fi - - ocf_log warn "${LH} Failed to stop ${service_name} with ${signal}" - return 1 - fi -} - -########################################################### -# Attempts to kill a process with the given pid or pid file -# using proc_kill and will retry with sigkill if sigterm is -# unsuccessful. -# -# Globals: -# OCF_ERR_GENERIC -# OCF_SUCCESS -# LL -# Arguments: -# $1 - pidfile or pid or 'none', if stopping by the name matching -# $2 - service name used for logging or for the failback stopping method -# $3 - stop process timeout (in sec), used to determine how many times we try -# SIGTERM and an upper limit on how long this function should try and -# stop the process. Defaults to 15. -# Returns: -# OCF_SUCCESS - if successful -# OCF_ERR_GENERIC - if process is still running according to procfs -########################################################### -proc_stop() -{ - local pid_param="${1}" - local service_name="${2}" - local timeout="${3:-15}" - local LH="${LL} proc_stop():" - local i - local pid - local pidfile - if [ "${pid_param}" = "none" ] ; then - pid="none" - else - # check if provide just a number - echo "${pid_param}" | egrep -q '^[0-9]+$' - if [ $? -eq 0 ]; then - pid="${pid_param}" - elif [ -e "${pid_param}" ]; then # check if passed in a pid file - pidfile="${pid_param}" - pid=$(cat "${pidfile}" 2>/dev/null | tr -s " " "\n" | sort -u) - else - ocf_log warn "${LH} pid param ${pid_param} is not a file or a number, try match by ${service_name}" - pid="none" - fi - fi - # number of times to try a SIGTEM is (timeout - 5 seconds) / 2 seconds - local stop_count=$(( ($timeout-5)/2 )) - - # make sure we stop at least once - if [ $stop_count -le 0 ]; then - stop_count=1 - fi - - if [ -z "${pid}" ] ; then - ocf_log warn "${LH} unable to get PID from ${pidfile}, try match by ${service_name}" - pid="none" - fi - - if [ -n "${pid}" ]; then - for i in ${pid} ; do - [ "${i}" ] || break - ocf_log info "${LH} Stopping ${service_name} by PID ${i}" - proc_kill "${i}" "${service_name}" SIGTERM $stop_count - if [ $? -ne 0 ]; then - # SIGTERM failed, send a single SIGKILL - proc_kill "${i}" "${service_name}" SIGKILL 1 2 - if [ $? -ne 0 ]; then - ocf_log err "${LH} ERROR: could not stop ${service_name}" - return "${OCF_ERR_GENERIC}" - fi - fi - done - fi - - # Remove the pid file here which will remove empty pid files as well - if [ -n "${pidfile}" ]; then - rm -f "${pidfile}" - fi - - ocf_log info "${LH} Stopped ${service_name}" - return "${OCF_SUCCESS}" -} - -# Invokes the given command as a rabbitmq user and wrapped in the -# timeout command. -su_rabbit_cmd() { - local timeout - if [ "$1" = "-t" ]; then - timeout="/usr/bin/timeout ${OCF_RESKEY_command_timeout} $2" - shift 2 - else - timeout=$COMMAND_TIMEOUT - fi - local cmd="${1:-status}" - local LH="${LL} su_rabbit_cmd():" - local rc=1 - local user=$OCF_RESKEY_username - local mail=/var/spool/mail/rabbitmq - local pwd=/var/lib/rabbitmq - local home=/var/lib/rabbitmq - - ocf_log debug "${LH} invoking a command: ${cmd}" - su $user -s /bin/sh -c "USER=${user} MAIL=${mail} PWD=${pwd} HOME=${home} LOGNAME=${user} \ - ${timeout} ${cmd}" - rc=$? - ocf_log info "${LH} the invoked command exited ${rc}: ${cmd}" - return $rc -} - -now() { - date -u +%s -} - -master_score() { - local LH="${LL} master_score():" - local score=$1 - if [ -z $score ] ; then - score=0 - fi - ocf_log info "${LH} Updating master score attribute with ${score}" - ocf_run crm_master -l reboot -v $score || return $OCF_ERR_GENERIC - return $OCF_SUCCESS -} - -# Return either FQDN or shortname, depends on the OCF_RESKEY_use_fqdn. -get_hostname() { - if [ "${OCF_RESKEY_use_fqdn}" = 'false' ] ; then - echo "$(hostname -s)" - else - echo "$(hostname -f)" - fi -} - -# Strip the FQDN to the shortname, if OCF_RESKEY_use_fqdn was set; -# Prepend prefix to the hostname -process_fqdn() { - if [ "${OCF_RESKEY_use_fqdn}" = 'false' ] ; then - echo "${OCF_RESKEY_fqdn_prefix}$1" | awk -F. '{print $1}' - else - echo "${OCF_RESKEY_fqdn_prefix}$1" - fi -} - -# Return OCF_SUCCESS, if current host is in the list of given hosts. -# Otherwise, return 10 -my_host() { - local hostlist="$1" - local hostname - local hn - local rc=10 - local LH="${LL} my_host():" - - hostname=$(process_fqdn $(get_hostname)) - ocf_log info "${LH} hostlist is: $hostlist" - for host in $hostlist ; do - hn=$(process_fqdn "${host}") - ocf_log debug "${LH} comparing '$hostname' with '$hn'" - if [ "${hostname}" = "${hn}" ] ; then - rc=$OCF_SUCCESS - break - fi - done - - return $rc -} - -srv_uptime() { - local stime - stime=$( crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --query 2>/dev/null | awk '{print $3}' | awk -F "=" '{print $2}' | sed -e '/(null)/d' ) - - if [ -z "${stime}" -o "${stime}" = "(null)" ] ; then - echo 0 - else - echo $(( $(now) - ${stime} )) - fi - - return $OCF_SUCCESS -} - -# Return either rabbit node name as FQDN or shortname, depends on the OCF_RESKEY_use_fqdn. -rabbit_node_name() { - echo "rabbit@$(process_fqdn $1)" -} - -rmq_setup_env() { - local H - local dir - H="$(get_hostname)" - export RABBITMQ_NODENAME=$(rabbit_node_name $H) - export RABBITMQ_NODE_PORT=$OCF_RESKEY_node_port - export RABBITMQ_PID_FILE=$OCF_RESKEY_pid_file - MNESIA_FILES="${OCF_RESKEY_mnesia_base}/$(rabbit_node_name $H)" - RMQ_START_TIME="${MNESIA_FILES}/ocf_server_start_time.txt" - MASTER_FLAG_FILE="${MNESIA_FILES}/ocf_master_for_${OCF_RESOURCE_INSTANCE}" - THIS_PCMK_NODE=`crm_node -n` - TOTALVMEM=`free -mt | awk '/Total:/ {print $2}'` - # check and make PID file dir - local PID_DIR=$( dirname $OCF_RESKEY_pid_file ) - if [ ! -d ${PID_DIR} ] ; then - mkdir -p ${PID_DIR} - chown -R ${OCF_RESKEY_username}:${OCF_RESKEY_groupname} ${PID_DIR} - chmod 755 ${PID_DIR} - fi - - # Regardless of whether we just created the directory or it - # already existed, check whether it is writable by the configured - # user - for dir in ${PID_DIR} "${OCF_RESKEY_mnesia_base}" "${OCF_RESKEY_log_dir}"; do - if test -e ${dir}; then - local files - files=$(su -s /bin/sh - $OCF_RESKEY_username -c "find ${dir} ! -writable") - if [ "${files}" ]; then - ocf_log warn "Directory ${dir} is not writable by ${OCF_RESKEY_username}, chowning." - chown -R ${OCF_RESKEY_username}:${OCF_RESKEY_groupname} "${dir}" - fi - fi - done - - export LL="${OCF_RESOURCE_INSTANCE}[$$]:" - update_cookie -} - -# Return a RabbitMQ node to its virgin state. -# For reset and force_reset to succeed the RabbitMQ application must have been stopped. -# If the app cannot be stopped, beam will be killed and mnesia files will be removed. -reset_mnesia() { - local LH="${LL} reset_mnesia():" - local make_amnesia=false - local rc=$OCF_ERR_GENERIC - - # check status of a beam process - get_status - rc=$? - if [ $rc -eq 0 ] ; then - # beam is running - # check status of rabbit app and stop it, if it is running - get_status rabbit - rc=$? - if [ $rc -eq 0 ] ; then - # rabbit app is running, have to stop it - ocf_log info "${LH} Stopping RMQ-app prior to reset the mnesia." - stop_rmq_server_app - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log warn "${LH} RMQ-app can't be stopped." - make_amnesia=true - fi - fi - - if ! $make_amnesia ; then - # rabbit app is not running, reset mnesia - ocf_log info "${LH} Execute reset with timeout: ${TIMEOUT_ARG}" - su_rabbit_cmd "${OCF_RESKEY_ctl} reset" - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log info "${LH} Execute force_reset with timeout: ${TIMEOUT_ARG}" - su_rabbit_cmd "${OCF_RESKEY_ctl} force_reset" - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log warn "${LH} Mnesia couldn't cleaned, even by force-reset command." - make_amnesia=true - fi - fi - fi - else - # there is no beam running - make_amnesia=true - ocf_log warn "${LH} There is no Beam process running." - fi - - # remove mnesia files, if required - if $make_amnesia ; then - kill_rmq_and_remove_pid - ocf_run rm -rf "${MNESIA_FILES}" - ocf_log warn "${LH} Mnesia files appear corrupted and have been removed from ${MNESIA_FILES}." - fi - # always return OCF SUCCESS - return $OCF_SUCCESS -} - - -block_client_access() -{ - # do not add temporary RMQ blocking rule, if it is already exist - # otherwise, try to add a blocking rule with max of 5 retries - local tries=5 - until $(iptables -nvL | grep -q 'temporary RMQ block') || [ $tries -eq 0 ]; do - tries=$((tries-1)) - iptables -I INPUT -p tcp -m tcp --dport ${OCF_RESKEY_node_port} -m state --state NEW,RELATED,ESTABLISHED \ - -m comment --comment 'temporary RMQ block' -j REJECT --reject-with tcp-reset - sleep 1 - done - if [ $tries -eq 0 ]; then - return $OCF_ERR_GENERIC - else - return $OCF_SUCCESS - fi -} - -unblock_client_access() -{ - # remove all temporary RMQ blocking rules, if there are more than one exist - for i in $(iptables -nvL --line-numbers | awk '/temporary RMQ block/ {print $1}'); do - iptables -D INPUT -p tcp -m tcp --dport ${OCF_RESKEY_node_port} -m state --state NEW,RELATED,ESTABLISHED \ - -m comment --comment 'temporary RMQ block' -j REJECT --reject-with tcp-reset - done -} - -get_nodes__base(){ - local infotype='' - local rc=$OCF_ERR_GENERIC - local c_status - - if [ "$1" = 'nodes' ] - then - infotype='db_nodes' - elif [ "$1" = 'running' ] - then - infotype='running_db_nodes' - fi - c_status=`${OCF_RESKEY_ctl} eval "mnesia:system_info(${infotype})." 2>/dev/null` - rc=$? - if [ $rc -ne 0 ] ; then - echo '' - return $OCF_ERR_GENERIC - fi - # translate line like '{running_nodes,['rabbit@node-1','rabbit@node-2','rabbit@node-3']},' to node_list - echo $(echo "${c_status}" | awk -F, '{ for (i=1;i<=NF;i++) { if ($i ~ /@/) { gsub(/[\[\]}{]/,"",$i); print $i; } }}' | tr -d "\'") - return $OCF_SUCCESS -} - -get_nodes() { - echo $(get_nodes__base nodes) - return $? -} - -get_running_nodes() { - echo $(get_nodes__base running) - return $? -} - -# Get all known cluster nodes including offline ones -get_all_pacemaker_nodes() -{ - echo `crm_node -l | awk '{print $2}' | grep -v "^$" | sed -e '/(null)/d'` -} - -# Get alive cluster nodes in visible partition, but the specified one -get_alive_pacemaker_nodes_but() -{ - if [ -z "$1" ]; then - echo `crm_node -l -p | sed -e '/(null)/d'` - else - echo `crm_node -l -p | sed -e "s/${1}//g" | sed -e '/(null)/d'` - fi -} - -# Get current master. If a parameter is provided, -# do not check node with that name -get_master_name_but() -{ - local node - for node in $(get_alive_pacemaker_nodes_but "$@") - do - ocf_log info "${LH} looking if $node is master" - - if is_master $node; then - ocf_log info "${LH} master is $node" - echo $node - break - fi - done -} - -# Returns 0 if we are clustered with provideded node -is_clustered_with() -{ - get_running_nodes | grep -q $(rabbit_node_name $1); - return $? -} - - -check_need_join_to() { - local join_to - local node - local running_nodes - local rc=$OCF_ERR_GENERIC - - rc=0 - join_to=$(rabbit_node_name $1) - running_nodes=$(get_running_nodes) - for node in $running_nodes ; do - if [ "${join_to}" = "${node}" ] ; then - rc=1 - break - fi - done - - return $rc -} - -# Update erlang cookie, if it has been specified -update_cookie() { - local cookie_file_content - if [ "${OCF_RESKEY_erlang_cookie}" != 'false' ] ; then - if [ -f "${OCF_RESKEY_erlang_cookie_file}" ]; then - # First line of cookie file without newline - cookie_file_content=$(head -n1 "${OCF_RESKEY_erlang_cookie_file}" | perl -pe chomp) - fi - # As there is a brief period of time when the file is empty - # (shell redirection has already opened and truncated file, - # and echo hasn't finished its job), we are doing this write - # only when cookie has changed. - if [ "${OCF_RESKEY_erlang_cookie}" != "${cookie_file_content}" ]; then - echo "${OCF_RESKEY_erlang_cookie}" > "${OCF_RESKEY_erlang_cookie_file}" - fi - # And this are idempotent operations, so we don't have to - # check any preconditions for running them. - chown ${OCF_RESKEY_username}:${OCF_RESKEY_groupname} "${OCF_RESKEY_erlang_cookie_file}" - chmod 600 "${OCF_RESKEY_erlang_cookie_file}" - fi - return $OCF_SUCCESS -} - -# Stop rmq beam process by pid and by rabbit node name match. Returns SUCCESS/ERROR -kill_rmq_and_remove_pid() { - local LH="${LL} kill_rmq_and_remove_pid():" - # Stop the rabbitmq-server by its pidfile, use the name matching as a fallback, - # and ignore the exit code - proc_stop "${OCF_RESKEY_pid_file}" "beam.*${RABBITMQ_NODENAME}" "${OCF_RESKEY_stop_time}" - # Ensure the beam.smp stopped by the rabbit node name matching as well - proc_stop none "beam.*${RABBITMQ_NODENAME}" "${OCF_RESKEY_stop_time}" - if [ $? -eq 0 ] ; then - return $OCF_SUCCESS - else - return $OCF_ERR_GENERIC - fi -} - -trim_var(){ - local string="$*" - echo ${string%% } -} - -action_validate() { - # todo(sv): validate some incoming parameters - OCF_RESKEY_CRM_meta_notify_post=$(trim_var $OCF_RESKEY_CRM_meta_notify_post) - OCF_RESKEY_CRM_meta_notify_pre=$(trim_var $OCF_RESKEY_CRM_meta_notify_pre) - OCF_RESKEY_CRM_meta_notify_start=$(trim_var $OCF_RESKEY_CRM_meta_notify_start) - OCF_RESKEY_CRM_meta_notify_stop=$(trim_var $OCF_RESKEY_CRM_meta_notify_stop) - OCF_RESKEY_CRM_meta_notify_start_resource=$(trim_var $OCF_RESKEY_CRM_meta_notify_start_resource) - OCF_RESKEY_CRM_meta_notify_stop_resource=$(trim_var $OCF_RESKEY_CRM_meta_notify_stop_resource) - OCF_RESKEY_CRM_meta_notify_active_resource=$(trim_var $OCF_RESKEY_CRM_meta_notify_active_resource) - OCF_RESKEY_CRM_meta_notify_inactive_resource=$(trim_var $OCF_RESKEY_CRM_meta_notify_inactive_resource) - OCF_RESKEY_CRM_meta_notify_start_uname=$(trim_var $OCF_RESKEY_CRM_meta_notify_start_uname) - OCF_RESKEY_CRM_meta_notify_stop_uname=$(trim_var $OCF_RESKEY_CRM_meta_notify_stop_uname) - OCF_RESKEY_CRM_meta_notify_active_uname=$(trim_var $OCF_RESKEY_CRM_meta_notify_active_uname) - OCF_RESKEY_CRM_meta_notify_master_resource=$(trim_var $OCF_RESKEY_CRM_meta_notify_master_resource) - OCF_RESKEY_CRM_meta_notify_master_uname=$(trim_var $OCF_RESKEY_CRM_meta_notify_master_uname) - OCF_RESKEY_CRM_meta_notify_demote_resource=$(trim_var $OCF_RESKEY_CRM_meta_notify_demote_resource) - OCF_RESKEY_CRM_meta_notify_demote_uname=$(trim_var $OCF_RESKEY_CRM_meta_notify_demote_uname) - OCF_RESKEY_CRM_meta_notify_slave_resource=$(trim_var $OCF_RESKEY_CRM_meta_notify_slave_resource) - OCF_RESKEY_CRM_meta_notify_slave_uname=$(trim_var $OCF_RESKEY_CRM_meta_notify_slave_uname) - OCF_RESKEY_CRM_meta_notify_promote_resource=$(trim_var $OCF_RESKEY_CRM_meta_notify_promote_resource) - OCF_RESKEY_CRM_meta_notify_promote_uname=$(trim_var $OCF_RESKEY_CRM_meta_notify_promote_uname) - return $OCF_SUCCESS -} - -join_to_cluster() { - local node="$1" - local rmq_node - local rc=$OCF_ERR_GENERIC - local LH="${LL} join_to_cluster():" - local nowtime - - ocf_log info "${LH} start." - - rmq_node=$(rabbit_node_name $node) - ocf_log info "${LH} Joining to cluster by node '${rmq_node}'." - get_status rabbit - rc=$? - if [ $rc -eq $OCF_SUCCESS ] ; then - ocf_log info "${LH} rabbitmq app will be stopped." - stop_rmq_server_app - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log err "${LH} Can't stop rabbitmq app by stop_app command. Stopping." - action_stop - return $OCF_ERR_GENERIC - fi - fi - ocf_log info "${LH} Execute join_cluster with timeout: ${TIMEOUT_ARG}" - su_rabbit_cmd "${OCF_RESKEY_ctl} join_cluster $rmq_node" - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log err "${LH} Can't join to cluster by node '${rmq_node}'. Stopping." - action_stop - return $OCF_ERR_GENERIC - fi - sleep 2 - try_to_start_rmq_app - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log err "${LH} Can't start RMQ app after join to cluster. Stopping." - action_stop - return $OCF_ERR_GENERIC - else - nowtime="$(now)" - ocf_log info "${LH} Rabbit app started successfully. Updating start time attribute with ${nowtime}" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --update "${nowtime}" - ocf_log info "${LH} Joined to cluster succesfully." - fi - - ocf_log info "${LH} end." - return $rc -} - -unjoin_nodes_from_cluster() { - # node names of the nodes where the pcs resource is being stopped - local nodelist="$1" - local hostname - local nodename - local rc=$OCF_ERR_GENERIC - local rnode - # nodes in rabbit cluster db - local nodes_in_cluster - local LH="${LL} unjoin_nodes_from_cluster():" - - nodes_in_cluster=$(get_nodes) - rc=$? - if [ $rc -ne 0 ] ; then - # no nodes in node list, nothing to do - return $OCF_SUCCESS - fi - - # unjoin all cluster nodes which are being stopped (i.e. recieved post-stop notify), except *this* node - # before to unjoin the nodes, make sure they were disconnected from *this* node - for hostname in $nodelist ; do - nodename=$(rabbit_node_name $hostname) - if [ "${nodename}" = "${RABBITMQ_NODENAME}" ] ; then - continue - fi - for rnode in $nodes_in_cluster ; do - if [ "${nodename}" = "${rnode}" ] ; then - # disconnect node being unjoined from this node - ocf_run ${OCF_RESKEY_ctl} eval "disconnect_node(list_to_atom(\"${nodename}\"))." 2>&1 - rc=$? - if [ $rc -eq $OCF_SUCCESS ] ; then - ocf_log info "${LH} node '${nodename}' disconnected succesfully." - else - ocf_log info "${LH} disconnecting node '${nodename}' failed." - fi - - # unjoin node - # when the rabbit node went down, its status - # remains 'running' for a while, so few retries are required - local tries=0 - until [ $tries -eq 5 ]; do - tries=$((tries+1)) - if is_clustered_with $nodename; then - ocf_log info "${LH} the ${nodename} is alive and cannot be kicked from the cluster yet" - else - break - fi - sleep 10 - done - ocf_log info "${LH} Execute forget_cluster_node with timeout: ${TIMEOUT_ARG}" - su_rabbit_cmd "${OCF_RESKEY_ctl} forget_cluster_node ${nodename}" - rc=$? - if [ $rc -eq 0 ] ; then - ocf_log info "${LH} node '${nodename}' unjoined succesfully." - else - ocf_log warn "${LH} unjoining node '${nodename}' failed." - fi - fi - done - done - return $OCF_SUCCESS -} - -# Stop RMQ beam server process. Returns SUCCESS/ERROR -stop_server_process() { - local pid - local rc=$OCF_ERR_GENERIC - local LH="${LL} stop_server_process():" - - pid=$(cat ${OCF_RESKEY_pid_file}) - rc=$? - if [ $rc -ne 0 ] ; then - # Try to stop without known PID - ocf_log err "${LH} RMQ-server process PIDFILE was not found!" - su_rabbit_cmd "${OCF_RESKEY_ctl} stop 2>&1 >> \"${OCF_RESKEY_log_dir}/shutdown_log\"" - if [ $? -eq 0 ] ; then - ocf_log info "${LH} RMQ-server process stopped succesfully, although there was no PIDFILE found." - ocf_log info "${LH} grant a graceful termintation window ${OCF_RESKEY_stop_time} to end its beam" - sleep "${OCF_RESKEY_stop_time}" - else - kill_rmq_and_remove_pid - fi - elif [ "${pid}" ] ; then - # Try to stop gracefully by known PID - ocf_log info "${LH} Execute stop with timeout: ${TIMEOUT_ARG}" - su_rabbit_cmd "${OCF_RESKEY_ctl} stop ${OCF_RESKEY_pid_file} 2>&1 >> \"${OCF_RESKEY_log_dir}/shutdown_log\"" - [ $? -eq 0 ] && ocf_log info "${LH} RMQ-server process (PID=${pid}) stopped succesfully." - fi - - # Ensure there is no beam process and pidfile left - pgrep -f "beam.*${RABBITMQ_NODENAME}" > /dev/null - rc=$? - if [ -f ${OCF_RESKEY_pid_file} -o $rc -eq 0 ] ; then - ocf_log warn "${LH} The pidfile or beam's still exist, forcing the RMQ-server cleanup" - kill_rmq_and_remove_pid - fi - - # Return the actual status - get_status - if [ $? -ne 0 ] ; then - return $OCF_SUCCESS - else - return $OCF_ERR_GENERIC - fi -} - -# Stop RMQ-app. Return OCF_SUCCESS, if the app was stopped, -# otherwise return OCF_ERR_GENERIC -stop_rmq_server_app() { - local rc=$OCF_ERR_GENERIC - - # if the beam process isn't running, then rabbit app is stopped as well - get_status - rc=$? - if [ $rc -ne 0 ] ; then - return $OCF_SUCCESS - fi - - # stop the app - ocf_log info "${LH} Execute stop_app with timeout: ${TIMEOUT_ARG}" - su_rabbit_cmd "${OCF_RESKEY_ctl} stop_app 2>&1 >> \"${OCF_RESKEY_log_dir}/shutdown_log\"" - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log err "${LH} RMQ-server app cannot be stopped." - return $OCF_ERR_GENERIC - fi - - get_status rabbit - rc=$? - if [ $rc -ne $OCF_SUCCESS ] ; then - ocf_log info "${LH} RMQ-server app stopped succesfully." - rc=$OCF_SUCCESS - else - ocf_log err "${LH} RMQ-server app cannot be stopped." - rc=$OCF_ERR_GENERIC - fi - - return $rc -} - -start_beam_process() { - local command - local rc=$OCF_ERR_GENERIC - local ts_end - local pf_end - local pid - local LH="${LL} start_beam_process():" - - # remove old PID-file if it exists - if [ -f "${OCF_RESKEY_pid_file}" ] ; then - ocf_log warn "${LH} found old PID-file '${OCF_RESKEY_pid_file}'." - pid=$(cat ${OCF_RESKEY_pid_file}) - if [ "${pid}" -a -d "/proc/${pid}" ] ; then - ocf_run cat /proc/${pid}/cmdline | grep -c 'bin/beam' 2>&1 > /dev/null - rc=$? - if [ $rc -eq $OCF_SUCCESS ] ; then - ocf_log warn "${LH} found beam process with PID=${pid}, killing...'." - ocf_run kill -TERM $pid - else - ocf_log err "${LH} found unknown process with PID=${pid} from '${OCF_RESKEY_pid_file}'." - return $OCF_ERR_GENERIC - fi - fi - ocf_run rm -f $OCF_RESKEY_pid_file - fi - - [ -f /etc/default/rabbitmq-server ] && . /etc/default/rabbitmq-server - - # run beam process - command="${OCF_RESKEY_binary} >> \"${OCF_RESKEY_log_dir}/startup_log\" 2>/dev/null" - RABBITMQ_NODE_ONLY=1 su rabbitmq -s /bin/sh -c "${command}"& - ts_end=$(( $(now) + ${OCF_RESKEY_start_time} )) - rc=$OCF_ERR_GENERIC - while [ $(now) -lt ${ts_end} ]; do - # waiting for normal start of beam - pid=0 - pf_end=$(( $(now) + 3 )) - while [ $(now) -lt ${pf_end} ]; do - # waiting for OCF_RESKEY_pid_file of beam process - if [ -f "${OCF_RESKEY_pid_file}" ] ; then - pid=$(cat ${OCF_RESKEY_pid_file}) - break - fi - sleep 1 - done - if [ "${pid}" != "0" -a -d "/proc/${pid}" ] ; then - rc=$OCF_SUCCESS - break - fi - sleep 2 - done - if [ $rc -ne $OCF_SUCCESS ]; then - if [ "${pid}" = "0" ] ; then - ocf_log warn "${LH} PID-file '${OCF_RESKEY_pid_file}' not found" - fi - ocf_log err "${LH} RMQ-runtime (beam) didn't start succesfully (rc=${rc})." - fi - - return $rc -} - -check_plugins() { - # Check if it's safe to load plugins and if we need to do so. Logic is: - # if (EnabledPlugins > 0) and (ActivePlugins == 0) ; then it's safe to load - # If we have at least one active plugin, then it's not safe to re-load them - # because plugins:setup() would remove existing dependency plugins in plugins_expand_dir. - ${OCF_RESKEY_ctl} eval '{ok, EnabledFile} = application:get_env(rabbit, enabled_plugins_file), EnabledPlugins = rabbit_plugins:read_enabled(EnabledFile), ActivePlugins = rabbit_plugins:active(), if length(EnabledPlugins)>0 -> if length(ActivePlugins)==0 -> erlang:error("need_to_load_plugins"); true -> false end; true -> false end.' - return $? -} - -load_plugins() { - check_plugins - local rc=$? - if [ $rc -eq 0 ] ; then - return 0 - else - ${OCF_RESKEY_ctl} eval 'ToBeLoaded = rabbit_plugins:setup(), ok = app_utils:load_applications(ToBeLoaded), StartupApps = app_utils:app_dependency_order(ToBeLoaded,false), app_utils:start_applications(StartupApps).' - return $? - fi -} - -list_active_plugins() { - local list - list=`${OCF_RESKEY_ctl} eval 'rabbit_plugins:active().'` - echo "${list}" -} - -try_to_start_rmq_app() { - local startup_log="${1:-${OCF_RESKEY_log_dir}/startup_log}" - local rc=$OCF_ERR_GENERIC - local LH="${LL} try_to_start_rmq_app():" - - get_status - rc=$? - if [ $rc -ne $OCF_SUCCESS ] ; then - ocf_log info "${LH} RMQ-runtime (beam) not started, starting..." - start_beam_process - rc=$? - if [ $rc -ne $OCF_SUCCESS ]; then - ocf_log err "${LH} Failed to start beam - returning from the function" - return $OCF_ERR_GENERIC - fi - fi - - - if [ -z "${startup_log}" ] ; then - startup_log="${OCF_RESKEY_log_dir}/startup_log" - fi - - ocf_log info "${LH} begin." - ocf_log info "${LH} Execute start_app with timeout: ${TIMEOUT_ARG}" - su_rabbit_cmd "${OCF_RESKEY_ctl} start_app >>${startup_log} 2>&1" - rc=$? - if [ $rc -eq 0 ] ; then - ocf_log info "${LH} start_app was successful." - ocf_log info "${LH} waiting for start to finish with timeout: ${TIMEOUT_ARG}" - su_rabbit_cmd "${OCF_RESKEY_ctl} wait ${OCF_RESKEY_pid_file}" - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log err "${LH} RMQ-server app failed to wait for start." - return $OCF_ERR_GENERIC - fi - rc=$OCF_SUCCESS - # Loading enabled modules - ocf_log info "${LH} start plugins." - load_plugins - local mrc=$? - if [ $mrc -eq 0 ] ; then - local mlist - mlist=`list_active_plugins` - ocf_log info "${LH} Starting plugins: ${mlist}" - else - ocf_log info "${LH} Starting plugins: failed." - fi - else - ocf_log info "${LH} start_app failed." - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -start_rmq_server_app() { - local rc=$OCF_ERR_GENERIC - local startup_log="${OCF_RESKEY_log_dir}/startup_log" - local startup_output - local LH="${LL} start_rmq_server_app():" - local a - - #We are performing initial start check. - #We are not ready to provide service. - #Clients should not have access. - - - ocf_log info "${LH} begin." - # Safe-unblock the rules, if there are any - unblock_client_access - # Apply the blocking rule - block_client_access - rc=$? - if [ $rc -eq $OCF_SUCCESS ]; then - ocf_log info "${LH} blocked access to RMQ port" - else - ocf_log err "${LH} cannot block access to RMQ port!" - return $OCF_ERR_GENERIC - fi - get_status - rc=$? - if [ $rc -ne $OCF_SUCCESS ] ; then - ocf_log info "${LH} RMQ-runtime (beam) not started, starting..." - start_beam_process - rc=$? - if [ $rc -ne $OCF_SUCCESS ]; then - unblock_client_access - ocf_log info "${LH} unblocked access to RMQ port" - return $OCF_ERR_GENERIC - fi - fi - - ocf_log info "${LH} RMQ-server app not started, starting..." - try_to_start_rmq_app "$startup_log" - rc=$? - if [ $rc -eq $OCF_SUCCESS ] ; then - # rabbitmq-server started successfuly as master of cluster - master_score 1 # minimal positive master-score for this node. - stop_rmq_server_app - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log err "${LH} RMQ-server app can't be stopped. Beam will be killed." - kill_rmq_and_remove_pid - unblock_client_access - ocf_log info "${LH} unblocked access to RMQ port" - return $OCF_ERR_GENERIC - fi - else - # error at start RMQ-server - ocf_log warn "${LH} RMQ-server app can't start without Mnesia cleaning." - for a in $(seq 1 10) ; do - rc=$OCF_ERR_GENERIC - reset_mnesia || break - try_to_start_rmq_app "$startup_log" - rc=$? - if [ $rc -eq $OCF_SUCCESS ]; then - stop_rmq_server_app - rc=$? - if [ $rc -eq $OCF_SUCCESS ]; then - ocf_log info "${LH} RMQ-server app Mnesia cleaned successfully." - rc=$OCF_SUCCESS - master_score 1 - break - else - ocf_log err "${LH} RMQ-server app can't be stopped during Mnesia cleaning. Beam will be killed." - kill_rmq_and_remove_pid - unblock_client_access - ocf_log info "${LH} unblocked access to RMQ port" - return $OCF_ERR_GENERIC - fi - fi - done - fi - if [ $rc -eq $OCF_ERR_GENERIC ] ; then - ocf_log err "${LH} RMQ-server can't be started while many tries. Beam will be killed." - kill_rmq_and_remove_pid - fi - ocf_log info "${LH} end." - unblock_client_access - ocf_log info "${LH} unblocked access to RMQ port" - return $rc -} - -# check status of rabbit beam process or a rabbit app, if rabbit arg specified -# by default, test if the kernel app is running, otherwise consider it is "not running" -get_status() { - local what="${1:-kernel}" - local rc=$OCF_NOT_RUNNING - local LH="${LL} get_status():" - local body - local beam_running - - body=$( ${COMMAND_TIMEOUT} ${OCF_RESKEY_ctl} eval 'rabbit_misc:which_applications().' 2>&1 ) - rc=$? - - pgrep -f "beam.*${RABBITMQ_NODENAME}" > /dev/null - beam_running=$? - # report not running only if the which_applications() reported an error AND the beam is not running - if [ $rc -ne 0 -a $beam_running -ne 0 ] ; then - ocf_log info "${LH} failed with code ${rc}. Command output: ${body}" - return $OCF_NOT_RUNNING - # return a generic error, if there were errors and beam is found running - elif [ $rc -ne 0 ] ; then - ocf_log info "${LH} found the beam process running but failed with code ${rc}. Command output: ${body}" - return $OCF_ERR_GENERIC - fi - - # try to parse the which_applications() output only if it exited w/o errors - if [ "${what}" -a $rc -eq 0 ] ; then - rc=$OCF_NOT_RUNNING - echo "$body" | grep "\{${what}," 2>&1 > /dev/null && rc=$OCF_SUCCESS - - if [ $rc -ne $OCF_SUCCESS ] ; then - ocf_log info "${LH} app ${what} was not found in command output: ${body}" - fi - fi - - [ $rc -ne $OCF_SUCCESS ] && rc=$OCF_NOT_RUNNING - return $rc -} - -action_status() { - local rc=$OCF_ERR_GENERIC - - get_status - rc=$? - return $rc -} - -# return 0, if given node has a master attribute in CIB, -# otherwise, return 1 -is_master() { - local result - result=`crm_attribute -N "${1}" -l reboot --name 'rabbit-master' --query 2>/dev/null |\ - awk '{print $3}' | awk -F "=" '{print $2}' | sed -e '/(null)/d'` - if [ "${result}" != 'true' ] ; then - return 1 - fi - return 0 -} - -# Verify if su_rabbit_cmd exited by timeout by checking its return code. -# If it did not, return 0. If it did AND it is -# $OCF_RESKEY_max_rabbitmqctl_timeouts'th timeout in a row, -# return 2 to signal get_monitor that it should -# exit with error. Otherwise return 1 to signal that there was a timeout, -# but it should be ignored. Timeouts for different operations are tracked -# separately. The second argument is used to distingush them. -check_timeouts() { - local op_rc=$1 - local timeouts_attr_name=$2 - local op_name=$3 - - if [ $op_rc -ne 124 -a $op_rc -ne 137 ]; then - ocf_run attrd_updater -p --name $timeouts_attr_name --update 0 - return 0 - fi - - local count - count=`attrd_updater --name $timeouts_attr_name --query 2>/dev/null` - if [ $? -ne 0 ]; then - # the attrd_updater exited with error. In that case most probably it printed garbage - # instead of the number we need. So defensively assume that it is zero. - - count=0 - fi - count=`echo "${count}" | awk '{print $3}' | awk -F "=" '{print $2}' | sed -e '/(null)/d'` - - count=$((count+1)) - # There is a slight chance that this piece of code will be executed twice simultaneously. - # As a result, $timeouts_attr_name's value will be one less than it should be. But we don't need - # precise calculation here. - ocf_run attrd_updater -p --name $timeouts_attr_name --update $count - - if [ $count -lt $OCF_RESKEY_max_rabbitmqctl_timeouts ]; then - ocf_log warn "${LH} 'rabbitmqctl $op_name' timed out $count of max. $OCF_RESKEY_max_rabbitmqctl_timeouts time(s) in a row. Doing nothing for now." - return 1 - else - ocf_log err "${LH} 'rabbitmqctl $op_name' timed out $count of max. $OCF_RESKEY_max_rabbitmqctl_timeouts time(s) in a row and is not responding. The resource is failed." - return 2 - fi -} - -wait_sync() { - wait_time=$1 - - queues="${COMMAND_TIMEOUT} ${OCF_RESKEY_ctl} list_queues name state" - su_rabbit_cmd -t "${wait_time}" "sh -c \"while ${queues} | grep -q 'syncing,'; \ - do sleep 2; done\"" - return $? -} - -get_monitor() { - local rc=$OCF_ERR_GENERIC - local LH="${LL} get_monitor():" - local status_master=1 - local rabbit_running - local name - local node - local nodelist - local max - local our_uptime - local node_uptime - local node_start_time - - ocf_log info "${LH} CHECK LEVEL IS: ${OCF_CHECK_LEVEL}" - get_status - rc=$? - if [ $rc -eq $OCF_NOT_RUNNING ] ; then - ocf_log info "${LH} get_status() returns ${rc}." - ocf_log info "${LH} ensuring this slave does not get promoted." - master_score 0 - return $OCF_NOT_RUNNING - elif [ $rc -eq $OCF_SUCCESS ] ; then - ocf_log info "${LH} get_status() returns ${rc}." - ocf_log info "${LH} also checking if we are master." - get_status rabbit - rabbit_running=$? - is_master $THIS_PCMK_NODE - status_master=$? - ocf_log info "${LH} master attribute is ${status_master}" - if [ $status_master -eq 0 -a $rabbit_running -eq $OCF_SUCCESS ] - then - ocf_log info "${LH} We are the running master" - rc=$OCF_RUNNING_MASTER - elif [ $status_master -eq 0 -a $rabbit_running -ne $OCF_SUCCESS ] ; then - ocf_log err "${LH} We are the master and RMQ-runtime (beam) is not running. this is a failure" - exit $OCF_FAILED_MASTER - fi - fi - get_status rabbit - rabbit_running=$? - ocf_log info "${LH} checking if rabbit app is running" - - if [ $rabbit_running -eq $OCF_SUCCESS ] - then - ocf_log info "${LH} rabbit app is running. checking if we are the part of healthy cluster" - - if [ $rc -eq $OCF_RUNNING_MASTER ] ; then - # The master is always running inside of its cluster - ocf_log info "${LH} rabbit app is running and is master of cluster" - - else - local master_name=$(get_master_name_but $THIS_PCMK_NODE) - - if [ -z "$master_name" ]; then - ocf_log info "${LH} no master is elected currently. Skipping cluster health check." - - elif is_clustered_with $master_name; then - ocf_log info "${LH} rabbit app is running and is member of healthy cluster" - - else - # Rabbit is running but is not connected to master - # Failing to avoid split brain - ocf_log err "${LH} rabbit node is running out of the cluster" - stop_server_process - rc=$OCF_ERR_GENERIC - fi - fi - else - if [ "$OCF_CHECK_LEVEL" -gt 20 ]; then - ocf_log info "${LH} rabbit app is not running. checking if there is a master" - # Do not refetch the master status as we know it already - if [ $rc -eq $OCF_RUNNING_MASTER ]; then - ocf_log err "${LH} we are the master and rabbit app is not running. this is a failure" - exit $OCF_FAILED_MASTER - fi - - local master_name=$(get_master_name_but $THIS_PCMK_NODE) - - if [ -n "$master_name" ]; then - ocf_log info "${LH} master exists and rabbit app is not running. Exiting to be restarted by pacemaker" - stop_server_process - rc=$OCF_ERR_GENERIC - fi - fi - fi - - if [ $rc -eq $OCF_ERR_GENERIC ]; then - ocf_log err "${LH} get_status() returns generic error ${rc}" - ocf_log info "${LH} ensuring this slave does not get promoted." - master_score 0 - return $OCF_ERR_GENERIC - elif [ $rc -ne $OCF_RUNNING_MASTER ] ; then - ocf_log info "${LH} preparing to update master score for node" - our_uptime=$(srv_uptime) - nodelist=$(get_alive_pacemaker_nodes_but $THIS_PCMK_NODE) - max=1 - for node in $nodelist - do - node_start_time=`crm_attribute -N $node -l reboot --name 'rabbit-start-time' --query 2>/dev/null | awk '{print $3}' | awk -F "=" '{print $2}' | sed -e '/(null)/d'` - if [ -z "${node_start_time}" -o "${node_start_time}" = "(null)" ] ; then - node_uptime=0 - else - node_uptime=$(( $(now) - ${node_start_time} )) - fi - ocf_log info "${LH} comparing our uptime (${our_uptime}) with $node (${node_uptime})" - if [ ${our_uptime} -lt ${node_uptime} ] - then - max=1 - break - else - # When uptime is equal, accept the existing master - if any - as the oldest node - is_master $node - status_master=$? - if [ $status_master -eq 0 ] ; then - max=1 - ocf_log info "${LH} Found the oldest master node $node with uptime (${node_uptime})" - break - else - max=0 - fi - fi - done - - - if [ $max -eq 0 ] - then - ocf_log info "${LH} we are the oldest node" - master_score 1000 - fi - fi - - # Skip all other checks if rabbit app is not running - if [ $rabbit_running -ne $OCF_SUCCESS ]; then - ocf_log info "${LH} RabbitMQ is not running, get_monitor function ready to return ${rc}" - return $rc - fi - - # Check if the rabbitmqctl control plane is alive. - local rc_alive - local timeout_alive - su_rabbit_cmd "${OCF_RESKEY_ctl} list_channels 2>&1 > /dev/null" - rc_alive=$? - [ $rc_alive -eq 137 -o $rc_alive -eq 124 ] && ocf_log err "${LH} 'rabbitmqctl list_channels' timed out, per-node explanation: $(enhanced_list_channels)" - check_timeouts $rc_alive "rabbit_list_channels_timeouts" "list_channels" - timeout_alive=$? - - if [ $timeout_alive -eq 2 ]; then - master_score 0 - return $OCF_ERR_GENERIC - elif [ $timeout_alive -eq 0 ]; then - if [ $rc_alive -ne 0 ]; then - ocf_log err "${LH} rabbitmqctl list_channels exited with errors." - rc=$OCF_ERR_GENERIC - fi - fi - - # Check for memory alarms for this Master or Slave node. - # If alert found, reset the alarm - # and restart the resource as it likely means a dead end situation - # when rabbitmq cluster is running with blocked publishing due - # to high memory watermark exceeded. - local alarms - local rc_alarms - local timeout_alarms - alarms=`su_rabbit_cmd "${OCF_RESKEY_ctl} -q eval 'rabbit_alarm:get_alarms().'"` - rc_alarms=$? - check_timeouts $rc_alarms "rabbit_get_alarms_timeouts" "get_alarms" - timeout_alarms=$? - - if [ $timeout_alarms -eq 2 ]; then - master_score 0 - return $OCF_ERR_GENERIC - - elif [ $timeout_alarms -eq 0 ]; then - if [ $rc_alarms -ne 0 ]; then - ocf_log err "${LH} rabbitmqctl get_alarms exited with errors." - rc=$OCF_ERR_GENERIC - - elif [ -n "${alarms}" ]; then - for node in "${alarms}"; do - name=`echo ${node} | perl -n -e "m/memory,'(?<n>\S+)+'/ && print \"$+{n}\n\""` - if [ "${name}" = "${RABBITMQ_NODENAME}" ] ; then - ocf_log err "${LH} Found raised memory alarm. Erasing the alarm and restarting." - su_rabbit_cmd "${OCF_RESKEY_ctl} set_vm_memory_high_watermark 10 2>&1 > /dev/null" - rc=$OCF_ERR_GENERIC - break - fi - done - fi - fi - - if ! is_cluster_status_ok ; then - rc=$OCF_ERR_GENERIC - fi - - # Check if the list of all queues is available, - # Also report some queues stats and total virtual memory. - local queues - local rc_queues - local timeout_queues - queues=`su_rabbit_cmd "${OCF_RESKEY_ctl} -q list_queues memory messages consumer_utilisation"` - rc_queues=$? - check_timeouts $rc_queues "rabbit_list_queues_timeouts" "list_queues" - timeout_queues=$? - - if [ $timeout_queues -eq 2 ]; then - master_score 0 - return $OCF_ERR_GENERIC - - elif [ $timeout_queues -eq 0 ]; then - if [ $rc_queues -ne 0 ]; then - ocf_log err "${LH} rabbitmqctl list_queues exited with errors." - rc=$OCF_ERR_GENERIC - - elif [ -n "${queues}" ]; then - local q_c - q_c=`printf "%b\n" "${queues}" | wc -l` - local mem - mem=`printf "%b\n" "${queues}" | awk -v sum=0 '{sum+=$1} END {print (sum/1048576)}'` - local mes - mes=`printf "%b\n" "${queues}" | awk -v sum=0 '{sum+=$2} END {print sum}'` - local c_u - c_u=`printf "%b\n" "${queues}" | awk -v sum=0 -v cnt=${q_c} '{sum+=$3} END {print (sum+1)/(cnt+1)}'` - local status - status=`echo $(su_rabbit_cmd "${OCF_RESKEY_ctl} -q status")` - ocf_log info "${LH} RabbitMQ is running ${q_c} queues consuming ${mem}m of ${TOTALVMEM}m total, with ${mes} queued messages, average consumer utilization ${c_u}" - ocf_log info "${LH} RabbitMQ status: ${status}" - fi - fi - - ocf_log info "${LH} get_monitor function ready to return ${rc}" - return $rc -} - -ocf_update_private_attr() { - local attr_name="${1:?}" - local attr_value="${2:?}" - ocf_run attrd_updater -p --name "$attr_name" --update "$attr_value" -} - -rabbitmqctl_with_timeout_check() { - local command="${1:?}" - local timeout_attr_name="${2:?}" - - su_rabbit_cmd "${OCF_RESKEY_ctl} $command" - local rc=$? - - check_timeouts $rc $timeout_attr_name "$command" - local has_timed_out=$? - - case "$has_timed_out" in - 0) - return $rc;; - 1) - return 0;; - 2) - return 1;; - esac -} - -is_cluster_status_ok() { - local LH="${LH}: is_cluster_status_ok:" - rabbitmqctl_with_timeout_check cluster_status rabbit_cluster_status_timeouts > /dev/null 2>&1 -} - -action_monitor() { - local rc=$OCF_ERR_GENERIC - local LH="${LL} monitor:" - ocf_log debug "${LH} action start." - if [ "${OCF_RESKEY_debug}" = 'true' ] ; then - d=`date '+%Y%m%d %H:%M:%S'` - echo $d >> /tmp/rmq-monitor.log - env >> /tmp/rmq-monitor.log - echo "$d [monitor] start='${OCF_RESKEY_CRM_meta_notify_start_uname}' stop='${OCF_RESKEY_CRM_meta_notify_stop_uname}' active='${OCF_RESKEY_CRM_meta_notify_active_uname}' inactive='${OCF_RESKEY_CRM_meta_notify_inactive_uname}'" >> /tmp/rmq-ocf.log - fi - get_monitor - rc=$? - ocf_log debug "${LH} role: ${OCF_RESKEY_CRM_meta_role}" - ocf_log debug "${LH} result: $rc" - ocf_log debug "${LH} action end." - return $rc -} - - -action_start() { - local rc=$OCF_ERR_GENERIC - local LH="${LL} start:" - - if [ "${OCF_RESKEY_debug}" = 'true' ] ; then - d=`date '+%Y%m%d %H:%M:%S'` - echo $d >> /tmp/rmq-start.log - env >> /tmp/rmq-start.log - echo "$d [start] start='${OCF_RESKEY_CRM_meta_notify_start_uname}' stop='${OCF_RESKEY_CRM_meta_notify_stop_uname}' active='${OCF_RESKEY_CRM_meta_notify_active_uname}' inactive='${OCF_RESKEY_CRM_meta_notify_inactive_uname}'" >> /tmp/rmq-ocf.log - fi - - ocf_log info "${LH} action begin." - - get_status - rc=$? - if [ $rc -eq $OCF_SUCCESS ] ; then - ocf_log warn "${LH} RMQ-runtime (beam) already started." - return $OCF_SUCCESS - fi - - local attrs_to_zero="rabbit_list_channels_timeouts rabbit_get_alarms_timeouts rabbit_list_queues_timeouts rabbit_cluster_status_timeouts" - local attr_name_to_reset - for attr_name_to_reset in $attrs_to_zero; do - ocf_update_private_attr $attr_name_to_reset 0 - done - - ocf_log info "${LH} Deleting start time attribute" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --delete - ocf_log info "${LH} Deleting master attribute" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-master' --delete - - ocf_log info "${LH} RMQ going to start." - start_rmq_server_app - rc=$? - if [ $rc -eq $OCF_SUCCESS ] ; then - ocf_log info "${LH} RMQ prepared for start succesfully." - fi - - ocf_log info "${LH} action end." - return $rc -} - - -action_stop() { - local rc=$OCF_ERR_GENERIC - local LH="${LL} stop:" - - if [ "${OCF_RESKEY_debug}" = 'true' ] ; then - d=$(date '+%Y%m%d %H:%M:%S') - echo $d >> /tmp/rmq-stop.log - env >> /tmp/rmq-stop.log - echo "$d [stop] start='${OCF_RESKEY_CRM_meta_notify_start_uname}' stop='${OCF_RESKEY_CRM_meta_notify_stop_uname}' active='${OCF_RESKEY_CRM_meta_notify_active_uname}' inactive='${OCF_RESKEY_CRM_meta_notify_inactive_uname}'" >> /tmp/rmq-ocf.log - fi - - ocf_log info "${LH} action begin." - - ocf_log info "${LH} Deleting master attribute" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-master' --delete - master_score 0 - ocf_log info "${LH} Deleting start time attribute" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --delete - - # Wait for synced state first - ocf_log info "${LH} waiting $((OCF_RESKEY_stop_time/2)) to sync" - wait_sync $((OCF_RESKEY_stop_time/2)) - - ocf_log info "${LH} RMQ-runtime (beam) going to down." - stop_server_process - # Fail early without additional rabbitmqctl invocations - if [ $? -ne $OCF_SUCCESS ] ; then - ocf_log err "RMQ-runtime (beam) couldn't be stopped and will likely became unmanaged. Take care of it manually!" - ocf_log info "${LH} action end." - exit $OCF_ERR_GENERIC - fi - - # Ensure the actual status to be returned - get_status - if [ $? -eq $OCF_NOT_RUNNING ] ; then - ocf_log info "${LH} RMQ-runtime (beam) not running." - ocf_log info "${LH} action end." - return $OCF_SUCCESS - else - ocf_log err "RMQ-runtime (beam) couldn't be stopped and will likely became unmanaged. Take care of it manually!" - ocf_log info "${LH} action end." - exit $OCF_ERR_GENERIC - fi - -} - -####################################################################### -# Enhanced list_channels: -# - nodes are processed in parallel -# - report contains information about which nodes timed out -# -# 'list_channels' is used as a healh-check for current node, but it -# actually checks overall health of all node in cluster. And there were -# some bugs where only one (non-local) channel became stuck, but OCF -# script was wrongfully killing local node. -# -# Hopefully all such bugs are fixed, but if not - it will allow to -# detect such conditions. -# -# Somewhat strange implementation is due to the following reasons: -# - ability to support older versions of RabbitMQ which have reached -# end-of-life with single version of the script -# - zero dependencies - for older versions this functionality could be -# implemented as a plugin, but it'll require this plugin installation -enhanced_list_channels() { - # One second less than timeout of su_rabbit_cmd - local timeout=$((${TIMEOUT_ARG:-5} - 1)) - - su_rabbit_cmd "xargs -0 ${OCF_RESKEY_ctl} eval" <<EOF -SecondsToCompletion = $timeout, - -%% Milliseconds since unix epoch -Now = fun() -> - {Mega, Secs, Micro} = os:timestamp(), - Mili = Micro div 1000, - Mili + 1000 * (Secs + 1000000 * Mega) - end, - -%% We shouldn't continue execution past this time -ShouldEndAt = Now() + SecondsToCompletion * 1000, - -%% How many milliseconds we still have -Timeout = fun() -> - case ShouldEndAt - Now() of - Past when Past =< 0 -> - 0; - Timeout -> - Timeout - end - end, - -%% Lambda combinator - for defining anonymous recursive functions -Y = fun(F) -> - (fun (X) -> F(fun(Y) -> (X(X))(Y) end) end)( - fun (X) -> F(fun(Y) -> (X(X))(Y) end) end) - end, - -Parent = self(), - -ListChannels = Y(fun(Rec) -> - fun (({Node, [], OkChannelsCount})) -> - Parent ! {Node, ok, OkChannelsCount}; - ({Node, [Chan|Rest], OkChannelsCount}) -> - case catch rpc:call(Node, rabbit_channel, info, [Chan], Timeout()) of - Infos when is_list(Infos) -> - Rec({Node, Rest, OkChannelsCount + 1}); - {badrpc, {'EXIT', {noproc, _}}} -> - %% Channel became dead before we could request it's status, don't care - Rec({Node, Rest, OkChannelsCount}); - Err -> - Parent ! {Node, Err, OkChannelsCount} - end - end - end), - -SingleNodeListing = fun(Node) -> - case catch rpc:call(Node, pg_local, get_members, [rabbit_channels], Timeout()) of - LocalChannels when is_list(LocalChannels) -> - ListChannels({Node, LocalChannels, 0}); - Err -> - Parent ! {Node, Err, 0} - end - end, - -AllNodes = rabbit_mnesia:cluster_nodes(running), -[ spawn(fun() -> SingleNodeListing(Node) end) || Node <- AllNodes ], - -WaitForNodes = Y(fun(Rec) -> - fun ({[], Acc}) -> - Acc; - ({RemainingNodes, Acc}) -> - receive - {Node, _Status, _ChannelCount} = Smth -> - RemainingNodes1 = lists:delete(Node, RemainingNodes), - Rec({RemainingNodes1, [Smth|Acc]}) - after Timeout() + 100 -> - Acc - end - end - end), - -Result = WaitForNodes({AllNodes, []}), - -ExpandedResult = [ case lists:keysearch(Node, 1, Result) of - {value, NodeResult} -> - NodeResult; - false -> - {Node, no_data_collected, 0} - end || Node <- AllNodes ], - -ExpandedResult. -EOF -} - -####################################################################### -# Join the cluster and return OCF_SUCCESS, if joined. -# Return 10, if node is trying to join to itself or empty destination. -# Return OCF_ERR_GENERIC, if cannot join. -jjj_join () { - local join_to="$1" - local rc=$OCF_ERR_GENERIC - local LH="${LL} jjj_join:" - - my_host ${join_to} - rc=$? - ocf_log debug "${LH} node='${join_to}' rc='${rc}'" - - # Check whether we are joining to ourselves - # or master host is not given - if [ $rc -ne 0 -a "${join_to}" ] ; then - ocf_log info "${LH} Joining to cluster by node '${join_to}'" - join_to_cluster "${join_to}" - rc=$? - if [ $rc -ne $OCF_SUCCESS ] ; then - ocf_log err "${LH} Failed to join the cluster. The mnesia will be reset." - reset_mnesia - rc=$OCF_ERR_GENERIC - fi - fi - return $rc -} - -action_notify() { - local rc_join=$OCF_SUCCESS - local rc=$OCF_ERR_GENERIC - local rc2=$OCF_ERR_GENERIC - local LH="${LL} notify:" - local nodelist - local nowtime - - if [ "${OCF_RESKEY_debug}" = 'true' ] ; then - d=`date '+%Y%m%d %H:%M:%S'` - echo $d >> /tmp/rmq-notify.log - env >> /tmp/rmq-notify.log - echo "$d [notify] ${OCF_RESKEY_CRM_meta_notify_type}-${OCF_RESKEY_CRM_meta_notify_operation} promote='${OCF_RESKEY_CRM_meta_notify_promote_uname}' demote='${OCF_RESKEY_CRM_meta_notify_demote_uname}' master='${OCF_RESKEY_CRM_meta_notify_master_uname}' slave='${OCF_RESKEY_CRM_meta_notify_slave_uname}' start='${OCF_RESKEY_CRM_meta_notify_start_uname}' stop='${OCF_RESKEY_CRM_meta_notify_stop_uname}' active='${OCF_RESKEY_CRM_meta_notify_active_uname}' inactive='${OCF_RESKEY_CRM_meta_notify_inactive_uname}'" >> /tmp/rmq-ocf.log - fi - - if [ "${OCF_RESKEY_CRM_meta_notify_type}" = 'pre' ] ; then - # PRE- anything notify section - case "$OCF_RESKEY_CRM_meta_notify_operation" in - promote) - ocf_log info "${LH} pre-promote begin." - my_host "$OCF_RESKEY_CRM_meta_notify_promote_uname" - rc=$? - if [ $rc -eq $OCF_SUCCESS ] ; then - nodelist=$(get_all_pacemaker_nodes) - for i in $nodelist - do - ocf_log info "${LH} Deleting master attribute for node ${i}" - ocf_run crm_attribute -N $i -l reboot --name 'rabbit-master' --delete - done - ocf_log info "${LH} pre-promote end." - fi - ;; - *) - ;; - esac - fi - - if [ "${OCF_RESKEY_CRM_meta_notify_type}" = 'post' ] ; then - # POST- anything notify section - case "$OCF_RESKEY_CRM_meta_notify_operation" in - promote) - ocf_log info "${LH} post-promote begin." - - rc=$OCF_SUCCESS - - # Do nothing, if the list of nodes being promoted reported empty. - # Delegate recovery, if needed, to the "running out of the cluster" monitor's logic - if [ -z "${OCF_RESKEY_CRM_meta_notify_promote_uname}" ] ; then - ocf_log warn "${LH} there are no nodes to join to reported on post-promote. Nothing to do." - - elif my_host "${OCF_RESKEY_CRM_meta_notify_promote_uname}"; then - ocf_log info "${LH} ignoring post-promote of self" - - elif is_clustered_with "${OCF_RESKEY_CRM_meta_notify_promote_uname}"; then - ocf_log info "${LH} we are already clustered with master - ${OCF_RESKEY_CRM_meta_notify_promote_uname}. Nothing to do." - - else - # Note, this should fail when the mnesia is inconsistent. - # For example, when the "old" master processing the promition of the new one. - # Later this ex-master node will rejoin the cluster at post-start. - jjj_join "${OCF_RESKEY_CRM_meta_notify_promote_uname}" - rc=$? - if [ $rc -eq $OCF_ERR_GENERIC ] ; then - ocf_log err "${LH} Failed to join the cluster on post-promote. The resource will be restarted." - fi - fi - - ocf_log info "${LH} post-promote end." - return $rc - ;; - start) - ocf_log info "${LH} post-start begin." - local nodes_list="${OCF_RESKEY_CRM_meta_notify_start_uname} ${OCF_RESKEY_CRM_meta_notify_active_uname}" - # Do nothing, if the list of nodes being started or running reported empty - # Delegate recovery, if needed, to the "running out of the cluster" monitor's logic - if [ -z "${nodes_list}" ] ; then - ocf_log warn "${LH} I'm a last man standing and I must survive!" - ocf_log info "${LH} post-start end." - return $OCF_SUCCESS - fi - # check did this event from this host - my_host "${nodes_list}" - rc=$? - # Do nothing, if there is no master reported - # Delegate recovery, if needed, to the "running out of the cluster" monitor's logic - if [ -z "${OCF_RESKEY_CRM_meta_notify_master_uname}" ] ; then - ocf_log warn "${LH} there are no nodes to join to reported on post-start. Nothing to do." - ocf_log info "${LH} post-start end." - return $OCF_SUCCESS - fi - if [ $rc -eq $OCF_SUCCESS ] ; then - # Now we need to: - # a. join to the cluster if we are not joined yet - # b. start the RabbitMQ application, which is always - # stopped after start action finishes - check_need_join_to ${OCF_RESKEY_CRM_meta_notify_master_uname} - rc_join=$? - if [ $rc_join -eq $OCF_SUCCESS ]; then - ocf_log warn "${LH} Going to join node ${OCF_RESKEY_CRM_meta_notify_master_uname}" - jjj_join "${OCF_RESKEY_CRM_meta_notify_master_uname}" - rc2=$? - else - ocf_log warn "${LH} We are already clustered with node ${OCF_RESKEY_CRM_meta_notify_master_uname}" - if try_to_start_rmq_app; then - rc2=$OCF_SUCCESS - nowtime="$(now)" - ocf_log info "${LH} Updating start time attribute with ${nowtime}" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --update "${nowtime}" - else - rc2=$OCF_ERR_GENERIC - fi - fi - ocf_log info "${LH} post-start end." - if [ -s "${OCF_RESKEY_definitions_dump_file}" ] ; then - ocf_log info "File ${OCF_RESKEY_definitions_dump_file} exists" - ocf_run curl --silent --show-error --request POST --user $OCF_RESKEY_admin_user:$OCF_RESKEY_admin_password $OCF_RESKEY_host_ip:15672/api/definitions --header "Content-Type:application/json" --data @$OCF_RESKEY_definitions_dump_file - rc=$? - if [ $rc -eq $OCF_SUCCESS ] ; then - ocf_log info "RMQ definitions have imported succesfully." - else - ocf_log err "RMQ definitions have not imported." - fi - fi - if [ $rc2 -eq $OCF_ERR_GENERIC ] ; then - ocf_log warn "${LH} Failed to join the cluster on post-start. The resource will be restarted." - ocf_log info "${LH} post-start end." - return $OCF_ERR_GENERIC - fi - fi - ;; - stop) - # if rabbitmq-server stops on any another node, we should remove it from cluster (as ordinary operation) - ocf_log info "${LH} post-stop begin." - # Report not running, if there are no nodes being stopped reported - if [ -z "${OCF_RESKEY_CRM_meta_notify_stop_uname}" ] ; then - ocf_log warn "${LH} there are no nodes being stopped reported on post-stop. The resource will be restarted." - ocf_log info "${LH} post-stop end." - return $OCF_ERR_GENERIC - fi - my_host "${OCF_RESKEY_CRM_meta_notify_stop_uname}" - rc=$? - if [ $rc -ne $OCF_SUCCESS ] ; then - # Wait for synced state first - ocf_log info "${LH} waiting $((OCF_RESKEY_stop_time/2)) to sync" - wait_sync $((OCF_RESKEY_stop_time/2)) - # On other nodes processing the post-stop, make sure the stopped node will be forgotten - unjoin_nodes_from_cluster "${OCF_RESKEY_CRM_meta_notify_stop_uname}" - else - # On the nodes being stopped, reset the master score - ocf_log info "${LH} resetting the master score." - master_score 0 - fi - # always returns OCF_SUCCESS - ocf_log info "${LH} post-stop end." - ;; - demote) - # if rabbitmq-server stops on any another node, we should remove it from cluster (as ordinary operation) - ocf_log info "${LH} post-demote begin." - # Report not running, if the list of nodes being demoted reported empty - if [ -z "${OCF_RESKEY_CRM_meta_notify_demote_uname}" ] ; then - ocf_log warn "${LH} there are no nodes being demoted reported on post-demote. The resource will be restarted." - ocf_log info "${LH} post-demote end." - return $OCF_ERR_GENERIC - fi - my_host "${OCF_RESKEY_CRM_meta_notify_demote_uname}" - rc=$? - if [ $rc -ne $OCF_SUCCESS ] ; then - # On ohter nodes processing the post-demote, make sure the demoted node will be forgotten - unjoin_nodes_from_cluster "${OCF_RESKEY_CRM_meta_notify_demote_uname}" - else - # Wait for synced state first - ocf_log info "${LH} waiting $((OCF_RESKEY_stop_time/2)) to sync" - wait_sync $((OCF_RESKEY_stop_time/2)) - # On the nodes being demoted, reset the master score - ocf_log info "${LH} resetting the master score." - master_score 0 - ocf_log info "${LH} Deleting start time attribute" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --delete - ocf_log info "${LH} Deleting master attribute" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-master' --delete - ocf_log info "${LH} master was demoted. stopping RabbitMQ app." - stop_rmq_server_app - rc2=$? - if [ $rc2 -ne $OCF_SUCCESS ] ; then - ocf_log err "${LH} RMQ-server app can't be stopped on post-demote. Master resource is failed" - ocf_log info "${LH} post-demote end." - exit $OCF_FAILED_MASTER - fi - fi - ocf_log info "${LH} post-demote end." - ;; - *) ;; - esac - fi - - return $OCF_SUCCESS -} - - -action_promote() { - local rc=$OCF_ERR_GENERIC - local LH="${LL} promote:" - local nowtime - - if [ "${OCF_RESKEY_debug}" = 'true' ] ; then - d=$(date '+%Y%m%d %H:%M:%S') - echo $d >> /tmp/rmq-promote.log - env >> /tmp/rmq-promote.log - echo "$d [promote] start='${OCF_RESKEY_CRM_meta_notify_start_uname}' stop='${OCF_RESKEY_CRM_meta_notify_stop_uname}' active='${OCF_RESKEY_CRM_meta_notify_active_uname}' inactive='${OCF_RESKEY_CRM_meta_notify_inactive_uname}'" >> /tmp/rmq-ocf.log - fi - - ocf_log info "${LH} action begin." - - get_monitor - rc=$? - ocf_log info "${LH} get_monitor returns ${rc}" - case "$rc" in - "$OCF_SUCCESS") - # Running as slave. Normal, expected behavior. - ocf_log info "${LH} Resource is currently running as Slave" - # rabbitmqctl start_app if need - get_status rabbit - rc=$? - ocf_log info "${LH} Updating cluster master attribute" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-master' --update 'true' - if [ $rc -ne $OCF_SUCCESS ] ; then - ocf_log info "${LH} RMQ app is not started. Starting..." - start_rmq_server_app - rc=$? - if [ $rc -eq 0 ] ; then - try_to_start_rmq_app - rc=$? - if [ $rc -ne 0 ] ; then - ocf_log err "${LH} Can't start RMQ app. Master resource is failed." - ocf_log info "${LH} action end." - exit $OCF_FAILED_MASTER - fi - - [ -f "${OCF_RESKEY_policy_file}" ] && . "${OCF_RESKEY_policy_file}" - - # create timestamp file - nowtime="$(now)" - ocf_log info "${LH} Updating start timestamp with ${nowtime}" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --update "${nowtime}" - ocf_log info "${LH} Checking master status" - get_monitor - rc=$? - ocf_log info "${LH} Master status is $rc" - if [ $rc = $OCF_RUNNING_MASTER ] - then - rc=$OCF_SUCCESS - else - ocf_log err "${LH} Master resource is failed." - ocf_log info "${LH} action end." - exit $OCF_FAILED_MASTER - fi - else - ocf_log err "${LH} Can't start RMQ-runtime." - rc=$OCF_ERR_GENERIC - fi - fi - return $rc - ;; - "$OCF_RUNNING_MASTER") - # Already a master. Unexpected, but not a problem. - ocf_log warn "${LH} Resource is already running as Master" - rc=$OCF_SUCCESS - ;; - - "$OCF_FAILED_MASTER") - # Master failed. - ocf_log err "${LH} Master resource is failed and not running" - ocf_log info "${LH} action end." - exit $OCF_FAILED_MASTER - ;; - - "$OCF_NOT_RUNNING") - # Currently not running. - ocf_log err "${LH} Resource is currently not running" - rc=$OCF_NOT_RUNNING - ;; - *) - # Failed resource. Let the cluster manager recover. - ocf_log err "${LH} Unexpected error, cannot promote" - ocf_log info "${LH} action end." - exit $rc - ;; - esac - - # transform slave RMQ-server to master - - ocf_log info "${LH} action end." - return $rc -} - - -action_demote() { - local rc=$OCF_ERR_GENERIC - local LH="${LL} demote:" - - if [ "${OCF_RESKEY_debug}" = 'true' ] ; then - d=`date '+%Y%m%d %H:%M:%S'` - echo $d >> /tmp/rmq-demote.log - env >> /tmp/rmq-demote.log - echo "$d [demote] start='${OCF_RESKEY_CRM_meta_notify_start_uname}' stop='${OCF_RESKEY_CRM_meta_notify_stop_uname}' active='${OCF_RESKEY_CRM_meta_notify_active_uname}' inactive='${OCF_RESKEY_CRM_meta_notify_inactive_uname}'" >> /tmp/rmq-ocf.log - - fi - - ocf_log info "${LH} action begin." - - get_monitor - rc=$? - case "$rc" in - "$OCF_RUNNING_MASTER") - # Running as master. Normal, expected behavior. - ocf_log warn "${LH} Resource is currently running as Master" - ocf_log info "${LH} Deleting master attribute" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-master' --delete - ocf_log info "${LH} Deleting start timestamp" - ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --delete - - # Wait for synced state first - ocf_log info "${LH} waiting $((OCF_RESKEY_stop_time/2)) to sync" - wait_sync $((OCF_RESKEY_stop_time/2)) - - stop_rmq_server_app - rc=$? - ;; - "$OCF_SUCCESS") - # Alread running as slave. Nothing to do. - ocf_log warn "${LH} Resource is currently running as Slave" - rc=$OCF_SUCCESS - ;; - "$OCF_FAILED_MASTER") - # Master failed and being demoted. - ocf_log err "${LH} Demoting of a failed Master." - ocf_log info "${LH} action end." - exit $OCF_FAILED_MASTER - ;; - "$OCF_NOT_RUNNING") - ocf_log warn "${LH} Try to demote currently not running resource. Nothing to do." - rc=$OCF_SUCCESS - ;; - "$OCF_ERR_GENERIC") - ocf_log err "${LH} Error while demote. Stopping resource." - action_stop - rc=$? - ;; - *) - # Failed resource. Let the cluster manager recover. - ocf_log err "${LH} Unexpected error, cannot demote" - ocf_log info "${LH} action end." - exit $rc - ;; - esac - - # transform master RMQ-server to slave - ocf_log info "${LH} action end." - return $rc -} -####################################################################### - -rmq_setup_env - -case "$1" in - meta-data) meta_data - exit $OCF_SUCCESS;; - usage|help) usage - exit $OCF_SUCCESS;; -esac - -# Anything except meta-data and help must pass validation -action_validate || exit $? - -# What kind of method was invoked? -case "$1" in - start) action_start;; - stop) action_stop;; - status) action_status;; - monitor) action_monitor;; - validate) action_validate;; - promote) action_promote;; - demote) action_demote;; - notify) action_notify;; - validate-all) action_validate;; - *) usage;; -esac -### diff --git a/scripts/rabbitmq-server.ocf b/scripts/rabbitmq-server.ocf deleted file mode 100755 index 804e65423d..0000000000 --- a/scripts/rabbitmq-server.ocf +++ /dev/null @@ -1,371 +0,0 @@ -#!/bin/sh -## The contents of this file are subject to the Mozilla Public License -## Version 1.1 (the "License"); you may not use this file except in -## compliance with the License. You may obtain a copy of the License -## at http://www.mozilla.org/MPL/ -## -## Software distributed under the License is distributed on an "AS IS" -## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -## the License for the specific language governing rights and -## limitations under the License. -## -## The Original Code is RabbitMQ. -## -## The Initial Developer of the Original Code is GoPivotal, Inc. -## Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. -## - -## -## OCF Resource Agent compliant rabbitmq-server resource script. -## - -## OCF instance parameters -## OCF_RESKEY_server -## OCF_RESKEY_ctl -## OCF_RESKEY_nodename -## OCF_RESKEY_ip -## OCF_RESKEY_port -## OCF_RESKEY_config_file -## OCF_RESKEY_log_base -## OCF_RESKEY_mnesia_base -## OCF_RESKEY_server_start_args -## OCF_RESKEY_pid_file - -####################################################################### -# Initialization: - -: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat} -. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs - -####################################################################### - -OCF_RESKEY_server_default="/usr/sbin/rabbitmq-server" -OCF_RESKEY_ctl_default="/usr/sbin/rabbitmqctl" -OCF_RESKEY_nodename_default="rabbit@localhost" -OCF_RESKEY_log_base_default="/var/log/rabbitmq" -OCF_RESKEY_pid_file_default="/var/run/rabbitmq/pid" -: ${OCF_RESKEY_server=${OCF_RESKEY_server_default}} -: ${OCF_RESKEY_ctl=${OCF_RESKEY_ctl_default}} -: ${OCF_RESKEY_nodename=${OCF_RESKEY_nodename_default}} -: ${OCF_RESKEY_log_base=${OCF_RESKEY_log_base_default}} -: ${OCF_RESKEY_pid_file=${OCF_RESKEY_pid_file_default}} - -meta_data() { - cat <<END -<?xml version="1.0"?> -<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> -<resource-agent name="rabbitmq-server"> -<version>1.0</version> - -<longdesc lang="en"> -Resource agent for RabbitMQ-server -</longdesc> - -<shortdesc lang="en">Resource agent for RabbitMQ-server</shortdesc> - -<parameters> -<parameter name="server" unique="0" required="0"> -<longdesc lang="en"> -The path to the rabbitmq-server script -</longdesc> -<shortdesc lang="en">Path to rabbitmq-server</shortdesc> -<content type="string" default="${OCF_RESKEY_server_default}" /> -</parameter> - -<parameter name="ctl" unique="0" required="0"> -<longdesc lang="en"> -The path to the rabbitmqctl script -</longdesc> -<shortdesc lang="en">Path to rabbitmqctl</shortdesc> -<content type="string" default="${OCF_RESKEY_ctl_default}" /> -</parameter> - -<parameter name="nodename" unique="0" required="0"> -<longdesc lang="en"> -The node name for rabbitmq-server -</longdesc> -<shortdesc lang="en">Node name</shortdesc> -<content type="string" default="${OCF_RESKEY_nodename_default}" /> -</parameter> - -<parameter name="ip" unique="0" required="0"> -<longdesc lang="en"> -The IP address for rabbitmq-server to listen on -</longdesc> -<shortdesc lang="en">IP Address</shortdesc> -<content type="string" default="" /> -</parameter> - -<parameter name="port" unique="0" required="0"> -<longdesc lang="en"> -The IP Port for rabbitmq-server to listen on -</longdesc> -<shortdesc lang="en">IP Port</shortdesc> -<content type="integer" default="" /> -</parameter> - -<parameter name="config_file" unique="0" required="0"> -<longdesc lang="en"> -Location of the config file (without the .config suffix) -</longdesc> -<shortdesc lang="en">Config file path (without the .config suffix)</shortdesc> -<content type="string" default="" /> -</parameter> - -<parameter name="log_base" unique="0" required="0"> -<longdesc lang="en"> -Location of the directory under which logs will be created -</longdesc> -<shortdesc lang="en">Log base path</shortdesc> -<content type="string" default="${OCF_RESKEY_log_base_default}" /> -</parameter> - -<parameter name="mnesia_base" unique="0" required="0"> -<longdesc lang="en"> -Location of the directory under which mnesia will store data -</longdesc> -<shortdesc lang="en">Mnesia base path</shortdesc> -<content type="string" default="" /> -</parameter> - -<parameter name="server_start_args" unique="0" required="0"> -<longdesc lang="en"> -Additional arguments provided to the server on startup -</longdesc> -<shortdesc lang="en">Server start arguments</shortdesc> -<content type="string" default="" /> -</parameter> - -<parameter name="pid_file" unique="0" required="0"> -<longdesc lang="en"> -Location of the file in which the pid will be stored -</longdesc> -<shortdesc lang="en">Pid file path</shortdesc> -<content type="string" default="${OCF_RESKEY_pid_file_default}" /> -</parameter> - -</parameters> - -<actions> -<action name="start" timeout="600" /> -<action name="stop" timeout="120" /> -<action name="status" timeout="20" interval="10" /> -<action name="monitor" timeout="20" interval="10" /> -<action name="validate-all" timeout="30" /> -<action name="meta-data" timeout="5" /> -</actions> -</resource-agent> -END -} - -rabbit_usage() { - cat <<END -usage: $0 {start|stop|status|monitor|validate-all|meta-data} - -Expects to have a fully populated OCF RA-compliant environment set. -END -} - -RABBITMQ_SERVER=$OCF_RESKEY_server -RABBITMQ_CTL=$OCF_RESKEY_ctl -RABBITMQ_NODENAME=$OCF_RESKEY_nodename -RABBITMQ_NODE_IP_ADDRESS=$OCF_RESKEY_ip -RABBITMQ_NODE_PORT=$OCF_RESKEY_port -RABBITMQ_CONFIG_FILE=$OCF_RESKEY_config_file -RABBITMQ_LOG_BASE=$OCF_RESKEY_log_base -RABBITMQ_MNESIA_BASE=$OCF_RESKEY_mnesia_base -RABBITMQ_SERVER_START_ARGS=$OCF_RESKEY_server_start_args -RABBITMQ_PID_FILE=$OCF_RESKEY_pid_file -[ ! -z $RABBITMQ_NODENAME ] && NODENAME_ARG="-n $RABBITMQ_NODENAME" -[ ! -z $RABBITMQ_NODENAME ] && export RABBITMQ_NODENAME - -ensure_pid_dir () { - PID_DIR=`dirname ${RABBITMQ_PID_FILE}` - if [ ! -d ${PID_DIR} ] ; then - mkdir -p ${PID_DIR} - chown -R rabbitmq:rabbitmq ${PID_DIR} - chmod 755 ${PID_DIR} - fi - return $OCF_SUCCESS -} - -remove_pid () { - rm -f ${RABBITMQ_PID_FILE} - rmdir `dirname ${RABBITMQ_PID_FILE}` || : -} - -export_vars() { - [ ! -z $RABBITMQ_NODE_IP_ADDRESS ] && export RABBITMQ_NODE_IP_ADDRESS - [ ! -z $RABBITMQ_NODE_PORT ] && export RABBITMQ_NODE_PORT - [ ! -z $RABBITMQ_CONFIG_FILE ] && export RABBITMQ_CONFIG_FILE - [ ! -z $RABBITMQ_LOG_BASE ] && export RABBITMQ_LOG_BASE - [ ! -z $RABBITMQ_MNESIA_BASE ] && export RABBITMQ_MNESIA_BASE - [ ! -z $RABBITMQ_SERVER_START_ARGS ] && export RABBITMQ_SERVER_START_ARGS - [ ! -z $RABBITMQ_PID_FILE ] && ensure_pid_dir && export RABBITMQ_PID_FILE -} - -rabbit_validate_partial() { - if [ ! -x $RABBITMQ_SERVER ]; then - ocf_log err "rabbitmq-server server $RABBITMQ_SERVER does not exist or is not executable"; - exit $OCF_ERR_INSTALLED; - fi - - if [ ! -x $RABBITMQ_CTL ]; then - ocf_log err "rabbitmq-server ctl $RABBITMQ_CTL does not exist or is not executable"; - exit $OCF_ERR_INSTALLED; - fi -} - -rabbit_validate_full() { - if [ ! -z $RABBITMQ_CONFIG_FILE ] && [ ! -e "${RABBITMQ_CONFIG_FILE}.config" ]; then - ocf_log err "rabbitmq-server config_file ${RABBITMQ_CONFIG_FILE}.config does not exist or is not a file"; - exit $OCF_ERR_INSTALLED; - fi - - if [ ! -z $RABBITMQ_LOG_BASE ] && [ ! -d $RABBITMQ_LOG_BASE ]; then - ocf_log err "rabbitmq-server log_base $RABBITMQ_LOG_BASE does not exist or is not a directory"; - exit $OCF_ERR_INSTALLED; - fi - - if [ ! -z $RABBITMQ_MNESIA_BASE ] && [ ! -d $RABBITMQ_MNESIA_BASE ]; then - ocf_log err "rabbitmq-server mnesia_base $RABBITMQ_MNESIA_BASE does not exist or is not a directory"; - exit $OCF_ERR_INSTALLED; - fi - - rabbit_validate_partial - - return $OCF_SUCCESS -} - -rabbit_status() { - rabbitmqctl_action "status" -} - -rabbit_wait() { - rabbitmqctl_action "wait" $1 -} - -rabbitmqctl_action() { - local rc - local action - action=$@ - $RABBITMQ_CTL $NODENAME_ARG $action > /dev/null 2> /dev/null - rc=$? - case "$rc" in - 0) - ocf_log debug "RabbitMQ server is running normally" - return $OCF_SUCCESS - ;; - 2) - ocf_log debug "RabbitMQ server is not running" - return $OCF_NOT_RUNNING - ;; - *) - ocf_log err "Unexpected return from rabbitmqctl $NODENAME_ARG $action: $rc" - exit $OCF_ERR_GENERIC - esac -} - -rabbit_start() { - local rc - - if rabbit_status; then - ocf_log info "Resource already running." - return $OCF_SUCCESS - fi - - export_vars - - setsid sh -c "$RABBITMQ_SERVER > ${RABBITMQ_LOG_BASE}/startup_log 2> ${RABBITMQ_LOG_BASE}/startup_err" & - - # Wait for the server to come up. - # Let the CRM/LRM time us out if required - rabbit_wait $RABBITMQ_PID_FILE - rc=$? - if [ "$rc" != $OCF_SUCCESS ]; then - remove_pid - ocf_log info "rabbitmq-server start failed: $rc" - exit $OCF_ERR_GENERIC - fi - - return $OCF_SUCCESS -} - -rabbit_stop() { - local rc - - if ! rabbit_status; then - ocf_log info "Resource not running." - return $OCF_SUCCESS - fi - - $RABBITMQ_CTL stop ${RABBITMQ_PID_FILE} - rc=$? - - if [ "$rc" != 0 ]; then - ocf_log err "rabbitmq-server stop command failed: $RABBITMQ_CTL stop, $rc" - return $rc - fi - - # Spin waiting for the server to shut down. - # Let the CRM/LRM time us out if required - stop_wait=1 - while [ $stop_wait = 1 ]; do - rabbit_status - rc=$? - if [ "$rc" = $OCF_NOT_RUNNING ]; then - remove_pid - stop_wait=0 - break - elif [ "$rc" != $OCF_SUCCESS ]; then - ocf_log info "rabbitmq-server stop failed: $rc" - exit $OCF_ERR_GENERIC - fi - sleep 1 - done - - return $OCF_SUCCESS -} - -rabbit_monitor() { - rabbit_status - return $? -} - -case $__OCF_ACTION in - meta-data) - meta_data - exit $OCF_SUCCESS - ;; - usage|help) - rabbit_usage - exit $OCF_SUCCESS - ;; -esac - -if ocf_is_probe; then - rabbit_validate_partial -else - rabbit_validate_full -fi - -case $__OCF_ACTION in - start) - rabbit_start - ;; - stop) - rabbit_stop - ;; - status|monitor) - rabbit_monitor - ;; - validate-all) - exit $OCF_SUCCESS - ;; - *) - rabbit_usage - exit $OCF_ERR_UNIMPLEMENTED - ;; -esac - -exit $? diff --git a/scripts/travis_test_ocf_ra.sh b/scripts/travis_test_ocf_ra.sh deleted file mode 100644 index e8f9a74194..0000000000 --- a/scripts/travis_test_ocf_ra.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -eux -# Prepare and run a smoke test against the RabbitMQ OCF RA only if -# the scripts/rabbitmq-server-ha.ocf has changes -if ! git diff HEAD~ --name-only | grep -q scripts/rabbitmq-server-ha.ocf -then - exit 0 -fi - -export VAGRANT_VERSION=1.8.1 -export DOCKER_IMAGE=bogdando/rabbitmq-cluster-ocf-wily -export UPLOAD_METHOD=none -export DOCKER_MOUNTS="$(pwd)/scripts/rabbitmq-server-ha.ocf:/tmp/rabbitmq-server-ha" - -# Install vagrant and requirements -sudo apt-get install -qq git wget -wget --no-verbose https://releases.hashicorp.com/vagrant/${VAGRANT_VERSION}/vagrant_${VAGRANT_VERSION}_x86_64.deb -sudo dpkg -i --force-all ./vagrant_${VAGRANT_VERSION}_x86_64.deb -vagrant plugin install vagrant-triggers - -# Update docker and prepare images -sudo apt-get update -sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install --only-upgrade docker-engine -sudo service docker restart -docker pull $DOCKER_IMAGE - -# Prepare and run a smoke test for a rabbitmq cluster by the OCF RA -git clone https://github.com/bogdando/rabbitmq-cluster-ocf-vagrant.git -cd ./rabbitmq-cluster-ocf-vagrant -vagrant up --provider docker -docker exec -it n1 /bin/bash /vagrant/vagrant_script/test_rabbitcluster.sh rabbit@n1 rabbit@n2 diff --git a/src/gm.erl b/src/gm.erl index 176e14537f..74e19ee6fd 100644 --- a/src/gm.erl +++ b/src/gm.erl @@ -611,7 +611,7 @@ handle_call({add_on_right, NewMember}, _From, handle_callback_result({Result, {ok, Group}, State1}) catch lost_membership -> - {stop, normal, State} + {stop, shutdown, State} end. %% add_on_right causes a catchup to be sent immediately from the left, @@ -646,7 +646,7 @@ handle_cast({?TAG, ReqVer, Msg}, Result, fun handle_msg_true/3, fun handle_msg_false/3, Msg, State1)) catch lost_membership -> - {stop, normal, State} + {stop, shutdown, State} end; handle_cast({broadcast, _Msg, _SizeHint}, @@ -675,16 +675,21 @@ handle_cast(join, State = #state { self = Self, module = Module, callback_args = Args, txn_executor = TxnFun }) -> - View = join_group(Self, GroupName, TxnFun), - MembersState = - case alive_view_members(View) of - [Self] -> blank_member_state(); - _ -> undefined - end, - State1 = check_neighbours(State #state { view = View, - members_state = MembersState }), - handle_callback_result( - {Module:joined(Args, get_pids(all_known_members(View))), State1}); + try + View = join_group(Self, GroupName, TxnFun), + MembersState = + case alive_view_members(View) of + [Self] -> blank_member_state(); + _ -> undefined + end, + State1 = check_neighbours(State #state { view = View, + members_state = MembersState }), + handle_callback_result( + {Module:joined(Args, get_pids(all_known_members(View))), State1}) + catch + lost_membership -> + {stop, shutdown, State} + end; handle_cast({validate_members, OldMembers}, State = #state { view = View, @@ -756,13 +761,18 @@ handle_info({'DOWN', MRef, process, _Pid, Reason}, end catch lost_membership -> - {stop, normal, State} - end. + {stop, shutdown, State} + end; +handle_info(_, State) -> + %% Discard any unexpected messages, such as late replies from neighbour_call/2 + %% TODO: For #gm_group{} related info messages, it could be worthwhile to + %% change_view/2, as this might reflect an alteration in the gm group, meaning + %% we now need to update our state. see rabbitmq-server#914. + noreply(State). terminate(Reason, #state { module = Module, callback_args = Args }) -> Module:handle_terminate(Args, Reason). - code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -865,7 +875,7 @@ handle_msg({activity, Left, Activity}, Result, fun activity_true/3, fun activity_false/3, Activity3, State2) catch lost_membership -> - {{stop, normal}, State} + {{stop, shutdown}, State} end; handle_msg({activity, _NotLeft, _Activity}, State) -> @@ -1131,7 +1141,7 @@ record_dead_member_in_group(Self, Member, GroupName, TxnFun, Verify) -> true -> check_membership(Self, read_group(GroupName)); false -> - read_group(GroupName) + check_group(read_group(GroupName)) end, case lists:splitwith( fun (Member1) -> Member1 =/= Member end, Members) of @@ -1593,7 +1603,9 @@ check_membership(Self, #gm_group{members = M} = Group) -> Group; false -> throw(lost_membership) - end. + end; +check_membership(_Self, {error, not_found}) -> + throw(lost_membership). check_membership(GroupName) -> case dirty_read_group(GroupName) of @@ -1607,3 +1619,8 @@ check_membership(GroupName) -> {error, not_found} -> throw(lost_membership) end. + +check_group({error, not_found}) -> + throw(lost_membership); +check_group(Any) -> + Any. diff --git a/src/mochinum.erl b/src/mochinum.erl deleted file mode 100644 index 4ea7a22acf..0000000000 --- a/src/mochinum.erl +++ /dev/null @@ -1,358 +0,0 @@ -%% This file is a copy of `mochijson2.erl' from mochiweb, revision -%% d541e9a0f36c00dcadc2e589f20e47fbf46fc76f. For the license, see -%% `LICENSE-MIT-Mochi'. - -%% @copyright 2007 Mochi Media, Inc. -%% @author Bob Ippolito <bob@mochimedia.com> - -%% @doc Useful numeric algorithms for floats that cover some deficiencies -%% in the math module. More interesting is digits/1, which implements -%% the algorithm from: -%% http://www.cs.indiana.edu/~burger/fp/index.html -%% See also "Printing Floating-Point Numbers Quickly and Accurately" -%% in Proceedings of the SIGPLAN '96 Conference on Programming Language -%% Design and Implementation. - --module(mochinum). --author("Bob Ippolito <bob@mochimedia.com>"). --export([digits/1, frexp/1, int_pow/2, int_ceil/1]). - -%% IEEE 754 Float exponent bias --define(FLOAT_BIAS, 1022). --define(MIN_EXP, -1074). --define(BIG_POW, 4503599627370496). - -%% External API - -%% @spec digits(number()) -> string() -%% @doc Returns a string that accurately represents the given integer or float -%% using a conservative amount of digits. Great for generating -%% human-readable output, or compact ASCII serializations for floats. -digits(N) when is_integer(N) -> - integer_to_list(N); -digits(0.0) -> - "0.0"; -digits(Float) -> - {Frac1, Exp1} = frexp_int(Float), - [Place0 | Digits0] = digits1(Float, Exp1, Frac1), - {Place, Digits} = transform_digits(Place0, Digits0), - R = insert_decimal(Place, Digits), - case Float < 0 of - true -> - [$- | R]; - _ -> - R - end. - -%% @spec frexp(F::float()) -> {Frac::float(), Exp::float()} -%% @doc Return the fractional and exponent part of an IEEE 754 double, -%% equivalent to the libc function of the same name. -%% F = Frac * pow(2, Exp). -frexp(F) -> - frexp1(unpack(F)). - -%% @spec int_pow(X::integer(), N::integer()) -> Y::integer() -%% @doc Moderately efficient way to exponentiate integers. -%% int_pow(10, 2) = 100. -int_pow(_X, 0) -> - 1; -int_pow(X, N) when N > 0 -> - int_pow(X, N, 1). - -%% @spec int_ceil(F::float()) -> integer() -%% @doc Return the ceiling of F as an integer. The ceiling is defined as -%% F when F == trunc(F); -%% trunc(F) when F < 0; -%% trunc(F) + 1 when F > 0. -int_ceil(X) -> - T = trunc(X), - case (X - T) of - Pos when Pos > 0 -> T + 1; - _ -> T - end. - - -%% Internal API - -int_pow(X, N, R) when N < 2 -> - R * X; -int_pow(X, N, R) -> - int_pow(X * X, N bsr 1, case N band 1 of 1 -> R * X; 0 -> R end). - -insert_decimal(0, S) -> - "0." ++ S; -insert_decimal(Place, S) when Place > 0 -> - L = length(S), - case Place - L of - 0 -> - S ++ ".0"; - N when N < 0 -> - {S0, S1} = lists:split(L + N, S), - S0 ++ "." ++ S1; - N when N < 6 -> - %% More places than digits - S ++ lists:duplicate(N, $0) ++ ".0"; - _ -> - insert_decimal_exp(Place, S) - end; -insert_decimal(Place, S) when Place > -6 -> - "0." ++ lists:duplicate(abs(Place), $0) ++ S; -insert_decimal(Place, S) -> - insert_decimal_exp(Place, S). - -insert_decimal_exp(Place, S) -> - [C | S0] = S, - S1 = case S0 of - [] -> - "0"; - _ -> - S0 - end, - Exp = case Place < 0 of - true -> - "e-"; - false -> - "e+" - end, - [C] ++ "." ++ S1 ++ Exp ++ integer_to_list(abs(Place - 1)). - - -digits1(Float, Exp, Frac) -> - Round = ((Frac band 1) =:= 0), - case Exp >= 0 of - true -> - BExp = 1 bsl Exp, - case (Frac =/= ?BIG_POW) of - true -> - scale((Frac * BExp * 2), 2, BExp, BExp, - Round, Round, Float); - false -> - scale((Frac * BExp * 4), 4, (BExp * 2), BExp, - Round, Round, Float) - end; - false -> - case (Exp =:= ?MIN_EXP) orelse (Frac =/= ?BIG_POW) of - true -> - scale((Frac * 2), 1 bsl (1 - Exp), 1, 1, - Round, Round, Float); - false -> - scale((Frac * 4), 1 bsl (2 - Exp), 2, 1, - Round, Round, Float) - end - end. - -scale(R, S, MPlus, MMinus, LowOk, HighOk, Float) -> - Est = int_ceil(math:log10(abs(Float)) - 1.0e-10), - %% Note that the scheme implementation uses a 326 element look-up table - %% for int_pow(10, N) where we do not. - case Est >= 0 of - true -> - fixup(R, S * int_pow(10, Est), MPlus, MMinus, Est, - LowOk, HighOk); - false -> - Scale = int_pow(10, -Est), - fixup(R * Scale, S, MPlus * Scale, MMinus * Scale, Est, - LowOk, HighOk) - end. - -fixup(R, S, MPlus, MMinus, K, LowOk, HighOk) -> - TooLow = case HighOk of - true -> - (R + MPlus) >= S; - false -> - (R + MPlus) > S - end, - case TooLow of - true -> - [(K + 1) | generate(R, S, MPlus, MMinus, LowOk, HighOk)]; - false -> - [K | generate(R * 10, S, MPlus * 10, MMinus * 10, LowOk, HighOk)] - end. - -generate(R0, S, MPlus, MMinus, LowOk, HighOk) -> - D = R0 div S, - R = R0 rem S, - TC1 = case LowOk of - true -> - R =< MMinus; - false -> - R < MMinus - end, - TC2 = case HighOk of - true -> - (R + MPlus) >= S; - false -> - (R + MPlus) > S - end, - case TC1 of - false -> - case TC2 of - false -> - [D | generate(R * 10, S, MPlus * 10, MMinus * 10, - LowOk, HighOk)]; - true -> - [D + 1] - end; - true -> - case TC2 of - false -> - [D]; - true -> - case R * 2 < S of - true -> - [D]; - false -> - [D + 1] - end - end - end. - -unpack(Float) -> - <<Sign:1, Exp:11, Frac:52>> = <<Float:64/float>>, - {Sign, Exp, Frac}. - -frexp1({_Sign, 0, 0}) -> - {0.0, 0}; -frexp1({Sign, 0, Frac}) -> - Exp = log2floor(Frac), - <<Frac1:64/float>> = <<Sign:1, ?FLOAT_BIAS:11, (Frac-1):52>>, - {Frac1, -(?FLOAT_BIAS) - 52 + Exp}; -frexp1({Sign, Exp, Frac}) -> - <<Frac1:64/float>> = <<Sign:1, ?FLOAT_BIAS:11, Frac:52>>, - {Frac1, Exp - ?FLOAT_BIAS}. - -log2floor(Int) -> - log2floor(Int, 0). - -log2floor(0, N) -> - N; -log2floor(Int, N) -> - log2floor(Int bsr 1, 1 + N). - - -transform_digits(Place, [0 | Rest]) -> - transform_digits(Place, Rest); -transform_digits(Place, Digits) -> - {Place, [$0 + D || D <- Digits]}. - - -frexp_int(F) -> - case unpack(F) of - {_Sign, 0, Frac} -> - {Frac, ?MIN_EXP}; - {_Sign, Exp, Frac} -> - {Frac + (1 bsl 52), Exp - 53 - ?FLOAT_BIAS} - end. - -%% -%% Tests -%% --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). - -int_ceil_test() -> - ?assertEqual(1, int_ceil(0.0001)), - ?assertEqual(0, int_ceil(0.0)), - ?assertEqual(1, int_ceil(0.99)), - ?assertEqual(1, int_ceil(1.0)), - ?assertEqual(-1, int_ceil(-1.5)), - ?assertEqual(-2, int_ceil(-2.0)), - ok. - -int_pow_test() -> - ?assertEqual(1, int_pow(1, 1)), - ?assertEqual(1, int_pow(1, 0)), - ?assertEqual(1, int_pow(10, 0)), - ?assertEqual(10, int_pow(10, 1)), - ?assertEqual(100, int_pow(10, 2)), - ?assertEqual(1000, int_pow(10, 3)), - ok. - -digits_test() -> - ?assertEqual("0", - digits(0)), - ?assertEqual("0.0", - digits(0.0)), - ?assertEqual("1.0", - digits(1.0)), - ?assertEqual("-1.0", - digits(-1.0)), - ?assertEqual("0.1", - digits(0.1)), - ?assertEqual("0.01", - digits(0.01)), - ?assertEqual("0.001", - digits(0.001)), - ?assertEqual("1.0e+6", - digits(1000000.0)), - ?assertEqual("0.5", - digits(0.5)), - ?assertEqual("4503599627370496.0", - digits(4503599627370496.0)), - %% small denormalized number - %% 4.94065645841246544177e-324 =:= 5.0e-324 - <<SmallDenorm/float>> = <<0,0,0,0,0,0,0,1>>, - ?assertEqual("5.0e-324", - digits(SmallDenorm)), - ?assertEqual(SmallDenorm, - list_to_float(digits(SmallDenorm))), - %% large denormalized number - %% 2.22507385850720088902e-308 - <<BigDenorm/float>> = <<0,15,255,255,255,255,255,255>>, - ?assertEqual("2.225073858507201e-308", - digits(BigDenorm)), - ?assertEqual(BigDenorm, - list_to_float(digits(BigDenorm))), - %% small normalized number - %% 2.22507385850720138309e-308 - <<SmallNorm/float>> = <<0,16,0,0,0,0,0,0>>, - ?assertEqual("2.2250738585072014e-308", - digits(SmallNorm)), - ?assertEqual(SmallNorm, - list_to_float(digits(SmallNorm))), - %% large normalized number - %% 1.79769313486231570815e+308 - <<LargeNorm/float>> = <<127,239,255,255,255,255,255,255>>, - ?assertEqual("1.7976931348623157e+308", - digits(LargeNorm)), - ?assertEqual(LargeNorm, - list_to_float(digits(LargeNorm))), - %% issue #10 - mochinum:frexp(math:pow(2, -1074)). - ?assertEqual("5.0e-324", - digits(math:pow(2, -1074))), - ok. - -frexp_test() -> - %% zero - ?assertEqual({0.0, 0}, frexp(0.0)), - %% one - ?assertEqual({0.5, 1}, frexp(1.0)), - %% negative one - ?assertEqual({-0.5, 1}, frexp(-1.0)), - %% small denormalized number - %% 4.94065645841246544177e-324 - <<SmallDenorm/float>> = <<0,0,0,0,0,0,0,1>>, - ?assertEqual({0.5, -1073}, frexp(SmallDenorm)), - %% large denormalized number - %% 2.22507385850720088902e-308 - <<BigDenorm/float>> = <<0,15,255,255,255,255,255,255>>, - ?assertEqual( - {0.99999999999999978, -1022}, - frexp(BigDenorm)), - %% small normalized number - %% 2.22507385850720138309e-308 - <<SmallNorm/float>> = <<0,16,0,0,0,0,0,0>>, - ?assertEqual({0.5, -1021}, frexp(SmallNorm)), - %% large normalized number - %% 1.79769313486231570815e+308 - <<LargeNorm/float>> = <<127,239,255,255,255,255,255,255>>, - ?assertEqual( - {0.99999999999999989, 1024}, - frexp(LargeNorm)), - %% issue #10 - mochinum:frexp(math:pow(2, -1074)). - ?assertEqual( - {0.5, -1073}, - frexp(math:pow(2, -1074))), - ok. - --endif. diff --git a/src/rabbit.app.src b/src/rabbit.app.src index 572c1f6bc6..872336bd8e 100644 --- a/src/rabbit.app.src +++ b/src/rabbit.app.src @@ -95,7 +95,8 @@ {msg_store_credit_disc_bound, {2000, 500}}, {msg_store_io_batch_size, 2048}, %% see rabbitmq-server#143 - {credit_flow_default_credit, {200, 50}}, + %% and rabbitmq-server#949 + {credit_flow_default_credit, {200, 100}}, %% see rabbitmq-server#248 %% and rabbitmq-server#667 {channel_operation_timeout, 15000} diff --git a/src/rabbit_amqqueue_process.erl b/src/rabbit_amqqueue_process.erl index da84c612d9..4f8581f78a 100644 --- a/src/rabbit_amqqueue_process.erl +++ b/src/rabbit_amqqueue_process.erl @@ -85,6 +85,7 @@ %% e.g. message expiration messages from previously set up timers %% that may or may not be still valid args_policy_version, + mirroring_policy_version = 0, %% running | flow | idle status }). @@ -1017,7 +1018,17 @@ prioritise_info(Msg, _Len, #q{q = #amqqueue{exclusive_owner = DownPid}}) -> end. handle_call({init, Recover}, From, State) -> - init_it(Recover, From, State); + try + init_it(Recover, From, State) + catch + {coordinator_not_started, Reason} -> + %% The GM can shutdown before the coordinator has started up + %% (lost membership or missing group), thus the start_link of + %% the coordinator returns {error, shutdown} as rabbit_amqqueue_process + %% is trapping exists. The master captures this return value and + %% throws the current exception. + {stop, Reason, State} + end; handle_call(info, _From, State) -> reply(infos(info_keys(), State), State); @@ -1168,7 +1179,17 @@ handle_call(cancel_sync_mirrors, _From, State) -> reply({ok, not_syncing}, State). handle_cast(init, State) -> - init_it({no_barrier, non_clean_shutdown}, none, State); + try + init_it({no_barrier, non_clean_shutdown}, none, State) + catch + {coordinator_not_started, Reason} -> + %% The GM can shutdown before the coordinator has started up + %% (lost membership or missing group), thus the start_link of + %% the coordinator returns {error, shutdown} as rabbit_amqqueue_process + %% is trapping exists. The master captures this return value and + %% throws the current exception. + {stop, Reason, State} + end; handle_cast({run_backing_queue, Mod, Fun}, State = #q{backing_queue = BQ, backing_queue_state = BQS}) -> @@ -1235,22 +1256,15 @@ handle_cast({set_maximum_since_use, Age}, State) -> ok = file_handle_cache:set_maximum_since_use(Age), noreply(State); -handle_cast(start_mirroring, State = #q{backing_queue = BQ, - backing_queue_state = BQS}) -> - %% lookup again to get policy for init_with_existing_bq - {ok, Q} = rabbit_amqqueue:lookup(qname(State)), - true = BQ =/= rabbit_mirror_queue_master, %% assertion - BQ1 = rabbit_mirror_queue_master, - BQS1 = BQ1:init_with_existing_bq(Q, BQ, BQS), - noreply(State#q{backing_queue = BQ1, - backing_queue_state = BQS1}); - -handle_cast(stop_mirroring, State = #q{backing_queue = BQ, - backing_queue_state = BQS}) -> - BQ = rabbit_mirror_queue_master, %% assertion - {BQ1, BQS1} = BQ:stop_mirroring(BQS), - noreply(State#q{backing_queue = BQ1, - backing_queue_state = BQS1}); +handle_cast(update_mirroring, State = #q{q = Q, + mirroring_policy_version = Version}) -> + case needs_update_mirroring(Q, Version) of + false -> + noreply(State); + {Policy, NewVersion} -> + State1 = State#q{mirroring_policy_version = NewVersion}, + noreply(update_mirroring(Policy, State1)) + end; handle_cast({credit, ChPid, CTag, Credit, Drain}, State = #q{consumers = Consumers, @@ -1393,3 +1407,54 @@ handle_pre_hibernate(State = #q{backing_queue = BQ, {hibernate, stop_rate_timer(State1)}. format_message_queue(Opt, MQ) -> rabbit_misc:format_message_queue(Opt, MQ). + +needs_update_mirroring(Q, Version) -> + {ok, UpQ} = rabbit_amqqueue:lookup(Q#amqqueue.name), + DBVersion = UpQ#amqqueue.policy_version, + case DBVersion > Version of + true -> {rabbit_policy:get(<<"ha-mode">>, UpQ), DBVersion}; + false -> false + end. + +update_mirroring(Policy, State = #q{backing_queue = BQ}) -> + case update_to(Policy, BQ) of + start_mirroring -> + start_mirroring(State); + stop_mirroring -> + stop_mirroring(State); + ignore -> + State; + update_ha_mode -> + update_ha_mode(State) + end. + +update_to(undefined, rabbit_mirror_queue_master) -> + stop_mirroring; +update_to(_, rabbit_mirror_queue_master) -> + update_ha_mode; +update_to(undefined, BQ) when BQ =/= rabbit_mirror_queue_master -> + ignore; +update_to(_, BQ) when BQ =/= rabbit_mirror_queue_master -> + start_mirroring. + +start_mirroring(State = #q{backing_queue = BQ, + backing_queue_state = BQS}) -> + %% lookup again to get policy for init_with_existing_bq + {ok, Q} = rabbit_amqqueue:lookup(qname(State)), + true = BQ =/= rabbit_mirror_queue_master, %% assertion + BQ1 = rabbit_mirror_queue_master, + BQS1 = BQ1:init_with_existing_bq(Q, BQ, BQS), + State#q{backing_queue = BQ1, + backing_queue_state = BQS1}. + +stop_mirroring(State = #q{backing_queue = BQ, + backing_queue_state = BQS}) -> + BQ = rabbit_mirror_queue_master, %% assertion + {BQ1, BQS1} = BQ:stop_mirroring(BQS), + State#q{backing_queue = BQ1, + backing_queue_state = BQS1}. + +update_ha_mode(State) -> + {ok, Q} = rabbit_amqqueue:lookup(qname(State)), + ok = rabbit_mirror_queue_misc:update_mirrors(Q), + State. diff --git a/src/rabbit_autoheal.erl b/src/rabbit_autoheal.erl index 5865ba8227..3adcc09692 100644 --- a/src/rabbit_autoheal.erl +++ b/src/rabbit_autoheal.erl @@ -180,6 +180,18 @@ node_down(_Node, not_healing) -> node_down(Node, {winner_waiting, _, Notify}) -> abort([Node], Notify); +node_down(Node, {leader_waiting, Node, _Notify}) -> + %% The winner went down, we don't know what to do so we simply abort. + rabbit_log:info("Autoheal: aborting - winner ~p went down~n", [Node]), + not_healing; + +node_down(Node, {leader_waiting, _, _} = St) -> + %% If it is a partial partition, the winner might continue with the + %% healing process. If it is a full partition, the winner will also + %% see it and abort. Let's wait for it. + rabbit_log:info("Autoheal: ~p went down, waiting for winner decision ~n", [Node]), + St; + node_down(Node, _State) -> rabbit_log:info("Autoheal: aborting - ~p went down~n", [Node]), not_healing. @@ -218,14 +230,24 @@ handle_msg({become_winner, Losers}, not_healing, _Partitions) -> rabbit_log:info("Autoheal: I am the winner, waiting for ~p to stop~n", [Losers]), - %% The leader said everything was ready - do we agree? If not then - %% give up. - Down = Losers -- rabbit_node_monitor:alive_rabbit_nodes(Losers), - case Down of - [] -> [send(L, {winner_is, node()}) || L <- Losers], - {winner_waiting, Losers, Losers}; - _ -> abort(Down, Losers) - end; + stop_partition(Losers); + +handle_msg({become_winner, Losers}, + {winner_waiting, _, Losers}, _Partitions) -> + %% The leader has aborted the healing, might have seen us down but + %% we didn't see the same. Let's try again as it is the same partition. + rabbit_log:info("Autoheal: I am the winner and received a duplicated " + "request, waiting again for ~p to stop~n", [Losers]), + stop_partition(Losers); + +handle_msg({become_winner, _}, + {winner_waiting, _, Losers}, _Partitions) -> + %% Something has happened to the leader, it might have seen us down but we + %% are still alive. Partitions have changed, cannot continue. + rabbit_log:info("Autoheal: I am the winner and received another healing " + "request, partitions have changed to ~p. Aborting ~n", [Losers]), + winner_finish(Losers), + not_healing; handle_msg({winner_is, Winner}, State = not_healing, _Partitions) -> @@ -269,6 +291,14 @@ handle_msg({autoheal_finished, Winner}, not_healing, _Partitions) %% We are the leader and the winner. The state already transitioned %% to "not_healing" at the end of the autoheal process. rabbit_log:info("Autoheal finished according to winner ~p~n", [node()]), + not_healing; + +handle_msg({autoheal_finished, Winner}, not_healing, _Partitions) -> + %% We might have seen the winner down during a partial partition and + %% transitioned to not_healing. However, the winner was still able + %% to finish. Let it pass. + rabbit_log:info("Autoheal finished according to winner ~p." + " Unexpected, I might have previously seen the winner down~n", [Winner]), not_healing. %%---------------------------------------------------------------------------- @@ -279,7 +309,9 @@ abort(Down, Notify) -> rabbit_log:info("Autoheal: aborting - ~p down~n", [Down]), %% Make sure any nodes waiting for us start - it won't necessarily %% heal the partition but at least they won't get stuck. - winner_finish(Notify). + %% If we are executing this, we are not stopping. Thus, don't wait + %% for ourselves! + winner_finish(Notify -- [node()]). winner_finish(Notify) -> %% There is a race in Mnesia causing a starting loser to hang @@ -297,21 +329,33 @@ winner_finish(Notify) -> send(leader(), {autoheal_finished, node()}), not_healing. -wait_for_mnesia_shutdown([Node | Rest] = AllNodes) -> - case rpc:call(Node, mnesia, system_info, [is_running]) of - no -> - wait_for_mnesia_shutdown(Rest); - Running when - Running =:= yes orelse - Running =:= starting orelse - Running =:= stopping -> - timer:sleep(?MNESIA_STOPPED_PING_INTERNAL), - wait_for_mnesia_shutdown(AllNodes); - _ -> - wait_for_mnesia_shutdown(Rest) - end; -wait_for_mnesia_shutdown([]) -> - ok. +%% This improves the previous implementation, but could still potentially enter an infinity +%% loop. If it also possible that for when it finishes some of the nodes have been +%% manually restarted, but we can't do much more (apart from stop them again). So let it +%% continue and notify all the losers to restart. +wait_for_mnesia_shutdown(AllNodes) -> + Monitors = lists:foldl(fun(Node, Monitors0) -> + pmon:monitor({mnesia_sup, Node}, Monitors0) + end, pmon:new(), AllNodes), + wait_for_supervisors(Monitors). + +wait_for_supervisors(Monitors) -> + case pmon:is_empty(Monitors) of + true -> + ok; + false -> + receive + {'DOWN', _MRef, process, {mnesia_sup, _} = I, _Reason} -> + wait_for_supervisors(pmon:erase(I, Monitors)) + after + 60000 -> + AliveLosers = [Node || {_, Node} <- pmon:monitored(Monitors)], + rabbit_log:info("Autoheal: mnesia in nodes ~p is still up, sending " + "winner notification again to these ~n", [AliveLosers]), + [send(L, {winner_is, node()}) || L <- AliveLosers], + wait_for_mnesia_shutdown(AliveLosers) + end + end. restart_loser(State, Winner) -> rabbit_log:warning( @@ -391,3 +435,13 @@ fmt_error({remote_down, RemoteDown}) -> rabbit_misc:format("Remote nodes disconnected:~n ~p", [RemoteDown]); fmt_error({nodes_down, NodesDown}) -> rabbit_misc:format("Local nodes down: ~p", [NodesDown]). + +stop_partition(Losers) -> + %% The leader said everything was ready - do we agree? If not then + %% give up. + Down = Losers -- rabbit_node_monitor:alive_rabbit_nodes(Losers), + case Down of + [] -> [send(L, {winner_is, node()}) || L <- Losers], + {winner_waiting, Losers, Losers}; + _ -> abort(Down, Losers) + end. diff --git a/src/rabbit_cli.erl b/src/rabbit_cli.erl index 6b35482217..c0e5c93247 100644 --- a/src/rabbit_cli.erl +++ b/src/rabbit_cli.erl @@ -18,7 +18,7 @@ -include("rabbit_cli.hrl"). -export([main/3, start_distribution/0, start_distribution/1, - parse_arguments/4, filter_opts/2, + parse_arguments/4, mutually_exclusive_flags/3, rpc_call/4, rpc_call/5, rpc_call/7]). %%---------------------------------------------------------------------------- @@ -42,8 +42,7 @@ [{string(), optdef()}], string(), [string()]) -> parse_result(). --spec filter_opts([{option_name(), option_value()}], [option_name()]) -> - [boolean()]. +-spec mutually_exclusive_flags([{option_name(), option_value()}], term(), [{option_name(), term()}]) -> {ok, term()} | {error, string()}. -spec rpc_call(node(), atom(), atom(), [any()]) -> any(). -spec rpc_call(node(), atom(), atom(), [any()], number()) -> any(). @@ -147,7 +146,7 @@ main(ParseFun, DoFun, UsageMod) -> start_distribution_anon(0, LastError) -> {error, LastError}; start_distribution_anon(TriesLeft, _) -> - NameCandidate = list_to_atom(rabbit_misc:format("rabbitmq-cli-~2..0b", [rand_compat:uniform(100)])), + NameCandidate = generate_cli_node_name(), case net_kernel:start([NameCandidate, name_type()]) of {ok, _} = Result -> Result; @@ -155,7 +154,7 @@ start_distribution_anon(TriesLeft, _) -> start_distribution_anon(TriesLeft - 1, Reason) end. -%% Tries to start distribution with randonm name choosen from limited list of candidates - to +%% Tries to start distribution with random name choosen from limited list of candidates - to %% prevent atom table pollution on target nodes. start_distribution() -> rabbit_nodes:ensure_epmd(), @@ -171,6 +170,22 @@ name_type() -> _ -> shortnames end. +generate_cli_node_name() -> + Base = rabbit_misc:format("rabbitmq-cli-~2..0b", [rand_compat:uniform(100)]), + NameAsList = + case {name_type(), inet_db:res_option(domain)} of + {longnames, []} -> + %% Distribution will fail to start if it's unable to + %% determine FQDN of a node (with at least one dot in + %% a name). + %% CLI is always an initiator of connection, so it + %% doesn't matter if the name will not resolve. + Base ++ "@" ++ inet_db:gethostname() ++ ".no-domain"; + _ -> + Base + end, + list_to_atom(NameAsList). + usage(Mod) -> usage(Mod, ?EX_USAGE). @@ -250,20 +265,22 @@ process_opts(Defs, C, [A | As], Found, KVs, Outs) -> {none, _, _} -> no_command end. -%% When we have a set of flags that are used for filtering, we want by -%% default to include every such option in our output. But if a user -%% explicitly specified any such flag, we want to include only items -%% which he has requested. -filter_opts(CurrentOptionValues, AllOptionNames) -> - Explicit = lists:map(fun(OptName) -> - proplists:get_bool(OptName, CurrentOptionValues) - end, - AllOptionNames), - case lists:member(true, Explicit) of - true -> - Explicit; - false -> - lists:duplicate(length(AllOptionNames), true) +mutually_exclusive_flags(CurrentOptionValues, Default, FlagsAndValues) -> + PresentFlags = lists:filtermap(fun({OptName, _} = _O) -> + proplists:get_bool(OptName, CurrentOptionValues) + end, + FlagsAndValues), + case PresentFlags of + [] -> + {ok, Default}; + [{_, Value}] -> + {ok, Value}; + _ -> + Names = [ [$', N, $'] || {N, _} <- PresentFlags ], + CommaSeparated = string:join(lists:droplast(Names), ", "), + AndOneMore = lists:last(Names), + Msg = io_lib:format("Options ~s and ~s are mutually exclusive", [CommaSeparated, AndOneMore]), + {error, lists:flatten(Msg)} end. %%---------------------------------------------------------------------------- diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index d2f0e8bcb0..92898c2a2c 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -74,7 +74,7 @@ {clear_policy, [?VHOST_DEF]}, {list_policies, [?VHOST_DEF]}, - {list_queues, [?VHOST_DEF, ?OFFLINE_DEF, ?ONLINE_DEF]}, + {list_queues, [?VHOST_DEF, ?OFFLINE_DEF, ?ONLINE_DEF, ?LOCAL_DEF]}, {list_exchanges, [?VHOST_DEF]}, {list_bindings, [?VHOST_DEF]}, {list_connections, [?VHOST_DEF]}, @@ -632,12 +632,19 @@ action(list_user_permissions, Node, Args = [_Username], _Opts, Inform, Timeout) true); action(list_queues, Node, Args, Opts, Inform, Timeout) -> - [Online, Offline] = rabbit_cli:filter_opts(Opts, [?ONLINE_OPT, ?OFFLINE_OPT]), - Inform("Listing queues", []), - VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), - ArgAtoms = default_if_empty(Args, [name, messages]), - call(Node, {rabbit_amqqueue, info_all, [VHostArg, ArgAtoms, Online, Offline]}, - ArgAtoms, Timeout); + case rabbit_cli:mutually_exclusive_flags( + Opts, all, [{?ONLINE_OPT, online} + ,{?OFFLINE_OPT, offline} + ,{?LOCAL_OPT, local}]) of + {ok, Filter} -> + Inform("Listing queues", []), + VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), + ArgAtoms = default_if_empty(Args, [name, messages]), + call(Node, {rabbit_amqqueue, info_all, [VHostArg, ArgAtoms, Filter]}, + ArgAtoms, Timeout); + {error, ErrStr} -> + {error_string, ErrStr} + end; action(list_exchanges, Node, Args, Opts, Inform, Timeout) -> Inform("Listing exchanges", []), @@ -953,6 +960,9 @@ nodes_in_cluster(Node) -> unsafe_rpc(Node, rabbit_mnesia, cluster_nodes, [running]). alarms_by_node(Name) -> - Status = unsafe_rpc(Name, rabbit, status, []), - {_, As} = lists:keyfind(alarms, 1, Status), - {Name, As}. + case rpc_call(Name, rabbit, status, []) of + {badrpc,nodedown} -> {Name, [nodedown]}; + Status -> + {_, As} = lists:keyfind(alarms, 1, Status), + {Name, As} + end. diff --git a/src/rabbit_mirror_queue_coordinator.erl b/src/rabbit_mirror_queue_coordinator.erl index 221f11f18a..562f0f0fcf 100644 --- a/src/rabbit_mirror_queue_coordinator.erl +++ b/src/rabbit_mirror_queue_coordinator.erl @@ -355,13 +355,28 @@ handle_cast({gm_deaths, DeadGMPids}, DeadPids), rabbit_mirror_queue_misc:add_mirrors(QueueName, ExtraNodes, async), noreply(State); + {ok, _MPid0, DeadPids, _ExtraNodes} -> + %% see rabbitmq-server#914; + %% Different slave is now master, stop current coordinator normally. + %% Initiating queue is now slave and the least we could do is report + %% deaths which we 'think' we saw. + %% NOTE: Reported deaths here, could be inconsistant. + rabbit_mirror_queue_misc:report_deaths(MPid, false, QueueName, + DeadPids), + {stop, shutdown, State}; {error, not_found} -> {stop, normal, State} end; -handle_cast(request_depth, State = #state { depth_fun = DepthFun }) -> - ok = DepthFun(), - noreply(State); +handle_cast(request_depth, State = #state { depth_fun = DepthFun, + q = #amqqueue { name = QName, pid = MPid }}) -> + case rabbit_amqqueue:lookup(QName) of + {ok, #amqqueue{ pid = MPid }} -> + ok = DepthFun(), + noreply(State); + _ -> + {stop, shutdown, State} + end; handle_cast({ensure_monitoring, Pids}, State = #state { monitors = Mons }) -> noreply(State #state { monitors = pmon:monitor_all(Pids, Mons) }); diff --git a/src/rabbit_mirror_queue_master.erl b/src/rabbit_mirror_queue_master.erl index d78f6180e7..d82cdf336a 100644 --- a/src/rabbit_mirror_queue_master.erl +++ b/src/rabbit_mirror_queue_master.erl @@ -101,35 +101,43 @@ init(Q, Recover, AsyncCallback) -> State. init_with_existing_bq(Q = #amqqueue{name = QName}, BQ, BQS) -> - {ok, CPid} = rabbit_mirror_queue_coordinator:start_link( - Q, undefined, sender_death_fun(), depth_fun()), - GM = rabbit_mirror_queue_coordinator:get_gm(CPid), - Self = self(), - ok = rabbit_misc:execute_mnesia_transaction( - fun () -> - [Q1 = #amqqueue{gm_pids = GMPids}] - = mnesia:read({rabbit_queue, QName}), - ok = rabbit_amqqueue:store_queue( - Q1#amqqueue{gm_pids = [{GM, Self} | GMPids], - state = live}) - end), - {_MNode, SNodes} = rabbit_mirror_queue_misc:suggested_queue_nodes(Q), - %% We need synchronous add here (i.e. do not return until the - %% slave is running) so that when queue declaration is finished - %% all slaves are up; we don't want to end up with unsynced slaves - %% just by declaring a new queue. But add can't be synchronous all - %% the time as it can be called by slaves and that's - %% deadlock-prone. - rabbit_mirror_queue_misc:add_mirrors(QName, SNodes, sync), - #state { name = QName, - gm = GM, - coordinator = CPid, - backing_queue = BQ, - backing_queue_state = BQS, - seen_status = dict:new(), - confirmed = [], - known_senders = sets:new(), - wait_timeout = rabbit_misc:get_env(rabbit, slave_wait_timeout, 15000) }. + case rabbit_mirror_queue_coordinator:start_link( + Q, undefined, sender_death_fun(), depth_fun()) of + {ok, CPid} -> + GM = rabbit_mirror_queue_coordinator:get_gm(CPid), + Self = self(), + ok = rabbit_misc:execute_mnesia_transaction( + fun () -> + [Q1 = #amqqueue{gm_pids = GMPids}] + = mnesia:read({rabbit_queue, QName}), + ok = rabbit_amqqueue:store_queue( + Q1#amqqueue{gm_pids = [{GM, Self} | GMPids], + state = live}) + end), + {_MNode, SNodes} = rabbit_mirror_queue_misc:suggested_queue_nodes(Q), + %% We need synchronous add here (i.e. do not return until the + %% slave is running) so that when queue declaration is finished + %% all slaves are up; we don't want to end up with unsynced slaves + %% just by declaring a new queue. But add can't be synchronous all + %% the time as it can be called by slaves and that's + %% deadlock-prone. + rabbit_mirror_queue_misc:add_mirrors(QName, SNodes, sync), + #state { name = QName, + gm = GM, + coordinator = CPid, + backing_queue = BQ, + backing_queue_state = BQS, + seen_status = dict:new(), + confirmed = [], + known_senders = sets:new(), + wait_timeout = rabbit_misc:get_env(rabbit, slave_wait_timeout, 15000) }; + {error, Reason} -> + %% The GM can shutdown before the coordinator has started up + %% (lost membership or missing group), thus the start_link of + %% the coordinator returns {error, shutdown} as rabbit_amqqueue_process + % is trapping exists + throw({coordinator_not_started, Reason}) + end. stop_mirroring(State = #state { coordinator = CPid, backing_queue = BQ, diff --git a/src/rabbit_mirror_queue_misc.erl b/src/rabbit_mirror_queue_misc.erl index 83350920e6..375a0366dd 100644 --- a/src/rabbit_mirror_queue_misc.erl +++ b/src/rabbit_mirror_queue_misc.erl @@ -20,7 +20,7 @@ -export([remove_from_queue/3, on_node_up/0, add_mirrors/3, report_deaths/4, store_updated_slaves/1, initial_queue_node/2, suggested_queue_nodes/1, - is_mirrored/1, update_mirrors/2, validate_policy/1, + is_mirrored/1, update_mirrors/2, update_mirrors/1, validate_policy/1, maybe_auto_sync/1, maybe_drop_master_after_sync/1, sync_batch_size/1, log_info/3, log_warning/3]). @@ -76,7 +76,7 @@ remove_from_queue(QueueName, Self, DeadGMPids) -> rabbit_misc:execute_mnesia_transaction( fun () -> %% Someone else could have deleted the queue before we - %% get here. + %% get here. Or, gm group could've altered. see rabbitmq-server#914 case mnesia:read({rabbit_queue, QueueName}) of [] -> {error, not_found}; [Q = #amqqueue { pid = QPid, @@ -90,7 +90,16 @@ remove_from_queue(QueueName, Self, DeadGMPids) -> AlivePids = [Pid || {_GM, Pid} <- AliveGM], Alive = [Pid || Pid <- [QPid | SPids], lists:member(Pid, AlivePids)], - {QPid1, SPids1} = promote_slave(Alive), + {QPid1, SPids1} = case Alive of + [] -> + %% GM altered, & if all pids are + %% perceived as dead, rather do + %% do nothing here, & trust the + %% promoted slave to have updated + %% mnesia during the alteration. + {QPid, SPids}; + _ -> promote_slave(Alive) + end, Extra = case {{QPid, SPids}, {QPid1, SPids1}} of {Same, Same} -> @@ -98,7 +107,8 @@ remove_from_queue(QueueName, Self, DeadGMPids) -> _ when QPid =:= QPid1 orelse QPid1 =:= Self -> %% Either master hasn't changed, so %% we're ok to update mnesia; or we have - %% become the master. + %% become the master. If gm altered, + %% we have no choice but to proceed. Q1 = Q#amqqueue{pid = QPid1, slave_pids = SPids1, gm_pids = AliveGM}, @@ -392,15 +402,12 @@ update_mirrors(OldQ = #amqqueue{pid = QPid}, NewQ = #amqqueue{pid = QPid}) -> case {is_mirrored(OldQ), is_mirrored(NewQ)} of {false, false} -> ok; - {true, false} -> rabbit_amqqueue:stop_mirroring(QPid); - {false, true} -> rabbit_amqqueue:start_mirroring(QPid); - {true, true} -> update_mirrors0(OldQ, NewQ) + _ -> rabbit_amqqueue:update_mirroring(QPid) end. -update_mirrors0(OldQ = #amqqueue{name = QName}, - NewQ = #amqqueue{name = QName}) -> - {OldMNode, OldSNodes, _} = actual_queue_nodes(OldQ), - {NewMNode, NewSNodes} = suggested_queue_nodes(NewQ), +update_mirrors(Q = #amqqueue{name = QName}) -> + {OldMNode, OldSNodes, _} = actual_queue_nodes(Q), + {NewMNode, NewSNodes} = suggested_queue_nodes(Q), OldNodes = [OldMNode | OldSNodes], NewNodes = [NewMNode | NewSNodes], %% When a mirror dies, remove_from_queue/2 might have to add new @@ -414,7 +421,7 @@ update_mirrors0(OldQ = #amqqueue{name = QName}, drop_mirrors(QName, OldNodes -- NewNodes), %% This is for the case where no extra nodes were added but we changed to %% a policy requiring auto-sync. - maybe_auto_sync(NewQ), + maybe_auto_sync(Q), ok. %% The arrival of a newly synced slave may cause the master to die if diff --git a/src/rabbit_mirror_queue_slave.erl b/src/rabbit_mirror_queue_slave.erl index 6f46cdc698..4770018f9e 100644 --- a/src/rabbit_mirror_queue_slave.erl +++ b/src/rabbit_mirror_queue_slave.erl @@ -225,9 +225,15 @@ handle_call({gm_deaths, DeadGMPids}, From, _ -> %% master has changed to not us gen_server2:reply(From, ok), - %% assertion, we don't need to add_mirrors/2 in this - %% branch, see last clause in remove_from_queue/2 - [] = ExtraNodes, + %% see rabbitmq-server#914; + %% It's not always guaranteed that we won't have ExtraNodes. + %% If gm alters, master can change to not us with extra nodes, + %% in which case we attempt to add mirrors on those nodes. + case ExtraNodes of + [] -> void; + _ -> rabbit_mirror_queue_misc:add_mirrors( + QName, ExtraNodes, async) + end, %% Since GM is by nature lazy we need to make sure %% there is some traffic when a master dies, to %% make sure all slaves get informed of the @@ -250,8 +256,21 @@ handle_cast(go, {not_started, Q} = NotStarted) -> handle_cast({run_backing_queue, Mod, Fun}, State) -> noreply(run_backing_queue(Mod, Fun, State)); -handle_cast({gm, Instruction}, State) -> - handle_process_result(process_instruction(Instruction, State)); +handle_cast({gm, Instruction}, State = #state{q = #amqqueue { name = QName }}) -> + case rabbit_amqqueue:lookup(QName) of + {ok, #amqqueue{slave_pids = SPids}} -> + case lists:member(self(), SPids) of + true -> + handle_process_result(process_instruction(Instruction, State)); + false -> + %% Potentially a duplicated slave caused by a partial partition, + %% will stop as a new slave could start unaware of our presence + {stop, shutdown, State} + end; + {error, not_found} -> + %% Would not expect this to happen after fixing #953 + {stop, shutdown, State} + end; handle_cast({deliver, Delivery = #delivery{sender = Sender, flow = Flow}, true}, State) -> diff --git a/src/rabbit_mirror_queue_sync.erl b/src/rabbit_mirror_queue_sync.erl index 54f0855fce..c438e91a3f 100644 --- a/src/rabbit_mirror_queue_sync.erl +++ b/src/rabbit_mirror_queue_sync.erl @@ -248,9 +248,15 @@ syncer_loop(Ref, MPid, SPids) -> syncer_loop(Ref, MPid, SPids); {msgs, Ref, Msgs} -> SPids1 = wait_for_credit(SPids), - broadcast(SPids1, {sync_msgs, Ref, Msgs}), - MPid ! {next, Ref}, - syncer_loop(Ref, MPid, SPids1); + case SPids1 of + [] -> + % Die silently because there are no slaves left. + ok; + _ -> + broadcast(SPids1, {sync_msgs, Ref, Msgs}), + MPid ! {next, Ref}, + syncer_loop(Ref, MPid, SPids1) + end; {cancel, Ref} -> %% We don't tell the slaves we will die - so when we do %% they interpret that as a failure, which is what we diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl index 26a864f0f5..596eb62b03 100644 --- a/src/rabbit_mnesia.erl +++ b/src/rabbit_mnesia.erl @@ -58,7 +58,7 @@ %% Main interface -spec init() -> 'ok'. -spec join_cluster(node(), node_type()) - -> 'ok' | {'ok', 'already_member'}. + -> ok | {ok, already_member} | {error, {inconsistent_cluster, string()}}. -spec reset() -> 'ok'. -spec force_reset() -> 'ok'. -spec update_cluster_nodes(node()) -> 'ok'. diff --git a/src/rabbit_node_monitor.erl b/src/rabbit_node_monitor.erl index 0322aacfd1..bea2a3fa96 100644 --- a/src/rabbit_node_monitor.erl +++ b/src/rabbit_node_monitor.erl @@ -336,7 +336,17 @@ init([]) -> process_flag(trap_exit, true), net_kernel:monitor_nodes(true, [nodedown_reason]), {ok, _} = mnesia:subscribe(system), - {ok, ensure_keepalive_timer(#state{monitors = pmon:new(), + %% If the node has been restarted, Mnesia can trigger a system notification + %% before the monitor subscribes to receive them. To avoid autoheal blocking due to + %% the inconsistent database event never arriving, we being monitoring all running + %% nodes as early as possible. The rest of the monitoring ops will only be triggered + %% when notifications arrive. + Nodes = possibly_partitioned_nodes(), + startup_log(Nodes), + Monitors = lists:foldl(fun(Node, Monitors0) -> + pmon:monitor({rabbit, Node}, Monitors0) + end, pmon:new(), Nodes), + {ok, ensure_keepalive_timer(#state{monitors = Monitors, subscribers = pmon:new(), partitions = [], guid = rabbit_guid:gen(), @@ -486,20 +496,22 @@ handle_cast({partial_partition_disconnect, Other}, State) -> %% mnesia propagation. handle_cast({node_up, Node, NodeType}, State = #state{monitors = Monitors}) -> - case pmon:is_monitored({rabbit, Node}, Monitors) of - true -> {noreply, State}; - false -> rabbit_log:info("rabbit on node ~p up~n", [Node]), - {AllNodes, DiscNodes, RunningNodes} = read_cluster_status(), - write_cluster_status({add_node(Node, AllNodes), - case NodeType of - disc -> add_node(Node, DiscNodes); - ram -> DiscNodes - end, - add_node(Node, RunningNodes)}), - ok = handle_live_rabbit(Node), - Monitors1 = pmon:monitor({rabbit, Node}, Monitors), - {noreply, maybe_autoheal(State#state{monitors = Monitors1})} - end; + rabbit_log:info("rabbit on node ~p up~n", [Node]), + {AllNodes, DiscNodes, RunningNodes} = read_cluster_status(), + write_cluster_status({add_node(Node, AllNodes), + case NodeType of + disc -> add_node(Node, DiscNodes); + ram -> DiscNodes + end, + add_node(Node, RunningNodes)}), + ok = handle_live_rabbit(Node), + Monitors1 = case pmon:is_monitored({rabbit, Node}, Monitors) of + true -> + Monitors; + false -> + pmon:monitor({rabbit, Node}, Monitors) + end, + {noreply, maybe_autoheal(State#state{monitors = Monitors1})}; handle_cast({joined_cluster, Node, NodeType}, State) -> {AllNodes, DiscNodes, RunningNodes} = read_cluster_status(), @@ -572,7 +584,7 @@ handle_info({mnesia_system_event, State1 = case pmon:is_monitored({rabbit, Node}, Monitors) of true -> State; false -> State#state{ - monitors = pmon:monitor({rabbit, Node}, Monitors)} + monitors = pmon:monitor({rabbit, Node}, Monitors)} end, ok = handle_live_rabbit(Node), Partitions1 = lists:usort([Node | Partitions]), @@ -873,3 +885,12 @@ alive_rabbit_nodes(Nodes) -> ping_all() -> [net_adm:ping(N) || N <- rabbit_mnesia:cluster_nodes(all)], ok. + +possibly_partitioned_nodes() -> + alive_rabbit_nodes() -- rabbit_mnesia:cluster_nodes(running). + +startup_log([]) -> + rabbit_log:info("Starting rabbit_node_monitor~n", []); +startup_log(Nodes) -> + rabbit_log:info("Starting rabbit_node_monitor, might be partitioned from ~p~n", + [Nodes]). diff --git a/src/rabbit_policy.erl b/src/rabbit_policy.erl index eb8cf63327..a9caadf972 100644 --- a/src/rabbit_policy.erl +++ b/src/rabbit_policy.erl @@ -276,7 +276,9 @@ update_queue(Q = #amqqueue{name = QName, policy = OldPolicy}, Policies) -> NewPolicy -> case rabbit_amqqueue:update( QName, fun(Q1) -> rabbit_queue_decorator:set( - Q1#amqqueue{policy = NewPolicy}) + Q1#amqqueue{policy = NewPolicy, + policy_version = + Q1#amqqueue.policy_version + 1 }) end) of #amqqueue{} = Q1 -> {Q, Q1}; not_found -> {Q, Q } diff --git a/src/rabbit_queue_location_validator.erl b/src/rabbit_queue_location_validator.erl index 44394a962c..c5aad50e64 100644 --- a/src/rabbit_queue_location_validator.erl +++ b/src/rabbit_queue_location_validator.erl @@ -26,7 +26,9 @@ {mfa, {rabbit_registry, register, [policy_validator, <<"queue-master-locator">>, - ?MODULE]}}]}). + ?MODULE]}}, + {requires, rabbit_registry}, + {enables, recovery}]}). validate_policy(KeyList) -> case proplists:lookup(<<"queue-master-locator">> , KeyList) of diff --git a/src/rabbit_upgrade_functions.erl b/src/rabbit_upgrade_functions.erl index a49f7a5893..1b647f9c05 100644 --- a/src/rabbit_upgrade_functions.erl +++ b/src/rabbit_upgrade_functions.erl @@ -52,6 +52,7 @@ -rabbit_upgrade({down_slave_nodes, mnesia, [queue_decorators]}). -rabbit_upgrade({queue_state, mnesia, [down_slave_nodes]}). -rabbit_upgrade({recoverable_slaves, mnesia, [queue_state]}). +-rabbit_upgrade({policy_version, mnesia, [recoverable_slaves]}). -rabbit_upgrade({user_password_hashing, mnesia, [hash_passwords]}). %% ------------------------------------------------------------------- @@ -443,6 +444,24 @@ recoverable_slaves(Table) -> sync_slave_pids, recoverable_slaves, policy, gm_pids, decorators, state]). +policy_version() -> + ok = policy_version(rabbit_queue), + ok = policy_version(rabbit_durable_queue). + +policy_version(Table) -> + transform( + Table, + fun ({amqqueue, Name, Durable, AutoDelete, ExclusiveOwner, Arguments, + Pid, SlavePids, SyncSlavePids, DSN, Policy, GmPids, Decorators, + State}) -> + {amqqueue, Name, Durable, AutoDelete, ExclusiveOwner, Arguments, + Pid, SlavePids, SyncSlavePids, DSN, Policy, GmPids, Decorators, + State, 0} + end, + [name, durable, auto_delete, exclusive_owner, arguments, pid, slave_pids, + sync_slave_pids, recoverable_slaves, policy, gm_pids, decorators, state, + policy_version]). + %% Prior to 3.6.0, passwords were hashed using MD5, this populates %% existing records with said default. Users created with 3.6.0+ will %% have internal_user.hashing_algorithm populated by the internal diff --git a/src/rabbit_variable_queue.erl b/src/rabbit_variable_queue.erl index 9ad752a174..297df086ad 100644 --- a/src/rabbit_variable_queue.erl +++ b/src/rabbit_variable_queue.erl @@ -939,7 +939,7 @@ convert_to_lazy(State) -> %% is not in a proper state for a lazy BQ (unless all %% messages have been paged to disk already). wait_for_msg_store_credit(), - convert_to_lazy(State1) + convert_to_lazy(resume(State1)) end. wait_for_msg_store_credit() -> diff --git a/test/dynamic_ha_SUITE.erl b/test/dynamic_ha_SUITE.erl index 5872d97d4c..bba7fad707 100644 --- a/test/dynamic_ha_SUITE.erl +++ b/test/dynamic_ha_SUITE.erl @@ -31,6 +31,7 @@ %% The first two are change_policy, the last two are change_cluster -include_lib("common_test/include/ct.hrl"). +-include_lib("proper/include/proper.hrl"). -include_lib("eunit/include/eunit.hrl"). -include_lib("amqp_client/include/amqp_client.hrl"). @@ -61,6 +62,10 @@ groups() -> {cluster_size_3, [], [ change_policy, rapid_change + % FIXME: Re-enable those tests when the know issues are + % fixed. + %failing_random_policies, + %random_policy ]} ]} ]. @@ -137,7 +142,7 @@ change_policy(Config) -> assert_slaves(A, ?QNAME, {A, [C]}, [{A, [B, C]}]), %% Clear the policy, and we go back to non-mirrored - rabbit_ct_broker_helpers:clear_policy(Config, A, ?POLICY), + ok = rabbit_ct_broker_helpers:clear_policy(Config, A, ?POLICY), assert_slaves(A, ?QNAME, {A, ''}), %% Test switching "away" from an unmirrored node @@ -206,7 +211,7 @@ rapid_loop(Config, Node, MRef) -> after 0 -> rabbit_ct_broker_helpers:set_ha_policy(Config, Node, ?POLICY, <<"all">>), - rabbit_ct_broker_helpers:clear_policy(Config, Node, ?POLICY), + ok = rabbit_ct_broker_helpers:clear_policy(Config, Node, ?POLICY), rapid_loop(Config, Node, MRef) end. @@ -253,6 +258,23 @@ promote_on_shutdown(Config) -> durable = true}), ok. +random_policy(Config) -> + run_proper(fun prop_random_policy/1, [Config]). + +failing_random_policies(Config) -> + [A, B | _] = Nodes = rabbit_ct_broker_helpers:get_node_configs(Config, + nodename), + %% Those set of policies were found as failing by PropEr in the + %% `random_policy` test above. We add them explicitely here to make + %% sure they get tested. + ?assertEqual(true, test_random_policy(Config, Nodes, + [{nodes, [A, B]}, {nodes, [A]}])), + ?assertEqual(true, test_random_policy(Config, Nodes, + [{exactly, 3}, undefined, all, {nodes, [B]}])), + ?assertEqual(true, test_random_policy(Config, Nodes, + [all, undefined, {exactly, 2}, all, {exactly, 3}, {exactly, 3}, + undefined, {exactly, 3}, all])). + %%---------------------------------------------------------------------------- assert_slaves(RPCNode, QName, Exp) -> @@ -327,3 +349,131 @@ get_stacktrace() -> _:e -> erlang:get_stacktrace() end. + +%%---------------------------------------------------------------------------- +run_proper(Fun, Args) -> + ?assertEqual(true, + proper:counterexample(erlang:apply(Fun, Args), + [{numtests, 25}, + {on_output, fun(F, A) -> ct:pal(?LOW_IMPORTANCE, F, A) end}])). + +prop_random_policy(Config) -> + Nodes = rabbit_ct_broker_helpers:get_node_configs( + Config, nodename), + ?FORALL( + Policies, non_empty(list(policy_gen(Nodes))), + test_random_policy(Config, Nodes, Policies)). + +test_random_policy(Config, Nodes, Policies) -> + [NodeA | _] = Nodes, + Ch = rabbit_ct_client_helpers:open_channel(Config, NodeA), + amqp_channel:call(Ch, #'queue.declare'{queue = ?QNAME}), + %% Add some load so mirrors can be busy synchronising + rabbit_ct_client_helpers:publish(Ch, ?QNAME, 100000), + %% Apply policies in parallel on all nodes + apply_in_parallel(Config, Nodes, Policies), + %% Give it some time to generate all internal notifications + timer:sleep(2000), + %% Check the result + Result = wait_for_last_policy(?QNAME, NodeA, Policies, 30), + %% Cleanup + amqp_channel:call(Ch, #'queue.delete'{queue = ?QNAME}), + _ = rabbit_ct_broker_helpers:clear_policy(Config, NodeA, ?POLICY), + Result. + +apply_in_parallel(Config, Nodes, Policies) -> + Self = self(), + [spawn_link(fun() -> + [begin + apply_policy(Config, N, Policy) + end || Policy <- Policies], + Self ! parallel_task_done + end) || N <- Nodes], + [receive + parallel_task_done -> + ok + end || _ <- Nodes]. + +%% Proper generators +policy_gen(Nodes) -> + %% Stop mirroring needs to be called often to trigger rabbitmq-server#803 + frequency([{3, undefined}, + {1, all}, + {1, {nodes, nodes_gen(Nodes)}}, + {1, {exactly, choose(1, 3)}} + ]). + +nodes_gen(Nodes) -> + ?LET(List, non_empty(list(oneof(Nodes))), + sets:to_list(sets:from_list(List))). + +%% Checks +wait_for_last_policy(QueueName, NodeA, TestedPolicies, Tries) -> + %% Ensure the owner/master is able to process a call request, + %% which means that all pending casts have been processed. + %% Use the information returned by owner/master to verify the + %% test result + Info = find_queue(QueueName, NodeA), + Pid = proplists:get_value(pid, Info), + Node = node(Pid), + %% Gets owner/master + case rpc:call(Node, gen_server, call, [Pid, info], 5000) of + {badrpc, _} -> + %% The queue is probably being migrated to another node. + %% Let's wait a bit longer. + timer:sleep(1000), + wait_for_last_policy(QueueName, NodeA, TestedPolicies, Tries - 1); + FinalInfo -> + %% The last policy is the final state + LastPolicy = lists:last(TestedPolicies), + case verify_policy(LastPolicy, FinalInfo) of + true -> + true; + false when Tries =:= 1 -> + Policies = rpc:call(Node, rabbit_policy, list, [], 5000), + ct:pal( + "Last policy not applied:~n" + " Queue node: ~s (~p)~n" + " Queue info: ~p~n" + " Configured policies: ~p~n" + " Tested policies: ~p", + [Node, Pid, FinalInfo, Policies, TestedPolicies]), + false; + false -> + timer:sleep(1000), + wait_for_last_policy(QueueName, NodeA, TestedPolicies, + Tries - 1) + end + end. + +verify_policy(undefined, Info) -> + %% If the queue is not mirrored, it returns '' + '' == proplists:get_value(slave_pids, Info); +verify_policy(all, Info) -> + 2 == length(proplists:get_value(slave_pids, Info)); +verify_policy({exactly, 1}, Info) -> + %% If the queue is mirrored, it returns a list + [] == proplists:get_value(slave_pids, Info); +verify_policy({exactly, N}, Info) -> + (N - 1) == length(proplists:get_value(slave_pids, Info)); +verify_policy({nodes, Nodes}, Info) -> + Master = node(proplists:get_value(pid, Info)), + Slaves = [node(P) || P <- proplists:get_value(slave_pids, Info)], + lists:sort(Nodes) == lists:sort([Master | Slaves]). + +%% Policies +apply_policy(Config, N, undefined) -> + _ = rabbit_ct_broker_helpers:clear_policy(Config, N, ?POLICY); +apply_policy(Config, N, all) -> + rabbit_ct_broker_helpers:set_ha_policy( + Config, N, ?POLICY, <<"all">>, + [{<<"ha-sync-mode">>, <<"automatic">>}]); +apply_policy(Config, N, {nodes, Nodes}) -> + NNodes = [rabbit_misc:atom_to_binary(Node) || Node <- Nodes], + rabbit_ct_broker_helpers:set_ha_policy( + Config, N, ?POLICY, {<<"nodes">>, NNodes}, + [{<<"ha-sync-mode">>, <<"automatic">>}]); +apply_policy(Config, N, {exactly, Exactly}) -> + rabbit_ct_broker_helpers:set_ha_policy( + Config, N, ?POLICY, {<<"exactly">>, Exactly}, + [{<<"ha-sync-mode">>, <<"automatic">>}]). diff --git a/test/gm_SUITE.erl b/test/gm_SUITE.erl index f5ccf75b70..df73d8ac27 100644 --- a/test/gm_SUITE.erl +++ b/test/gm_SUITE.erl @@ -38,7 +38,9 @@ all() -> broadcast, confirmed_broadcast, member_death, - receive_in_order + receive_in_order, + unexpected_msg, + down_in_members_change ]. init_per_suite(Config) -> @@ -114,6 +116,49 @@ receive_in_order(_Config) -> passed end). +unexpected_msg(_Config) -> + passed = with_two_members( + fun(Pid, _) -> + Pid ! {make_ref(), old_gen_server_answer}, + true = erlang:is_process_alive(Pid), + passed + end). + +down_in_members_change(_Config) -> + %% Setup + ok = gm:create_tables(), + {ok, Pid} = gm:start_link(?MODULE, ?MODULE, self(), + fun rabbit_misc:execute_mnesia_transaction/1), + passed = receive_joined(Pid, [Pid], timeout_joining_gm_group_1), + {ok, Pid2} = gm:start_link(?MODULE, ?MODULE, self(), + fun rabbit_misc:execute_mnesia_transaction/1), + passed = receive_joined(Pid2, [Pid, Pid2], timeout_joining_gm_group_2), + passed = receive_birth(Pid, Pid2, timeout_waiting_for_birth_2), + + %% Test. Simulate that the gm group is deleted (forget_group) while + %% processing the 'DOWN' message from the neighbour + process_flag(trap_exit, true), + ok = meck:new(mnesia, [passthrough]), + ok = meck:expect(mnesia, read, fun({gm_group, ?MODULE}) -> + []; + (Key) -> + meck:passthrough([Key]) + end), + gm:leave(Pid2), + Passed = receive + {'EXIT', Pid, shutdown} -> + passed; + {'EXIT', Pid, _} -> + crashed + after 15000 -> + timeout + end, + %% Cleanup + meck:unload(mnesia), + process_flag(trap_exit, false), + passed = Passed. + + do_broadcast(Fun) -> with_two_members(broadcast_fun(Fun)). diff --git a/test/health_check_SUITE.erl b/test/health_check_SUITE.erl index 4d8f56e9d3..50abc97a02 100644 --- a/test/health_check_SUITE.erl +++ b/test/health_check_SUITE.erl @@ -33,6 +33,8 @@ ,ignores_remote_alarms/1 ,detects_local_alarm/1 ,honors_timeout_argument/1 + ,detects_stuck_local_node_monitor/1 + ,ignores_stuck_remote_node_monitor/1 ]). all() -> @@ -47,6 +49,8 @@ groups() -> ,ignores_remote_alarms ,detects_local_alarm ,honors_timeout_argument + ,detects_stuck_local_node_monitor + ,ignores_stuck_remote_node_monitor ]}]. init_per_suite(Config) -> @@ -123,6 +127,21 @@ detects_local_alarm(Config) -> {match, _} = re:run(Str, "resource alarm.*in effect"), ok. +detects_stuck_local_node_monitor(Config) -> + [A|_] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), + rabbit_ct_broker_helpers:rpc(Config, A, sys, suspend, [rabbit_node_monitor]), + {error, 75, Str} = rabbit_ct_broker_helpers:rabbitmqctl(Config, A, ["-t", "5", "node_health_check"]), + {match, _} = re:run(Str, "operation node_health_check.*timed out"), + resume_sys_process(Config, A, rabbit_node_monitor), + ok. + +ignores_stuck_remote_node_monitor(Config) -> + [A, B] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), + rabbit_ct_broker_helpers:rpc(Config, A, sys, suspend, [rabbit_node_monitor]), + {ok, _} = rabbit_ct_broker_helpers:rabbitmqctl(Config, B, ["-t", "5", "node_health_check"]), + resume_sys_process(Config, A, rabbit_node_monitor), + ok. + honors_timeout_argument(Config) -> [A|_] = open_channel_and_declare_queue_everywhere(Config), QPid = suspend_single_queue(Config, A), diff --git a/test/inet_proxy_dist.erl b/test/inet_proxy_dist.erl deleted file mode 100644 index 32b7641a79..0000000000 --- a/test/inet_proxy_dist.erl +++ /dev/null @@ -1,201 +0,0 @@ -%% The contents of this file are subject to the Mozilla Public License -%% Version 1.1 (the "License"); you may not use this file except in -%% compliance with the License. You may obtain a copy of the License -%% at http://www.mozilla.org/MPL/ -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and -%% limitations under the License. -%% -%% The Original Code is RabbitMQ. -%% -%% The Initial Developer of the Original Code is GoPivotal, Inc. -%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved. -%% --module(inet_proxy_dist). - -%% A distribution plugin that uses the usual inet_tcp_dist but allows -%% insertion of a proxy at the receiving end. - -%% inet_*_dist "behaviour" --export([listen/1, accept/1, accept_connection/5, - setup/5, close/1, select/1, is_node_name/1]). - -%% For copypasta from inet_tcp_dist --export([do_setup/6]). --import(error_logger,[error_msg/2]). - --define(REAL, inet_tcp_dist). - -%%---------------------------------------------------------------------------- - -listen(Name) -> ?REAL:listen(Name). -select(Node) -> ?REAL:select(Node). -accept(Listen) -> ?REAL:accept(Listen). -close(Socket) -> ?REAL:close(Socket). -is_node_name(Node) -> ?REAL:is_node_name(Node). - -accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) -> - ?REAL:accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime). - -%% This is copied from inet_tcp_dist, in order to change the -%% output of erl_epmd:port_please/2. - --include_lib("kernel/include/net_address.hrl"). --include_lib("kernel/include/dist_util.hrl"). - -setup(Node, Type, MyNode, LongOrShortNames,SetupTime) -> - spawn_opt(?MODULE, do_setup, - [self(), Node, Type, MyNode, LongOrShortNames, SetupTime], - [link, {priority, max}]). - -do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) -> - ?trace("~p~n",[{inet_tcp_dist,self(),setup,Node}]), - [Name, Address] = splitnode(Node, LongOrShortNames), - case inet:getaddr(Address, inet) of - {ok, Ip} -> - Timer = dist_util:start_timer(SetupTime), - case erl_epmd:port_please(Name, Ip) of - {port, TcpPort, Version} -> - ?trace("port_please(~p) -> version ~p~n", - [Node,Version]), - dist_util:reset_timer(Timer), - %% Modification START - Ret = application:get_env(kernel, - dist_and_proxy_ports_map), - PortsMap = case Ret of - {ok, M} -> M; - undefined -> [] - end, - ProxyPort = case inet_tcp_proxy:is_enabled() of - true -> proplists:get_value(TcpPort, PortsMap, TcpPort); - false -> TcpPort - end, - case inet_tcp:connect(Ip, ProxyPort, - [{active, false}, - {packet,2}]) of - {ok, Socket} -> - {ok, {_, SrcPort}} = inet:sockname(Socket), - ok = inet_tcp_proxy_manager:register( - node(), Node, SrcPort, TcpPort, ProxyPort), - %% Modification END - HSData = #hs_data{ - kernel_pid = Kernel, - other_node = Node, - this_node = MyNode, - socket = Socket, - timer = Timer, - this_flags = 0, - other_version = Version, - f_send = fun inet_tcp:send/2, - f_recv = fun inet_tcp:recv/3, - f_setopts_pre_nodeup = - fun(S) -> - inet:setopts - (S, - [{active, false}, - {packet, 4}, - nodelay()]) - end, - f_setopts_post_nodeup = - fun(S) -> - inet:setopts - (S, - [{active, true}, - {deliver, port}, - {packet, 4}, - nodelay()]) - end, - f_getll = fun inet:getll/1, - f_address = - fun(_,_) -> - #net_address{ - address = {Ip,TcpPort}, - host = Address, - protocol = tcp, - family = inet} - end, - mf_tick = fun tick/1, - mf_getstat = fun inet_tcp_dist:getstat/1, - request_type = Type - }, - dist_util:handshake_we_started(HSData); - R -> - io:format("~p failed! ~p~n", [node(), R]), - %% Other Node may have closed since - %% port_please ! - ?trace("other node (~p) " - "closed since port_please.~n", - [Node]), - ?shutdown(Node) - end; - _ -> - ?trace("port_please (~p) " - "failed.~n", [Node]), - ?shutdown(Node) - end; - _Other -> - ?trace("inet_getaddr(~p) " - "failed (~p).~n", [Node,_Other]), - ?shutdown(Node) - end. - -%% If Node is illegal terminate the connection setup!! -splitnode(Node, LongOrShortNames) -> - case split_node(atom_to_list(Node), $@, []) of - [Name|Tail] when Tail =/= [] -> - Host = lists:append(Tail), - case split_node(Host, $., []) of - [_] when LongOrShortNames =:= longnames -> - error_msg("** System running to use " - "fully qualified " - "hostnames **~n" - "** Hostname ~s is illegal **~n", - [Host]), - ?shutdown(Node); - L when length(L) > 1, LongOrShortNames =:= shortnames -> - error_msg("** System NOT running to use fully qualified " - "hostnames **~n" - "** Hostname ~s is illegal **~n", - [Host]), - ?shutdown(Node); - _ -> - [Name, Host] - end; - [_] -> - error_msg("** Nodename ~p illegal, no '@' character **~n", - [Node]), - ?shutdown(Node); - _ -> - error_msg("** Nodename ~p illegal **~n", [Node]), - ?shutdown(Node) - end. - -split_node([Chr|T], Chr, Ack) -> [lists:reverse(Ack)|split_node(T, Chr, [])]; -split_node([H|T], Chr, Ack) -> split_node(T, Chr, [H|Ack]); -split_node([], _, Ack) -> [lists:reverse(Ack)]. - -%% we may not always want the nodelay behaviour -%% for performance reasons - -nodelay() -> - case application:get_env(kernel, dist_nodelay) of - undefined -> - {nodelay, true}; - {ok, true} -> - {nodelay, true}; - {ok, false} -> - {nodelay, false}; - _ -> - {nodelay, true} - end. - -tick(Socket) -> - case inet_tcp:send(Socket, [], [force]) of - {error, closed} -> - self() ! {tcp_closed, Socket}, - {error, closed}; - R -> - R - end. diff --git a/test/inet_tcp_proxy.erl b/test/inet_tcp_proxy.erl deleted file mode 100644 index 4498b8f952..0000000000 --- a/test/inet_tcp_proxy.erl +++ /dev/null @@ -1,134 +0,0 @@ -%% The contents of this file are subject to the Mozilla Public License -%% Version 1.1 (the "License"); you may not use this file except in -%% compliance with the License. You may obtain a copy of the License -%% at http://www.mozilla.org/MPL/ -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and -%% limitations under the License. -%% -%% The Original Code is RabbitMQ. -%% -%% The Initial Developer of the Original Code is GoPivotal, Inc. -%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved. -%% --module(inet_tcp_proxy). - -%% A TCP proxy for insertion into the Erlang distribution mechanism, -%% which allows us to simulate network partitions. - --export([start/3, reconnect/1, is_enabled/0, allow/1, block/1]). - --define(TABLE, ?MODULE). - -%% This can't start_link because there's no supervision hierarchy we -%% can easily fit it into (we need to survive all application -%% restarts). So we have to do some horrible error handling. - -start(ManagerNode, DistPort, ProxyPort) -> - application:set_env(kernel, inet_tcp_proxy_manager_node, ManagerNode), - Parent = self(), - Pid = spawn(error_handler(fun() -> go(Parent, DistPort, ProxyPort) end)), - MRef = erlang:monitor(process, Pid), - receive - ready -> - erlang:demonitor(MRef), - ok; - {'DOWN', MRef, _, _, Reason} -> - {error, Reason} - end. - -reconnect(Nodes) -> - [erlang:disconnect_node(N) || N <- Nodes, N =/= node()], - ok. - -is_enabled() -> - lists:member(?TABLE, ets:all()). - -allow(Node) -> - rabbit_log:info("(~s) Allowing distribution between ~s and ~s~n", - [?MODULE, node(), Node]), - ets:delete(?TABLE, Node). -block(Node) -> - rabbit_log:info("(~s) BLOCKING distribution between ~s and ~s~n", - [?MODULE, node(), Node]), - ets:insert(?TABLE, {Node, block}). - -%%---------------------------------------------------------------------------- - -error_handler(Thunk) -> - fun () -> - try - Thunk() - catch _:{{nodedown, _}, _} -> - %% The only other node we ever talk to is the test - %% runner; if that's down then the test is nearly - %% over; die quietly. - ok; - _:X -> - io:format(user, "TCP proxy died with ~p~n At ~p~n", - [X, erlang:get_stacktrace()]), - erlang:halt(1) - end - end. - -go(Parent, Port, ProxyPort) -> - ets:new(?TABLE, [public, named_table]), - {ok, Sock} = gen_tcp:listen(ProxyPort, [inet, - {reuseaddr, true}]), - Parent ! ready, - accept_loop(Sock, Port). - -accept_loop(ListenSock, Port) -> - {ok, Sock} = gen_tcp:accept(ListenSock), - Proxy = spawn(error_handler(fun() -> run_it(Sock, Port) end)), - ok = gen_tcp:controlling_process(Sock, Proxy), - accept_loop(ListenSock, Port). - -run_it(SockIn, Port) -> - case {inet:peername(SockIn), inet:sockname(SockIn)} of - {{ok, {_Addr, SrcPort}}, {ok, {Addr, _OtherPort}}} -> - {ok, Remote, This} = inet_tcp_proxy_manager:lookup(SrcPort), - case node() of - This -> ok; - _ -> exit({not_me, node(), This}) - end, - {ok, SockOut} = gen_tcp:connect(Addr, Port, [inet]), - run_loop({SockIn, SockOut}, Remote, []); - _ -> - ok - end. - -run_loop(Sockets, RemoteNode, Buf0) -> - Block = [{RemoteNode, block}] =:= ets:lookup(?TABLE, RemoteNode), - receive - {tcp, Sock, Data} -> - Buf = [Data | Buf0], - case {Block, get(dist_was_blocked)} of - {true, false} -> - put(dist_was_blocked, Block), - rabbit_log:warning( - "(~s) Distribution BLOCKED between ~s and ~s~n", - [?MODULE, node(), RemoteNode]); - {false, S} when S =:= true orelse S =:= undefined -> - put(dist_was_blocked, Block), - rabbit_log:warning( - "(~s) Distribution allowed between ~s and ~s~n", - [?MODULE, node(), RemoteNode]); - _ -> - ok - end, - case Block of - false -> gen_tcp:send(other(Sock, Sockets), lists:reverse(Buf)), - run_loop(Sockets, RemoteNode, []); - true -> run_loop(Sockets, RemoteNode, Buf) - end; - {tcp_closed, Sock} -> - gen_tcp:close(other(Sock, Sockets)); - X -> - exit({weirdness, X}) - end. - -other(A, {A, B}) -> B; -other(B, {A, B}) -> A. diff --git a/test/inet_tcp_proxy_manager.erl b/test/inet_tcp_proxy_manager.erl deleted file mode 100644 index 18255b8d48..0000000000 --- a/test/inet_tcp_proxy_manager.erl +++ /dev/null @@ -1,107 +0,0 @@ -%% The contents of this file are subject to the Mozilla Public License -%% Version 1.1 (the "License"); you may not use this file except in -%% compliance with the License. You may obtain a copy of the License -%% at http://www.mozilla.org/MPL/ -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and -%% limitations under the License. -%% -%% The Original Code is RabbitMQ. -%% -%% The Initial Developer of the Original Code is GoPivotal, Inc. -%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved. -%% --module(inet_tcp_proxy_manager). - -%% The TCP proxies need to decide whether to block based on the node -%% they're running on, and the node connecting to them. The trouble -%% is, they don't have an easy way to determine the latter. Therefore -%% when A connects to B we register the source port used by A here, so -%% that B can later look it up and find out who A is without having to -%% sniff the distribution protocol. -%% -%% That does unfortunately mean that we need a central control -%% thing. We assume here it's running on the node called -%% 'standalone_test' since that's where tests are orchestrated from. -%% -%% Yes, this leaks. For its intended lifecycle, that's fine. - --behaviour(gen_server). - --export([start/0, register/5, lookup/1]). - --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, - code_change/3]). - --define(NODE, ct). - --record(state, {ports, pending}). - -start() -> - gen_server:start({local, ?MODULE}, ?MODULE, [], []). - -register(_From, _To, _SrcPort, Port, Port) -> - %% No proxy, don't register - ok; -register(From, To, SrcPort, _Port, _ProxyPort) -> - gen_server:call(name(), {register, From, To, SrcPort}, infinity). - -lookup(SrcPort) -> - gen_server:call(name(), {lookup, SrcPort}, infinity). - -controller_node() -> - {ok, ManagerNode} = application:get_env(kernel, - inet_tcp_proxy_manager_node), - ManagerNode. - -name() -> - {?MODULE, controller_node()}. - -%%---------------------------------------------------------------------------- - -init([]) -> - net_kernel:monitor_nodes(true), - {ok, #state{ports = dict:new(), - pending = []}}. - -handle_call({register, FromNode, ToNode, SrcPort}, _From, - State = #state{ports = Ports, - pending = Pending}) -> - {Notify, Pending2} = - lists:partition(fun ({P, _}) -> P =:= SrcPort end, Pending), - [gen_server:reply(From, {ok, FromNode, ToNode}) || {_, From} <- Notify], - {reply, ok, - State#state{ports = dict:store(SrcPort, {FromNode, ToNode}, Ports), - pending = Pending2}}; - -handle_call({lookup, SrcPort}, From, - State = #state{ports = Ports, pending = Pending}) -> - case dict:find(SrcPort, Ports) of - {ok, {FromNode, ToNode}} -> - {reply, {ok, FromNode, ToNode}, State}; - error -> - {noreply, State#state{pending = [{SrcPort, From} | Pending]}} - end; - -handle_call(_Req, _From, State) -> - {reply, unknown_request, State}. - -handle_cast(_C, State) -> - {noreply, State}. - -handle_info({nodedown, Node}, State = #state{ports = Ports}) -> - Ports1 = dict:filter( - fun (_, {From, To}) -> - Node =/= From andalso Node =/= To - end, Ports), - {noreply, State#state{ports = Ports1}}; - -handle_info(_I, State) -> - {noreply, State}. - -terminate(_Reason, _State) -> - ok. - -code_change(_, State, _) -> {ok, State}. diff --git a/test/partitions_SUITE.erl b/test/partitions_SUITE.erl index 1b901b5940..aa1c1df24f 100644 --- a/test/partitions_SUITE.erl +++ b/test/partitions_SUITE.erl @@ -45,6 +45,8 @@ groups() -> {cluster_size_3, [], [ autoheal, autoheal_after_pause_if_all_down, + autoheal_multiple_partial_partitions, + autoheal_unexpected_finish, ignore, pause_if_all_down_on_blocked, pause_if_all_down_on_down, @@ -307,6 +309,27 @@ do_autoheal(Config) -> Test([{A, B}, {A, C}, {B, C}]), ok. +autoheal_multiple_partial_partitions(Config) -> + set_mode(Config, autoheal), + [A, B, C] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), + block_unblock([{A, B}]), + block_unblock([{A, C}]), + block_unblock([{A, B}]), + block_unblock([{A, C}]), + block_unblock([{A, B}]), + block_unblock([{A, C}]), + [await_listening(N, true) || N <- [A, B, C]], + [await_partitions(N, []) || N <- [A, B, C]], + ok. + +autoheal_unexpected_finish(Config) -> + set_mode(Config, autoheal), + [A, B, _C] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), + Pid = rpc:call(A, erlang, whereis, [rabbit_node_monitor]), + Pid ! {autoheal_msg, {autoheal_finished, B}}, + Pid = rpc:call(A, erlang, whereis, [rabbit_node_monitor]), + ok. + partial_false_positive(Config) -> [A, B, C] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), block([{A, B}]), diff --git a/test/rabbitmqctl_integration_SUITE.erl b/test/rabbitmqctl_integration_SUITE.erl new file mode 100644 index 0000000000..9305781bda --- /dev/null +++ b/test/rabbitmqctl_integration_SUITE.erl @@ -0,0 +1,146 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License +%% at http://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and +%% limitations under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is GoPivotal, Inc. +%% Copyright (c) 2016 Pivotal Software, Inc. All rights reserved. +%% +-module(rabbitmqctl_integration_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("amqp_client/include/amqp_client.hrl"). + +-export([all/0 + ,groups/0 + ,init_per_suite/1 + ,end_per_suite/1 + ,init_per_group/2 + ,end_per_group/2 + ,init_per_testcase/2 + ,end_per_testcase/2 + ]). + +-export([list_queues_local/1 + ,list_queues_offline/1 + ,list_queues_online/1 + ]). + +all() -> + [{group, list_queues}]. + +groups() -> + [{list_queues, [], + [list_queues_local + ,list_queues_online + ,list_queues_offline + ]}]. + +init_per_suite(Config) -> + rabbit_ct_helpers:log_environment(), + rabbit_ct_helpers:run_setup_steps(Config). + +end_per_suite(Config) -> + rabbit_ct_helpers:run_teardown_steps(Config). + +init_per_group(list_queues, Config0) -> + NumNodes = 3, + Config = create_n_node_cluster(Config0, NumNodes), + Config1 = declare_some_queues(Config), + rabbit_ct_broker_helpers:stop_node(Config1, NumNodes - 1), + Config1; +init_per_group(_, Config) -> + Config. + +create_n_node_cluster(Config0, NumNodes) -> + Config1 = rabbit_ct_helpers:set_config( + Config0, [{rmq_nodes_count, NumNodes}, + {rmq_nodes_clustered, true}]), + rabbit_ct_helpers:run_steps(Config1, + rabbit_ct_broker_helpers:setup_steps() ++ + rabbit_ct_client_helpers:setup_steps()). + +declare_some_queues(Config) -> + Nodes = rabbit_ct_helpers:get_config(Config, rmq_nodes), + PerNodeQueues = [ declare_some_queues(Config, NodeNum) + || NodeNum <- lists:seq(0, length(Nodes)-1) ], + rabbit_ct_helpers:set_config(Config, {per_node_queues, PerNodeQueues}). + +declare_some_queues(Config, NodeNum) -> + {Conn, Chan} = rabbit_ct_client_helpers:open_connection_and_channel(Config, NodeNum), + NumQueues = 5, + Queues = [ list_to_binary(io_lib:format("queue-~b-on-node-~b", [QueueNum, NodeNum])) + || QueueNum <- lists:seq(1, NumQueues) ], + lists:foreach(fun (QueueName) -> + #'queue.declare_ok'{} = amqp_channel:call(Chan, #'queue.declare'{queue = QueueName, durable = true}) + end, Queues), + rabbit_ct_client_helpers:close_connection_and_channel(Conn, Chan), + Queues. + +end_per_group(list_queues, Config0) -> + Config1 = case rabbit_ct_helpers:get_config(Config0, save_config) of + undefined -> Config0; + C -> C + end, + rabbit_ct_helpers:run_steps(Config1, + rabbit_ct_client_helpers:teardown_steps() ++ + rabbit_ct_broker_helpers:teardown_steps()); +end_per_group(_, Config) -> + Config. + +init_per_testcase(Testcase, Config0) -> + rabbit_ct_helpers:testcase_started(Config0, Testcase). + +end_per_testcase(Testcase, Config0) -> + rabbit_ct_helpers:testcase_finished(Config0, Testcase). + +%%---------------------------------------------------------------------------- +%% Test cases +%%---------------------------------------------------------------------------- +list_queues_local(Config) -> + Node1Queues = lists:sort(lists:nth(1, ?config(per_node_queues, Config))), + Node2Queues = lists:sort(lists:nth(2, ?config(per_node_queues, Config))), + assert_ctl_queues(Config, 0, ["--local"], Node1Queues), + assert_ctl_queues(Config, 1, ["--local"], Node2Queues), + ok. + +list_queues_online(Config) -> + Node1Queues = lists:sort(lists:nth(1, ?config(per_node_queues, Config))), + Node2Queues = lists:sort(lists:nth(2, ?config(per_node_queues, Config))), + OnlineQueues = Node1Queues ++ Node2Queues, + assert_ctl_queues(Config, 0, ["--online"], OnlineQueues), + assert_ctl_queues(Config, 1, ["--online"], OnlineQueues), + ok. + +list_queues_offline(Config) -> + Node3Queues = lists:sort(lists:nth(3, ?config(per_node_queues, Config))), + OfflineQueues = Node3Queues, + assert_ctl_queues(Config, 0, ["--offline"], OfflineQueues), + assert_ctl_queues(Config, 1, ["--offline"], OfflineQueues), + ok. + +%%---------------------------------------------------------------------------- +%% Helpers +%%---------------------------------------------------------------------------- +assert_ctl_queues(Config, Node, Args, Expected0) -> + Expected = lists:sort(Expected0), + Got0 = run_list_queues(Config, Node, Args), + Got = lists:sort(lists:map(fun hd/1, Got0)), + case Got of + Expected -> + ok; + _ -> + ct:pal(error, "Listing queues on node ~p failed. Expected:~n~p~n~nGot:~n~p~n~n", + [Node, Expected, Got]), + exit({list_queues_unexpected_on, Node, Expected, Got}) + end. + +run_list_queues(Config, Node, Args) -> + rabbit_ct_broker_helpers:rabbitmqctl_list(Config, Node, ["list_queues"] ++ Args ++ ["name"]). diff --git a/test/unit_SUITE.erl b/test/unit_SUITE.erl index ba0f43f11e..43e812fa3d 100644 --- a/test/unit_SUITE.erl +++ b/test/unit_SUITE.erl @@ -31,7 +31,7 @@ groups() -> [ {parallel_tests, [parallel], [ arguments_parser, - filtering_flags_parsing, + mutually_exclusive_flags_parsing, {basic_header_handling, [parallel], [ write_table_with_invalid_existing_type, invalid_existing_headers, @@ -135,26 +135,41 @@ check_parse_arguments(ExpRes, Fun, As) -> true = SortRes(ExpRes) =:= SortRes(Fun(As)). -filtering_flags_parsing(_Config) -> - Cases = [{[], [], []} - ,{[{"--online", true}], ["--offline", "--online", "--third-option"], [false, true, false]} - ,{[{"--online", true}, {"--third-option", true}, {"--offline", true}], ["--offline", "--online", "--third-option"], [true, true, true]} - ,{[], ["--offline", "--online", "--third-option"], [true, true, true]} - ], - lists:foreach(fun({Vals, Opts, Expect}) -> - case rabbit_cli:filter_opts(Vals, Opts) of - Expect -> +mutually_exclusive_flags_parsing(_Config) -> + Matcher = fun ({ok, Value}, {ok, Value}) -> true; + ({error, Value}, {error, Pattern}) -> + case re:run(Value, Pattern) of + {match, _} -> true; + _ -> false + end; + (_, _) -> false + end, + Spec = [{"--online", online} + ,{"--offline", offline} + ,{"--local", local}], + Default = all, + Cases =[{["--online"], {ok, online}} + ,{[], {ok, Default}} + ,{["--offline"], {ok, offline}} + ,{["--local"], {ok, local}} + ,{["--offline", "--local"], {error, "mutually exclusive"}} + ,{["--offline", "--online"], {error, "mutually exclusive"}} + ,{["--offline", "--local", "--online"], {error, "mutually exclusive"}} + ], + lists:foreach(fun({Opts, Expected}) -> + ExpandedOpts = [ {Opt, true} || Opt <- Opts ], + Got = rabbit_cli:mutually_exclusive_flags(ExpandedOpts, all, Spec), + case Matcher(Got, Expected) of + true -> ok; - Got -> - exit({no_match, Got, Expect, {args, Vals, Opts}}) + false -> + exit({no_match, Got, Expected, {opts, Opts}}) end - end, - Cases). + end, Cases). %% ------------------------------------------------------------------- %% basic_header_handling. %% ------------------------------------------------------------------- - -define(XDEATH_TABLE, [{<<"reason">>, longstr, <<"blah">>}, {<<"queue">>, longstr, <<"foo.bar.baz">>}, diff --git a/test/unit_inbroker_SUITE.erl b/test/unit_inbroker_SUITE.erl index e9ecbf5444..98cd77ccbe 100644 --- a/test/unit_inbroker_SUITE.erl +++ b/test/unit_inbroker_SUITE.erl @@ -1684,15 +1684,15 @@ credit_flow_settings(Config) -> credit_flow_settings1(_Config) -> %% default values - passed = test_proc(200, 50), + passed = test_proc(200, 100), - application:set_env(rabbit, credit_flow_default_credit, {100, 20}), - passed = test_proc(100, 20), + application:set_env(rabbit, credit_flow_default_credit, {100, 300}), + passed = test_proc(100, 300), application:unset_env(rabbit, credit_flow_default_credit), % back to defaults - passed = test_proc(200, 50), + passed = test_proc(200, 100), passed. test_proc(InitialCredit, MoreCreditAfter) -> |
