From 6bc3b53dd1ae1edb9f2ab118d0a4e254bc150a09 Mon Sep 17 00:00:00 2001 From: Tomasz Setkowski Date: Sat, 27 Feb 2016 23:15:22 +0000 Subject: [PATCH] #63 #67 improve version handling and installing on windows --- attributes/repository.rb | 51 +++-------- libraries/helpers.rb | 147 ++++++++++++++++++++++++++++++ recipes/agent_linux_install.rb | 15 +-- recipes/agent_windows_install.rb | 22 ++--- recipes/server_linux_install.rb | 13 +-- recipes/server_windows_install.rb | 21 ++--- spec/go_agent_spec.rb | 8 +- spec/go_agent_windows_spec.rb | 21 +++-- spec/go_server_spec.rb | 8 +- spec/go_server_windows_spec.rb | 20 ++-- 10 files changed, 222 insertions(+), 104 deletions(-) diff --git a/attributes/repository.rb b/attributes/repository.rb index b7e99f9..f97837a 100644 --- a/attributes/repository.rb +++ b/attributes/repository.rb @@ -1,50 +1,21 @@ -default['gocd']['install_method'] = 'repository' -default['gocd']['download']['baseurl'] = 'https://download.go.cd' +if node['platform_family'] == 'windows' + default['gocd']['install_method'] = 'package_file' +else + default['gocd']['install_method'] = 'repository' +end +default['gocd']['updates']['baseurl'] = 'https://update.go.cd/channels' -default['gocd']['repository']['apt']['uri'] = node['gocd']['download']['baseurl'] +default['gocd']['repository']['apt']['uri'] = 'https://download.go.cd' default['gocd']['repository']['apt']['components'] = [ '/' ] default['gocd']['repository']['apt']['distribution'] = '' default['gocd']['repository']['apt']['package_options'] = '' default['gocd']['repository']['apt']['keyserver'] = 'pgp.mit.edu' default['gocd']['repository']['apt']['key'] = '0xd8843f288816c449' -default['gocd']['repository']['yum']['baseurl'] = node['gocd']['download']['baseurl'] +default['gocd']['repository']['yum']['baseurl'] = 'https://download.go.cd' default['gocd']['repository']['yum']['gpgcheck'] = true default['gocd']['repository']['yum']['gpgkey'] = 'https://download.go.cd/GOCD-GPG-KEY.asc' -case node['gocd']['install_method'] -when 'repository' -# version = nil so just pick latest available -else - default['gocd']['version'] = '16.2.1-3027' -end - -version = node['gocd']['version'] -os_dir = nil - -case node['platform_family'] -when 'debian' - default['gocd']['server']['package_file']['filename'] = "go-server-#{version}.deb" - default['gocd']['agent']['package_file']['filename'] = "go-agent-#{version}.deb" - default['gocd']['package_file']['baseurl'] = node['gocd']['download']['baseurl'] - os_dir = 'deb' -when 'rhel', 'fedora' - default['gocd']['server']['package_file']['filename'] = "go-server-#{version}.noarch.rpm" - default['gocd']['agent']['package_file']['filename'] = "go-agent-#{version}.noarch.rpm" - default['gocd']['package_file']['baseurl'] = node['gocd']['download']['baseurl'] - os_dir = 'rpm' -when 'windows' - default['gocd']['server']['package_file']['filename'] = "go-server-#{version}-setup.exe" - default['gocd']['agent']['package_file']['filename'] = "go-agent-#{version}-setup.exe" - default['gocd']['package_file']['baseurl'] = node['gocd']['download']['baseurl'] - os_dir = 'win' -end - -default['gocd']['server']['package_file']['path'] = - File.join(Chef::Config[:file_cache_path], node['gocd']['server']['package_file']['filename']) -default['gocd']['server']['package_file']['url'] = - "#{node['gocd']['package_file']['baseurl']}/binaries/#{version}/#{os_dir}/#{node['gocd']['server']['package_file']['filename']}" -default['gocd']['agent']['package_file']['path'] = - File.join(Chef::Config[:file_cache_path], node['gocd']['agent']['package_file']['filename']) -default['gocd']['agent']['package_file']['url'] = - "#{node['gocd']['package_file']['baseurl']}/binaries/#{version}/#{os_dir}/#{node['gocd']['agent']['package_file']['filename']}" +default['gocd']['package_file']['baseurl'] = nil # official - "https://download.go.cd/binaries" +default['gocd']['agent']['package_file']['url'] = nil # official +default['gocd']['server']['package_file']['url'] = nil # official diff --git a/libraries/helpers.rb b/libraries/helpers.rb index 1658556..ef3fda7 100644 --- a/libraries/helpers.rb +++ b/libraries/helpers.rb @@ -41,6 +41,153 @@ def go_server_config_file '/etc/go/cruise-config.xml' end end + + def go_version + if node['gocd']['version'] + # user explictly requested Go version + node['gocd']['version'] + elsif node['platform_family'] == 'windows' + # we are on windows, so there is no repository to tell what is 'latest' + # but we can ask go updates service + fetch_go_version 'stable' + else + 'stable' + end + end + # version to pass into 'package' resource + def go_version_repo + # just return attribute value, when nil it will default to installing stable + node['gocd']['version'] + end + + # Only needed when downloading package from URL + def remote_version + version = go_version + if version == 'stable' || version == 'supported' || version == 'experimental' + fetch_go_version version + elsif version.nil? + fetch_go_version 'stable' + else + version + end + end + + def updates_base_feed + node['gocd']['updates']['baseurl'] + end + + def fetch_go_version name + require 'net/http' + require 'uri' + case name + when 'stable', :stable, 'supported', :supported + # https://update.go.cd/channels/supported/latest.json + url = "#{updates_base_feed}/supported/latest.json" + when 'experimental', :experimental + # https://update.go.cd/channels/experimental/latest.json + url = "#{updates_base_feed}/experimental/latest.json" + else + fail "Invalid version name '#{name}' - must be stable (supported) or experimental" + end + begin + json = Net::HTTP.get(URI.parse(url)) + parsed = JSON.parse(json) + fail 'Invalid format in version json file' unless parsed['message'] + message = JSON.parse(parsed['message']) + return message['latest-version'] + rescue Exception => e + Chef::Log.error("Failed to get Go version from updates service - #{e}") + # fallback to last known stable + '16.2.1-3027' + end + end + + def package_extension + case node['platform_family'] + when 'debian' + ".deb" + when 'rhel', 'fedora' + ".noarch.rpm" + when 'windows' + "-setup.exe" + else + ".zip" + end + end + + def os_dir + case node['platform_family'] + when 'debian' + 'deb' + when 'rhel', 'fedora' + 'rpm' + when 'windows' + 'win' + else + "generic" + end + end + + def go_agent_remote_package_name + "go-agent-#{remote_version}#{package_extension}" + end + def go_server_remote_package_name + "go-server-#{remote_version}#{package_extension}" + end + + def user_friendly_agent_version + if node['gocd']['version'] + return node['gocd']['version'] + elsif node['gocd']['agent']['package_file']['url'] + return 'custom' + else + return 'stable' + end + end + def user_friendly_server_version + if node['gocd']['version'] + return node['gocd']['version'] + elsif node['gocd']['server']['package_file']['url'] + return 'custom' + else + return 'stable' + end + end + + # user-friendly file names to use when downloading remote file + def go_agent_package_name + "go-agent-#{user_friendly_agent_version}#{package_extension}" + end + def go_server_package_name + "go-server-#{user_friendly_server_version}#{package_extension}" + end + + def go_baseurl + if node['gocd']['package_file']['baseurl'] + # user specifed url to download packages from + node['gocd']['package_file']['baseurl'] + else + # use official source + "https://download.go.cd/binaries" + end + end + + def go_agent_package_url + if node['gocd']['agent']['package_file']['url'] + # user specifed explictly the URL to download from + node['gocd']['agent']['package_file']['url'] + else + "#{go_baseurl}/#{remote_version}/#{os_dir}/#{go_agent_remote_package_name}" + end + end + def go_server_package_url + if node['gocd']['server']['package_file']['url'] + # user specifed explictly the URL to download from + node['gocd']['server']['package_file']['url'] + else + "#{go_baseurl}/#{remote_version}/#{os_dir}/#{go_server_remote_package_name}" + end + end end end diff --git a/recipes/agent_linux_install.rb b/recipes/agent_linux_install.rb index ebbb2c3..af05380 100644 --- a/recipes/agent_linux_install.rb +++ b/recipes/agent_linux_install.rb @@ -11,23 +11,24 @@ package_options = node['gocd']['repository']['apt']['package_options'] if node['platform_family'] == 'debian' package "go-agent" do notifies :reload, 'ohai[reload_passwd_for_go_user]', :immediately - version node['gocd']['version'] + version go_version_repo end when 'package_file' - remote_file node['gocd']['agent']['package_file']['filename'] do - path node['gocd']['agent']['package_file']['path'] - source node['gocd']['agent']['package_file']['url'] - mode 0644 + package_path = File.join(Chef::Config[:file_cache_path],go_agent_package_name) + remote_file go_agent_package_name do + path package_path + source go_agent_package_url + mode 00644 end case node['platform_family'] when 'debian' dpkg_package 'go-agent' do - source node['gocd']['agent']['package_file']['path'] + source package_path notifies :reload, 'ohai[reload_passwd_for_go_user]', :immediately end when 'rhel','fedora' rpm_package 'go-agent' do - source node['gocd']['agent']['package_file']['path'] + source package_path notifies :reload, 'ohai[reload_passwd_for_go_user]', :immediately end end diff --git a/recipes/agent_windows_install.rb b/recipes/agent_windows_install.rb index 3a689c7..683c8e7 100644 --- a/recipes/agent_windows_install.rb +++ b/recipes/agent_windows_install.rb @@ -1,6 +1,8 @@ -remote_file node['gocd']['agent']['package_file']['filename'] do - path node['gocd']['agent']['package_file']['path'] - source node['gocd']['agent']['package_file']['url'] +package_path = File.join(Chef::Config[:file_cache_path],go_agent_package_name) + +remote_file go_agent_package_name do + path package_path + source go_agent_package_url end autoregister_values = get_agent_properties @@ -12,16 +14,10 @@ opts = [] opts << "/SERVERIP=#{autoregister_values[:go_server_host]}" +opts << "/S" opts << '/D=C:\GoAgent' -if defined?(Chef::Provider::Package::Windows) - package 'Go Agent' do - source node['gocd']['agent']['package_file']['path'] - options opts.join(" ") - end -else - windows_package 'Go Agent' do - source node['gocd']['agent']['package_file']['path'] - options opts.join(" ") - end +execute "install Go Agent" do + command "#{package_path} #{opts.join(' ')}" + creates "C:\\GoAgent\\agent.cmd" end diff --git a/recipes/server_linux_install.rb b/recipes/server_linux_install.rb index e1c2281..aba1308 100644 --- a/recipes/server_linux_install.rb +++ b/recipes/server_linux_install.rb @@ -13,25 +13,26 @@ include_recipe 'gocd::repository' package_options = node['gocd']['repository']['apt']['package_options'] if node['platform_family'] == 'debian' package "go-server" do - version node['gocd']['version'] + version go_version_repo options package_options notifies :reload, 'ohai[reload_passwd_for_go_user]', :immediately end when 'package_file' - remote_file node['gocd']['server']['package_file']['filename'] do - path node['gocd']['server']['package_file']['path'] - source node['gocd']['server']['package_file']['url'] + package_path = File.join(Chef::Config[:file_cache_path],go_server_package_name) + remote_file go_server_package_name do + path package_path + source go_server_package_url mode 0644 end case node['platform_family'] when 'debian' dpkg_package 'go-server' do - source node['gocd']['server']['package_file']['path'] + source package_path notifies :reload, 'ohai[reload_passwd_for_go_user]', :immediately end when 'rhel','fedora' rpm_package 'go-server' do - source node['gocd']['server']['package_file']['path'] + source package_path notifies :reload, 'ohai[reload_passwd_for_go_user]', :immediately end end diff --git a/recipes/server_windows_install.rb b/recipes/server_windows_install.rb index 4fc7d67..eedb0a3 100644 --- a/recipes/server_windows_install.rb +++ b/recipes/server_windows_install.rb @@ -1,20 +1,15 @@ -remote_file node['gocd']['server']['package_file']['filename'] do - path node['gocd']['server']['package_file']['path'] - source node['gocd']['server']['package_file']['url'] +package_path = File.join(Chef::Config[:file_cache_path],go_server_package_name) + +remote_file go_server_package_name do + path package_path + source go_server_package_url end opts = [] opts << '/S' opts << '/D=C:\GoServer' -if defined?(Chef::Provider::Package::Windows) - package 'Go Server' do - source node['gocd']['server']['package_file']['path'] - options opts.join(" ") - end -else - windows_package 'Go Server' do - source node['gocd']['server']['package_file']['path'] - options opts.join(" ") - end +execute "install Go Server" do + command "#{package_path} #{opts.join(' ')}" + creates "C:\\GoServer" end diff --git a/spec/go_agent_spec.rb b/spec/go_agent_spec.rb index bf6accd..4c1da33 100644 --- a/spec/go_agent_spec.rb +++ b/spec/go_agent_spec.rb @@ -164,8 +164,8 @@ end it_behaves_like :agent_recipe_linux it 'downloads go-agent .deb from remote URL' do - expect(chef_run).to create_remote_file('go-agent-16.1.0-2855.deb').with( - source: 'https://download.go.cd/binaries/16.1.0-2855/deb/go-agent-16.1.0-2855.deb') + expect(chef_run).to create_remote_file('go-agent-stable.deb').with( + source: 'https://download.go.cd/binaries/16.2.1-3027/deb/go-agent-16.2.1-3027.deb') end it 'installs go-agent package from file' do expect(chef_run).to install_dpkg_package('go-agent') @@ -187,8 +187,8 @@ end it_behaves_like :agent_recipe_linux it 'downloads go-agent .rpm from remote URL' do - expect(chef_run).to create_remote_file('go-agent-16.1.0-2855.noarch.rpm').with( - source: 'https://download.go.cd/binaries/16.1.0-2855/rpm/go-agent-16.1.0-2855.noarch.rpm') + expect(chef_run).to create_remote_file('go-agent-stable.noarch.rpm').with( + source: 'https://download.go.cd/binaries/16.2.1-3027/rpm/go-agent-16.2.1-3027.noarch.rpm') end it 'installs go-agent package from file' do expect(chef_run).to install_rpm_package('go-agent') diff --git a/spec/go_agent_windows_spec.rb b/spec/go_agent_windows_spec.rb index 4eadedf..b19fa56 100644 --- a/spec/go_agent_windows_spec.rb +++ b/spec/go_agent_windows_spec.rb @@ -19,10 +19,12 @@ run.converge(described_recipe) end - it 'installs go-agent package' do - expect(chef_run).to install_package('Go Agent').with( - :source => 'https://download.go.cd/binaries/16.1.0-2855/win/go-agent-16.1.0-2855-setup.exe' - ) + it 'downloads official installer' do + expect(chef_run).to create_remote_file('go-agent-stable-setup.exe').with( + :source => 'https://download.go.cd/binaries/16.2.1-3027/win/go-agent-16.2.1-3027-setup.exe') + end + it 'installs package via execute' do + expect(chef_run).to run_execute('install Go Agent') end end @@ -37,11 +39,12 @@ end run.converge(described_recipe) end - - it 'installs go-agent package' do - expect(chef_run).to install_package('Go Agent').with( - :source => 'https://example.com/go-agent.exe' - ) + it 'downloads specified installer' do + expect(chef_run).to create_remote_file('go-agent-custom-setup.exe').with( + :source => 'https://example.com/go-agent.exe') + end + it 'installs package via execute' do + expect(chef_run).to run_execute('install Go Agent') end end end diff --git a/spec/go_server_spec.rb b/spec/go_server_spec.rb index 397f828..160ed3d 100644 --- a/spec/go_server_spec.rb +++ b/spec/go_server_spec.rb @@ -62,8 +62,8 @@ end it_behaves_like :server_recipe it 'downloads go-server .deb from remote URL' do - expect(chef_run).to create_remote_file('go-server-16.1.0-2855.deb').with( - source: 'https://download.go.cd/binaries/16.1.0-2855/deb/go-server-16.1.0-2855.deb') + expect(chef_run).to create_remote_file('go-server-stable.deb').with( + source: 'https://download.go.cd/binaries/16.2.1-3027/deb/go-server-16.2.1-3027.deb') end it 'installs go-server package from file' do expect(chef_run).to install_dpkg_package('go-server') @@ -81,8 +81,8 @@ end it_behaves_like :server_recipe it 'downloads go-server .rpm from remote URL' do - expect(chef_run).to create_remote_file('go-server-16.1.0-2855.noarch.rpm').with( - source: 'https://download.go.cd/binaries/16.1.0-2855/rpm/go-server-16.1.0-2855.noarch.rpm') + expect(chef_run).to create_remote_file('go-server-stable.noarch.rpm').with( + source: 'https://download.go.cd/binaries/16.2.1-3027/rpm/go-server-16.2.1-3027.noarch.rpm') end it 'installs go-server package from file' do expect(chef_run).to install_rpm_package('go-server') diff --git a/spec/go_server_windows_spec.rb b/spec/go_server_windows_spec.rb index 531a3c6..55d2041 100644 --- a/spec/go_server_windows_spec.rb +++ b/spec/go_server_windows_spec.rb @@ -19,10 +19,12 @@ run.converge(described_recipe) end - it 'installs go-server package' do - expect(chef_run).to install_package('Go Server').with( - :source => 'https://download.go.cd/binaries/16.1.0-2855/win/go-server-16.1.0-2855-setup.exe' - ) + it 'downloads official installer' do + expect(chef_run).to create_remote_file('go-server-stable-setup.exe').with( + :source => 'https://download.go.cd/binaries/16.2.1-3027/win/go-server-16.2.1-3027-setup.exe') + end + it 'installs package via execute' do + expect(chef_run).to run_execute('install Go Server') end end @@ -38,10 +40,12 @@ run.converge(described_recipe) end - it 'installs go-server package' do - expect(chef_run).to install_package('Go Server').with( - :source => 'https://example.com/go-server.exe' - ) + it 'downloads specified installer' do + expect(chef_run).to create_remote_file('go-server-custom-setup.exe').with( + :source => 'https://example.com/go-server.exe') + end + it 'installs package via execute' do + expect(chef_run).to run_execute('install Go Server') end end end