gaddygaddy 0.1.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/gaddygaddy-client +10 -0
- data/bin/interval +8 -0
- data/conf/development.yml +0 -0
- data/conf/gaddy.yml +2 -0
- data/conf/log4r.yml +47 -0
- data/conf/test.yml +1 -0
- data/lib/device_info/device_info.rb +60 -0
- data/lib/gaddygaddy-client/chef_files.rb +98 -0
- data/lib/gaddygaddy-client/device_config.rb +0 -0
- data/lib/gaddygaddy-client/espeak.rb +26 -0
- data/lib/gaddygaddy-client/log_data.rb +42 -0
- data/lib/gaddygaddy-client/notification/espeak.rb +32 -0
- data/lib/gaddygaddy-client/notification/file_notification.rb +43 -0
- data/lib/gaddygaddy-client/notification/file_notification.rb~ +36 -0
- data/lib/gaddygaddy-client/notification/sensu.rb +40 -0
- data/lib/gaddygaddy-client/notification/wall.rb +25 -0
- data/lib/gaddygaddy-client/notification.rb +73 -0
- data/lib/gaddygaddy-client/svn-commit.tmp~ +4 -0
- data/lib/gaddygaddy-client.rb +396 -0
- data/lib/gaddygaddy-client.rb~ +425 -0
- data/lib/gg_config/gg_config.rb +162 -0
- data/lib/interval.rb +280 -0
- data/lib/logging/logging.rb +62 -0
- data/lib/utils/hash_monkeypatch.rb +34 -0
- data/lib/utils/request.rb +52 -0
- data/lib/utils/retriable.rb +63 -0
- data/lib/utils/run.rb +20 -0
- data/locales/en.yml +24 -0
- data/locales/sv.yml +11 -0
- metadata +160 -0
data/lib/interval.rb
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
APPLICATION_NAME = "interval"
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'json'
|
5
|
+
require 'logging/logging'
|
6
|
+
require 'systemu'
|
7
|
+
require 'uri'
|
8
|
+
|
9
|
+
SENSU_HOST = "127.0.0.1"
|
10
|
+
|
11
|
+
class Interval
|
12
|
+
include Logging
|
13
|
+
|
14
|
+
##################################################################
|
15
|
+
# Read and parse command line options
|
16
|
+
#
|
17
|
+
def read_options(argv)
|
18
|
+
@options = {}
|
19
|
+
optparse = OptionParser.new do|opts|
|
20
|
+
opts.banner = "Usage: interval [options] -p <proc_name> -c <command_to_run>"
|
21
|
+
|
22
|
+
@options[:proc_name] = nil
|
23
|
+
opts.on( '-p', '--proc_name <name>', 'Process name to use' ) do |proc_name|
|
24
|
+
@options[:proc_name] = proc_name
|
25
|
+
end
|
26
|
+
|
27
|
+
@options[:cmd] = nil
|
28
|
+
opts.on( '-c', '--cmd <path>', 'Command to run' ) do |cmd|
|
29
|
+
@options[:cmd] = cmd
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on( '-u', '--uri_cmd <path>', 'Command to run (URI-encoded)' ) do |ucmd|
|
33
|
+
@options[:cmd] = URI.unescape(ucmd)
|
34
|
+
end
|
35
|
+
|
36
|
+
@options[:config_name] = nil
|
37
|
+
opts.on( '-C', '--config_name <name>', 'Config name to use' ) do |config_name|
|
38
|
+
@options[:config_name] = config_name
|
39
|
+
end
|
40
|
+
|
41
|
+
@options[:home] = nil
|
42
|
+
opts.on( '-h', '--home <home>', 'Home directory of application' ) do |home|
|
43
|
+
@options[:home] = home
|
44
|
+
end
|
45
|
+
|
46
|
+
@options[:log_file] = nil
|
47
|
+
opts.on( '-l', '--logfile FILE', 'Write log to FILE, defaults to STDOUT' ) do |file|
|
48
|
+
@options[:log_file] = file
|
49
|
+
end
|
50
|
+
|
51
|
+
@options[:log_level] = 'info'
|
52
|
+
opts.on( '-L', '--log_level level', 'Set the log level (debug, info, warn, error, fatal)' ) do| level|
|
53
|
+
@options[:log_level] = level
|
54
|
+
end
|
55
|
+
|
56
|
+
@options[:count] = nil
|
57
|
+
opts.on( '-n', '--num <count>', 'Run the command <count> times and then exit (use for testing)' ) do |count|
|
58
|
+
@options[:count] = count.to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
@options[:fail_on_error] = false
|
62
|
+
opts.on( '-f', '--fail_on_error', 'Abort if the program fails' ) do
|
63
|
+
@options[:fail_on_error] = true
|
64
|
+
end
|
65
|
+
|
66
|
+
@options[:sensu_enabled] = false
|
67
|
+
opts.on( '-z', '--sensu', 'Do report status to Sensu' ) do
|
68
|
+
@options[:sensu_enabled] = true
|
69
|
+
end
|
70
|
+
|
71
|
+
@options[:sensu_port] = 3030
|
72
|
+
opts.on( '--sensu_port <port>', Integer, 'Port to talk to sensu on' ) do |port|
|
73
|
+
@options[:sensu_port] = port
|
74
|
+
end
|
75
|
+
|
76
|
+
@options[:status_file] = nil
|
77
|
+
opts.on( '-s', '--status_file <status>', 'File to write last run status to' ) do |status|
|
78
|
+
@options[:status_file] = status
|
79
|
+
end
|
80
|
+
|
81
|
+
@options[:interval] = nil
|
82
|
+
opts.on( '-i', '--interval <interval>', 'Time between runs of program (seconds if no unit is specified)' ) do |interval|
|
83
|
+
@options[:interval] = interval
|
84
|
+
end
|
85
|
+
|
86
|
+
@options[:time_stamp] = nil
|
87
|
+
opts.on( '-t', '--time <time>', 'Run command at a specific time each day, could be comma separated. Format HHMM. Example 1430,0230 will run the command at 14:30 and 02:30 each day' ) do |time|
|
88
|
+
@options[:time_stamp] = time.split(",")
|
89
|
+
end
|
90
|
+
|
91
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
92
|
+
puts opts
|
93
|
+
exit
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
begin
|
98
|
+
optparse.parse!(argv)
|
99
|
+
if @options[:config_name].nil?
|
100
|
+
@options[:config_name] = @options[:proc_name]
|
101
|
+
end
|
102
|
+
mandatory = [:proc_name, :cmd]
|
103
|
+
missing = mandatory.select{ |param| @options[param].nil? }
|
104
|
+
unless missing.empty?
|
105
|
+
STDERR.puts "Missing options: #{missing.join(', ')}"
|
106
|
+
STDERR.puts optparse
|
107
|
+
exit 1
|
108
|
+
end
|
109
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument #
|
110
|
+
STDERR.puts $!.to_s # Friendly output when parsing fails
|
111
|
+
STDERR.puts optparse #
|
112
|
+
exit 1 #
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
##################################################################
|
117
|
+
# Parse a time expression
|
118
|
+
#
|
119
|
+
# The argument should be in one of the following forms
|
120
|
+
# <number> - parsed as seconds
|
121
|
+
# <number>s - parsed as seconds
|
122
|
+
# <number>m - parsed as minutes
|
123
|
+
# <number>h - parsed as hours
|
124
|
+
#
|
125
|
+
# @param s [String] String to parse
|
126
|
+
#
|
127
|
+
# return [Numeric] number of seconds time represents
|
128
|
+
|
129
|
+
def parse_time(s)
|
130
|
+
case s
|
131
|
+
when /^\d+s?$/
|
132
|
+
s.to_i
|
133
|
+
when /^\d+m$/
|
134
|
+
s.to_i * 60
|
135
|
+
when /^\d+h$/
|
136
|
+
s.to_i * 60 * 60
|
137
|
+
else
|
138
|
+
-1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
##################################################################
|
143
|
+
# Store status on disk
|
144
|
+
def store_status(exit_code)
|
145
|
+
if @options[:status_file]
|
146
|
+
File.open(@options[:status_file], 'w') do |f| f.puts("result=#{exit_code}") end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
##################################################################
|
151
|
+
# Fail, exit with an error message
|
152
|
+
def my_fail(msg)
|
153
|
+
logger.fatal msg if logger
|
154
|
+
STDERR.puts msg
|
155
|
+
send_to_sensu(1, "Error running interval for #{@options[:proc_name]}, #{msg}")
|
156
|
+
store_status 1
|
157
|
+
exit 1
|
158
|
+
end
|
159
|
+
|
160
|
+
###################################################################
|
161
|
+
# Send message to sensu
|
162
|
+
#
|
163
|
+
def send_to_sensu(status, message)
|
164
|
+
if @options[:sensu_enabled]
|
165
|
+
report = {
|
166
|
+
:name => "interval_error_#{@options[:proc_name]}",
|
167
|
+
:output => "",
|
168
|
+
:status => status
|
169
|
+
}
|
170
|
+
if status != 0
|
171
|
+
report[:output] = "Failed to run #{@options[:proc_name]} #{message}"
|
172
|
+
end
|
173
|
+
|
174
|
+
begin
|
175
|
+
s = TCPSocket.open(SENSU_HOST, @options[:sensu_port])
|
176
|
+
s.print JSON.generate(report)
|
177
|
+
s.close
|
178
|
+
rescue Exception => e
|
179
|
+
logger.error "Failed to send report to sensu: #{e.message}"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def get_prop(option_name)
|
185
|
+
prop_value = nil
|
186
|
+
if @options[option_name]
|
187
|
+
prop_value = @options[option_name]
|
188
|
+
end
|
189
|
+
logger.debug "Found value #{prop_value} for #{option_name.to_s}"
|
190
|
+
prop_value
|
191
|
+
end
|
192
|
+
|
193
|
+
def run
|
194
|
+
read_options(ARGV)
|
195
|
+
|
196
|
+
# Check binary
|
197
|
+
unless File.executable?(@options[:cmd].split[0])
|
198
|
+
my_fail "Specified binary '#{@options[:cmd]}' does not exist or is not executable"
|
199
|
+
end
|
200
|
+
|
201
|
+
set_log_level @options[:log_level]
|
202
|
+
set_log_file @options[:log_file] if @options[:log_file]
|
203
|
+
|
204
|
+
if @options[:home]
|
205
|
+
Dir.chdir(@options[:home])
|
206
|
+
end
|
207
|
+
|
208
|
+
# Get properties
|
209
|
+
conf_name = @options[:config_name] ? @options[:config_name] : @options[:proc_name]
|
210
|
+
|
211
|
+
begin
|
212
|
+
interval_in = get_prop :interval
|
213
|
+
if interval_in
|
214
|
+
interval = parse_time interval_in
|
215
|
+
logger.info "Using an run interval of #{interval} seconds"
|
216
|
+
if interval < 1
|
217
|
+
my_fail "Illegal interval #{interval} given for property #{conf_name}.run.interval"
|
218
|
+
end
|
219
|
+
|
220
|
+
else
|
221
|
+
time_stamp = get_prop :time_stamp
|
222
|
+
raise "Could not found interval or time_stamp option, one of those is needed" unless time_stamp
|
223
|
+
logger.info "Will run at time stamp #{time_stamp.join(",")}"
|
224
|
+
end
|
225
|
+
rescue StandardError => e
|
226
|
+
puts e.message
|
227
|
+
my_fail "Did not find config value for #{conf_name}"
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
logger.info "Starting interval #{@options.inspect}"
|
232
|
+
|
233
|
+
store_status 0
|
234
|
+
|
235
|
+
count = 0
|
236
|
+
first = true
|
237
|
+
loop do
|
238
|
+
unless time_stamp && first
|
239
|
+
count = count+1
|
240
|
+
logger.info "Launching[#{count}]: #{@options[:cmd]}"
|
241
|
+
result, stdout, stderr = systemu @options[:cmd]
|
242
|
+
store_status result.exitstatus
|
243
|
+
if result != 0
|
244
|
+
logger.error "Failed to run #{@options[:cmd]} (exit code #{result})"
|
245
|
+
logger.error "Stdout: #{stdout.strip}" if stdout.length > 0
|
246
|
+
logger.error "Stderr: #{stderr.strip}" if stderr.length > 0
|
247
|
+
send_to_sensu(1, "Result is #{result}. Stderr is: #{stderr}, stdout is #{stdout}")
|
248
|
+
if @options[:fail_on_error]
|
249
|
+
exit result
|
250
|
+
end
|
251
|
+
else
|
252
|
+
logger.info "Command completed successfully"
|
253
|
+
logger.info "Stdout: #{stdout.strip}" if stdout.length > 0
|
254
|
+
send_to_sensu(0, "")
|
255
|
+
end
|
256
|
+
end
|
257
|
+
first = false
|
258
|
+
|
259
|
+
if @options[:count] && count >= @options[:count]
|
260
|
+
exit 0
|
261
|
+
end
|
262
|
+
if time_stamp
|
263
|
+
diff = []
|
264
|
+
time_stamp.each do |time|
|
265
|
+
current = Time.now.strftime("%H%M%S")
|
266
|
+
diff_time = ((time[0..1].to_i * 60 + time[2..3].to_i) - (current[0..1].to_i * 60 + current[2..3].to_i))*60 - current[4..5].to_i
|
267
|
+
diff_time += 24*60*60 if diff_time <= 0
|
268
|
+
diff << diff_time
|
269
|
+
end
|
270
|
+
logger.debug "sleep for #{diff.min + 1} seconds"
|
271
|
+
sleep diff.min + 1
|
272
|
+
else
|
273
|
+
logger.debug "sleep for #{interval} seconds"
|
274
|
+
sleep interval
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# logging.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
require 'log4r'
|
17
|
+
require 'log4r/outputter/datefileoutputter'
|
18
|
+
require 'log4r/yamlconfigurator'
|
19
|
+
|
20
|
+
module Logging
|
21
|
+
# This is the magical bit that gets mixed into your classes
|
22
|
+
@@log_conf = const_defined?(:APPLICATION_NAME) ? APPLICATION_NAME : "default"
|
23
|
+
|
24
|
+
def logger
|
25
|
+
Logging.logger
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_log_level(level_str)
|
29
|
+
logger.level = (Log4r::Log4rConfig::LogLevels.index level_str.upcase) + 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_log_file(new_filename)
|
33
|
+
format = Log4r::PatternFormatter.new(:pattern => "[%5l] %d :: %m", :date_pattern => '%y%m%d %H:%M:%S')
|
34
|
+
dir_name = File.dirname(new_filename)
|
35
|
+
file_name = File.basename(new_filename)
|
36
|
+
logger.outputters << Log4r::DateFileOutputter.new('log_file', :filename => file_name, :dirname => dir_name, :formatter => format, :date_pattern => '%Y%m%d')
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.set_log_conf log_conf
|
40
|
+
@@log_conf = log_conf
|
41
|
+
end
|
42
|
+
|
43
|
+
# create a new log4r logger with config
|
44
|
+
|
45
|
+
def self.create_logger
|
46
|
+
log_cfg = Log4r::YamlConfigurator
|
47
|
+
conf_file = File.join(File.dirname(__FILE__), "..", "..", "conf","log4r.yml")
|
48
|
+
log_cfg.load_yaml_file(conf_file)
|
49
|
+
|
50
|
+
# app logger
|
51
|
+
new_logger = Log4r::Logger[@@log_conf]
|
52
|
+
raise "Missing logger config #{@@log_conf} in log config file #{conf_file}" unless new_logger
|
53
|
+
new_logger.level = Log4r::INFO
|
54
|
+
new_logger.info "Log initiated"
|
55
|
+
new_logger
|
56
|
+
end
|
57
|
+
|
58
|
+
# Global, memoized, lazy initialized instance of a logger
|
59
|
+
def self.logger
|
60
|
+
@logger ||= create_logger
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# hash.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
class Hash
|
17
|
+
# Return a new hash with all keys converted to symbols, as long as
|
18
|
+
# they respond to +to_sym+.
|
19
|
+
#
|
20
|
+
# { 'name' => 'Rob', 'years' => '28' }.symbolize_keys
|
21
|
+
# #=> { :name => "Rob", :years => "28" }
|
22
|
+
def symbolize_keys
|
23
|
+
dup.symbolize_keys!
|
24
|
+
end
|
25
|
+
|
26
|
+
# Destructively convert all keys to symbols, as long as they respond
|
27
|
+
# to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
|
28
|
+
def symbolize_keys!
|
29
|
+
keys.each do |key|
|
30
|
+
self[(key.to_sym rescue key) || key] = delete(key)
|
31
|
+
end
|
32
|
+
self
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# requests.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
require 'cgi'
|
16
|
+
|
17
|
+
require_relative '../utils/retriable'
|
18
|
+
require_relative '../logging/logging'
|
19
|
+
class Request
|
20
|
+
extend Logging
|
21
|
+
extend Retriable
|
22
|
+
|
23
|
+
# Get a base url for accessing the client service
|
24
|
+
# TODO Change this to https but we need a certificate for that
|
25
|
+
def self.get_base_url(host)
|
26
|
+
url = host
|
27
|
+
url = "http://" + url unless url[0..3] == "http"
|
28
|
+
url
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
#
|
33
|
+
# Will do a request
|
34
|
+
# path will be evaluated so there could be parameters in that one and then use '' for the string
|
35
|
+
# to have the parameters evaluated in this function
|
36
|
+
#
|
37
|
+
def self.client_service_get(host, path)
|
38
|
+
url = get_base_url(host) + path
|
39
|
+
logger.debug "Will request url #{url}"
|
40
|
+
result = with_retries(:limit => 10, :sleep=> 5) { RestClient.get url }
|
41
|
+
result_json = JSON.parse(result)
|
42
|
+
logger.debug "The result of the request is #{result.inspect}"
|
43
|
+
result_json
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.client_service_post(url, param)
|
47
|
+
logger.debug "Will request url #{url}"
|
48
|
+
result = with_retries(:limit => 10, :sleep=> 5) { RestClient.post url, param }
|
49
|
+
JSON.parse(result)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# retriable.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
|
12
|
+
module Retriable
|
13
|
+
|
14
|
+
@@test_mode = false
|
15
|
+
|
16
|
+
# This will catch any exception and retry twice (three tries total):
|
17
|
+
# with_retries { ... }
|
18
|
+
#
|
19
|
+
# This will catch any exception and retry four times (five tries total):
|
20
|
+
# with_retries(:limit => 5) { ... }
|
21
|
+
#
|
22
|
+
# This will catch a specific exception and retry once (two tries total):
|
23
|
+
# with_retries(Some::Error, :limit => 2) { ... }
|
24
|
+
#
|
25
|
+
# You can also sleep inbetween tries. This is helpful if you're hoping
|
26
|
+
# that some external service recovers from its issues.
|
27
|
+
# with_retries(Service::Error, :sleep => 1) { ... }
|
28
|
+
#
|
29
|
+
def with_retries(*args, &block)
|
30
|
+
|
31
|
+
options = extract_options args
|
32
|
+
exceptions = args
|
33
|
+
|
34
|
+
options[:limit] ||= 3
|
35
|
+
options[:limit] = 0 if @@test_mode
|
36
|
+
options[:sleep] ||= 0
|
37
|
+
exceptions = [Exception] if exceptions.empty?
|
38
|
+
|
39
|
+
retried = 0
|
40
|
+
begin
|
41
|
+
yield
|
42
|
+
rescue *exceptions => e
|
43
|
+
logger.warn "Could not do command, will retry. Error message is #{e.inspect.to_s}"
|
44
|
+
if retried + 1 < options[:limit]
|
45
|
+
retried += 1
|
46
|
+
sleep options[:sleep]
|
47
|
+
retry
|
48
|
+
else
|
49
|
+
raise e
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def extract_options(array)
|
55
|
+
array.last.is_a?(::Hash) ? array.pop : {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.set_test_mode
|
59
|
+
@@test_mode = true
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
end
|
data/lib/utils/run.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# run.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
|
17
|
+
def run_cmd(cmd)
|
18
|
+
status, stdout, stderr = systemu cmd
|
19
|
+
raise "Could not run command: #{cmd}, stdout is #{stdout}, error message is #{stderr}" if status != 0
|
20
|
+
end
|
data/locales/en.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
en:
|
2
|
+
event:
|
3
|
+
converge:
|
4
|
+
chef_failed: ! 'Installation of gaddy failed. Please contact the support. Installation failed at %s. Reason: %s and %s'
|
5
|
+
chef_failed_v1: ! 'Installation of gaddy failed. Please contact the support. Installation failed at %s. Reason: %s'
|
6
|
+
ok: The device has been successful installed
|
7
|
+
repair: Repair of installation done.
|
8
|
+
usb_drive_missing: A USB drive is not connected. It should be connected as %s
|
9
|
+
init:
|
10
|
+
config_updated: The device has been succesfully initiated, installation will now start
|
11
|
+
connected: The device is successful connected to internet
|
12
|
+
install:
|
13
|
+
installation_begin: Installation of gApp %s has started
|
14
|
+
installation_failed: Installation of gApp %s failed. The gApp is not running
|
15
|
+
installation_finished: Installation of gApp %s is finished
|
16
|
+
log:
|
17
|
+
error: Error in log %s message %s
|
18
|
+
not_running: ! '%s not working. '
|
19
|
+
not_running_v1: gApp is not running
|
20
|
+
ok: Running normally
|
21
|
+
spotify_config_not_ok: There is a problem with the Spotify configuration. Try to update username and password
|
22
|
+
vpn_proxy:
|
23
|
+
missing_user_or_password: Missing user name or password for vpn_proxy, check gApp
|
24
|
+
no_connection: Could not connect to the VPN server, check configuration
|