ref: refs/heads/resource-restful
commit 3227e82ff5129bb3f0bd15af086b6a91fc8cf448
Author: Josef Reidinger
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>
+ http://en.opensuse.org/YAST
+
+ <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>
+ no
+ no
+ </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
+
+%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>
- http://en.opensuse.org/YAST
-
- <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>
- no
- no
- </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