Commit fd95fde3 authored by Marin Jankovski's avatar Marin Jankovski

Merge tag 'v5.0.0' of https://github.com/chef/omnibus into upgrade_omnibus_version

Version 5.0.0
parents dc6b89b2 c078b22c
rvm:
- 2.0.0
- 2.1
- 2.2
bundler_args: "--jobs 7 --without docs local"
branches:
only:
......
Omnibus CHANGELOG
=================
v5.0.0 (November 10, 2015)
--------------------------
### New Features
- Wind River Linux 5 support for Cisco Nexus devices (#539)
- [artifactory publisher] Support custom properties in Artifactory publishing (#568)
- [msi packager] New "fast" mode for MSI packager (#565)
- Change the `appbundler` DSL method to not make an apps dir
- Unit and functional tests now run on Windows (and are tested by Appveyor) (#556, #557)
### Bug Fixes
- [msi packager] Fix missing package name in signature (#541)
- [rpm packager] Fix building RPMs on ARM platforms (#542)
- [bff packager] Fix regression with AIX package ownership in staging directory (#553)
- [solaris packager] Use the proper architecture value in Solaris packages (#554, #555)
- Add info message for publish cli corner case (#551)
- [net fetcher] missing checksum raises exception (#549)
### Potentially Breaking Changes
- Dropped Ruby 1.9.x support (#567)
v4.1.0 (September 1, 2015)
-------------------------
### New Features
......
......@@ -18,9 +18,10 @@ project lead.
## Maintainers
* [Daniel DeLeo](https://github.com/danielsdeleo)
* [Jay Mundrawala](https://github.com/jdmundrawala)
* [Jay Mundrawala](https://github.com/jaym)
* [Lamont Granquist](https://github.com/lamont-granquist)
* [Scott Hain](https://github.com/scotthain)
* [Seth Vargo](http://github.com/sethvargo)
* [Steven Danna](https://github.com/stevendanna)
* [Yvonne Lam](http://github.com/yzl)
* [Thom May](https://github.com/thommay)
......@@ -204,7 +204,7 @@ Additionally, there are a number of DSL methods avaiable inside the `build` bloc
For more DSL methods, please consult the [`Builder` documentation](http://rubydoc.info/github/opscode/omnibus/Omnibus/Builder).
You can support building multiple verisons of the same software in the same software definition file using the `version` method and giving a block:
You can support building multiple versions of the same software in the same software definition file using the `version` method and giving a block:
```ruby
name "ruby"
......
......@@ -276,27 +276,12 @@ module Omnibus
def appbundle(app_name, options = {})
build_commands << BuildCommand.new("appbundle `#{app_name}'") do
bin_dir = "#{install_dir}/bin"
embedded_apps_root = "#{install_dir}/embedded/apps"
embedded_app_dir = "#{embedded_apps_root}/#{app_name}"
gemfile_lock = "#{embedded_app_dir}/Gemfile.lock"
appbundler_bin = windows_safe_path("#{install_dir}/embedded/bin/appbundler")
# Ensure the main bin dir exists
FileUtils.mkdir_p(bin_dir)
# Ensure the embedded app directory exists
FileUtils.mkdir_p(embedded_apps_root)
# Copy the application code into place
FileUtils.cp_r("#{Omnibus::Config.source_dir}/#{app_name}", embedded_apps_root)
# Delete any top-level `.git` directory
FileUtils.rm_rf("#{embedded_app_dir}/.git")
# Prepare the environment
options[:env] ||= {}
env = with_embedded_path || {}
env["BUNDLE_GEMFILE"] = gemfile_lock
options[:env].merge!(env)
shellout!("#{appbundler_bin} '#{embedded_app_dir}' '#{bin_dir}'", options)
shellout!("#{appbundler_bin} '#{Omnibus::Config.source_dir}/#{app_name}' '#{bin_dir}'", options)
end
end
expose :appbundle
......
......@@ -70,6 +70,10 @@ module Omnibus
type: :boolean,
desc: 'Optionally create an Artifactory build record for the published artifacts',
default: true
method_option :properties,
type: :hash,
desc: 'Properites to attach to published artifacts',
default: {}
desc 'artifactory REPOSITORY PATTERN', 'Publish to an Artifactory instance'
def artifactory(repository, pattern)
options[:repository] = repository
......
......@@ -214,6 +214,18 @@ EOH
end
end
class ChecksumMissing < Error
def initialize(software)
super <<-EOH
Verification for #{software.name} failed due to a missing checksum.
This added security check is used to prevent MITM attacks when downloading the
remote file. You must specify a checksum for each version of software downloaded
from a remote location.
EOH
end
end
class ChecksumMismatch < Error
def initialize(software, expected, actual)
super <<-EOH
......
......@@ -229,12 +229,16 @@ module Omnibus
#
# The digest type defined in the software definition
#
# @raise [ChecksumMissing]
# if the checksum does not exist
#
# @return [Symbol]
#
def digest_type
DIGESTS.each do |digest|
return digest if source.key? digest
end
raise ChecksumMissing.new(self)
end
#
......
......@@ -96,7 +96,7 @@ module Omnibus
when 1
from_hash_v1(manifest_data)
else
raise InvalidManifestFormat, "Unknown manifest fromat version: #{manifest_data['manifest_format']}"
raise InvalidManifestFormat, "Unknown manifest format version: #{manifest_data['manifest_format']}"
end
end
......
......@@ -18,6 +18,9 @@ require 'json'
module Omnibus
class Metadata
extend Sugarable
include Sugarable
class << self
#
# Render the metadata for the package at the given path, generated by the
......@@ -108,8 +111,14 @@ module Omnibus
# @return [String]
#
def arch
if (Ohai['platform'] == 'windows') && (Config.windows_arch.to_sym == :x86)
if windows? && windows_arch_i386?
'i386'
elsif solaris?
if intel?
'i386'
elsif sparc?
'sparc'
end
else
Ohai['kernel']['machine']
end
......@@ -132,9 +141,9 @@ module Omnibus
# the platform family short name
#
def platform_shortname
if Ohai['platform_family'] == 'rhel'
if rhel?
'el'
elsif Ohai['platform'] == 'suse'
elsif suse?
'sles'
else
Ohai['platform']
......@@ -157,7 +166,7 @@ module Omnibus
#
def truncate_platform_version(platform_version, platform)
case platform
when 'centos', 'debian', 'el', 'fedora', 'freebsd', 'omnios', 'pidora', 'raspbian', 'rhel', 'sles', 'suse', 'smartos'
when 'centos', 'debian', 'el', 'fedora', 'freebsd', 'omnios', 'pidora', 'raspbian', 'rhel', 'sles', 'suse', 'smartos', 'nexus', 'ios_xr'
# Only want MAJOR (e.g. Debian 7, OmniOS r151006, SmartOS 20120809T221258Z)
platform_version.split('.').first
when 'aix', 'gentoo', 'mac_os_x', 'openbsd', 'slackware', 'solaris2', 'opensuse', 'ubuntu'
......
......@@ -37,6 +37,7 @@ module Omnibus
'debian' => DEB,
'fedora' => RPM,
'rhel' => RPM,
'wrlinux' => RPM,
'aix' => BFF,
'solaris2' => Solaris,
'windows' => MSI,
......
......@@ -22,6 +22,7 @@ module Omnibus
include Digestable
include Logging
include NullArgumentable
include Sugarable
include Templating
include Util
......
......@@ -173,7 +173,7 @@ module Omnibus
# This implies that if we are in /tmp/staging/project/dir/things,
# we will chown from 'project' on, rather than 'project/dir', which leaves
# project owned by the build user (which is incorrect)
shellout!("sudo chown -R 0:0 #{File.join(staging_dir, project.install_dir)}")
shellout!("sudo chown -R 0:0 #{File.join(staging_dir, project.install_dir.match(/^\/?(\w+)/).to_s)}")
log.info(log_key) { "Creating .bff file" }
# Since we want the owner to be root, we need to sudo the mkinstallp
......
......@@ -421,6 +421,10 @@ module Omnibus
else
'armv7l'
end
when 'aarch64'
# Debian prefers amd64 on ARMv8/AArch64 (64bit ARM) platforms
# see https://wiki.debian.org/Arm64Port
'arm64'
when 'ppc64le'
# Debian prefers to use ppc64el for little endian architecture name
# where as others like gnutools/rhel use ppc64le( note the last 2 chars)
......
......@@ -14,6 +14,8 @@
# limitations under the License.
#
require 'pathname'
module Omnibus
class Packager::MSI < Packager::Base
DEFAULT_TIMESTAMP_SERVERS = ['http://timestamp.digicert.com',
......@@ -45,48 +47,29 @@ module Omnibus
FileSyncer.glob("#{resources_path}/assets/*").each do |file|
copy_file(file, "#{resources_dir}/assets/#{File.basename(file)}")
end
# Source for the custom action is at https://github.com/chef/fastmsi-custom-action
# The dll will be built separately as part of the custom action build process
# and made available as a binary for the Omnibus projects to use.
copy_file(resource_path('CustomActionFastMsi.CA.dll'), staging_dir) if fast_msi
end
build do
# If fastmsi, zip up the contents of the install directory
shellout!(zip_command) if fast_msi
# Harvest the files with heat.exe, recursively generate fragment for
# project directory
Dir.chdir(staging_dir) do
shellout! <<-EOH.split.join(' ').squeeze(' ').strip
heat.exe dir "#{windows_safe_path(project.install_dir)}"
-nologo -srd -gg -cg ProjectDir
-dr PROJECTLOCATION
-var "var.ProjectSourceDir"
-out "project-files.wxs"
EOH
shellout!(heat_command)
# Compile with candle.exe
log.debug(log_key) { "wix_candle_flags: #{wix_candle_flags}" }
shellout! <<-EOH.split.join(' ').squeeze(' ').strip
candle.exe
-nologo
#{wix_candle_flags}
#{wix_extension_switches(wix_candle_extensions)}
-dProjectSourceDir="#{windows_safe_path(project.install_dir)}" "project-files.wxs"
"#{windows_safe_path(staging_dir, 'source.wxs')}"
EOH
shellout!(candle_command)
# Create the msi, ignoring the 204 return code from light.exe since it is
# about some expected warnings
msi_file = windows_safe_path(Config.package_dir, msi_name)
light_command = <<-EOH.split.join(' ').squeeze(' ').strip
light.exe
-nologo
-ext WixUIExtension
#{wix_extension_switches(wix_light_extensions)}
-cultures:en-us
-loc "#{windows_safe_path(staging_dir, 'localization-en-us.wxl')}"
project-files.wixobj source.wixobj
-out "#{msi_file}"
EOH
shellout!(light_command, returns: [0, 204])
shellout!(light_command(msi_file), returns: [0, 204])
if signing_identity
sign_package(msi_file)
......@@ -94,32 +77,11 @@ module Omnibus
# This assumes, rightly or wrongly, that any installers we want to bundle
# into our installer will be downloaded by omnibus and put in the cache dir
if bundle_msi
shellout! <<-EOH.split.join(' ').squeeze(' ').strip
candle.exe
-nologo
#{wix_candle_flags}
-ext WixBalExtension
#{wix_extension_switches(wix_candle_extensions)}
-dOmnibusCacheDir="#{windows_safe_path(File.expand_path(Config.cache_dir))}"
"#{windows_safe_path(staging_dir, 'bundle.wxs')}"
EOH
shellout!(candle_command(is_bundle: true))
bundle_file = windows_safe_path(Config.package_dir, bundle_name)
bundle_light_command = <<-EOH.split.join(' ').squeeze(' ').strip
light.exe
-nologo
-ext WixUIExtension
-ext WixBalExtension
#{wix_extension_switches(wix_light_extensions)}
-cultures:en-us
-loc "#{windows_safe_path(staging_dir, 'localization-en-us.wxl')}"
bundle.wixobj
-out "#{bundle_file}"
EOH
shellout!(bundle_light_command, returns: [0, 204])
shellout!(light_command(bundle_file, is_bundle: true), returns: [0, 204])
if signing_identity
sign_package(bundle_file)
......@@ -149,7 +111,7 @@ module Omnibus
@upgrade_code || raise(MissingRequiredAttribute.new(self, :upgrade_code, '2CD7259C-776D-4DDB-A4C8-6E544E580AA1'))
else
unless val.is_a?(String)
raise InvalidValue.new(:parameters, 'be a String')
raise InvalidValue.new(:upgrade_code, 'be a String')
end
@upgrade_code = val
......@@ -245,6 +207,25 @@ module Omnibus
end
expose :bundle_msi
#
# Signal that we're building a zip-based MSI
#
# @example
# fast_msi true
#
# @param [TrueClass, FalseClass] value
# whether we're building a zip-based MSI or not
#
# @return [TrueClass, FalseClass]
# whether we're building a zip-based MSI or not
def fast_msi(val = false)
unless (val.is_a?(TrueClass) || val.is_a?(FalseClass))
raise InvalidValue.new(:fast_msi, 'be TrueClass or FalseClass')
end
@fast_msi ||= val
end
expose :fast_msi
#
# Set the signing certificate name
#
......@@ -311,6 +292,37 @@ module Omnibus
end
expose :signing_identity
#
# Discovers a path to a gem/file included in a gem under the install directory.
#
# @example
# gem_path 'chef-[0-9]*-mingw32' -> 'some/path/to/gems/chef-version-mingw32'
#
# @param [String] glob
# a ruby acceptable glob path such as with **, *, [] etc.
#
# @return [String] path relative to the project's install_dir
#
# Raises exception the glob matches 0 or more than 1 file/directory.
#
def gem_path(glob = NULL)
unless glob.is_a?(String) || null?(glob)
raise InvalidValue.new(:glob, 'be an String')
end
install_path = Pathname.new(project.install_dir)
# Find path in which the Chef gem is installed
search_pattern = install_path.join('**', 'gems')
search_pattern = search_pattern.join(glob) unless null?(glob)
file_paths = Pathname.glob(search_pattern).find
raise "Could not find `#{search_pattern}'!" if file_paths.none?
raise "Multiple possible matches of `#{search_pattern}'! : #{file_paths}" if file_paths.count > 1
file_paths.first.relative_path_from(install_path).to_s
end
expose :gem_path
#
# @!endgroup
# --------------------------------------------------
......@@ -415,7 +427,7 @@ module Omnibus
friendly_name: project.friendly_name,
maintainer: project.maintainer,
hierarchy: hierarchy,
fastmsi: fast_msi,
wix_install_dir: wix_install_dir,
}
)
......@@ -462,6 +474,106 @@ module Omnibus
"#{versions[0]}.#{versions[1]}.#{versions[2]}.#{project.build_iteration}"
end
#
# Get the shell command to create a zip file that contains
# the contents of the project install directory
#
# @return [String]
#
def zip_command
<<-EOH.split.join(' ').squeeze(' ').strip
7z a -r
#{windows_safe_path(staging_dir)}\\#{project.name}.zip
#{windows_safe_path(project.install_dir)}\\*
EOH
end
#
# Get the shell command to run heat in order to create a
# a WIX manifest of project files to be packaged into the MSI
#
# @return [String]
#
def heat_command
if fast_msi
<<-EOH.split.join(' ').squeeze(' ').strip
heat.exe file "#{project.name}.zip"
-cg ProjectDir
-dr INSTALLLOCATION
-nologo -sfrag -srd -sreg -gg
-out "project-files.wxs"
EOH
else
<<-EOH.split.join(' ').squeeze(' ').strip
heat.exe dir "#{windows_safe_path(project.install_dir)}"
-nologo -srd -sreg -gg -cg ProjectDir
-dr PROJECTLOCATION
-var "var.ProjectSourceDir"
-out "project-files.wxs"
EOH
end
end
#
# Get the shell command to complie the project WIX files
#
# @return [String]
#
def candle_command(is_bundle: false)
if is_bundle
<<-EOH.split.join(' ').squeeze(' ').strip
candle.exe
-nologo
#{wix_candle_flags}
-ext WixBalExtension
#{wix_extension_switches(wix_candle_extensions)}
-dOmnibusCacheDir="#{windows_safe_path(File.expand_path(Config.cache_dir))}"
"#{windows_safe_path(staging_dir, 'bundle.wxs')}"
EOH
else
<<-EOH.split.join(' ').squeeze(' ').strip
candle.exe
-nologo
#{wix_candle_flags}
#{wix_extension_switches(wix_candle_extensions)}
-dProjectSourceDir="#{windows_safe_path(project.install_dir)}" "project-files.wxs"
"#{windows_safe_path(staging_dir, 'source.wxs')}"
EOH
end
end
#
# Get the shell command to link the project WIX object files
#
# @return [String]
#
def light_command(out_file, is_bundle: false)
if is_bundle
<<-EOH.split.join(' ').squeeze(' ').strip
light.exe
-nologo
-ext WixUIExtension
-ext WixBalExtension
#{wix_extension_switches(wix_light_extensions)}
-cultures:en-us
-loc "#{windows_safe_path(staging_dir, 'localization-en-us.wxl')}"
bundle.wixobj
-out "#{out_file}"
EOH
else
<<-EOH.split.join(' ').squeeze(' ').strip
light.exe
-nologo
-ext WixUIExtension
#{wix_extension_switches(wix_light_extensions)}
-cultures:en-us
-loc "#{windows_safe_path(staging_dir, 'localization-en-us.wxl')}"
project-files.wixobj source.wixobj
-out "#{out_file}"
EOH
end
end
#
# The display version calculated from the {Project#build_version}.
#
......@@ -545,6 +657,7 @@ module Omnibus
arr << '/sm' if machine_store?
arr << "/s #{cert_store_name}"
arr << "/sha1 #{thumbprint}"
arr << "/d #{project.package_name}"
arr << "\"#{msi_file}\""
end
shellout!(cmd.join(" "))
......
......@@ -282,27 +282,27 @@ module Omnibus
render_template(resource_path('spec.erb'),
destination: spec_file,
variables: {
name: safe_base_package_name,
version: safe_version,
iteration: safe_build_iteration,
vendor: vendor,
license: license,
dist_tag: dist_tag,
architecture: safe_architecture,
maintainer: project.maintainer,
homepage: project.homepage,
description: project.description,
priority: priority,
category: category,
conflicts: project.conflicts,
replaces: project.replaces,
dependencies: project.runtime_dependencies,
user: project.package_user,
group: project.package_group,
scripts: scripts,
config_files: config_files,
files: files,
build_dir: build_dir,
name: safe_base_package_name,
version: safe_version,
iteration: safe_build_iteration,
vendor: vendor,
license: license,
dist_tag: dist_tag,
maintainer: project.maintainer,
homepage: project.homepage,
description: project.description,
priority: priority,
category: category,
conflicts: project.conflicts,
replaces: project.replaces,
dependencies: project.runtime_dependencies,
user: project.package_user,
group: project.package_group,
scripts: scripts,
config_files: config_files,
files: files,
build_dir: build_dir,
platform_family: Ohai['platform_family']
}
)
end
......@@ -316,6 +316,7 @@ module Omnibus
#
def create_rpm_file
command = %|fakeroot rpmbuild|
command << %| --target #{safe_architecture}|
command << %| -bb|
command << %| --buildroot #{staging_dir}/BUILD|
command << %| --define '_topdir #{staging_dir}'|
......@@ -494,16 +495,27 @@ module Omnibus
# http://rpm.org/ticket/56
#
if version =~ /\-/
converted = version.gsub('-', '~')
log.warn(log_key) do
"Tildes hold special significance in the RPM package versions. " \
"They mark a version as lower priority in RPM's version compare " \
"logic. We'll replace all dashes (-) with tildes (~) so pre-release" \
"versions get sorted earlier then final versions. Converting" \
"`#{project.build_version}' to `#{converted}'."
if Ohai['platform_family'] == 'wrlinux'
converted = version.gsub('-', '_') #WRL has an elderly RPM version
log.warn(log_key) do
"Omnibus replaces dashes (-) with tildes (~) so pre-release " \
"versions get sorted earlier than final versions. However, the " \
"version of rpmbuild on Wind River Linux does not support this. " \
"All dashes will be replaced with underscores (_). Converting " \
"`#{project.build_version}' to `#{converted}'."
end
else
converted = version.gsub('-', '~')
log.warn(log_key) do
"Tildes hold special significance in the RPM package versions. " \
"They mark a version as lower priority in RPM's version compare " \
"logic. We'll replace all dashes (-) with tildes (~) so pre-release" \
"versions get sorted earlier then final versions. Converting" \
"`#{project.build_version}' to `#{converted}'."
end
end
version = converted
end
......
......@@ -14,29 +14,32 @@
# limitations under the License.
#
require 'socket'
module Omnibus
class Packager::Solaris < Packager::Base
# @return [Hash]
SCRIPT_MAP = {
# Default Omnibus naming
postinst: 'postinstall',
postrm: 'postremove',
# Default Solaris naming
postinstall: 'postinstall',
postremove: 'postremove',
}.freeze
id :solaris
build do
shellout! "cd #{install_dirname} && find #{install_basename} -print > #{staging_dir_path('files')}"
write_prototype_content
write_pkginfo_content
copy_file("#{project.package_scripts_path}/postinst", staging_dir_path('postinstall'))
copy_file("#{project.package_scripts_path}/postrm", staging_dir_path('postremove'))
shellout! "pkgmk -o -r #{install_dirname} -d #{staging_dir} -f #{staging_dir_path('Prototype')}"
shellout! "pkgchk -vd #{staging_dir} #{project.package_name}"
shellout! "pkgtrans #{staging_dir} #{package_path} #{project.package_name}"
write_scripts
write_prototype_file
write_pkginfo_file
create_solaris_file
end
# @see Base#package_name
def package_name
"#{project.package_name}-#{pkgmk_version}.#{Ohai['kernel']['machine']}.solaris"
"#{project.package_name}-#{pkgmk_version}.#{safe_architecture}.solaris"
end
def pkgmk_version
......@@ -50,24 +53,42 @@ module Omnibus
def install_basename
File.basename(project.install_dir)
end
def staging_dir_path(file_name)
File.join(staging_dir, file_name)