apt-repair-sources 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ Copyright (c) 2011, Till Klampaeckel
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ ## apt-repair-sources
2
+
3
+ Find broken packages in your sources.list (or sources.list.d/*). This code is [BSD licensed][bsd].
4
+
5
+ [bsd]: http://www.opensource.org/licenses/bsd-license.php
6
+
7
+ ### Setup
8
+
9
+ 1. best install REE
10
+ 2. `gem install trollop`
11
+ 3. clone this repo
12
+
13
+ ### USAGE
14
+
15
+ Display broken entries on your system:
16
+
17
+ ./apt-repair-sources.rb --dry-run
18
+
19
+ Fix broken entries:
20
+
21
+ ./apt-repair-sources.rb --fix-it-for-me
22
+
23
+
24
+ ### TODO
25
+
26
+ * Step 1: display what's broken (**DONE**)
27
+ * Step 2: fix it (**DONE**)
28
+ * Step 3: autocorrect entries (e.g. distro moves from a mirror to archive, to old-releases)
29
+
@@ -0,0 +1,51 @@
1
+
2
+ # -*- encoding: utf-8 -*-
3
+ $:.push('lib')
4
+ require "apt/repair/sources/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "apt-repair-sources"
8
+ s.version = Apt::Repair::Sources::VERSION.dup
9
+ s.date = "2011-11-23"
10
+ s.summary = "A tool to clean up your sources.list"
11
+ s.email = "till@php.net"
12
+ s.homepage = "http://github.com/lagged/apt-repair-sources"
13
+ s.authors = ['Till Klampaeckel']
14
+
15
+ s.description = <<-EOF
16
+ A tool to clean up your sources.list:
17
+
18
+ * apt-repair-sources -d: let's you examine your current sources
19
+ * apt-repair-sources -f: attempts to fix them
20
+
21
+ apt-repair-sources checks the following locations:
22
+
23
+ * /etc/apt/sources.list
24
+ * /etc/apt/sources.list.d/*.list
25
+
26
+ EOF
27
+
28
+ dependencies = [
29
+ [:runtime, "trollop", "~> 1.16.2"],
30
+ [:development, "test-unit", "~> 2.4.1"],
31
+ ]
32
+
33
+ s.files = Dir['**/*']
34
+ s.test_files = Dir['test/**/*'] + Dir['spec/**/*']
35
+ s.executables = Dir['bin/*'].map { |f| File.basename(f) }
36
+ s.require_paths = ["lib"]
37
+
38
+
39
+ ## Make sure you can build the gem on older versions of RubyGems too:
40
+ s.rubygems_version = "1.3.6"
41
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
42
+ s.specification_version = 3 if s.respond_to? :specification_version
43
+
44
+ dependencies.each do |type, name, version|
45
+ if s.respond_to?("add_#{type}_dependency")
46
+ s.send("add_#{type}_dependency", name, version)
47
+ else
48
+ s.add_dependency(name, version)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Author: Till Klampaeckel
4
+ # License: New BSD License, http://www.opensource.org/licenses/bsd-license.php
5
+ # Setup: gem install trollop
6
+ # Copyright: 2011 Till Klampaeckel
7
+ #
8
+
9
+ require 'rubygems'
10
+ require 'trollop'
11
+ require 'net/http'
12
+
13
+ $: << File.join(File.dirname(__FILE__), "..", "lib")
14
+ require 'apt/repair/sources'
15
+
16
+ ubuntu = `lsb_release -i|awk '{print $3}'`.gsub(/\s+/, "")
17
+ if (ubuntu != 'Ubuntu')
18
+ puts "Ubuntu-only, currently."
19
+ exit 1
20
+ end
21
+
22
+ work = []
23
+
24
+ if File.exist?("/etc/apt/sources.list")
25
+ work.push("/etc/apt/sources.list")
26
+ end
27
+
28
+ if File.directory?("/etc/apt/sources.list.d")
29
+ work += Dir["/etc/apt/sources.list.d/*.list"]
30
+ end
31
+
32
+ if work.length == 0
33
+ puts "Nothing to be done."
34
+ exit
35
+ end
36
+
37
+ opts = Trollop::options do
38
+ version "apt-repair-sources 0.1.0 (c) 2011 Till Klampaeckel"
39
+ banner <<-EOS
40
+ This tool helps you clean out bad entries from apt's sources.
41
+
42
+ Usage:
43
+
44
+ sudo apt-repair-sources --dry-run|--fix-it-for-me
45
+ EOS
46
+ opt :dry_run, "Display bad entries, this is enabled by default (no changes)", :default => false
47
+ opt :fix_it_for_me, "Remove bad entries from the sources (changes will be made)", :default => false
48
+ end
49
+
50
+ if opts[:dry_run] == true && opts[:fix_it_for_me] == true
51
+ puts "Cannot have both."
52
+ exit 1
53
+ else
54
+ if opts[:fix_it_for_me_given] && opts[:fix_it_for_me] == true
55
+ dry_run = false
56
+ else
57
+ dry_run = true
58
+ end
59
+ end
60
+
61
+ p = Apt::Repair::Sources::find_platform
62
+
63
+ work.each do |f|
64
+ File.open(f, "r") do |infile|
65
+ keep = []
66
+ err = 0
67
+ while (l = infile.gets)
68
+
69
+ if l.nil? || l.empty?
70
+ next
71
+ end
72
+
73
+ unless l[0,3] == 'deb' || l[0,7] == 'deb-src'
74
+ next
75
+ end
76
+
77
+ helper = Apt::Repair::Sources.new(l)
78
+ url = helper.get_url(nil)
79
+ el = helper.get_el
80
+
81
+ has_error = false
82
+
83
+ el.each do |t|
84
+
85
+ break if has_error == true
86
+
87
+ uri = url + t
88
+ uri += helper.get_end
89
+
90
+ if helper.uri_exists(uri) == true
91
+ next
92
+ end
93
+
94
+ has_error = true
95
+
96
+ err += 1
97
+
98
+ if dry_run == true
99
+ puts "#{f}: #{uri}"
100
+ end
101
+
102
+ end
103
+
104
+ if has_error == true
105
+ keep.push(helper.fix_line)
106
+ else
107
+ keep.push(l)
108
+ end
109
+
110
+ end
111
+
112
+ # save to be safe
113
+ if dry_run == false && err > 0
114
+ File.open(f, 'w') do |f|
115
+ f.write(keep.join("\n"))
116
+ end
117
+ end
118
+
119
+ if err == 0 && dry_run == true
120
+ puts "There are no errors in #{f}"
121
+ end
122
+
123
+ end
124
+ end
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Author: Till Klampaeckel
4
+ # License: New BSD License, http://www.opensource.org/licenses/bsd-license.php
5
+ # Copyright: 2011 Till Klampaeckel
6
+ #
7
+
8
+ module Apt
9
+ module Repair
10
+ # @author Till Klampaeckel
11
+ class Apt::Repair::Sources
12
+
13
+ # @param [String] line A line from a source.list file.
14
+ # @return [AptRepairSources]
15
+ def initialize(line)
16
+ @l = line
17
+ @e = line.split(" ")
18
+ end
19
+
20
+ # @return [String] The architecture: amd64, i686
21
+ def self.find_platform
22
+ return `dpkg --print-architecture`.gsub(/\s+/, "")
23
+ end
24
+
25
+ # Each 'line' in a sources.list file contains various elements, this is an array
26
+ # with them. type (deb, deb-src), url and distribution are stripped.
27
+ # @return [Array]
28
+ def get_el
29
+ el = @l.split(" ")
30
+
31
+ el.shift
32
+ el.shift
33
+ el.shift
34
+
35
+ return el
36
+ end
37
+
38
+ # @return [String] For the URL test!
39
+ def get_end
40
+ if self.get_type == 'deb'
41
+ return "/binary-#{self.class.find_platform}/Packages.gz"
42
+ end
43
+ return "/source/Sources.gz"
44
+ end
45
+
46
+ # @return [String] The type: most likely deb or deb-src
47
+ def get_type
48
+ return @e[0]
49
+ end
50
+
51
+ # @return [String] Create the base url to test against.
52
+ def get_url(base = nil)
53
+ if base.nil?
54
+ url = @e[1]
55
+ else
56
+ url = base
57
+ end
58
+ if url[-1,1] != "/"
59
+ url += "/"
60
+ end
61
+ url += "dists/" + @e[2] + "/"
62
+ return url
63
+ end
64
+
65
+ # Tries to fix a line from a sources.list file by correcting the URL or commenting
66
+ # it out. When the URL is corrected, we attempt to test if the new URL exists. The
67
+ # the failover is always to comment it out.
68
+ # @return [String]
69
+ def fix_line
70
+ el = @l.split(" ")
71
+
72
+ u = URI(el[1])
73
+
74
+ disable = false
75
+
76
+ case u.host
77
+ when "releases.ubuntu.com"
78
+ c = u.host
79
+ u.host = "archive.ubuntu.com"
80
+ if self.uri_exists(self.get_url(u.to_s)) == false
81
+ u.host = c
82
+ end
83
+ when "archive.ubuntu.com", "security.ubuntu.com"
84
+ c = u.host
85
+ u.host = "old-releases.ubuntu.com"
86
+ if self.uri_exists(self.get_url(u.to_s)) == false
87
+ u.host = c
88
+ end
89
+ when "old-releases.ubuntu.com"
90
+ raise Exception, "You're fucked."
91
+ else
92
+ # this is tricky, e.g. is the mirror down or did it move?
93
+ c = u.host
94
+
95
+ if c =~ /(.*)\.releases\.ubuntu\.com/
96
+ u.host = "archive.ubuntu.com"
97
+ elsif c =~ /(.*)\.archive\.ubuntu\.com/
98
+ u.host = "old-releases.ubuntu.com"
99
+ else
100
+ disable = true
101
+ end
102
+
103
+ if disable == false
104
+ if self.uri_exists(u.to_s) == false
105
+ u.host = c
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ el[1] = u.to_s
112
+ line = el.join(" ")
113
+
114
+ if disable == true
115
+ line = '#' + line
116
+ end
117
+
118
+ return line
119
+ end
120
+
121
+ # Check if a URL exists by issueing a HEAD request.
122
+ # @param [String] URL
123
+ # @return [Boolean]
124
+ def uri_exists(url)
125
+
126
+ u = URI(url)
127
+
128
+ Net::HTTP.start(u.host, u.port) do |http|
129
+ http.open_timeout = 1
130
+ http.read_timeout = 1
131
+ res = http.head(u.path)
132
+
133
+ if res.code == "200"
134
+ return true
135
+ end
136
+ return false
137
+ end
138
+ end
139
+
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,7 @@
1
+ module Apt
2
+ module Repair
3
+ module Sources
4
+ VERSION = '0.0.1'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,58 @@
1
+ $: << File.join(File.dirname(__FILE__), "..", "lib")
2
+ require 'rubygems'
3
+ require 'net/http'
4
+ require 'apt/repair/sources'
5
+ require 'test/unit'
6
+
7
+ class AptRepairSourcesTest < Test::Unit::TestCase
8
+ def test_type
9
+ l = "deb http://archive.ubuntu.com/ubuntu/ lucid main restricted universe multiverse"
10
+
11
+ helper = Apt::Repair::Sources.new(l)
12
+
13
+ assert_equal("deb", helper.get_type)
14
+ end
15
+
16
+ def test_url
17
+ l = "deb http://archive.ubuntu.com/ubuntu/ lucid main restricted universe multiverse"
18
+
19
+ helper = Apt::Repair::Sources.new(l)
20
+
21
+ u = helper.get_url(nil)
22
+ el = helper.get_el
23
+
24
+ el.each do |t|
25
+ c = u + t + helper.get_end
26
+ assert_equal(true, helper.uri_exists(c))
27
+ end
28
+
29
+ end
30
+
31
+ # Karmic moved from archive to old-releases.
32
+ def test_archive
33
+ l = "deb http://archive.ubuntu.com/ubuntu/ karmic main universe"
34
+ e = "deb http://old-releases.ubuntu.com/ubuntu/ karmic main universe"
35
+
36
+ helper = Apt::Repair::Sources.new(l)
37
+ assert_equal(e, helper.fix_line)
38
+ end
39
+
40
+ # Apt::Repair::Sources::get_url - parameter test
41
+ def test_get_url
42
+ l = "deb-src http://security.ubuntu.com/ubuntu karmic-security main universe"
43
+
44
+ helper = Apt::Repair::Sources.new(l)
45
+ assert_equal("http://security.ubuntu.com/ubuntu/dists/karmic-security/", helper.get_url(nil))
46
+
47
+ assert_equal("http://old-releases.ubuntu.com/ubuntu/dists/karmic-security/", helper.get_url("http://old-releases.ubuntu.com/ubuntu"))
48
+ end
49
+
50
+ # Assert that old entries move according to plan.
51
+ def test_multiverse_security
52
+ l = "deb-src http://security.ubuntu.com/ubuntu karmic-security main universe"
53
+ e = "deb-src http://old-releases.ubuntu.com/ubuntu karmic-security main universe"
54
+
55
+ helper = Apt::Repair::Sources.new(l)
56
+ assert_equal(e, helper.fix_line)
57
+ end
58
+ end
@@ -0,0 +1,11 @@
1
+ require 'test/unit'
2
+ require 'net/http'
3
+
4
+ class LearningRubyTest < Test::Unit::TestCase
5
+ def test_uri
6
+ u = URI('http://example.org/path?query=string')
7
+ u.host = 'example2.org'
8
+
9
+ assert_equal('http://example2.org/path?query=string', u.to_s)
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: apt-repair-sources
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Till Klampaeckel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-23 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: trollop
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 83
30
+ segments:
31
+ - 1
32
+ - 16
33
+ - 2
34
+ version: 1.16.2
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: test-unit
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 29
46
+ segments:
47
+ - 2
48
+ - 4
49
+ - 1
50
+ version: 2.4.1
51
+ type: :development
52
+ version_requirements: *id002
53
+ description: |+
54
+ A tool to clean up your sources.list:
55
+
56
+ * apt-repair-sources -d: let's you examine your current sources
57
+ * apt-repair-sources -f: attempts to fix them
58
+
59
+ apt-repair-sources checks the following locations:
60
+
61
+ * /etc/apt/sources.list
62
+ * /etc/apt/sources.list.d/*.list
63
+
64
+ email: till@php.net
65
+ executables:
66
+ - apt-repair-sources
67
+ extensions: []
68
+
69
+ extra_rdoc_files: []
70
+
71
+ files:
72
+ - bin/apt-repair-sources
73
+ - LICENSE
74
+ - README.md
75
+ - tests/AptRepairSourcesTest.rb
76
+ - tests/LearningRubyTest.rb
77
+ - apt-repair-sources.gemspec
78
+ - lib/apt/repair/sources.rb
79
+ - lib/apt/repair/sources/version.rb
80
+ has_rdoc: true
81
+ homepage: http://github.com/lagged/apt-repair-sources
82
+ licenses: []
83
+
84
+ post_install_message:
85
+ rdoc_options: []
86
+
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ requirements: []
108
+
109
+ rubyforge_project:
110
+ rubygems_version: 1.3.7
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: A tool to clean up your sources.list
114
+ test_files: []
115
+