diff --git a/README.md b/README.md index 74ed6f7..269470a 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,59 @@ end * `app_module` – Celery application module. *(default: auto-detect)* * `worker_pool` – The Pool implementation used by the Celery worker (gevent,eventlet or prefork). *(default: prefork)* * `service_name` – Name of the service to create. *(default: auto-detect)* -# `user` – User to run the service as. *(default: application owner)* +* `user` – User to run the service as. *(default: application owner)* + +### `application_flower_config` + +The `application_flower_config` creates a `flowerconfig.py` configuration file. + +```ruby +application '/srv/myapp' do + flower_config do + options do + broker 'amqp://' + end + end +end +``` + +#### Actions + +* `:deploy` – Create the configuration file. *(default)* + +#### Properties + +* `path` – Path to write the configuration file to. If given as a directory, + create `path/flowerconfig.py`. *(name attribute)* +* `options` – Hash or block of options to set in the configuration file. + +### `application_flower` + +The `application_flower` resource creates a service for the `flower` process. + +```ruby +application '/srv/myapp' do + flower do + config_file 'path/flowerconfig.py`' + end +end +``` + +#### Actions + +* `:enable` – Create, enable and start the service. *(default)* +* `:disable` – Stop, disable, and destroy the service. +* `:start` – Start the service. +* `:stop` – Stop the service. +* `:restart` – Stop and then start the service. +* `:reload` – Send the configured reload signal to the service. + +#### Properties + +* `path` – Base path for the application. *(name attribute)* +* `config_file` – path of the configuration file to use *(default: path/flowerconfig)* +* `service_name` – Name of the service to create. *(default: auto-detect)* +* `user` – User to run the service as. *(default: application owner)* ### `application_django` diff --git a/chef/templates/flowerconfig.py.erb b/chef/templates/flowerconfig.py.erb new file mode 100644 index 0000000..e55e430 --- /dev/null +++ b/chef/templates/flowerconfig.py.erb @@ -0,0 +1,5 @@ +# Generated by Chef for <%= @new_resource.to_s %> + +<%- @new_resource.options.each do |key, value| -%> +<%= key %> = <%= PoisePython::Utils.to_python(value) %> +<%- end -%> diff --git a/lib/poise_application_python/resources.rb b/lib/poise_application_python/resources.rb index a7b8fa3..8f87ff2 100644 --- a/lib/poise_application_python/resources.rb +++ b/lib/poise_application_python/resources.rb @@ -18,6 +18,8 @@ require 'poise_application_python/resources/celery_config' require 'poise_application_python/resources/celery_worker' require 'poise_application_python/resources/django' +require 'poise_application_python/resources/flower' +require 'poise_application_python/resources/flower_config' require 'poise_application_python/resources/gunicorn' require 'poise_application_python/resources/pip_requirements' require 'poise_application_python/resources/python' diff --git a/lib/poise_application_python/resources/flower.rb b/lib/poise_application_python/resources/flower.rb new file mode 100644 index 0000000..04d0620 --- /dev/null +++ b/lib/poise_application_python/resources/flower.rb @@ -0,0 +1,66 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +require 'uri' + +require 'chef/provider' +require 'chef/resource' +require 'poise' +require 'poise_application' +require 'poise_python' + +require 'poise_application_python/app_mixin' +require 'poise_application_python/service_mixin' +require 'poise_application_python/error' + + +module PoiseApplicationPython + module Resources + # (see FlowerConfig::Resource) + # @since 4.1.0 + module Flower + # @since 4.1.0 + class Resource < Chef::Resource + include PoiseApplicationPython::ServiceMixin + provides(:application_flower) + attribute(:config_file, kind_of: [String, NilClass], default: lazy { default_path }) + + private + + def default_path + if ::File.directory?(name) + ::File.join(name, 'flowerconfig.py') + else + name + end + end + end + + class Provider < Chef::Provider + include PoiseApplicationPython::ServiceMixin + provides(:application_flower) + + private + + def service_options(resource) + super + raise PoiseApplicationPython::Error.new("Unable to determine configuration file for #{new_resource}") unless new_resource.config_file + resource.command("#{new_resource.python} -m flower --conf=#{new_resource.config_file}") + end + end + end + end +end diff --git a/lib/poise_application_python/resources/flower_config.rb b/lib/poise_application_python/resources/flower_config.rb new file mode 100644 index 0000000..1019632 --- /dev/null +++ b/lib/poise_application_python/resources/flower_config.rb @@ -0,0 +1,109 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +require 'uri' + +require 'chef/provider' +require 'chef/resource' +require 'poise' +require 'poise_application' +require 'poise_python' + +require 'poise_application_python/app_mixin' +require 'poise_application_python/service_mixin' +require 'poise_application_python/error' + + +module PoiseApplicationPython + module Resources + # (see CeleryConfig::Resource) + # @since 4.1.0 + module FlowerConfig + # An `application_flower_config` resource to configure flower monitoring app. + # + # @since 4.1.0 + # @provides application_flower_config + # @action deploy + # @example + # application '/srv/myapp' do + # git '...' + # pip_requirements + # flower_config do + # options do + # btoker '...' + # end + # end + # end + class Resource < Chef::Resource + include PoiseApplicationPython::AppMixin + provides(:application_flower_config) + actions(:deploy) + + attribute('', template: true, default_source: 'flowerconfig.py.erb') + # @!attribute group + # Owner for the Flower application, defaults to application group. + # @return [String] + attribute(:group, kind_of: String, default: lazy { parent && parent.group }) + # @!attribute owner + # Owner for the Flower application, defaults to application owner. + # @return [String] + attribute(:owner, kind_of: String, default: lazy { parent && parent.owner }) + attribute(:path, kind_of: String, default: lazy { default_path }) + + private + + def default_path + if ::File.directory?(name) + ::File.join(name, 'flowerconfig.py') + else + name + end + end + end + + # Provider for `application_flower_config`. + # + # @since 4.1.0 + # @see Resource + # @provides application_flower_config + class Provider < Chef::Provider + include PoiseApplicationPython::AppMixin + provides(:application_flower_config) + + # `deploy` action for `application_flower_config`. Writes config file. + # + # @return [void] + def action_deploy + notifying_block do + write_config + end + end + + private + + def write_config + file new_resource.path do + content new_resource.content + mode '640' + owner new_resource.owner + group new_resource.group + end + end + + end + end + end +end diff --git a/lib/poise_application_python/version.rb b/lib/poise_application_python/version.rb index 50af440..6813b43 100644 --- a/lib/poise_application_python/version.rb +++ b/lib/poise_application_python/version.rb @@ -15,5 +15,5 @@ # module PoiseApplicationPython - VERSION = '4.0.1.pre' + VERSION = '4.1.0' end diff --git a/test/spec/resources/flower_config_spec.rb b/test/spec/resources/flower_config_spec.rb new file mode 100644 index 0000000..d03c349 --- /dev/null +++ b/test/spec/resources/flower_config_spec.rb @@ -0,0 +1,58 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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. +# + +require 'spec_helper' + +describe PoiseApplicationPython::Resources::FlowerConfig do + step_into(:application_flower_config) + before do + allow(File).to receive(:directory?).and_call_original + allow(File).to receive(:directory?).with('/test').and_return(true) + end + + context 'with defaults' do + recipe do + application_flower_config '/test' + end + it { is_expected.to deploy_application_flower_config('/test').with(path: '/test/flowerconfig.py') } + it { is_expected.to render_file('/test/flowerconfig.py').with_content(eq(<<-FLOWERCONFIG)) } +# Generated by Chef for application_flower_config[/test] + +FLOWERCONFIG + end # /context with defaults + + context 'with a specific path' do + recipe do + application_flower_config '/test/foo.py' + end + it { is_expected.to deploy_application_flower_config('/test/foo.py').with(path: '/test/foo.py') } + end # /context with a specific path + + context 'with template options' do + recipe do + application_flower_config '/test' do + options do + broker 'amqp://' + end + end + end + it { is_expected.to render_file('/test/flowerconfig.py').with_content(eq(<<-FLOWERCONFIG)) } +# Generated by Chef for application_flower_config[/test] + +broker = "amqp://" +FLOWERCONFIG + end # /context with template options +end