pupistry 0.0.10 → 0.0.11

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
  SHA1:
3
- metadata.gz: e5f9601622da2e9d834ecb81aec0b908ef5ad12e
4
- data.tar.gz: 2fdd67a6cb8433ee0556e24b3c17ee0836657849
3
+ metadata.gz: b516bef9aa8033e4871098cd224fe497ef82f1b6
4
+ data.tar.gz: 7b158bdc381764e80618a4236e6287d19ac6670e
5
5
  SHA512:
6
- metadata.gz: f13aeefb955e9784a5c1b34d861ef6ff2f6d7c94e89ac0f1c0d0bcb7f28409bc2b3e76a62786da160773d872bc229b5b52715c08fbecae8dea7f3b713254664b
7
- data.tar.gz: 044fd9496533f320be7f0a0e17963b8713a5ca00f70408ae0858587005a41e4ea1c74b71b3bec8d2eaf7132afdf821499fd1d806a145abb1f70de706981b5217
6
+ metadata.gz: 8f2f7720b7b9ef5f8042282d49ba3093bfcc4c160bbc8288ba200410daaae4da4842d4b2bc21059879adb0ac4686a841413a58f4be2f90c9ba37a980a3ec5aed
7
+ data.tar.gz: 3466558b948d2e141fb73a1b7e86ac898dc4d88504133d8b450c14124b1013e6ec42a8f0d421eeacb80904e7e3960b79fd94ed1a31f2df6cb835fabecf898dd7
data/bin/pupistry CHANGED
@@ -49,105 +49,18 @@ class CLI < Thor
49
49
  $logger.warn "A daemon running in noop will do nothing except log what changes it could apply"
50
50
  end
51
51
 
52
- # Muppet dev check
53
- if options[:daemon]
54
- $logger.fatal "Daemon mode not implemented yet"
55
- exit 0
56
- end
57
-
58
-
59
- # Fetch artifact versions
60
- $logger.info "Checking version of artifact available..."
61
-
62
- artifact = Pupistry::Artifact.new
63
- artifact.checksum = artifact.fetch_latest
64
-
65
- unless artifact.checksum
66
- $logger.error "There is no current artifact available for download, no steps can be taken."
67
- exit 0
68
- end
69
-
70
- artifact_installed = Pupistry::Artifact.new
71
- artifact_installed.checksum = artifact_installed.fetch_installed
72
-
73
- if artifact_installed.checksum
74
- $logger.debug "Currently on #{artifact_installed.checksum}"
75
- else
76
- $logger.debug "No currently installed artifact - blank slate!"
77
- end
78
-
79
- # Download the new artifact if one has changed. If we already have this
80
- # version, then we should skip downloading and go straight to running
81
- # Puppet - unless the user runs with --force (eg to fix a corrupted
82
- # artifact).
83
-
84
- if artifact.checksum != artifact_installed.checksum or options[:force]
85
- if options[:force]
86
- $logger.warn "Forcing download of latest artifact regardless of current one."
87
- end
88
-
89
- # Install the artifact
90
- $logger.info "Downloading latest artifact (#{artifact.checksum})..."
91
-
92
- artifact.fetch_artifact
93
- artifact.unpack
94
-
95
- unless artifact.install
96
- $logger.fatal "An unexpected error happened when installing the latest artifact, cancelling Puppet run"
97
- exit 0
98
- end
99
-
100
- # Remove temporary unpacked files
101
- artifact.clean_unpack
102
- else
103
- $logger.info "Already have latest artifact applied."
104
-
105
- # By default we run Puppet even if we have the latest artifact. There's
106
- # some grounds for debate about whether this is the right thing - in some
107
- # ways it is often a waste of CPU, since if the artifact hasn't changed,
108
- # then it's unlikley anything else has changed.
109
- #
110
- # But that's not always 100% true - Puppet will undo local changes or
111
- # upgrade package versions (ensure => latest) if appropiate, so we should
112
- # act like the standard command and attempt to apply whatever we can.
113
- #
114
- # To provide users with options, we provide the --lazy parameter to avoid
115
- # running Puppet except when the artifact changes. By default, Puppet
116
- # runs every thing to avoid surprise.
117
-
118
- if options[:minimal]
119
- $logger.info "Running with minimal effort mode enabled, not running Puppet since artifact version already applied"
120
- exit 0
121
- end
122
-
52
+ if options[:force] and options[:daemon]
53
+ $logger.warn "A daemon running with force will be very wasteful of system resources! NOT RECOMMENDED."
123
54
  end
124
55
 
125
56
 
126
- # Execute Puppet.
127
- puppet_cmd = "puppet apply"
128
-
129
- if options[:noop]
130
- puppet_cmd += " --noop"
131
- end
132
-
133
- if options[:environment]
134
- environment = options[:environment]
57
+ if options[:daemon]
58
+ # Run as a daemon service
59
+ Pupistry::Agent.daemon options
135
60
  else
136
- environment = 'master'
61
+ # Single-run Agent Execution
62
+ Pupistry::Agent.apply options
137
63
  end
138
-
139
- puppet_cmd += " --environment #{environment}"
140
- puppet_cmd += " --modulepath #{$config["agent"]["puppetcode"]}/#{environment}/modules/"
141
- puppet_cmd += " --hiera_config #{$config["agent"]["puppetcode"]}/#{environment}/hiera.yaml"
142
- puppet_cmd += " #{$config["agent"]["puppetcode"]}/#{environment}/manifests/site.pp"
143
-
144
- $logger.info "Executing Puppet..."
145
- $logger.debug "With: #{puppet_cmd}"
146
-
147
- unless system puppet_cmd
148
- $logger.fatal "An unexpected issue occured when running puppet"
149
- end
150
-
151
64
  end
152
65
 
153
66
 
@@ -243,6 +156,11 @@ class CLI < Thor
243
156
  #
244
157
  # So given this, we might as well go native and just rely on the system
245
158
  # diff command to do the job.
159
+ #
160
+ # TODO: We need smarts here to handle git branching, so a branch doens't
161
+ # produce a new mega diff, we want only the real changes to be
162
+ # easily visible, or the diff function loses value to people.
163
+ # Pull requests welcome :-) xoxo
246
164
 
247
165
  Dir.chdir("#{$config["general"]["app_cache"]}/artifacts/") do
248
166
  unless system "diff -Nuar unpacked.#{artifact_upstream.checksum} unpacked.#{artifact_current.checksum}"
@@ -0,0 +1,173 @@
1
+ require 'rubygems'
2
+ require 'fileutils'
3
+ require 'rufus/scheduler'
4
+
5
+ module Pupistry
6
+ # Pupistry::Agent
7
+
8
+ class Agent
9
+ # Functions for running the Pupistry agent aka "apply mode" to actually
10
+ # download and run Puppet against the contents of the artifact.
11
+
12
+
13
+ def self.daemon options
14
+ ## Run as a daemon
15
+
16
+
17
+ # Since options comes from Thor, it can't be modified, so we need to
18
+ # copy the options and then we can edit it.
19
+
20
+ options_new = options.inject({}) do |new, (name, value)|
21
+ new[name] = value;
22
+ new
23
+ end
24
+
25
+ # If the minimal mode has been enabled in config, respect.
26
+ if $config["agent"]["daemon_minimal"]
27
+ options_new[:minimal] = true
28
+ end
29
+
30
+ # If no frequency supplied, use 300 seconds safe default.
31
+ unless $config["agent"]["daemon_frequency"]
32
+ $config["agent"]["daemon_frequency"] = 300
33
+ end
34
+
35
+
36
+ # Use rufus-scheduler to run our apply job as a regularly scheduled job
37
+ # but with build in locking handling.
38
+
39
+ $logger.info "Launching daemon... frequency of #{$config["agent"]["daemon_frequency"]} seconds."
40
+
41
+ begin
42
+
43
+ scheduler = Rufus::Scheduler.new
44
+
45
+ scheduler.every "#{$config["agent"]["daemon_frequency"]}s", :overlap => false, :timeout => '1d', :first_at => Time.now + 1 do
46
+ $logger.info "Triggering another Pupistry run (#{$config["agent"]["daemon_frequency"]}s)"
47
+ apply options_new
48
+ end
49
+
50
+ scheduler.join
51
+
52
+ rescue Rufus::Scheduler::TimeoutError
53
+ $logger.error "A run of Pupistry timed out after 1 day as a safety measure. There may be a bug or a Puppet action causing it to get stuck"
54
+
55
+ rescue SignalException => e
56
+ # Clean shutdown signal (eg SIGTERM)
57
+ $logger.info "Clean shutdown of Pupistry daemon requests"
58
+ exit 0
59
+
60
+ rescue Exception => e
61
+ raise e
62
+ end
63
+
64
+ end
65
+
66
+
67
+ def self.apply options
68
+ ## Download and apply the latest artifact (if any)
69
+
70
+ # Fetch artifact versions
71
+ $logger.info "Checking version of artifact available..."
72
+
73
+ artifact = Pupistry::Artifact.new
74
+ artifact.checksum = artifact.fetch_latest
75
+
76
+ unless artifact.checksum
77
+ $logger.error "There is no current artifact available for download, no steps can be taken."
78
+ return false
79
+ end
80
+
81
+ artifact_installed = Pupistry::Artifact.new
82
+ artifact_installed.checksum = artifact_installed.fetch_installed
83
+
84
+ if artifact_installed.checksum
85
+ $logger.debug "Currently on #{artifact_installed.checksum}"
86
+ else
87
+ $logger.debug "No currently installed artifact - blank slate!"
88
+ end
89
+
90
+ # Download the new artifact if one has changed. If we already have this
91
+ # version, then we should skip downloading and go straight to running
92
+ # Puppet - unless the user runs with --force (eg to fix a corrupted
93
+ # artifact).
94
+
95
+ if artifact.checksum != artifact_installed.checksum or options[:force]
96
+ if options[:force]
97
+ $logger.warn "Forcing download of latest artifact regardless of current one."
98
+ end
99
+
100
+ # Install the artifact
101
+ $logger.info "Downloading latest artifact (#{artifact.checksum})..."
102
+
103
+ artifact.fetch_artifact
104
+ artifact.unpack
105
+
106
+ unless artifact.install
107
+ $logger.fatal "An unexpected error happened when installing the latest artifact, cancelling Puppet run"
108
+ return false
109
+ end
110
+
111
+ # Remove temporary unpacked files
112
+ artifact.clean_unpack
113
+ else
114
+ $logger.info "Already have latest artifact applied."
115
+
116
+ # By default we run Puppet even if we have the latest artifact. There's
117
+ # some grounds for debate about whether this is the right thing - in some
118
+ # ways it is often a waste of CPU, since if the artifact hasn't changed,
119
+ # then it's unlikley anything else has changed.
120
+ #
121
+ # But that's not always 100% true - Puppet will undo local changes or
122
+ # upgrade package versions (ensure => latest) if appropiate, so we should
123
+ # act like the standard command and attempt to apply whatever we can.
124
+ #
125
+ # To provide users with options, we provide the --lazy parameter to avoid
126
+ # running Puppet except when the artifact changes. By default, Puppet
127
+ # runs every thing to avoid surprise.
128
+
129
+ if options[:minimal]
130
+ $logger.info "Running with minimal effort mode enabled, not running Puppet since artifact version already applied"
131
+ return false
132
+ end
133
+
134
+ end
135
+
136
+ # Check if the requested environment/branch actually exists
137
+ if options[:environment]
138
+ environment = options[:environment]
139
+ else
140
+ environment = 'master'
141
+ end
142
+
143
+ unless Dir.exists?("#{$config["agent"]["puppetcode"]}/#{environment}")
144
+ $logger.fatal "The requested branch/environment of #{environment} does not exist, unable to run Puppet"
145
+ return false
146
+ end
147
+
148
+
149
+ # Execute Puppet.
150
+ puppet_cmd = "puppet apply"
151
+
152
+ if options[:noop]
153
+ puppet_cmd += " --noop"
154
+ end
155
+
156
+ puppet_cmd += " --environment #{environment}"
157
+ puppet_cmd += " --modulepath #{$config["agent"]["puppetcode"]}/#{environment}/modules/"
158
+ puppet_cmd += " --hiera_config #{$config["agent"]["puppetcode"]}/#{environment}/hiera.yaml"
159
+ puppet_cmd += " #{$config["agent"]["puppetcode"]}/#{environment}/manifests/site.pp"
160
+
161
+ $logger.info "Executing Puppet..."
162
+ $logger.debug "With: #{puppet_cmd}"
163
+
164
+ unless system puppet_cmd
165
+ $logger.error "An unexpected issue occured when running puppet"
166
+ end
167
+
168
+ end
169
+
170
+ end
171
+ end
172
+
173
+ # vim:shiftwidth=2:tabstop=2:softtabstop=2:expandtab:smartindent
@@ -72,6 +72,8 @@ module Pupistry
72
72
  secret_access_key: $config["agent"]["secret_access_key"],
73
73
  region: $config["agent"]["region"],
74
74
  proxy_uri: $config["agent"]["proxy_uri"],
75
+ daemon_frequency: $config["agent"]["daemon_frequency"],
76
+ daemon_minimal: $config["agent"]["daemon_minimal"]
75
77
  }
76
78
 
77
79
  # Generate template using ERB
data/lib/pupistry.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'pupistry/agent'
1
2
  require 'pupistry/artifact'
2
3
  require 'pupistry/bootstrap'
3
4
  require 'pupistry/config'
@@ -47,6 +47,19 @@ agent:
47
47
  region: ap-southeast-2
48
48
  proxy_uri:
49
49
 
50
+ # (If Daemonised)
51
+ # Default is to check for a new artifact every 60 seconds, but only to
52
+ # actually run Puppet if there has been a change to the artifact contents.
53
+ #
54
+ # At a polling rate of 60 seconds, the cost of S3 will be about $0.02 per
55
+ # month per system running Pupistry.
56
+ #
57
+ # If you want to force regular Puppet runs regardless whether or not a new
58
+ # artifact has been released, turn daemon_minimal off, but make sure the
59
+ # frequency isn't too low - 300 seconds+ recommended otherwise Puppet will
60
+ # be hammering your system resources.
61
+ daemon_frequency: 60
62
+ daemon_minimal: true
50
63
 
51
64
 
52
65
  # The following settings are only needed on the build machines (people building
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pupistry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jethro Carr
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rufus-scheduler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: r10k
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -75,6 +89,7 @@ extra_rdoc_files: []
75
89
  files:
76
90
  - bin/pupistry
77
91
  - lib/pupistry.rb
92
+ - lib/pupistry/agent.rb
78
93
  - lib/pupistry/artifact.rb
79
94
  - lib/pupistry/bootstrap.rb
80
95
  - lib/pupistry/config.rb