mirror of
https://github.com/fluent/fluentd-ui.git
synced 2025-08-07 14:57:18 +02:00
167 lines
3.7 KiB
Ruby
167 lines
3.7 KiB
Ruby
require "fileutils"
|
|
require "json"
|
|
require "httpclient"
|
|
|
|
class Plugin
|
|
class GemError < StandardError; end
|
|
|
|
WORKING = []
|
|
|
|
include ActiveModel::Model
|
|
include Draper::Decoratable
|
|
|
|
attr_accessor :gem_name, :version, :category, :api_version
|
|
validates :gem_name, presence: true
|
|
validates :version, presence: true
|
|
|
|
def to_param
|
|
gem_name
|
|
end
|
|
|
|
def install!
|
|
return if installed?
|
|
self.version ||= latest_version
|
|
valid? && gem_install
|
|
end
|
|
|
|
def uninstall!
|
|
return unless installed?
|
|
gem_uninstall # NOTE: not validate
|
|
end
|
|
|
|
def upgrade!(new_version)
|
|
return unless installed?
|
|
|
|
upgrade = self.class.new(gem_name: self.gem_name, version: new_version)
|
|
if self.valid? && upgrade.valid?
|
|
self.uninstall!
|
|
upgrade.install!
|
|
self.version = upgrade.version
|
|
end
|
|
end
|
|
|
|
def installed?
|
|
self.class.installed.any? do |plugin|
|
|
plugin.gem_name == gem_name
|
|
end
|
|
end
|
|
|
|
def processing?
|
|
WORKING.any?{|data| data[:plugin].gem_name == gem_name}
|
|
end
|
|
|
|
def installed_version
|
|
return unless installed?
|
|
version
|
|
end
|
|
|
|
def latest_version?
|
|
installed_version == latest_version
|
|
end
|
|
|
|
def latest_version
|
|
@latest_version ||= JSON.parse(gem_versions).map {|ver| Gem::Version.new ver["number"] }.max.to_s
|
|
end
|
|
|
|
def released_versions
|
|
@released_versions ||= JSON.parse(gem_versions).map {|ver| ver["number"]}.sort_by{|ver| Gem::Version.new ver}.reverse
|
|
end
|
|
|
|
def summary
|
|
property("summary")
|
|
end
|
|
|
|
def authors
|
|
property("authors")
|
|
end
|
|
|
|
def inspect
|
|
self.version ||= latest_version
|
|
%Q|<#{gem_name}, "#{version}">|
|
|
end
|
|
|
|
def rubygems_org_page
|
|
"https://rubygems.org/gems/#{gem_name}"
|
|
end
|
|
|
|
def self.installed
|
|
Bundler.with_clean_env do
|
|
gems = FluentGem.list
|
|
gems.grep(/fluent-plugin/).map do |gem|
|
|
name, versions_str = gem.strip.split(" ")
|
|
version = versions_str[/[^(), ]+/]
|
|
new(gem_name: name, version: version)
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.recommended
|
|
Settings.recommended_plugins.map do |data|
|
|
new(category: data["category"], gem_name: "fluent-plugin-#{data["name"]}", api_version: data["api_version"])
|
|
end
|
|
end
|
|
|
|
def self.processing
|
|
WORKING.find_all do |data|
|
|
data[:state] == :running
|
|
end
|
|
end
|
|
|
|
def self.installing
|
|
processing_state(:install)
|
|
end
|
|
|
|
def self.uninstalling
|
|
processing_state(:uninstall)
|
|
end
|
|
|
|
def gem_versions
|
|
Rails.cache.fetch(gem_json_url, expires_in: 60.minutes) do # NOTE: 60.minutes could be changed if it doesn't fit
|
|
gem_versions!
|
|
end
|
|
end
|
|
|
|
def gem_versions!
|
|
res = HTTPClient.get(gem_json_url)
|
|
if res.code == 200
|
|
json = res.body
|
|
Rails.cache.write(gem_json_url, json, expires_in: 60.minutes) # NOTE: 60.minutes could be changed if it doesn't fit
|
|
json
|
|
end
|
|
end
|
|
|
|
def gem_json_url
|
|
"https://rubygems.org/api/v1/versions/#{gem_name}.json"
|
|
end
|
|
|
|
private
|
|
def self.processing_state(state)
|
|
processing.find_all{|data| data[:type] == state }.map{ |data| data[:plugin] }
|
|
end
|
|
|
|
def property(prop)
|
|
target_version = self.version || latest_version
|
|
JSON.parse(gem_versions).find {|ver| ver["number"] == target_version }.try(:[], prop)
|
|
end
|
|
|
|
def gem_install
|
|
data = { plugin: self, state: :running, type: :install }
|
|
return if processing?
|
|
return if installed?
|
|
WORKING.push(data)
|
|
FluentGem.install(gem_name, "--no-ri", "--no-rdoc", "-v", version)
|
|
ensure
|
|
WORKING.delete(data)
|
|
end
|
|
|
|
def gem_uninstall
|
|
data = { plugin: self, state: :running, type: :uninstall }
|
|
return if processing?
|
|
return unless installed?
|
|
WORKING.push(data)
|
|
FluentGem.uninstall(gem_name, "-x", "-a")
|
|
ensure
|
|
WORKING.delete(data)
|
|
end
|
|
end
|