[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