dekernel 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/dekernel +28 -0
- data/lib/dekernel.rb +24 -0
- data/lib/dekernel/cernel.rb +104 -0
- data/lib/dekernel/message.rb +74 -0
- data/spec/lib/dekernel/cernel_spec.rb +284 -0
- data/spec/lib/dekernel/message_spec.rb +110 -0
- data/spec/lib/dekernel_spec.rb +57 -0
- data/spec/spec_helper.rb +28 -0
- metadata +75 -0
data/bin/dekernel
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
$options = { dry_run: false, assume_yes: false, kernels_list: nil,
|
5
|
+
all_except: nil, no_confirm: false }
|
6
|
+
OptionParser.new { |opts|
|
7
|
+
opts.banner = "Usage: ./deKernelScript [--dry-run, --assume-yes, --kernels-list=[space separated kernel #'s]"
|
8
|
+
|
9
|
+
opts.on('-s', '--dry-run', 'Dry run with apt-get') do
|
10
|
+
$options[:dry_run] = true
|
11
|
+
end
|
12
|
+
opts.on('-y', '--assume-yes', 'Assume yes with apt-get') do
|
13
|
+
$options[:assume_yes] = true
|
14
|
+
end
|
15
|
+
opts.on('-n', '--no-confirm', "Do not confirm with 'Are you sure?' message") do
|
16
|
+
$options[:no_confirm] = true
|
17
|
+
end
|
18
|
+
opts.on('-x', '--all-except', 'Remove all except the lastest (n) kernels', '=MANDATORY', Integer) do |v|
|
19
|
+
$options[:all_except] = v.to_i
|
20
|
+
end
|
21
|
+
opts.on('-k', '--kernels-list', 'Kernels to remove list', '=MANDATORY') do |v|
|
22
|
+
$options[:kernels_list] = v
|
23
|
+
end
|
24
|
+
}.parse!
|
25
|
+
|
26
|
+
require 'dekernel'
|
27
|
+
|
28
|
+
DeKernel.run
|
data/lib/dekernel.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class DeKernel
|
2
|
+
require 'dekernel/cernel'
|
3
|
+
require 'dekernel/message'
|
4
|
+
|
5
|
+
def self.run
|
6
|
+
original_free_space = Cernel.get_free_disk_space
|
7
|
+
Kernel.system "clear"
|
8
|
+
if $options[:dry_run]
|
9
|
+
$stdout.puts "\n" + " THIS IS A DRY-RUN!, apt-get will only pretend." + "\n" + "\n"
|
10
|
+
end
|
11
|
+
$stdout.puts "It's generally recommended to leave at least " +
|
12
|
+
"three of your latest kernels installed." + "\n" + "\n"
|
13
|
+
if $options[:all_except] != nil
|
14
|
+
Cernel.purge_packages_from_a_list_of_kernels(Cernel.find_all_except_latest($options[:all_except]))
|
15
|
+
elsif $options[:kernels_list] != nil
|
16
|
+
Cernel.purge_packages_from_a_list_of_kernels(Cernel.safe_ified_kernels_list)
|
17
|
+
else
|
18
|
+
Cernel.purge_packages_from_a_list_of_kernels(Cernel.ask_which_to_remove)
|
19
|
+
end
|
20
|
+
ensure
|
21
|
+
$stdout.puts Message.other_kernels
|
22
|
+
$stdout.puts "#{Cernel.get_free_disk_space - original_free_space} megabytes of disk space were freed."
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
class Cernel
|
2
|
+
class << self
|
3
|
+
def find_kernels
|
4
|
+
all_kernels = find_all_kernels
|
5
|
+
installed_kernels = find_installed_kernels(all_kernels)
|
6
|
+
{ all: all_kernels, installed: installed_kernels }
|
7
|
+
end
|
8
|
+
|
9
|
+
def ask_which_to_remove
|
10
|
+
installed_kernels = find_kernels[:installed]
|
11
|
+
$stdout.puts Message.installed_kernels(installed_kernels)
|
12
|
+
Kernel.exit if installed_kernels.length == 0
|
13
|
+
kernels_to_remove = create_kernels_to_remove_list(installed_kernels)
|
14
|
+
end
|
15
|
+
|
16
|
+
def purge_packages_from_a_list_of_kernels(kernels_to_remove)
|
17
|
+
($stderr.puts "\n" + "No kernels selected!" ; Kernel.exit) unless kernels_to_remove.length > 0
|
18
|
+
confirm_removals(kernels_to_remove) unless $options[:no_confirm]
|
19
|
+
packages_list = find_kernel_packages(kernels_to_remove)
|
20
|
+
IO.send(:popen, "sudo apt-get purge #{apt_options} #{packages_list.join("\s")} 1>&2") { |p| p.each { |f| $stdout.puts f } }
|
21
|
+
if $?.exitstatus != 0
|
22
|
+
$stdout.puts Message.purge_packages_failure($?)
|
23
|
+
else
|
24
|
+
$stdout.puts Message.purge_packages_success(kernels_to_remove)
|
25
|
+
Kernel.system "sudo apt-get clean" unless $options[:dry_run]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_free_disk_space
|
30
|
+
Kernel.send(:`, "df -BM /boot").split[10].to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_all_except_latest(number)
|
34
|
+
kernels = find_kernels
|
35
|
+
sort_properly(kernels[:installed]).rotate(-number).drop(number)
|
36
|
+
end
|
37
|
+
|
38
|
+
def safe_ified_kernels_list
|
39
|
+
options = $options[:kernels_list].split(" ").reject { |kernel| kernel =~ (/[a-z]/i) }
|
40
|
+
options = options.reject { |kernel| kernel =~ (/[0-9]{3,}/i) }
|
41
|
+
options.select { |kernel| kernel =~ kernel_regex }
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
private
|
46
|
+
def find_all_kernels
|
47
|
+
Kernel.send(:`, "ls /boot").each_line.grep(/vmlinuz/).collect { |l|
|
48
|
+
l.match(kernel_regex).to_s
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def kernel_regex
|
53
|
+
/[0-9]\.[0-9]{1,2}\.[0-9]{1,2}-[0-9]{1,2}/
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_installed_kernels(all_kernels)
|
57
|
+
all_kernels.select { |kernel|
|
58
|
+
Kernel.send(:system, "dpkg-query -f '${Package}\n' -W *#{kernel}* >/dev/null 2>&1")
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_kernels_to_remove_list(installed_kernels)
|
63
|
+
installed_kernels.select { |kernel|
|
64
|
+
$stdout.print "Do you want to remove the #{kernel} kernel [y/N/yes/NO/?]"
|
65
|
+
next unless !!ARGF.first.strip.match(/^y$|^yes$/i)
|
66
|
+
$stdout.puts "Marking #{kernel} for removal" ; true
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def find_kernel_packages(kernels_to_remove)
|
71
|
+
packages = kernels_to_remove.map { |kernel|
|
72
|
+
Kernel.send(:`, "dpkg-query -f '${Package}\n' -W *#{kernel}*").split("\n")
|
73
|
+
}.flatten
|
74
|
+
if packages.empty?
|
75
|
+
$stderr.puts "ERROR: No packages to remove." ; Kernel.exit
|
76
|
+
else
|
77
|
+
$stdout.puts "Packages are being uninstalled, please stand by..."
|
78
|
+
end ; packages
|
79
|
+
end
|
80
|
+
|
81
|
+
def confirm_removals(kernels_to_remove)
|
82
|
+
all_kernels = find_kernels
|
83
|
+
installed_kernels = all_kernels[:installed]
|
84
|
+
Kernel.system "clear"
|
85
|
+
$stdout.puts Message.ask_to_confirm_kernels_to_remove(kernels_to_remove, installed_kernels)
|
86
|
+
($stderr.puts "Canceled!" ; Kernel.exit) unless !!ARGF.first.strip.match(/^y$|^yes$/i)
|
87
|
+
kernels_to_remove
|
88
|
+
end
|
89
|
+
|
90
|
+
def sort_properly(kernels)
|
91
|
+
kernels.sort_by { |kernel_string|
|
92
|
+
split = kernel_string.split(/-/)
|
93
|
+
[split[0], "%02d" % split[1]].join('-')
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def apt_options
|
98
|
+
{ y: $options[:assume_yes], s: $options[:dry_run] }.collect { |k, v|
|
99
|
+
if v == true ; "-#{k}" ; end
|
100
|
+
}.join(' ').strip
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class Message
|
2
|
+
class << self
|
3
|
+
## Every method in this class returns a String object
|
4
|
+
|
5
|
+
def installed_kernels(installed_kernels)
|
6
|
+
[kernel_count(installed_kernels),
|
7
|
+
(installed_kernels.collect { |k| " #{k} " })].flatten.push("", "").join("\n")
|
8
|
+
end
|
9
|
+
|
10
|
+
def other_kernels
|
11
|
+
kernels = Cernel.find_kernels
|
12
|
+
if (kernels[:all] - kernels[:installed]).length > 0
|
13
|
+
["",
|
14
|
+
"### NOTE: You have kernels in your /boot directory " +
|
15
|
+
"that have no corresponding packages installed.",
|
16
|
+
"### If you know you don't want those kernels, " +
|
17
|
+
"you may want to remove them.",
|
18
|
+
"### You can list and remove them with the following commands:",
|
19
|
+
list_and_remove_commands(kernels[:all] - kernels[:installed]),
|
20
|
+
"", ""].join("\n")
|
21
|
+
end or String.new
|
22
|
+
end
|
23
|
+
|
24
|
+
[:success, :failure].each { |exit_status|
|
25
|
+
define_method "purge_packages_#{exit_status}" do |message|
|
26
|
+
if exit_status == :success
|
27
|
+
["",
|
28
|
+
"Successfully removed the kernel packages for: #{message.join(', ')}",
|
29
|
+
"",
|
30
|
+
"### NOTE: Usually apt-get will update your bootloader automatically,",
|
31
|
+
"### but if you have any trouble you may need to update it manually.",
|
32
|
+
"### (i.e. `sudo update-grub2` if you are using grub2)"]
|
33
|
+
else
|
34
|
+
["", "ERROR: apt-get purge failed with \"#{message}\""]
|
35
|
+
end.join("\n")
|
36
|
+
end
|
37
|
+
}
|
38
|
+
|
39
|
+
def ask_to_confirm_kernels_to_remove(kernels_to_remove, installed_kernels)
|
40
|
+
header_message = kernels_to_remove.length > 1 \
|
41
|
+
? "The #{kernels_to_remove.length} kernels marked with asterisks will be apt-get purged:" \
|
42
|
+
: "The kernel marked with asterisks will be apt-get purged:"
|
43
|
+
marked_up_kernels_list = installed_kernels.collect { |kernel|
|
44
|
+
kernels_to_remove.include?(kernel) ? "**#{kernel}**" : " #{kernel} "
|
45
|
+
}
|
46
|
+
[header_message, marked_up_kernels_list, "",
|
47
|
+
"Are you sure you want to continue [y/N/yes/NO/?]"].join("\n")
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
{ "list" => "ls -ahl", "remove" => "rm -f " }.each { |name, command|
|
52
|
+
define_method "#{name}_command" do |other_kernels|
|
53
|
+
command = other_kernels.collect { |kernel| "sudo #{command} /boot/*-#{kernel}*" }.join(" && ")
|
54
|
+
"### `%s`" % command
|
55
|
+
end
|
56
|
+
}
|
57
|
+
|
58
|
+
def list_and_remove_commands(other_kernels)
|
59
|
+
[list_command(other_kernels), remove_command(other_kernels)].join("\n")
|
60
|
+
end
|
61
|
+
|
62
|
+
def kernel_count(installed_kernels)
|
63
|
+
case installed_kernels.length
|
64
|
+
when 0
|
65
|
+
"ERROR: No kernels found in the /boot directory!"
|
66
|
+
when 1
|
67
|
+
"Only one kernel found!"
|
68
|
+
when 2..(1.0/0.0)
|
69
|
+
"Found #{installed_kernels.length} kernels installed:"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,284 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Cernel' do
|
4
|
+
before :each do
|
5
|
+
$stdout.stub!(:puts)
|
6
|
+
$stdout.stub!(:print)
|
7
|
+
$stderr.stub!(:puts)
|
8
|
+
Kernel.stub!(:system)
|
9
|
+
end
|
10
|
+
context "#find_kernels" do
|
11
|
+
it "finds all kernels" do
|
12
|
+
Cernel.stub!(:find_all_kernels).and_return(@all_kernels)
|
13
|
+
kernels = Cernel.find_kernels
|
14
|
+
expect(kernels[:all]).to eq @all_kernels
|
15
|
+
end
|
16
|
+
|
17
|
+
it "finds installed kernels" do
|
18
|
+
Cernel.stub!(:find_installed_kernels).and_return(@installed_kernels)
|
19
|
+
kernels = Cernel.find_kernels
|
20
|
+
expect(kernels[:installed]).to eq @installed_kernels
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "#ask_which_to_remove" do
|
25
|
+
it "raises SystemExit if installed_kernels.length == 0" do
|
26
|
+
Cernel.stub!(:find_kernels).and_return({ installed: [] })
|
27
|
+
expect(lambda { Cernel.ask_which_to_remove }).to raise_error SystemExit
|
28
|
+
end
|
29
|
+
|
30
|
+
it "prints each one and adds to list" do
|
31
|
+
Cernel.stub!(:find_installed_kernels).and_return(@installed_kernels)
|
32
|
+
ARGF.stub!(:first).and_return("y", "n", "y")
|
33
|
+
|
34
|
+
expect(Cernel.ask_which_to_remove.to_s).to match(/#{@remove_kernels.to_s}/)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "calls 'Message.installed_kernels(installed_kernels)'" do
|
38
|
+
Kernel.stub!(:exit)
|
39
|
+
Cernel.stub!(:find_kernels).and_return(@kernels_hash)
|
40
|
+
Message.should_receive(:installed_kernels).with(@installed_kernels)
|
41
|
+
ARGF.stub!(:first).and_return("y")
|
42
|
+
|
43
|
+
Cernel.ask_which_to_remove
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "#purge_packages_from_a_list_of_kernels(kernels_to_remove)" do
|
48
|
+
before :each do
|
49
|
+
IO.stub!(:popen)
|
50
|
+
Message.stub!(:purge_packages_success)
|
51
|
+
Message.stub!(:purge_packages_failure)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "calls confirm_removals with $options[:no_confirm] = false (default)" do
|
55
|
+
Cernel.stub!(:find_kernel_packages).and_return(@remove_packages)
|
56
|
+
Cernel.should_receive(:confirm_removals).with(@remove_kernels)
|
57
|
+
|
58
|
+
Cernel.purge_packages_from_a_list_of_kernels(@remove_kernels)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "does not call confirm_removals with $options[:no_confirm] = true" do
|
62
|
+
$options[:no_confirm] = true
|
63
|
+
Cernel.stub!(:find_kernel_packages).and_return(@remove_packages)
|
64
|
+
Cernel.should_not_receive(:confirm_removals).with(@remove_kernels)
|
65
|
+
|
66
|
+
Cernel.purge_packages_from_a_list_of_kernels(@remove_kernels)
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when kernels_to_remove.length is 0" do
|
70
|
+
it "raises SystemExit" do
|
71
|
+
expect(lambda do
|
72
|
+
Cernel.purge_packages_from_a_list_of_kernels([])
|
73
|
+
end).to raise_error SystemExit
|
74
|
+
end
|
75
|
+
|
76
|
+
it "prints 'no kernels selected' message" do
|
77
|
+
Kernel.stub!(:exit)
|
78
|
+
$stderr.should_receive(:puts).with("\nNo kernels selected!")
|
79
|
+
|
80
|
+
Cernel.purge_packages_from_a_list_of_kernels([])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
it "prints 'no packages error' message" do
|
86
|
+
Kernel.stub!(:exit)
|
87
|
+
$stderr.should_receive(:puts).with("ERROR: No packages to remove.")
|
88
|
+
Cernel.purge_packages_from_a_list_of_kernels([])
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when kernels_to_remove.length is > 0" do
|
92
|
+
context "when packages found" do
|
93
|
+
before :each do
|
94
|
+
Cernel.stub!(:confirm_removals).and_return(@remove_kernels)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "prints 'packages being uninstalled' message" do
|
98
|
+
Kernel.stub!(:`).with("dpkg-query -f '${Package}\n' -W *#{@installed_kernels.first}*").
|
99
|
+
and_return("package1 package2")
|
100
|
+
$stdout.should_receive(:puts).with("Packages are being uninstalled, please stand by...")
|
101
|
+
|
102
|
+
Cernel.purge_packages_from_a_list_of_kernels(@installed_kernels.first(1))
|
103
|
+
end
|
104
|
+
|
105
|
+
it "runs `apt-get purge` command with no options" do
|
106
|
+
IO.should_receive(:popen).with("sudo apt-get purge package1 package2 1>&2")
|
107
|
+
Cernel.stub!(:find_kernel_packages).and_return(["package1", "package2"])
|
108
|
+
|
109
|
+
Cernel.purge_packages_from_a_list_of_kernels(@installed_kernels.first(1))
|
110
|
+
end
|
111
|
+
|
112
|
+
it "does not run 'apt-get clean' command if $options[:dry_run] == true" do
|
113
|
+
$options[:dry_run] = true
|
114
|
+
$?.stub!(:exitstatus).and_return(0)
|
115
|
+
IO.should_receive(:popen).with("sudo apt-get purge -s package1 package2 1>&2")
|
116
|
+
Cernel.stub!(:find_kernel_packages).and_return(["package1", "package2"])
|
117
|
+
Kernel.should_not_receive(:system).with("sudo apt-get clean")
|
118
|
+
|
119
|
+
Cernel.purge_packages_from_a_list_of_kernels(@installed_kernels.first(1))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "#get_free_disk_space" do
|
126
|
+
it "gets available disk space" do
|
127
|
+
Kernel.should_receive(:`).with("df -BM /boot").
|
128
|
+
and_return("Filesystem 1M-blocks Used Available Use% Mounted on\n/dev/sdc3 46935M 9115M 35437M 21% /\n")
|
129
|
+
|
130
|
+
Cernel.get_free_disk_space
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "#find_all_except_latest(number)" do
|
135
|
+
it "should find all except latest (number) kernels" do
|
136
|
+
Cernel.stub!(:find_kernels).and_return(@kernels_hash)
|
137
|
+
expect(Cernel.send(:find_all_except_latest, 1)).to eq @all_except_latest_one
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
### private methods, test them or not?
|
143
|
+
|
144
|
+
context "#find_all_kernels" do
|
145
|
+
before :each do
|
146
|
+
Kernel.should_receive(:`).with("ls /boot").
|
147
|
+
and_return("vmlinuz-2.28.10-38-generic\nvmlinuz-3.2.0-39-generic\nvmlinuz-3.2.0-40-generic\n")
|
148
|
+
end
|
149
|
+
|
150
|
+
it "returns an array" do
|
151
|
+
expect(Cernel.send(:find_all_kernels)).to be_a_kind_of(Array)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "returns greped kernel numbers" do
|
155
|
+
expect(Cernel.send(:find_all_kernels)).to eq ["2.28.10-38", "3.2.0-39", "3.2.0-40"]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "#find_installed_kernels(all_kernels)" do
|
160
|
+
it "returns an array" do
|
161
|
+
expect(Cernel.send(:find_installed_kernels, @all_kernels)).to be_a_kind_of(Array)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "calls dpkg command for each kernel" do
|
165
|
+
@all_kernels.each do |kernel|
|
166
|
+
Kernel.stub!(:`).with("dpkg-query -f '${Package}\n' -W *#{kernel}* >/dev/null 2>&1")
|
167
|
+
Kernel.should_receive(:system).with("dpkg-query -f '${Package}\n' -W *#{kernel}* >/dev/null 2>&1").
|
168
|
+
and_return("linux-headers-#{kernel}\nlinux-headers-#{kernel}-generic\nlinux-image-#{kernel}-generic\n")
|
169
|
+
end
|
170
|
+
Cernel.send(:find_installed_kernels, @all_kernels)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "returns only kernels that have installed packages" do
|
174
|
+
{ "true" => @installed_kernels, "false" => @other_kernels }.each do |value, kernels|
|
175
|
+
kernels.each do |kernel|
|
176
|
+
Kernel.stub!(:system).
|
177
|
+
with("dpkg-query -f '${Package}\n' -W *#{kernel}* >/dev/null 2>&1").
|
178
|
+
and_return(!!value.match(/true/))
|
179
|
+
end
|
180
|
+
end
|
181
|
+
expect(Cernel.send(:find_installed_kernels, @all_kernels)).to eq @installed_kernels
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "#create_kernels_to_remove_list(installed_kernels)" do
|
186
|
+
it "returns an array" do
|
187
|
+
ARGF.should_receive(:first).exactly(@installed_kernels.length).times.and_return('yes')
|
188
|
+
expect(Cernel.send(:create_kernels_to_remove_list, @installed_kernels)).to be_a_kind_of(Array)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "returns only the kernels selected" do
|
192
|
+
ARGF.should_receive(:first).exactly(@installed_kernels.length).times.and_return('yes', 'no', 'no')
|
193
|
+
expect(Cernel.send(:create_kernels_to_remove_list, @installed_kernels)).to eq @installed_kernels.first(1)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context "#find_kernel_packages(kernels_to_remove)" do
|
198
|
+
before :each do
|
199
|
+
@remove_kernels.each do |kernel|
|
200
|
+
Kernel.should_receive(:`).exactly(1).times.with("dpkg-query -f '${Package}\n' -W *#{kernel}*").
|
201
|
+
and_return(@remove_packages.join("\n"))
|
202
|
+
end
|
203
|
+
(@all_kernels - @remove_kernels).each do |kernel|
|
204
|
+
Kernel.should_not_receive(:system).with("dpkg-query -f '${Package}\n' -W *#{kernel}*")
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
it "returns an array" do
|
209
|
+
expect(Cernel.send(:find_kernel_packages, @remove_kernels)).to be_a_kind_of(Array)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "returns only packages from the kernels_to_remove" do
|
213
|
+
# why do i have to use 'uniq' right here? without 'uniq' it returns a doubled array.
|
214
|
+
#expect(Cernel.send(:find_kernel_packages, @remove_kernels)).to eq @remove_packages
|
215
|
+
expect(Cernel.send(:find_kernel_packages, @remove_kernels).uniq).to eq @remove_packages
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context "#confirm_removals(kernels_to_remove, installed_kernels)" do
|
220
|
+
before :each do
|
221
|
+
Cernel.stub!(:find_kernels).and_return(@kernels_hash)
|
222
|
+
ARGF.should_receive(:first).exactly(1).times.and_return('no')
|
223
|
+
end
|
224
|
+
|
225
|
+
context "when confirmation not met" do
|
226
|
+
it "raises system exit" do
|
227
|
+
expect(lambda do
|
228
|
+
Cernel.send(:confirm_removals, @remove_kernels)
|
229
|
+
end).to raise_error SystemExit
|
230
|
+
end
|
231
|
+
|
232
|
+
it "prints 'canceled' message" do
|
233
|
+
Kernel.stub!(:exit)
|
234
|
+
|
235
|
+
$stderr.should_receive(:puts).with("Canceled!")
|
236
|
+
Cernel.send(:confirm_removals, @remove_kernels)
|
237
|
+
end
|
238
|
+
|
239
|
+
it "returns kernels_to_remove" do
|
240
|
+
Kernel.stub!(:exit)
|
241
|
+
|
242
|
+
expect(Cernel.send(:confirm_removals, @remove_kernels)).to eq @remove_kernels
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context "#sort_properly(kernels)" do
|
248
|
+
it "pads dash-number" do
|
249
|
+
unsorted = ["2.23.10-1", "3.2.0-8", "2.23.1-4", "3.2.0-11", "2.3.1-10", "2.23.1-34"]
|
250
|
+
sorted = ["2.23.1-4", "2.23.1-34", "2.23.10-1", "2.3.1-10", "3.2.0-8", "3.2.0-11"]
|
251
|
+
|
252
|
+
expect(Cernel.send(:sort_properly, unsorted)).to eq sorted
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
context "#apt_options" do
|
257
|
+
it "returns a string of the options" do
|
258
|
+
$options[:assume_yes] = false
|
259
|
+
$options[:dry_run] = false
|
260
|
+
expect(Cernel.send(:apt_options)).to eq ""
|
261
|
+
|
262
|
+
$options[:assume_yes] = true
|
263
|
+
$options[:dry_run] = false
|
264
|
+
expect(Cernel.send(:apt_options)).to eq "-y"
|
265
|
+
|
266
|
+
$options[:assume_yes] = false
|
267
|
+
$options[:dry_run] = true
|
268
|
+
expect(Cernel.send(:apt_options)).to eq "-s"
|
269
|
+
|
270
|
+
$options[:assume_yes] = true
|
271
|
+
$options[:dry_run] = true
|
272
|
+
expect(Cernel.send(:apt_options)).to eq "-y -s"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "#safe_ified_kernels_list" do
|
277
|
+
it "removes entries with letters" do
|
278
|
+
$options[:kernels_list] = "3.2.r-12 3.2.0-11 3.324.43-32 343 3.2.0-123"
|
279
|
+
|
280
|
+
expect(Cernel.send("safe_ified_kernels_list")).to eq ["3.2.0-11"]
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Message' do
|
4
|
+
context "#installed_kernels(installed_kernels)" do
|
5
|
+
context "when installed_kernels = 0" do
|
6
|
+
it "returns 'no kernels found error' message" do
|
7
|
+
expect(Message.installed_kernels([])).
|
8
|
+
to match "ERROR: No kernels found in the /boot directory!"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when installed_kernels = 1" do
|
13
|
+
it "returns 'only one kernel found' message" do
|
14
|
+
expect(Message.installed_kernels(@installed_kernels.last(1))).
|
15
|
+
to match "Only one kernel found!"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when installed_kernels > 1" do
|
20
|
+
it "returns 'multiple kernels found' message" do
|
21
|
+
expect(Message.installed_kernels(@installed_kernels)).
|
22
|
+
to match "Found #{@installed_kernels.length} kernels installed:"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns kernels as a string" do
|
27
|
+
expect(Message.installed_kernels(@installed_kernels)).
|
28
|
+
to match ["Found #{@installed_kernels.length} kernels installed:"].
|
29
|
+
concat(@installed_kernels.collect { |k| " #{k} " }).join("\n")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "#other_kernels" do
|
34
|
+
context "when other_kernels.length is greater than 0" do
|
35
|
+
it "returns 'you have other kernels' message" do
|
36
|
+
Cernel.stub!(:find_kernels).and_return(@kernels_hash)
|
37
|
+
message = "### NOTE: You have kernels in your /boot directory " +
|
38
|
+
"that have no corresponding packages installed." + "\n"
|
39
|
+
"### If you know you don't want those kernels, " +
|
40
|
+
"you may want to remove them."
|
41
|
+
|
42
|
+
expect(Message.other_kernels).to match message
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns list and remove commands" do
|
46
|
+
Cernel.stub!(:find_kernels).
|
47
|
+
and_return(@kernels_hash)
|
48
|
+
|
49
|
+
[@other_kernels.first, "sudo ls -ahl ", "sudo rm -f "].each do |string|
|
50
|
+
expect(Message.other_kernels).to match string
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns nothing if other_kernels.length == 0" do
|
56
|
+
Cernel.stub!(:find_kernels).and_return({ :all => @all_kernels, :installed => @all_kernels })
|
57
|
+
expect(Message.other_kernels).to be_empty
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "#purge_packages_success(kernels_to_remove)" do
|
62
|
+
it "returns successful purge message" do
|
63
|
+
string = [
|
64
|
+
"Successfully removed the kernel packages for: #{@all_kernels.drop(2).join(', ')}",
|
65
|
+
"",
|
66
|
+
"### NOTE: Usually apt-get will update your bootloader automatically,",
|
67
|
+
"### but if you have any trouble you may need to update it manually."].join("\n")
|
68
|
+
expect(Message.purge_packages_success(@all_kernels.drop(2))).to match string
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "#purge_packages_failure(exit_code)" do
|
73
|
+
it "returns failed purge message" do
|
74
|
+
string = 'ERROR: apt-get purge failed with \"12345\"'
|
75
|
+
expect(Message.purge_packages_failure("12345")).to match string
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "#ask_to_confirm_kernels_to_remove(kernels_to_remove, installed_kernels)" do
|
80
|
+
it "returns 'multiple kernels message' when multiple kernels" do
|
81
|
+
output = Message.ask_to_confirm_kernels_to_remove(@installed_kernels.drop(1), @installed_kernels)
|
82
|
+
count = @installed_kernels.drop(1).length
|
83
|
+
|
84
|
+
expect(output).to match "The #{count} kernels marked with asterisks will be apt-get purged:"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "returns 'singular kernel message' when only one kernel" do
|
88
|
+
output = Message.ask_to_confirm_kernels_to_remove(@installed_kernels.first(1),
|
89
|
+
@installed_kernels)
|
90
|
+
|
91
|
+
["The kernel marked with asterisks will be apt-get purged:",
|
92
|
+
"Are you sure you want to continue "].each do |string|
|
93
|
+
expect(output).to match string
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "responds to purge_packages_success and purge_packages_failure methods" do
|
99
|
+
["success", "failure"].each do |boolean|
|
100
|
+
expect(Message).to respond_to("purge_packages_#{boolean}")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "responds to list_command and remove_command methods" do
|
105
|
+
["list", "remove"].each do |name|
|
106
|
+
expect(Message).to respond_to("#{name}_command")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'deKernel' do
|
4
|
+
before :each do
|
5
|
+
$stdout.stub!(:puts)
|
6
|
+
Message.stub!(:other_kernels)
|
7
|
+
Kernel.stub!(:system).with("clear")
|
8
|
+
Cernel.stub!(:get_free_disk_space).and_return(12345)
|
9
|
+
Cernel.stub!(:ask_which_to_remove)
|
10
|
+
Cernel.stub!(:purge_packages_from_a_list_of_kernels)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "prints 'generally recommended' message" do
|
14
|
+
$stdout.should_receive(:puts).
|
15
|
+
with("It's generally recommended to leave at least three of your latest kernels installed.\n\n")
|
16
|
+
DeKernel.run
|
17
|
+
end
|
18
|
+
|
19
|
+
it "calls Cernel.purge_packages_from_a_list_of_kernels(Cernel.ask_which_to_remove)" do
|
20
|
+
Cernel.should_receive(:ask_which_to_remove)
|
21
|
+
Cernel.should_receive(:purge_packages_from_a_list_of_kernels)
|
22
|
+
DeKernel.run
|
23
|
+
end
|
24
|
+
|
25
|
+
it "prints Message.other_kernels" do
|
26
|
+
$stdout.should_receive(:puts)
|
27
|
+
Message.should_receive(:other_kernels)
|
28
|
+
DeKernel.run
|
29
|
+
end
|
30
|
+
|
31
|
+
it "prints 'disk space freed' message" do
|
32
|
+
$stdout.should_receive(:puts).with("0 megabytes of disk space were freed.")
|
33
|
+
DeKernel.run
|
34
|
+
end
|
35
|
+
|
36
|
+
it "accepts a list of kernels to remove" do
|
37
|
+
$options[:kernels_list] = @remove_kernels.join(" ")
|
38
|
+
Cernel.should_not_receive(:ask_which_to_remove)
|
39
|
+
Cernel.should_receive(:purge_packages_from_a_list_of_kernels).with(@remove_kernels)
|
40
|
+
|
41
|
+
DeKernel.run
|
42
|
+
end
|
43
|
+
|
44
|
+
context "accepts 'all-except (n)' kernels" do
|
45
|
+
it "removes all except latest (n)" do
|
46
|
+
$options[:all_except] = 1
|
47
|
+
$options[:kernels_list] = @remove_kernels.join(" ")
|
48
|
+
Cernel.should_not_receive(:ask_which_to_remove)
|
49
|
+
Cernel.should_not_receive(:purge_packages_from_a_list_of_kernels).with($options[:kernels_list].split(" "))
|
50
|
+
Cernel.should_receive(:find_all_except_latest).with(1)
|
51
|
+
Cernel.should_receive(:purge_packages_from_a_list_of_kernels)
|
52
|
+
|
53
|
+
DeKernel.run
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
|
4
|
+
require 'dekernel'
|
5
|
+
require 'dekernel/cernel'
|
6
|
+
require 'dekernel/message'
|
7
|
+
|
8
|
+
RSpec.configure do |c|
|
9
|
+
c.before :all do
|
10
|
+
$options = { dry_run: false, assume_yes: false, kernels_list: nil,
|
11
|
+
all_except: nil, no_confirm: false }
|
12
|
+
|
13
|
+
@all_kernels = ["2.3.56-1", "2.4.28-11", "3.2.0-11", "3.2.0-8"]
|
14
|
+
@installed_kernels = @all_kernels.drop(1)
|
15
|
+
@all_except_latest_one = @installed_kernels - ["3.2.0-11"]
|
16
|
+
@kernels_hash = { all: @all_kernels, installed: @installed_kernels }
|
17
|
+
@other_kernels = @all_kernels - @installed_kernels
|
18
|
+
@remove_kernels = @installed_kernels.drop(1)
|
19
|
+
|
20
|
+
@remove_packages = @remove_kernels.collect { |kernel|
|
21
|
+
["linux-headers-#{kernel}",
|
22
|
+
"linux-headers-#{kernel}-generic",
|
23
|
+
"linux-image-#{kernel}-generic"]
|
24
|
+
}.flatten
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dekernel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- david amick
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.11'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.11'
|
30
|
+
description: deKernel is a simple tool that finds installed kernels and automates
|
31
|
+
the removal of any you choose, freeing disk space. With optional flags, it can also
|
32
|
+
be automated for scripting.
|
33
|
+
email: github@davidamick.com
|
34
|
+
executables:
|
35
|
+
- dekernel
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- bin/dekernel
|
40
|
+
- lib/dekernel.rb
|
41
|
+
- lib/dekernel/cernel.rb
|
42
|
+
- lib/dekernel/message.rb
|
43
|
+
- spec/spec_helper.rb
|
44
|
+
- spec/lib/dekernel_spec.rb
|
45
|
+
- spec/lib/dekernel/cernel_spec.rb
|
46
|
+
- spec/lib/dekernel/message_spec.rb
|
47
|
+
homepage: https://github.com/snarlysodboxer/deKernel#dekernel
|
48
|
+
licenses: []
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.23
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Remove old/unused kernel packages.
|
71
|
+
test_files:
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
- spec/lib/dekernel_spec.rb
|
74
|
+
- spec/lib/dekernel/cernel_spec.rb
|
75
|
+
- spec/lib/dekernel/message_spec.rb
|