ok
This commit is contained in:
parent
7376a8521e
commit
0c74272f88
152
linux-update.rb
152
linux-update.rb
|
@ -46,10 +46,32 @@ EOF
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RequiredGems.require do |rg, &push|
|
def requires_lib_gem &block
|
||||||
|
requires = []
|
||||||
|
push = lambda {|lib, gem = lib, name = gem| requires.push [lib, gem, name] }
|
||||||
|
block.call &push
|
||||||
|
failed = requires.reject do |(lib, _, _)|
|
||||||
|
begin
|
||||||
|
require lib
|
||||||
|
true
|
||||||
|
rescue LoadError
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return if failed.empty?
|
||||||
|
STDERR.puts <<EOF
|
||||||
|
Loading of #{failed.map{|(_,_,n)|n}.join ', '} failed.
|
||||||
|
Please install if first:
|
||||||
|
sudo gem install #{failed.map{|(_,g,_)|g}.join ' '}
|
||||||
|
EOF
|
||||||
|
exit 127
|
||||||
|
end
|
||||||
|
|
||||||
|
requires_lib_gem do |&push|
|
||||||
push[ 'thor', nil, 'Thor']
|
push[ 'thor', nil, 'Thor']
|
||||||
push[ 'irb-pager', nil, 'IRB::Pager']
|
push[ 'irb-pager', nil, 'IRB::Pager']
|
||||||
push[ 'httpclient', nil, 'HTTPClient']
|
push[ 'active_support/all', 'activesupport', 'ActiveSupport']
|
||||||
|
push[ 'excon', nil, 'Excon']
|
||||||
push[ 'versionomy', nil, 'Versionomy']
|
push[ 'versionomy', nil, 'Versionomy']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -60,10 +82,10 @@ module LinuxUpdate
|
||||||
include Comparable
|
include Comparable
|
||||||
def self.parse json
|
def self.parse json
|
||||||
return nil if json['version'] =~ /^next-/
|
return nil if json['version'] =~ /^next-/
|
||||||
data = members.map {|m| json[m.to_s] }
|
data = members.map {|m| json[m.to_s] }
|
||||||
data[0] = Versionomy.parse data[0]
|
data[0] = Versionomy.parse data[0]
|
||||||
data[2] = URI.parse data[2]
|
data[2] = URI.parse data[2] rescue
|
||||||
data[3] = URI.parse data[3]
|
data[3] = URI.parse data[3] rescue
|
||||||
data[4] = Time.at data[4]['timestamp'].to_i
|
data[4] = Time.at data[4]['timestamp'].to_i
|
||||||
new *data
|
new *data
|
||||||
end
|
end
|
||||||
|
@ -146,6 +168,7 @@ module LinuxUpdate
|
||||||
def import_config_from_io( io) open_config('w') {|c| io.each_line {|l| c.print l } } end
|
def import_config_from_io( io) open_config('w') {|c| io.each_line {|l| c.print l } } end
|
||||||
|
|
||||||
def import_config file_or_io_or_fetched
|
def import_config file_or_io_or_fetched
|
||||||
|
info "Import config #{file_or_io_or_fetched}"
|
||||||
case file_or_io_or_fetched
|
case file_or_io_or_fetched
|
||||||
when IO then import_config_from_io file_or_io_or_fetched
|
when IO then import_config_from_io file_or_io_or_fetched
|
||||||
when Fetched
|
when Fetched
|
||||||
|
@ -156,20 +179,28 @@ module LinuxUpdate
|
||||||
end
|
end
|
||||||
|
|
||||||
def oldconfig
|
def oldconfig
|
||||||
|
info 'make oldconfig'
|
||||||
make 'oldconfig'
|
make 'oldconfig'
|
||||||
end
|
end
|
||||||
|
|
||||||
def menuconfig
|
def menuconfig
|
||||||
|
info 'make menuconfig'
|
||||||
make 'menuconfig'
|
make 'menuconfig'
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile
|
def compile
|
||||||
|
info 'make all'
|
||||||
make 'all'
|
make 'all'
|
||||||
end
|
end
|
||||||
|
|
||||||
def install
|
def install
|
||||||
|
info 'make modules_install install'
|
||||||
make 'modules_install', 'install'
|
make 'modules_install', 'install'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def info text
|
||||||
|
STDERR.puts "[#{version}] #{text}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Base
|
class Base
|
||||||
|
@ -180,27 +211,38 @@ module LinuxUpdate
|
||||||
class MakeFailed <Error
|
class MakeFailed <Error
|
||||||
end
|
end
|
||||||
class DownloadFailed <Error
|
class DownloadFailed <Error
|
||||||
|
def initialize uri
|
||||||
|
super "Download of #{uri} failed."
|
||||||
|
end
|
||||||
end
|
end
|
||||||
attr_reader :releases_uri, :sources_base_dir
|
class UnpackFailed <Error
|
||||||
|
def initialize tarball
|
||||||
|
super "Unpack of #{tarball} failed."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
attr_reader :releases_uri, :sources_base_dir, :cache_dir
|
||||||
ReleasesURI = 'https://www.kernel.org/releases.json'
|
ReleasesURI = 'https://www.kernel.org/releases.json'
|
||||||
SourcesBaseDir = '/usr/src'
|
SourcesBaseDir = '/usr/src'
|
||||||
|
CacheDir = '/var/cache/linux-update'
|
||||||
|
|
||||||
def releases_uri= uri
|
def releases_uri=( uri) @releases_uri = URI.parse uri.to_s end
|
||||||
@releases_uri = URI.parse uri.to_s
|
def sources_base_dir=( dir) @sources_base_dir = Pathname.new dir.to_s end
|
||||||
end
|
def cache_dir=( dir) @cache_dir = Pathname.new dir.to_s end
|
||||||
|
|
||||||
def sources_base_dir= dir
|
|
||||||
@sources_base_dir = Pathname.new dir.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
self.releases_uri = ENV['LINUX_RELEASE_URI'] || ReleasesURI
|
self.releases_uri = ENV['LINUX_RELEASE_URI'] || ReleasesURI
|
||||||
self.sources_base_dir = ENV['LINUX_SOURCES_BASE_DIR'] || SourcesBaseDir
|
self.sources_base_dir = ENV['LINUX_SOURCES_BASE_DIR'] || SourcesBaseDir
|
||||||
|
self.cache_dir = ENV['CacheDir'] || CacheDir
|
||||||
|
end
|
||||||
|
|
||||||
|
def info text
|
||||||
|
STDERR.puts text
|
||||||
end
|
end
|
||||||
|
|
||||||
def releases
|
def releases
|
||||||
return @releases if @releases
|
return @releases if @releases
|
||||||
json = JSON.parse HTTPClient.get_content( @releases_uri)
|
res = Excon.get @releases_uri.to_s, expects: 200
|
||||||
|
json = JSON.parse res.body
|
||||||
@releases = json['releases'].map {|r| Release.parse r }.compact
|
@releases = json['releases'].map {|r| Release.parse r }.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -211,7 +253,7 @@ module LinuxUpdate
|
||||||
def fetched
|
def fetched
|
||||||
@fetched ||= Dir[ @sources_base_dir + 'linux-*'].
|
@fetched ||= Dir[ @sources_base_dir + 'linux-*'].
|
||||||
map( &Pathname.method( :new)).
|
map( &Pathname.method( :new)).
|
||||||
select!( &:directory?).
|
select( &:directory?).
|
||||||
map {|d| Fetched.new d }
|
map {|d| Fetched.new d }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -221,9 +263,9 @@ module LinuxUpdate
|
||||||
def find_fetched_version version
|
def find_fetched_version version
|
||||||
case version
|
case version
|
||||||
when Fetched then version
|
when Fetched then version
|
||||||
when Versionomy then fetched.find {|f| version == f.version }
|
when Versionomy::Value then fetched.find {|f| version == f.version }
|
||||||
when Release then __callee__ version.version
|
when Release then find_fetched_version version.version
|
||||||
when String then __callee__ Versionomy.parse( version)
|
when String then find_fetched_version Versionomy.parse( version)
|
||||||
when nil, false then fetched.max
|
when nil, false then fetched.max
|
||||||
else raise InvalidVersionType, "I know Fetched, Versionomy, Release and String, but what is #{version.class}?"
|
else raise InvalidVersionType, "I know Fetched, Versionomy, Release and String, but what is #{version.class}?"
|
||||||
end
|
end
|
||||||
|
@ -233,32 +275,66 @@ module LinuxUpdate
|
||||||
Pathname.new( file.to_s).exist?
|
Pathname.new( file.to_s).exist?
|
||||||
end
|
end
|
||||||
|
|
||||||
def download release_or_uri
|
def format_bytes bytes
|
||||||
uri = case release_or_uri
|
case bytes
|
||||||
when Release then release_or_uri.source.to_s
|
when 0...1.kilobyte then "%6dB" % bytes
|
||||||
when URI, String then release_or_uri.to_s
|
when 0...1.megabyte then "%4dKiB" % (bytes / 1.kilobyte)
|
||||||
else raise UnexpectedThingToDownload, "This is no URI, String or Release"
|
when 0...1.gigabyte then "%4dMiB" % (bytes / 1.megabyte)
|
||||||
end
|
when 0...1.terabyte then "%4dGiB" % (bytes / 1.gigabyte)
|
||||||
dir = @sources_base_dir
|
when 0...1.petabyte then "%4dTiB" % (bytes / 1.terabyte)
|
||||||
HTTPClient.new do |hc|
|
else "%4dEiB" % (bytes / 1.petabyte)
|
||||||
hc.get uri do |chunk|
|
end
|
||||||
p chunk.length
|
end
|
||||||
next
|
|
||||||
tar_pid = fork do
|
def _download uri, file
|
||||||
Dir.chdir dir
|
dest = Pathname.new "#{file}.download"
|
||||||
STDIN.reopen rd
|
info "Download #{uri} => #{tarball}"
|
||||||
Kernel.exec 'tar', '--no-ignore-command-error', '-xJf', '-'
|
if true
|
||||||
|
raise DownloadFailed, uri unless Kernel.system( 'wget', '-c', '-O', dest.to_s, uri.to_s)
|
||||||
|
else
|
||||||
|
done = dest.size
|
||||||
|
p dest => done
|
||||||
|
dest.open 'a+' do |fd|
|
||||||
|
streamer = lambda do |chunk, remaining, total|
|
||||||
|
fd.write chunk
|
||||||
|
count = total - remaining
|
||||||
|
STDERR.print "\rloading %s/%s % 3d%%\e[J" % [
|
||||||
|
format_bytes(count), format_bytes(total), 100.0*count/total ]
|
||||||
end
|
end
|
||||||
Process.waitpid tar_pid
|
res = Excon.get uri.to_s,
|
||||||
tar_status = $?.exitstatus
|
response_block: streamer,
|
||||||
raise DownloadFailed, "Download of #{uri} failed." unless 0 == curl_status and 0 == tar_status
|
expects: 200,
|
||||||
|
headers: {'Range' => "#{done}-" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
dest.rename file
|
||||||
|
end
|
||||||
|
|
||||||
|
def _unpack tarball, destdir
|
||||||
|
info "Unpack #{tarball} => #{destdir}"
|
||||||
|
unless Kernel.system 'tar', '-C', destdir.to_s, '-xf', tarball.to_s
|
||||||
|
raise UnpackFailed, tarball
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def download release_or_uri
|
||||||
|
uri =
|
||||||
|
case release_or_uri
|
||||||
|
when Release then release_or_uri.source
|
||||||
|
when URI, String then URI.parse release_or_uri.to_s
|
||||||
|
else raise UnexpectedThingToDownload, "This is no URI, String or Release"
|
||||||
|
end
|
||||||
|
# We do not understand anything else than operating systems with / as separator
|
||||||
|
@cache_dir.mkdir 0755 unless @cache_dir.exist?
|
||||||
|
tarball = @cache_dir + File.basename( uri.path)
|
||||||
|
_download uri, tarball unless tarball.exist?
|
||||||
|
_unpack tarball, @sources_base_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
def oldconfig_prepare version = nil, config = nil
|
def oldconfig_prepare version = nil, config = nil
|
||||||
version = find_fetched_version version
|
version = find_fetched_version version
|
||||||
config = case config
|
config =
|
||||||
|
case config
|
||||||
when lambda {|x| Pathname.new( config.to_s).exist? } then config
|
when lambda {|x| Pathname.new( config.to_s).exist? } then config
|
||||||
when nil, false then configured.max.config
|
when nil, false then configured.max.config
|
||||||
else find_fetched_version( config).config
|
else find_fetched_version( config).config
|
||||||
|
@ -315,7 +391,7 @@ module LinuxUpdate
|
||||||
end
|
end
|
||||||
|
|
||||||
desc 'importconfig [VERSION] [CONFIG]', 'Imports an other config from file or an other source directory. (default: most actual version with config to most actual version).'
|
desc 'importconfig [VERSION] [CONFIG]', 'Imports an other config from file or an other source directory. (default: most actual version with config to most actual version).'
|
||||||
def importconfig version, config = nil
|
def importconfig version = nil, config = nil
|
||||||
version, config = base.oldconfig_prepare( version, options[:config])
|
version, config = base.oldconfig_prepare( version, options[:config])
|
||||||
version.import_config config if config
|
version.import_config config if config
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue