Skip to content

Instantly share code, notes, and snippets.

@colinrymer
Last active August 29, 2015 14:00
Show Gist options
  • Save colinrymer/11062908 to your computer and use it in GitHub Desktop.
Save colinrymer/11062908 to your computer and use it in GitHub Desktop.
require 'yaml'
require 'erb'
require 'fileutils'
require 'primedia/rpm_defaults'
module Primedia
class RpmHelper
include Rake::DSL if defined? Rake::DSL
class << self
# set when install'd.
attr_accessor :instance
def install_tasks(opts = {})
new(opts[:name]).install
end
end
attr_reader :spec_path
def initialize(name = nil)
end
def install(name = nil, version = nil, release = nil)
namespace :rpm do
desc "Build #{name}-#{version}-#{release}.rpm into the pkg directory."
task :build do
build(name, version, release)
end
end
end
private
def build(name, version, release)
if File.exists?(config_file)
user_config = YAML.load_file(config_file)
else
fail "Must provide a config/rpm.yml file."
end
if File.exists?(build_info_file)
build_info = YAML.load_file(build_info_file)
else
fail "Must provide a BUILD_INFO file."
end
# opts is used by the ERB template which has access to it due to being passed the current binding.
opts = Primedia::RpmDefaults::SPEC_DEFAULTS.merge(user_config)
opts['version'] = build_info['version'].gsub('_','.')
opts['revision'] = short_sha(build_info['revision'])
app_name = opts['app']['name']
filename = "#{app_name}.spec"
build_root = "/tmp/rpmbuild-#{app_name}-#{opts['revision']}"
%w(BUILD RPMS SOURCES SPECS SRPMS).each do |build_dir|
FileUtils.mkdir_p(File.join(build_root, build_dir))
end
File.open("#{build_root}/SPECS/#{filename}", 'w') do |f|
f.write( spec_template.result(binding) )
end
FileUtils.cp build_info['artifact_name'], "#{build_root}/SOURCES/#{app_name}.tar.gz"
Bundler.clean_system("rpmbuild --define '_topdir #{build_root}' -ba #{build_root}/SPECS/ag.spec")
end
def config_file
@config_file ||= File.join(Rake.application.original_dir, 'config/rpm.yml')
end
def build_info_file
@build_info_file ||= File.join(Rake.application.original_dir, 'BUILD_INFO')
end
def spec_template
@spec_template ||= ERB.new(File.read(spec_template_file))
end
def spec_template_file
@spec_template_file ||= File.expand_path('../templates/ruby.spec.erb', __FILE__)
end
def date_as_version
# e.g. 2013.12.31
Time.now.strftime("%Y.%m.%d.%H.%M")
end
def short_sha(revision)
revision[0,6]
end
end
end
# RPM Spec File for Ruby Application deployment via RPM
#
# by Colin Rymer, 2013-12-03
#
# Inspired by:
# RPM Spec File for Rails Application deployment via RPM
# by Tilo Sloboda, 2012-10-17
#
# We should use a separate build user, not root, to create the RPMs
#
Name: <%= opts['app']['name'] %>
Version: <%= opts['version'] %>
Release: <%= opts['revision'] %>
Summary: <%= "#{opts['app']['name']}-#{opts['version']}-#{opts['revision']}" %>
Group: Applications/Internet
License: Proprietary
URL: <%= opts['app']['url'] %>
# AutoReqProv: see doc!!! we don't want shared libraries to the dependencies
AutoReqProv: no
ExclusiveArch: x86_64
ExclusiveOS: linux
Provides: <%= "#{opts['app']['name']} = #{opts['version']}" %>
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
# List of all tools needed to BUILD the RPM:
# this also needs to list required YUM / RPM packages, such as shared libraries specific for the application!!
<% opts['app']['build_requires'].each do |req| %>
BuildRequires: <%= req %>
<% end if opts['app']['build_requires'] %>
# REQUIREMENTS:
Requires: chruby-ruby = <%= opts["app"]["ruby_version"] %>
<% opts['app']['requires'].each do |req| %>
Requires: <%= req %>
<% end if opts['app']['requires'] %>
Source: <%= opts['app']['name'] %>.tar.gz
# No debuginfo rpm creation, etc.
%global debug_package %{nil}
%define deploy_user <%= opts['deploy']['user'] %>
%define deploy_group <%= opts['deploy']['group'] %>
%description
<%= opts['app']['description'] %>
# run after RPM is built
%clean
rm -rf $RPM_BUILD_ROOT
# run before RPM is built:
%prep
%setup -q -c
%build
bundle install --deployment --without <%= opts["app"]["bundle_without"].join(' ') %>
# these files are not needed for the deployment:
<% opts['app']['exclude'].each do |file| %>
<%= "rm -rf #{file}" unless file.start_with?('/') %>
<% end %>
# HOOK for installing the compiled bits into a directory structure which will then be bundled up into the actual RPM:
%install
mkdir -p %{buildroot}/var/log/%{name} %{buildroot}/var/www/%{name} %{buildroot}/var/run/%{name}
cp -R ./ %{buildroot}/var/www/%{name}
# Manifest of all Files which are part of the RPM:
%files
%defattr(-,%{deploy_user},%{deploy_group},0755)
/var/www/%{name}
%config %ghost /var/log/%{name}
%config %ghost /var/run/%{name}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment