loom-core 0.0.5 → 0.0.6

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/bin/loom +5 -1
  4. data/lib/loom/config.rb +10 -3
  5. data/lib/loom/facts/fact_set.rb +7 -1
  6. data/lib/loom/mods/module.rb +3 -4
  7. data/lib/loom/pattern/definition_context.rb +1 -1
  8. data/lib/loom/pattern/dsl.rb +113 -32
  9. data/lib/loom/pattern/reference_set.rb +7 -7
  10. data/lib/loom/runner.rb +8 -0
  11. data/lib/loom/shell/api.rb +2 -0
  12. data/lib/loom/version.rb +1 -1
  13. data/lib/loomext/corefacts/system_info_provider.rb +2 -1
  14. data/lib/loomext/coremods/all.rb +2 -1
  15. data/lib/loomext/coremods/exec.rb +10 -0
  16. data/lib/loomext/coremods/git.rb +19 -0
  17. data/lib/loomext/coremods/package/adapter.rb +1 -1
  18. data/lib/loomext/coremods/systemd.rb +1 -0
  19. data/lib/loomext/coremods/systemd/all.rb +2 -0
  20. data/lib/loomext/coremods/{system.rb → systemd/systemd.rb} +19 -5
  21. data/lib/loomext/coremods/systemd/systemd_units.rb +69 -0
  22. data/scripts/harness.sh +1 -0
  23. data/spec/.loom/error_handling.loom +15 -0
  24. data/spec/.loom/fail.loom +20 -0
  25. data/spec/.loom/files.loom +39 -0
  26. data/spec/.loom/net.loom +21 -0
  27. data/spec/.loom/pattern_context.loom +78 -0
  28. data/spec/.loom/pkg.loom +33 -0
  29. data/spec/.loom/shell.loom +46 -0
  30. data/spec/.loom/test.loom +73 -0
  31. data/spec/.loom/user.loom +29 -0
  32. data/spec/.loom/vms.loom +22 -0
  33. data/spec/loom/facts/fact_set_spec.rb +57 -0
  34. data/spec/loom/pattern/dsl_spec.rb +58 -9
  35. data/spec/loom/shell/harness_blob_spec.rb +1 -1
  36. data/spec/loom/shell/harness_command_builder_spec.rb +1 -1
  37. data/spec/loomext/coremods/systemd_spec.rb +31 -0
  38. data/spec/runloom.sh +12 -19
  39. data/spec/scripts/harness_spec.rb +1 -1
  40. data/spec/shared/loom_internals_helper.rb +41 -0
  41. data/spec/spec_helper.rb +5 -1
  42. data/spec/systemd.loom +22 -0
  43. data/spec/test_loom_spec.rb +95 -17
  44. data/test +2 -0
  45. metadata +26 -5
  46. data/spec/test.loom +0 -370
@@ -0,0 +1,19 @@
1
+ module LoomExt::CoreMods
2
+ class Git < Loom::Mods::Module
3
+
4
+ register_mod :git
5
+ required_commands :git
6
+
7
+ module Actions
8
+ def push
9
+ shell.execute :git, :push
10
+ end
11
+
12
+ def pull
13
+ shell.execute :git, :pull
14
+ end
15
+ end
16
+ end
17
+
18
+ Git.import_actions Git::Actions
19
+ end
@@ -40,7 +40,7 @@ module LoomExt::CoreMods
40
40
  end
41
41
 
42
42
  def install(pkg_name)
43
- loom << "gem install #{pkg_name}"
43
+ loom.x :gem, :install, pkg_name
44
44
  end
45
45
  end
46
46
 
@@ -0,0 +1 @@
1
+ require_relative "systemd/all"
@@ -0,0 +1,2 @@
1
+ require_relative "systemd"
2
+ require_relative "systemd_units"
@@ -1,13 +1,27 @@
1
1
  module LoomExt::CoreMods
2
2
 
3
+ module SystemdCommon
4
+ def do_systemctl(action, unit=nil, *args, flags: [])
5
+ flags << "--no-pager"
6
+ flags << "--no-legend"
7
+ flags << "--no-ask-password"
8
+
9
+ exec_args = [
10
+ "systemctl",
11
+ flags,
12
+ action,
13
+ unit
14
+ ].flatten.compact
15
+ args = exec_args.concat args
16
+ shell.execute(*args)
17
+ end
18
+ end
19
+
3
20
  class Systemd < Loom::Mods::Module
21
+ include SystemdCommon
4
22
 
5
23
  register_mod :systemd
6
24
 
7
- def do_systemctl(action, *args)
8
- shell.execute "systemctl", action, *args
9
- end
10
-
11
25
  module Actions
12
26
 
13
27
  def is_loaded?(unit)
@@ -15,7 +29,7 @@ module LoomExt::CoreMods
15
29
  end
16
30
 
17
31
  def is_active?(unit)
18
- status(unit).match? /^\s+Active:\sactive\s/
32
+ do_systemctl "is-active", unit
19
33
  end
20
34
 
21
35
  def status(unit)
@@ -0,0 +1,69 @@
1
+ module LoomExt::CoreMods
2
+
3
+ module SystemdUnitsCommon
4
+
5
+ def init_action(*units, type: nil)
6
+ @units = units
7
+ @type = type
8
+ end
9
+
10
+ def do_systemctl_list(list_what, flags=common_list_flags)
11
+ do_systemctl("list-%s" % list_what, flags: flags)
12
+ end
13
+
14
+ def common_list_flags
15
+ ["--plain", "--full", "--all"]
16
+ end
17
+ end
18
+
19
+ class SystemdUnits < Loom::Mods::Module
20
+ include SystemdCommon
21
+ include SystemdUnitsCommon
22
+
23
+ register_mod :systemd_units
24
+
25
+ module Actions
26
+ def list
27
+ do_systemctl_list :units
28
+ end
29
+
30
+ def status
31
+ @units.map do |unit|
32
+ do_systemctl "status", unit, flags: ["--output=short-unix"]
33
+ end
34
+ end
35
+ end
36
+
37
+ import_actions Actions
38
+ end
39
+
40
+ class SystemdSockets < SystemdUnits
41
+ include SystemdCommon
42
+ include SystemdUnitsCommon
43
+
44
+ register_mod :systemd_sockets
45
+
46
+ module Actions
47
+ def list
48
+ do_systemctl_list :sockets
49
+ end
50
+ end
51
+
52
+ import_actions Actions
53
+ end
54
+
55
+ class SystemdTimers < SystemdUnits
56
+ include SystemdCommon
57
+ include SystemdUnitsCommon
58
+
59
+ register_mod :systemd_timers
60
+
61
+ module Actions
62
+ def list
63
+ do_systemctl_list :timers
64
+ end
65
+ end
66
+
67
+ import_actions Actions
68
+ end
69
+ end
@@ -7,6 +7,7 @@
7
7
  #
8
8
  # 1. base64 encode an arbitrary shell script, this is the encoded
9
9
  # script
10
+ # TODO[P0]: this should be a checksum for the original script!!! Check the code.
10
11
  # 2. get a checksum for the encoded script
11
12
  # 3. send the encoded script and checksum to a shell in another
12
13
  # process (local or remote) to invoke the encoded script via this
@@ -0,0 +1,15 @@
1
+ # !!! NOTE: This will reboot the host it runs on!!!
2
+ module ErrorHandling
3
+ include Loom::Pattern
4
+
5
+ namespace :err
6
+
7
+ desc "Handle SSH disconnection errors"
8
+ pattern :ssh_disconnect do |loom, facts|
9
+ if facts[:really_really_reboot]
10
+ loom.sudo cmd: :reboot
11
+ else
12
+ puts "to REALLY reboot set fact[:really_really_reboot] = true"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ # All patterns are expected to fail
2
+
3
+ desc "Always fails due to return code."
4
+ pattern :fail_soft do |loom, facts|
5
+ unless loom << :false
6
+ loom.x :echo, "i am false"
7
+ end
8
+ end
9
+
10
+ desc "Always fails due to a hard failure"
11
+ pattern :fail_hard do |loom, facts|
12
+ loom.fail "Fail big or not at all"
13
+ end
14
+
15
+ desc "Expected to fail: Check timeout commands"
16
+ pattern :timeout_fail do |loom, facts|
17
+ loom.timeout(:timeout => 1) do
18
+ loom.x :sleep, 2
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ # Tests for LoomExt::CoreMods::Package
2
+ module Files
3
+ include Loom::Pattern
4
+
5
+ desc "Reads a file"
6
+ pattern :read do |loom, facts|
7
+ loom.files("/etc/hosts").cat
8
+ end
9
+
10
+ desc "Gsubs file text"
11
+ pattern :gsub do |loom, facts|
12
+ loom.files("/tmp/garbage").write <<EOS
13
+ This is a bunch of junk
14
+ 192.123.456.0\t\thostname.xyz
15
+ EOS
16
+
17
+ loom.files("/tmp/garbage")
18
+ .cat
19
+ .gsub(pattern: /[\d]{3}/, replace: "xxx")
20
+ .append("this is something new")
21
+ .cat
22
+ end
23
+
24
+ desc "Chowns a file"
25
+ pattern :chown do |loom, facts|
26
+ loom.files("/tmp/chown.me")
27
+ .touch
28
+ .append("this file will be owned by root")
29
+
30
+ loom.sudo do
31
+ loom.files("/tmp/chown.me").chown user: :root
32
+ loom.x :ls, "-lZ", "/tmp/chown.me"
33
+
34
+ loom.files("/tmp/chown.me").chown user: :root, group: :root
35
+ end
36
+
37
+ loom.sudo { loom.exec :rm, "/tmp/chown.me" }
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ module Net
2
+ include Loom::Pattern
3
+
4
+ desc "tests the net package, with_net check"
5
+ pattern :check_net do |loom, facts|
6
+ unless loom.net(check_host: '127.0.0.1').has_net?
7
+ loom.fail 'can not ping localhost'
8
+ end
9
+
10
+ has_local_net = false
11
+ loom.net(check_host: '127.0.0.1').with_net do
12
+ has_local_net = true
13
+ end
14
+ loom.fail "should have local net" unless has_local_net
15
+ end
16
+
17
+ desc "expected check_net failures"
18
+ pattern :check_net_fail do |loom, facts|
19
+ loom.net(timeout: 2, check_host: '1.1.1.1').check_net
20
+ end
21
+ end
@@ -0,0 +1,78 @@
1
+ # Tests patterns nested at deeper module levels with contextual let, before, and
2
+ # after hooks. Verifies hook order and contexts are set correctly.
3
+ module PatternContext
4
+ module Parent
5
+ include Loom::Pattern
6
+
7
+ with_facts :outer_fact => :outer, :replaced => :original
8
+
9
+ before do
10
+ puts "Test::Parent => before"
11
+ end
12
+
13
+ after do
14
+ puts "Test::Parent => after"
15
+ end
16
+
17
+ desc "Checks facts on a parent pattern"
18
+ pattern :check_facts do |loom, facts|
19
+ unless facts[:outer_fact] == :outer
20
+ raise "expected outer fact => #{facts[:outer_fact]}"
21
+ end
22
+ end
23
+
24
+ let(:a_let_key) { "the value" }
25
+ let(:a_fact_based_let) { |facts| facts[:outer_fact].to_s + "/let" }
26
+ let(:a_referencing_let) { a_let_key + " referenced" }
27
+
28
+ desc "Checks let defines"
29
+ pattern :check_lets do |loom, facts|
30
+ raise "bad let :a_let_key" unless a_let_key == "the value"
31
+ raise "bad let :a_fact_based_let" unless a_fact_based_let == "outer/let"
32
+
33
+ unless a_referencing_let == "the value referenced"
34
+ raise "bad let :a_referencing_let => #{a_referencing_let}"
35
+ end
36
+
37
+ puts "a_let_key: %s" % a_let_key
38
+ puts "a_fact_based_let: %s" % a_fact_based_let
39
+ end
40
+
41
+ module Child
42
+ include Loom::Pattern
43
+
44
+ with_facts :inner_fact => :inner, :replaced => :override
45
+ let(:a_let_key) { |facts| facts[:inner_fact].to_s + " overrides parent" }
46
+
47
+ before do
48
+ puts "Test::Parent::Child => before"
49
+ end
50
+
51
+ after do
52
+ puts "Test::Parent::Child => after"
53
+ end
54
+
55
+ desc "Check let overrides"
56
+ pattern :check_let_overrides do |loom, facts|
57
+ raise "bad let :a_let_key" unless a_let_key == "inner overrides parent"
58
+ raise "bad let :a_fact_based_let" unless a_fact_based_let == "outer/let"
59
+
60
+ puts "child a_let_key: %s" % a_let_key
61
+ puts "child a_fact_based_let: %s" % a_fact_based_let
62
+ end
63
+
64
+ desc "Checks inherited facts on a cihld pattern"
65
+ pattern :check_facts do |loom, facts|
66
+ unless facts[:inner_fact] == :inner
67
+ raise "expected inner fact => #{facts[:inner_fact]}"
68
+ end
69
+ unless facts[:outer_fact] == :outer
70
+ raise "expected outer fact => #{facts[:outer_fact]}"
71
+ end
72
+ unless facts[:replaced] == :override
73
+ raise "expected replaced fact => #{facts[:replaced_fact]}"
74
+ end
75
+ end
76
+ end # Child
77
+ end # Parent
78
+ end #PatternContext
@@ -0,0 +1,33 @@
1
+ # Tests for LoomExt::CoreMods::Package
2
+ module Package
3
+ include Loom::Pattern
4
+
5
+ namespace :pkg
6
+
7
+ before do |loom, facts|
8
+ puts "#{self} in before"
9
+ end
10
+
11
+ after do
12
+ puts "#{self} in after"
13
+ end
14
+
15
+ desc "Updates the default package manager cache"
16
+ pattern :update_cache do |loom, facts|
17
+ loom.sudo { loom.pkg.update_cache }
18
+ end
19
+
20
+ desc "Installs Apache HTTP server"
21
+ pattern :install_httpd do |loom, facts|
22
+ loom.sudo do
23
+ loom.pkg.install 'apache2' unless loom.pkg.installed? 'apache2'
24
+ end
25
+ end
26
+
27
+ desc "Installs Facter GEM"
28
+ pattern :install_facter do |loom, facts|
29
+ loom.sudo do
30
+ loom.pkg[:gem].ensure_installed :facter
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ module Shell
2
+ include Loom::Pattern
3
+
4
+ desc "Executes some commands in a subshell"
5
+ pattern :subshell do |loom, facts|
6
+ loom << :"(echo $$; echo $BASHPID; whoami)"
7
+ loom << :"(sudo -i -u root whoami)"
8
+
9
+ loom.local << :"(echo $$; echo $BASHPID; whoami)"
10
+ # loom.local << "(sudo -i -u root whoami)"
11
+ end
12
+
13
+ desc "Tests nested sudo scenarios"
14
+ pattern :sudo do |loom, facts|
15
+ loom.sudo user: "root" do
16
+ loom << :pwd
17
+ loom << :whoami
18
+ loom.exec :touch, "loom.file"
19
+
20
+ loom.sudo do
21
+ loom << :whoami
22
+ loom << :pwd
23
+ loom.x :touch, "root.file"
24
+
25
+ loom.user.add_system_user :postgres, uid: 999
26
+ loom.sudo user: :postgres do
27
+ loom << :whoami
28
+ loom.cd "/tmp" do
29
+ loom << :pwd
30
+ loom.x :touch, "postgres.file"
31
+ end
32
+ end
33
+ loom.user.remove :postgres
34
+
35
+ loom.x :touch, "root.file2"
36
+ end
37
+ end
38
+
39
+ loom.cd "/tmp" do
40
+ loom << :pwd
41
+ loom.sudo user: :root, cmd: :pwd do loom << :pwd end
42
+ loom << :pwd
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,73 @@
1
+ # TODO: add in test verifications that these tests are actually doing what
2
+ # they're supposed to do.
3
+
4
+ module Smoke
5
+ include Loom::Pattern
6
+
7
+ desc "Prints some known facts"
8
+ report :three_facts do |loom, facts|
9
+ facts
10
+ end
11
+
12
+ desc "Reports `uptime` status"
13
+ pattern :uptime do |loom, facts|
14
+ loom << :uptime
15
+ loom << :hostname
16
+ loom.local << :hostname
17
+ end
18
+ #produces { pkg.installed? :httpd }
19
+
20
+ desc "cd's to the /etc directory and runs `pwd`"
21
+ pattern :cd do |loom, facts|
22
+ loom.cd "/etc" do
23
+ loom << :pwd
24
+ end
25
+ end
26
+
27
+ desc "tests return codes from wrapped commands"
28
+ pattern :wrap_returns do |loom, facts|
29
+ # using loom.time as a proxy for Shell::Core#wrap here
30
+ loom.time do
31
+ raise "wrapped true is not true" unless loom.test :true
32
+ raise "wrapped false is not false" if loom.test :false
33
+ end
34
+ end
35
+
36
+ desc "Tests a condition."
37
+ pattern :test do |loom, facts|
38
+ unless loom.test :false
39
+ loom.x :echo, "i tested false"
40
+ end
41
+
42
+ if loom.test :true
43
+ loom.x :echo, "i tested true"
44
+ end
45
+
46
+ if loom.test :which, "bash"
47
+ loom.x :echo, "has bash"
48
+ end
49
+ end
50
+
51
+ desc "Tests a grep condition."
52
+ pattern :match do |loom, facts|
53
+ if loom.files("/etc/hosts").match? :pattern => "aldsfja;ldjf"
54
+ loom.fail "should not match garbage"
55
+ else
56
+ loom.x :echo, "I didnt match garbage"
57
+ end
58
+
59
+ unless loom.files("/etc/hosts").match? :pattern => "localhost"
60
+ loom.fail "should match localhost"
61
+ else
62
+ loom.x :echo, "I did match my target"
63
+ end
64
+ end
65
+ end
66
+
67
+ desc "Wrapped time commands"
68
+ pattern :time do |loom, facts|
69
+ loom.time do
70
+ loom.x :echo, :hi
71
+ loom.x :sleep, 2
72
+ end
73
+ end