ref: refs/heads/resource-restful commit 3227e82ff5129bb3f0bd15af086b6a91fc8cf448 Author: Josef Reidinger <jreidinger@suse.cz> Date: Thu Sep 17 16:37:39 2009 +0200 move ntp to separate backend service --- plugins/ntp/MIT-LICENSE | 20 +++++ plugins/ntp/README | 13 +++ plugins/ntp/Rakefile | 10 +++ plugins/ntp/app/controllers/ntp_controller.rb | 38 +++++++++ plugins/ntp/app/models/ntp.rb | 44 +++++++++++ plugins/ntp/config/rails_parent.rb | 15 ++++ plugins/ntp/config/resources/ntp.yml | 3 + plugins/ntp/init.rb | 1 + plugins/ntp/install.rb | 1 + plugins/ntp/package/NTP.pm | 34 ++++++++ .../org.opensuse.yast.modules.yapi.ntp.policy | 19 +++++ plugins/ntp/package/yast2-webservice-ntp.spec | 81 ++++++++++++++++++++ plugins/ntp/test/functional/ntp_controller_test.rb | 38 +++++++++ plugins/ntp/test/test_helper.rb | 52 +++++++++++++ plugins/ntp/test/unit/ntp_test.rb | 32 ++++++++ plugins/ntp/uninstall.rb | 1 + plugins/time/package/NTP.pm | 34 -------- .../org.opensuse.yast.modules.yapi.ntp.policy | 19 ----- plugins/time/package/yast2-webservice-time.spec | 7 -- 19 files changed, 402 insertions(+), 60 deletions(-) diff --git a/plugins/ntp/MIT-LICENSE b/plugins/ntp/MIT-LICENSE new file mode 100644 index 0000000..658dd59 --- /dev/null +++ b/plugins/ntp/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009 Novell, 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/plugins/ntp/README b/plugins/ntp/README new file mode 100644 index 0000000..2fee937 --- /dev/null +++ b/plugins/ntp/README @@ -0,0 +1,13 @@ +System +====== + +REST interface for accessing ntp configuration and synchronization + + +It uses own YaPI that uses sntp program. The reasons are: + +- ntp-client is too much complex and cannot be easily extracted only required functionality +- need root permissions to run sntp and YaPI ensure also policyKit check + + +Copyright (c) 2009 Novell, released under the MIT license diff --git a/plugins/ntp/Rakefile b/plugins/ntp/Rakefile new file mode 100644 index 0000000..8f4c2f2 --- /dev/null +++ b/plugins/ntp/Rakefile @@ -0,0 +1,10 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' +require 'rake/packagetask' +require File.join(File.dirname(__FILE__), 'config', 'rails_parent') +require File.join(RailsParent.parent, 'config', 'boot') +require 'tasks/rails' + +desc 'Default: run unit tests.' +task :default => :test diff --git a/plugins/ntp/app/controllers/ntp_controller.rb b/plugins/ntp/app/controllers/ntp_controller.rb new file mode 100644 index 0000000..dda4d03 --- /dev/null +++ b/plugins/ntp/app/controllers/ntp_controller.rb @@ -0,0 +1,38 @@ + +class NtpController < ApplicationController + + before_filter :login_required + + def show + ntp = Ntp.find + + respond_to do |format| + format.html { render :xml => ntp.actions.to_xml(:root => :actions)} #return xml only + format.xml { render :xml => ntp.actions.to_xml(:root => :actions)} + format.json { render :json => ntp.actions.to_json } + end + end + + def update + root = params["ntp"] + if root == nil || root == {} #FIXME exception for this + render ErrorResult.error(404, 2, "format error - missing actions") and return + end + + @ntp = Ntp.find + + if root["synchronize"] + yapi_perm_check "ntp.synchronize" + @ntp.actions[:synchronize] = true + end + + @ntp.save + redirect_to :action => :show + end + + # See update + def create + update + end + +end diff --git a/plugins/ntp/app/models/ntp.rb b/plugins/ntp/app/models/ntp.rb new file mode 100644 index 0000000..790b01d --- /dev/null +++ b/plugins/ntp/app/models/ntp.rb @@ -0,0 +1,44 @@ +class Ntp + + attr_accessor :actions + + public + def initialize + @actions = { :synchronize => false } + end + + def self.find + Ntp.new + end + + def save + if @actions[:synchronize] + synchronize + end + end + + private + def synchronize + ret = YastService.Call("YaPI::NTP::Synchronize") + raise NtpError.new(ret) unless ret == "OK" + end +end + +require 'exceptions' +class NtpError < BackendException + def initialize(message) + @message = message + super("Ntp failed to synchronize with this error: #{@message}.") + end + + def to_xml + xml = Builder::XmlMarkup.new({}) + xml.instruct! + + xml.error do + xml.type "NTP_ERROR" + xml.description message + xml.output @message + end + end +end \ No newline at end of file diff --git a/plugins/ntp/config/rails_parent.rb b/plugins/ntp/config/rails_parent.rb new file mode 100644 index 0000000..b869908 --- /dev/null +++ b/plugins/ntp/config/rails_parent.rb @@ -0,0 +1,15 @@ +class RailsParent + + def RailsParent.parent + parent = ENV["RAILS_PARENT"] + unless parent + parent = File.expand_path(File.join('..','..','..', 'webservice'), File.dirname(__FILE__)) + unless File.directory?( parent || "" ) + $stderr.puts "Nope: #{parent}\nPlease set RAILS_PARENT environment" + exit 1 + end + end + parent + end + +end diff --git a/plugins/ntp/config/resources/ntp.yml b/plugins/ntp/config/resources/ntp.yml new file mode 100644 index 0000000..176ff2a --- /dev/null +++ b/plugins/ntp/config/resources/ntp.yml @@ -0,0 +1,3 @@ +interface: org.opensuse.yast.modules.yapi.ntp +controller: ntp +singular: true diff --git a/plugins/ntp/init.rb b/plugins/ntp/init.rb new file mode 100644 index 0000000..3c19a74 --- /dev/null +++ b/plugins/ntp/init.rb @@ -0,0 +1 @@ +# Include hook code here diff --git a/plugins/ntp/install.rb b/plugins/ntp/install.rb new file mode 100644 index 0000000..f7732d3 --- /dev/null +++ b/plugins/ntp/install.rb @@ -0,0 +1 @@ +# Install hook code here diff --git a/plugins/ntp/package/NTP.pm b/plugins/ntp/package/NTP.pm new file mode 100644 index 0000000..47f824a --- /dev/null +++ b/plugins/ntp/package/NTP.pm @@ -0,0 +1,34 @@ +package YaPI::NTP; + +use strict; +use YaPI; + +our %TYPEINFO; + +BEGIN{$TYPEINFO{Synchronize} = ["function", + "string"]; +} +sub Synchronize { + my $self = shift; + my $servers = getServers(); + my $out = undef; + + foreach my $server (@{$servers}){ + # -r: do set the system time + # -P no: do not ask if time difference is too large + # -c 1 -d 15: delay 15s, only one try (bnc#442287) + $out = `/usr/sbin/sntp -c 1 -d 15 -r -P no '$server' 2>&1`; + return "OK" unless ($?); + $out = "Error for server $server: $out"; + } + return "NOSERVERS" unless (defined ($out)); + return $out; +} + +sub getServers { + my $servers = `grep "^[:space:]*NETCONFIG_NTP_STATIC_SERVERS" /etc/sysconfig/network/config | sed 's/.*="\(.*\)"/\1/'`; + my @serv = split(/\s+/,$servers); + return @serv; +} + +1; diff --git a/plugins/ntp/package/org.opensuse.yast.modules.yapi.ntp.policy b/plugins/ntp/package/org.opensuse.yast.modules.yapi.ntp.policy new file mode 100644 index 0000000..8641500 --- /dev/null +++ b/plugins/ntp/package/org.opensuse.yast.modules.yapi.ntp.policy @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE policyconfig PUBLIC + "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" + "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> +<policyconfig> + + <vendor>YaST Webservice Project</vendor> + <vendor_url>http://en.opensuse.org/YAST</vendor_url> + + <action id="org.opensuse.yast.modules.yapi.ntp.synchronize"> + <description>One time synchronization again given ntp server</description> + <message>Authentication is required to onetime synchronize with ntp</message> + <defaults> + <allow_inactive>no</allow_inactive> + <allow_active>no</allow_active> + </defaults> + </action> + +</policyconfig> diff --git a/plugins/ntp/package/yast2-webservice-ntp.changes b/plugins/ntp/package/yast2-webservice-ntp.changes new file mode 100644 index 0000000..e69de29 diff --git a/plugins/ntp/package/yast2-webservice-ntp.spec b/plugins/ntp/package/yast2-webservice-ntp.spec new file mode 100644 index 0000000..37ad371 --- /dev/null +++ b/plugins/ntp/package/yast2-webservice-ntp.spec @@ -0,0 +1,81 @@ +# +# spec file for package yast2-webservice-ntp +# +# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + + +Name: yast2-webservice-ntp +PreReq: yast2-webservice +# requires HAL for reboot/shutdown actions +Requires: ntp +Provides: yast2-webservice:/srv/www/yastws/app/controllers/ntp_controller.rb +License: MIT +Group: Productivity/Networking/Web/Utilities +Autoreqprov: on +Version: 0.0.1 +Release: 0 +Summary: YaST2 - Webservice - NTP +Source: www.tar.bz2 +Source1: NTP.pm +Source2: org.opensuse.yast.modules.yapi.ntp.policy +BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildArch: noarch + +# +%define pkg_user yastws +%define plugin_name ntp +# + + +%description +YaST2 - Webservice - REST based interface for basic ntp access + +Authors: +-------- + Josef Reidinger <jreidinger@novell.com> + +%prep +%setup -q -n www + +%build + +%install + +# +# Install all web and frontend parts. +# +mkdir -p $RPM_BUILD_ROOT/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name} +cp -a * $RPM_BUILD_ROOT/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name} +cp ${SOURCE1} $RPM_BUILD_ROOT/usr/share/YaST2/modules/YaPI/ +mkdir -p $RPM_BUILD_ROOT/usr/share/PolicyKit/policy/ +cp ${SOURCE2} $RPM_BUILD_ROOT/usr/share/PolicyKit/policy/ + + +%clean +rm -rf $RPM_BUILD_ROOT + +%post + +%postun + +%files +%defattr(-,root,root) +%dir /srv/www/%{pkg_user} +%dir /srv/www/%{pkg_user}/vendor +%dir /srv/www/%{pkg_user}/vendor/plugins +%dir /srv/www/%{pkg_user}/vendor/plugins/%{plugin_name} +/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/MIT-LICENSE +/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/README +/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/Rakefile +/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/init.rb +/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/install.rb +/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/uninstall.rb +/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/app +/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/config +/usr/share/YaST2/modules/YaPI/${SOURCE1} +/usr/share/PolicyKit/policy/${SOURCE2} diff --git a/plugins/ntp/test/functional/ntp_controller_test.rb b/plugins/ntp/test/functional/ntp_controller_test.rb new file mode 100644 index 0000000..41e5294 --- /dev/null +++ b/plugins/ntp/test/functional/ntp_controller_test.rb @@ -0,0 +1,38 @@ +require File.expand_path(File.dirname(__FILE__) + "/../test_helper") +require 'test/unit' + +#don't have plugin basic tests because doesn't have read permission + + +class SystemControllerTest < ActionController::TestCase + fixtures :accounts + + def setup + @controller = NtpController.new + @request = ActionController::TestRequest.new + # http://railsforum.com/viewtopic.php?id=1719 + @request.session[:account_id] = 1 # defined in fixtures + end + + + def test_index + ret = get :show + assert_response :success + response = Hash.from_xml(ret.body) + assert response["actions"]["synchronize"] == false + end + + def test_update + YastService.stubs(:Call).with("YaPI::NTP::Synchronize").once.returns("OK") + post :update, {"ntp"=>{"synchronize"=>true}} + assert_response :redirect + assert_redirected_to :action => "show" + end + + def test_update_failed + YastService.stubs(:Call).with("YaPI::NTP::Synchronize").once.returns("Failed") + post :update, {"ntp"=>{"synchronize"=>true}} + assert_response 503 + end + +end diff --git a/plugins/ntp/test/test_helper.rb b/plugins/ntp/test/test_helper.rb new file mode 100644 index 0000000..7d67910 --- /dev/null +++ b/plugins/ntp/test/test_helper.rb @@ -0,0 +1,52 @@ +# find the rails parent +require File.join(File.dirname(__FILE__), '..', 'config', 'rails_parent') +# first config rails +require File.expand_path( File.join("config","environment"), RailsParent.parent ) +# then enable testing, this will get the routing right +ENV["RAILS_ENV"] = "test" +require 'test_help' + +class ActiveSupport::TestCase + # Transactional fixtures accelerate your tests by wrapping each test method + # in a transaction that's rolled back on completion. This ensures that the + # test database remains unchanged so your fixtures don't have to be reloaded + # between every test method. Fewer database queries means faster tests. + # + # Read Mike Clark's excellent walkthrough at + # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting + # + # Every Active Record database supports transactions except MyISAM tables + # in MySQL. Turn off transactional fixtures in this case; however, if you + # don't care one way or the other, switching from MyISAM to InnoDB tables + # is recommended. + # + # The only drawback to using transactional fixtures is when you actually + # need to test transactions. Since your test is bracketed by a transaction, + # any transactions started in your code will be automatically rolled back. + self.use_transactional_fixtures = true + + # Instantiated fixtures are slow, but give you @david where otherwise you + # would need people(:david). If you don't want to migrate your existing + # test cases which use the @david style and don't mind the speed hit (each + # instantiated fixtures translates to a database query per test method), + # then set this back to true. + self.use_instantiated_fixtures = false + + # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. + # + # Note: You'll currently still have to declare fixtures explicitly in integration tests + # -- they do not yet inherit this setting + fixtures :all + + # Add more helper methods to be used by all tests here... + + # See http://pennysmalls.com/2009/03/04/rails-23-breakage-and-fixage/ + def clean_backtrace(&block) + yield + rescue ActiveSupport::TestCase::Assertion => error + framework_path = Regexp.new(File.expand_path("#{File.dirname(__FILE__)}/assertions")) + error.backtrace.reject! { |line| File.expand_path(line) =~ framework_path } + raise + end + +end diff --git a/plugins/ntp/test/unit/ntp_test.rb b/plugins/ntp/test/unit/ntp_test.rb new file mode 100644 index 0000000..26e2b5d --- /dev/null +++ b/plugins/ntp/test/unit/ntp_test.rb @@ -0,0 +1,32 @@ +require 'test_helper' + +require 'system' + +class NtpTest < ActiveSupport::TestCase + + def setup + @model = Ntp.find + end + + def test_actions + assert_not_nil @model.actions + assert_instance_of(Hash, @model.actions, "action() returns Hash") + end + + def test_synchronize_ok + @model.actions[:synchronize] = true + YastService.stubs(:Call).with("YaPI::NTP::Synchronize").once.returns("OK") + assert_nothing_raised do + @model.save + end + end + + def test_synchronize_error + @model.actions[:synchronize] = true + YastService.stubs(:Call).with("YaPI::NTP::Synchronize").once.returns("No server defined") + assert_raise(NtpError.new "No server defined") do + @model.save + end + end + +end diff --git a/plugins/ntp/uninstall.rb b/plugins/ntp/uninstall.rb new file mode 100644 index 0000000..9738333 --- /dev/null +++ b/plugins/ntp/uninstall.rb @@ -0,0 +1 @@ +# Uninstall hook code here diff --git a/plugins/time/package/NTP.pm b/plugins/time/package/NTP.pm deleted file mode 100644 index 47f824a..0000000 --- a/plugins/time/package/NTP.pm +++ /dev/null @@ -1,34 +0,0 @@ -package YaPI::NTP; - -use strict; -use YaPI; - -our %TYPEINFO; - -BEGIN{$TYPEINFO{Synchronize} = ["function", - "string"]; -} -sub Synchronize { - my $self = shift; - my $servers = getServers(); - my $out = undef; - - foreach my $server (@{$servers}){ - # -r: do set the system time - # -P no: do not ask if time difference is too large - # -c 1 -d 15: delay 15s, only one try (bnc#442287) - $out = `/usr/sbin/sntp -c 1 -d 15 -r -P no '$server' 2>&1`; - return "OK" unless ($?); - $out = "Error for server $server: $out"; - } - return "NOSERVERS" unless (defined ($out)); - return $out; -} - -sub getServers { - my $servers = `grep "^[:space:]*NETCONFIG_NTP_STATIC_SERVERS" /etc/sysconfig/network/config | sed 's/.*="\(.*\)"/\1/'`; - my @serv = split(/\s+/,$servers); - return @serv; -} - -1; diff --git a/plugins/time/package/org.opensuse.yast.modules.yapi.ntp.policy b/plugins/time/package/org.opensuse.yast.modules.yapi.ntp.policy deleted file mode 100644 index 070184f..0000000 --- a/plugins/time/package/org.opensuse.yast.modules.yapi.ntp.policy +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE policyconfig PUBLIC - "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" - "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> -<policyconfig> - - <vendor>YaST Webservice Project</vendor> - <vendor_url>http://en.opensuse.org/YAST</vendor_url> - - <action id="org.opensuse.yast.modules.yapi.ntp.synchronize"> - <description>One time synchronization agaijn given ntp server</description> - <message>Authentication is required to onetime synchronize with ntp</message> - <defaults> - <allow_inactive>no</allow_inactive> - <allow_active>no</allow_active> - </defaults> - </action> - -</policyconfig> diff --git a/plugins/time/package/yast2-webservice-time.spec b/plugins/time/package/yast2-webservice-time.spec index 67570a2..8f1177f 100644 --- a/plugins/time/package/yast2-webservice-time.spec +++ b/plugins/time/package/yast2-webservice-time.spec @@ -19,8 +19,6 @@ Version: 0.0.3 Release: 0 Summary: YaST2 - Webservice - Time Source: www.tar.bz2 -Source1: NTP.pm -Source2: org.opensuse.yast.modules.yapi.ntp.policy BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildArch: noarch BuildRequires: rubygem-mocha @@ -52,9 +50,6 @@ Authors: # mkdir -p $RPM_BUILD_ROOT/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name} cp -a * $RPM_BUILD_ROOT/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name} -cp ${SOURCE1} $RPM_BUILD_ROOT/usr/share/YaST2/modules/YaPI/ -mkdir -p $RPM_BUILD_ROOT/usr/share/PolicyKit/policy/ -cp ${SOURCE2} $RPM_BUILD_ROOT/usr/share/PolicyKit/policy/ %clean @@ -88,5 +83,3 @@ rm -rf $RPM_BUILD_ROOT /srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/tasks #/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/test /srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/doc/README_FOR_APP -/usr/share/YaST2/modules/YaPI/${SOURCE1} -/usr/share/PolicyKit/policy/${SOURCE2} -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org