Class: Chef::Knife::PdSync

Inherits:
Chef::Knife show all
Defined in:
lib/chef/knife/pd_sync.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#altered_cookbooksObject (readonly)

Returns the value of attribute altered_cookbooks.



25
26
27
# File 'lib/chef/knife/pd_sync.rb', line 25

def altered_cookbooks
  @altered_cookbooks
end

Instance Method Details

#check_commitObject



124
125
126
127
128
129
130
# File 'lib/chef/knife/pd_sync.rb', line 124

def check_commit
  if origin_commit.nil?
    ui.confirm('failed to determine the origin/master. sync anyway?')
  elsif local_branch == 'master' && local_commit != origin_commit
    ui.confirm('local master branch is different than origin, sync anyway?')
  end
end

#chef_serverObject



140
141
142
# File 'lib/chef/knife/pd_sync.rb', line 140

def chef_server
  URI(Chef::Config[:chef_server_url]).host
end

#converge_by(msg) ⇒ Object



164
165
166
167
168
169
170
# File 'lib/chef/knife/pd_sync.rb', line 164

def converge_by(msg)
  if config[:why_run]
    ui.info('Will '+msg)
  else
    yield if block_given?
  end
end

#local_branchObject



136
137
138
# File 'lib/chef/knife/pd_sync.rb', line 136

def local_branch
  %x(git symbolic-ref --short HEAD).strip! || 'unknown'
end

#local_commitObject



156
157
158
# File 'lib/chef/knife/pd_sync.rb', line 156

def local_commit
  @local_commit ||= %x(git rev-parse master).strip! || 'unknown'
end

#localhostObject



160
161
162
# File 'lib/chef/knife/pd_sync.rb', line 160

def localhost
  @localhost ||= Socket.gethostname
end

#origin_commitObject



144
145
146
147
148
149
150
151
152
153
154
# File 'lib/chef/knife/pd_sync.rb', line 144

def origin_commit
  @origin_commit||= begin
    Timeout::timeout(5) do
      commit = Mixlib::ShellOut.new("git ls-remote origin master | awk '{ print $1 }'")
      commit.run_command
      commit.exitstatus == 0 ? commit.stdout.strip : nil
    end
  rescue Timeout::Error
    nil
  end
end

#preflight_checksObject



113
114
115
116
117
118
119
120
121
122
# File 'lib/chef/knife/pd_sync.rb', line 113

def preflight_checks
  vdir = File.join(Dir.pwd, 'vendor')
  if vendor_dir != vdir
    ui.confirm("vendor directory (#{vendor_dir}) is different than standard one(#{vdir}), continue?")
  end
  if local_branch != 'master'
    ui.confirm("You are deploying a non-master branch(#{local_branch}), continue?")
  end
  check_commit
end

#runObject



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/chef/knife/pd_sync.rb', line 73

def run
  @altered_cookbooks = nil
  if config[:restore]
    ui.warn 'pd sync will delete and reupload all cookbooks!'
    plugin = Chef::Knife::CookbookBulkDelete.new
    plugin.name_args = Array('.')
    plugin.config[:yes] = true
    plugin.config[:purge] = true
    converge_by "delete all existing cookbooks" do
      plugin.run
    end
  end
  lockfile = '/tmp/restore_chef.lock'
  user = Chef::Config[:node_name] || 'unknown'
  converge_by 'perform pre-syn checks' do
    preflight_checks
  end
  lock = PagerDuty::ChefServer::SyncLock.new(
      lockfile, chef_server, localhost, user, local_branch
    )
  converge_by 'acquire lock' do
    lock.lock
  end
  sync = PagerDuty::ChefServer::Sync.new(
    vendor_dir: vendor_dir,
    why_run: config[:why_run]
    )
  begin
    @altered_cookbooks = sync.run
    update_commit
  rescue StandardError => e
    ui.warn(e.message)
    ui.warn(e.backtrace)
  ensure
    converge_by 'release lock' do
      lock.unlock
    end
  end
end

#update_commitObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/chef/knife/pd_sync.rb', line 172

def update_commit
  ui.info("updating commit from #{origin_commit} => #{local_commit}")
  file = Tempfile.new(['restorechef', '.json'])

  unless Chef::DataBag.list.keys.include?('metadata')
    plugin = Chef::Knife::DataBagCreate.new
    plugin.name_args = Array('metadata')
    converge_by 'create data bag metadata' do
      plugin.run
    end
  end
  begin
    file.write(JSON.dump({ id: 'commit', commit: local_commit }))
    file.flush
    dbag = Chef::Knife::DataBagFromFile.new
    dbag.name_args = ['metadata', file.path]
    converge_by 'update commit' do
      dbag.run
    end
  ensure
    file.close
    file.unlink
  end
end

#vendor_dirObject



132
133
134
# File 'lib/chef/knife/pd_sync.rb', line 132

def vendor_dir
  Chef::Config[:cookbook_path].first
end