#!/usr/local/ruby-current/bin/ruby # Copyright:: Copyright (c) 2019 eGlobalTech, Inc., all rights reserved # # Licensed under the BSD-3 license (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License in the root of the project or at # # http://egt-labs.com/mu/LICENSE.html # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require File.realpath(File.expand_path(File.dirname(__FILE__)+"/../bin/mu-load-config.rb")) # now we have our global config available as the read-only hash $MU_CFG require 'rubygems' require 'bundler/setup' require 'optimist' require 'mu' bok_dir = MU.myRoot+"/extras/image-generators" available_clouds = {} Dir.foreach(bok_dir) { |d| next if d == "." or d == ".." next if !Dir.exist?(MU.myRoot+"/extras/image-generators/"+d) available_clouds[d] = [] Dir.foreach(bok_dir+"/"+d) { |yamlfile| next if !yamlfile.match(/(.+?)\.yaml$/) platform = Regexp.last_match[1] available_clouds[d] << platform } } $opts = Optimist::options do banner <<-EOS Usage: #{$0} [-c ] [-p ] EOS opt :clouds, "Clouds for which to generate images", :require => false, :type => :strings, :default => available_clouds.keys opt :platforms, "Platforms for which to generate images", :require => false, :type => :strings, :default => available_clouds.values.flatten.sort.uniq opt :environment, "Environment with which to tag our generated images.", :require => false, :type => :string, :default => "prod" opt :age, "Minimum age, in days, at which we will replace existing images. Set to 0 to force a new build regardless of age.", :require => false, :type => :integer, :default => 30 if available_clouds.keys.include?("AWS") opt :upload_to, "AWS S3 bucket and path to which we should upload our updated image list.", :require => false, :type => :string, :default => "s3://"+MU::Cloud::BASE_IMAGE_BUCKET+MU::Cloud::BASE_IMAGE_PATH end available_clouds.keys.each { |cloud| opt (cloud.downcase+"_creds").to_sym, "Credentials to use when creating images in #{cloud}.", :require => false, :type => :string } opt :dryrun, "Don't actually run our deploy.", :require => false, :type => :boolean, :default => false end pwd = Dir.pwd if !available_clouds.keys.include?("AWS") # XXX or if we don't have permissions to write $opt[:upload_to] MU.log "No AWS credentials available- I have nowhere to upload new imaged lists. Will print to STDOUT instead.", MU::WARN end now = DateTime.now exitcode = 0 succeeded = 0 $opts[:clouds].each { |cloud| current_images = MU::Cloud.getStockImage(cloud, fail_hard: true) $opts[:platforms].each { |platform| if File.exists?(bok_dir+"/"+cloud+"/"+platform+".yaml") cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud).const_get("Server") if current_images[platform].is_a?(String) age = cloudclass.imageTimeStamp(current_images[platform]) if (now - age) >= $opts[:age] MU.log "#{cloud} image for #{platform} was last built #{age.to_s}, refreshing", MU::NOTICE else next end else needed = false if !current_images[platform] needed = true else current_images[platform].each_pair { |r, img_id| age = cloudclass.imageTimeStamp(img_id, region: r) if (now - age) >= $opts[:age] MU.log "#{cloud} image for #{platform} was last built #{age.to_s}, refreshing", MU::NOTICE needed = true break end } end next if !needed end MU.log "Loading "+bok_dir+"/"+cloud+"/"+platform+".yaml" conf_engine = MU::Config.new( bok_dir+"/"+cloud+"/"+platform+".yaml", default_credentials: $opts[(cloud.downcase+"_creds").to_sym] ) stack_conf = conf_engine.config if $opts[:dryrun] puts stack_conf.to_yaml else begin deployer = MU::Deploy.new( $opts[:environment], stack_conf: stack_conf ) deployer.run MU.log "New images for #{cloud}:#{platform}", MU::NOTICE, details: deployer.mommacat.deployment['images'] current_images[platform] ||= {} current_images.deep_merge!(deployer.mommacat.deployment['images']) # Scrub any loose metadata left over from our image deployment. It's # ok, this won't touch the images we just made. MU::Cleanup.run(deployer.mommacat.deploy_id, skipsnapshots: true, verbosity: MU::Logger::QUIET) succeeded += 1 rescue Exception => e MU.log e.message, MU::ERR exitcode = 1 end end end } if !$opts[:dryrun] and succeeded > 0 puts current_images.to_yaml if available_clouds.keys.include?("AWS") MU::Cloud::AWS::Bucket.upload($opts[:upload_to]+"/"+cloud+".yaml", data: current_images.to_yaml, credentials: $opts[:aws_creds], acl: "public-read") end end } exit exitcode