[PATCH conductor 1/2] rufus scheduler integration - RM 3273
Richard Su
rwsu at redhat.com
Fri Jun 1 16:33:16 UTC 2012
On 06/01/2012 01:27 AM, Jan Provaznik wrote:
> On 05/31/2012 08:40 PM, Richard Su wrote:
>> https://www.aeolusproject.org/redmine/issues/3273
>>
>> REST api to turn the rufus scheduler on (:new) and off (:destroy)
>> and to check its status (:index).
>>
>> A singleton class JobScheduler encapsulates the rufus scheduler
>> so that only a single scheduler instance runs at any time.
>>
>> Only users who have the ROLE view and modify permissions may
>> control the scheduler.
>> ---
>> aeolus-conductor.spec.in | 2 +
>> src/app/controllers/job_scheduler_controller.rb | 45 +++++++++
>> src/app/views/job_scheduler/destroy.xml.haml | 2 +
>> src/app/views/job_scheduler/index.xml.haml | 2 +
>> src/app/views/job_scheduler/new.xml.haml | 2 +
>> src/config/routes.rb | 2 +
>> src/lib/job_scheduler.rb | 94
>> ++++++++++++++++++++
>> .../controllers/job_scheduler_controller_spec.rb | 84
>> +++++++++++++++++
>> 8 files changed, 233 insertions(+), 0 deletions(-)
>> create mode 100644 src/app/controllers/job_scheduler_controller.rb
>> create mode 100644 src/app/views/job_scheduler/destroy.xml.haml
>> create mode 100644 src/app/views/job_scheduler/index.xml.haml
>> create mode 100644 src/app/views/job_scheduler/new.xml.haml
>> create mode 100644 src/lib/job_scheduler.rb
>> create mode 100644
>> src/spec/controllers/job_scheduler_controller_spec.rb
>>
>> diff --git a/aeolus-conductor.spec.in b/aeolus-conductor.spec.in
>> index a40d517..6cca32f 100644
>> --- a/aeolus-conductor.spec.in
>> +++ b/aeolus-conductor.spec.in
>> @@ -47,6 +47,7 @@ Requires: rubygem(oauth)
>> Requires: rubygem(rake)
>> Requires: rubygem(delayed_job)>= 2.1.4
>> Requires: rubygem(paranoia)
>> +Requires: rubygem(rufus-scheduler)
>> Requires: postgresql
>> Requires: postgresql-server
>> Requires: system-logos
>> @@ -189,6 +190,7 @@ haml="app/views/hardware_profiles
>> app/views/realm_mappings \
>> app/views/deployables app/views/catalogs \
>> app/views/provider_types app/views/api/images \
>> app/views/config_servers app/views/provider_realms \
>> + app/views/job_scheduler \
>> app/views/logs \
>> app/views/api/hooks \
>> app/views/api \
>> diff --git a/src/app/controllers/job_scheduler_controller.rb
>> b/src/app/controllers/job_scheduler_controller.rb
>> new file mode 100644
>> index 0000000..b1a2701
>> --- /dev/null
>> +++ b/src/app/controllers/job_scheduler_controller.rb
>> @@ -0,0 +1,45 @@
>> +#
>> +# Copyright 2012 Red Hat, Inc.
>> +#
>> +# 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 'job_scheduler'
>> +
>> +class JobSchedulerController< ApplicationController
>> + before_filter :require_user_api
>> + respond_to :xml
>> + layout :false
>> +
>> + # GET /jobscheduler
>> + # GET /jobscheduler.xml
>> + def index
>> + require_privilege(Privilege::PERM_VIEW)
>> + respond_with(JobScheduler.activated?)
>> + end
>> +
>> + # GET /jobscheduler/new
>> + # GET /jobscheduler/new.xml
>> + def new
>> + require_privilege(Privilege::PERM_SET)
>> + respond_with(JobScheduler.start)
>> + end
>> +
>> + # DELETE /jobscheduler/1
>> + # DELETE /jobscheduler/1.xml
>> + def destroy
>> + require_privilege(Privilege::PERM_SET)
>> + respond_with(JobScheduler.stop)
>> + end
>> +
>> +end
>> diff --git a/src/app/views/job_scheduler/destroy.xml.haml
>> b/src/app/views/job_scheduler/destroy.xml.haml
>> new file mode 100644
>> index 0000000..18e796d
>> --- /dev/null
>> +++ b/src/app/views/job_scheduler/destroy.xml.haml
>> @@ -0,0 +1,2 @@
>> +!!! XML
>> +%activated=JobScheduler.activated?
>> \ No newline at end of file
>> diff --git a/src/app/views/job_scheduler/index.xml.haml
>> b/src/app/views/job_scheduler/index.xml.haml
>> new file mode 100644
>> index 0000000..b5c75d6
>> --- /dev/null
>> +++ b/src/app/views/job_scheduler/index.xml.haml
>> @@ -0,0 +1,2 @@
>> +!!! XML
>> +%activated=JobScheduler.activated?
>> diff --git a/src/app/views/job_scheduler/new.xml.haml
>> b/src/app/views/job_scheduler/new.xml.haml
>> new file mode 100644
>> index 0000000..18e796d
>> --- /dev/null
>> +++ b/src/app/views/job_scheduler/new.xml.haml
>> @@ -0,0 +1,2 @@
>> +!!! XML
>> +%activated=JobScheduler.activated?
>> \ No newline at end of file
>> diff --git a/src/config/routes.rb b/src/config/routes.rb
>> index 265f752..518b013 100644
>> --- a/src/config/routes.rb
>> +++ b/src/config/routes.rb
>> @@ -238,6 +238,8 @@ Conductor::Application.routes.draw do
>> resources :provider_images
>> end
>>
>> + resources :job_scheduler, :only => [:index, :new, :destroy]
>> +
>> get 'api', :controller => 'api/entrypoint', :action => 'index'
>> namespace :api do
>> resources :images do
>> diff --git a/src/lib/job_scheduler.rb b/src/lib/job_scheduler.rb
>> new file mode 100644
>> index 0000000..1050ecd
>> --- /dev/null
>> +++ b/src/lib/job_scheduler.rb
>> @@ -0,0 +1,94 @@
>> +#
>> +# Copyright 2012 Red Hat, Inc.
>> +#
>> +# 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 'curb'
>> +require 'rufus-scheduler'
>> +
>> +class JobScheduler
>> +
>> + @@scheduler = nil
>> +
>> + def self.initialize
>> + self.start
>> + end
>> +
>> + def self.start
>> + if @@scheduler.nil?
>> + @@scheduler = Rufus::Scheduler::PlainScheduler.start_new
>> + schedule_tasks(@@scheduler)
>> + end
>> + end
>> +
>> + def self.stop
>> + if @@scheduler
>> + @@scheduler.stop
>> + @@scheduler = nil
>> + end
>> + end
>> +
>> + def self.activated?
>> + if @@scheduler
>> + true
>> + else
>> + false
>> + end
>> + end
>> +
>> + def self.status_via_http(login, password, hostname)
>> + curl = self.curl_request(login, password)
>> + curl.url = job_scheduler_url(hostname, '')
>> + curl.http_get
>> + curl.body_str.to_s
>> + end
>> +
>> + def self.start_via_http(login, password, hostname)
>> + curl = self.curl_request(login, password)
>> + curl.url = job_scheduler_url(hostname, 'new')
>> + curl.http_get
>> + curl.body_str.to_s
>> + end
>> +
>> + def self.stop_via_http(login, password, hostname)
>> + curl = self.curl_request(login, password)
>> + curl.url = job_scheduler_url(hostname, '1')
>> + curl.http_delete
>> + curl.body_str.to_s
>> + end
>> +
>> + private
>> +
>> + def self.schedule_tasks(scheduler)
>> + scheduler.every("1m") do
>> + puts "job scheduler is running"
>> + end
>> + end
>> +
>> + def self.job_scheduler_url(hostname, suffix)
>> + # TODO: is there a better way to generate this url?
>> + url =
>> "https://#{hostname}/conductor/#{JobSchedulerController.controller_path}/#{suffix}"
>> + end
>> +
>> + def self.curl_request(login, password)
>> + curl = Curl::Easy.new
>> + curl.username = login
>> + curl.password = password
>> + curl.headers['HTTP_ACCEPT'] = 'application/xml'
>> + curl.headers['CONTENT_TYPE'] = 'application/xml'
>> + curl.http_auth_types = :basic
>> + return curl
>> + end
>> +
>> +end
>> diff --git a/src/spec/controllers/job_scheduler_controller_spec.rb
>> b/src/spec/controllers/job_scheduler_controller_spec.rb
>> new file mode 100644
>> index 0000000..75726ec
>> --- /dev/null
>> +++ b/src/spec/controllers/job_scheduler_controller_spec.rb
>> @@ -0,0 +1,84 @@
>> +#
>> +# Copyright 2012 Red Hat, Inc.
>> +#
>> +# 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 JobSchedulerController do
>> + render_views
>> +
>> + context "when authenticated as admin" do
>> +
>> + before(:each) do
>> + @admin_permission = FactoryGirl.create :admin_permission
>> + @admin = @admin_permission.user
>> + mock_warden(@admin)
>> + end
>> +
>> + describe "scheduler controls" do
>> +
>> + it "scheduler status from 'GET index'" do
>> + send_and_accept_xml
>> + get :index
>> + response.should be_success
>> + response.body.strip.should == "<activated>false</activated>"
>> + end
>> +
>> + it "turn on scheduler by 'GET new'" do
>> + send_and_accept_xml
>> + get :new
>> + response.should be_success
>> + response.body.strip.should == "<activated>true</activated>"
>> + end
>> +
>> + it "turn off scheduler by 'POST destroy'" do
>> + send_and_accept_xml
>> + post :destroy, :id => 1
>> + response.should be_success
>> + response.body.strip.should == "<activated>false</activated>"
>> + end
>> +
>> + it "turn scheduler on and then off" do
>> + send_and_accept_xml
>> + get :index
>> + response.should be_success
>> + response.body.strip.should == "<activated>false</activated>"
>> + get :new
>> + response.should be_success
>> + response.body.strip.should == "<activated>true</activated>"
>> + post :destroy, :id => 1
>> + response.should be_success
>> + response.body.strip.should == "<activated>false</activated>"
>> + end
>> + end
>> + end
>> +
>> + context "when not authenticated as admin" do
>> +
>> + before(:each) do
>> + @non_admin_permission = FactoryGirl.create :pool_user_permission
>> + @user = @non_admin_permission.user
>> + mock_warden(@user)
>> + end
>> +
>> + it "requests should be denied" do
>> + send_and_accept_xml
>> + get :index
>> + response.should_not be_success
>> + end
>> +
>> + end
>> +
>> +end
>
> Hi Richard,
> based on plans from last week (DC is going to implement some kind of
> Cloud State app), I'm not sure for what purposes we will need rufus
> scheduler? Instances/realms would be potentially handled by the Cloud
> State app (though nothing is confirmed yet), and remaining candidate
> for scheduler was LDAP sync which we finally not gonna do too. Is
> there some other usage of the scheduler?
>
> Jan
I was half way through this patch set when the cloud state app
discussion began, and I figured I would see it through. It is ok if we
don't use this patch, it was still get a good exercise for me.
The DC tracker will remove the need for a scheduler. Instance and realms
checking are the remaining use cases for a scheduler.
There might be a possibility of us converting some parts of dbomatic,
depending on when DC tracker becomes available or if we need to make a
tactical fix if users report issues with timeouts in dbomatic.
More information about the aeolus-devel
mailing list