lib/mixlib/install.rb in mixlib-install-0.7.1 vs lib/mixlib/install.rb in mixlib-install-0.8.0.alpha.0
- old
+ new
@@ -1,7 +1,8 @@
#
# Author:: Thom May (<thom@chef.io>)
+# Author:: Patrick Wright (<patrick@chef.io>)
# Copyright:: Copyright (c) 2015 Chef, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,202 +15,78 @@
# 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 "mixlib/install/util"
-require "cgi"
+require "mixlib/versioning"
+require "mixlib/install/backend"
+require "mixlib/install/options"
+require "mixlib/install/generator"
+
module Mixlib
class Install
- attr_accessor :version
- attr_accessor :powershell
+ attr_reader :options
- attr_accessor :prerelease
-
- attr_accessor :nightlies
-
- attr_accessor :install_flags
-
- attr_accessor :endpoint
-
- attr_accessor :root
-
- attr_accessor :use_sudo
-
- attr_reader :sudo_command
-
- def sudo_command=(cmd)
- if cmd.nil?
- @use_sudo = false
- else
- @sudo_command = cmd
- end
+ def initialize(options = {})
+ @options = Options.new(options)
end
- attr_accessor :http_proxy
- attr_accessor :https_proxy
-
- attr_accessor :omnibus_url
- attr_accessor :install_msi_url
-
- VALID_INSTALL_OPTS = %w(omnibus_url
- endpoint
- http_proxy
- https_proxy
- install_flags
- install_msi_url
- nightlies
- prerelease
- project
- root
- use_sudo
- sudo_command)
-
- def initialize(version, powershell = false, opts = {})
- @version = version || "latest"
- @powershell = powershell
- @http_proxy = nil
- @https_proxy = nil
- @install_flags = nil
- @prerelease = false
- @nightlies = false
- @endpoint = "metadata"
- @omnibus_url = "https://www.chef.io/chef/install.sh"
- @use_sudo = true
- @sudo_command = "sudo -E"
-
- @root = if powershell
- "$env:systemdrive\\opscode\\chef"
- else
- "/opt/chef"
- end
-
- parse_opts(opts)
+ #
+ # Fetch artifact metadata information
+ #
+ # @return [ArtifactInfo] fetched artifact data
+ #
+ def artifact_info
+ Backend.info(options)
end
+ #
+ # Returns an install script for the given options
+ #
+ # @return [String] script for installing with given options
+ #
def install_command
- vars = if powershell
- install_command_vars_for_powershell
- else
- install_command_vars_for_bourne
- end
- shell_code_from_file(vars)
+ Generator.install_command(options)
end
- private
-
- # Generates the install command variables for Bourne shell-based
- # platforms.
#
- # @return [String] shell variable lines
- # @api private
- def install_command_vars_for_bourne
- flags = %w[latest true nightlies].include?(version) ? "" : "-v #{CGI.escape(version)}"
- flags << " " << "-n" if nightlies
- flags << " " << "-p" if prerelease
- flags << " " << install_flags if install_flags
-
- [
- shell_var("chef_omnibus_root", root),
- shell_var("chef_omnibus_url", omnibus_url),
- shell_var("install_flags", flags.strip),
- shell_var("pretty_version", Util.pretty_version(version)),
- shell_var("sudo_sh", sudo("sh")),
- shell_var("version", version)
- ].join("\n")
- end
-
- # Generates the install command variables for PowerShell-based platforms.
+ # Returns the base installation directory for the given options
#
- # @param version [String] version string
- # @param metadata_url [String] The metadata URL for the Chef Omnitruck API server
- # @param omnibus_root [String] The base directory the project is installed to
- # @return [String] shell variable lines
- # @api private
- def install_command_vars_for_powershell
- [
- shell_var("chef_omnibus_root", root),
- shell_var("msi", "$env:TEMP\\chef-#{version}.msi"),
- ].tap { |vars|
- if install_msi_url
- vars << shell_var("chef_msi_url", install_msi_url)
- else
- vars << shell_var("chef_metadata_url", windows_metadata_url)
- vars << shell_var("pretty_version", Util.pretty_version(version))
- vars << shell_var("version", version)
- end
- }.join("\n")
- end
-
- def validate_opts!(opt)
- err_msg = ["#{opt} is not a valid option",
- "valid options are #{VALID_INSTALL_OPTS.join(' ')}"].join(',')
- fail ArgumentError, err_msg unless VALID_INSTALL_OPTS.include?(opt.to_s)
- end
-
- # rubocop:disable Metrics/MethodLength
- def parse_opts(opts)
- opts.each do |opt, setting|
- validate_opts!(opt)
- case opt.to_s
- when 'project', 'endpoint'
- self.endpoint = metadata_endpoint_from_project(setting)
- else
- send("#{opt.to_sym}=", setting)
- end
- end
- end
-
- def shell_code_from_file(vars)
- fn = File.join(
- File.dirname(__FILE__),
- %w[.. .. support],
- "install_command"
- )
- Util.shell_code_from_file(vars, fn, powershell,
- http_proxy: http_proxy, https_proxy: https_proxy)
- end
-
- # Builds a shell variable assignment string for the required shell type.
+ # @return [String] the installation directory for the project
#
- # @param name [String] variable name
- # @param value [String] variable value
- # @return [String] shell variable assignment
- # @api private
- def shell_var(name, value)
- Util.shell_var(name, value, powershell)
+ def root
+ # TODO: Support root as "$env:systemdrive\\opscode\\chef" when on windows.
+ # This only works for chef and chefdk but they are the only projects
+ # we are supporting as of now.
+ "/opt/#{options.product_name}"
end
- # @return the correct Chef Omnitruck API metadata endpoint, based on project
- def metadata_endpoint_from_project(project = nil)
- if project.nil? || project.downcase == "chef"
- "metadata"
- else
- "metadata-#{project.downcase}"
+ #
+ # Returns the current version of the installed product.
+ # Returns nil if the product is not installed.
+ #
+ def current_version
+ # Note that this logic does not work for products other than
+ # chef & chefdk since version-manifest is created under the
+ # install directory which can be different than the product name (e.g.
+ # chef-server -> /opt/opscode). But this is OK for now since
+ # chef & chefdk are the only supported products.
+ version_manifest_file = "/opt/#{options.product_name}/version-manifest.json"
+ if File.exist? version_manifest_file
+ JSON.parse(File.read(version_manifest_file))["build_version"]
end
end
- def windows_metadata_url
- base = if omnibus_url =~ %r{/install.sh$}
- "#{File.dirname(omnibus_url)}/"
- end
-
- url = "#{base}#{endpoint}"
- url << "?p=windows&m=x86_64&pv=2008r2" # same package for all versions
- url << "&v=#{CGI.escape(version.to_s.downcase)}"
- url << "&prerelease=true" if prerelease
- url << "&nightlies=true" if nightlies
- url
- end
-
- # Conditionally prefixes a command with a sudo command.
#
- # @param command [String] command to be prefixed
- # @return [String] the command, conditionaly prefixed with sudo
- # @api private
- def sudo(script)
- use_sudo ? "#{sudo_command} #{script}" : script
+ # Returns true if an upgradable version is available, false otherwise.
+ #
+ def upgrade_available?
+ return true if current_version.nil?
+
+ available_ver = Mixlib::Versioning.parse(artifact_info.first.version)
+ current_ver = Mixlib::Versioning.parse(current_version)
+ (available_ver > current_ver)
end
end
end