dust-deploy 0.13.3 → 0.13.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,16 @@
1
1
  Changelog
2
2
  =============
3
3
 
4
+ 0.13.4
5
+ ------------
6
+
7
+ - adds cron recipe that maintains cronjobs
8
+
9
+ recipes:
10
+ cron:
11
+ mycronjob_name: { minute: '*/1', command: 'my command' }
12
+
13
+
4
14
  0.13.3
5
15
  ------------
6
16
 
@@ -74,6 +74,11 @@ class String
74
74
  rescue NameError
75
75
  false
76
76
  end
77
+
78
+ # checks if string is a valid integer
79
+ def is_int?
80
+ true if Integer(self) rescue false
81
+ end
77
82
  end
78
83
 
79
84
 
@@ -0,0 +1,161 @@
1
+ class Cron < Recipe
2
+
3
+ desc 'cron:deploy', 'maintains cronjobs'
4
+ def deploy
5
+ # check config
6
+ # install cron
7
+ # enable name: remove to remove a job
8
+
9
+ unless @node.dir_exists? '/etc/cron.d'
10
+ return @node.messages.add('your system does not support /etc/cron.d').failed
11
+ end
12
+
13
+ @config.each do |name, job|
14
+ # remove job if requested
15
+ if job == 'remove'
16
+ remove(name)
17
+ next
18
+ end
19
+
20
+ @node.messages.add("processing cronjob '#{name}'\n")
21
+
22
+ # apply default settings, unless set
23
+ job = default_job.merge job
24
+
25
+ parse_cronjob(job)
26
+ next unless check_cronjob(job)
27
+ cronjob = generate_cronjob(job)
28
+
29
+ # deploy rule file
30
+ msg = @node.messages.add('deploying', :indent => 2)
31
+ msg.parse_result(@node.write("/etc/cron.d/#{name}", cronjob, :quiet => true))
32
+ end
33
+ end
34
+
35
+
36
+ private
37
+
38
+ # removes all files in /etc/cron.d/
39
+ def remove(name)
40
+ msg = @node.messages.add("removing cronjob #{name}")
41
+ msg.parse_result(@node.rm("/etc/cron.d/#{name}", :quiet => true))
42
+ end
43
+
44
+ # default settings for a cronjob
45
+ def default_job
46
+ { 'minute' => '*', 'hour' => '*', 'monthday' => '*',
47
+ 'month' => '*', 'weekday' => '*', 'user' => 'root' }
48
+ end
49
+
50
+ def generate_cronjob(job)
51
+ "#{job['minute']} #{job['hour']} #{job['monthday']} " +
52
+ "#{job['month']} #{job['weekday']} #{job['user']} " +
53
+ "#{job['command']}\n"
54
+ end
55
+
56
+ # translate month and day names to numbers
57
+ def parse_cronjob(job)
58
+
59
+ # valid months and days
60
+ months = { 'january' => 1, 'jan' => 1,
61
+ 'february' => 2, 'feb' => 2,
62
+ 'march' => 3, 'mar' => 3,
63
+ 'april' => 4, 'apr' => 4,
64
+ 'may' => 5,
65
+ 'june' => 6, 'jun' => 6,
66
+ 'july' => 7, 'jul' => 7,
67
+ 'august' => 8, 'aug' => 8,
68
+ 'september' => 9, 'sep' => 9,
69
+ 'october' => 10, 'oct' => 10,
70
+ 'november' => 11, 'nov' => 11,
71
+ 'december' => 12, 'dec' => 12 }
72
+
73
+ days = { 'sunday' => 0, 'sun' => 0,
74
+ 'monday' => 1, 'mon' => 1,
75
+ 'tuesday' => 2, 'tue' => 2,
76
+ 'wednesday' => 3, 'wed' => 3,
77
+ 'thursday' => 4, 'thu' => 4,
78
+ 'friday' => 5, 'fri' => 5,
79
+ 'saturday' => 6, 'sat' => 6 }
80
+
81
+ # only process, if month is a string
82
+ if job['month'].is_a? String and not job['month'] == '*'
83
+ m = []
84
+
85
+ # multiple month are allowed, splitting using ','
86
+ job['month'].split(',').each do |i|
87
+
88
+ # if month is an int, add it to list and continue
89
+ if i.is_int?
90
+ d << i.to_i
91
+ next
92
+ end
93
+
94
+ # find month number in hash, add it to list
95
+ if months[i.downcase]
96
+ m << months[i.downcase]
97
+
98
+ # if month is not found, add -1 (will throw error on check_cronjob later)
99
+ else
100
+ m << -1
101
+ end
102
+
103
+ end
104
+
105
+ # join the numbers pack together
106
+ job['month'] = m.join(',')
107
+ end
108
+
109
+ # do the same with weekdays
110
+ if job['weekday'].is_a? String and not job['weekday'] == '*'
111
+ d = []
112
+ job['weekday'].split(',').each do |i|
113
+ if i.is_int?
114
+ d << i.to_i
115
+ next
116
+ end
117
+
118
+ if days[i.downcase]
119
+ d << days[i.downcase]
120
+ else
121
+ d << -1
122
+ end
123
+ end
124
+ job['weekday'] = d.join(',')
125
+ end
126
+
127
+ end
128
+
129
+ # check if cronjob is valid
130
+ def check_cronjob(job)
131
+ msg = @node.messages.add('validating', :indent => 2)
132
+
133
+ return msg.failed(': no command given') unless job['command'].is_a? String
134
+ return msg.failed(': invalid user') unless job['user'].is_a? String
135
+ return msg.failed(': minute field invalid') unless check_period(job['minute'], 0, 59)
136
+ return msg.failed(': hour field invalid') unless check_period(job['hour'], 0, 23)
137
+ return msg.failed(': monthday field invalid') unless check_period(job['monthday'], 1, 31)
138
+ return msg.failed(': month field invalid') unless check_period(job['month'], 1, 12)
139
+ return msg.failed(': weekday field invalid') unless check_period(job['weekday'], 0, 6)
140
+
141
+ msg.ok
142
+ end
143
+
144
+ # check if a cronjob time period is valid
145
+ def check_period(period, from, to)
146
+ # if period is an int, directly check if it's between from and to
147
+ return period.to_i.between?(from, to) if period.is_a? Fixnum
148
+
149
+ # cron supports multiple periods
150
+ # and e.g */5 for e.g. every 5 minutes/hours
151
+ period.split(/[\/,]/).each do |p|
152
+ next if p.is_int? and p.to_i.between?(from, to)
153
+ next if p == '*'
154
+
155
+ # if none of the criteria matches, this period is invalid.
156
+ return false
157
+ end
158
+
159
+ true
160
+ end
161
+ end
@@ -76,7 +76,7 @@ module Dust
76
76
  # the use of > < && || | and ; doesn't screw things up
77
77
  if @node['sudo']
78
78
  channel.request_pty
79
- command = "sudo sh -c \"#{command.gsub('"','\\"')}\""
79
+ command = "sudo -k -- sh -c \"#{command.gsub('"','\\"')}\""
80
80
  end
81
81
 
82
82
  channel.exec command do |ch, success|
@@ -1,3 +1,3 @@
1
1
  module Dust
2
- VERSION = "0.13.3"
2
+ VERSION = "0.13.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dust-deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.3
4
+ version: 0.13.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-29 00:00:00.000000000 Z
12
+ date: 2012-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -170,6 +170,7 @@ files:
170
170
  - lib/dust/recipes/aliases.rb
171
171
  - lib/dust/recipes/apt.rb
172
172
  - lib/dust/recipes/cjdroute.rb
173
+ - lib/dust/recipes/cron.rb
173
174
  - lib/dust/recipes/cups_client.rb
174
175
  - lib/dust/recipes/debsecan.rb
175
176
  - lib/dust/recipes/dnsmasq.rb