AArch64: Ubuntu local partial mirror: Add arm64
[armband.git] / patches / opnfv-fuel / upstream-backports / 0003-f_repobuild-Use-packetary-to-build-partial-mirror.patch
1 From: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
2 Date: Wed, 6 Jul 2016 17:03:49 +0200
3 Subject: [PATCH] f_repobuild: Use packetary to build partial mirror
4
5 FIXME: DO NOT MERGE until [2, 3] are merged upstream & included here!
6 TODO: drop ALL fuel-mirror dependencies, for Fuel Newton compatibility.
7
8 Packetary [1] will replace fuel-mirror in upstream Fuel.
9 fuel-mirror is using packetary under the hood already, so the
10 transition should not be too hard.
11
12 Adapt OPNFV Ubuntu partial mirror build:
13 - obsolete opnfv-config.yaml (packetary uses CLI args for this);
14 - split old ubuntu.yaml into:
15   * mos_<arch>_mirror.yaml - MOS mirror cfg, only for deps analysis;
16   * ubuntu_<arch>_mirror.yaml - Ubuntu mirror cfg, for pkgs download;
17   * ubuntu_<arch>_packages.yaml - Ubuntu packages to download;
18
19 While the consumers of our mirror still use `debootstrap`, which only
20 supports the "main" repo component, make sure the "main" package set
21 is complete, in the scope of:
22   * ubuntu_<arch>_mirror_main.yaml - Ubuntu [main only] mirror;
23   * ubuntu_<arch>_packages_main.yaml - Ubuntu packages for [main];
24
25 New workflow (executed for EACH architecture):
26 1. Parse "fuel-mirror/contrib/fuel_mirror/data/ubuntu.yaml"
27    and write correponding sections to new yaml files described above;
28
29    NOTE: Since fuel-mirror is going to be made obsolete, there are a
30    number of new ways we can gather the data currently passed via
31    fuel-mirror's "ubuntu.yaml" (e.g. use "mos-repos" from Fuel ISO
32    to determine MOS dependencies).
33
34 2. Add OPNFV extra package dependencies (NEW)
35    Currently, this is empty / not used, but might be used to add
36    extra packages to the local mirror, like additional kernels,
37    bootloaders etc.
38
39    NOTE: Dependencies up to and including this group should also
40    be satisfiable from Ubuntu "main" repo component only.
41
42 3. Append plugin dependencies to the package list;
43
44 4. Run `packetary unresolved` for MOS repos, gathering MOS deps that
45    should be fetched from Ubuntu. The new packages will be appended
46    to the predefined list from old "ubuntu.yaml";
47
48 5. Run `packetary clone` to download all required pkgs for the
49    partial Ubuntu mirror.
50
51 6. IF repo component merging is disabled, run `packetary clone` only
52    on Ubuntu[main] repo components to download any (still) missing
53    dependencies for `debootstrap`, which only looks at this component,
54    and not the whole mirror.
55
56 7. IF repo component merging is enabled, run first `dpkg-scanpackages`
57    to filter out old duplicate versions of packages, then run
58    `packetary create` to merge all repo comps into a single "main".
59
60 v1 -> v2:
61 - multiarch support (activated via UBUNTU_ARCH envvar);
62 - fixed debootstrap missing deps in "main" component of Ubuntu mirror;
63 - factored out some hardcodes into variables/functions;
64 - add .gitignore file;
65 - move generated config files to "opnfv_config" subdir;
66 - added arm64 Ubuntu repo URL (ports.ubuntu.com is separated from the
67   main Ubuntu mirror, archive.ubuntu.com, which only holds x86 pkgs);
68
69 v3 -> v4:
70 - introduce env var "MIRROR_UBUNTU_MERGE" to control local mirror
71   repo-component merging into a single "main";
72 - enable mirror repo-component merging by default, edit
73   fuel_bootstrap_cli.yaml accordingly;
74
75 v4 -> v6:
76 - edit dea_base to use only main mirror;
77 - fix duplicated logs;
78 - remove `-q` flag for `create`;
79
80 NOTE: Without filtering out old package verisons using
81 `dpkg-scanpackages`, bootstrap build cannot solve all deps.
82
83 FIXME: Packetary solves missing dependecies by also accepting
84 different packages that provide the same package name (e.g. "ifupdown"
85 is satisfied by "netscript" package).
86
87 FIXME: Repo component merging is sort of slow, since packetary insists
88 on copying the source files to the destination dir even if they are
89 pointing to the same repo.
90
91 FIXME: Packetary `create` uses a different directory scheme for the
92 created mirror than the upstream Ubuntu, e.g.:
93 [p] mirrors/ubuntu/pool/main/l/lvm2_2.02.98-6ubuntu2_amd64.deb
94 [U] mirrors/ubuntu/pool/main/l/lvm2/lvm2_2.02.98-6ubuntu2_amd64.deb
95
96 This disencourages creating the "merged" mirror in the same location
97 as the source partial mirror.
98
99 [1] https://wiki.openstack.org/wiki/Packetary
100 [2] https://review.openstack.org/#/c/392936/
101 [3] https://review.openstack.org/#/c/392937/
102
103 JIRA: FUEL-218
104 JIRA: FUEL-223
105
106 Change-Id: If2ee86f348b7683c83bfaf686baba4f1b8f555f0
107 Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
108 ---
109  build/config.mk                                    |   5 +
110  build/f_isoroot/f_repobuild/.gitignore             |   4 +
111  build/f_isoroot/f_repobuild/Makefile               |  34 ++-
112  build/f_isoroot/f_repobuild/config.mk              |  26 +++
113  .../f_isoroot/f_repobuild/fuel_bootstrap_cli.yaml  |  14 +-
114  build/f_isoroot/f_repobuild/opnfv_mirror_conf.py   |  57 -----
115  build/f_isoroot/f_repobuild/opnfv_mirror_ubuntu.py | 246 +++++++++++++++++++++
116  build/f_isoroot/f_repobuild/opnfv_packages.yaml    |  14 ++
117  deploy/config/dea_base.yaml                        |  14 +-
118  9 files changed, 312 insertions(+), 102 deletions(-)
119  create mode 100644 build/f_isoroot/f_repobuild/.gitignore
120  create mode 100644 build/f_isoroot/f_repobuild/config.mk
121  delete mode 100755 build/f_isoroot/f_repobuild/opnfv_mirror_conf.py
122  create mode 100755 build/f_isoroot/f_repobuild/opnfv_mirror_ubuntu.py
123  create mode 100644 build/f_isoroot/f_repobuild/opnfv_packages.yaml
124
125 diff --git a/build/config.mk b/build/config.mk
126 index ab27858..a62b7e9 100644
127 --- a/build/config.mk
128 +++ b/build/config.mk
129 @@ -17,6 +17,11 @@ FUEL_MAIN_TAG = 9.0.1
130  MOS_VERSION   = 9.0
131  OPENSTACK_VERSION = mitaka-9.0
132  
133 +# List of space-separated Ubuntu architectures supported with current build
134 +# Format: same as `dpkg-architecture -qDEB_HOST_ARCH1`
135 +# NOTE: Currently only amd64 is supported by Fuel@OPNFV. Armband adds arm64.
136 +export UBUNTU_ARCH ?= amd64
137 +
138  # FIXME(alav): Disable remote tracking for now, stick to submodule commits
139  FUEL_TRACK_REMOTES =
140  
141 diff --git a/build/f_isoroot/f_repobuild/.gitignore b/build/f_isoroot/f_repobuild/.gitignore
142 new file mode 100644
143 index 0000000..cfedefb
144 --- /dev/null
145 +++ b/build/f_isoroot/f_repobuild/.gitignore
146 @@ -0,0 +1,4 @@
147 +packetary
148 +fuel-mirror
149 +nailgun
150 +opnfv_config
151 diff --git a/build/f_isoroot/f_repobuild/Makefile b/build/f_isoroot/f_repobuild/Makefile
152 index 8beb882..a47441c 100644
153 --- a/build/f_isoroot/f_repobuild/Makefile
154 +++ b/build/f_isoroot/f_repobuild/Makefile
155 @@ -1,7 +1,8 @@
156  ##############################################################################
157 -# Copyright (c) 2015 Ericsson AB and others.
158 +# Copyright (c) 2015,2016 Ericsson AB, Enea AB and others.
159  # stefan.k.berg@ericsson.com
160  # jonas.bjurel@ericsson.com
161 +# Alexandru.Avadanii@enea.com
162  # All rights reserved. This program and the accompanying materials
163  # are made available under the terms of the Apache License, Version 2.0
164  # which accompanies this distribution, and is available at
165 @@ -10,41 +11,36 @@
166  
167  SHELL := /bin/bash
168  TOP := $(shell pwd)
169 -TMP_ROOT_DIR := $(shell echo "$(MIRROR_UBUNTU_ROOT)" | cut -d "/" -f2)
170  
171  include ../../config.mk
172 +include config.mk
173  
174  export MOS_VERSION
175 -export OPENSTACK_VERSION
176 +export MIRROR_UBUNTU_OPNFV_PATH:=$(TOP)/nailgun/mirrors/ubuntu
177  
178  .PHONY: all
179  all: nailgun
180  
181  nailgun:
182 -       sudo apt-get install -y git libxml2-dev libxslt-dev python-dev  python-pip libz-dev libyaml-dev createrepo python-yaml
183 -       rm -Rf nailgun
184 -       sudo mkdir -p /var/www/nailgun
185 +       sudo apt-get install -y createrepo git libxml2-dev libxslt1-dev \
186 +               python-dev zlib1g-dev
187 +       rm -Rf nailgun packetary opnfv_config && mkdir opnfv_config
188         ln -sf ${F_SUBMOD_DIR}/fuel-mirror fuel-mirror
189 -       sudo pip install -U -r ./fuel-mirror/requirements.txt
190 -       sudo pip install ./fuel-mirror
191 -       sudo pip install ./fuel-mirror/contrib/fuel_mirror
192 -       ./opnfv_mirror_conf.py
193 -       sudo fuel-mirror --debug --config ./opnfv-config.yaml create --group ubuntu --pattern=ubuntu
194 -       sudo chmod -R 755 /var/www/nailgun
195 -       cp -Rp /var/www/nailgun .
196 -       # In the end we want to have ubuntu repository in mirrors/ubuntu directory
197 -       -if [ "$(MIRROR_UBUNTU_ROOT)" != "/ubuntu/" ]; then \
198 -         mkdir -p nailgun/mirrors/ubuntu;\
199 -         mv nailgun/mirrors$(MIRROR_UBUNTU_ROOT)* nailgun/mirrors/ubuntu;\
200 -         [ "$(MIRROR_UBUNTU_ROOT)" != "/" ] && rm -rf nailgun/mirrors/$(TMP_ROOT_DIR);\
201 +       git clone --quiet $(PACKETARY_REPO)
202 +       if [ -n $(PACKETARY_COMMIT) ]; then \
203 +               git -C packetary checkout $(PACKETARY_COMMIT); \
204         fi
205 +       sudo pip install -U -r ./packetary/requirements.txt
206 +       sudo pip install ./packetary
207 +       # Handle config and mirror build in one place
208 +       ./opnfv_mirror_ubuntu.py
209         # Store artifact in cache straight away if caching is enabled
210         # (no .cacheid will be present unless this is a cached build)
211         test -f .cacheid && $(MAKE) -f Makefile put-cache || exit 0
212  
213  .PHONY: clean
214  clean:
215 -       @rm -rf ../release/opnfv/nailgun nailgun fuel-mirror opnfv-config.yaml ubuntu.yaml
216 +       @rm -rf ../release/opnfv/nailgun nailgun packetary fuel-mirror opnfv_config
217  
218  .PHONY: release
219  release:nailgun
220 diff --git a/build/f_isoroot/f_repobuild/config.mk b/build/f_isoroot/f_repobuild/config.mk
221 new file mode 100644
222 index 0000000..79e7d1a
223 --- /dev/null
224 +++ b/build/f_isoroot/f_repobuild/config.mk
225 @@ -0,0 +1,26 @@
226 +##############################################################################
227 +# Copyright (c) 2016 Ericsson AB, Enea AB and others.
228 +# stefan.k.berg@ericsson.com
229 +# jonas.bjurel@ericsson.com
230 +# Alexandru.Avadanii@enea.com
231 +# All rights reserved. This program and the accompanying materials
232 +# are made available under the terms of the Apache License, Version 2.0
233 +# which accompanies this distribution, and is available at
234 +# http://www.apache.org/licenses/LICENSE-2.0
235 +##############################################################################
236 +
237 +# Use a recent master commit, since tags/branches are not yet mature
238 +# FIXME(armband): Update upstream commit ref once [1, 2] are merged
239 +# [1] https://review.openstack.org/#/c/392937/
240 +# [2] https://review.openstack.org/#/c/392936/
241 +export PACKETARY_REPO?=https://github.com/openstack/packetary
242 +export PACKETARY_COMMIT?=c46465c3255a9f5e59a05b8701e06054df39f32f
243 +
244 +# arm64 Ubuntu mirror is separated from archive.ubuntu.com
245 +export MIRROR_UBUNTU_URL_arm64=http://ports.ubuntu.com/ubuntu-ports/
246 +export MIRROR_UBUNTU_ROOT_arm64=ubuntu-ports
247 +
248 +# Merge all local mirror repo components/section into single "main"
249 +# NOTE: When changing this, make sure to also update all consumer config, like:
250 +# - fuel_bootstrap_cli.yaml
251 +export MIRROR_UBUNTU_MERGE=true
252 diff --git a/build/f_isoroot/f_repobuild/fuel_bootstrap_cli.yaml b/build/f_isoroot/f_repobuild/fuel_bootstrap_cli.yaml
253 index fcf4257..647dcb6 100644
254 --- a/build/f_isoroot/f_repobuild/fuel_bootstrap_cli.yaml
255 +++ b/build/f_isoroot/f_repobuild/fuel_bootstrap_cli.yaml
256 @@ -47,23 +47,11 @@
257    https_proxy: ""
258    repos:
259      - name: ubuntu
260 -      section: "main universe multiverse"
261 +      section: "main"
262        uri: "http://127.0.0.1:8080/mirrors/ubuntu"
263        priority:
264        suite: trusty
265        type: deb
266 -    - name: ubuntu-updates
267 -      section: "main universe multiverse"
268 -      uri: "http://127.0.0.1:8080/mirrors/ubuntu"
269 -      priority:
270 -      suite: trusty-updates
271 -      type: deb
272 -    - name: ubuntu-security
273 -      section: "main universe multiverse"
274 -      uri: "http://127.0.0.1:8080/mirrors/ubuntu"
275 -      priority:
276 -      suite: trusty-security
277 -      type: deb
278      - name: mos
279        section: "main restricted"
280        uri: "http://127.0.0.1:8080/ubuntu/x86_64"
281 diff --git a/build/f_isoroot/f_repobuild/opnfv_mirror_conf.py b/build/f_isoroot/f_repobuild/opnfv_mirror_conf.py
282 deleted file mode 100755
283 index 1c7eb59..0000000
284 --- a/build/f_isoroot/f_repobuild/opnfv_mirror_conf.py
285 +++ /dev/null
286 @@ -1,57 +0,0 @@
287 -#!/usr/bin/env python
288 -##############################################################################
289 -# Copyright (c) 2015 Ericsson AB and others.
290 -# mskalski@mirantis.com
291 -# All rights reserved. This program and the accompanying materials
292 -# are made available under the terms of the Apache License, Version 2.0
293 -# which accompanies this distribution, and is available at
294 -# http://www.apache.org/licenses/LICENSE-2.0
295 -##############################################################################
296 -import os
297 -import yaml
298 -
299 -current_snapshot =  os.environ["LATEST_TARGET_UBUNTU"]
300 -mos_version = os.environ['MOS_VERSION']
301 -openstack_version = os.environ['OPENSTACK_VERSION']
302 -mos_ubuntu = os.environ['MIRROR_MOS_UBUNTU']
303 -mos_ubuntu_root = os.environ['MIRROR_MOS_UBUNTU_ROOT']
304 -mirror_ubuntu = os.environ['MIRROR_UBUNTU_URL']
305 -if os.environ.get('BUILD_FUEL_PLUGINS'):
306 -  plugins = os.environ['BUILD_FUEL_PLUGINS']
307 -else:
308 -  plugins = os.environ['PLUGINS']
309 -
310 -
311 -configuration_file = open('fuel-mirror/contrib/fuel_mirror/etc/config.yaml').read()
312 -conf = yaml.load(configuration_file)
313 -conf['pattern_dir'] = '.'
314 -conf['openstack_version'] = openstack_version
315 -conf['mos_version'] = mos_version
316 -
317 -with open('opnfv-config.yaml', 'w') as outfile:
318 -  outfile.write( yaml.dump(conf, default_flow_style=False) )
319 -
320 -pattern_file = open('fuel-mirror/contrib/fuel_mirror/data/ubuntu.yaml').read()
321 -pattern = yaml.load(pattern_file)
322 -pattern['mos_baseurl'] = "http://{}{}".format(mos_ubuntu, mos_ubuntu_root)
323 -pattern['ubuntu_baseurl'] = mirror_ubuntu
324 -for group in pattern['groups']['mos']:
325 -  group['uri'] = pattern['mos_baseurl']
326 -for group in pattern['groups']['ubuntu']:
327 -  group['uri'] = pattern['ubuntu_baseurl']
328 -
329 -for plugin in plugins.split():
330 -  path = "../{}/packages.yaml".format(plugin)
331 -  if os.path.isfile(path):
332 -    f = open(path).read()
333 -    plugin_yaml = yaml.load(f)
334 -    plugin_set = set(plugin_yaml['packages'])
335 -    main_set = set(pattern['packages'])
336 -    new_packages = plugin_set - main_set
337 -    print "Plugin {} require new packages: {}".format(plugin, ', '.join(new_packages))
338 -    pattern['packages'] = pattern['packages'] + list(new_packages)
339 -
340 -pattern['requirements']['ubuntu'] = pattern['packages']
341 -
342 -with open('ubuntu.yaml', 'w') as outfile:
343 -  outfile.write( yaml.safe_dump(pattern, default_flow_style=False) )
344 diff --git a/build/f_isoroot/f_repobuild/opnfv_mirror_ubuntu.py b/build/f_isoroot/f_repobuild/opnfv_mirror_ubuntu.py
345 new file mode 100755
346 index 0000000..89ec938
347 --- /dev/null
348 +++ b/build/f_isoroot/f_repobuild/opnfv_mirror_ubuntu.py
349 @@ -0,0 +1,246 @@
350 +#!/usr/bin/env python
351 +##############################################################################
352 +# Copyright (c) 2015,2016 Ericsson AB, Mirantis Inc., Enea AB and others.
353 +# mskalski@mirantis.com
354 +# Alexandru.Avadanii@enea.com
355 +# All rights reserved. This program and the accompanying materials
356 +# are made available under the terms of the Apache License, Version 2.0
357 +# which accompanies this distribution, and is available at
358 +# http://www.apache.org/licenses/LICENSE-2.0
359 +##############################################################################
360 +
361 +##############################################################################
362 +# Build multiarch partial local Ubuntu mirror
363 +##############################################################################
364 +# Design quirks / workarounds:
365 +# 1. Fuel-agent uses `debootstrap` to build bootstrap and target chroots from
366 +#    the local mirror; which only uses the "main" component from the first
367 +#    repository, i.e. does not include "updates"/"security".
368 +#    In order to fullfill all debootstrap dependencies in "main" repo, we will
369 +#    do an extra packetary run using a reduced scope:
370 +#    - only "main" component of the first mirror;
371 +#    - reduced package dependency list (without MOS/OPNFV plugin deps).
372 +# 2. If repo structure is not mandatory to be in sync with official mirrors,
373 +#    we can mitigate the issue by "merging" all repo-components into a single
374 +#    "main".
375 +##############################################################################
376 +# Mirror build steps:
377 +# 1. Parse old <fuel-mirror> package list ("ubuntu.yaml");
378 +# 2. Parse new "opnfv_packages.yaml" list of additional packages;
379 +# 3. Inherit enviroment variable(s) for mirror URLs, paths etc.
380 +#    - Allow arch-specific overrides for each env var;
381 +# 4. For each architecture in UBUNTU_ARCH:
382 +# 4.1. Mirror config is defined based on common config + OPNFV overrides;
383 +#      - Convert old configuration format to packetary style where needed;
384 +# 4.2. Package lists are defined based on common config + OPNFV deps;
385 +#      - Keep track of "main" packages separately, required by debootstrap;
386 +# 4.3. Clone/update all mirror components;
387 +# 4.4. IF mirror merging is disabled OR workaround for ifupdown (see below):
388 +#      - Clone/update "main" mirror component (fix missing debootstrap deps);
389 +# 5. IF mirror merging is enabled:
390 +#    - Use `dpkg-scanpackages` to filter out old versions of duplicate pkgs;
391 +#    - Run `packetary create` on the set of downloaded packages, merging
392 +#      them on the fly into a single-component mirror;
393 +##############################################################################
394 +
395 +import copy
396 +import os
397 +import shutil
398 +import sys
399 +import yaml
400 +from contextlib import contextmanager
401 +from cStringIO import StringIO
402 +from packetary.cli.app import main
403 +
404 +@contextmanager
405 +def captureStdOut(output):
406 +    stdout = sys.stdout
407 +    sys.stdout = output
408 +    yield
409 +    sys.stdout = stdout
410 +
411 +# FIXME: Find a better approach for eliminating duplicate logs than this
412 +def force_logger_reload():
413 +  for mod in sys.modules.keys():
414 +    if mod.startswith('logging'):
415 +      try:
416 +        reload(sys.modules[mod])
417 +      except:
418 +        pass
419 +
420 +# Determine missing package dependecies for a mirror defition
421 +def get_unres_pkgs(arch, cfg_mirror):
422 +  unresolved = dict()
423 +  unresolved['packages'] = list()
424 +  packetary_output = StringIO()
425 +  with captureStdOut(packetary_output):
426 +    main('unresolved -a {0} -r {1} -c name version --sep ;'
427 +      .format(_ARCHITECTURES[arch], cfg_mirror).split(' '))
428 +  for dep_pkg in packetary_output.getvalue().splitlines():
429 +    if dep_pkg.startswith('#'):
430 +      continue
431 +    dep = dep_pkg.split(';')
432 +    unresolved['packages'] += [ {'name': dep[0], 'version': dep[1]} ]
433 +  force_logger_reload()
434 +  return unresolved
435 +
436 +# Create single-component local repo (one arch per call)
437 +def do_local_repo(arch, cfg_repo, cfg_packages_paths):
438 +  # Packetary does not use a global config file, so pass old settings here.
439 +  main('create -t deb -a {0} --repository {1} --package-files {2}'
440 +    ' --ignore-errors-num 2 --retries-num 3 --threads-num 10'
441 +    .format(_ARCHITECTURES[arch], cfg_repo, cfg_packages_paths).split(' '))
442 +  force_logger_reload()
443 +
444 +# Clone partial local mirror (one arch per call)
445 +def do_partial_mirror(arch, cfg_mirror, cfg_packages):
446 +  # Note: '-d .' is ignored, as each mirror defines its own path.
447 +  main('clone -t deb -a {0} -r {1} -R {2} -d .'
448 +    ' --ignore-errors-num 2 --retries-num 3 --threads-num 10'
449 +    .format(_ARCHITECTURES[arch], cfg_mirror, cfg_packages).split(' '))
450 +  force_logger_reload()
451 +
452 +# Write configuration (yaml) file (package list / mirror defition)
453 +def write_cfg_file(cfg_mirror, data):
454 +  with open(cfg_mirror, 'w') as outfile:
455 +    outfile.write( yaml.safe_dump(data, default_flow_style=False) )
456 +
457 +# Allow arch-specific overrides of env vars
458 +def get_env(env_var, arch=None):
459 +  if arch:
460 +    env_var_arch = '{0}_{1}'.format(env_var, arch)
461 +    if os.environ.get(env_var_arch):
462 +      return os.environ[env_var_arch]
463 +  if os.environ.get(env_var):
464 +    return os.environ[env_var]
465 +  return None
466 +
467 +# Architecture name mapping (dpkg:packetary) for packetary CLI invocation
468 +_ARCHITECTURES = {
469 +    "i386": "i386",
470 +    "amd64": "x86_64",
471 +    "arm64": "aarch64",
472 +}
473 +
474 +# Arch-indepedent configuration (old fuel-mirror + OPNFV extra packages)
475 +cfg_dir = 'opnfv_config'
476 +cfg_p_opnfv = 'opnfv_packages.yaml'
477 +mos_version = get_env('MOS_VERSION')
478 +ubuntu_arch = get_env('UBUNTU_ARCH')
479 +mirror_ubuntu_path = get_env('MIRROR_UBUNTU_OPNFV_PATH')
480 +mirror_ubuntu_tmp_path = '{0}.tmp'.format(mirror_ubuntu_path)
481 +mirror_ubuntu_merge = get_env('MIRROR_UBUNTU_MERGE')
482 +cfg_mm_ubuntu = '{0}/ubuntu_mirror_local.yaml'.format(cfg_dir)
483 +pattern_file = open('fuel-mirror/contrib/fuel_mirror/data/ubuntu.yaml').read()
484 +pattern = yaml.load(pattern_file)
485 +opnfv_pkgs_yaml = open(cfg_p_opnfv).read()
486 +opnfv_pkgs = yaml.load(opnfv_pkgs_yaml)
487 +
488 +# FIXME: Packetary solves missing dependecies by also accepting
489 +# different packages that provide the same name (e.g. "ifupdown" dependency
490 +# is satisfied by "netscript" package from "universe" repo-component).
491 +# Work around this by resolving all deps in "main" repo-component,
492 +# then scan and keep only latest debs for the whole <merged> repo.
493 +mirror_ubuntu_resolve_main_deps = True
494 +
495 +# Create local partial mirror using packetary, one arch at a time
496 +for arch in ubuntu_arch.split(' '):
497 +  # Mirror / Package env vars, arch-overrideable
498 +  mos_ubuntu = get_env('MIRROR_MOS_UBUNTU', arch)
499 +  mos_ubuntu_root = get_env('MIRROR_MOS_UBUNTU_ROOT', arch)
500 +  mirror_ubuntu = get_env('MIRROR_UBUNTU_URL', arch)
501 +  plugins = get_env('BUILD_FUEL_PLUGINS', arch)
502 +  if plugins is None:
503 +    plugins = get_env('PLUGINS', arch)
504 +
505 +  # Mirror / Package list configuration files (arch-specific)
506 +  cfg_m_mos = '{0}/mos_{1}_mirror.yaml'.format(cfg_dir, arch)
507 +  cfg_m_ubuntu = '{0}/ubuntu_{1}_mirror.yaml'.format(cfg_dir, arch)
508 +  cfg_p_ubuntu = '{0}/ubuntu_{1}_packages.yaml'.format(cfg_dir, arch)
509 +  cfg_m_ubuntu_main = '{0}/ubuntu_{1}_mirror_main.yaml'.format(cfg_dir, arch)
510 +  cfg_p_ubuntu_main = '{0}/ubuntu_{1}_packages_main.yaml'.format(cfg_dir, arch)
511 +
512 +  # Mirror config fork before customizing (arch-specific)
513 +  arch_group_mos = 'mos_{0}'.format(arch)
514 +  arch_group_ubuntu = 'ubuntu_{0}'.format(arch)
515 +  arch_packages = 'packages_{0}'.format(arch)
516 +  pattern['groups'][arch_group_mos] = copy.deepcopy(pattern['groups']['mos'])
517 +  pattern['groups'][arch_group_ubuntu] = copy.deepcopy(pattern['groups']['ubuntu'])
518 +  pattern[arch_packages] = pattern['packages']
519 +
520 +  # Mirror config update & conversion to packetary input
521 +  group_main_ubuntu = dict()
522 +  for group in pattern['groups'][arch_group_mos]:
523 +    group['uri'] = "http://{}{}".format(mos_ubuntu, mos_ubuntu_root)
524 +    group['suite'] = group['suite'].replace('$mos_version', mos_version)
525 +    group['section'] = group['section'].split()
526 +  for group in pattern['groups'][arch_group_ubuntu]:
527 +    group['uri'] = mirror_ubuntu
528 +    # FIXME: At `create`, packetary insists on copying all pkgs to dest dir,
529 +    # so configure it for another dir, which will replace the orig at the end.
530 +    group['path'] = mirror_ubuntu_tmp_path
531 +    group['section'] = group['section'].split()
532 +    if not group_main_ubuntu and 'main' in group:
533 +      group_main_ubuntu = [ copy.deepcopy(group) ]
534 +      group_main_ubuntu[0]['section'] = [ 'main' ]
535 +
536 +  # Mirror config dump: MOS (for dep resolution), Ubuntu, Ubuntu[main]
537 +  write_cfg_file(cfg_m_mos, pattern['groups'][arch_group_mos])
538 +  write_cfg_file(cfg_m_ubuntu, pattern['groups'][arch_group_ubuntu])
539 +  if mirror_ubuntu_resolve_main_deps or mirror_ubuntu_merge is None:
540 +    write_cfg_file(cfg_m_ubuntu_main, group_main_ubuntu)
541 +  if mirror_ubuntu_merge is not None:
542 +    # FIXME: For multiarch, only one dump would be enough
543 +    group_main_ubuntu[0]['origin'] = 'Ubuntu'
544 +    group_main_ubuntu[0]['path'] = mirror_ubuntu_path
545 +    group_main_ubuntu[0]['uri'] = mirror_ubuntu_path
546 +    write_cfg_file(cfg_mm_ubuntu, group_main_ubuntu[0])
547 +
548 +  # Package list conversion from `old fuel-mirror` to `packetary` style + OPNFV
549 +  unresolved_pkgs = dict()
550 +  unresolved_pkgs['packages'] = list()
551 +  unresolved_pkgs['mandatory'] = 'exact'
552 +  if opnfv_pkgs['packages'] is not None:
553 +    unresolved_pkgs['packages'] = opnfv_pkgs['packages']
554 +  for pkg in pattern['packages']:
555 +    unresolved_pkgs['packages'] += [ {'name': pkg} ]
556 +
557 +  # Package list (reduced, i.e. no MOS/OPNFV plugin deps)
558 +  if mirror_ubuntu_resolve_main_deps or mirror_ubuntu_merge is None:
559 +    write_cfg_file(cfg_p_ubuntu_main, unresolved_pkgs)
560 +
561 +  # OPNFV plugins dependency resolution
562 +  for plugin in plugins.split():
563 +    path = "../{}/packages.yaml".format(plugin)
564 +    if os.path.isfile(path):
565 +      f = open(path).read()
566 +      plugin_yaml = yaml.load(f)
567 +      plugin_set = set(plugin_yaml['packages'])
568 +      main_set = set(pattern['packages'])
569 +      new_packages = plugin_set - main_set
570 +      print('Plugin {0} requires new packages for arch [{1}]: {2}'
571 +            .format(plugin, arch, ', '.join(new_packages)))
572 +      for pkg in new_packages:
573 +        unresolved_pkgs['packages'] += [ {'name': pkg} ]
574 +
575 +  # Mirror package list (full, including MOS/OPNFV plugin deps)
576 +  unresolved_pkgs['packages'] += get_unres_pkgs(arch, cfg_m_mos)['packages']
577 +  write_cfg_file(cfg_p_ubuntu, unresolved_pkgs)
578 +  do_partial_mirror(arch, cfg_m_ubuntu, cfg_p_ubuntu)
579 +  if mirror_ubuntu_resolve_main_deps or mirror_ubuntu_merge is None:
580 +    # Ubuntu[main] must be evaluated after Ubuntu
581 +    do_partial_mirror(arch, cfg_m_ubuntu_main, cfg_p_ubuntu_main)
582 +
583 +if mirror_ubuntu_merge is None:
584 +  shutil.move(mirror_ubuntu_tmp_path, mirror_ubuntu_path)
585 +else:
586 +  # Construct single-component mirror from all components
587 +  for arch in ubuntu_arch.split(' '):
588 +    cfg_pp_ubuntu = '{0}/ubuntu_{1}_packages_paths.yaml'.format(cfg_dir, arch)
589 +    # FIXME: We need scanpackages to omit older DEBs
590 +    # Inspired from http://askubuntu.com/questions/198474/
591 +    os.system('dpkg-scanpackages -a {0} {1} 2>/dev/null | '
592 +      'grep -e "^Filename:" | sed "s|Filename: |- file://|g" > {2}'
593 +        .format(arch, mirror_ubuntu_tmp_path, cfg_pp_ubuntu))
594 +    do_local_repo(arch, cfg_mm_ubuntu, cfg_pp_ubuntu)
595 +  shutil.rmtree(mirror_ubuntu_tmp_path)
596 diff --git a/build/f_isoroot/f_repobuild/opnfv_packages.yaml b/build/f_isoroot/f_repobuild/opnfv_packages.yaml
597 new file mode 100644
598 index 0000000..3f5c59f
599 --- /dev/null
600 +++ b/build/f_isoroot/f_repobuild/opnfv_packages.yaml
601 @@ -0,0 +1,14 @@
602 +##############################################################################
603 +# Copyright (c) 2016 Enea AB and others.
604 +# Alexandru.Avadanii@enea.com
605 +# All rights reserved. This program and the accompanying materials
606 +# are made available under the terms of the Apache License, Version 2.0
607 +# which accompanies this distribution, and is available at
608 +# http://www.apache.org/licenses/LICENSE-2.0
609 +##############################################################################
610 +
611 +# This file lists packages that should be present in the local Ubuntu mirror,
612 +# but are not direct dependencies of any other packages from  MOS or Ubuntu.
613 +# e.g.: additional kernels, bootloaders etc.
614 +
615 +packages:
616 diff --git a/deploy/config/dea_base.yaml b/deploy/config/dea_base.yaml
617 index c1a0606..786c231 100644
618 --- a/deploy/config/dea_base.yaml
619 +++ b/deploy/config/dea_base.yaml
620 @@ -633,22 +633,10 @@ settings:
621          value:
622          - name: ubuntu
623            priority: null
624 -          section: main universe multiverse
625 +          section: main
626            suite: trusty
627            type: deb
628            uri: http://10.20.0.2:8080/mirrors/ubuntu/
629 -        - name: ubuntu-updates
630 -          priority: null
631 -          section: main universe multiverse
632 -          suite: trusty-updates
633 -          type: deb
634 -          uri: http://10.20.0.2:8080/mirrors/ubuntu/
635 -        - name: ubuntu-security
636 -          priority: null
637 -          section: main universe multiverse
638 -          suite: trusty-security
639 -          type: deb
640 -          uri: http://10.20.0.2:8080/mirrors/ubuntu/
641          - name: mos
642            priority: 1050
643            section: main restricted