linux-update: removed. ruby-version should be more stable than shell-version. linux-update.rb renamed to linux-update.
This commit is contained in:
parent
de8785d5ba
commit
777cfce5a3
614
linux-update
614
linux-update
|
@ -1,181 +1,497 @@
|
||||||
#!/bin/sh
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
[ 0 = "`id -u`" ] || exec sudo http_proxy="$http_proxy" "$0" "$@"
|
require 'shellwords'
|
||||||
|
require 'getoptlong'
|
||||||
|
require 'json'
|
||||||
|
require 'pathname'
|
||||||
|
require 'shell'
|
||||||
|
require 'uri'
|
||||||
|
|
||||||
SOURCE_BASE_DIR=/usr/src
|
class RequiredGems
|
||||||
SOURCE_BASE_URI=http://www.kernel.org/pub/linux/kernel/v3.x/
|
attr_reader :requires, :failed
|
||||||
|
def self.require &block
|
||||||
|
rg = new
|
||||||
|
block.call rg, &rg.method(:push)
|
||||||
|
rg.require
|
||||||
|
end
|
||||||
|
|
||||||
usage() {
|
def initialize
|
||||||
echo "Usage: $0 $(help | sed -ne '3,$s/^\([^'"`printf '\t'`"']*\)'"`printf '\t'`"'.*$/\1/p' | tr '\n' '|' | sed -e 's/|/ | /g;s/ | $//')"
|
@requires, @failed = [], []
|
||||||
}
|
end
|
||||||
|
|
||||||
help() { #@ Print this help message
|
def push lib, gem = nil, name = nil
|
||||||
cat <<EOH
|
gem ||= lib
|
||||||
$0 Command
|
name ||= gem
|
||||||
possible commands:
|
@requires.push [lib, gem, name]
|
||||||
EOH
|
end
|
||||||
}
|
|
||||||
|
|
||||||
cache() {
|
def try_require lib
|
||||||
eval "$1() { echo '$(echo "$2" | sed -e 's/'\''/'"'\\\''"'/g')'; }"
|
require lib
|
||||||
$1
|
true
|
||||||
}
|
rescue LoadError
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
_latest_stable() {
|
def require lib = nil
|
||||||
curl -s http://www.kernel.org/kdist/finger_banner | sed -E -ne 's/^The latest stable .* version of the Linux kernel is: *([0-9.]*).*/\1/p' | head -1
|
return super lib if lib # if lib given, require it.
|
||||||
}
|
|
||||||
|
|
||||||
latest_stable() { #@ prints the latest stable available version on kernel.org
|
@failed = @requires.reject {|(lib, _, _)| try_require lib }
|
||||||
cache latest_stable "`_latest_stable`"
|
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
|
||||||
|
end
|
||||||
|
|
||||||
print_version() {
|
def requires_lib_gem &block
|
||||||
while read v d
|
requires = []
|
||||||
do
|
push = lambda {|lib, gem = lib, name = gem| requires.push [lib, gem, name] }
|
||||||
echo "$v"
|
block.call &push
|
||||||
done
|
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
|
||||||
|
|
||||||
print_dir() {
|
requires_lib_gem do |&push|
|
||||||
while read v d
|
push[ 'thor', nil, 'Thor']
|
||||||
do
|
push[ 'irb-pager', nil, 'IRB::Pager']
|
||||||
echo "$d"
|
push[ 'active_support/all', 'activesupport', 'ActiveSupport']
|
||||||
done
|
push[ 'excon', nil, 'Excon']
|
||||||
}
|
push[ 'versionomy', nil, 'Versionomy']
|
||||||
|
end
|
||||||
|
|
||||||
kernelversion_of() {
|
|
||||||
make -isC "$1" kernelversion
|
|
||||||
}
|
|
||||||
|
|
||||||
dir_of() {
|
module LinuxUpdate
|
||||||
w="${1}"
|
Release = Struct.new :version, :moniker, :source, :pgp, :released, :gitweb, :changelog, :patch_full, :patch_incremental, :iseol
|
||||||
fetched | while read v d
|
class Release
|
||||||
do
|
include Comparable
|
||||||
[ "$w" = "$v" ] && echo "$d"
|
def self.parse json
|
||||||
done
|
return nil if json['version'] =~ /^next-/
|
||||||
}
|
data = members.map {|m| json[m.to_s] }
|
||||||
|
data[0] = Versionomy.parse data[0]
|
||||||
|
data[2] = URI.parse data[2] rescue
|
||||||
|
data[3] = URI.parse data[3] rescue
|
||||||
|
data[4] = Time.at data[4]['timestamp'].to_i
|
||||||
|
new *data
|
||||||
|
end
|
||||||
|
|
||||||
fetched() { #@ prints all fetched versions
|
def stable?() 'stable' == moniker end
|
||||||
for d in "${SOURCE_BASE_DIR}"/linux-*
|
def mainline?() 'mainline' == moniker end
|
||||||
do
|
def longterm?() 'longterm' == moniker end
|
||||||
v="`kernelversion_of "$d"`"
|
def linux_next?() 'linux-next' == moniker end
|
||||||
if [ "$v" ]
|
alias eol? iseol
|
||||||
then
|
alias end_of_life? iseol
|
||||||
echo "$v $d"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
latest_version() {
|
def <=>( other) version <=> other.version end
|
||||||
sort -rV | head -1
|
|
||||||
}
|
|
||||||
|
|
||||||
latest_fetched() { #@ prints the latest fetched version
|
def to_s
|
||||||
fetched | latest_version
|
r = "linux-#{version} (#{moniker})"
|
||||||
}
|
r += " (EOL)" if end_of_life?
|
||||||
|
r
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
is_listed() {
|
class Fetched
|
||||||
awk \""${1}"'"==$1{print$0;exit}'
|
attr_reader :dir
|
||||||
}
|
def initialize dir
|
||||||
|
@dir = Pathname.new dir
|
||||||
|
end
|
||||||
|
|
||||||
latest_stable_is_fetched() {
|
def make *opts, &block
|
||||||
fetched | is_listed "`latest_stable`"
|
block ||= lambda {|rd| IO::copy_stream rd, STDOUT }
|
||||||
}
|
dir = @dir.to_s
|
||||||
|
rd, wr = IO.pipe
|
||||||
|
pid = fork do
|
||||||
|
STDOUT.reopen wr
|
||||||
|
rd.close
|
||||||
|
exec 'make', '-C', dir, *opts
|
||||||
|
end
|
||||||
|
wr.close
|
||||||
|
wr = nil
|
||||||
|
reader = Thread.new { block.call rd }
|
||||||
|
Process.waitpid pid
|
||||||
|
raise Base::MakeFailed, "make #{opts.join ' '}" unless 0 == $?.exitstatus
|
||||||
|
reader.value
|
||||||
|
ensure
|
||||||
|
rd.close if rd
|
||||||
|
wr.close if wr
|
||||||
|
end
|
||||||
|
|
||||||
update_available() { #@ prints the latest stable available version on kernel.org if it isn't fetched yet
|
def version
|
||||||
[ -z "`latest_stable_is_fetched`" ]
|
@version ||= make '-is', 'kernelversion' do |rd|
|
||||||
}
|
Versionomy.parse rd.readlines.join.chomp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
download_uri() { #@ [V] prints the uri of V (default: latest_stable)
|
def config
|
||||||
echo "${SOURCE_BASE_URI}/linux-${1:-`latest_stable`}.tar.xz"
|
dir + '.config'
|
||||||
}
|
end
|
||||||
|
|
||||||
download() { #@ [V] downloads the kernel of V (default: latest_stable)
|
def configured?
|
||||||
echo "Download $1" >&2
|
return @configured if @configured
|
||||||
curl `download_uri "${1}"`
|
@configured = config.exist?
|
||||||
}
|
end
|
||||||
|
|
||||||
unpack() { #@ simple unpack with unxz and tar in \$SOURCE_BASE_DIR (default: $SOURCE_BASE_DIR)
|
def <=>( other) version <=> other.version end
|
||||||
unxz | tar -C "${SOURCE_BASE_DIR}" -xf -
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch() { #@ [V] downloads and unpack the kernel of V (default: latest_stable)
|
def to_s
|
||||||
download "${1}" | unpack
|
r = "#{dir}"
|
||||||
}
|
r += " #{version}" if @version
|
||||||
|
r += " #{configured? ? :configured : 'not configured'}" if nil != @configured
|
||||||
|
r
|
||||||
|
end
|
||||||
|
|
||||||
update() { #@ downloads and unpack the latest_stable kernel if it isn't fetched yet
|
def open_config opts = nil, &block
|
||||||
if update_available
|
opts ||= 'r'
|
||||||
then
|
if block_given?
|
||||||
echo Update available: `latest_stable`
|
File.open config, opts, &block
|
||||||
fetch
|
|
||||||
else
|
else
|
||||||
echo "Upto date."
|
File.open config, opts
|
||||||
return 1
|
end
|
||||||
fi
|
end
|
||||||
}
|
|
||||||
|
|
||||||
configs() {
|
def import_config_from_io( io) open_config('w') {|c| io.each_line {|l| c.print l } } end
|
||||||
fetched | while read v d
|
|
||||||
do
|
|
||||||
[ -e "$d/.config" ] && echo "$v $d"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
has_config() { #@ [V] This kernel has a config?
|
def import_config file_or_io_or_fetched
|
||||||
configs | is_listed "$2"
|
info "Import config #{file_or_io_or_fetched}"
|
||||||
}
|
case file_or_io_or_fetched
|
||||||
|
when IO then import_config_from_io file_or_io_or_fetched
|
||||||
|
when Fetched
|
||||||
|
file_or_io_or_fetched.open_config &method(:import_config_from_io)
|
||||||
|
else
|
||||||
|
File.open file_or_io_or_fetched.to_s, &method(:import_config_from_io)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
latest_config() { #@ Which is the latest kernel with config?
|
def oldconfig
|
||||||
configs | latest_version
|
info 'make oldconfig'
|
||||||
}
|
make 'oldconfig'
|
||||||
|
end
|
||||||
|
|
||||||
copy_to_dir_config() {
|
def menuconfig
|
||||||
cp "${2:-`latest_config | print_dir`}/.config" "${1:-`latest_fetched | print_dir`}"
|
info 'make menuconfig'
|
||||||
}
|
make 'menuconfig'
|
||||||
|
end
|
||||||
|
|
||||||
install_config() { #@ [V] Copys the config of the newest kernel with config to V.
|
def compile
|
||||||
d="${1:-`latest_fetched | print_dir`}"
|
info 'make all'
|
||||||
s="${2:-`latest_config | print_dir`}"
|
make 'all'
|
||||||
[ -e "$d/.config" ] || copy_to_dir_config "${d}" "${s}"
|
end
|
||||||
}
|
|
||||||
|
|
||||||
oldconfig() { #@ [V] Run oldconfig (calls install_config previeusly).
|
def install
|
||||||
d="${1:-`latest_fetched | print_dir`}"
|
info 'make modules_install install'
|
||||||
install_config "$d" && make -C "$d" oldconfig
|
make 'modules_install', 'install'
|
||||||
}
|
end
|
||||||
|
|
||||||
install_all() {
|
def info text
|
||||||
echo "=====-- $1 --====="
|
STDERR.puts "[#{version}] #{text}"
|
||||||
d="${1:-`latest_fetched | print_dir`}"
|
end
|
||||||
echo "===== $d ====="
|
end
|
||||||
oldconfig "$d" && \
|
|
||||||
make -j3 -C "$d" all && \
|
|
||||||
make -j3 -C "$d" modules_install && \
|
|
||||||
make -j3 -C "$d" install
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd="$1"
|
class Base
|
||||||
shift
|
class Error <Exception
|
||||||
|
end
|
||||||
|
class InvalidVersionType <Error
|
||||||
|
end
|
||||||
|
class MakeFailed <Error
|
||||||
|
end
|
||||||
|
class DownloadFailed <Error
|
||||||
|
def initialize uri
|
||||||
|
super "Download of #{uri} failed."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
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'
|
||||||
|
SourcesBaseDir = '/usr/src/linux'
|
||||||
|
CacheDir = '/var/cache/linux-update'
|
||||||
|
|
||||||
case "$cmd" in
|
def releases_uri=( uri) @releases_uri = URI.parse uri.to_s end
|
||||||
latest_stable) latest_stable ;;
|
def sources_base_dir=( dir) @sources_base_dir = Pathname.new dir.to_s end
|
||||||
fetched) fetched ;;
|
def cache_dir=( dir) @cache_dir = Pathname.new dir.to_s end
|
||||||
latest_fetched) latest_fetched ;;
|
|
||||||
update_available) update_available ;;
|
def initialize
|
||||||
fetch) fetch "$@" ;;
|
self.releases_uri = ENV['LINUX_RELEASE_URI'] || ReleasesURI
|
||||||
download_uri) download_uri "$@" ;;
|
self.sources_base_dir = ENV['LINUX_SOURCES_BASE_DIR'] || SourcesBaseDir
|
||||||
download) download "$@" ;;
|
self.cache_dir = ENV['CacheDir'] || CacheDir
|
||||||
unpack) unpack ;;
|
end
|
||||||
update) update ;;
|
|
||||||
help|--help|-h) help ;;
|
def info text
|
||||||
usage) usage ;;
|
STDERR.puts text
|
||||||
latest_stable_is_fetched) latest_stable_is_fetched ;;
|
end
|
||||||
oldconfig) oldconfig "${1:+`dir_of "$1"`}" ;;
|
|
||||||
configs) configs "${1:+`dir_of "$1"`}" ;;
|
def releases
|
||||||
install) install_all "${1:+`dir_of "$1"`}" ;;
|
return @releases if @releases
|
||||||
all) update "$1" && install_all "${1:+`dir_of "$1"`}" ;;
|
res = Excon.get @releases_uri.to_s, expects: 200
|
||||||
*)
|
json = JSON.parse res.body
|
||||||
usage >&2
|
@releases = json['releases'].map {|r| Release.parse r }.compact
|
||||||
exit 1
|
end
|
||||||
;;
|
|
||||||
esac
|
def releases_moniker moniker = nil
|
||||||
|
moniker ? releases.select {|r| moniker == r.moniker } : releases
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetched
|
||||||
|
@fetched ||= Dir[ @sources_base_dir + 'linux-*'].
|
||||||
|
map( &Pathname.method( :new)).
|
||||||
|
select( &:directory?).
|
||||||
|
map {|d| Fetched.new d }
|
||||||
|
end
|
||||||
|
|
||||||
|
def configured() fetched.select &:configured? end
|
||||||
|
def unconfigured() fetched.reject &:configured? end
|
||||||
|
|
||||||
|
def find_fetched_version version
|
||||||
|
case version
|
||||||
|
when Fetched then version
|
||||||
|
when Versionomy::Value then fetched.find {|f| version == f.version }
|
||||||
|
when Release then find_fetched_version version.version
|
||||||
|
when String then find_fetched_version Versionomy.parse( version)
|
||||||
|
when nil, false then fetched.max
|
||||||
|
else raise InvalidVersionType, "I know Fetched, Versionomy, Release and String, but what is #{version.class}?"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def exist? file
|
||||||
|
Pathname.new( file.to_s).exist?
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_bytes bytes
|
||||||
|
case bytes
|
||||||
|
when 0...1.kilobyte then "%6dB" % bytes
|
||||||
|
when 0...1.megabyte then "%4dKiB" % (bytes / 1.kilobyte)
|
||||||
|
when 0...1.gigabyte then "%4dMiB" % (bytes / 1.megabyte)
|
||||||
|
when 0...1.terabyte then "%4dGiB" % (bytes / 1.gigabyte)
|
||||||
|
when 0...1.petabyte then "%4dTiB" % (bytes / 1.terabyte)
|
||||||
|
else "%4dEiB" % (bytes / 1.petabyte)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def _download uri, file
|
||||||
|
dest = Pathname.new "#{file}.download"
|
||||||
|
info "Download #{uri} => #{file}"
|
||||||
|
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
|
||||||
|
res = Excon.get uri.to_s,
|
||||||
|
response_block: streamer,
|
||||||
|
expects: 200,
|
||||||
|
headers: {'Range' => "#{done}-" }
|
||||||
|
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
|
||||||
|
|
||||||
|
# returns tarballs-filename (e.g. linux-3.1.0.tar.xz)
|
||||||
|
# unpack-path will be @sources_base_dir, but sources dir is unknown.
|
||||||
|
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
|
||||||
|
tarball.basename
|
||||||
|
end
|
||||||
|
|
||||||
|
def oldconfig_prepare version = nil, config = nil
|
||||||
|
version = find_fetched_version version
|
||||||
|
config =
|
||||||
|
case config
|
||||||
|
when lambda {|x| Pathname.new( config.to_s).exist? } then config
|
||||||
|
when nil, false then configured.max.config
|
||||||
|
else find_fetched_version( config).config
|
||||||
|
end
|
||||||
|
[version, config]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Cmd < Thor
|
||||||
|
class Error < Exception
|
||||||
|
end
|
||||||
|
class NoAvailableRelease < Error
|
||||||
|
end
|
||||||
|
class InvalidVersionType < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
option :latest, type: :boolean, aliases: '-l', desc: 'Only the most actual linux kernel.'
|
||||||
|
option :moniker, type: :string, aliases: '-m', desc: 'stable, mainline, longterm (default: no moniker)'
|
||||||
|
desc 'releases [MONIKER]', 'Prints known linux-kernel releases'
|
||||||
|
def releases moniker = nil
|
||||||
|
listing base.releases_moniker( moniker || options[:moniker])
|
||||||
|
end
|
||||||
|
|
||||||
|
option :latest, type: :boolean, aliases: '-l', desc: 'Only the most actual linux kernel.'
|
||||||
|
desc 'fetched', 'Prints all fetched linux-kernel'
|
||||||
|
def fetched
|
||||||
|
listing base.fetched
|
||||||
|
end
|
||||||
|
|
||||||
|
option :print, type: :boolean, aliases: '-p', desc: 'Only print the URI. No fetch.'
|
||||||
|
option :any, type: :boolean, aliases: '-a', desc: 'Select any versions.'
|
||||||
|
option :longterm, type: :boolean, aliases: '-o', desc: 'Select long term versions.'
|
||||||
|
option :stable, type: :boolean, aliases: '-s', desc: 'Select stable versions (default).'
|
||||||
|
option :mainline, type: :boolean, aliases: '-m', desc: 'Select mainline versions.'
|
||||||
|
desc 'fetch [VERSION]', 'Download linux-kernel'
|
||||||
|
def fetch version = nil
|
||||||
|
rs = nil
|
||||||
|
if version
|
||||||
|
version = Versionomy.parse version
|
||||||
|
rs = base.releases.select! {|r| version == r.version }
|
||||||
|
else
|
||||||
|
moniker = :stable
|
||||||
|
moniker = :mainline if options[:mainline]
|
||||||
|
moniker = nil if options[:any]
|
||||||
|
rs = base.releases_moniker moniker.to_s
|
||||||
|
end
|
||||||
|
release = rs.max
|
||||||
|
raise NoAvailableRelease, "There is no available release which matchs your wishes." unless release
|
||||||
|
if options[:print]
|
||||||
|
puts release.source
|
||||||
|
return
|
||||||
|
end
|
||||||
|
base.download release
|
||||||
|
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).'
|
||||||
|
def importconfig version = nil, config = nil
|
||||||
|
version, config = base.oldconfig_prepare( version, options[:config])
|
||||||
|
version.import_config config if config
|
||||||
|
end
|
||||||
|
|
||||||
|
option :config, type: :string, aliases: '-c', default: false,
|
||||||
|
desc: 'Which pre existing config should be used? Can be an other linux-VERSION with an old config or a config-file. --no-config will prevent copying a config.'
|
||||||
|
desc 'oldconfig [VERSION]', 'Configure linux-VERSION (default: most actual version).'
|
||||||
|
long_desc <<-ELD
|
||||||
|
First it will copy an older config to your sources-directory, if needed and not --no-config.
|
||||||
|
If you use `--config CONFIG`, the existing config will be replaced by CONFIG!
|
||||||
|
Second make oldconfig will called.
|
||||||
|
ELD
|
||||||
|
def oldconfig version = nil
|
||||||
|
version, config = base.oldconfig_prepare( version, options[:config])
|
||||||
|
version.import_config config if nil != options['config'] and config and not version.config.exist?
|
||||||
|
version.oldconfig
|
||||||
|
end
|
||||||
|
|
||||||
|
option :config, type: :string, aliases: '-c', default: false,
|
||||||
|
desc: 'Which pre existing config should be used? Can be an other linux-VERSION with an old config or a config-file. --no-config will prevent copying a config.'
|
||||||
|
desc 'oldconfig [VERSION]', 'Configure linux-VERSION (default: most actual version).'
|
||||||
|
long_desc <<-ELD
|
||||||
|
First it will copy an older config to your sources-directory, if needed and not --no-config.
|
||||||
|
If you use `--config CONFIG`, the existing config will be replaced by CONFIG!
|
||||||
|
Second make oldconfig will called.
|
||||||
|
ELD
|
||||||
|
desc 'menuconfig|configure [VERSION]', 'Configure your linux-VERSION. (default: most actual version).'
|
||||||
|
def menuconfig version = nil
|
||||||
|
version, config = base.oldconfig_prepare( version, options[:config])
|
||||||
|
version.import_config config if nil != options['config'] and config and not version.config.exist?
|
||||||
|
version.menuconfig
|
||||||
|
end
|
||||||
|
map configure: :menuconfig
|
||||||
|
|
||||||
|
desc 'compile [VERSION]', 'Will compile kernel and modules.'
|
||||||
|
def compile version = nil
|
||||||
|
version = base.find_fetched_version version
|
||||||
|
version.compile
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'install [VERSION]', 'Will install kernel and modules. It will trigger updating third-party-modules.'
|
||||||
|
def install version = nil
|
||||||
|
version = base.find_fetched_version version
|
||||||
|
version.install
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'all [VERSION]', 'Will oldconfig, compile and install kernel and modules. See these methods.'
|
||||||
|
def all version = nil
|
||||||
|
version, config = base.oldconfig_prepare( version, options[:config])
|
||||||
|
version.import_config config if nil != options['config'] and config and not version.config.exist?
|
||||||
|
version.oldconfig
|
||||||
|
version.compile
|
||||||
|
version.install
|
||||||
|
end
|
||||||
|
|
||||||
|
option :any, type: :boolean, aliases: '-a', desc: 'Select any versions.'
|
||||||
|
option :longterm, type: :boolean, aliases: '-o', desc: 'Select long term versions.'
|
||||||
|
option :stable, type: :boolean, aliases: '-s', desc: 'Select stable versions (default).'
|
||||||
|
option :mainline, type: :boolean, aliases: '-m', desc: 'Select mainline versions.'
|
||||||
|
desc 'update [VERSION]', 'Download, compile and install linux-kernel'
|
||||||
|
def update version = nil
|
||||||
|
tarball = fetch version
|
||||||
|
/^linux-(.*)\.tar\./ =~ tarball.basename.to_s
|
||||||
|
# try it with version in tarball's name:
|
||||||
|
all $1
|
||||||
|
end
|
||||||
|
|
||||||
|
no_commands do
|
||||||
|
def base
|
||||||
|
@base ||= Base.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def listing list
|
||||||
|
list.each do |e|
|
||||||
|
e.configured? if e.is_a? Fetched
|
||||||
|
end
|
||||||
|
if options[:latest]
|
||||||
|
puts list.max
|
||||||
|
else
|
||||||
|
puts list.sort {|a,b|b<=>a}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
begin # if __FILE__ == $0
|
||||||
|
$debug = true if $DEBUG
|
||||||
|
LinuxUpdate::Cmd.start ARGV
|
||||||
|
rescue LinuxUpdate::Cmd::Error, LinuxUpdate::Base::Error
|
||||||
|
STDERR.puts "Error: #{$!}"
|
||||||
|
STDERR.puts $!.backtrace.map {|c| "\t#{c}" } if $debug
|
||||||
|
raise
|
||||||
|
#exit 1
|
||||||
|
rescue Object
|
||||||
|
STDERR.puts "Unknown and unexpected Error: #{$!} (#{$!.class})"
|
||||||
|
STDERR.puts $!.backtrace.map {|c| "\t#{c}" } if $debug
|
||||||
|
raise
|
||||||
|
#exit 2
|
||||||
|
end if __FILE__ == $0
|
||||||
|
|
497
linux-update.rb
497
linux-update.rb
|
@ -1,497 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
require 'shellwords'
|
|
||||||
require 'getoptlong'
|
|
||||||
require 'json'
|
|
||||||
require 'pathname'
|
|
||||||
require 'shell'
|
|
||||||
require 'uri'
|
|
||||||
|
|
||||||
class RequiredGems
|
|
||||||
attr_reader :requires, :failed
|
|
||||||
def self.require &block
|
|
||||||
rg = new
|
|
||||||
block.call rg, &rg.method(:push)
|
|
||||||
rg.require
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@requires, @failed = [], []
|
|
||||||
end
|
|
||||||
|
|
||||||
def push lib, gem = nil, name = nil
|
|
||||||
gem ||= lib
|
|
||||||
name ||= gem
|
|
||||||
@requires.push [lib, gem, name]
|
|
||||||
end
|
|
||||||
|
|
||||||
def try_require lib
|
|
||||||
require lib
|
|
||||||
true
|
|
||||||
rescue LoadError
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def require lib = nil
|
|
||||||
return super lib if lib # if lib given, require it.
|
|
||||||
|
|
||||||
@failed = @requires.reject {|(lib, _, _)| try_require lib }
|
|
||||||
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
|
|
||||||
end
|
|
||||||
|
|
||||||
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[ 'irb-pager', nil, 'IRB::Pager']
|
|
||||||
push[ 'active_support/all', 'activesupport', 'ActiveSupport']
|
|
||||||
push[ 'excon', nil, 'Excon']
|
|
||||||
push[ 'versionomy', nil, 'Versionomy']
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
module LinuxUpdate
|
|
||||||
Release = Struct.new :version, :moniker, :source, :pgp, :released, :gitweb, :changelog, :patch_full, :patch_incremental, :iseol
|
|
||||||
class Release
|
|
||||||
include Comparable
|
|
||||||
def self.parse json
|
|
||||||
return nil if json['version'] =~ /^next-/
|
|
||||||
data = members.map {|m| json[m.to_s] }
|
|
||||||
data[0] = Versionomy.parse data[0]
|
|
||||||
data[2] = URI.parse data[2] rescue
|
|
||||||
data[3] = URI.parse data[3] rescue
|
|
||||||
data[4] = Time.at data[4]['timestamp'].to_i
|
|
||||||
new *data
|
|
||||||
end
|
|
||||||
|
|
||||||
def stable?() 'stable' == moniker end
|
|
||||||
def mainline?() 'mainline' == moniker end
|
|
||||||
def longterm?() 'longterm' == moniker end
|
|
||||||
def linux_next?() 'linux-next' == moniker end
|
|
||||||
alias eol? iseol
|
|
||||||
alias end_of_life? iseol
|
|
||||||
|
|
||||||
def <=>( other) version <=> other.version end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
r = "linux-#{version} (#{moniker})"
|
|
||||||
r += " (EOL)" if end_of_life?
|
|
||||||
r
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Fetched
|
|
||||||
attr_reader :dir
|
|
||||||
def initialize dir
|
|
||||||
@dir = Pathname.new dir
|
|
||||||
end
|
|
||||||
|
|
||||||
def make *opts, &block
|
|
||||||
block ||= lambda {|rd| IO::copy_stream rd, STDOUT }
|
|
||||||
dir = @dir.to_s
|
|
||||||
rd, wr = IO.pipe
|
|
||||||
pid = fork do
|
|
||||||
STDOUT.reopen wr
|
|
||||||
rd.close
|
|
||||||
exec 'make', '-C', dir, *opts
|
|
||||||
end
|
|
||||||
wr.close
|
|
||||||
wr = nil
|
|
||||||
reader = Thread.new { block.call rd }
|
|
||||||
Process.waitpid pid
|
|
||||||
raise Base::MakeFailed, "make #{opts.join ' '}" unless 0 == $?.exitstatus
|
|
||||||
reader.value
|
|
||||||
ensure
|
|
||||||
rd.close if rd
|
|
||||||
wr.close if wr
|
|
||||||
end
|
|
||||||
|
|
||||||
def version
|
|
||||||
@version ||= make '-is', 'kernelversion' do |rd|
|
|
||||||
Versionomy.parse rd.readlines.join.chomp
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def config
|
|
||||||
dir + '.config'
|
|
||||||
end
|
|
||||||
|
|
||||||
def configured?
|
|
||||||
return @configured if @configured
|
|
||||||
@configured = config.exist?
|
|
||||||
end
|
|
||||||
|
|
||||||
def <=>( other) version <=> other.version end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
r = "#{dir}"
|
|
||||||
r += " #{version}" if @version
|
|
||||||
r += " #{configured? ? :configured : 'not configured'}" if nil != @configured
|
|
||||||
r
|
|
||||||
end
|
|
||||||
|
|
||||||
def open_config opts = nil, &block
|
|
||||||
opts ||= 'r'
|
|
||||||
if block_given?
|
|
||||||
File.open config, opts, &block
|
|
||||||
else
|
|
||||||
File.open config, opts
|
|
||||||
end
|
|
||||||
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
|
|
||||||
info "Import config #{file_or_io_or_fetched}"
|
|
||||||
case file_or_io_or_fetched
|
|
||||||
when IO then import_config_from_io file_or_io_or_fetched
|
|
||||||
when Fetched
|
|
||||||
file_or_io_or_fetched.open_config &method(:import_config_from_io)
|
|
||||||
else
|
|
||||||
File.open file_or_io_or_fetched.to_s, &method(:import_config_from_io)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def oldconfig
|
|
||||||
info 'make oldconfig'
|
|
||||||
make 'oldconfig'
|
|
||||||
end
|
|
||||||
|
|
||||||
def menuconfig
|
|
||||||
info 'make menuconfig'
|
|
||||||
make 'menuconfig'
|
|
||||||
end
|
|
||||||
|
|
||||||
def compile
|
|
||||||
info 'make all'
|
|
||||||
make 'all'
|
|
||||||
end
|
|
||||||
|
|
||||||
def install
|
|
||||||
info 'make modules_install install'
|
|
||||||
make 'modules_install', 'install'
|
|
||||||
end
|
|
||||||
|
|
||||||
def info text
|
|
||||||
STDERR.puts "[#{version}] #{text}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Base
|
|
||||||
class Error <Exception
|
|
||||||
end
|
|
||||||
class InvalidVersionType <Error
|
|
||||||
end
|
|
||||||
class MakeFailed <Error
|
|
||||||
end
|
|
||||||
class DownloadFailed <Error
|
|
||||||
def initialize uri
|
|
||||||
super "Download of #{uri} failed."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
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'
|
|
||||||
SourcesBaseDir = '/usr/src/linux'
|
|
||||||
CacheDir = '/var/cache/linux-update'
|
|
||||||
|
|
||||||
def releases_uri=( uri) @releases_uri = URI.parse uri.to_s end
|
|
||||||
def sources_base_dir=( dir) @sources_base_dir = Pathname.new dir.to_s end
|
|
||||||
def cache_dir=( dir) @cache_dir = Pathname.new dir.to_s end
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
self.releases_uri = ENV['LINUX_RELEASE_URI'] || ReleasesURI
|
|
||||||
self.sources_base_dir = ENV['LINUX_SOURCES_BASE_DIR'] || SourcesBaseDir
|
|
||||||
self.cache_dir = ENV['CacheDir'] || CacheDir
|
|
||||||
end
|
|
||||||
|
|
||||||
def info text
|
|
||||||
STDERR.puts text
|
|
||||||
end
|
|
||||||
|
|
||||||
def releases
|
|
||||||
return @releases if @releases
|
|
||||||
res = Excon.get @releases_uri.to_s, expects: 200
|
|
||||||
json = JSON.parse res.body
|
|
||||||
@releases = json['releases'].map {|r| Release.parse r }.compact
|
|
||||||
end
|
|
||||||
|
|
||||||
def releases_moniker moniker = nil
|
|
||||||
moniker ? releases.select {|r| moniker == r.moniker } : releases
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetched
|
|
||||||
@fetched ||= Dir[ @sources_base_dir + 'linux-*'].
|
|
||||||
map( &Pathname.method( :new)).
|
|
||||||
select( &:directory?).
|
|
||||||
map {|d| Fetched.new d }
|
|
||||||
end
|
|
||||||
|
|
||||||
def configured() fetched.select &:configured? end
|
|
||||||
def unconfigured() fetched.reject &:configured? end
|
|
||||||
|
|
||||||
def find_fetched_version version
|
|
||||||
case version
|
|
||||||
when Fetched then version
|
|
||||||
when Versionomy::Value then fetched.find {|f| version == f.version }
|
|
||||||
when Release then find_fetched_version version.version
|
|
||||||
when String then find_fetched_version Versionomy.parse( version)
|
|
||||||
when nil, false then fetched.max
|
|
||||||
else raise InvalidVersionType, "I know Fetched, Versionomy, Release and String, but what is #{version.class}?"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def exist? file
|
|
||||||
Pathname.new( file.to_s).exist?
|
|
||||||
end
|
|
||||||
|
|
||||||
def format_bytes bytes
|
|
||||||
case bytes
|
|
||||||
when 0...1.kilobyte then "%6dB" % bytes
|
|
||||||
when 0...1.megabyte then "%4dKiB" % (bytes / 1.kilobyte)
|
|
||||||
when 0...1.gigabyte then "%4dMiB" % (bytes / 1.megabyte)
|
|
||||||
when 0...1.terabyte then "%4dGiB" % (bytes / 1.gigabyte)
|
|
||||||
when 0...1.petabyte then "%4dTiB" % (bytes / 1.terabyte)
|
|
||||||
else "%4dEiB" % (bytes / 1.petabyte)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def _download uri, file
|
|
||||||
dest = Pathname.new "#{file}.download"
|
|
||||||
info "Download #{uri} => #{file}"
|
|
||||||
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
|
|
||||||
res = Excon.get uri.to_s,
|
|
||||||
response_block: streamer,
|
|
||||||
expects: 200,
|
|
||||||
headers: {'Range' => "#{done}-" }
|
|
||||||
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
|
|
||||||
|
|
||||||
# returns tarballs-filename (e.g. linux-3.1.0.tar.xz)
|
|
||||||
# unpack-path will be @sources_base_dir, but sources dir is unknown.
|
|
||||||
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
|
|
||||||
tarball.basename
|
|
||||||
end
|
|
||||||
|
|
||||||
def oldconfig_prepare version = nil, config = nil
|
|
||||||
version = find_fetched_version version
|
|
||||||
config =
|
|
||||||
case config
|
|
||||||
when lambda {|x| Pathname.new( config.to_s).exist? } then config
|
|
||||||
when nil, false then configured.max.config
|
|
||||||
else find_fetched_version( config).config
|
|
||||||
end
|
|
||||||
[version, config]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Cmd < Thor
|
|
||||||
class Error < Exception
|
|
||||||
end
|
|
||||||
class NoAvailableRelease < Error
|
|
||||||
end
|
|
||||||
class InvalidVersionType < Error
|
|
||||||
end
|
|
||||||
|
|
||||||
option :latest, type: :boolean, aliases: '-l', desc: 'Only the most actual linux kernel.'
|
|
||||||
option :moniker, type: :string, aliases: '-m', desc: 'stable, mainline, longterm (default: no moniker)'
|
|
||||||
desc 'releases [MONIKER]', 'Prints known linux-kernel releases'
|
|
||||||
def releases moniker = nil
|
|
||||||
listing base.releases_moniker( moniker || options[:moniker])
|
|
||||||
end
|
|
||||||
|
|
||||||
option :latest, type: :boolean, aliases: '-l', desc: 'Only the most actual linux kernel.'
|
|
||||||
desc 'fetched', 'Prints all fetched linux-kernel'
|
|
||||||
def fetched
|
|
||||||
listing base.fetched
|
|
||||||
end
|
|
||||||
|
|
||||||
option :print, type: :boolean, aliases: '-p', desc: 'Only print the URI. No fetch.'
|
|
||||||
option :any, type: :boolean, aliases: '-a', desc: 'Select any versions.'
|
|
||||||
option :longterm, type: :boolean, aliases: '-o', desc: 'Select long term versions.'
|
|
||||||
option :stable, type: :boolean, aliases: '-s', desc: 'Select stable versions (default).'
|
|
||||||
option :mainline, type: :boolean, aliases: '-m', desc: 'Select mainline versions.'
|
|
||||||
desc 'fetch [VERSION]', 'Download linux-kernel'
|
|
||||||
def fetch version = nil
|
|
||||||
rs = nil
|
|
||||||
if version
|
|
||||||
version = Versionomy.parse version
|
|
||||||
rs = base.releases.select! {|r| version == r.version }
|
|
||||||
else
|
|
||||||
moniker = :stable
|
|
||||||
moniker = :mainline if options[:mainline]
|
|
||||||
moniker = nil if options[:any]
|
|
||||||
rs = base.releases_moniker moniker.to_s
|
|
||||||
end
|
|
||||||
release = rs.max
|
|
||||||
raise NoAvailableRelease, "There is no available release which matchs your wishes." unless release
|
|
||||||
if options[:print]
|
|
||||||
puts release.source
|
|
||||||
return
|
|
||||||
end
|
|
||||||
base.download release
|
|
||||||
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).'
|
|
||||||
def importconfig version = nil, config = nil
|
|
||||||
version, config = base.oldconfig_prepare( version, options[:config])
|
|
||||||
version.import_config config if config
|
|
||||||
end
|
|
||||||
|
|
||||||
option :config, type: :string, aliases: '-c', default: false,
|
|
||||||
desc: 'Which pre existing config should be used? Can be an other linux-VERSION with an old config or a config-file. --no-config will prevent copying a config.'
|
|
||||||
desc 'oldconfig [VERSION]', 'Configure linux-VERSION (default: most actual version).'
|
|
||||||
long_desc <<-ELD
|
|
||||||
First it will copy an older config to your sources-directory, if needed and not --no-config.
|
|
||||||
If you use `--config CONFIG`, the existing config will be replaced by CONFIG!
|
|
||||||
Second make oldconfig will called.
|
|
||||||
ELD
|
|
||||||
def oldconfig version = nil
|
|
||||||
version, config = base.oldconfig_prepare( version, options[:config])
|
|
||||||
version.import_config config if nil != options['config'] and config and not version.config.exist?
|
|
||||||
version.oldconfig
|
|
||||||
end
|
|
||||||
|
|
||||||
option :config, type: :string, aliases: '-c', default: false,
|
|
||||||
desc: 'Which pre existing config should be used? Can be an other linux-VERSION with an old config or a config-file. --no-config will prevent copying a config.'
|
|
||||||
desc 'oldconfig [VERSION]', 'Configure linux-VERSION (default: most actual version).'
|
|
||||||
long_desc <<-ELD
|
|
||||||
First it will copy an older config to your sources-directory, if needed and not --no-config.
|
|
||||||
If you use `--config CONFIG`, the existing config will be replaced by CONFIG!
|
|
||||||
Second make oldconfig will called.
|
|
||||||
ELD
|
|
||||||
desc 'menuconfig|configure [VERSION]', 'Configure your linux-VERSION. (default: most actual version).'
|
|
||||||
def menuconfig version = nil
|
|
||||||
version, config = base.oldconfig_prepare( version, options[:config])
|
|
||||||
version.import_config config if nil != options['config'] and config and not version.config.exist?
|
|
||||||
version.menuconfig
|
|
||||||
end
|
|
||||||
map configure: :menuconfig
|
|
||||||
|
|
||||||
desc 'compile [VERSION]', 'Will compile kernel and modules.'
|
|
||||||
def compile version = nil
|
|
||||||
version = base.find_fetched_version version
|
|
||||||
version.compile
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'install [VERSION]', 'Will install kernel and modules. It will trigger updating third-party-modules.'
|
|
||||||
def install version = nil
|
|
||||||
version = base.find_fetched_version version
|
|
||||||
version.install
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'all [VERSION]', 'Will oldconfig, compile and install kernel and modules. See these methods.'
|
|
||||||
def all version = nil
|
|
||||||
version, config = base.oldconfig_prepare( version, options[:config])
|
|
||||||
version.import_config config if nil != options['config'] and config and not version.config.exist?
|
|
||||||
version.oldconfig
|
|
||||||
version.compile
|
|
||||||
version.install
|
|
||||||
end
|
|
||||||
|
|
||||||
option :any, type: :boolean, aliases: '-a', desc: 'Select any versions.'
|
|
||||||
option :longterm, type: :boolean, aliases: '-o', desc: 'Select long term versions.'
|
|
||||||
option :stable, type: :boolean, aliases: '-s', desc: 'Select stable versions (default).'
|
|
||||||
option :mainline, type: :boolean, aliases: '-m', desc: 'Select mainline versions.'
|
|
||||||
desc 'update [VERSION]', 'Download, compile and install linux-kernel'
|
|
||||||
def update version = nil
|
|
||||||
tarball = fetch version
|
|
||||||
/^linux-(.*)\.tar\./ =~ tarball.basename.to_s
|
|
||||||
# try it with version in tarball's name:
|
|
||||||
all $1
|
|
||||||
end
|
|
||||||
|
|
||||||
no_commands do
|
|
||||||
def base
|
|
||||||
@base ||= Base.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def listing list
|
|
||||||
list.each do |e|
|
|
||||||
e.configured? if e.is_a? Fetched
|
|
||||||
end
|
|
||||||
if options[:latest]
|
|
||||||
puts list.max
|
|
||||||
else
|
|
||||||
puts list.sort {|a,b|b<=>a}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
begin # if __FILE__ == $0
|
|
||||||
$debug = true if $DEBUG
|
|
||||||
LinuxUpdate::Cmd.start ARGV
|
|
||||||
rescue LinuxUpdate::Cmd::Error, LinuxUpdate::Base::Error
|
|
||||||
STDERR.puts "Error: #{$!}"
|
|
||||||
STDERR.puts $!.backtrace.map {|c| "\t#{c}" } if $debug
|
|
||||||
raise
|
|
||||||
#exit 1
|
|
||||||
rescue Object
|
|
||||||
STDERR.puts "Unknown and unexpected Error: #{$!} (#{$!.class})"
|
|
||||||
STDERR.puts $!.backtrace.map {|c| "\t#{c}" } if $debug
|
|
||||||
raise
|
|
||||||
#exit 2
|
|
||||||
end if __FILE__ == $0
|
|
Loading…
Reference in a new issue