Skip to content

Commit 267dd43

Browse files
committed
Add platform specific checks
Signed-off-by: Kentaro Hayashi <hayashi@clear-code.com>
1 parent 46f5e48 commit 267dd43

5 files changed

+144
-5
lines changed

fluent-plugin-fluent-package-update-notifier.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ Gem::Specification.new do |spec|
2929
spec.add_development_dependency "bundler", "~> 2.4"
3030
spec.add_development_dependency "rake", "~> 13.2.1"
3131
spec.add_development_dependency "test-unit", "~> 3.6.7"
32+
spec.add_development_dependency "test-unit-rr", "~> 1.0.5"
3233
spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
3334
end

lib/fluent/plugin/fluent_package_update_checker.rb

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
require 'open-uri'
22
require 'json'
33
require 'tmpdir'
4+
require 'rbconfig'
45

56
module Fluent
67
module Plugin
78
module FluentPackage
89
class UpdateChecker
910
DEFAULT_PACKAGE_CONFIG_PATH = "/opt/fluent/share/config"
11+
1012
def initialize(options={})
1113
@logger = options[:logger]
1214
@options = options
@@ -20,6 +22,15 @@ def initialize(options={})
2022
rescue LoadError
2123
@logger.error "Failed to load #{ENV["FLUENT_PACKAGE_CONFIG"] || DEFAULT_PACKAGE_CONFIG_PATH}"
2224
end
25+
@host_os = RbConfig::CONFIG['host_os']
26+
end
27+
28+
def windows?
29+
!!(@host_os =~ /mswin|mingw/)
30+
end
31+
32+
def linux?
33+
!!(@host_os =~ /linux/)
2334
end
2435

2536
def tags_cached?
@@ -65,6 +76,89 @@ def major_lts_update?(base_version, target_version)
6576
[base_version.segments[1], target_version.segments[1]] == [0, 0]
6677
end
6778

79+
def parse_os_release(key)
80+
File.open("/etc/os-release").readlines.each do |line|
81+
if line.start_with?(key)
82+
line.chomp =~ /^#{key}=(.+)$/
83+
return $1
84+
end
85+
end
86+
nil
87+
end
88+
89+
def package_url(prefix, distribution, version)
90+
major = version.segments.first
91+
channel = @options[:lts] ? "lts/#{major}" : major
92+
case distribution
93+
when "debian", "ubuntu"
94+
release = parse_os_release("VERSION_CODENAME")
95+
"#{prefix}/#{channel}/#{distribution}/#{release}/pool/contrib/f/fluent-package/fluent-package_#{version}-1_amd64.deb"
96+
when "redhat/8"
97+
"#{prefix}/#{channel}/#{distribution}/x86_64/fluent-package_#{version}-1.el8.x86_64.rpm"
98+
when "redhat/9"
99+
"#{prefix}/#{channel}/#{distribution}/x86_64/fluent-package_#{version}-1.el9.x86_64.rpm"
100+
when "amazon/2023"
101+
"#{prefix}/#{channel}/#{distribution}/x86_64/fluent-package_#{version}-1.amzn2023.x86_64.rpm"
102+
when "amazon/2"
103+
"#{prefix}/#{channel}/#{distribution}/x86_64/fluent-package_#{version}-1.amzn2.x86_64.rpm"
104+
when "windows"
105+
"#{prefix}/#{channel}/#{distribution}/fluent-package-#{version}-x64.msi"
106+
end
107+
end
108+
109+
def generate_remote_package_url(url_prefix, target_version)
110+
if linux?
111+
os_release_id = parse_os_release("ID")
112+
case os_release_id
113+
when "debian"
114+
url = package_url(url_prefix, "debian", target_version)
115+
@logger.debug("Check existence of #{url}")
116+
url
117+
when "ubuntu"
118+
package_url(url_prefix, "ubuntu", target_version)
119+
when "rocky", "almalinux", "amzn"
120+
cpe = parse_os_release("CPE_NAME")
121+
case cpe
122+
when /rocky:8/, /almalinux:8/
123+
package_url(url_prefix, "redhat/8", target_version)
124+
when /rocky:9/, /almalinux:9/
125+
package_url(url_prefix, "redhat/9", target_version)
126+
when /amazon_linux:2023/, /amazon_linux:2/
127+
version = parse_os_release("VERSION")
128+
case version
129+
when "2023"
130+
package_url(url_prefix, "amazon/2023", target_version)
131+
when "2"
132+
package_url(url_prefix, "amazon/2", target_version)
133+
end
134+
end
135+
end
136+
elsif windows?
137+
package_url(url_prefix, "windows", target_version)
138+
end
139+
end
140+
141+
def check_remote_packages(target_version)
142+
@options[:repository_sites].each do |url_prefix|
143+
yield generate_remote_package_url(url_prefix, target_version)
144+
end
145+
end
146+
147+
def check_package_released?(target_version)
148+
major = target_version.segments.first
149+
check_remote_packages(target_version) do |url|
150+
begin
151+
URI.open(url)
152+
return true
153+
rescue => e
154+
# package is not available
155+
@logger.debug("#{url} is inaccessible", error: e)
156+
end
157+
end
158+
# assume package is not available by default
159+
false
160+
end
161+
68162
def check_update_versions
69163
current_version = Gem::Version.new("#{PACKAGE_VERSION}")
70164
fetch_tags do |releases|
@@ -75,16 +169,16 @@ def check_update_versions
75169
if target_version > current_version
76170
major = current_version.segments.first
77171
if same_lts_series?(current_version, target_version)
78-
@newer_lts_versions << version
172+
@newer_lts_versions << version if check_package_released?(target_version)
79173
elsif version.start_with?("v#{major}")
80-
@newer_versions << version
174+
@newer_versions << version if check_package_released?(target_version)
81175
else
82176
# major upgrade standard/LTS version
83177
if major_lts_update?(current_version, target_version)
84178
# LTS
85-
@major_lts_updates << version
179+
@major_lts_updates << version if check_package_released?(target_version)
86180
else
87-
@major_updates << version
181+
@major_updates << version if check_package_released?(target_version)
88182
end
89183
end
90184
end

lib/fluent/plugin/in_fluent_package_update_notifier.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class FluentPackageUpdateNotifierInput < Fluent::Plugin::Input
3737
desc "Notify checking update intervals"
3838
config_param :notify_interval, :integer, default: 60 * 60 * 24
3939

40+
desc "Package repository site"
41+
config_param :repository_sites, :array, default: ["https://packages.treasuredata.com"]
42+
4043
def configure(conf)
4144
super
4245
end
@@ -63,7 +66,8 @@ def check_fluent_pacakge_update_information
6366
lts: @lts,
6467
notify_major_upgrade: @notify_major_upgrade,
6568
notify_level: @notify_level,
66-
logger: log
69+
logger: log,
70+
repository_sites: @repository_sites
6771
}
6872
checker = Fluent::Plugin::FluentPackage::UpdateChecker.new(options)
6973
checker.run

test/helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require "test-unit"
2+
require "test/unit/rr"
23
require "fluent/test"
34
require "fluent/test/driver/input"
45
require "fluent/test/helpers"

test/plugin/test_in_fluent_package_update_notifier.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def cache_tags_path(path, versions)
7878
setup do
7979
ENV["FLUENT_PACKAGE_CONFIG"] = "#{@tmp_dir}/config.rb"
8080
ENV["FLUENT_PACKAGE_TAGS_PATH"] = "#{@tmp_dir}/tags.json"
81+
stub.instance_of(Fluent::Plugin::FluentPackage::UpdateChecker).check_package_released?(anything) { true }
8182
end
8283

8384
test "no LTS update" do
@@ -138,6 +139,7 @@ def cache_tags_path(path, versions)
138139
setup do
139140
ENV["FLUENT_PACKAGE_CONFIG"] = "#{@tmp_dir}/config.rb"
140141
ENV["FLUENT_PACKAGE_TAGS_PATH"] = "#{@tmp_dir}/tags.json"
142+
stub.instance_of(Fluent::Plugin::FluentPackage::UpdateChecker).check_package_released?(anything) { true }
141143
end
142144

143145
test "no update" do
@@ -201,6 +203,43 @@ def cache_tags_path(path, versions)
201203
end
202204
end
203205

206+
sub_test_case "each platforms" do
207+
setup do
208+
ENV["FLUENT_PACKAGE_CONFIG"] = "#{@tmp_dir}/config.rb"
209+
ENV["FLUENT_PACKAGE_TAGS_PATH"] = "#{@tmp_dir}/tags.json"
210+
end
211+
212+
data("trixie" => [%W(ID=debian\n VERSION_CODENAME=trixie\n)],
213+
"ubuntu" => [%W(ID=plucky]\n VERSION_CODENAME=plucky\n)],
214+
"rockylinux/8" => [%W(ID="rocky"\n CPE_NAME="cpe:/o:rocky:rocky:8:GA"\n)],
215+
"rockylinux/9" => [%W(ID="rocky"\n CPE_NAME="cpe:/o:rocky:rocky:9:GA"\n)],
216+
"almalinux/8" => [%W(ID="almalinux"\n CPE_NAME="cpe:/o:almalinux:almalinux:8::baseos"\n)],
217+
"almalinux/9" => [%W(ID="almalinux"\n CPE_NAME="cpe:/o:almalinux:almalinux:8::baseos"\n)],
218+
"amazonlinux/2" => [%W(ID="amzn"\n CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"\n)],
219+
"amazonlinux/2023" => [%W(ID="amzn"\n CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2023"\n)])
220+
test "released, but not shipped yet for linux" do
221+
assert_nothing_raised do |os_release|
222+
stub(File).readlines { os_release }
223+
write_config_version("5.0.6")
224+
cache_tags_path(ENV["FLUENT_PACKAGE_TAGS_PATH"], ["5.0.404"])
225+
d = create_driver
226+
d.run
227+
assert_match(/\[info\]: No update for fluent-package 5.0.6/, d.logs.last)
228+
end
229+
end
230+
231+
test "released, but not shipped yet for windows" do
232+
assert_nothing_raised do |os_release|
233+
stub(RbConfig::CONFIG) { {'host_os' => "mingw32"} }
234+
write_config_version("5.0.6")
235+
cache_tags_path(ENV["FLUENT_PACKAGE_TAGS_PATH"], ["5.0.404"])
236+
d = create_driver
237+
d.run
238+
assert_match(/\[info\]: No update for fluent-package 5.0.6/, d.logs.last)
239+
end
240+
end
241+
end
242+
204243
private
205244

206245
def create_driver(conf=config)

0 commit comments

Comments
 (0)