require 'atlas' require 'dotenv/tasks' require 'pathname' require 'progress' # Show progress when file is read by excon used by atlas class BodyProgress # :nodoc: def initialize(path, &block) fail ArgumentError, 'block required' unless block @io = File.open(path) Progress.start(path, File.size(path)) do yield self end end def size @io.size end def read(length) data = @io.read(length) Progress.step data.length if data data end end class Box # :nodoc: attr_reader :definition_path, :definition_dir, :name, :path def initialize(definition_path) @definition_path = Pathname(definition_path) @definition_dir = @definition_path.dirname @name = @definition_dir.basename.to_s @path = Pathname("#{@name}.box") end def dependencies [definition_path] + Array(definition[:postinstall_files]).map do |path| definition_dir + path end end def build sh(*%W[veewee vbox build --auto --checksum --force --nogui #{name}]) sh(*%w[sleep 30]) sh(*%W[veewee vbox export --force #{name}]) sh(*%W[veewee vbox destroy #{name}]) end def add assert_box_created sh(*%W[vagrant box add --force --name boxes/#{path} #{path}]) end def upload(version) assert_box_created box = Atlas::Box.create({ :username => 'image_optim_pack', :name => name, :short_description => "minimal #{name} (bash, wget) from #{definition[:iso_file]}", }) version = box.create_version(:version => version) provider = version.create_provider(:name => 'virtualbox') BodyProgress.new(path) do |f| provider.upload(f) end version.release end private def definition @definition ||= begin eval definition_path.read.sub('Veewee::Session.declare', '{}.merge') end end def assert_box_created abort "#{path} doesn't exist" unless path.size? end def sh(*args) abort unless system(*args) end end task :atlas => :dotenv do token = ENV['ATLAS_TOKEN'].to_s fail 'ATLAS_TOKEN missing' if token.empty? Atlas.configure do |config| config.access_token = token end end desc 'build all boxes' task :build desc 'add all boxes to vagrant' task :add desc 'upload all boxes to atlas' task :upload version = Time.now.strftime('%Y%m%d.0.0') Dir['definitions/*/definition.rb'].each do |definition_path| box = Box.new(definition_path) desc "build #{box.path}" file box.path => box.dependencies do box.build end task :build => box.path namespace :add do desc "add #{box.path}" task box.name => box.path do box.add end end task :add => "add:#{box.name}" namespace :upload do desc "upload #{box.path}" task box.name => [:atlas, box.path] do box.upload(version) end end task :upload => "upload:#{box.name}" end desc 'remove *.box and iso dir' task :clean do sh 'rm *.box || true' sh 'rm -r iso || true' end task :default => :build