133
def apt_cache(in_memory=True):
134
"""Build and return an apt cache"""
138
apt_pkg.config.set("Dir::Cache::pkgcache", "")
139
apt_pkg.config.set("Dir::Cache::srcpkgcache", "")
140
return apt_pkg.Cache()
139
143
def apt_install(packages, options=None, fatal=False):
140
144
"""Install one or more packages"""
141
145
if options is None:
203
207
def add_source(source, key=None):
208
"""Add a package source to this system.
210
@param source: a URL or sources.list entry, as supported by
211
add-apt-repository(1). Examples:
213
deb https://stub:key@private.example.com/ubuntu trusty main
216
'proposed:' may be used to enable the standard 'proposed'
217
pocket for the release.
218
'cloud:' may be used to activate official cloud archive pockets,
219
such as 'cloud:icehouse'
221
@param key: A key to be added to the system's APT keyring and used
222
to verify the signatures on packages. Ideally, this should be an
223
ASCII format GPG public key including the block headers. A GPG key
224
id may also be used, but be aware that only insecure protocols are
225
available to retrieve the actual public key from a public keyserver
226
placing your Juju environment at risk. ppa and cloud archive keys
227
are securely added automtically, so sould not be provided.
204
229
if source is None:
205
230
log('Source is not present. Skipping')
225
250
release = lsb_release()['DISTRIB_CODENAME']
226
251
with open('/etc/apt/sources.list.d/proposed.list', 'w') as apt:
227
252
apt.write(PROPOSED_POCKET.format(release))
254
raise SourceConfigError("Unknown source: {!r}".format(source))
229
subprocess.check_call(['apt-key', 'adv', '--keyserver',
230
'hkp://keyserver.ubuntu.com:80', '--recv',
257
if '-----BEGIN PGP PUBLIC KEY BLOCK-----' in key:
258
with NamedTemporaryFile() as key_file:
262
subprocess.check_call(['apt-key', 'add', '-'], stdin=key_file)
264
# Note that hkp: is in no way a secure protocol. Using a
265
# GPG key id is pointless from a security POV unless you
266
# absolutely trust your network and DNS.
267
subprocess.check_call(['apt-key', 'adv', '--keyserver',
268
'hkp://keyserver.ubuntu.com:80', '--recv',
234
272
def configure_sources(update=False,
235
273
sources_var='install_sources',
236
274
keys_var='install_keys'):
238
Configure multiple sources from charm configuration
276
Configure multiple sources from charm configuration.
278
The lists are encoded as yaml fragments in the configuration.
279
The frament needs to be included as a string. Sources and their
280
corresponding keys are of the types supported by add_source().
243
285
- "http://example.com/repo precise main"
248
290
Note that 'null' (a.k.a. None) should not be quoted.
250
sources = safe_load(config(sources_var))
251
keys = config(keys_var)
253
keys = safe_load(keys)
254
if isinstance(sources, basestring) and (
255
keys is None or isinstance(keys, basestring)):
256
add_source(sources, keys)
292
sources = safe_load((config(sources_var) or '').strip()) or []
293
keys = safe_load((config(keys_var) or '').strip()) or None
295
if isinstance(sources, basestring):
299
for source in sources:
300
add_source(source, None)
258
if not len(sources) == len(keys):
259
msg = 'Install sources and keys lists are different lengths'
260
raise SourceConfigError(msg)
261
for src_num in range(len(sources)):
262
add_source(sources[src_num], keys[src_num])
302
if isinstance(keys, basestring):
305
if len(sources) != len(keys):
306
raise SourceConfigError(
307
'Install sources and keys lists are different lengths')
308
for source, key in zip(sources, keys):
309
add_source(source, key)
264
311
apt_update(fatal=True)