Class: AptDownloader

Inherits:
Object
  • Object
show all
Defined in:
lib/apt_downloader.rb

Constant Summary collapse

VERSION =
'1.0.2'
VALID_DEBIAN_ARCHITECTURES =
%w[alpha amd64 arm armel hppa i386 ia64 mips
mipsel powerpc s390 sparc]
APT_FS_PATH =
"#{Dir::tmpdir}/apt_fs_#{$$}_"
DEFAULT_DEBIAN_SERVER_LIST =
['deb     http://security.debian.org/ testing/updates main contrib non-free',
 'deb-src http://security.debian.org/ testing/updates main contrib non-free',
 'deb     http://security.debian.org/ stable/updates main contrib non-free',
 'deb-src http://security.debian.org/ stable/updates main contrib non-free',
 # Main archives
 'deb     http://ftp.us.debian.org/debian/ stable main non-free contrib',
 'deb-src http://ftp.us.debian.org/debian/ stable main non-free contrib',
 'deb     http://ftp.us.debian.org/debian/ testing main non-free contrib',
 'deb-src http://ftp.us.debian.org/debian/ testing main non-free contrib',
 'deb     http://ftp.us.debian.org/debian/ unstable main non-free contrib',
 'deb-src http://ftp.us.debian.org/debian/ unstable main non-free contrib',

 'deb     http://ftp.us.debian.org/debian/ ' +
 'experimental main non-free contrib',

 'deb-src http://ftp.us.debian.org/debian/ ' +
 'experimental main non-free contrib',

 # --- debian-multimedia
 # deb http://www.debian-multimedia.org etch main'
 'deb http://www.debian-multimedia.org unstable main',
 'deb http://www.debian-multimedia.org testing main',
 'deb http://www.debian-multimedia.org experimental main',
 'deb-src http://www.debian-multimedia.org sid main',
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(architecture = 'armel', *packages) ⇒ AptDownloader

Returns a new instance of AptDownloader.



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/apt_downloader.rb', line 148

def initialize architecture='armel', *packages
  @packages         = []
  packages.each{ |package| addPackage package }

  @already_updated  = false
  @apt_config       = nil
  @apt_tmp_fs       = nil
  
  @architecture     = architecture
  @download_dir     = nil
  @extract_dir      = nil
  @sudo_extract     = false
  @dependencies     = []
  @suggestions      = []
  @all_dependencies = []
  @all_suggestions  = []
end

Instance Attribute Details

#apt_tmp_fsObject

Returns the value of attribute apt_tmp_fs.



91
92
93
# File 'lib/apt_downloader.rb', line 91

def apt_tmp_fs
  @apt_tmp_fs
end

#architectureObject

Returns the value of attribute architecture.



91
92
93
# File 'lib/apt_downloader.rb', line 91

def architecture
  @architecture
end

#download_dirObject

Returns the value of attribute download_dir.



91
92
93
# File 'lib/apt_downloader.rb', line 91

def download_dir
  @download_dir
end

#extract_dirObject

Returns the value of attribute extract_dir.



91
92
93
# File 'lib/apt_downloader.rb', line 91

def extract_dir
  @extract_dir
end

#packagesObject (readonly)

at this point packages once added can’t be deleted, until i implement apt-remove to get rid of them from apt-tmp-fs



97
98
99
# File 'lib/apt_downloader.rb', line 97

def packages
  @packages
end

#sudo_extractObject

Returns the value of attribute sudo_extract.



92
93
94
# File 'lib/apt_downloader.rb', line 92

def sudo_extract
  @sudo_extract
end

Class Method Details

.validPackage?(packageName) ⇒ Boolean

Returns true if packageName is a real debian package, and false otherwise

Returns:

  • (Boolean)


212
213
214
215
# File 'lib/apt_downloader.rb', line 212

def AptDownloader.validPackage? packageName
  result = %x[apt-cache pkgnames]
  result.split("\n").include?(packageName)
end

Instance Method Details

#_get_dependencies_backend(callword, searchword, recurse = false) ⇒ Object

internal use only



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/apt_downloader.rb', line 239

def _get_dependencies_backend callword, searchword, recurse=false
  unless @packages
    raise StandardError, "No packages set!"
  end
  dependencies = packages.map { |package|
    deps = %x[apt-cache #{recurse ? '--recurse' : ''} #{callword} #{package}]
    deps = deps.map{ |x|
      # get rid of coflicts/and other messages we aren't lookign for
      x = x.sub!(searchword, '') ? x.strip! : ''
      x = x.include?('|') ? '' : x
    }
  }
  dependencies.flatten!.uniq!
  dependencies.delete ''
  dependencies
end

#addPackage(package) ⇒ Object



226
227
228
# File 'lib/apt_downloader.rb', line 226

def addPackage(package)
  addPackages package
end

#addPackages(*packageNames) ⇒ Object



217
218
219
220
221
222
223
224
# File 'lib/apt_downloader.rb', line 217

def addPackages(*packageNames)
  packageNames.each { |name|
    unless AptDownloader::validPackage? name
      raise ArgumentError, "Package #{name} does not exist."
    end
    @packages << name
  }
end

#config_file_contentsObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/apt_downloader.rb', line 40

def config_file_contents
  return <<-EOS
APT "";
APT::Architecture "#{@architecture}";
APT::Build-Essential "";
APT::Build-Essential:: "build-essential";
APT::Install-Recommends "1";
APT::Install-Suggests "0";
APT::Acquire "";
APT::Acquire::Translation "environment";
APT::Authentication "";
APT::Authentication::TrustCDROM "true";
APT::NeverAutoRemove "";
APT::NeverAutoRemove:: "^linux-image.*";
APT::NeverAutoRemove:: "^linux-restricted-modules.*";
APT::Default-Release "testing";
APT::Cache-Limit "141943904";
Dir "#{APT_FS_PATH}/";
Dir::State "#{APT_FS_PATH}/var/lib/apt/";
Dir::State::lists "lists/";
Dir::State::cdroms "cdroms.list";
Dir::State::userstatus "status.user";
Dir::State::status "#{APT_FS_PATH}/var/lib/dpkg/status";
Dir::Cache "#{APT_FS_PATH}/var/cache/apt/";
Dir::Cache::archives "archives/";
Dir::Cache::srcpkgcache "srcpkgcache.bin";
Dir::Cache::pkgcache "pkgcache.bin";
Dir::Etc "etc/apt/";
Dir::Etc::sourcelist "sources.list";
Dir::Etc::sourceparts "sources.list.d";
Dir::Etc::vendorlist "vendors.list";
Dir::Etc::vendorparts "vendors.list.d";
Dir::Etc::main "apt.conf";
Dir::Etc::parts "apt.conf.d";
Dir::Etc::preferences "preferences";
Dir::Bin "";
Dir::Bin::methods "/usr/lib/apt/methods";
Dir::Bin::dpkg "/usr/bin/dpkg";
Dir::Log "#{APT_FS_PATH}/var/log/apt";
Dir::Log::Terminal "term.log";
DPkg "";
DPkg::Pre-Install-Pkgs "";
DPkg::Pre-Install-Pkgs:: "/usr/sbin/dpkg-preconfigure --apt || true";
DPkg::Post-Invoke "";
DPkg::Post-Invoke:: "if [ -x /usr/bin/debsums ]; then /usr/bin/debsums --generate=nocheck -sp /var/cache/apt/archives; fi";

EOS

end

#create_apt_fsObject

create a temprorary directory structure that imititates the parts of the linux filesystem that apt cares about



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/apt_downloader.rb', line 107

def create_apt_fs
  # create a temporary directory to do all downloads to
  @apt_tmp_fs = FileUtils.mkpath APT_FS_PATH

  %w[/etc/apt/
     /var/cache/apt/archives/partial
     /var/lib/apt/lists/partial
     /var/lib/dpkg/
    ].each{ |directory| FileUtils.mkpath(APT_FS_PATH + directory) }

  %w[/var/lib/dpkg/lock
     /var/lib/dpkg/status
     /var/lib/apt/lists/lock
     /etc/apt/sources.list
    ].each{ |file| FileUtils.touch(APT_FS_PATH + file) }

  File.open(APT_FS_PATH + "/etc/apt/sources.list",
            File::WRONLY |
            File::TRUNC |
            File::CREAT ) { |sources_file|
    DEFAULT_DEBIAN_SERVER_LIST.each{ |source| sources_file.puts source }
  }

  # set up directory for removal on program delete
  at_exit{ FileUtils.rm_rf APT_FS_PATH  }
end

#create_config_fileObject



99
100
101
102
103
# File 'lib/apt_downloader.rb', line 99

def create_config_file
  @apt_config = Tempfile.new 'config_file'
  @apt_config.sync = true
  @apt_config.write config_file_contents
end

#dependsObject



256
257
258
# File 'lib/apt_downloader.rb', line 256

def depends
  @dependencies = _get_dependencies_backend 'depends', 'Depends:'
end

#download(packages) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/apt_downloader.rb', line 135

def download packages
  call = "apt-get -c #{@apt_config.path} update"
  puts "** apt-downloader: #{call}"
  system(call) unless @already_updated

  @already_updated = true

  call = "apt-get -c #{@apt_config.path} --download-only " +
         "--assume-yes --force-yes install #{packages}"
  puts "\n** apt-downloader: #{call}"
  system(call)
end

#goObject



199
200
201
202
203
204
205
206
207
208
209
# File 'lib/apt_downloader.rb', line 199

def go
  create_config_file unless @apt_config
  create_apt_fs unless @apt_tmp_fs

  packages_string = ''
  packages.each{ |package| packages_string += package + ' ' }
  download packages_string

  _copy_debs_to @download_dir if (@download_dir)
  _extract_debs_to @extract_dir if(@extract_dir)
end

#recursiveDependsObject



264
265
266
# File 'lib/apt_downloader.rb', line 264

def recursiveDepends
  @all_dependencies = _get_dependencies_backend 'depends', 'Depends:', true
end

#recursiveSuggestsObject



268
269
270
# File 'lib/apt_downloader.rb', line 268

def recursiveSuggests
  @all_suggestions = _get_dependencies_backend 'depends', 'Suggests:', true
end

#suggestsObject



260
261
262
# File 'lib/apt_downloader.rb', line 260

def suggests
  @suggestions = _get_dependencies_backend 'depends', 'Suggests:'
end