Class: VagrantPlugins::Orchestrate::Command::Push

Inherits:
Object
  • Object
show all
Includes:
Vagrant::Util, CommandMixins
Defined in:
lib/vagrant-orchestrate/command/push.rb

Instance Method Summary collapse

Methods included from CommandMixins

#filter_unmanaged, #super_delete

Instance Method Details

#batchify(machines, action, options) ⇒ Object



153
154
155
156
157
158
159
160
161
162
# File 'lib/vagrant-orchestrate/command/push.rb', line 153

def batchify(machines, action, options)
  @env.batch(options[:parallel]) do |batch|
    machines.each do |machine|
      # This is necessary to disable the low level provisioning in the
      # Vagrant builtin provisioner.
      options[:provision_enabled] = false unless options[:provision]
      batch.action(machine, action, options)
    end
  end
end

#deploy(options, *groups) ⇒ Object

rubocop:disable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/vagrant-orchestrate/command/push.rb', line 116

def deploy(options, *groups)
  groups.select! { |g| g.size > 0 }
  groups.each_with_index do |machines, index|
    next if machines.empty?
    if groups.size > 1
      @env.ui.info("Orchestrating push to group number #{index + 1} of #{groups.size}.")
      @env.ui.info(" -- Hosts: #{machines.collect { |m| m.name.to_s }.join(',')}")
    end
    ENV["VAGRANT_ORCHESTRATE_COMMAND"] = "PUSH"
    begin
      batchify(machines, :push, options)
    ensure
      @logger.debug("Finished orchestrating push to group number #{index + 1} of #{groups.size}.")
      status_source = options[:status].local_path
      super_delete(status_source) if File.exist?(status_source)
      ENV.delete "VAGRANT_ORCHESTRATE_COMMAND"
    end

    # Don't prompt on the last group, that would be annoying
    if index == groups.size - 1 || options[:force]
      @logger.debug("Suppressing prompt because --force specified.") if options[:force]
    else
      return false unless prompt_for_continue
    end
  end
end

#executeObject

rubocop:disable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
# File 'lib/vagrant-orchestrate/command/push.rb', line 29

def execute
  options = {}
  options[:force] = @env.vagrantfile.config.orchestrate.force_push
  options[:provision] = true

  opts = OptionParser.new do |o|
    o.banner = "Usage: vagrant orchestrate push"
    o.separator ""

    o.on("--[no-]provision", "Enable or disable provisioning. Default is true") do |p|
      options[:provision] = p
    end

    o.on("--reboot", "Reboot a managed server after the provisioning step") do
      options[:reboot] = true
    end

    o.on("--strategy strategy", "The orchestration strategy to use. Default is serial") do |v|
      options[:strategy] = v
    end

    o.on("-f", "--force", "Suppress prompting in between groups") do
      options[:force] = true
    end
  end

  argv = parse_options(opts)
  return unless argv

  guard_clean unless ENV["VAGRANT_ORCHESTRATE_NO_GUARD_CLEAN"]

  machines = filter_unmanaged(argv)
  return 0 if machines.empty?

  retrieve_creds(machines) if @env.vagrantfile.config.orchestrate.credentials

  # Write the status file to disk so that it can be used as part of the
  # push action.
  status = RepoStatus.new
  status.write(@env.tmp_path)
  options[:status] = status

  options[:parallel] = true
  strategy = options[:strategy] || @env.vagrantfile.config.orchestrate.strategy
  @env.ui.info("Pushing to managed servers using #{strategy} strategy.")

  # Handle a couple of them more tricky edges.
  strategy = :serial if machines.size == 1
  strategy = :half_half if strategy.to_sym == :canary_half_half && machines.size == 2

  case strategy.to_sym
  when :serial
    options[:parallel] = false
    result = deploy(options, machines)
  when :parallel
    result = deploy(options, machines)
  when :canary
    # A single canary server and then the rest
    result = deploy(options, machines.take(1), machines.drop(1))
  when :half_half
    # Split into two (almost) equal groups
    groups = split(machines)
    result = deploy(options, groups.first, groups.last)
  when :canary_half_half
    # A single canary and then two equal groups
    canary = machines.take(1)
    groups = split(machines.drop(1))
    result = deploy(options, canary, groups.first, groups.last)
  else
    @env.ui.error("Invalid deployment strategy specified")
    result = false
  end

  return 1 unless result
  0
end

#guard_cleanObject



178
179
180
181
# File 'lib/vagrant-orchestrate/command/push.rb', line 178

def guard_clean
  message = "ERROR!\nThere are files that need to be committed first."
  RepoStatus.clean? && RepoStatus.committed? && !RepoStatus.untracked? || abort(message)
end

#prompt_for_continueObject

rubocop:enable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



144
145
146
147
148
149
150
151
# File 'lib/vagrant-orchestrate/command/push.rb', line 144

def prompt_for_continue
  result = @env.ui.ask("Deployment paused for manual review. Would you like to continue? (y/n) ")
  if result.upcase != "Y"
    @env.ui.info("Deployment push action cancelled by user")
    return false
  end
  true
end

#retrieve_creds(machines) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/vagrant-orchestrate/command/push.rb', line 164

def retrieve_creds(machines)
  creds = VagrantPlugins::Orchestrate::Action::SetCredentials.new
  (username, password) = creds.retrieve_creds(@env.vagrantfile.config.orchestrate.credentials, @env.ui)

  # Apply the credentials to the machine info, or back out if we were unable to procure them.
  if username && password
    machines.each do |machine|
      creds.apply_creds(machine, username, password)
    end
  else
    @env.ui.warn "Vagrant-orchestrate did find any credentials. Continuing with default credentials."
  end
end

#split(machines) ⇒ Object

rubocop:enable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity



107
108
109
110
111
112
113
# File 'lib/vagrant-orchestrate/command/push.rb', line 107

def split(machines)
  groups = machines.in_groups(2)
  # Move an item from the first to second group if they are unbalanced so that
  # the smaller group is pushed to first.
  groups.last.unshift(groups.first.pop) if groups.any? && groups.first.size > groups.last.size
  groups
end