ref: refs/heads/resource-restful
commit 9fc8d20ee79c86983f1bb66d876c386c9bb7026e
Author: Duncan Mac-Vicar P
Date: Wed Sep 9 18:11:34 2009 +0200
allow only defined logs
---
plugins/status/app/controllers/logs_controller.rb | 58 ++++
.../status/app/controllers/metrics_controller.rb | 89 ++++++
plugins/status/app/models/metric.rb | 302 ++++++++++++++++++++
plugins/status/config/resources/logs.yml | 4 +
plugins/status/config/resources/metrics.yml | 4 +
plugins/status/lib/metric.rb | 269 -----------------
plugins/status/test/unit/metric_test.rb | 7 +-
webservice/app/controllers/logs_controller.rb | 39 ---
webservice/test/unit/vendor_setting_test.rb | 3 +
9 files changed, 466 insertions(+), 309 deletions(-)
diff --git a/plugins/status/app/controllers/logs_controller.rb b/plugins/status/app/controllers/logs_controller.rb
new file mode 100644
index 0000000..7ee0d88
--- /dev/null
+++ b/plugins/status/app/controllers/logs_controller.rb
@@ -0,0 +1,58 @@
+require 'scr'
+#require 'vendor_setting'
+require 'yast/config_file'
+
+class LogsController < ApplicationController
+ CONFIG_FILE="/etc/YaST2/vendor/logs.yml"
+
+ def initialize
+ @cfg = case File.exists?(CONFIG_FILE)
+ when true then YaST::ConfigFile.new("/etc/YaST2/vendor/logs.yml")
+ else {}
+ end
+ end
+
+ def index
+ xml = Builder::XmlMarkup.new
+ xml.instruct!
+
+ xml.logs(:type => :array) do
+ @cfg.each do |logid, logdata|
+ xml.log do
+ xml.id logid
+ xml.path logdata["path"]
+ xml.description logdata["description"]
+ end
+ end
+ end
+
+ respond_to do |format|
+ format.xml { render :xml => xml.target! }
+ end
+ end
+
+ def show
+
+ # find the configured logs, use /var/log/messages
+ # as default
+ id = params[:id]
+ if !@cfg.has_key?(id) or ! @cfg[id].has_key?('path')
+ render :nothing => true, :status => 404 and return
+ end
+
+ log_filename = @cfg[id]['path']
+
+ # how many lines to show
+ lines = case params[:lines]
+ when nil then 50
+ else params[:lines].to_i
+ end
+
+ output = Scr.instance.execute(['tail', '-n', "#{lines}", log_filename])
+
+ respond_to do |format|
+ format.text { render :xml => output[:stdout] }
+ end
+ end
+
+end
diff --git a/plugins/status/app/controllers/metrics_controller.rb b/plugins/status/app/controllers/metrics_controller.rb
new file mode 100644
index 0000000..d9d4221
--- /dev/null
+++ b/plugins/status/app/controllers/metrics_controller.rb
@@ -0,0 +1,89 @@
+include ApplicationHelper
+
+require 'scr'
+require 'metric'
+
+class MetricsController < ApplicationController
+ before_filter :login_required
+
+ private
+
+ def create_limit(status, label = "", limits = {})
+ if status.is_a? Hash
+ status.each do |key, value|
+ if key=="limit" && value.is_a?(Hash) && value["value"].to_f>0
+ limit = Hash.new
+ limit["value"] = value["value"].to_f
+ limit["maximum"] = value["maximum"]
+ limits[label] = limit
+ end
+ next_label = ""
+ if label.blank?
+ next_label = key
+ else
+ next_label = label+ "/" + key
+ end
+ create_limit(value, next_label, limits) if value.is_a? Hash
+ end
+ end
+ return limits
+ end
+
+ public
+
+ # POST /status
+ # POST /status.xml
+ def create
+ permission_check("org.opensuse.yast.system.status.writelimits")
+
+ #find the correct plugin path for the config file
+ plugin_config_dir = "#{RAILS_ROOT}/config" #default
+ Rails.configuration.plugin_paths.each do |plugin_path|
+ if File.directory?(File.join(plugin_path, "status"))
+ plugin_config_dir = plugin_path+"/status/config"
+ Dir.mkdir(plugin_config_dir) unless File.directory?(plugin_config_dir)
+ break
+ end
+ end
+ limits = Hash.new
+ limits = create_limit(params["status"])
+ f = File.open(File.join(plugin_config_dir, "status_limits.yaml"), "w")
+ f.write(limits.to_yaml)
+ f.close
+
+ @status = Status.new
+ # use now if time is not valid
+ begin
+ stop = params[:stop].blank? ? Time.now : Time.at(params[:stop].to_i)
+ start = params[:start].blank? ? stop - 300 : Time.at(params[:start].to_i)
+ @status.collect_data(start, stop, params[:data])
+ render :show
+ rescue Exception => e
+ render :text => e.to_s, :status => 400 # bad request
+ end
+ end
+
+ # GET /status
+ # GET /status.xml
+ def index
+ opts = {}
+ opts.merge!(params)
+ @metrics = Metric.find(:all, opts)
+
+ end
+
+ # GET /status/1
+ # GET /status/1.xml
+ def show
+ #permission_check("org.opensuse.yast.system.status.read")
+ @metrics =
+ begin
+ @status = Status.new
+ stop = params[:stop].blank? ? Time.now : Time.at(params[:stop].to_i)
+ start = params[:start].blank? ? stop - 300 : Time.at(params[:start].to_i)
+ @status.collect_data(start, stop, params[:data])
+ rescue Exception => e
+ render :text => e.to_s, :status => 400 # bad request
+ end
+ end
+end
diff --git a/plugins/status/app/models/metric.rb b/plugins/status/app/models/metric.rb
new file mode 100644
index 0000000..c19f8ee
--- /dev/null
+++ b/plugins/status/app/models/metric.rb
@@ -0,0 +1,302 @@
+#
+# Model over collectd data
+#
+# @author Bjoern Geuken
+# @author Duncan Mac-Vicar P.
+# @author Stefan Schubert
+#
+require 'scr'
+require 'yaml'
+
+#
+# This class acts as a model for metrics provided by collectd
+# each round robin database
+#
+# By default the model operates in the current host, or in the
+# first available one, unless overriden by the :host option
+#
+# each value has an identifier based on
+# host, plugin, plugin instance, type and type instance
+# See http://collectd.org/wiki/index.php/Naming_schema
+#
+# for the naming schema of a metric
+# metrics = Metric.find(:all, :plugin => /cpu/)
+# metrics.each do |metric|
+# metric.type
+# metric.type_instance
+# metric.plugin
+# metric.plugin_instance
+# metric.host
+# metric.data(:stop => Time.now - 5000)
+# end
+#
+class Metric
+
+ COLLECTD_BASE = "/var/lib/collectd"
+
+ # path to the round robin database for this value
+ attr_reader :path
+ attr_reader :host
+ attr_reader :plugin, :plugin_instance
+ attr_reader :type, :type_instance
+ # convenience, plugin and instance
+ attr_reader :plugin_full
+ attr_reader :type_full
+
+ # alias for identifier
+ def id
+ identifier
+ end
+
+ def identifier
+ [host, plugin_full, type_full].join('/')
+ end
+
+ # plugin and plugin instance ie: cpu-0
+ def plugin_full
+ return plugin if plugin_instance.blank?
+ "#{plugin}-#{plugin_instance}"
+ end
+
+ # type and type instance, ie: memory-free
+ def type_full
+ return type if type_instance.blank?
+ "#{type}-#{type_instance}"
+ end
+
+ # returns available hosts for which metrics are collected
+ def self.available_hosts
+ Dir.glob(File.join(COLLECTD_BASE, "*")).reject{|x| not File.directory?(x) }.map{|x| File.basename(x) }
+ end
+
+ # whether there is data available for a given host
+ def self.host_available?(host)
+ available_hosts.include?(host)
+ end
+
+ # returns the hostname of the running
+ # host or nil if not available
+ def self.this_hostname
+ Socket.gethostbyname(Socket.gethostname).first rescue nil
+ end
+
+ # what host should be used if host is not
+ # specified
+ #
+ # we try to use the running system hostname
+ # or the first hostname with data available
+ def self.default_host
+ # try to get the real hostname
+ hostname = this_hostname
+ hosts = available_hosts
+ return case
+ # if data exists for it, then this is the default
+ when host_available?(hostname) then hostname
+ when !hosts.empty? then hosts.first
+ else raise "Can't determine default host to read metric from"
+ end
+ end
+
+ # returns true if collectd daemon is running
+ def self.collectd_running?
+ ret = Scr.instance.execute(["/usr/sbin/rccollectd", "status"])
+ ret[:exit].zero?
+ end
+
+ #
+ def self.plugins
+ Metric.find(:all).map { |x| x.plugin }
+ end
+
+ # avaliable databases for a host
+ def self.rrd_files
+ Dir.glob(File.join(COLLECTD_BASE, '**/*.rrd'))
+ end
+
+ # initialize with the path to the rrdb database
+ def initialize(path)
+ @path = path
+ # these values can be extracted from the file but we cache
+ # them
+ @host, @plugin, @plugin_instance, @type, @type_instance = Metric.parse_file_path(path)
+ end
+
+ # parses the host, plugin, plugin_instance, type and type_instance
+ # from the file name
+ def self.parse_file_path(path)
+ type_full = File.basename(path, '.rrd')
+ plugin_instance_path = File.dirname(path)
+ plugin_full = File.basename(plugin_instance_path)
+ host_path = File.dirname(plugin_instance_path)
+ host = File.basename(host_path)
+
+ type, type_instance = type_full.split('-', 2)
+ plugin, plugin_instance = plugin_full.split('-', 2)
+
+ return host, plugin, plugin_instance, type, type_instance
+ end
+
+ # Finds metrics.
+ #
+ # Metric.find(:all)
+ # Metric.find(:all, group => "cpu-1")
+ # Metric.find(id)
+ # Where id is host:group:name (whithout rrd extension)
+ def self.find(what, opts={})
+ case what
+ when :all then opts.empty? ? find_all : find_multiple(opts)
+ # in this case, the options are the first
+ # parameter
+ when Hash
+ else find_multiple(what.merge(opts))
+ end
+ end
+
+ # find all values
+ def self.find_all
+ ret = []
+ rrd_files.each do |path|
+ ret << Metric.new(path)
+ end
+ ret
+ end
+
+ def self.find_multiple(opts)
+ ret = []
+
+ # think how to factor this out
+ opts[:host] = default_host if not opts.has_key?(:host)
+
+ all = Metric.find(:all)
+ all.each do |metric|
+ matched = true
+ # match each attribute passed in opts
+ opts.each do |key, val|
+ raise "Unknown attribute #{key}" if not metric.respond_to?(key)
+ # if the val is a regexp we do different matching
+ if val.is_a?(Regexp)
+ matched = false if not metric.send(key) =~ val
+ else
+ matched = false if metric.send(key) != val
+ end
+ end
+ # go to next value if this does not match
+ next if not matched
+ ret << metric
+ end
+ ret
+ end
+
+ # returns data for a given period of time
+ # range can be specified with the :start and
+ # :stop options
+ #
+ # default last 5 minutes from now
+ #
+ # result is a hash of the type:
+ # { column1 => { time1 => value1, time2 => value2, ...}, ...}
+ #
+ def data(opts={})
+ Metric.read_metric_file(path, opts)
+ end
+
+ # converts the metric to xml
+ def to_xml(opts={})
+ data_opts = {}
+ data_opts[:start] = opts[:start] if opts.has_key?(:start)
+ data_opts[:stop] = opts[:stop] if opts.has_key?(:stop)
+
+ metric_data = data(data_opts)
+ starttime = metric_data['starttime']
+ interval = metric_data['interval']
+
+ xml = opts[:builder] ||= Builder::XmlMarkup.new(opts)
+ xml.instruct! unless opts[:skip_instruct]
+
+ xml.metric do
+ xml.id self.identifier
+ xml.host self.host
+ xml.plugin self.plugin
+ xml.plugin_instance self.plugin_instance
+ xml.type self.type
+ xml.type_instance self.type_instance
+
+ metric_data.each do |col, values|
+ next if col == "starttime"
+ next if col == "interval"
+ xml.data(:column => col, :start => starttime, :interval => interval ) do
+ values.each { |time, value| xml.value value }
+ end
+ end
+
+ end
+
+ end
+
+ # runs the rddtool on file with start time and end time
+ #
+ # You can pass start and stop options:
+ # Metric.run_rrdtool(file, :start => t1, :stop => t2)
+ #
+ # default last 5 minutes from now
+ def self.run_rrdtool(file, opts={})
+ stop = opts.has_key?(:stop) ? opts[:stop] : Time.now
+ start = opts.has_key?(:stop) ? opts[:stop] : stop - 300
+
+ cmd = IO.popen("rrdtool fetch #{file} AVERAGE --start #{start.strftime("%H:%M,%m/%d/%Y")} --end #{stop.strftime("%H:%M,%m/%d/%Y")}")
+ output = cmd.read
+ cmd.close
+ output
+ end
+
+ def self.read_metric_file(rrdfile, opts={})
+ result = Hash.new
+ output = run_rrdtool(rrdfile, opts)
+
+ raise "Error running collectd rrdtool" if output =~ /ERROR/ or output.nil?
+
+ labels=""
+ output = output.gsub(",", ".") # translates eg. 1,234e+07 to 1.234e+07
+ lines = output.split "\n"
+
+ # set label names
+ lines[0].each do |l|
+ if l =~ /\D*/
+ labels = l.split " "
+ end
+ end
+ unless labels.blank?
+ # set values for each label and time
+ # evaluates interval and starttime once for each metric (not each label)
+ nexttime = 9.9e+99
+ result["starttime"] = 9.9e+99
+ lines.each do |l| # each time
+ next if l.blank?
+ if l =~ /\d*:\D*/
+ pair = l.split ":"
+ values = pair[1].split " "
+ column = 0
+ values.each do |v| # each label
+ unless result["interval"] # already defined?
+ # get the least distance to evaluate time interval
+ if pair[0].to_i < result["starttime"].to_i
+ result["starttime"] = pair[0].to_i
+ elsif pair[0].to_i < nexttime and pair[0].to_i > result["starttime"].to_i
+ nexttime = pair[0].to_i
+ end
+ end
+ v = "invalid" if v == "nan" #store valid values only
+ result[labels[column]] ||= Hash.new
+ result[labels[column]][pair[0]] = v
+ column += 1
+ end
+ end
+ end
+ result["interval"] = nexttime.to_i - result["starttime"].to_i if result["interval"].nil?
+ return result
+ else
+ raise "error reading data from rrdtool"
+ end
+ end
+
+end
diff --git a/plugins/status/config/resources/logs.yml b/plugins/status/config/resources/logs.yml
new file mode 100644
index 0000000..aae7514
--- /dev/null
+++ b/plugins/status/config/resources/logs.yml
@@ -0,0 +1,4 @@
+interface: org.opensuse.yast.system.logs
+controller: logs
+singular: false
+
diff --git a/plugins/status/config/resources/metrics.yml b/plugins/status/config/resources/metrics.yml
new file mode 100644
index 0000000..546d225
--- /dev/null
+++ b/plugins/status/config/resources/metrics.yml
@@ -0,0 +1,4 @@
+interface: org.opensuse.yast.system.metrics
+controller: metrics
+singular: false
+
diff --git a/plugins/status/lib/metric.rb b/plugins/status/lib/metric.rb
deleted file mode 100644
index 85d859f..0000000
--- a/plugins/status/lib/metric.rb
+++ /dev/null
@@ -1,269 +0,0 @@
-#
-# Model over collectd data
-#
-# @author Bjoern Geuken
-# @author Duncan Mac-Vicar P.
-# @author Stefan Schubert
-#
-require 'scr'
-require 'yaml'
-
-#
-# This class acts as a model for metrics provided by collectd
-# each round robin database
-#
-# By default the model operates in the current host, or in the
-# first available one, unless overriden by the :host option
-#
-# each value has an identifier based on
-# host, plugin, plugin instance, type and type instance
-# See http://collectd.org/wiki/index.php/Naming_schema
-#
-# for the naming schema of a metric
-# metrics = Metric.find(:all, :plugin => /cpu/)
-# metrics.each do |metric|
-# metric.type
-# metric.type_instance
-# metric.plugin
-# metric.plugin_instance
-# metric.host
-# metric.data(:stop => Time.now - 5000)
-# end
-#
-class Metric
-
- COLLECTD_BASE = "/var/lib/collectd"
-
- # path to the round robin database for this value
- attr_reader :path
- attr_reader :host
- attr_reader :plugin, :plugin_instance
- attr_reader :type, :type_instance
- # convenience, plugin and instance
- attr_reader :plugin_full
- attr_reader :type_full
-
- # alias for identifier
- def id
- identifier
- end
-
- def identifier
- [host, plugin_full, type_full].join('/')
- end
-
- # plugin and plugin instance ie: cpu-0
- def plugin_full
- return plugin if plugin_instance.blank?
- "#{plugin}-#{plugin_instance}"
- end
-
- # type and type instance, ie: memory-free
- def type_full
- return type if type_instance.blank?
- "#{type}-#{type_instance}"
- end
-
- # returns available hosts for which metrics are collected
- def self.available_hosts
- Dir.glob(File.join(COLLECTD_BASE, "*")).reject{|x| not File.directory?(x) }.map{|x| File.basename(x) }
- end
-
- # whether there is data available for a given host
- def self.host_available?(host)
- available_hosts.include?(host)
- end
-
- # returns the hostname of the running
- # host or nil if not available
- def self.this_hostname
- Socket.gethostbyname(Socket.gethostname).first rescue nil
- end
-
- # what host should be used if host is not
- # specified
- #
- # we try to use the running system hostname
- # or the first hostname with data available
- def self.default_host
- # try to get the real hostname
- hostname = this_hostname
- hosts = available_hosts
- return case
- # if data exists for it, then this is the default
- when host_available?(hostname) then hostname
- when !hosts.empty? then hosts.first
- else raise "Can't determine default host to read metric from"
- end
- end
-
- # returns true if collectd daemon is running
- def self.collectd_running?
- ret = Scr.instance.execute(["/usr/sbin/rccollectd", "status"])
- ret[:exit].zero?
- end
-
- #
- def self.plugins
- Metric.find(:all).map { |x| x.plugin }
- end
-
- # avaliable databases for a host
- def self.rrd_files
- Dir.glob(File.join(COLLECTD_BASE, '**/*.rrd'))
- end
-
- # initialize with the path to the rrdb database
- def initialize(path)
- @path = path
- # these values can be extracted from the file but we cache
- # them
- @host, @plugin, @plugin_instance, @type, @type_instance = Metric.parse_file_path(path)
- end
-
- # parses the host, plugin, plugin_instance, type and type_instance
- # from the file name
- def self.parse_file_path(path)
- type_full = File.basename(path, '.rrd')
- plugin_instance_path = File.dirname(path)
- plugin_full = File.basename(plugin_instance_path)
- host_path = File.dirname(plugin_instance_path)
- host = File.basename(host_path)
-
- type, type_instance = type_full.split('-', 2)
- plugin, plugin_instance = plugin_full.split('-', 2)
-
- return host, plugin, plugin_instance, type, type_instance
- end
-
- # Finds metrics.
- #
- # Metric.find(:all)
- # Metric.find(:all, group => "cpu-1")
- # Metric.find(id)
- # Where id is host:group:name (whithout rrd extension)
- def self.find(what, opts={})
- case what
- when :all then opts.empty? ? find_all : find_multiple(opts)
- # in this case, the options are the first
- # parameter
- when Hash
- else find_multiple(what.merge(opts))
- end
- end
-
- # find all values
- def self.find_all
- ret = []
- rrd_files.each do |path|
- ret << Metric.new(path)
- end
- ret
- end
-
- def self.find_multiple(opts)
- ret = []
-
- # think how to factor this out
- opts[:host] = default_host if not opts.has_key?(:host)
-
- all = Metric.find(:all)
- all.each do |metric|
- matched = true
- # match each attribute passed in opts
- opts.each do |key, val|
- raise "Unknown attribute #{key}" if not metric.respond_to?(key)
- # if the val is a regexp we do different matching
- if val.is_a?(Regexp)
- matched = false if not metric.send(key) =~ val
- else
- matched = false if metric.send(key) != val
- end
- end
- # go to next value if this does not match
- next if not matched
- ret << metric
- end
- ret
- end
-
- # returns data for a given period of time
- # range can be specified with the :start and
- # :stop options
- #
- # default last 5 minutes from now
- #
- # result is a hash of the type:
- # { column1 => { time1 => value1, time2 => value2, ...}, ...}
- #
- def data(opts={})
- Metric.read_metric_file(path, opts)
- end
-
- # runs the rddtool on file with start time and end time
- #
- # You can pass start and stop options:
- # Metric.run_rrdtool(file, :start => t1, :stop => t2)
- #
- # default last 5 minutes from now
- def self.run_rrdtool(file, opts={})
- stop = opts.has_key?(:stop) ? opts[:stop] : Time.now
- start = opts.has_key?(:stop) ? opts[:stop] : stop - 300
-
- cmd = IO.popen("rrdtool fetch #{file} AVERAGE --start #{start.strftime("%H:%M,%m/%d/%Y")} --end #{stop.strftime("%H:%M,%m/%d/%Y")}")
- output = cmd.read
- cmd.close
- output
- end
-
- def self.read_metric_file(rrdfile, opts={})
- result = Hash.new
- output = run_rrdtool(rrdfile, opts)
-
- raise "Error running collectd rrdtool" if output =~ /ERROR/ or output.nil?
-
- labels=""
- output = output.gsub(",", ".") # translates eg. 1,234e+07 to 1.234e+07
- lines = output.split "\n"
-
- # set label names
- lines[0].each do |l|
- if l =~ /\D*/
- labels = l.split " "
- end
- end
- unless labels.blank?
- # set values for each label and time
- # evaluates interval and starttime once for each metric (not each label)
- nexttime = 9.9e+99
- result["starttime"] = 9.9e+99
- lines.each do |l| # each time
- next if l.blank?
- if l =~ /\d*:\D*/
- pair = l.split ":"
- values = pair[1].split " "
- column = 0
- values.each do |v| # each label
- unless result["interval"] # already defined?
- # get the least distance to evaluate time interval
- if pair[0].to_i < result["starttime"].to_i
- result["starttime"] = pair[0].to_i
- elsif pair[0].to_i < nexttime and pair[0].to_i > result["starttime"].to_i
- nexttime = pair[0].to_i
- end
- end
- v = "invalid" if v == "nan" #store valid values only
- result[labels[column]] ||= Hash.new
- result[labels[column]][pair[0]] = v
- column += 1
- end
- end
- end
- result["interval"] = nexttime.to_i - result["starttime"].to_i if result["interval"].nil?
- return result
- else
- raise "error reading data from rrdtool"
- end
- end
-
-end
diff --git a/plugins/status/test/unit/metric_test.rb b/plugins/status/test/unit/metric_test.rb
index 6ae1a4e..867a638 100644
--- a/plugins/status/test/unit/metric_test.rb
+++ b/plugins/status/test/unit/metric_test.rb
@@ -75,7 +75,12 @@ class MetricTest < ActiveSupport::TestCase
"starttime"=>1252075500}
assert_equal expected, packets.data(:start => start, :stop => stop)
-
+
+ require 'pp'
+ pp packets.data(:start => start, :stop => stop)
+
+ assert_equal "", packets.to_xml(:start => start, :stop => stop)
+ #assert_equal "", packets.to_xml
end
def test_collectd_running
diff --git a/webservice/app/controllers/logs_controller.rb b/webservice/app/controllers/logs_controller.rb
deleted file mode 100644
index d3a975f..0000000
--- a/webservice/app/controllers/logs_controller.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'scr'
-
-class LogsController < ApplicationController
-
- def index
- end
-
- def show
-
- log_filename = case params[:id]
- when "messages" then '/var/log/messages'
- when "apache_access" then '/var/log/apache2/access_log'
- when "apache_error" then '/var/log/apache2/error_log'
- when "custom"
- # if a custom log is requested, then
- # we evaluate a filename parameter
- params[:filename].blank? ? nil : params[:filename]
- else params[:id]
- end
-
- # not found
- if log_filename.nil? or not File.exist?(log_filename)
- render :nothing => true, :status => 404 and return
- end
-
- # how many lines to show
- lines = case params[:lines]
- when nil then 50
- else params[:lines].to_i
- end
-
- output = Scr.instance.execute(['tail', '-n', "#{lines}", log_filename])
-
- respond_to do |format|
- format.text { render :xml => output[:stdout] }
- end
- end
-
-end
diff --git a/webservice/test/unit/vendor_setting_test.rb b/webservice/test/unit/vendor_setting_test.rb
index 2c29925..ba2a793 100644
--- a/webservice/test/unit/vendor_setting_test.rb
+++ b/webservice/test/unit/vendor_setting_test.rb
@@ -22,6 +22,9 @@ eula:
This is an evil eula that will
make you think twice before
clicking it
+logs:
+ - /var/log/messages
+ - /var/log/apache2/access_log
EOF
YaST::ConfigFile.stubs(:read_file).with('/etc/YaST2/vendor.yml').returns(@config_data)
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org