hatecf 0.1.1 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f676f5ae2e918677f40a743d982a5ffcbd061a3c0d2dd7bc043ee85c3d6c5da8
4
- data.tar.gz: 1ab539b2ddde0464b7ed36dd02958afae19929c721513fe3b89e58cf29001c9d
3
+ metadata.gz: 9dac6ef08ee3123c1815d6e8381147f8927693400da455086562073f14c591e3
4
+ data.tar.gz: acdf885dc3fe9ef1689ec14249c6a30ce13281c1839dd8ceacaa8856b10e4d25
5
5
  SHA512:
6
- metadata.gz: d78d49b37f6b614aa53062626d98c2bf4642882b688b7f436be3ea6a383f25722fd9393b3773ca5fbc66a1babbfeb668ee5ece7dfb2d0d627b55135b86023412
7
- data.tar.gz: 9806d0189e2f2ff6e21a85e98a17386b0ffe079208f871dd3a78c292d17e5ffb4b0d3d0f72ff9ecf9e5e263ac5b22f36598a79596753a91a2a79d48776b977b4
6
+ metadata.gz: 5852eca0446e36b759683599ae8005e97cf12e8404160001078199388a7dedbbb78831340b486b63e3e5b01a677501d84f81f0eef61fd4cb22a8e7e20477f7f4
7
+ data.tar.gz: 245aaa98f3ae07c4bc7b7802969a2aa61ea7334815245dadc23911d5c3fc70de294eaf8617762a2e7bb74dfdd7f077a6817096e003238ceff89e6b2691e90b13
data/bootstrap_ruby CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/bin/sh
2
- dpkg -s ruby > /dev/null || (echo "machine has no ruby; installing..."; apt-get install --no-install-recommends -y ruby)
2
+ which ruby > /dev/null || (echo "machine has no ruby; installing..."; apt-get install --no-install-recommends -y ruby)
data/lib/local.rb CHANGED
@@ -18,9 +18,12 @@ module Local
18
18
  end
19
19
  end
20
20
 
21
+ attr_accessor :really_die
22
+ @really_die = false
21
23
  def die(message)
22
24
  $stderr.puts "Script error: #{message}"
23
25
  print_location
26
+ @really_die = true
24
27
  exit 1
25
28
  end
26
29
 
@@ -66,9 +69,11 @@ module Local
66
69
  @local_files = []
67
70
 
68
71
  require 'pathname'
72
+ # TODO: we are not able to copy directories with this,
73
+ # but we should be
69
74
  def copy_local_files_to(dir)
70
75
  @local_files.each do |local_file|
71
- # dublicating the whole directory stucture
76
+ # duplicating the whole directory structure
72
77
  acc = []
73
78
  Pathname.new(local_file).each_filename do |chunk|
74
79
  source_path = File.join(*(['/'] + acc << chunk))
@@ -87,14 +92,20 @@ module Local
87
92
  end
88
93
  end
89
94
 
95
+ @performed = false
90
96
  require 'tmpdir'
91
97
  def perform!
98
+ return if @performed # just for compatibility with < 0.2
99
+ # when manual invoke of peform! was needed
92
100
  die "no target host specified!" if (@target[:host] || "").empty?
93
- script_path = File.expand_path(ENV["_"])
94
- script_dir = File.dirname(File.expand_path(ENV["_"]))
101
+ script_path = File.expand_path ENV["_"]
102
+ script_dir = File.dirname script_path
95
103
  status = nil
96
104
  Dir.mktmpdir "hatecf" do |tmp_dir|
97
105
  debug "using temporary dir #{tmp_dir}"
106
+ File.chmod(00755, tmp_dir) # TODO: this is a tiny security issue.
107
+ # We should set these permissions
108
+ # only when we have "as" blocks.
98
109
  FileUtils.cp(script_path, File.join(tmp_dir, "script.rb"))
99
110
  File.chmod(00777, File.join(tmp_dir, "script.rb"))
100
111
  FileUtils.cp(File.join(__dir__, "../remote/hatecf.rb" ), tmp_dir)
@@ -117,19 +128,25 @@ module Local
117
128
  pid, status = Process.wait2(Process.spawn(cmd))
118
129
  debug "exit status: #{status.exitstatus}"
119
130
  end
131
+ @performed = true
120
132
  # FIXME: this always returns the status of "; rm" above, doesn't it?
121
133
  exit status.exitstatus
122
134
  end
123
135
 
124
136
  require 'optparse'
125
- OptionParser.new do |opts|
126
- opts.on "--dry", "don't change anything, just test everything" do |x|
127
- @dry_run = true
128
- end
129
- opts.on "-v", "verbose mode: print debug messages" do |x|
130
- @verbose = true
131
- end
132
- end.parse!
137
+ begin
138
+ OptionParser.new do |opts|
139
+ opts.on "--dry", "don't change anything, just test everything" do |x|
140
+ @dry_run = true
141
+ end
142
+ opts.on "-v", "verbose mode: print debug messages" do |x|
143
+ @verbose = true
144
+ end
145
+ end.parse!
146
+ rescue OptionParser::InvalidOption => e
147
+ $stderr.puts e
148
+ exit 1
149
+ end
133
150
 
134
151
  def debug(s)
135
152
  info s if @verbose
data/lib/local_dsl.rb CHANGED
@@ -4,10 +4,14 @@ def target(host:, user: nil, port: nil)
4
4
  Local.type_check(:host, host, String)
5
5
  Local.type_check(:user, user, String) if user
6
6
  Local.type_check(:port, port, Integer) if port
7
- #Local.target = Local::DEFAULT_TARGET.dup
8
- Local.target[:host] = host
9
- Local.target[:user] = user if user
10
- Local.target[:port] = port if port
7
+ if Local.target.empty?
8
+ Local.target[:host] = host
9
+ Local.target[:user] = user if user
10
+ Local.target[:port] = port if port
11
+ else
12
+ Local.die "multiple targets not supported (yet, idk)"
13
+ exit 1
14
+ end
11
15
  end
12
16
 
13
17
  class LocalFile
@@ -215,10 +219,14 @@ class RemoteFile
215
219
  end
216
220
  end
217
221
 
218
- def perform!
222
+ def perform! # legacy, not needed since 0.2
219
223
  Local.perform!
220
224
  end
221
225
 
226
+ Kernel.at_exit do
227
+ Local.perform! unless Local.really_die
228
+ end
229
+
222
230
  # Monkey-patching
223
231
 
224
232
  class Array
data/remote/remote.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  module Remote
2
2
  extend self
3
3
 
4
- # $HOME variable should be imported from local machine
5
- # in order to access ~/ paths
6
- # and directory of scrip should be imported
4
+ # $HOME variable should be imported from the local machine
5
+ # in order to access tilda ~/ paths
6
+ # and directory of the script should be imported
7
7
  # in order to access relative ./ paths
8
8
  attr_accessor :local_home, :local_script_dir
9
9
 
@@ -129,6 +129,7 @@ module Remote
129
129
  end
130
130
 
131
131
  def service_reload(name)
132
+ name = name.to_s
132
133
  destructive "reloading service #{name}" do
133
134
  cmd = ["systemctl", "reload", name]
134
135
  spawn(cmd, expect_status: 0)
@@ -136,6 +137,7 @@ module Remote
136
137
  end
137
138
 
138
139
  def service_restart(name)
140
+ name = name.to_s
139
141
  destructive "restarting service #{name}" do
140
142
  cmd = ["systemctl", "restart", name]
141
143
  spawn(cmd, expect_status: 0)
@@ -163,6 +165,8 @@ module Remote
163
165
 
164
166
  def create_user(name, create_home, shell)
165
167
  if user_exists?(name)
168
+ # TODO: should we check if existing user
169
+ # has the specified shell?
166
170
  ok "#{name} user exists"
167
171
  else
168
172
  destructive "creating user #{name}" do
@@ -175,6 +179,7 @@ module Remote
175
179
  end
176
180
 
177
181
  require 'fileutils'
182
+ # FIXME: even when run "afterwards" it crashes if user doesn't exist.
178
183
  def authorize_ssh_key(user, key)
179
184
  case key
180
185
  when LocalFile
@@ -220,7 +225,6 @@ module Remote
220
225
  end
221
226
  end
222
227
 
223
- attr_accessor :apt_updated
224
228
  def dpkg_installed?(names)
225
229
  # | virtual | virtual | removed
226
230
  # | package | package | but
@@ -248,6 +252,7 @@ module Remote
248
252
  end
249
253
  end
250
254
 
255
+ @apt_updated = false
251
256
  def apt_install(names)
252
257
  names = names.to_s if names.is_a? Symbol
253
258
  names = names.split(/\s+/).map(&:strip).select{|x|not x.empty?} if names.is_a? String
@@ -255,10 +260,10 @@ module Remote
255
260
  ok "installed: #{names.join(', ')}"
256
261
  else
257
262
  destructive "apt-get install #{names.join(' ')}" do
258
- unless apt_updated
263
+ unless @apt_updated
259
264
  cmd = ["apt-get", "update", "-q"]
260
265
  spawn(cmd, expect_status: 0)
261
- apt_updated = true
266
+ @apt_updated = true
262
267
  end
263
268
 
264
269
  cmd = ["apt-get", "install", "--no-install-recommends", "-y"]
@@ -277,10 +282,12 @@ module Remote
277
282
  if installed.empty?
278
283
  ok "removed: #{names.join(", ")}"
279
284
  else
285
+ # FIXME: eh, what was the logic behind this cycle when I made it?..
286
+ # Why do I need to remove packages one by one?
280
287
  installed.each do |name|
281
288
  destructive "apt-get remove #{name}" do
282
289
  cmd = ["apt-get", "remove", "-y"]
283
- cmd += names
290
+ cmd << name
284
291
  spawn cmd, expect_status: 0
285
292
  end
286
293
  end
@@ -332,7 +339,7 @@ module Remote
332
339
 
333
340
  def rm(x)
334
341
  x = File.expand_path x
335
- if File.exists? x
342
+ if File.exist? x
336
343
  destructive "rm #{x}" do
337
344
  FileUtils.rm x
338
345
  end
@@ -341,7 +348,7 @@ module Remote
341
348
  end
342
349
  end
343
350
 
344
- # TODO: the dst is a dir case
351
+ # TODO: handle "dst is a dir" case
345
352
  def cp(src, dst, mode)
346
353
  src = src.remote_path if src.is_a? LocalFile
347
354
  dst = File.expand_path dst
@@ -376,10 +383,12 @@ module Remote
376
383
  end
377
384
  end
378
385
 
386
+ # TODO: handle "dst is a dir" case
387
+ # TODO: relative path case
379
388
  def ln_s(src, dst)
380
389
  src = File.expand_path src
381
390
  dst = File.expand_path dst
382
- if File.exist?(dst) &&File.lstat(dst).symlink? && File.readlink(dst) == src
391
+ if File.exist?(dst) && File.lstat(dst).symlink? && File.readlink(dst) == src
383
392
  ok "#{dst} leads to #{src}"
384
393
  else
385
394
  destructive "ln -s #{src} #{dst}" do
@@ -388,8 +397,6 @@ module Remote
388
397
  end
389
398
  end
390
399
 
391
- #attr_accessor :impressionating_user
392
-
393
400
  def spawn(cmd, expect_status: nil)
394
401
  expect_status = [expect_status] unless expect_status.nil? || expect_status.respond_to?(:include?)
395
402
  stdout_r, stdout_w = IO.pipe
@@ -510,4 +517,11 @@ module Remote
510
517
  @verbose = true
511
518
  end
512
519
  end.parse!
520
+
521
+ @performed = false
522
+ def perform!
523
+ return if @performed
524
+ info "ok: #{ok_counter}, changed: #{changed_counter}"
525
+ @performed = true
526
+ end
513
527
  end
data/remote/remote_dsl.rb CHANGED
@@ -181,8 +181,12 @@ def remote_file(path)
181
181
  Remote::RemoteFile.new(path)
182
182
  end
183
183
 
184
- def perform!
185
- Remote.info "ok: #{Remote.ok_counter}, changed: #{Remote.changed_counter}"
184
+ def perform! # legacy, not needed since 0.2
185
+ Remote.perform!
186
+ end
187
+
188
+ Kernel.at_exit do
189
+ Remote.perform!
186
190
  end
187
191
 
188
192
  # Monkey-patching
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hatecf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Markov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-30 00:00:00.000000000 Z
11
+ date: 2026-03-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Configuration management engine like Ansible but without YAML and 30
14
14
  times faster