From 32ca1f64ab42f238478d1626eb7dd8f488784500 Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Wed, 18 Dec 2019 09:42:48 +0100 Subject: [PATCH] Retire repository Fuel (from openstack namespace) and fuel-ccp (in x namespace) repositories are unused and ready to retire. This change removes all content from the repository and adds the usual README file to point out that the repository is retired following the process from https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project See also http://lists.openstack.org/pipermail/openstack-discuss/2019-December/011647.html Depends-On: https://review.opendev.org/699362 Change-Id: I274ce8f03b58ad770221219c197336055e263d38 --- .gitignore | 26 -- 00-debmirror.patch | 13 - LICENSE | 176 -------- MAINTAINERS | 67 --- Makefile | 75 ---- README.md | 41 -- README.rst | 10 + config.mk | 202 --------- fuel-release/RPM-GPG-KEY-mos | 30 -- fuel-release/mos-os.repo | 8 - fuel-release/mos-security.repo | 8 - fuel-release/mos-updates.repo | 8 - fuel-release/override_rpm_repos.py | 55 --- iso/.discinfo | 4 - iso/.treeinfo | 20 - iso/bootstrap_admin_node.sh | 592 ------------------------- iso/fix_default_repos.py | 206 --------- iso/isolinux/isolinux.cfg | 27 -- iso/isolinux/splash.jpg | Bin 141168 -> 0 bytes iso/ks.py | 85 ---- iso/ks.template | 531 ---------------------- iso/ks.yaml | 1 - iso/module.mk | 199 --------- mirror/centos/boot.mk | 46 -- mirror/centos/extra-repos.mk | 35 -- mirror/centos/module.mk | 23 - mirror/centos/mos-repo.mk | 18 - mirror/centos/repo.mk | 190 -------- mirror/centos/yum-priorities-plugin.py | 226 ---------- mirror/centos/yum_repos.mk | 144 ------ mirror/centos/yumdownloader-deps.patch | 25 -- mirror/module.mk | 22 - mirror/ubuntu/module.mk | 100 ----- packages/deb/genpkgnames.pl | 14 - packages/deb/module.mk | 81 ---- packages/module.mk | 108 ----- packages/rpm/genpkgnames.py | 6 - packages/rpm/module.mk | 109 ----- prepare-build-env.sh | 57 --- report-changelog.sh | 28 -- repos.mk | 56 --- requirements-fuel-rpm.txt | 26 -- requirements-rpm.txt | 276 ------------ rules.mk | 46 -- sandbox.mk | 268 ----------- specs/fuel-main.spec | 105 ----- 46 files changed, 10 insertions(+), 4383 deletions(-) delete mode 100644 .gitignore delete mode 100644 00-debmirror.patch delete mode 100644 LICENSE delete mode 100644 MAINTAINERS delete mode 100644 Makefile delete mode 100644 README.md create mode 100644 README.rst delete mode 100644 config.mk delete mode 100644 fuel-release/RPM-GPG-KEY-mos delete mode 100644 fuel-release/mos-os.repo delete mode 100644 fuel-release/mos-security.repo delete mode 100644 fuel-release/mos-updates.repo delete mode 100755 fuel-release/override_rpm_repos.py delete mode 100644 iso/.discinfo delete mode 100644 iso/.treeinfo delete mode 100755 iso/bootstrap_admin_node.sh delete mode 100755 iso/fix_default_repos.py delete mode 100644 iso/isolinux/isolinux.cfg delete mode 100644 iso/isolinux/splash.jpg delete mode 100644 iso/ks.py delete mode 100644 iso/ks.template delete mode 100644 iso/ks.yaml delete mode 100644 iso/module.mk delete mode 100644 mirror/centos/boot.mk delete mode 100644 mirror/centos/extra-repos.mk delete mode 100644 mirror/centos/module.mk delete mode 100644 mirror/centos/mos-repo.mk delete mode 100644 mirror/centos/repo.mk delete mode 100644 mirror/centos/yum-priorities-plugin.py delete mode 100644 mirror/centos/yum_repos.mk delete mode 100644 mirror/centos/yumdownloader-deps.patch delete mode 100644 mirror/module.mk delete mode 100644 mirror/ubuntu/module.mk delete mode 100644 packages/deb/genpkgnames.pl delete mode 100644 packages/deb/module.mk delete mode 100644 packages/module.mk delete mode 100644 packages/rpm/genpkgnames.py delete mode 100644 packages/rpm/module.mk delete mode 100755 prepare-build-env.sh delete mode 100755 report-changelog.sh delete mode 100644 repos.mk delete mode 100644 requirements-fuel-rpm.txt delete mode 100644 requirements-rpm.txt delete mode 100644 rules.mk delete mode 100644 sandbox.mk delete mode 100644 specs/fuel-main.spec diff --git a/.gitignore b/.gitignore deleted file mode 100644 index ccfa5178a..000000000 --- a/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -*.pyc -*.sqlite - -*.gem - -# vim swap files -.*.swp - -# services' runtime files -*.log -*.pid - -# Vagrant housekeeping file -/.vagrant - -/build -/local_mirror -nosetests.xml -nailgun.log -lock - -.idea -.DS_Store - -Nailgun.egg-info -repomd.xml* diff --git a/00-debmirror.patch b/00-debmirror.patch deleted file mode 100644 index 46302cbfc..000000000 --- a/00-debmirror.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/debmirror b/debmirror -index 0c2543c..f2fdd61 100755 ---- a/debmirror -+++ b/debmirror -@@ -2116,7 +2116,7 @@ sub name_release { - - if ($origin eq "none") { - $codename = $dist_raw; -- } elsif ($origin eq "Ubuntu" or $origin eq "Canonical") { -+ } elsif ($origin eq "Ubuntu" or $origin eq "Canonical" or $origin eq "Mirantis") { - if ($suite) { - say("Ubuntu Release file: using Suite ($suite)."); - $codename = $suite; diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 68c771a09..000000000 --- a/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - diff --git a/MAINTAINERS b/MAINTAINERS deleted file mode 100644 index 809568b78..000000000 --- a/MAINTAINERS +++ /dev/null @@ -1,67 +0,0 @@ ---- -description: - For Fuel team structure and contribution policy, see [1]. - - This is repository level MAINTAINERS file. All contributions to this - repository must be approved by one or more Core Reviewers [2]. - If you are contributing to files (or create new directories) in - root folder of this repository, please contact Core Reviewers for - review and merge requests. - - If you are contributing to subfolders of this repository, please - check 'maintainers' section of this file in order to find maintainers - for those specific modules. - - It is mandatory to get +1 from one or more maintainers before asking - Core Reviewers for review/merge in order to decrease a load on Core Reviewers [3]. - Exceptions are when maintainers are actually cores, or when maintainers - are not available for some reason (e.g. on vacation). - - [1] https://specs.openstack.org/openstack/fuel-specs/policy/team-structure - [2] https://review.openstack.org/#/admin/groups/659,members - [3] http://lists.openstack.org/pipermail/openstack-dev/2015-August/072406.html - - Please keep this file in YAML format in order to allow helper scripts - to read this as a configuration data. - -maintainers: - -- ./: - - - name: Alexei Sheplyakov - email: asheplyakov@mirantis.com - IRC: asheplyakov - - - name: Sergey Kulanov - email: skulanov@mirantis.com - IRC: sergk - - - name: Vitaly Parakhin - email: vparakhin@mirantis.com - IRC: brain461 - -- specs/: - - - name: Mikhail Ivanov - email: mivanov@mirantis.com - IRC: mivanov - - - name: Artem Silenkov - email: asilenkov@mirantis.com - IRC: asilenkov - - - name: Alexander Tsamutali - email: atsamutali@mirantis.com - IRC: astsmtl - - - name: Daniil Trishkin - email: dtrishkin@mirantis.com - IRC: dtrishkin - - - name: Ivan Udovichenko - email: iudovichenko@mirantis.com - IRC: tlbr - - - name: Igor Yozhikov - email: iyozhikov@mirantis.com - IRC: IgorYozhikov diff --git a/Makefile b/Makefile deleted file mode 100644 index d0be41cd1..000000000 --- a/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -.PHONY: all clean help deep_clean - -help: - @echo 'Build directives (can be overrided by environment variables' - @echo 'or by command line parameters):' - @echo ' SOURCE_DIR: $(SOURCE_DIR)' - @echo ' BUILD_DIR: $(BUILD_DIR)' - @echo ' LOCAL_MIRROR: $(LOCAL_MIRROR)' - @echo ' YUM_REPOS: $(YUM_REPOS)' - @echo ' MIRROR_CENTOS: $(MIRROR_CENTOS)' - @echo ' EXTRA_RPM_REPOS: $(EXTRA_RPM_REPOS)' - @echo ' EXTRA_DEB_REPOS: $(EXTRA_DEB_REPOS)' - @echo ' ISO_DIR/ISO_NAME: $(ISO_PATH)' - @echo ' ENV_NAME: $(ENV_NAME)' - @echo ' KSYAML: $(KSYAML)' - @echo - @echo 'Available targets:' - @echo ' all - build product' - @echo ' iso - build iso image' - @echo ' clean - remove build directory and resetting .done flags' - @echo ' deep_clean - clean + removing $(LOCAL_MIRROR) directory' - @echo - @echo 'To build system using one of the proprietary mirrors use ' - @echo 'the following commands:' - @echo - @echo 'Saratov office (default):' - @echo 'make iso' - @echo - @echo 'Moscow office:' - @echo 'make iso USE_MIRROR=msk' - @echo - @echo 'Custom location:' - @echo 'make iso YUM_REPOS=proprietary MIRROR_CENTOS=http:///centos' - @echo - @echo 'Extra RPM repos:' - @echo 'make iso EXTRA_RPM_REPOS=",http:// ,ftp://"' - @echo - @echo 'Extra DEB repos:' - @echo 'make iso EXTRA_DEB_REPOS="http:///ubuntu /|ftp:// precise main"' - @echo - -# Path to the sources. -# Default value: directory with Makefile -SOURCE_DIR?=$(dir $(lastword $(MAKEFILE_LIST))) -SOURCE_DIR:=$(abspath $(SOURCE_DIR)) - -all: iso - -clean: - sudo rm -rf $(BUILD_DIR) -deep_clean: clean - sudo rm -rf $(LOCAL_MIRROR) - -vbox-scripts: - echo "Target is deprecated. Virtualbox scripts have been moved to http://git.openstack.org/openstack/fuel-virtualbox.git" - -# Common configuration file. -include $(SOURCE_DIR)/config.mk - -.PHONY: current-version -current-version: $(BUILD_DIR)/current_version -$(BUILD_DIR)/current_version: $(call depv,CURRENT_VERSION) - echo $(CURRENT_VERSION) > $@ - -# Macroses for make -include $(SOURCE_DIR)/rules.mk - -# Sandbox macroses. -include $(SOURCE_DIR)/sandbox.mk - -# Modules -include $(SOURCE_DIR)/repos.mk -include $(SOURCE_DIR)/mirror/module.mk -include $(SOURCE_DIR)/packages/module.mk -include $(SOURCE_DIR)/iso/module.mk diff --git a/README.md b/README.md deleted file mode 100644 index 896e0ee41..000000000 --- a/README.md +++ /dev/null @@ -1,41 +0,0 @@ -Team and repository tags -======================== - -[![Team and repository tags](http://governance.openstack.org/badges/fuel-main.svg)](http://governance.openstack.org/reference/tags/index.html) - - - -FUEL -==== - -This git repository contains Fuel ISO build scripts. - -Directory structure: -- ```fuel-bootstrap-image``` - Scripts which allow us to build Ubuntu based bootstrap ramdisk on the - Fuel master node in runtime. The status of this ramdisk is experimental. -- ```iso``` - Scripts that are used for building Fuel ISO. -- ```mirror``` - Scripts to build local mirrors that are used for building chroot environments, bootstrap and - target images, etc. -- ```packages``` - Scripts that are used for building Fuel RPM and DEB packages. -- ```specs``` - RPM spec for fuel and fuel-release packages. -- ```utils``` - Auxiliary scripts. (being deprecated) -- ```Makefile``` - It is the main GNU Make file which includes all other necessary GNU Make files. -- ```config.mk``` - The file where the whole build process is parametrized. -- ```prepare-build-env.sh``` - The script installs all necessary packages that are needed for the build process. Currently - only Ubuntu 14.04 is supported. -- ```repos.mk``` - The script which downloads git repositories that are needed for the build process. -- ```requirements-rpm.txt``` - This file is used when building local RPM mirror. All RPM packages that are needed for Fuel - are listed here. -- ```sandbox.mk``` - The script that is used for building chroot environments. diff --git a/README.rst b/README.rst new file mode 100644 index 000000000..86e34d67c --- /dev/null +++ b/README.rst @@ -0,0 +1,10 @@ +This project is no longer maintained. + +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". + +For any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/config.mk b/config.mk deleted file mode 100644 index b35073155..000000000 --- a/config.mk +++ /dev/null @@ -1,202 +0,0 @@ -# -# Build directives. Can be overrided by environment variables. -# - -# Base path for build and mirror directories. -# Default value: current directory -TOP_DIR?=$(PWD) -TOP_DIR:=$(abspath $(TOP_DIR)) -# Working build directory -BUILD_DIR?=$(TOP_DIR)/build -BUILD_DIR:=$(abspath $(BUILD_DIR)) -# Path for build artifacts -ARTS_DIR?=$(BUILD_DIR)/artifacts -ARTS_DIR:=$(abspath $(ARTS_DIR)) -# Path for cache of downloaded packages -LOCAL_MIRROR?=$(TOP_DIR)/local_mirror -LOCAL_MIRROR:=$(abspath $(LOCAL_MIRROR)) - -PRODUCT_VERSION?=10.0 - -# This variable is used for naming of auxillary objects -# related to product: repositories, mirrors etc -PRODUCT_NAME:=mos - -CURRENT_VERSION:=$(PRODUCT_VERSION) - -PACKAGE_VERSION?=10.0.0 -FUEL_LIBRARY_VERSION?=10.0 - -# Artifacts names -ISO_NAME?=fuel-$(PRODUCT_VERSION) - -# Where we put artifacts -ISO_PATH:=$(ARTS_DIR)/$(ISO_NAME).iso - -MASTER_IP?=10.20.0.2 -MASTER_DNS?=10.20.0.1 -MASTER_NETMASK?=255.255.255.0 -MASTER_GW?=10.20.0.1 - -CENTOS_MAJOR?=7 -CENTOS_RELEASE:=$(CENTOS_MAJOR) -CENTOS_ARCH:=x86_64 - -UBUNTU_RELEASE?=xenial -UBUNTU_MAJOR?=16 -UBUNTU_MINOR?=04 -UBUNTU_RELEASE_NUMBER:=$(UBUNTU_MAJOR).$(UBUNTU_MINOR) -UBUNTU_KERNEL_FLAVOR?=lts-xenial -UBUNTU_NETBOOT_FLAVOR?=netboot -UBUNTU_ARCH:=amd64 -UBUNTU_IMAGE_RELEASE:=$(UBUNTU_MAJOR)$(UBUNTU_MINOR) -SEPARATE_IMAGES?=/boot,ext2 /,ext4 - -# Rebuld packages locally (do not use upstream versions) -BUILD_PACKAGES?=1 - -# by default we are not allowed to downgrade rpm packages, -# setting this flag to 0 will cause to use repo priorities only (!) -DENY_RPM_DOWNGRADE?=1 - -# Do not compress javascript and css files -NO_UI_OPTIMIZE:=0 - -# Repos and versions -FUELLIB_COMMIT?=master -NAILGUN_COMMIT?=master -PYTHON_FUELCLIENT_COMMIT?=master -FUEL_AGENT_COMMIT?=master -FUEL_NAILGUN_AGENT_COMMIT?=master -ASTUTE_COMMIT?=master -OSTF_COMMIT?=master -FUEL_MIRROR_COMMIT?=master -FUELMENU_COMMIT?=master -SHOTGUN_COMMIT?=master -NETWORKCHECKER_COMMIT?=master -FUELUPGRADE_COMMIT?=master -FUEL_UI_COMMIT?=master - -FUELLIB_REPO?=https://github.com/openstack/fuel-library.git -NAILGUN_REPO?=https://github.com/openstack/fuel-web.git -PYTHON_FUELCLIENT_REPO?=https://github.com/openstack/python-fuelclient.git -FUEL_AGENT_REPO?=https://github.com/openstack/fuel-agent.git -FUEL_NAILGUN_AGENT_REPO?=https://github.com/openstack/fuel-nailgun-agent.git -ASTUTE_REPO?=https://github.com/openstack/fuel-astute.git -OSTF_REPO?=https://github.com/openstack/fuel-ostf.git -FUELMENU_REPO?=https://github.com/openstack/fuel-menu.git -SHOTGUN_REPO?=https://github.com/openstack/shotgun.git -NETWORKCHECKER_REPO?=https://github.com/openstack/network-checker.git -FUEL_UI_REPO?=https://github.com/openstack/fuel-ui.git - -# Gerrit URLs and commits -FUELLIB_GERRIT_URL?=https://review.openstack.org/openstack/fuel-library -NAILGUN_GERRIT_URL?=https://review.openstack.org/openstack/fuel-web -PYTHON_FUELCLIENT_GERRIT_URL?=https://review.openstack.org/openstack/python-fuelclient -FUEL_AGENT_GERRIT_URL?=https://review.openstack.org/openstack/fuel-agent -FUEL_NAILGUN_AGENT_GERRIT_URL?=https://review.openstack.org/openstack/fuel-nailgun-agent -ASTUTE_GERRIT_URL?=https://review.openstack.org/openstack/fuel-astute -OSTF_GERRIT_URL?=https://review.openstack.org/openstack/fuel-ostf -FUELMENU_GERRIT_URL?=https://review.openstack.org/openstack/fuel-menu -SHOTGUN_GERRIT_URL?=https://review.openstack.org/openstack/shotgun -NETWORKCHECKER_GERRIT_URL?=https://review.openstack.org/openstack/network-checker -FUEL_UI_GERRIT_URL?=https://review.openstack.org/openstack/fuel-ui - -FUELLIB_GERRIT_COMMIT?=none -NAILGUN_GERRIT_COMMIT?=none -PYTHON_FUELCLIENT_GERRIT_COMMIT?=none -FUEL_AGENT_GERRIT_COMMIT?=none -FUEL_NAILGUN_AGENT_GERRIT_COMMIT?=none -ASTUTE_GERRIT_COMMIT?=none -OSTF_GERRIT_COMMIT?=none -FUELMAIN_GERRIT_COMMIT?=none -FUELMENU_GERRIT_COMMIT?=none -SHOTGUN_GERRIT_COMMIT?=none -NETWORKCHECKER_GERRIT_COMMIT?=none -FUEL_UI_GERRIT_COMMIT?=none - -LOCAL_MIRROR_CENTOS:=$(LOCAL_MIRROR)/centos -LOCAL_MIRROR_CENTOS_OS_BASEURL:=$(LOCAL_MIRROR_CENTOS)/os/$(CENTOS_ARCH) -LOCAL_MIRROR_MOS_CENTOS:=$(LOCAL_MIRROR)/mos-centos -LOCAL_MIRROR_MOS_CENTOS_OS_BASEURL:=$(LOCAL_MIRROR_MOS_CENTOS) -LOCAL_MIRROR_UBUNTU:=$(LOCAL_MIRROR)/ubuntu -LOCAL_MIRROR_UBUNTU_OS_BASEURL:=$(LOCAL_MIRROR_UBUNTU) - -# Use mirror.fuel-infra.org mirror by default. Other possible values are -# 'usa', 'cz' -ifeq ($(USE_MIRROR),usa) -MIRROR_FUEL?=http://mirror.seed-us1.fuel-infra.org/mos-repos/centos/$(PRODUCT_NAME)$(PRODUCT_VERSION)-centos$(CENTOS_MAJOR)/os/x86_64/ -MIRROR_UBUNTU?=mirror.seed-us1.fuel-infra.org -MIRROR_MOS_UBUNTU?=$(MIRROR_UBUNTU) -endif - -ifeq ($(USE_MIRROR),cz) -MIRROR_FUEL?=http://mirror.seed-cz1.fuel-infra.org/mos-repos/centos/$(PRODUCT_NAME)$(PRODUCT_VERSION)-centos$(CENTOS_MAJOR)/os/x86_64/ -MIRROR_UBUNTU?=mirror.seed-cz1.fuel-infra.org -MIRROR_MOS_UBUNTU?=$(MIRROR_UBUNTU) -endif - -# Which repositories to use for making local centos mirror. -# Possible values you can find out from mirror/centos/yum_repos.mk file. -# The actual name will be constracted prepending "yum_repo_" prefix. -# Example: YUM_REPOS?=official epel => yum_repo_official and yum_repo_epel -# will be used. -YUM_REPOS?=official extras fuel -MIRROR_CENTOS?=http://mirror.centos.org/centos/$(CENTOS_MAJOR) -MIRROR_CENTOS_KERNEL?=$(MIRROR_CENTOS) -SANDBOX_MIRROR_CENTOS_UPSTREAM?=$(MIRROR_CENTOS) -SANDBOX_MIRROR_EPEL?=http://mirror.yandex.ru/epel -MIRROR_UBUNTU_METHOD?=http -MIRROR_UBUNTU?=mirror.fuel-infra.org -MIRROR_UBUNTU_ROOT?=/pkgs/ubuntu/ -MIRROR_UBUNTU_SUITE?=$(UBUNTU_RELEASE) -MIRROR_UBUNTU_SECTION?=main universe multiverse restricted -MIRROR_MOS_UBUNTU_METHOD?=http -MIRROR_MOS_UBUNTU?=mirror.fuel-infra.org -MIRROR_MOS_UBUNTU_ROOT?=/mos-repos/ubuntu/$(PRODUCT_VERSION) -MIRROR_MOS_UBUNTU_SUITE?=$(PRODUCT_NAME)$(PRODUCT_VERSION) -MIRROR_MOS_UBUNTU_SECTION?=main restricted - -# MIRROR_FUEL affects build process only if YUM_REPOS variable contains 'fuel'. -# Otherwise it is ignored entirely. -MIRROR_FUEL?=http://mirror.fuel-infra.org/mos-repos/centos/$(PRODUCT_NAME)$(PRODUCT_VERSION)-centos$(CENTOS_MAJOR)/os/x86_64/ - -# Additional CentOS repos. -# Each repo must be comma separated tuple with repo-name and repo-path. -# Repos must be separated by space. -# Example: EXTRA_RPM_REPOS="lolo,http://my.cool.repo/rpm,priority bar,ftp://repo.foo,priority" -EXTRA_RPM_REPOS?="proposed,http://mirror.fuel-infra.org/mos-repos/centos/$(PRODUCT_NAME)$(PRODUCT_VERSION)-centos$(CENTOS_MAJOR)/snapshots/proposed-latest/x86_64/" - -# define RPM repo which contains fuel rpm-build-dep packages, in format -# EXTRA_RPM_BUILDDEP_REPO=http://my.cool.repo/rpm -EXTRA_RPM_BUILDDEP_REPO?="http://mirror.fuel-infra.org/mos-repos/centos/$(PRODUCT_NAME)$(PRODUCT_VERSION)-centos$(CENTOS_MAJOR)/snapshots/proposed-latest/x86_64/" - -comma:=, - -# Path to yaml configuration file to build ISO ks.cfg -KSYAML?=$(SOURCE_DIR)/iso/ks.yaml - -# Copy local /etc/ssl certs inside SANDBOX, which used for build deb mirror and packages. -# This option should be enabled, in case you have to pass https repos for Ubuntu. -SANDBOX_COPY_CERTS?=0 - -# Development option only: -# Please don’t change them if you don’t know what they do ## - -# Work-around for: LP1482667 -# If not empty, will try to download prepared upstream puppet modules source, -# which used like requirements for build fuel-library package. -# List of modules, which SHOULD be passed via this file can be found: -# https://github.com/openstack/fuel-library/blob/master/deployment/Puppetfile -# -# Usage example: -# USE_PREDEFINED_FUEL_LIB_PUPPET_MODULES?=http://127.0.0.1/files/upstream_modules.tar.gz -# Content example: -# upstream_modules.tar.gz:\ -# \apt/metadata.json -# \concat/metadata.json -USE_PREDEFINED_FUEL_LIB_PUPPET_MODULES?= - -# proxy configuration in format: -# PROXY_CONFIG="http_proxy=http://proxy_ip_address:proxy_port https_proxy=https://proxy_ip_address:proxy_port no_proxy=localhost" -PROXY_CONFIG?= diff --git a/fuel-release/RPM-GPG-KEY-mos b/fuel-release/RPM-GPG-KEY-mos deleted file mode 100644 index 59c48c912..000000000 --- a/fuel-release/RPM-GPG-KEY-mos +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -mQENBFWt8ogBCACtT/j4WMGuhEI486Vv9zVV0GWGefHE5hBlgJSjSgrExLFqQ2Fo -ScaABCfvzUeuXHNoh/c2eLjx3YE6oFrdiw5tam0NFlZMM+PSufciTxQz8vrXHGx7 -VB5rg2TXKoqOv9cW690FsRAeOtKTtBxZvYVTLEPn2GJW09Xy9CBa+n23XBHTBvKs -j3hxkn25Oy70Wgxk/BJqpynXGno+NzuAnIbb+f+X7i6fiXwrvtp5zOYOJeUwS+fU -IM/mXbetOd/sHtJqc9NUYpTip4nElEqAYRCsXDTbuMNdzSr8VlSMM8b61mBGelLH -XJe+EPP+Logc5KXO8adoGgWhqlbD6n7w+ynHABEBAAG0LmZ1ZWwtaW5mcmEgKEV4 -YW1wbGUga2V5KSA8ZGV2b3BzQG1pcmFudGlzLmNvbT6JATgEEwECACIFAlWt8ogC -GwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJELzlzEYfoisIkuQIAJl0cFJ5 -BSKMXHhRYf0BeDzhdh3pmcOXs/jSznTIxB4OE5OdwrMgKyoIkSIP8AEttvB+BuOv -BHmhTL7kvRhP5xiKdbCwmDtoERoaqxhRRbZJcJ+pHvl7mkEu8Gj2KZe2lfE4Z6ZF -6q00Gx9HYfse1+VgUR5ymh41nZCvRTNEnYBp1RQcPogiLy2rYvZbxYnUtg4jaD7D -vuuEQwrfEHdKFUlWBCIVbl+e3K6ZSniOcqqyHK72/HI0SYuZpGfCzzw5deODcjWm -Gz4nZr41cB3eHXkfmG3ngdhmb2MpVr83u+JebOovjzusf71oIdZBTFNYsZNSVKrn -l0rrRuDIMHbQMuS5AQ0EVa3yiAEIALZqdLGXSGZAgUXl7zhPH5wnIQtdo6iMIovZ -zQNW95RDT2nm/3YddiRy6FuOTbaHXw07D4ZUl4dGVHzEwBllhULxcHV3OOdQ3gVp -4mBAZ8kv0EelzqPfDQWR2Cq0hi7IJ4Q4ePpZhQFiasz8qbV7D7CYbZdDAmQKxqAk -0XYOjbB3jzB2r6MHflAKmJzTp3+NAE9bDLAwXa0ot2THDbpPdB4R6pxpD6Y3jweW -uLUCnIfvyIBwhHobaU28pw/BA+0dkC9jnLnoO+TrzB9YD5839Lc3ctrdPBLiFPMG -wdfAVRCyfgLjOyULqjTudx1Mo+Dgz9+xrcTFoehI7UYoZnraEKkAEQEAAYkBHwQY -AQIACQUCVa3yiAIbDAAKCRC85cxGH6IrCPH5B/0Uc+OhMSCkRos1Yv5tA4bsEcjt -8+sJ2S6pUqCbZxmXpzKspKpnjp3DJjmQKDB2q4UPDVElVDMMdBlstTx1RRZDf8yk -nDvRBSzawk7Xhfloro8N2Lxv6gWhhMvHUYItyO6KMbAZuZ2M1I1/OFHG/f//7oPM -0QpNbihf+GqE/dWRz9ZDz+xlSFli6AR/3ldq7N6gkCsEFdi3j6ZDf0qLsZpazPUI -wiCC/aAYLkRDtTJV1G6EsWijmOTNNlCEFS/XDLQ3N2Ev/1sgAO0AlBMdXqSnqUI1 -1h/eSKCiGmkwFWlCf/4HnJVP7QpSeRPLyw785Fvt3p9vT+64isZ0ZK6cpcj8 -=0aQD ------END PGP PUBLIC KEY BLOCK----- diff --git a/fuel-release/mos-os.repo b/fuel-release/mos-os.repo deleted file mode 100644 index 48b31df81..000000000 --- a/fuel-release/mos-os.repo +++ /dev/null @@ -1,8 +0,0 @@ -[mos$fuelver-base] -name=mos$fuelver-base -#baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos$fuelver-centos$releasever/os/x86_64/ -mirrorlist=http://mirror.fuel-infra.org/mos-repos/centos/mos$fuelver-centos$releasever/mos-mirrors-os.txt -enabled=1 -gpgcheck=1 -gpgkey=file:///etc/pki/fuel-gpg/RPM-GPG-KEY-mos -skip_if_unavailable=1 diff --git a/fuel-release/mos-security.repo b/fuel-release/mos-security.repo deleted file mode 100644 index bd755623d..000000000 --- a/fuel-release/mos-security.repo +++ /dev/null @@ -1,8 +0,0 @@ -[mos$fuelver-security] -name=mos$fuelver-security -#baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos$fuelver-centos$releasever/security/x86_64/ -mirrorlist=http://mirror.fuel-infra.org/mos-repos/centos/mos$fuelver-centos$releasever/mos-mirrors-security.txt -enabled=1 -gpgcheck=1 -gpgkey=file:///etc/pki/fuel-gpg/RPM-GPG-KEY-mos -skip_if_unavailable=1 diff --git a/fuel-release/mos-updates.repo b/fuel-release/mos-updates.repo deleted file mode 100644 index 5056abed1..000000000 --- a/fuel-release/mos-updates.repo +++ /dev/null @@ -1,8 +0,0 @@ -[mos$fuelver-updates] -name=mos$fuelver-updates -#baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos$fuelver-centos$releasever/updates/x86_64/ -mirrorlist=http://mirror.fuel-infra.org/mos-repos/centos/mos$fuelver-centos$releasever/mos-mirrors-updates.txt -enabled=1 -gpgcheck=1 -gpgkey=file:///etc/pki/fuel-gpg/RPM-GPG-KEY-mos -skip_if_unavailable=1 diff --git a/fuel-release/override_rpm_repos.py b/fuel-release/override_rpm_repos.py deleted file mode 100755 index 8fc200b78..000000000 --- a/fuel-release/override_rpm_repos.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -# Copyright 2016 Mirantis, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import argparse -import yaml - - -def generate_yum_repos_config(repositories): - config = "" - for repo in repositories: - config += """ -[{name}] -name={name} -baseurl={uri} -enabled=1 -gpgcheck=0 -priority={priority} -skip_if_unavailable=1 -""".format(**repo) - return config - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument( - '--repositories-file', dest='repositories_file', action='store', - type=str, help='file where repositories are defined', required=True - ) - parser.add_argument( - '--output-file', dest='outfile', action='store', - type=str, help='file where to write yum config', required=True - ) - params, other_params = parser.parse_known_args() - - with open(params.repositories_file) as f: - repositories = yaml.safe_load(f) - - with open(params.outfile, 'wt') as f: - f.write(generate_yum_repos_config(repositories)) - - -if __name__ == "__main__": - main() diff --git a/iso/.discinfo b/iso/.discinfo deleted file mode 100644 index c3cf19aac..000000000 --- a/iso/.discinfo +++ /dev/null @@ -1,4 +0,0 @@ -1323560292.885204 -6.3 -x86_64 -1 diff --git a/iso/.treeinfo b/iso/.treeinfo deleted file mode 100644 index f7beb5c69..000000000 --- a/iso/.treeinfo +++ /dev/null @@ -1,20 +0,0 @@ -[general] -family = CentOS -timestamp = 1323560005.81 -variant = -totaldiscs = 1 -version = 6.3 -discnum = 1 -packagedir = -arch = x86_64 - -[images-x86_64] -kernel = images/pxeboot/vmlinuz -initrd = images/pxeboot/initrd.img - -[images-xen] -kernel = images/pxeboot/vmlinuz -initrd = images/pxeboot/initrd.img - -[stage2] -mainimage = LiveOS/squashfs.img diff --git a/iso/bootstrap_admin_node.sh b/iso/bootstrap_admin_node.sh deleted file mode 100755 index dbcac5f1f..000000000 --- a/iso/bootstrap_admin_node.sh +++ /dev/null @@ -1,592 +0,0 @@ -#!/bin/bash - -# LANG variable is a workaround for puppet-3.4.2 bug. See LP#1312758 for details -export LANG=en_US.UTF8 - -wwwdir="/var/www/nailgun" - -mkdir -p /var/log/puppet -mkdir -p ${wwwdir}/targetimages - -LOGFILE=${LOGFILE:-/var/log/puppet/bootstrap_admin_node.log} - -exec > >(tee -i "${LOGFILE}") -exec 2>&1 - -# LP#1535419: Hide too verbose kernel messages to prevent tty being -# filled with spam. -sysctl -w kernel.printk='4 1 1 7' - -VBOX_BLACKLIST_MODULES="i2c_piix4 intel_rapl" - -# The following packages need to be installed prior to installing any other ones -# fuel-release package should be installed at the end of all bootstrap packages -# since it introduces online mirrors which might be unavailable in isolated envs -BOOTSTRAP_PACKAGES="yum-plugin-priorities yum-utils fuel-release" - -FUEL_PACKAGES=" \ -augeas \ -authconfig \ -bind-utils \ -bridge-utils \ -daemonize \ -dhcp \ -docker \ -fuel \ -fuel-bootstrap-cli \ -fuel-openstack-metadata \ -fuel-utils \ -fuel-ui \ -gdisk \ -lrzip \ -lsof \ -mlocate \ -nmap-ncat \ -ntp \ -ntpdate \ -puppet \ -python-pypcap \ -python-timmy \ -rsync \ -rubygem-netaddr \ -rubygem-openstack \ -send2syslog \ -strace \ -sysstat \ -system-config-firewall-base \ -tcpdump \ -telnet \ -vim \ -virt-what \ -wget \ -" - -ASTUTE_YAML='/etc/fuel/astute.yaml' -BOOTSTRAP_NODE_CONFIG="/etc/fuel/bootstrap_admin_node.conf" -CUSTOM_REPOS="/root/default_deb_repos.yaml" -bs_build_log='/var/log/fuel-bootstrap-image-build.log' -bs_status=0 -# Backup network configs to this folder. Folder will be created only if -# backup process actually will be. -bup_folder="/var/bootstrap_admin_node_bup_$(date +%Y-%m-%d-%H-%M-%S)/" -### Long messages inside code makes them more complicated to read... -# bootstrap messages -# FIXME fix help links -bs_skip_message="WARNING: Ubuntu bootstrap build has been skipped. \ -Please build and activate bootstrap manually with CLI command \ -\`fuel-bootstrap build --activate\`. \ -While you don't activate any bootstrap - new nodes cannot be discovered \ -and added to cluster. \ -For more information please visit \ -http://docs.openstack.org/developer/fuel-docs/userdocs/fuel-install-guide/bootstrap/\ -bootstrap_troubleshoot.html" -bs_error_message="WARNING: Failed to build the bootstrap image, see $bs_build_log \ -for details. Perhaps your Internet connection is broken. Please fix the \ -problem and run \`fuel-bootstrap build --activate\`. \ -While you don\'t activate any bootstrap - new nodes cannot be discovered \ -and added to cluster. \ -For more information please visit \ -http://docs.openstack.org/developer/fuel-docs/userdocs/fuel-install-guide/bootstrap/\ -bootstrap_troubleshoot.html" -bs_progress_message="There is no active bootstrap. Bootstrap image building \ -is in progress. Usually it takes 15-20 minutes. It depends on your internet \ -connection and hardware performance. After bootstrap image becomes available, \ -reboot nodes that failed to be discovered." -bs_done_message="Default bootstrap image building done. Now you can boot new \ -nodes over PXE, they will be discovered and become available for installing \ -OpenStack on them" -# Update issues messages -update_warn_message="There is an issue connecting to update repository of \ -your distributions of OpenStack. \ -Please fix your connection prior to applying any updates. \ -Once the connection is fixed, we recommend reviewing and applying \ -maintenance updates for your distribution of OpenStack." -update_done_message="We recommend reviewing and applying maintenance updates \ -for your distribution of OpenStack." -fuelmenu_fail_message="Fuelmenu was not able to generate '/etc/fuel/astute.yaml' file! \ -Please, restart it manualy using 'fuelmenu' command." -fuelclient_fail_message="Fuel CLI credentials are invalid. Update \ -/etc/fuel/astute.yaml FUEL_ACCESS/password and ~/.config/fuel/fuel_client.yaml\ - in order to proceed with deployment." -function countdown() { - local i - sleep 1 - for ((i=$1-1; i>=1; i--)); do - printf '\b\b\b\b%04d' "$i" - sleep 1 - done -} - -function fail() { - MSG="ERROR: Fuel node deployment FAILED! Check ${LOGFILE} for details" - # LP: #1551658 - Ensure data will be flushed on disk - sed -i -u "\$a${MSG}" "${LOGFILE}" - - exit 1 -} - -function get_ethernet_interfaces() { - # Get list of all ethernet interfaces, non-virtual, not a wireless - for DEV in /sys/class/net/* ; do - # Take only links into account, skip files - if test ! -L $DEV ; then - continue - fi - DEVPATH=$(readlink -f $DEV) - # Avoid virtual devices like loopback, tunnels, bonding, vlans ... - case $DEVPATH in - */virtual/*) - continue - ;; - esac - IF=${DEVPATH##*/} - # Check ethernet only - case "`cat $DEV/type`" in - 1) - # TYPE=1 is ethernet, may also be wireless, bond, tunnel ... - # Virtual lo, bound, vlan, tunneling has been skipped before - if test -d $DEV/wireless -o -L $DEV/phy80211 ; - then - continue - else - # Catch ethernet non-virtual device - echo $IF - fi - ;; - *) continue - ;; - esac - done -} - -# Get value of a key from ifcfg-* files -# Usage: -# get_ifcfg_value NAME /etc/sysconfig/network-scripts/ifcfg-eth0 -function get_ifcfg_value { - local key=$1 - local path=$2 - local value='' - if [[ -f ${path} ]]; then - value=$(awk -F\= "\$1==\"${key}\" {print \$2}" ${path}) - value=${value//\"/} - fi - echo ${value} -} - -# Get IP address from interface name -function get_interface_ip { - local interface=$1 - echo $(ip -4 -o a s ${interface} | sed 's:/:\ :;s:\s\+:\ :g' | cut -d ' ' -f 4) -} - -# Workaround to fix dracut network configuration approach: -# Bring down all network interfaces which have the same IP -# address statically configured as 'primary' interface -function ifdown_ethernet_interfaces { - local adminif_ipaddr - local if_name - local if_ipaddr - local path - - adminif_ipaddr=$(get_interface_ip $ADMIN_INTERFACE) - if [[ -z "${adminif_ipaddr}" ]]; then - return - fi - for if_name in $(get_ethernet_interfaces); do - if [[ "${if_name}" == "${ADMIN_INTERFACE}" ]]; then - continue - fi - if_ipaddr=$(get_interface_ip $if_name) - if [[ "${if_ipaddr}" == "${adminif_ipaddr}" ]]; then - echo "Interface '${if_name}' uses the same ip '${if_ipaddr}' as admin interface '${ADMIN_INTERFACE}', removing ..." - ifdown ${if_name} - mkdir -p "${bup_folder}" - path="/etc/sysconfig/network-scripts/ifcfg-${if_name}" - if [[ -f ${path} ]]; then - mv -f "${path}" "${bup_folder}" - fi - fi - done -} - -# Check if interface name is valid by checking that -# a config file with NAME equal to given name exists. -function ifname_valid { - local adminif_name=$1 - local if_name - local if_config - for if_config in $(find /etc/sysconfig/network-scripts -name 'ifcfg-*' ! -name 'ifcfg-lo'); do - if_name=$(get_ifcfg_value NAME $if_config) - if [[ "${if_name}" == "${adminif_name}" ]]; then - return 0 - fi - done - return 1 -} - -# switch selinux to permissive mode -setenforce 0 -sed -i s/SELINUX=enforcing/SELINUX=permissive/g /etc/selinux/config || : - -yum makecache -echo $BOOTSTRAP_PACKAGES | xargs -n1 yum install -y -# /etc/fuel_release is provided by 'fuel-release' package -FUEL_RELEASE=$(cat /etc/fuel_release) - -# Disable online base MOS repo if we run an ISO installation -[ -f /etc/fuel_build_id ] && yum-config-manager --disable mos${FUEL_RELEASE}* --save - -echo $FUEL_PACKAGES | xargs -n1 yum install -y -# /etc/fuel_openstack_version is provided by 'fuel-openstack-metadata' package -OPENSTACK_VERSION=$(cat /etc/fuel_openstack_version) - - -touch /var/lib/hiera/common.yaml /etc/puppet/hiera.yaml - -# Be sure, that network devices have been initialized -udevadm trigger --subsystem-match=net -udevadm settle - -# Import bootstrap_admin_node.conf if exists -if [ -f "${BOOTSTRAP_NODE_CONFIG}" ]; then - source "${BOOTSTRAP_NODE_CONFIG}" -fi - -# Set defaults to unset / empty variables -# Although eth0 is not always valid it's a good well-known default -# If there is no such interface it will fail to pass ifname_valid -# check and will be replaced. -OLD_ADMIN_INTERFACE=${ADMIN_INTERFACE} -ADMIN_INTERFACE=${ADMIN_INTERFACE:-'eth0'} -showmenu=${showmenu:-'yes'} - -# Now check that ADMIN_INTERFACE points to a valid interface -# If it doesn't fallback to getting the first interface name -# from a list of all available interfaces sorted alphabetically -if ! ifname_valid $ADMIN_INTERFACE; then - # Take the very first ethernet interface as an admin interface - ADMIN_INTERFACE=$(get_ethernet_interfaces | sort -V | head -1) -fi - -if [[ "${OLD_ADMIN_INTERFACE}" != "${ADMIN_INTERFACE}" ]]; then - echo "Saving ADMIN_INTERFACE value" - sed -i "s/^ADMIN_INTERFACE=.*/ADMIN_INTERFACE=${ADMIN_INTERFACE}/g" \ - ${BOOTSTRAP_NODE_CONFIG} -fi - -echo "Applying admin interface '$ADMIN_INTERFACE'" -export ADMIN_INTERFACE - -echo "Bringing down ALL network interfaces except '${ADMIN_INTERFACE}'" -ifdown_ethernet_interfaces -systemctl restart network - -echo "Applying default Fuel settings..." -set -x - -# Set correct docker volume group -echo "VG=docker" >> /etc/sysconfig/docker-storage-setup - -# Disable create iptables rules by docker -echo "DOCKER_NETWORK_OPTIONS=--iptables=false" > /etc/sysconfig/docker-network - -# Disable subscription-manager plugins -sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/product-id.conf || : -sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/subscription-manager.conf || : - -# Disable GSSAPI in ssh server config -sed -i -e "/^\s*GSSAPICleanupCredentials yes/d" -e "/^\s*GSSAPIAuthentication yes/d" /etc/ssh/sshd_config - -# Enable MOTD banner in sshd -sed -i -e "s/^\s*PrintMotd no/PrintMotd yes/g" /etc/ssh/sshd_config - -# Add note regarding local repos creation to MOTD -cat >> /etc/motd << EOF - -All environments use online repositories by default. -Use the python-packetary package to create local repositories: - -yum install python-packetary -packetary --help - -Use python-fuelclient package to modify default repository settings: - -yum install python-fuelclient (installed by default) -fuel2 --help - -EOF - -# Generate Fuel UUID -[ ! -f "/etc/fuel/fuel-uuid" ] && uuidgen > /etc/fuel/fuel-uuid || : - -echo "tos orphan 7" >> /etc/ntp.conf && systemctl restart ntpd - -# Disabling splash -sed -i --follow-symlinks -e '/^\slinux16/ s/rhgb/debug/' /boot/grub2/grub.cfg - -# Copying default bash settings to the root directory -cp -f /etc/skel/.bash* /root/ - -# Blacklist and try to unload kernel modules that create errors on VirtualBox -if (virt-what | fgrep -q "virtualbox") ; then - for module in $VBOX_BLACKLIST_MODULES; do - echo "blacklist ${module}" > /etc/modprobe.d/blacklist-${module}.conf - rmmod ${module} || : - done -fi - -# change default repo path in fuel-menu before starting any deployment steps -if [ -f "${CUSTOM_REPOS}" ]; then - fix_default_repos.py fuelmenu --repositories-file "${CUSTOM_REPOS}" || fail -fi - -# setup stringify_facts for the puppet -augtool set /files/etc/puppet/puppet.conf/main/stringify_facts false - -fuelmenu --save-only --iface=$ADMIN_INTERFACE || fail -set +x -echo "Done!" - -if [[ "$showmenu" == "yes" || "$showmenu" == "YES" ]]; then - fuelmenu || fail -else - # Give user 15 seconds to enter fuelmenu or else continue - echo - echo -n "Press a key to enter Fuel Setup (or press ESC to skip)... 15" - countdown 15 & pid=$! - if ! read -s -n 1 -t 15 key; then - echo -e "\nSkipping Fuel Setup..." - else - { kill "$pid"; wait $!; } 2>/dev/null - case "$key" in - $'\e') echo "Skipping Fuel Setup.." - ;; - *) echo -e "\nEntering Fuel Setup..." - fuelmenu || fail - ;; - esac - fi -fi - -# Enable online base MOS repos (security, updates) if we run an ISO installation -[ -f /etc/fuel_build_id ] && \ - yum-config-manager --enable mos${FUEL_RELEASE}-security mos${FUEL_RELEASE}-updates --save - -if [ ! -f "${ASTUTE_YAML}" ]; then - echo ${fuelmenu_fail_message} - fail -fi - -# Replace local repository for building bootstrap with online one -# and create symlink for backward compatibility -# if we run deployment on a pre-provisioned server -if [ ! -f /etc/fuel_build_id ]; then - sed -i "s|127.0.0.1:8080/ubuntu/x86_64|mirror.fuel-infra.org/mos-repos/ubuntu/${FUEL_RELEASE}|g" "${ASTUTE_YAML}" - ln -s ${wwwdir}/${OPENSTACK_VERSION}/ubuntu ${wwwdir}/ubuntu -fi - -# Enable sshd -systemctl enable sshd -systemctl start sshd - -# Enable iptables -systemctl enable iptables.service -systemctl start iptables.service - -if [ "$wait_for_external_config" == "yes" ]; then - wait_timeout=3000 - pidfile=/var/lock/wait_for_external_config - echo -n "Waiting for external configuration (or press ESC to skip)... -$wait_timeout" - countdown $wait_timeout & countdown_pid=$! - exec -a wait_for_external_config sleep $wait_timeout & wait_pid=$! - echo $wait_pid > $pidfile - while ps -p $countdown_pid &> /dev/null && ps -p $wait_pid &>/dev/null; do - read -s -n 1 -t 2 key - case "$key" in - $'\e') echo -e "\b\b\b\b abort on user input" - break - ;; - *) ;; - esac - done - { kill $countdown_pid $wait_pid & wait $!; } - rm -f $pidfile -fi - -# Prepare custom /etc/issue logon banner and script for changing IP in it -# We can have several interface naming schemes applied and several interface -# UI will listen on -ipstr="" -NL=$'\n' -for ip in `ip -o -4 addr show | awk '/e[nt][hopsx]/ { split($4, arr, /\//); print arr[1] }'`; do - ipstr="${ipstr}https://${ip}:8443${NL}" -done -cat > /etc/issue <&2 - set_ui_bootstrap_error "${bs_progress_message}" >&2 - if fuel-bootstrap -v --debug build --activate >>"$bs_build_log" 2>&1; then - ret=0 - fuel notify --topic "done" --send "${bs_done_message}" - else - ret=1 - set_ui_bootstrap_error "${bs_error_message}" >&2 - fi - # perform hard-return from func - # this part will update input $1 variable - local __resultvar=$1 - eval $__resultvar="'${ret}'" - return $ret -} - -# Create empty files to make cobbler happy -# (even if we don't use Ubuntu based bootstrap) -make_ubuntu_bootstrap_stub - -service docker start - -old_sysctl_vm_value=$(sysctl -n vm.min_free_kbytes) -if [ ${old_sysctl_vm_value} -lt 65535 ]; then - echo "Set vm.min_free_kbytes..." - sysctl -w vm.min_free_kbytes=65535 -fi - -if [ ${old_sysctl_vm_value} -lt 65535 ]; then - echo "Restore sysctl vm.min_free_kbytes value..." - sysctl -w vm.min_free_kbytes=${old_sysctl_vm_value} -fi - -# Ensure fuelclient can authenticate -output=$(fuel token 2>&1) -if echo "$output" | grep -q "Unauthorized"; then - echo $fuelclient_fail_message - fail -fi - -# apply puppet -/etc/puppet/modules/fuel/examples/deploy.sh || fail -# Update default repo path -if [ -f "${CUSTOM_REPOS}" ]; then - fix_default_repos.py fuel \ - --repositories-file "${CUSTOM_REPOS}" \ - --release-version "${OPENSTACK_VERSION}" || fail -fi - -# Sync time -systemctl stop ntpd -systemctl start ntpdate || echo "Failed to synchronize time with 'ntpdate'" -systemctl start ntpd - -bash /etc/rc.local - -if [ "`get_bootstrap_skip`" = "False" ]; then - build_ubuntu_bootstrap bs_status || true -else - fuel notify --topic "warning" --send "${bs_skip_message}" - bs_status=2 -fi - -#Check if repo is accessible -echo "Checking for access to updates repository/mirrorlist..." -repourl=$(yum repolist all -v | awk '{if ($1 ~ "baseurl|mirrors" && $3 ~ "updates") print $3}' | head -1) -if urlaccesscheck check "$repourl" ; then - UPDATE_ISSUES=0 -else - UPDATE_ISSUES=1 -fi - -if [ $UPDATE_ISSUES -eq 1 ]; then - message=${update_warn_message} - level="warning" -else - message=${update_done_message} - level="done" -fi -echo -echo "*************************************************" -echo -e "${message}" -echo "*************************************************" -fuel notify --topic "${level}" --send $(echo "${message}" | tr '\r\n' ' ') 2>&1 - -# Perform bootstrap messaging to stdout -case ${bs_status} in - 1) - echo -e "${bs_error_message}" - echo "*************************************************" - ;; - 2) - echo -e "${bs_skip_message}" - echo "*************************************************" - ;; -esac - -echo "Fuel node deployment complete!" -# Sleep for agetty autologon -sleep 3 diff --git a/iso/fix_default_repos.py b/iso/fix_default_repos.py deleted file mode 100755 index 8bd060cbf..000000000 --- a/iso/fix_default_repos.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python -# Copyright 2016 Mirantis, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import argparse -import os - -import six -import yaml - -from fuelclient import objects - - -FUELMENU_DEFAULT_SETTINGS_PATH = \ - "/usr/lib/python2.7/site-packages/fuelmenu/settings.yaml" - - -def is_subdict(dict1, dict2): - """Checks that dict1 is subdict of dict2. - - >>> is_subdict({"a": 1}, {'a': 1, 'b': 1}) - True - - :param dict1: the candidate - :param dict2: the super dict - :return: True if all keys from dict1 are present - and has same value in dict2 otherwise False - """ - for k, v in six.iteritems(dict1): - if k not in dict2 or dict2[k] != v: - return False - return True - - -def lists_merge(main, patch, key): - """Merges the list of dicts with same keys. - - >>> lists_merge([{"a": 1, "c": 2}], [{"a": 1, "c": 3}], key="a") - [{'a': 1, 'c': 3}] - - :param main: the main list - :type main: list - :param patch: the list of additional elements - :type patch: list - :param key: the key for compare - """ - main_idx = dict( - (x[key], i) for i, x in enumerate(main) - ) - - patch_idx = dict( - (x[key], i) for i, x in enumerate(patch) - ) - - for k in sorted(patch_idx): - if k in main_idx: - main[main_idx[k]].update(patch[patch_idx[k]]) - else: - main.append(patch[patch_idx[k]]) - return main - - -def update_release_repos(repositories, - release_match, - replace_repos=False): - """Applies repositories for existing default settings. - :param repositories: the meta information of repositories - :param release_match: The pattern to check Fuel Release - """ - releases = six.moves.filter( - lambda x: is_subdict(release_match, x.data), - objects.Release.get_all() - ) - for release in releases: - modified = _update_repository_settings( - release.data["attributes_metadata"], - repositories, - replace_repos=replace_repos) - if modified: - release.data["attributes_metadata"] = modified - print "Try to update the Release '%s'" % release.data['name'] - release.connection.put_request( - release.instance_api_path.format(release.id), - release.data - ) - - -def _update_repository_settings(settings, - repositories, - replace_repos=False): - """Updates repository settings. - :param settings: the target settings - :param repositories: the meta of repositories - """ - editable = settings["editable"] - if 'repo_setup' not in editable: - return - - repos_attr = editable["repo_setup"]["repos"] - if replace_repos: - repos_attr['value'] = repositories - else: - lists_merge(repos_attr['value'], repositories, "name") - - settings["editable"]["repo_setup"]["repos"] = repos_attr - - return settings - - -def fix_fuel_repos(address, port, user, password, - release_version, release_os, repositories): - os.environ["SERVER_ADDRESS"] = address - os.environ["LISTEN_PORT"] = port - os.environ["KEYSTONE_USER"] = user - os.environ["KEYSTONE_PASS"] = password - - release_match = { - "version": release_version, - "operating_system": release_os - } - - update_release_repos(repositories, release_match) - - -def fix_fuelmenu_repos(repositories, replace_repos=False): - print "Try to update default fuelmenu settings" - with open(FUELMENU_DEFAULT_SETTINGS_PATH) as f: - settings = yaml.safe_load(f) - if replace_repos: - settings["BOOTSTRAP"]["repos"] = repositories - else: - lists_merge(settings["BOOTSTRAP"]["repos"], repositories, "name") - with open(FUELMENU_DEFAULT_SETTINGS_PATH, "w") as f: - f.write(yaml.safe_dump(settings, default_flow_style=False)) - - -def main(): - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers( - dest="action", help='actions' - ) - fuel_parser = subparsers.add_parser( - 'fuel', help='fix fuel repos' - ) - fuel_parser.add_argument( - '--release-version', dest='release_version', action='store', - type=str, help='release version', default='newton-10.0' - ) - fuel_parser.add_argument( - '--release-os', dest='release_os', action='store', - type=str, help='release operating system', default='Ubuntu' - ) - fuel_parser.add_argument( - '--repositories-file', dest='repositories_file', action='store', - type=str, help='file where repositories are defined', required=True - ) - fuel_parser.add_argument( - '-a', '--address', dest='address', action='store', type=str, - help='fuel address', default='127.0.0.1' - ) - fuel_parser.add_argument( - '-p', '--port', dest='port', action='store', type=str, - help='fuel port', default='8000' - ) - fuel_parser.add_argument( - '--user', dest='user', action='store', type=str, - help='fuel user', default='admin' - ) - fuel_parser.add_argument( - '--password', dest='password', action='store', type=str, - help='fuel password', default='admin' - ) - fuelmenu_parser = subparsers.add_parser( - 'fuelmenu', help='fix fuelmenu repos' - ) - fuelmenu_parser.add_argument( - '--repositories-file', dest='repositories_file', action='store', - type=str, help='file where repositories are defined', required=True - ) - params, other_params = parser.parse_known_args() - - with open(params.repositories_file) as f: - repositories = yaml.safe_load(f) - - if params.action == 'fuel': - fix_fuel_repos(params.address, params.port, - params.user, params.password, - params.release_version, params.release_os, - repositories) - else: - fix_fuelmenu_repos(repositories) - - -if __name__ == "__main__": - main() diff --git a/iso/isolinux/isolinux.cfg b/iso/isolinux/isolinux.cfg deleted file mode 100644 index c6b1ed9eb..000000000 --- a/iso/isolinux/isolinux.cfg +++ /dev/null @@ -1,27 +0,0 @@ -default vesamenu.c32 -#prompt 1 -timeout 300 - -display boot.msg - -menu background splash.jpg -menu title Welcome to Fuel Installer (version: will_be_substituted_with_PRODUCT_VERSION) -menu color border 0 #ffffffff #00000000 -menu color sel 7 #ffffffff #ff000000 -menu color title 0 #ffffffff #00000000 -menu color tabmsg 0 #ffffffff #00000000 -menu color unsel 0 #ffffffff #00000000 -menu color hotsel 0 #ff000000 #ffffffff -menu color hotkey 7 #ffffffff #ff000000 -menu color scrollbar 0 #ffffffff #00000000 - -label nailgun - menu label ^1. Fuel Install (Static IP) - menu default - kernel vmlinuz - append initrd=initrd.img net.ifnames=0 biosdevname=0 inst.repo=cdrom:LABEL=will_be_substituted_with_ISO_VOLUME_ID:/ inst.ks=cdrom:LABEL=will_be_substituted_with_ISO_VOLUME_ID:/ks.cfg ip=10.20.0.2::10.20.0.1:255.255.255.0:fuel.domain.tld:eth0:off::: nameserver=10.20.0.1 - -label nailgunifname - menu label ^2. Fuel Advanced Install (Static IP) - kernel vmlinuz - append initrd=initrd.img inst.repo=cdrom:LABEL=will_be_substituted_with_ISO_VOLUME_ID:/ inst.ks=cdrom:LABEL=will_be_substituted_with_ISO_VOLUME_ID:/ks.cfg ip=10.20.0.2::10.20.0.1:255.255.255.0:fuel.domain.tld:adminif:off::: nameserver=10.20.0.1 ifname=adminif:XX:XX:XX:XX:XX:XX diff --git a/iso/isolinux/splash.jpg b/iso/isolinux/splash.jpg deleted file mode 100644 index 212276f22da17bf872dde71c910b356d2204fc22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141168 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

G^4ZMy~2E~2-%0MhVV`(jJpO@L1w%f%w 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/dev/null ; then - echo - echo "$check_drive drive contains partition table:" - parted -s /dev/$check_drive print - echo - read -p "Are you sure you want to erase ALL data on disk $check_drive? (y/N)" confirm_format - if [[ "$confirm_format" == "y" ]] || [[ "$confirm_format" == "Y" ]] || [[ "$forceformat" == "yes" ]]; then - return 0 - else - return 1 - fi - else - return 0 - fi -} - -format_confirmed="no" - -if [ $numdrives -lt 1 ]; then - exec < /dev/tty3 > /dev/tty3 2>&1 - chvt 3 - clear - echo - echo '********************************************************************' - echo '* E R R O R *' - echo '* *' - echo '* There is no suitable media available for installation. *' - echo '* Please attach a drive and try again. *' - echo '* *' - echo '********************************************************************' - echo - read -p "Press Enter to shut down the system: " _ - poweroff -fi - -if [ ${numdrives} -gt 1 ] || [ `echo ${drives} | wc -w` -eq 0 ] ; then - exec < /dev/tty3 > /dev/tty3 2>&1 - chvt 3 - while [ "${tgtdrive}" = "undefined" ]; do - clear - echo - echo '********************************************************************************' - echo '* W A R N I N G *' - echo '* *' - echo '* Which of the detected hard drives do you want to be used as *' - echo '* the installation target? *' - echo '* *' - echo '********************************************************************************' - echo - echo "Possible choices" - echo "Persistent drives: ${drives}" - echo "Removable drives: ${removable_drives}" - echo - if [ `echo ${drives} | wc -w` -eq 1 ] ; then - read -t 30 -p "Choose hard drive: " tgtdrive || tgtdrive=$default_drive - else - read -p "Choose hard drive: " tgtdrive - fi - match="no" - for drive in ${drives[@]} ${removable_drives[@]}; do - if [[ "$drive" == "$tgtdrive" ]] && match="yes" ; then - if confirm_format $tgtdrive ; then - format_confirmed="yes" - break - else - tgtdrive="undefined" - read -p "You may select another disk. Press Enter to continue." _ - fi - fi - done - if [[ "$match" == "no" ]]; then - tgtdrive="undefined" - read -p "Invalid choice. Press Enter to continue." _ - fi - done - clear - chvt 1 -else - tgtdrive=`echo ${drives} | sed -e "s/^\s*//" -e "s/\s*$//"` -fi - -if [ "$format_confirmed" != "yes" ] ; then - exec < /dev/tty3 > /dev/tty3 2>&1 - chvt 3 - if ! confirm_format $tgtdrive ; then - clear - echo - echo '********************************************************************' - echo '* E R R O R *' - echo '* *' - echo '* Disk $tgtdrive contains active partition(s). *' - echo '* Installation cannot continue without confirmation. *' - echo '* *' - echo '********************************************************************' - echo - read -p "Press Enter to restart: " _ - reboot - fi - chvt 1 -fi - -# verify tgtdrive is at least 50GB -tgtdrivesize=$(( $(cat "/sys/class/block/${tgtdrive}/size") / 2 / 1024 )) -if [ $tgtdrivesize -lt 51200 ]; then - exec < /dev/tty3 > /dev/tty3 2>&1 - chvt 3 - clear - echo - echo '********************************************************************' - echo '* E R R O R *' - echo '* *' - echo '* Your disk is under 50GB in size. Installation cannot continue. *' - echo '* Restart installation with a larger disk. *' - echo '* *' - echo '********************************************************************' - echo - read -p "Press Enter to restart: " _ - reboot -fi - -# paths in /dev have "/" instead of "!" for cciss devices -tgtdrive=$(echo $tgtdrive | sed -e 's/!/\//') - -# source -iso_volume_id=will_be_substituted_with_ISO_VOLUME_ID - -cdrom_device= -if [ -e /proc/sys/dev/cdrom/info ]; then - cdrom_device=$(cat /proc/sys/dev/cdrom/info | awk '/drive name:/{print $3}') -fi - -if [ -e /dev/disk/by-label/${iso_volume_id} ]; then - real_device=$(readlink -e /dev/disk/by-label/${iso_volume_id}) - if [ "${real_device}" == "/dev/${cdrom_device}" ]; then - echo "cdrom" > /tmp/source.ks - else - echo "harddrive --partition=LABEL=${iso_volume_id} --dir=/" > /tmp/source.ks - fi -else - echo "cdrom" > /tmp/source.ks -fi - -vgdisplay -c | cut -d':' -f1 | xargs vgremove -ff -dd if=/dev/zero of=/dev/${tgtdrive} bs=10M count=10 -sleep 3 -hdparm -z /dev/${tgtdrive} -parted -s /dev/${tgtdrive} mklabel gpt -parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 0% 24 -parted -s /dev/${tgtdrive} set 1 bios_grub on -parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary fat16 24 224 -parted -s /dev/${tgtdrive} set 2 boot on -parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 224 424 -sleep 3 -hdparm -z /dev/${tgtdrive} - -# partition - -# This adds support for the p seperator required for cciss devices -if echo ${tgtdrive} | grep -q -e cciss ; then - bootdev=${tgtdrive}p -else - bootdev=${tgtdrive} -fi - -cat << EOF > /tmp/partition.ks -part /boot --onpart=/dev/${bootdev}3 -part /boot/efi --onpart=/dev/${bootdev}2 -part pv.001 --ondisk=${tgtdrive} --size=25000 --grow -part pv.002 --ondisk=${tgtdrive} --size=10000 -volgroup os pv.001 -volgroup docker pv.002 -logvol swap --vgname=os --recommended --name=swap -logvol / --vgname=os --size=10000 --name=root --fstype=ext4 -logvol /var --vgname=os --grow --percent 40 --name=var --fstype=ext4 -logvol /var/log --vgname=os --grow --percent 60 --name=varlog --fstype=ext4 -EOF - - - -# bootloader -echo "bootloader --driveorder=${tgtdrive} --append=' biosdevname=0 crashkernel=none'" > /tmp/bootloader.ks - -# Anaconda can not install grub 0.97 on disks which are >4T. -# The reason is that grub does not support such large geometries -# and it simply thinks that the cylinder number has negative value. -# Here we just set geometry manually so that grub thinks that disk -# size is equal to 1G. -# 130 cylinders * (16065 * 512 = 8225280 bytes) = 1G -echo "%post --nochroot --log=/mnt/sysimage/root/anaconda-post-partition.log" > /tmp/post_partition.ks -echo "echo \"device (hd0) /dev/${tgtdrive}\" >> /tmp/grub.script" >> /tmp/post_partition.ks -echo "echo \"geometry (hd0) 130 255 63\" >> /tmp/grub.script" >> /tmp/post_partition.ks -echo "echo \"root (hd0,2)\" >> /tmp/grub.script" >> /tmp/post_partition.ks -echo "echo \"install /grub/stage1 (hd0) /grub/stage2 p /grub/grub.conf\" >> /tmp/grub.script" >> /tmp/post_partition.ks -echo "echo quit >> /tmp/grub.script" >> /tmp/post_partition.ks -echo "cat /tmp/grub.script | chroot /mnt/sysimage /sbin/grub --no-floppy --batch" >> /tmp/post_partition.ks -echo "%end" >> /tmp/post_partition.ks -%end - - - - - -# POSTINSTALL SECTIONS -# HERE ARE COMMANDS THAT WILL BE LAUNCHED JUST AFTER -# INSTALLATION ITSELF COMPLETED - - -# Parse /proc/cmdline and save for next steps -%post --log=/root/anaconda-parse-cmdline.log -#!/bin/bash -set -x - -# Parse cmdline to alter keys which contains dot in their names -# Such keys can't be used as variables in bash, -# so every dot is replaced with double underscore. -# Double underscore needed to avoid possible naming collisions. -for item in $(cat /proc/cmdline); do - if [[ "${item}" =~ '=' ]]; then - key="${item%%=*}" - value="${item#*=}" - else - key="${item}" - value='yes' - fi - key="${key//\./__}" - value="${value:-'yes'}" - echo "${key}=${value}" >> /root/anaconda.cmdline.vars -done - -source /root/anaconda.cmdline.vars - -if [[ ! -z $ifname ]]; then - echo "adminif=$(udevadm info --query=property -p /sys/class/net/${ifname%%:*} | \ - awk -F\= '$1 == "ID_NET_NAME_ONBOARD" {s=$2; exit}; $1 == "ID_NET_NAME_SLOT" {s=$2; exit}; $1 == "ID_NET_NAME_PATH" {s=$2; next}; END {print s}')" >> /root/anaconda.cmdline.vars -fi - -# Add self entry to /etc/hosts -ipaddr=$(echo $ip | cut -d: -f1) -hostname=$(echo $ip | cut -d: -f5) -# Use default hostname if missing from parameters -[ -z "$hostname" ] && hostname="fuel.domain.tld" -short=$(echo $hostname | cut -d. -f1) -echo -e "${ipaddr} ${hostname} ${short}" >> /etc/hosts -%end - - - - - -# Mount installation media in chroot -%post --nochroot --log=/mnt/sysimage/root/anaconda-post-before-chroot.log -#!/bin/bash -set -x - -source "/mnt/sysimage/root/anaconda.cmdline.vars" - -SOURCE="/mnt/sysimage/tmp/source" - -mkdir -p "${SOURCE}" - -case "${repo}" in - nfs:*) - nfs_url="${repo#nfs:}" - mount -t nfs "${nfs_url}" "${SOURCE}" - ;; - *) - if [ -d "/mnt/source" ]; then - mount -o bind "/mnt/source" "${SOURCE}" - fi - ;; -esac - - -# If not mounted, try to bind /run/install/repo since -# anaconda shoud mount installation repo to that folder. -if ! mountpoint -q "${SOURCE}"; then - if [ -d '/run/install/repo' ] && mountpoint -q '/run/install/repo'; then - mount -o bind '/run/install/repo' "${SOURCE}" - fi -fi - - -# If still not mounted, try to mount from LABEL / UUID. -# It was moved from next phase here to keep all mounting stuff -# in one place. All other scripts should use SOURCE variable -# for access to dist files. - -iso_volume_id=will_be_substituted_with_ISO_VOLUME_ID -FS="/mnt/sysimage/tmp/fs" - -if ! mountpoint -q "${SOURCE}"; then - if [ -e "/dev/disk/by-label/${iso_volume_id}" ]; then - mount "/dev/disk/by-label/${iso_volume_id}" "${SOURCE}" - fi -fi - -# Sleep to capture full log -sleep 1 -%end - - - - - -%post --log=/root/anaconda-post-configure-repos.log -#!/bin/bash -set -x - -SOURCE=/tmp/source - -# this file is provided by fuel-openstack-metadata package -OPENSTACK_VERSION=`rpm2cpio ${SOURCE}/mos-centos/Packages/fuel-openstack-metadata*.rpm | \ - cpio -i --to-stdout ./etc/fuel_openstack_version 2>/dev/null` - -# build identifiers -test -e ${SOURCE}/fuel_build_number && cp ${SOURCE}/fuel_build_number /etc/fuel_build_number -test -e ${SOURCE}/fuel_build_id && cp ${SOURCE}/fuel_build_id /etc/fuel_build_id - -# Copy repos config -test -e ${SOURCE}/default_deb_repos.yaml && cp ${SOURCE}/default_deb_repos.yaml /root/default_deb_repos.yaml - -# ---------------------- -# UNPACKING REPOSITORIES -# ---------------------- - -wwwdir="/var/www/nailgun" -repodir="${wwwdir}/${OPENSTACK_VERSION}" - -# Copying Centos files -mkdir -p ${repodir}/centos/x86_64 -mkdir -p ${repodir}/mos-centos/x86_64 -cp -r ${SOURCE}/images ${repodir}/centos/x86_64 -cp -r ${SOURCE}/isolinux ${repodir}/centos/x86_64 -cp -r ${SOURCE}/repodata ${repodir}/centos/x86_64 -cp -r ${SOURCE}/Packages ${repodir}/centos/x86_64 -cp -r ${SOURCE}/mos-centos/repodata ${repodir}/mos-centos/x86_64 -cp -r ${SOURCE}/mos-centos/Packages ${repodir}/mos-centos/x86_64 -cp -r ${SOURCE}/extra-repos ${repodir}/ -cp ${SOURCE}/.treeinfo ${repodir}/centos/x86_64 - -# Copying Ubuntu files -mkdir -p ${repodir}/ubuntu/x86_64/images -cp -r ${SOURCE}/ubuntu/dists ${repodir}/ubuntu/x86_64 -cp -r ${SOURCE}/ubuntu/pool ${repodir}/ubuntu/x86_64 - -# make links for backward compatibility -ln -s ${repodir}/centos ${wwwdir}/centos -ln -s ${repodir}/ubuntu ${wwwdir}/ubuntu -#Make a symlink for mos-centos in /var/www/nailgun in iso/ks.template -ln -s ${repodir}/mos-centos ${wwwdir}/mos-centos -ln -s ${repodir}/extra-repos ${wwwdir}/extra-repos - -# Prepare local repository specification -rm /etc/yum.repos.d/CentOS*.repo -cp ${SOURCE}/extra-repos/extra.repo /etc/yum.repos.d/ -cat > /etc/yum.repos.d/nailgun.repo << EOF -[nailgun] -name=Nailgun Local Repo -baseurl=file:/var/www/nailgun/${OPENSTACK_VERSION}/centos/x86_64 -gpgcheck=0 -[mos] -name=MOS Local Repo -baseurl=file:/var/www/nailgun/${OPENSTACK_VERSION}/mos-centos/x86_64 -gpgcheck=0 -EOF -%end - - - - - -%post --log=/root/anaconda-post-configure-sysconfig.log -#!/bin/bash -set -x - -source "/root/anaconda.cmdline.vars" -SOURCE=/tmp/source -FS=/tmp/fs - -# Prepare bootstrap_admin_node config -mkdir -p /etc/fuel -cat > /etc/fuel/bootstrap_admin_node.conf << EOF -#Set to yes to run Fuel Setup -#Set to no to accept default settings -ADMIN_INTERFACE=${adminif} -showmenu=${showmenu:-yes} -wait_for_external_config=${wait_for_external_config:-no} -EOF - -# Unmounting source -umount -f ${SOURCE} || true -rm -rf ${SOURCE} - -umount -f ${FS} || true -rm -rf ${FS} - -%end - - - -%post --log=/root/anaconda-post-install-extrapackages.log -#!/bin/bash -set -x - -MASTER_NODE_EXTRA_PACKAGES="" -source "/root/anaconda.cmdline.vars" - -if [ -n "${MASTER_NODE_EXTRA_PACKAGES}" ]; then - for pkg in ${MASTER_NODE_EXTRA_PACKAGES}; do - yum -y install ${pkg} - done -fi - -%end - -%post --log=/root/anaconda-post-configure-autologon.log -#!/bin/bash -set -x - -# Enable once root autologin for initial setup -mkdir -p /etc/systemd/system/getty@tty1.service.d/ -cat > /etc/systemd/system/getty@tty1.service.d/autologin.conf << 'EOF' -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin root --noclear %I 115200 linux -EOF - -# Exec bootstrap_admin_node.sh if autologin enabled -cat >> /root/.bashrc << 'EOF' -if [[ "$(tty)" == "/dev/tty1" && -f /etc/systemd/system/getty@tty1.service.d/autologin.conf ]]; then - rm -Rf "/etc/systemd/system/getty@tty1.service.d" - /bin/systemctl daemon-reload - yum makecache - yum install -y fuel-setup - if [ -x /usr/sbin/bootstrap_admin_node.sh ]; then - exec /usr/sbin/bootstrap_admin_node.sh - fi -fi -EOF -%end - - -%post --nochroot --log=/mnt/sysimage/root/anaconda-post-interface-settings.log -#!/bin/bash -set -x - -source "/mnt/sysimage/root/anaconda.cmdline.vars" - -if [[ ! -z $adminif ]]; then - rm -f /mnt/sysimage/etc/sysconfig/network-scripts/ifcfg-${ifname%%:*} - sed "s/${ifname%%:*}/${adminif}/g" \ - /etc/sysconfig/network-scripts/ifcfg-${ifname%%:*} > \ - /mnt/sysimage/etc/sysconfig/network-scripts/ifcfg-${adminif} -fi -%end diff --git a/iso/ks.yaml b/iso/ks.yaml deleted file mode 100644 index bd93ec563..000000000 --- a/iso/ks.yaml +++ /dev/null @@ -1 +0,0 @@ -reboot: reboot --eject diff --git a/iso/module.mk b/iso/module.mk deleted file mode 100644 index ab7542b50..000000000 --- a/iso/module.mk +++ /dev/null @@ -1,199 +0,0 @@ -.PHONY: all iso listing -.DELETE_ON_ERROR: $(ISO_PATH) - -all: iso listing - -ISOROOT:=$(BUILD_DIR)/iso/isoroot - -iso: $(ISO_PATH) - -listing: $(BUILD_DIR)/iso/isoroot.done $(BUILD_DIR)/mirror/build.done - -find $(BUILD_DIR)/iso/isoroot \ - -regextype posix-egrep \ - -regex '.*(fuel|astute|network-checker|nailgun|packetary|shotgun).*\.rpm' | \ - while read package_file; do \ - echo; \ - echo $$(basename $$package_file); \ - rpm -q --changelog -p $$package_file | head -12; \ - done > $(BUILD_DIR)/listing-package-changelog.txt - -################### -# BUILD IDENTIFIERS -################### - -ifdef BUILD_NUMBER -$(BUILD_DIR)/iso/isoroot.done: $(ISOROOT)/fuel_build_number -$(ISOROOT)/fuel_build_number: - echo "$(BUILD_NUMBER)" > $@ -endif - -$(BUILD_DIR)/iso/isoroot.done: $(ISOROOT)/fuel_build_id -$(ISOROOT)/fuel_build_id: - echo "$(BUILD_ID)" > $@ - -############## -# CUSTOM REPOS -############## - -define default_deb_repos -- name: mos - suite: $(MIRROR_MOS_UBUNTU_SUITE) -endef - -# if we are not building packages and sync repos only, we MUST use -# the same suit as we use during debmirroring -ifeq ($(BUILD_PACKAGES),0) -$(BUILD_DIR)/iso/isoroot.done: $(ISOROOT)/default_deb_repos.yaml -endif -$(ISOROOT)/default_deb_repos.yaml: export default_deb_repos_content:=$(default_deb_repos) -$(ISOROOT)/default_deb_repos.yaml: - /bin/echo -e "$${default_deb_repos_content}\n" > $@ - -############### -# CENTOS MIRROR -############### -$(BUILD_DIR)/iso/isoroot-centos.done: \ - $(BUILD_DIR)/mirror/build.done \ - $(BUILD_DIR)/mirror/make-changelog.done \ - $(BUILD_DIR)/packages/build.done \ - $(BUILD_DIR)/iso/isoroot-dotfiles.done - mkdir -p $(ISOROOT) - rsync -rp $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/ $(ISOROOT) - rsync -rp $(LOCAL_MIRROR_MOS_CENTOS) $(ISOROOT) - rsync -rp $(LOCAL_MIRROR)/extra-repos $(ISOROOT) - rsync -rp $(LOCAL_MIRROR)/centos-packages.changelog $(ISOROOT) - $(ACTION.TOUCH) - -############### -# UBUNTU MIRROR -############### -$(BUILD_DIR)/iso/isoroot-ubuntu.done: \ - $(BUILD_DIR)/mirror/build.done \ - $(BUILD_DIR)/mirror/make-changelog.done \ - $(BUILD_DIR)/packages/build.done \ - $(BUILD_DIR)/iso/isoroot-dotfiles.done - mkdir -p $(ISOROOT)/ubuntu - rsync -rp $(LOCAL_MIRROR_UBUNTU_OS_BASEURL)/ $(ISOROOT)/ubuntu/ - rsync -rp $(LOCAL_MIRROR)/ubuntu-packages.changelog $(ISOROOT) - $(ACTION.TOUCH) - -######################## -# Extra files -######################## - -$(BUILD_DIR)/iso/isoroot-dotfiles.done: \ - $(ISOROOT)/.discinfo \ - $(ISOROOT)/.treeinfo - $(ACTION.TOUCH) - -$(BUILD_DIR)/iso/isoroot-files.done: \ - $(BUILD_DIR)/iso/isoroot-dotfiles.done \ - $(ISOROOT)/isolinux/isolinux.cfg \ - $(ISOROOT)/isolinux/splash.jpg \ - $(ISOROOT)/ks.cfg - $(ACTION.TOUCH) - -$(ISOROOT)/.discinfo: $(SOURCE_DIR)/iso/.discinfo ; $(ACTION.COPY) -$(ISOROOT)/.treeinfo: $(SOURCE_DIR)/iso/.treeinfo ; $(ACTION.COPY) - -$(ISOROOT)/ks.yaml: - @mkdir -p $(@D) - cp $(KSYAML) $@ - -$(ISOROOT)/isolinux/isolinux.cfg: $(SOURCE_DIR)/iso/isolinux/isolinux.cfg ; $(ACTION.COPY) -$(ISOROOT)/isolinux/splash.jpg: $(SOURCE_DIR)/iso/isolinux/splash.jpg ; $(ACTION.COPY) -$(ISOROOT)/ks.cfg: $(SOURCE_DIR)/iso/ks.template $(SOURCE_DIR)/iso/ks.py $(ISOROOT)/ks.yaml - python $(SOURCE_DIR)/iso/ks.py \ - -t $(SOURCE_DIR)/iso/ks.template \ - -c $(ISOROOT)/ks.yaml \ - -o $@.tmp - mv $@.tmp $@ - - -######################## -# Iso image root file system. -######################## - -$(BUILD_DIR)/iso/isoroot.done: \ - $(BUILD_DIR)/iso/isoroot-centos.done \ - $(BUILD_DIR)/iso/isoroot-ubuntu.done \ - $(BUILD_DIR)/iso/isoroot-files.done - $(ACTION.TOUCH) - -######################## -# Building CD and USB stick images -######################## - -# ISO_VOLUME_ID can't have whitespaces or other non-alphanumeric characters 'as is'. -# They must be represented as \xNN, where NN is the hexadecimal representation of the character. -# For example, \x20 is a white space (" "). -# This is the limitation of kickstart boot options. - -ISO_VOLUME_ID:=OpenStack_Fuel -ISO_VOLUME_PREP:="Fuel team" - -# keep in mind that mkisofs touches some files inside directory -# from which it builds iso image -# that is why we need to make isoroot.done dependent on some files -# and then copy these files into another directory -$(ISO_PATH): $(BUILD_DIR)/iso/isoroot.done - rm -f $@ - mkdir -p $(BUILD_DIR)/iso/isoroot-mkisofs $(@D) - rsync -a --delete $(ISOROOT)/ $(BUILD_DIR)/iso/isoroot-mkisofs - sudo sed -r -i -e "s/ip=[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/ip=$(MASTER_IP)/" $(BUILD_DIR)/iso/isoroot-mkisofs/isolinux/isolinux.cfg - sudo sed -r -i -e "s/dns1=[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/dns1=$(MASTER_DNS)/" $(BUILD_DIR)/iso/isoroot-mkisofs/isolinux/isolinux.cfg - sudo sed -r -i -e "s/netmask=[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/netmask=$(MASTER_NETMASK)/" $(BUILD_DIR)/iso/isoroot-mkisofs/isolinux/isolinux.cfg - sudo sed -r -i -e "s/gw=[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/gw=$(MASTER_GW)/" $(BUILD_DIR)/iso/isoroot-mkisofs/isolinux/isolinux.cfg - sudo sed -r -i -e "s/will_be_substituted_with_PRODUCT_VERSION/$(PRODUCT_VERSION)/" $(BUILD_DIR)/iso/isoroot-mkisofs/isolinux/isolinux.cfg - sudo sed -r -i -e 's/will_be_substituted_with_ISO_VOLUME_ID/$(ISO_VOLUME_ID)/g' $(BUILD_DIR)/iso/isoroot-mkisofs/isolinux/isolinux.cfg - sudo sed -r -i -e 's/will_be_substituted_with_ISO_VOLUME_ID/$(ISO_VOLUME_ID)/g' $(BUILD_DIR)/iso/isoroot-mkisofs/ks.cfg - - - mkdir -p $(BUILD_DIR)/iso/efi_tmp/efi_image - # We need to have a partition which will be pointed from ISO as efi partition - # vmlinuz + initrd + bootloader + conffile = about 38MB. 100M should be enough ^_^ - dd bs=1M count=100 if=/dev/zero of=$(BUILD_DIR)/iso/efi_tmp/efiboot.img - # UEFI standard say to us that EFI partition should be some FAT-related filesystem - mkfs.vfat -n EFI $(BUILD_DIR)/iso/efi_tmp/efiboot.img - sudo umount -l $(BUILD_DIR)/iso/efi_tmp/efi_image || true - sudo mount $(BUILD_DIR)/iso/efi_tmp/efiboot.img $(BUILD_DIR)/iso/efi_tmp/efi_image - - # This needs to be edited in place due to some strange implementations of UEFI - # For example, Tianocore OVMF will not use efiboot.img. Instead, it looks for - # bootloader and it conffiles in /EFI/BOOT/* on main ISO partition (with ISO9660 fs) - echo > $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - echo "default=0" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - #echo "splashimage=/EFI/BOOT/splash.xpm.gz" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - echo "timeout 300" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - echo "hiddenmenu" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - echo "title DVD Fuel Install (Static IP)" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - # efiboot.img is a partition with filesystem now and /vmlinuz there will be pointed - # to root of it - echo " kernel /vmlinuz biosdevname=0 ks=cdrom:/ks.cfg ip=$(MASTER_IP) gw=$(MASTER_GW) dns1=$(MASTER_DNS) netmask=$(MASTER_NETMASK) hostname=fuel.domain.tld showmenu=yes" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - echo " initrd /initrd.img" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - echo "title USB Fuel Install (Static IP)" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - echo " kernel /vmlinuz biosdevname=0 repo=hd:LABEL=\"$(ISO_VOLUME_ID)\":/ ks=hd:LABEL=\"$(ISO_VOLUME_ID)\":/ks.cfg ip=$(MASTER_IP) gw=$(MASTER_GW) dns1=$(MASTER_DNS) netmask=$(MASTER_NETMASK) hostname=fuel.domain.tld showmenu=yes" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - echo " initrd /initrd.img" >> $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf - - # But many UEFI implementations will use our efiboot.img and if we want to boot from it, - # we also need to place kernel and initrd there (and bootloader and conffile to it too) - sudo cp -f $(BUILD_DIR)/iso/isoroot-mkisofs/isolinux/vmlinuz $(BUILD_DIR)/iso/efi_tmp/efi_image/ - sudo cp -f $(BUILD_DIR)/iso/isoroot-mkisofs/isolinux/initrd.img $(BUILD_DIR)/iso/efi_tmp/efi_image/ - sudo mkdir -p $(BUILD_DIR)/iso/efi_tmp/efi_image/EFI/BOOT/ - sudo cp -f $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.conf $(BUILD_DIR)/iso/efi_tmp/efi_image/EFI/BOOT/ - sudo cp -f $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/BOOTX64.EFI $(BUILD_DIR)/iso/efi_tmp/efi_image/EFI/BOOT/ - #sudo cp -f $(BUILD_DIR)/iso/isoroot-mkisofs/EFI/BOOT/splash.xpm.gz $(BUILD_DIR)/iso/efi_tmp/efi_image/EFI/BOOT/ - sudo umount $(BUILD_DIR)/iso/efi_tmp/efi_image - cp -f $(BUILD_DIR)/iso/efi_tmp/efiboot.img $(BUILD_DIR)/iso/isoroot-mkisofs/images/ - sudo rm -rf $(BUILD_DIR)/iso/efi_tmp/ - - xorriso -as mkisofs \ - -V $(ISO_VOLUME_ID) -p $(ISO_VOLUME_PREP) \ - -J -R \ - -graft-points \ - -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table \ - -isohybrid-mbr /usr/lib/syslinux/isohdpfx.bin \ - -eltorito-alt-boot -e images/efiboot.img -no-emul-boot \ - -isohybrid-gpt-basdat \ - -o $@ $(BUILD_DIR)/iso/isoroot-mkisofs - implantisomd5 $@ diff --git a/mirror/centos/boot.mk b/mirror/centos/boot.mk deleted file mode 100644 index e927f96a5..000000000 --- a/mirror/centos/boot.mk +++ /dev/null @@ -1,46 +0,0 @@ -ISOLINUX_FILES:=boot.msg grub.conf initrd.img isolinux.bin memtest vesamenu.c32 vmlinuz -IMAGES_FILES:=efiboot.img boot.iso -LIVEOS_FILES:=squashfs.img -PXEBOOT_FILES:=initrd.img vmlinuz -EFI_FILES:=BOOTX64.EFI MokManager.efi grub.cfg grubx64.efi - -MIRROR_CENTOS_KERNEL?=$(MIRROR_CENTOS) -MIRROR_CENTOS_KERNEL_BASEURL?=$(MIRROR_CENTOS_KERNEL)/os/$(CENTOS_ARCH) - -# centos isolinux files -$(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/isolinux/,$(ISOLINUX_FILES)): - @mkdir -p $(@D) - wget -nv -O $@.tmp $(MIRROR_CENTOS_KERNEL_BASEURL)/isolinux/$(@F) - mv $@.tmp $@ - -# centos EFI boot images -$(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/EFI/BOOT/,$(EFI_FILES)): - @mkdir -p $(@D) - wget -nv -O $@.tmp $(MIRROR_CENTOS_KERNEL_BASEURL)/EFI/BOOT/$(@F) - mv $@.tmp $@ - -# centos boot images -$(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/images/,$(IMAGES_FILES)): - @mkdir -p $(@D) - wget -nv -O $@.tmp $(MIRROR_CENTOS_KERNEL_BASEURL)/images/$(@F) - mv $@.tmp $@ - -# centos pxeboot images -$(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/images/pxeboot/,$(PXEBOOT_FILES)): - @mkdir -p $(@D) - wget -nv -O $@.tmp $(MIRROR_CENTOS_KERNEL_BASEURL)/images/pxeboot/$(@F) - mv $@.tmp $@ - -# centos liveos images -$(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/LiveOS/,$(LIVEOS_FILES)): - @mkdir -p $(@D) - wget -nv -O $@.tmp $(MIRROR_CENTOS_KERNEL_BASEURL)/LiveOS/$(@F) - mv $@.tmp $@ - -$(BUILD_DIR)/mirror/centos/boot.done: \ - $(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/images/,$(IMAGES_FILES)) \ - $(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/EFI/BOOT/,$(EFI_FILES)) \ - $(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/isolinux/,$(ISOLINUX_FILES)) \ - $(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/images/pxeboot/,$(PXEBOOT_FILES)) \ - $(addprefix $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/LiveOS/,$(LIVEOS_FILES)) - $(ACTION.TOUCH) diff --git a/mirror/centos/extra-repos.mk b/mirror/centos/extra-repos.mk deleted file mode 100644 index 0d3207eff..000000000 --- a/mirror/centos/extra-repos.mk +++ /dev/null @@ -1,35 +0,0 @@ -extra_centos_empty_installroot:=$(BUILD_DIR)/mirror/centos/dummy_extra_installroot - -$(BUILD_DIR)/mirror/centos/extra-repos-download.done: $(BUILD_DIR)/mirror/centos/yum-config.done -$(BUILD_DIR)/mirror/centos/extra-repos-download.done: - mkdir -p $(LOCAL_MIRROR)/extra-repos - $(foreach repo,$(EXTRA_RPM_REPOS),$(call extra_repo_download,$(repo));) - $(ACTION.TOUCH) - -$(LOCAL_MIRROR)/extra-repos/extra.repo: $(call depv,EXTRA_RPM_REPOS) -$(LOCAL_MIRROR)/extra-repos/extra.repo: \ - export fuelnode_repos:=$(foreach repo,$(EXTRA_RPM_REPOS),\n$(call create_fuelnode_repo,$(repo))\n) -$(LOCAL_MIRROR)/extra-repos/extra.repo: - mkdir -p $(@D) - /bin/echo -e "$${fuelnode_repos}" > $@ - -$(BUILD_DIR)/mirror/centos/extra-repos.done: $(LOCAL_MIRROR)/extra-repos/extra.repo -$(BUILD_DIR)/mirror/centos/extra-repos.done: $(BUILD_DIR)/mirror/centos/extra-repos-download.done -$(BUILD_DIR)/mirror/centos/extra-repos.done: - $(foreach repo,$(EXTRA_RPM_REPOS),$(call extra_repo_metadata,$(repo));) - $(ACTION.TOUCH) - -define extra_repo_download -mkdir -p "$(extra_centos_empty_installroot)/cache" ; -set -ex ; env TMPDIR="$(extra_centos_empty_installroot)/cache" \ - TMP="$(extra_centos_empty_installroot)/cache" \ - reposync --downloadcomps --plugins --delete --arch=$(CENTOS_ARCH) \ - --cachedir="$(extra_centos_empty_installroot)/cache" \ - -c $(BUILD_DIR)/mirror/centos/etc/yum.conf --repoid=$(call get_repo_name,$1) \ - -p $(LOCAL_MIRROR)/extra-repos/ -endef - -define extra_repo_metadata -set -ex ; createrepo -g $(LOCAL_MIRROR)/extra-repos/$(call get_repo_name,$1)/comps.xml \ - -o $(LOCAL_MIRROR)/extra-repos/$(call get_repo_name,$1)/ $(LOCAL_MIRROR)/extra-repos/$(call get_repo_name,$1)/ -endef diff --git a/mirror/centos/module.mk b/mirror/centos/module.mk deleted file mode 100644 index 5c05ad6db..000000000 --- a/mirror/centos/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# This module downloads required upstream rpm packages and creates rpm repository. -include $(SOURCE_DIR)/mirror/centos/repo.mk -# This module downloads centos installation images. -include $(SOURCE_DIR)/mirror/centos/boot.mk -# This module downloads MOS rpm repository -include $(SOURCE_DIR)/mirror/centos/mos-repo.mk -# This module downloads extra rpm repositories -include $(SOURCE_DIR)/mirror/centos/extra-repos.mk - - -$(BUILD_DIR)/mirror/centos/build.done: \ - $(BUILD_DIR)/mirror/centos/repo.done \ - $(BUILD_DIR)/mirror/centos/boot.done \ - $(BUILD_DIR)/mirror/centos/mos-repo.done \ - $(BUILD_DIR)/mirror/centos/extra-repos.done - $(ACTION.TOUCH) - -mirror-centos: $(BUILD_DIR)/mirror/centos/build.done -repo-centos: $(BUILD_DIR)/mirror/centos/repo.done -repo-mos-centos: $(BUILD_DIR)/mirror/centos/mos-repo.done -extra-repos-centos: $(BUILD_DIR)/mirror/centos/extra-repos.done - -.PHONY: mirror-centos repo-centos repo-mos-centos extra-repos-centos diff --git a/mirror/centos/mos-repo.mk b/mirror/centos/mos-repo.mk deleted file mode 100644 index b8f48ef5a..000000000 --- a/mirror/centos/mos-repo.mk +++ /dev/null @@ -1,18 +0,0 @@ -mos_centos_empty_installroot:=$(BUILD_DIR)/mirror/centos/dummy_mos_installroot - -$(BUILD_DIR)/mirror/centos/mos-download.done: $(BUILD_DIR)/mirror/centos/yum-config.done - mkdir -p $(@D) - mkdir -p $(LOCAL_MIRROR_MOS_CENTOS) - mkdir -p "$(mos_centos_empty_installroot)/cache" - set -ex ; env TMPDIR="$(mos_centos_empty_installroot)/cache" \ - TMP="$(mos_centos_empty_installroot)/cache" \ - reposync --norepopath --downloadcomps --plugins --delete --arch=$(CENTOS_ARCH) \ - --cachedir="$(mos_centos_empty_installroot)/cache" \ - -c $(BUILD_DIR)/mirror/centos/etc/yum.conf --repoid=fuel -p $(LOCAL_MIRROR_MOS_CENTOS) - $(ACTION.TOUCH) - -$(BUILD_DIR)/mirror/centos/mos-repo.done: $(BUILD_DIR)/mirror/centos/mos-download.done - createrepo -g $(LOCAL_MIRROR_MOS_CENTOS)/comps.xml \ - -o $(LOCAL_MIRROR_MOS_CENTOS)/ $(LOCAL_MIRROR_MOS_CENTOS)/ - $(ACTION.TOUCH) - diff --git a/mirror/centos/repo.mk b/mirror/centos/repo.mk deleted file mode 100644 index d71c5357b..000000000 --- a/mirror/centos/repo.mk +++ /dev/null @@ -1,190 +0,0 @@ -include $(SOURCE_DIR)/mirror/centos/yum_repos.mk - -.PHONY: show-yum-urls-centos show-yum-urls-centos-full show-yum-repos-centos - -MIRROR_CENTOS_OS_BASEURL?=$(MIRROR_CENTOS)/os/$(CENTOS_ARCH) - -$(BUILD_DIR)/mirror/centos/etc/yum.conf: $(call depv,yum_conf) -$(BUILD_DIR)/mirror/centos/etc/yum.conf: export contents:=$(yum_conf) -$(BUILD_DIR)/mirror/centos/etc/yum.conf: - mkdir -p $(@D) - /bin/echo -e "$${contents}" > $@ - -$(BUILD_DIR)/mirror/centos/etc/yum-plugins/priorities.py: \ - $(SOURCE_DIR)/mirror/centos/yum-priorities-plugin.py - mkdir -p $(@D) - cp $(SOURCE_DIR)/mirror/centos/yum-priorities-plugin.py $@ - -# DENY_RPM_DOWNGRADE=0 - Disable full_match flag for yum priorities plugin. -# This means that we choose package candidate not by full match -# of version, realase and arch. This may lead to downgrading of -# packages (actually this is what we may want sometimes for -# testing purposes). Please use priorities plugin carefully - -$(BUILD_DIR)/mirror/centos/etc/yum/pluginconf.d/priorities.conf: - mkdir -p $(@D) - /bin/echo -e "[main]\nenabled=1\ncheck_obsoletes=1\nfull_match=$(DENY_RPM_DOWNGRADE)" > $@ - -$(BUILD_DIR)/mirror/centos/etc/yum.repos.d/base.repo: $(call depv,YUM_REPOS) -$(BUILD_DIR)/mirror/centos/etc/yum.repos.d/base.repo: \ - export contents:=$(foreach repo,$(YUM_REPOS),\n$(yum_repo_$(repo))\n) -$(BUILD_DIR)/mirror/centos/etc/yum.repos.d/base.repo: - @mkdir -p $(@D) - /bin/echo -e "$${contents}" > $@ - -$(BUILD_DIR)/bin/yumdownloader: $(SOURCE_DIR)/mirror/centos/yumdownloader-deps.patch - mkdir -p $(@D) - cp -a /usr/bin/yumdownloader $(BUILD_DIR)/yumdownloader - ( cd $(BUILD_DIR) && patch -p0 ) < $< - cp -a $(BUILD_DIR)/yumdownloader $@ - -$(BUILD_DIR)/mirror/centos/etc/yum.repos.d/extra.repo: $(call depv,EXTRA_RPM_REPOS) -$(BUILD_DIR)/mirror/centos/etc/yum.repos.d/extra.repo: \ - export contents:=$(foreach repo,$(EXTRA_RPM_REPOS),\n$(call create_extra_repo,$(repo))\n) -$(BUILD_DIR)/mirror/centos/etc/yum.repos.d/extra.repo: - @mkdir -p $(@D) - /bin/echo -e "$${contents}" > $@ - -centos_empty_installroot:=$(BUILD_DIR)/mirror/centos/dummy_installroot - -$(BUILD_DIR)/mirror/centos/yum-config.done: \ - $(BUILD_DIR)/bin/yumdownloader \ - $(BUILD_DIR)/mirror/centos/etc/yum.conf \ - $(BUILD_DIR)/mirror/centos/etc/yum.repos.d/base.repo \ - $(BUILD_DIR)/mirror/centos/etc/yum.repos.d/extra.repo \ - $(BUILD_DIR)/mirror/centos/etc/yum-plugins/priorities.py \ - $(BUILD_DIR)/mirror/centos/etc/yum/pluginconf.d/priorities.conf - rm -rf $(centos_empty_installroot) - mkdir -p $(centos_empty_installroot)/cache - $(ACTION.TOUCH) - -$(BUILD_DIR)/mirror/centos/yum.done: $(BUILD_DIR)/mirror/centos/rpm-download.done - $(ACTION.TOUCH) - -$(BUILD_DIR)/mirror/centos/rpm-download.done: $(BUILD_DIR)/mirror/centos/urls.list - dst="$(LOCAL_MIRROR_CENTOS_OS_BASEURL)/Packages"; \ - mkdir -p "$$dst" && \ - xargs -n1 -P4 wget -Nnv -P "$$dst" < $< - $(ACTION.TOUCH) - -# BUILD_PACKAGES=0 - apply patch for requirements rpm, since we need fuel-packages -ifeq ($(BUILD_PACKAGES),0) -$(BUILD_DIR)/requirements-rpm.txt: \ - $(SOURCE_DIR)/requirements-rpm.txt \ - $(SOURCE_DIR)/requirements-fuel-rpm.txt - cat $^ | sort -u > $@.tmp - mv $@.tmp $@ -else -$(BUILD_DIR)/requirements-rpm.txt: $(SOURCE_DIR)/requirements-rpm.txt - $(ACTION.COPY) -endif - -# Strip the comments and sort the list alphabetically -$(BUILD_DIR)/mirror/centos/requirements-rpm-0.txt: $(BUILD_DIR)/requirements-rpm.txt - mkdir -p $(@D) && \ - grep -v -e '^#' $< > $@.tmp && \ - sort -u < $@.tmp > $@.pre && \ - mv $@.pre $@ - -$(BUILD_DIR)/mirror/centos/urls.list: $(BUILD_DIR)/mirror/centos/requirements-rpm-0.txt \ - $(BUILD_DIR)/mirror/centos/yum-config.done - touch "$(BUILD_DIR)/mirror/centos/conflicting-packages-0.lst" - # 1st pass - find out which packages conflict - # 2nd pass - get the URLs of non-conflicting packages - # 3rd pass (under the else clause) - process the conflicting rpms one by one - count=0; \ - while true; do \ - if [ $$count -gt 1 ]; then \ - echo "Unable to resolve packages dependencies" >&2; \ - cat $(BUILD_DIR)/mirror/centos/yumdownloader-1.out >&2; \ - exit 1; \ - fi; \ - requirements_rpm="$(BUILD_DIR)/mirror/centos/requirements-rpm-$${count}.txt"; \ - requirements_rpm_next="$(BUILD_DIR)/mirror/centos/requirements-rpm-$$((count+1)).txt"; \ - out="$(BUILD_DIR)/mirror/centos/yumdownloader-$${count}.out"; \ - log="$(BUILD_DIR)/mirror/centos/yumdownloader-$${count}.log"; \ - conflict_lst="$(BUILD_DIR)/mirror/centos/conflicting-packages-$${count}.lst"; \ - conflict_lst_next="$(BUILD_DIR)/mirror/centos/conflicting-packages-$$((count+1)).lst"; \ - if ! env \ - TMPDIR="$(centos_empty_installroot)/cache" \ - TMP="$(centos_empty_installroot)/cache" \ - $(BUILD_DIR)/bin/yumdownloader -q --urls \ - --archlist=$(CENTOS_ARCH) \ - --installroot="$(centos_empty_installroot)" \ - -c $(BUILD_DIR)/mirror/centos/etc/yum.conf \ - --resolve \ - `cat $${requirements_rpm}` > "$$out" 2>"$$log"; then \ - sed -rne 's/^([a-zA-Z0-9_-]+)\s+conflicts with\s+(.+)$$/\1/p' < "$$out" > "$${conflict_lst_next}.pre" && \ - # Package X can declare conflict with package Y; but package Y is not obliged \ - # to declare a conflict with package X. yum will report that X conflicts with Y. \ - # We need to figure out that Y conflicts with X on our own. \ - sed -rne 's/^([a-zA-Z0-9_-]+)\s+conflicts with\s+(.+)$$/\2/p' < "$$out" > "$${conflict_lst_next}.more" && \ - while read nvra; do \ - nvr="$${nvra%.*}"; nv="$${nvr%-*}"; n="$${nv%-*}"; echo $$n; \ - done < "$${conflict_lst_next}.more" >> "$${conflict_lst_next}.pre" && \ - cat "$${conflict_lst_next}.pre" "$$conflict_lst" | sort -u > "$$conflict_lst_next" && \ - comm -23 "$$requirements_rpm" "$$conflict_lst_next" > "$${requirements_rpm}.new.pre" && \ - sort -u < "$${requirements_rpm}.new.pre" > "$${requirements_rpm_next}"; \ - else \ - conflicting_pkgs_urls="$(BUILD_DIR)/mirror/centos/urls_conflicting.lst"; \ - nonconflicting_pkgs="$$requirements_rpm"; \ - # Now process conflicting packages one by one. There is a small problem: \ - # in the original requirements-rpm.txt quite a number of packages are \ - # pinned to specific versions. These pins should be taken into account \ - # to avoid having several versions of the same package. For instance, \ - # zabbix-web-* depends on httpd, so the latest version of httpd gets \ - # installed along with the one listed in the requirements-rpm.txt. \ - # Therefore add the set of all nonconflicting packages to the package \ - # being processed to take into account version pins. \ - for pkg in `cat $$conflict_lst`; do \ - if ! env \ - TMPDIR="$(centos_empty_installroot)/cache" \ - TMP="$(centos_empty_installroot)/cache" \ - $(BUILD_DIR)/bin/yumdownloader -q --urls \ - --archlist=$(CENTOS_ARCH) \ - --installroot="$(centos_empty_installroot)" \ - -c "$(BUILD_DIR)/mirror/centos/etc/yum.conf" \ - --resolve $$pkg `cat $$nonconflicting_pkgs`; then \ - echo "Failed to resolve package $$pkg" >&2; \ - exit 1; \ - fi; \ - done > "$$conflicting_pkgs_urls" && \ - cat "$$out" "$$conflicting_pkgs_urls" > "$@.out" && \ - break; \ - fi; \ - count=$$((count+1)); \ - done - # yumdownloader -q prints logs to stdout, filter them out - sed -rne '/\.rpm$$/ {p}' < $@.out > $@.pre - sort -u < $@.pre > $@.tmp - mv $@.tmp $@.full - grep "$(MIRROR_CENTOS)" $@.full > $@ - -show-yum-urls-centos: $(BUILD_DIR)/mirror/centos/urls.list - cat $< - -show-yum-urls-centos-full: $(BUILD_DIR)/mirror/centos/urls.list - cat $(BUILD_DIR)/mirror/centos/urls.list.full - -show-yum-repos-centos: \ - $(BUILD_DIR)/mirror/centos/etc/yum.repos.d/base.repo \ - $(BUILD_DIR)/mirror/centos/etc/yum.repos.d/extra.repo - cat $^ - -$(LOCAL_MIRROR_CENTOS_OS_BASEURL)/comps.xml: \ - export COMPSXML=$(shell wget -nv -qO- $(MIRROR_CENTOS_OS_BASEURL)/repodata/repomd.xml | grep -m 1 '$(@F)' | awk -F'"' '{ print $$2 }') -$(LOCAL_MIRROR_CENTOS_OS_BASEURL)/comps.xml: - @mkdir -p $(@D) - if ( echo $${COMPSXML} | grep -q '\.gz$$' ); then \ - wget -nv -O $@.gz $(MIRROR_CENTOS_OS_BASEURL)/$${COMPSXML}; \ - gunzip $@.gz; \ - else \ - wget -nv -O $@ $(MIRROR_CENTOS_OS_BASEURL)/$${COMPSXML}; \ - fi - -$(BUILD_DIR)/mirror/centos/repo.done: \ - $(BUILD_DIR)/mirror/centos/yum.done \ - | $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/comps.xml - createrepo -g $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/comps.xml \ - -o $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/ $(LOCAL_MIRROR_CENTOS_OS_BASEURL)/ - $(ACTION.TOUCH) diff --git a/mirror/centos/yum-priorities-plugin.py b/mirror/centos/yum-priorities-plugin.py deleted file mode 100644 index b85175396..000000000 --- a/mirror/centos/yum-priorities-plugin.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/python -# -# yum-plugin-priorities 0.0.7 -# -# Copyright (c) 2006-2007 Daniel de Kok -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# This plugins is inspired by the protectbase plugin, and enables/disables -# packages based on a repository priority. -# -# You can install this plugin by copying it to /usr/lib/yum-plugins. To -# enable this plugin, make sure that you have 'plugins=1' in /etc/yum.conf, -# and create the file /etc/yum/pluginconf.d/priorities.conf with the -# following content: -# -# [main] -# enabled=1 -# -# If you also want the plugin to protect high-priority repositories against -# obsoletes in low-priority repositories, enable the 'check_obsoletes' bool: -# -# check_obsoletes=1 -# -# By default, this plugin excludes packages from lower priority repositories -# based on the package name. If you want to exclude packages based only the -# package name and architecture, enable the 'only_samearch' bool: -# -# only_samearch=1 -# -# If you want to be able to set package as the fully qualified package name -# including architecture and package version, enable 'full_match' bool: -# -# full_match=1 -# -# If full_match is enabled then check_obsoletes will be forced to disable -# -# You can add priorities to repositories, by adding the line: -# -# priority=N -# -# to the repository entry, where N is an integer number. The default -# priority for repositories is 99. The repositories with the lowest -# number have the highest priority. -# -# Please report errors to Daniel de Kok - -from yum.constants import * -from yum.plugins import TYPE_CORE -from yum import config -import yum - -check_obsoletes = False -only_samearch = False -full_match = False - -requires_api_version = '2.1' -plugin_type = (TYPE_CORE,) - - -def config_hook(conduit): - global check_obsoletes - global only_samearch - global full_match - - # Plugin configuration - check_obsoletes = conduit.confBool('main', 'check_obsoletes', - default=False) - only_samearch = conduit.confBool('main', 'only_samearch', default=False) - full_match = conduit.confBool('main', 'full_match', default=False) - - if full_match: - check_obsoletes = False - - # Repo priorities - if yum.__version__ >= '2.5.0': - # New style : yum >= 2.5 - config.RepoConf.priority = config.IntOption(99) - else: - # Old add extra options style - conduit.registerOpt('priority', PLUG_OPT_INT, PLUG_OPT_WHERE_REPO, 99) - - # Command-line options. - parser = conduit.getOptParser() - if parser: - if hasattr(parser, 'plugin_option_group'): - parser = parser.plugin_option_group - parser.add_option( - '', '--samearch-priorities', dest='samearch', action='store_true', - default=False, - help="Priority-exclude packages based on name + arch") - - -def _all_repo_priorities_same(allrepos): - """ Are all repos at the same priority """ - first = None - for repo in allrepos: - if first is None: - first = repo.priority - elif first != repo.priority: - return False - return True - - -def exclude_hook(conduit): - global only_samearch - global check_obsoletes - global full_match - - allrepos = conduit.getRepos().listEnabled() - - # If they haven't done anything, don't do any work - if _all_repo_priorities_same(allrepos): - return - - # Check whether the user specified the --samearch option. - opts, commands = conduit.getCmdLine() - if opts and opts.samearch: - only_samearch = True - - cnt = 0 - if check_obsoletes and not conduit._base.conf.obsoletes: - check_obsoletes = False - if check_obsoletes: - obsoletes = conduit._base.up.rawobsoletes - - # Build a dictionary with package priorities. Either with arch or - # archless, based on the user's settings. - if only_samearch: - pkg_priorities = dict() - if check_obsoletes or not only_samearch: - pkg_priorities_archless = dict() - for repo in allrepos: - if repo.enabled: - if only_samearch: - repopkgs = _pkglist_to_dict(conduit.getPackages(repo), - repo.priority, True) - _mergeprioritydicts(pkg_priorities, repopkgs) - - if check_obsoletes or not only_samearch: - repopkgs_archless = _pkglist_to_dict( - conduit.getPackages(repo), repo.priority) - _mergeprioritydicts(pkg_priorities_archless, repopkgs_archless) - - # Eliminate packages that have a low priority - for repo in allrepos: - if repo.enabled: - for po in conduit.getPackages(repo): - delPackage = False - - if full_match: - pname = str(po) - else: - pname = po.name - - if only_samearch: - key = "%s.%s" % (pname, po.arch) - if (key in pkg_priorities and - pkg_priorities[key] < repo.priority): - delPackage = True - else: - key = "%s" % pname - if (key in pkg_priorities_archless and - pkg_priorities_archless[key] < repo.priority): - delPackage = True - - if delPackage: - conduit.delPackage(po) - cnt += 1 - conduit.info(3, " --> %s from %s excluded " - "(priority)" % (po, po.repoid)) - - # If this packages obsoletes other packages, check whether - # one of the obsoleted packages is not available through - # a repo with a higher priority. If so, remove this package. - if check_obsoletes: - if po.pkgtup in obsoletes: - obsolete_pkgs = obsoletes[po.pkgtup] - for obsolete_pkg in obsolete_pkgs: - pkg_name = obsolete_pkg[0] - if (pkg_name in pkg_priorities_archless - and pkg_priorities_archless[pkg_name] < - repo.priority): - conduit.delPackage(po) - cnt += 1 - conduit.info( - 3, " --> %s from %s excluded " - "(priority)" % (po, po.repoid)) - break - if cnt: - conduit.info(2, '%d packages excluded due to repository ' - 'priority protections' % cnt) - if check_obsoletes: - # Atm. the update object doesn't get updated when we manually exclude - # things ... so delete it. This needs to be re-written. - conduit._base.up = None - - -def _pkglist_to_dict(pl, priority, addArch=False): - global full_match - out = dict() - for p in pl: - if full_match: - pname = str(p) - else: - pname = p.name - if addArch: - key = "%s.%s" % (pname, p.arch) - out[key] = priority - else: - out[pname] = priority - return out - - -def _mergeprioritydicts(dict1, dict2): - for package in dict2.keys(): - if package not in dict1 or dict2[package] < dict1[package]: - dict1[package] = dict2[package] diff --git a/mirror/centos/yum_repos.mk b/mirror/centos/yum_repos.mk deleted file mode 100644 index 5b089fc39..000000000 --- a/mirror/centos/yum_repos.mk +++ /dev/null @@ -1,144 +0,0 @@ - -# Problem: --archlist=x86_64 really means "x86_64 and i686". Therefore yum -# tries to resolve dependencies of i686 packages. Sometimes this fails due -# to an upgraded x86_64 only package available in the fuel repo. For -# instance, when yum is asked to download dmraid package it tries to resolve -# the dependencies of i686 version. This fails since the upgraded -# device-mapper-libs package (from the fuel repo) is x86_64 only: -# Package: device-mapper-libs-1.02.79-8.el6.i686 (base) -# Requires: device-mapper = 1.02.79-8.el6 -# Available: device-mapper-1.02.79-8.el6.x86_64 (base) -# device-mapper = 1.02.79-8.el6 -# Installing: device-mapper-1.02.90-2.mira1.x86_64 (fuel) -# device-mapper = 1.02.90-2.mira1 -# The obvious solution is to exclude i686 packages. However syslinux -# package depends on i686 package syslinux-nonlinux (which contians -# the binaries that run in the syslinux environment). Since excluding -# packages by regexp is impossible (only glob patterns are supported) -# base and updates repos are "cloned". Those "cloned" repos contain -# a few whitelisted i686 packages (for now only syslinux). -# Note: these packages should be also excluded from base and updates. -x86_rpm_packages_whitelist:=syslinux* - -define yum_conf -[main] -cachedir=$(BUILD_DIR)/mirror/centos/cache -keepcache=0 -debuglevel=6 -logfile=$(BUILD_DIR)/mirror/centos/yum.log -exclude=ntp-dev* -exactarch=1 -obsoletes=1 -gpgcheck=0 -plugins=1 -pluginpath=$(BUILD_DIR)/mirror/centos/etc/yum-plugins -pluginconfpath=$(BUILD_DIR)/mirror/centos/etc/yum/pluginconf.d -reposdir=$(BUILD_DIR)/mirror/centos/etc/yum.repos.d -sslverify=False -endef - -define yum_repo_official -[base] -name=CentOS-$(CENTOS_RELEASE) - Base -#mirrorlist=http://mirrorlist.centos.org/?release=$(CENTOS_RELEASE)&arch=$(CENTOS_ARCH)&repo=os -baseurl=$(MIRROR_CENTOS)/os/$(CENTOS_ARCH) -gpgcheck=0 -enabled=1 -exclude=*i686 $(x86_rpm_packages_whitelist) -priority=90 - -[updates] -name=CentOS-$(CENTOS_RELEASE) - Updates -#mirrorlist=http://mirrorlist.centos.org/?release=$(CENTOS_RELEASE)&arch=$(CENTOS_ARCH)&repo=updates -baseurl=$(MIRROR_CENTOS)/updates/$(CENTOS_ARCH) -gpgcheck=0 -enabled=1 -exclude=*i686 $(x86_rpm_packages_whitelist) -priority=90 - -[base_i686_whitelisted] -name=CentOS-$(CENTOS_RELEASE) - Base -#mirrorlist=http://mirrorlist.centos.org/?release=$(CENTOS_RELEASE)&arch=$(CENTOS_ARCH)&repo=os -baseurl=$(MIRROR_CENTOS)/os/$(CENTOS_ARCH) -gpgcheck=0 -enabled=1 -includepkgs=$(x86_rpm_packages_whitelist) -priority=90 - -[updates_i686_whitelisted] -name=CentOS-$(CENTOS_RELEASE) - Updates -#mirrorlist=http://mirrorlist.centos.org/?release=$(CENTOS_RELEASE)&arch=$(CENTOS_ARCH)&repo=updates -baseurl=$(MIRROR_CENTOS)/updates/$(CENTOS_ARCH) -gpgcheck=0 -enabled=1 -includepkgs=$(x86_rpm_packages_whitelist) -priority=90 -endef - -define yum_repo_extras -[extras] -name=CentOS-$(CENTOS_RELEASE) - Extras -#mirrorlist=http://mirrorlist.centos.org/?release=$(CENTOS_RELEASE)&arch=$(CENTOS_ARCH)&repo=extras -baseurl=$(MIRROR_CENTOS)/extras/$(CENTOS_ARCH) -gpgcheck=0 -enabled=1 -exclude=*i686 -priority=90 - -[centosplus] -name=CentOS-$(CENTOS_RELEASE) - Plus -#mirrorlist=http://mirrorlist.centos.org/?release=$(CENTOS_RELEASE)&arch=$(CENTOS_ARCH)&repo=centosplus -baseurl=$(MIRROR_CENTOS)/centosplus/$(CENTOS_ARCH) -gpgcheck=0 -enabled=0 -priority=90 - -[contrib] -name=CentOS-$(CENTOS_RELEASE) - Contrib -#mirrorlist=http://mirrorlist.centos.org/?release=$(CENTOS_RELEASE)&arch=$(CENTOS_ARCH)&repo=contrib -baseurl=$(MIRROR_CENTOS)/contrib/$(CENTOS_ARCH) -gpgcheck=0 -enabled=0 -priority=90 -endef - -define yum_repo_fuel -[fuel] -name=Fuel Packages -baseurl=$(MIRROR_FUEL) -gpgcheck=0 -enabled=1 -priority=20 -exclude=*debuginfo* -endef - -# Accept EXTRA_RPM_REPOS in a form of a list of: name,url,priority -# Accept EXTRA_RPM_REPOS in a form of list of (default priority=10): name,url -get_repo_name=$(shell echo $1 | cut -d ',' -f 1) -get_repo_url=$(shell echo $1 | cut -d ',' -f2) -get_repo_priority=$(shell val=`echo $1 | cut -d ',' -f3`; echo $${val:-10}) - -# It's a callable object. -# Usage: $(call create_extra_repo,repo) -# where: -# repo=repo_name,http://path_to_the_repo,repo_priority -# repo_priority is a number from 1 to 99 -define create_extra_repo -[$(call get_repo_name,$1)] -name = Repo "$(call get_repo_name,$1)" -baseurl = $(call get_repo_url,$1) -gpgcheck = 0 -enabled = 1 -priority = $(call get_repo_priority,$1) -exclude=*debuginfo* -endef - -define create_fuelnode_repo -[$(call get_repo_name,$1)] -name = Repo "$(call get_repo_name,$1)" -baseurl = file:///var/www/nailgun/extra-repos/$(call get_repo_name,$1) -gpgcheck = 0 -enabled = 1 -priority = $(call get_repo_priority,$1) -endef - diff --git a/mirror/centos/yumdownloader-deps.patch b/mirror/centos/yumdownloader-deps.patch deleted file mode 100644 index ea46c10b4..000000000 --- a/mirror/centos/yumdownloader-deps.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- yumdownloader.orig 2013-11-15 00:01:02.000000000 +0400 -+++ yumdownloader 2015-05-21 12:48:25.877327687 +0300 -@@ -182,7 +182,7 @@ - - if not installable: # doing one at a time, apart from groups - self.logger.error('No Match for argument %s' % pkg) -- continue -+ sys.exit(1) - for newpkg in installable: - toActOn.extend(_best_convert_pkg2srcpkgs(self, opts, newpkg)) - if toActOn: -@@ -208,7 +208,12 @@ - self.tsInfo.addInstall(po) - self.localPackages.append(po) - # Resolve dependencies -- self.resolveDeps() -+ result, errmsgs = self.resolveDeps() -+ if result == 1: -+ self.logger.error('Dependency resolution failed') -+ for msg in errmsgs: -+ self.logger.error(msg) -+ sys.exit(1) - # Add newly added packages to the toDownload list - for pkg in self.tsInfo.getMembers(): - if not pkg in toDownload: diff --git a/mirror/module.mk b/mirror/module.mk deleted file mode 100644 index f6e466d77..000000000 --- a/mirror/module.mk +++ /dev/null @@ -1,22 +0,0 @@ -.PHONY: mirror clean clean-mirror make-changelog - -mirror: $(BUILD_DIR)/mirror/build.done -make-changelog: $(BUILD_DIR)/mirror/make-changelog.done - -clean: clean-mirror - -clean-mirror: - sudo rm -rf $(BUILD_DIR)/mirror - -include $(SOURCE_DIR)/mirror/centos/module.mk -include $(SOURCE_DIR)/mirror/ubuntu/module.mk - -$(BUILD_DIR)/mirror/build.done: \ - $(BUILD_DIR)/mirror/centos/build.done \ - $(BUILD_DIR)/mirror/ubuntu/build.done - $(ACTION.TOUCH) - -$(BUILD_DIR)/mirror/make-changelog.done: $(BUILD_DIR)/mirror/build.done - sudo bash -c "export LOCAL_MIRROR=$(LOCAL_MIRROR); \ - $(SOURCE_DIR)/report-changelog.sh" - $(ACTION.TOUCH) diff --git a/mirror/ubuntu/module.mk b/mirror/ubuntu/module.mk deleted file mode 100644 index 5b4d762dc..000000000 --- a/mirror/ubuntu/module.mk +++ /dev/null @@ -1,100 +0,0 @@ -.PHONY: mirror-ubuntu repo-ubuntu - -mirror-ubuntu: $(BUILD_DIR)/mirror/ubuntu/mirror.done -repo-ubuntu: $(BUILD_DIR)/mirror/ubuntu/repo.done - -define reprepro_dist_conf -Origin: Mirantis -Label: $(PRODUCT_NAME)$(PRODUCT_VERSION) -Suite: $(PRODUCT_NAME)$(PRODUCT_VERSION) -Codename: $(PRODUCT_NAME)$(PRODUCT_VERSION) -Description: Mirantis OpenStack mirror -Architectures: $(UBUNTU_ARCH) -Components: main restricted -DebIndices: Packages Release . .gz .bz2 -Update: - $(PRODUCT_NAME)$(PRODUCT_VERSION) -endef - -define reprepro_updates_conf -Suite: $(PRODUCT_NAME)$(PRODUCT_VERSION) -Name: $(PRODUCT_NAME)$(PRODUCT_VERSION) -Method: file:$(LOCAL_MIRROR_UBUNTU) -Components: main -Architectures: $(UBUNTU_ARCH) -VerifyRelease: blindtrust -endef - -define do_debmirror -set -ex; ./debmirror --progress --checksums --nocleanup \ - --nosource --ignore-release-gpg --rsync-extra=none \ - --exclude-deb-section='^debug$$' \ - --method=$(MIRROR_MOS_UBUNTU_METHOD) \ - --host=$(MIRROR_MOS_UBUNTU) \ - --root=$(MIRROR_MOS_UBUNTU_ROOT) \ - --dist=$(MIRROR_MOS_UBUNTU_SUITE)$1 \ - --section=$(subst $(space),$(comma),$(MIRROR_MOS_UBUNTU_SECTION)) \ - --arch=$(UBUNTU_ARCH) \ - $(LOCAL_MIRROR_UBUNTU)/ -endef - -# Two operation modes: -# USE_MIRROR=none - mirroring mode, rsync full mirror from internal build server -# USE_MIRROR= - ISO building mode, get repository for current product release only -$(BUILD_DIR)/mirror/ubuntu/build.done: $(BUILD_DIR)/mirror/ubuntu/mirror.done -ifneq ($(BUILD_PACKAGES),0) - $(BUILD_DIR)/mirror/ubuntu/build.done: $(BUILD_DIR)/mirror/ubuntu/repo.done -endif - -REPREPRO_CONF_DIR:=$(BUILD_DIR)/mirror/ubuntu/reprepro/conf - -define config_reprepro -#Generate reprepro distributions config -cat > $(REPREPRO_CONF_DIR)/distributions << EOF -$(reprepro_dist_conf) -EOF -#Generate reprepro updates config -cat > $(REPREPRO_CONF_DIR)/updates << EOF -$(reprepro_updates_conf) -EOF -endef - -$(BUILD_DIR)/mirror/ubuntu/reprepro_config.done: export config_reprepro:=$(config_reprepro) -$(BUILD_DIR)/mirror/ubuntu/reprepro_config.done: - mkdir -p $(REPREPRO_CONF_DIR) - sh -c "$${config_reprepro}" - $(ACTION.TOUCH) - -$(BUILD_DIR)/mirror/ubuntu/prepare_debmirror.done: - cp /usr/bin/debmirror . - patch -p1 ./debmirror < ./00-debmirror.patch - $(ACTION.TOUCH) - -$(BUILD_DIR)/mirror/ubuntu/reprepro.done: \ - $(BUILD_DIR)/mirror/ubuntu/mirror.done \ - $(BUILD_DIR)/mirror/ubuntu/reprepro_config.done - # Import existing Ubuntu repository - cd $(LOCAL_MIRROR_UBUNTU) && reprepro --confdir=$(REPREPRO_CONF_DIR) -V includedeb $(PRODUCT_NAME)$(PRODUCT_VERSION) pool/*/*/*/*.deb - $(ACTION.TOUCH) - -$(BUILD_DIR)/mirror/ubuntu/repo.done: \ - $(BUILD_DIR)/mirror/ubuntu/reprepro_config.done \ - $(BUILD_DIR)/mirror/ubuntu/reprepro.done - # FIXME(aglarendil): do not touch upstream repo. instead - build new repo - # Import newly built packages - cd $(LOCAL_MIRROR_UBUNTU) && reprepro --confdir=$(REPREPRO_CONF_DIR) -V includedeb $(PRODUCT_NAME)$(PRODUCT_VERSION) $(BUILD_DIR)/packages/deb/packages/*.deb - # Clean up reprepro data - rm -rf $(LOCAL_MIRROR_UBUNTU)/db - rm -rf $(LOCAL_MIRROR_UBUNTU)/lists - $(ACTION.TOUCH) - -$(BUILD_DIR)/mirror/ubuntu/mirror.done: \ - $(BUILD_DIR)/mirror/ubuntu/prepare_debmirror.done - mkdir -p $(LOCAL_MIRROR_UBUNTU) - $(call do_debmirror) - -$(call do_debmirror,-proposed) - -$(call do_debmirror,-updates) - -$(call do_debmirror,-security) - -$(call do_debmirror,-holdback) - -$(call do_debmirror,-hotfix) - rm -rf $(LOCAL_MIRROR_UBUNTU)/.temp $(LOCAL_MIRROR_UBUNTU)/project - $(ACTION.TOUCH) diff --git a/packages/deb/genpkgnames.pl b/packages/deb/genpkgnames.pl deleted file mode 100644 index f8ba681cc..000000000 --- a/packages/deb/genpkgnames.pl +++ /dev/null @@ -1,14 +0,0 @@ -use Parse::DebControl; - -$parser = new Parse::DebControl; - -%options = ( - type => 'debian/control', - stripComments => 'true', - ); - - $data = $parser->parse_file($ARGV[0], \%options); - foreach my $a (@$data) { - next if exists $a->{"Source"}; - print ${a}->{"Package"}."\n"; - } diff --git a/packages/deb/module.mk b/packages/deb/module.mk deleted file mode 100644 index eb51b4a38..000000000 --- a/packages/deb/module.mk +++ /dev/null @@ -1,81 +0,0 @@ -.PHONY: clean clean-deb - -clean: clean-deb - -clean-deb: - -mount | grep '$(BUILD_DIR)/packages/deb' | while read entry; do \ - set -- $$entry; \ - mntpt="$$3"; \ - sudo umount $$mntpt; \ - done - sudo rm -rf $(BUILD_DIR)/packages/deb - -$(BUILD_DIR)/packages/deb/buildd.tar.gz: SANDBOX_DEB_PKGS:=wget bzip2 apt-utils build-essential fakeroot devscripts equivs debhelper python-setuptools python-pbr -$(BUILD_DIR)/packages/deb/buildd.tar.gz: SANDBOX_UBUNTU:=$(BUILD_DIR)/packages/deb/chroot -$(BUILD_DIR)/packages/deb/buildd.tar.gz: export SANDBOX_UBUNTU_UP:=$(SANDBOX_UBUNTU_UP) -$(BUILD_DIR)/packages/deb/buildd.tar.gz: export SANDBOX_UBUNTU_DOWN:=$(SANDBOX_UBUNTU_DOWN) -$(BUILD_DIR)/packages/deb/buildd.tar.gz: $(BUILD_DIR)/mirror/ubuntu/reprepro.done - sh -c "$${SANDBOX_UBUNTU_UP}" - sh -c "$${SANDBOX_UBUNTU_DOWN}" - sudo rm -f $(SANDBOX_UBUNTU)/var/cache/apt/archives/*.deb - sudo tar czf $@.tmp -C $(SANDBOX_UBUNTU) . - mv $@.tmp $@ - -# Usage: -# (eval (call build_deb,package_name)) -define build_deb -$1-deb: $(BUILD_DIR)/packages/deb/$1.done -$(BUILD_DIR)/packages/deb/build.done: $(BUILD_DIR)/packages/deb/$1.done - -$(BUILD_DIR)/mirror/ubuntu/repo.done: $(BUILD_DIR)/packages/deb/$1.done -$(BUILD_DIR)/packages/deb/$1.done: $(BUILD_DIR)/mirror/ubuntu/reprepro.done -$(BUILD_DIR)/packages/deb/$1.done: $(BUILD_DIR)/packages/source_$1.done -$(BUILD_DIR)/packages/deb/$1.done: $(BUILD_DIR)/packages/deb/buildd.tar.gz -$(BUILD_DIR)/packages/deb/$1.done: SANDBOX_UBUNTU:=$(BUILD_DIR)/packages/deb/SANDBOX/$1 -$(BUILD_DIR)/packages/deb/$1.done: export SANDBOX_UBUNTU_UP:=$$(SANDBOX_UBUNTU_UP) -$(BUILD_DIR)/packages/deb/$1.done: export SANDBOX_UBUNTU_DOWN:=$$(SANDBOX_UBUNTU_DOWN) -$(BUILD_DIR)/packages/deb/$1.done: $(BUILD_DIR)/repos/repos.done - mkdir -p $(BUILD_DIR)/packages/deb/packages $(BUILD_DIR)/packages/deb/sources - mkdir -p $$(SANDBOX_UBUNTU)/tmp/$1/ - if [ ! -e "$$(SANDBOX_UBUNTU)/etc/debian_version" ]; then \ - sudo tar xaf $(BUILD_DIR)/packages/deb/buildd.tar.gz -C $$(SANDBOX_UBUNTU); \ - fi - sudo tar zxf $(BUILD_DIR)/packages/sources/$1/$1-$(PACKAGE_VERSION).tar.gz -C $$(SANDBOX_UBUNTU)/tmp/$1/ - - DEBFULLNAME=`awk -F'=' '/DEBFULLNAME/ {print $$$$2}' $(BUILD_DIR)/packages/sources/$1/version` \ - DEBEMAIL=`awk -F'=' '/DEBEMAIL/ {print $$$$2}' $(BUILD_DIR)/packages/sources/$1/version` \ - sudo -E dch -c $$(SANDBOX_UBUNTU)/tmp/$1/debian/changelog -D $(UBUNTU_RELEASE) -b --force-distribution \ - -v $(PACKAGE_VERSION)-`awk -F'=' '/DEBRELEASE/ {print $$$$2}' $(BUILD_DIR)/packages/sources/$1/version` \ - "`awk -F'=' '/DEBMSG/ {print $$$$2}' $(BUILD_DIR)/packages/sources/$1/version`" - sudo chroot $$(SANDBOX_UBUNTU) /bin/sh -c "mk-build-deps --install --remove --tool 'apt-get --yes --no-remove --no-install-recommends' /tmp/$1/debian/control" - sudo chroot $$(SANDBOX_UBUNTU) /bin/sh -c "cd /tmp/$1 ; DEB_BUILD_OPTIONS=nocheck debuild -us -uc -b -d" - cp $$(SANDBOX_UBUNTU)/tmp/*.deb $(BUILD_DIR)/packages/deb/packages - sudo sh -c "$$$${SANDBOX_UBUNTU_DOWN}" - $$(ACTION.TOUCH) -endef - -define remove_deb -#FIXME(aglarendil): do not touch upstream repo. instead - build new repo -mkdir -p $(BUILD_DIR)/packages/deb -perl $(SOURCE_DIR)/packages/deb/genpkgnames.pl $(BUILD_DIR)/repos/$1/debian/control > $(BUILD_DIR)/packages/deb/$1.cleanup.list -cd $(LOCAL_MIRROR_UBUNTU) && cat $(BUILD_DIR)/packages/deb/$1.cleanup.list | \ -xargs -n1 -I{} reprepro --confdir=$(REPREPRO_CONF_DIR) remove $(PRODUCT_NAME)$(PRODUCT_VERSION) {} $(NEWLINE) -endef - -$(BUILD_DIR)/mirror/ubuntu/repo.done: $(BUILD_DIR)/packages/deb/repocleanup.done -$(BUILD_DIR)/packages/deb/repocleanup.done: $(BUILD_DIR)/mirror/ubuntu/reprepro.done -$(BUILD_DIR)/packages/deb/repocleanup.done: $(packages_list:%=$(BUILD_DIR)/packages/source_%.done) - $(foreach pkg,$(fuel_debian_packages),$(call remove_deb,$(pkg))) - $(ACTION.TOUCH) - -$(BUILD_DIR)/packages/deb/build.done: - $(ACTION.TOUCH) - -fuel_debian_packages:=fuel-nailgun \ -astute \ -fuel-agent \ -fuel-library$(FUEL_LIBRARY_VERSION) \ -nailgun-agent \ -network-checker - -$(eval $(foreach pkg,$(fuel_debian_packages),$(call build_deb,$(pkg))$(NEWLINE))) diff --git a/packages/module.mk b/packages/module.mk deleted file mode 100644 index c0d819f99..000000000 --- a/packages/module.mk +++ /dev/null @@ -1,108 +0,0 @@ -# Usage: -# (eval (call prepare_file_source,package_name,file_name,source_path,optional_prerequisite)) -# Note: dependencies for deb targets are also specified here to make -# sure the source is ready before the build is started. -define prepare_file_source -ifeq ($4,) -$(BUILD_DIR)/packages/sources/$1/$2: $(BUILD_DIR)/repos/repos.done -else -$(BUILD_DIR)/packages/sources/$1/$2: $4 -endif -$(BUILD_DIR)/packages/source_$1.done: $(BUILD_DIR)/packages/sources/$1/$2 -$(BUILD_DIR)/packages/sources/$1/$2: $(call find-files,$3) - mkdir -p $(BUILD_DIR)/packages/sources/$1 - cp $3 $(BUILD_DIR)/packages/sources/$1/$2 -endef - -# Prepare sources + rpm_changelog + version file in format: -# -# VERSION=$(PRODUCT_VERSION) -# RPMRELEASE=1.mos${commit_num} -# DEBRELEASE=1~u16.04+mos${commit_num} -# DEBFULLNAME=Commit Author -# DEBEMAIL=Commit Author email address -# DEBMSG={commit_sha} {Commit message} -define prepare_git_source -$(BUILD_DIR)/packages/sources/$1/$2: $(BUILD_DIR)/repos/repos.done -$(BUILD_DIR)/packages/source_$1.done: $(BUILD_DIR)/packages/sources/$1/$2 -$(BUILD_DIR)/packages/sources/$1/$2: VERSIONFILE:=$(BUILD_DIR)/packages/sources/$1/version -$(BUILD_DIR)/packages/sources/$1/$2: CHANGELOGFILE:=$(BUILD_DIR)/packages/sources/$1/changelog -$(BUILD_DIR)/packages/sources/$1/$2: - mkdir -p $(BUILD_DIR)/packages/sources/$1 - cd $3 && git archive --format tar --worktree-attributes $4 > $(BUILD_DIR)/packages/sources/$1/$1.tar - echo VERSION=$(PACKAGE_VERSION) > $$(VERSIONFILE) - echo RPMRELEASE=1.mos`git -C $3 rev-list --no-merges $4 --count` >> $$(VERSIONFILE) - echo "%changelog\n* `LC_TIME=C date +\"%a %b %d %Y\"` `git -C $3 log -1 --pretty=format:%an` \ - <`git -C $3 log -1 --pretty=format:%ae`> - $(PACKAGE_VERSION)-1.mos`git -C $3 rev-list --no-merges $4 --count`" > $$(CHANGELOGFILE) - echo "`git -C $3 log -10 --pretty='- %h %s'`" >> $$(CHANGELOGFILE) - echo DEBRELEASE=1~u16.04+mos`git -C $3 rev-list --no-merges $4 --count` >> $$(VERSIONFILE) - echo DEBFULLNAME=`git -C $3 log -1 --pretty=format:%an` >> $$(VERSIONFILE) - echo DEBEMAIL=`git -C $3 log -1 --pretty=format:%ae` >> $$(VERSIONFILE) - echo DEBMSG=`git -C $3 rev-parse --short HEAD` `git -C $3 log -1 --pretty=%s` >> $$(VERSIONFILE) - cd $(BUILD_DIR)/packages/sources/$1 && tar -rf $1.tar version -ifneq ($(USE_PREDEFINED_FUEL_LIB_PUPPET_MODULES),) - if [ "$1" = "fuel-library$(FUEL_LIBRARY_VERSION)" ]; then cd $(BUILD_DIR)/packages/sources/$1 && tar -rf $1.tar upstream_modules.tar.gz; fi -endif - cd $(BUILD_DIR)/packages/sources/$1 && gzip -9 $1.tar && mv $1.tar.gz $2 -endef - -# fuel-library offline build hook -ifneq ($(USE_PREDEFINED_FUEL_LIB_PUPPET_MODULES),) -$(BUILD_DIR)/packages/sources/fuel-library$(FUEL_LIBRARY_VERSION)/upstream_modules.tar.gz: - @mkdir -p $(@D) - wget -nv $(USE_PREDEFINED_FUEL_LIB_PUPPET_MODULES) -O $@.tmp - mv $@.tmp $@ - -$(BUILD_DIR)/packages/source_fuel-library$(FUEL_LIBRARY_VERSION).done: \ - $(BUILD_DIR)/packages/sources/fuel-library$(FUEL_LIBRARY_VERSION)/upstream_modules.tar.gz -endif - -$(BUILD_DIR)/packages/source_%.done: - $(ACTION.TOUCH) - -#NAILGUN_PKGS -$(eval $(call prepare_git_source,fuel-nailgun,fuel-nailgun-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/fuel-nailgun,HEAD,$(NAILGUN_GERRIT_COMMIT))) -#FUEL_OSTF_PKGS -$(eval $(call prepare_git_source,fuel-ostf,fuel-ostf-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/fuel-ostf,HEAD,$(OSTF_GERRIT_COMMIT))) -#ASTUTE_PKGS -$(eval $(call prepare_git_source,astute,astute-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/astute,HEAD,$(ASTUTE_GERRIT_COMMIT))) -#FUELLIB_PKGS -$(eval $(call prepare_git_source,fuel-library$(FUEL_LIBRARY_VERSION),fuel-library$(FUEL_LIBRARY_VERSION)-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/fuel-library$(FUEL_LIBRARY_VERSION),HEAD,$(FUELLIB_GERRIT_COMMIT))) -#FUEL_PYTHON_PKGS -$(eval $(call prepare_git_source,python-fuelclient,python-fuelclient-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/python-fuelclient,HEAD,$(PYTHON_FUELCLIENT_GERRIT_COMMIT))) -#FUEL_AGENT_PKGS -$(eval $(call prepare_git_source,fuel-agent,fuel-agent-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/fuel-agent,HEAD,$(FUEL_AGENT_GERRIT_COMMIT))) -#FUEL_NAILGUN_AGENT_PKGS -$(eval $(call prepare_git_source,nailgun-agent,nailgun-agent-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/nailgun-agent,HEAD,$(FUEL_NAILGUN_AGENT_GERRIT_COMMIT))) -#FUEL-IMAGE PKGS -$(eval $(call prepare_git_source,fuel-main,fuel-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/fuel-main,HEAD,$(FUELMAIN_GERRIT_COMMIT))) -#FUEL-MENU PKGS -$(eval $(call prepare_git_source,fuelmenu,fuelmenu-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/fuelmenu,HEAD,$(FUELMENU_GERRIT_COMMIT))) -#FUEL-UI PKGS -$(eval $(call prepare_git_source,fuel-ui,fuel-ui-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/fuel-ui,HEAD,$(FUEL_UI_GERRIT_COMMIT))) -#SHOTGUN PKGS -$(eval $(call prepare_git_source,shotgun,shotgun-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/shotgun,HEAD,$(SHOTGUN_GERRIT_COMMIT))) -#NETWORK-CHECKER PKGS -$(eval $(call prepare_git_source,network-checker,network-checker-$(PACKAGE_VERSION).tar.gz,$(BUILD_DIR)/repos/network-checker,HEAD,$(NETWORKCHECKER_GERRIT_COMMIT))) - -include $(SOURCE_DIR)/packages/rpm/module.mk -include $(SOURCE_DIR)/packages/deb/module.mk - -.PHONY: packages packages-deb packages-rpm - -ifneq ($(BUILD_PACKAGES),0) -$(BUILD_DIR)/packages/build.done: \ - $(BUILD_DIR)/packages/rpm/build.done \ - $(BUILD_DIR)/packages/deb/build.done -endif - -$(BUILD_DIR)/packages/build.done: - $(ACTION.TOUCH) - -packages: $(BUILD_DIR)/packages/build.done -packages-rpm: $(BUILD_DIR)/packages/rpm/build.done -packages-deb: $(BUILD_DIR)/packages/deb/build.done - -.PHONY: sources - -sources: $(packages_list:%=$(BUILD_DIR)/packages/source_%.done) diff --git a/packages/rpm/genpkgnames.py b/packages/rpm/genpkgnames.py deleted file mode 100644 index c9b4f2cde..000000000 --- a/packages/rpm/genpkgnames.py +++ /dev/null @@ -1,6 +0,0 @@ -import rpm -import sys -specfile = sys.argv[1] -spec = rpm.spec(specfile) -for pkg in spec.packages: - print pkg.header.format('%{name}') diff --git a/packages/rpm/module.mk b/packages/rpm/module.mk deleted file mode 100644 index a92339361..000000000 --- a/packages/rpm/module.mk +++ /dev/null @@ -1,109 +0,0 @@ -.PHONY: clean clean-rpm - -clean: clean-rpm - -clean-rpm: - -mount | grep '$(BUILD_DIR)/packages/rpm/SANDBOX' | while read entry; do \ - set -- $$entry; \ - mntpt="$$3"; \ - sudo umount $$mntpt; \ - done - sudo rm -rf $(BUILD_DIR)/packages/rpm - -RPM_SOURCES:=$(BUILD_DIR)/packages/rpm/SOURCES - -$(BUILD_DIR)/packages/rpm/buildd.tar.gz: SANDBOX_PACKAGES:=@buildsys-build yum yum-utils -$(BUILD_DIR)/packages/rpm/buildd.tar.gz: SANDBOX:=$(BUILD_DIR)/packages/rpm/SANDBOX/buildd -$(BUILD_DIR)/packages/rpm/buildd.tar.gz: export SANDBOX_UP:=$(SANDBOX_UP) -$(BUILD_DIR)/packages/rpm/buildd.tar.gz: export SANDBOX_DOWN:=$(SANDBOX_DOWN) -$(BUILD_DIR)/packages/rpm/buildd.tar.gz: $(BUILD_DIR)/mirror/centos/repo.done \ - $(BUILD_DIR)/mirror/centos/mos-repo.done - sh -c "$${SANDBOX_UP}" - sh -c "$${SANDBOX_DOWN}" - sudo tar czf $@.tmp -C $(SANDBOX) . - mv $@.tmp $@ - - -# Usage: -# (eval (call build_rpm,package_name)) -define build_rpm -$(BUILD_DIR)/packages/rpm/repo$2.done: $(BUILD_DIR)/packages/rpm/$1.done -$(BUILD_DIR)/packages/rpm/repo$2.done: $(BUILD_DIR)/packages/rpm/$1-repocleanup.done - -# You can use package name as a target, for example: make ruby21-rubygem-astute -# It will build astute rpm package -$1-rpm: $(BUILD_DIR)/packages/rpm/$1.done - -$(BUILD_DIR)/packages/rpm/$1.done: SANDBOX:=$(BUILD_DIR)/packages/rpm/SANDBOX/$1 -$(BUILD_DIR)/packages/rpm/$1.done: export SANDBOX_DOWN:=$$(SANDBOX_DOWN) -$(BUILD_DIR)/packages/rpm/$1.done: $(BUILD_DIR)/packages/source_$1.done -$(BUILD_DIR)/packages/rpm/$1.done: $(BUILD_DIR)/packages/rpm/buildd.tar.gz - -ifneq (late,$(findstring late,$2)) -$(BUILD_DIR)/packages/rpm/$1.done: SPECFILE:=$(BUILD_DIR)/repos/$1/specs/$1.spec -$(BUILD_DIR)/repos/$1/specs/$1.spec: $(BUILD_DIR)/repos/repos.done -$(BUILD_DIR)/repos/$1/specs/$1.spec: $(BUILD_DIR)/repos/$1.done -$(BUILD_DIR)/packages/rpm/$1.done: $(BUILD_DIR)/repos/$1/specs/$1.spec -else -$(BUILD_DIR)/packages/rpm/$1.done: SPECFILE:=$(SOURCE_DIR)/packages/rpm/specs/$1.spec -endif - -$(BUILD_DIR)/packages/rpm/$1.done: - mkdir -p $(BUILD_DIR)/packages/rpm/RPMS/x86_64 - mkdir -p $$(SANDBOX) && \ - sudo tar xzf $(BUILD_DIR)/packages/rpm/buildd.tar.gz -C $$(SANDBOX) && \ - sudo chroot $$(SANDBOX) bash -c "(mkdir -p /tmp/user/0)" - sudo mount --bind /proc $$(SANDBOX)/proc && \ - sudo mount --bind /dev $$(SANDBOX)/dev && \ - sudo mount --bind $$(LOCAL_MIRROR) $$(SANDBOX)/mirrors && \ - mkdir -p $$(SANDBOX)/tmp/SOURCES && \ - sudo cp -r $(BUILD_DIR)/packages/sources/$1/* $$(SANDBOX)/tmp/SOURCES - -test -f $(BUILD_DIR)/packages/sources/$1/changelog && cat $(BUILD_DIR)/packages/sources/$1/changelog >> $$(SPECFILE) - sudo cp $$(SPECFILE) $$(SANDBOX)/tmp && \ - sudo chroot $$(SANDBOX) yum-builddep -y /tmp/$1.spec - test -f $$(SANDBOX)/tmp/SOURCES/version && \ - sudo chroot $$(SANDBOX) rpmbuild --nodeps --define "_topdir /tmp" --define "release `awk -F'=' '/RPMRELEASE/ {print $$$$2}' $$(SANDBOX)/tmp/SOURCES/version`" -ba /tmp/$1.spec || \ - sudo chroot $$(SANDBOX) rpmbuild --nodeps --define "_topdir /tmp" -ba /tmp/$1.spec - cp $$(SANDBOX)/tmp/RPMS/*/*.rpm $(BUILD_DIR)/packages/rpm/RPMS/x86_64 - sudo sh -c "$$$${SANDBOX_DOWN}" - $$(ACTION.TOUCH) - -ifneq (late,$(findstring late,$2)) -$(BUILD_DIR)/packages/rpm/$1-repocleanup.done: SPECFILE:=$(BUILD_DIR)/repos/$1/specs/$1.spec -$(BUILD_DIR)/packages/rpm/$1-repocleanup.done: $(BUILD_DIR)/packages/source_$1.done -else -$(BUILD_DIR)/packages/rpm/$1-repocleanup.done: SPECFILE:=$(SOURCE_DIR)/packages/rpm/specs/$1.spec -endif -$(BUILD_DIR)/packages/rpm/$1-repocleanup.done: $(BUILD_DIR)/mirror/centos/mos-repo.done - python $(SOURCE_DIR)/packages/rpm/genpkgnames.py $$(SPECFILE) | xargs -I{} sudo find $(LOCAL_MIRROR_MOS_CENTOS_OS_BASEURL)/Packages -type f -regex '.*/{}-[^-]+-[^-]+' -delete - $$(ACTION.TOUCH) -endef - - -packages_list:=\ -astute \ -fuel-agent \ -fuel-library$(FUEL_LIBRARY_VERSION) \ -fuel-main \ -fuel-nailgun \ -fuel-ostf \ -fuel-ui \ -fuelmenu \ -nailgun-agent \ -network-checker \ -python-fuelclient \ -shotgun - -$(eval $(foreach pkg,$(packages_list),$(call build_rpm,$(pkg))$(NEWLINE))) - -$(BUILD_DIR)/packages/rpm/repo.done: - find $(BUILD_DIR)/packages/rpm/RPMS -name '*.rpm' -exec cp -u {} $(LOCAL_MIRROR_MOS_CENTOS_OS_BASEURL)/Packages \; - createrepo -g $(LOCAL_MIRROR_MOS_CENTOS)/comps.xml \ - -o $(LOCAL_MIRROR_MOS_CENTOS_OS_BASEURL) $(LOCAL_MIRROR_MOS_CENTOS_OS_BASEURL) - $(ACTION.TOUCH) - -$(BUILD_DIR)/packages/rpm/build.done: -ifeq (1,$(strip $(BUILD_PACKAGES))) -$(BUILD_DIR)/packages/rpm/build.done: $(BUILD_DIR)/packages/rpm/repo.done -endif - $(ACTION.TOUCH) diff --git a/prepare-build-env.sh b/prepare-build-env.sh deleted file mode 100755 index 140df3ef2..000000000 --- a/prepare-build-env.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -x - -# Copyright 2014 Mirantis, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# This script will install all the required packages necessary for -# building a Fuel ISO. - -# Check that HTTPS transport is available to APT -if [ ! -e /usr/lib/apt/methods/https ]; then - sudo apt-get update - sudo apt-get install -y apt-transport-https -fi - -# Install software -sudo apt-get update -sudo apt-get -y install \ - build-essential \ - createrepo \ - debmirror \ - debootstrap \ - devscripts \ - dosfstools \ - extlinux \ - git \ - isomd5sum \ - libparse-debcontrol-perl \ - lrzip \ - python-jinja2 \ - python-yaml \ - reprepro \ - rpm \ - syslinux \ - unzip \ - xorriso \ - yum \ - yum-utils - -# Add account to sudoers -echo "Updating /etc/sudoers.d/fuel-iso" -cat << EOF | sudo tee /etc/sudoers.d/fuel-iso -Defaults env_keep += "http_proxy https_proxy no_proxy" -${USER} ALL=(ALL) NOPASSWD:ALL -EOF - -echo "Dependency check completed, please proceed with 'make iso' command" diff --git a/report-changelog.sh b/report-changelog.sh deleted file mode 100755 index e0e0be0ff..000000000 --- a/report-changelog.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -e -CENTOS_CHANGELOG=${LOCAL_MIRROR}/centos-packages.changelog -UBUNTU_CHANGELOG=${LOCAL_MIRROR}/ubuntu-packages.changelog -[ -f ${CENTOS_CHANGELOG} ] && rm ${CENTOS_CHANGELOG} -for packagename in `find ${LOCAL_MIRROR} -name \*.rpm | sort -u`; do - echo ${packagename##*/} >> ${CENTOS_CHANGELOG} - rpm -qp --changelog ${packagename} 2>/dev/null | sed -e '/^$/,$d' >> ${CENTOS_CHANGELOG} - echo '' >> ${CENTOS_CHANGELOG} -done - -[ -f ${UBUNTU_CHANGELOG} ] && rm ${UBUNTU_CHANGELOG} -for packagename in `find ${LOCAL_MIRROR} -name \*.deb | sort -u`; do - pkgname=${packagename##*/} - DATAFILE=`ar t $packagename | grep ^data` - case ${DATAFILE##*.} in - bz2) ZFLAG='--bzip2' ;; - gz) ZFLAG='-z' ;; - xz) ZFLAG='-J' ;; - lzma) ZFLAG='--lzma' ;; - *) echo "Unknown data tarball format for package $packagename"; continue ;; - esac - CHANGELOGFILE=`ar p $packagename $DATAFILE | tar $ZFLAG -tvf - | grep '/usr/share/doc/' | grep "/changelog\.Debian\.gz" || :` - CHANGELOGFILE=${CHANGELOGFILE##* } - if [[ ${CHANGELOGFILE:0:2} == './' ]]; then - ar p $packagename $DATAFILE | tar $ZFLAG -xO $CHANGELOGFILE | gzip -cd | sed -n '1,/--/ p' >> ${UBUNTU_CHANGELOG} - echo '' >> ${UBUNTU_CHANGELOG} - fi -done diff --git a/repos.mk b/repos.mk deleted file mode 100644 index 617b24aae..000000000 --- a/repos.mk +++ /dev/null @@ -1,56 +0,0 @@ -.PHONY: repos clean-repos - -clean-repos: - rm -rf $(BUILD_DIR)/repos - -repos: $(BUILD_DIR)/repos/repos.done - -fuel_components_repos:= -# Usage: -# (eval (call build_repo,repo_name,repo_uri,sha)) -define build_repo -$(BUILD_DIR)/repos/$1/%: $(BUILD_DIR)/repos/$1.done -$(BUILD_DIR)/repos/repos.done: $(BUILD_DIR)/repos/$1.done -fuel_components_repos:=$(fuel_components_repos) $1 - -$(BUILD_DIR)/repos/$1.done: - # Clone repo and checkout required commit - mkdir -p $(BUILD_DIR)/repos - rm -rf $(BUILD_DIR)/repos/$1 - - #Clone everything and checkout to branch (or hash) - git clone $2 $(BUILD_DIR)/repos/$1 && (cd $(BUILD_DIR)/repos/$1 && git checkout -q $3) - - # Pull gerrit commits if given - $(foreach var,$(filter-out none,$5), - ( cd $(BUILD_DIR)/repos/$1 && git fetch $4 $(var) && git cherry-pick FETCH_HEAD ) ; - ) - touch $$@ -endef - - -$(eval $(call build_repo,fuel-nailgun,$(NAILGUN_REPO),$(NAILGUN_COMMIT),$(NAILGUN_GERRIT_URL),$(NAILGUN_GERRIT_COMMIT))) -$(eval $(call build_repo,python-fuelclient,$(PYTHON_FUELCLIENT_REPO),$(PYTHON_FUELCLIENT_COMMIT),$(PYTHON_FUELCLIENT_GERRIT_URL),$(PYTHON_FUELCLIENT_GERRIT_COMMIT))) -$(eval $(call build_repo,fuel-agent,$(FUEL_AGENT_REPO),$(FUEL_AGENT_COMMIT),$(FUEL_AGENT_GERRIT_URL),$(FUEL_AGENT_GERRIT_COMMIT))) -$(eval $(call build_repo,nailgun-agent,$(FUEL_NAILGUN_AGENT_REPO),$(FUEL_NAILGUN_AGENT_COMMIT),$(FUEL_NAILGUN_AGENT_GERRIT_URL),$(FUEL_NAILGUN_AGENT_GERRIT_COMMIT))) -$(eval $(call build_repo,astute,$(ASTUTE_REPO),$(ASTUTE_COMMIT),$(ASTUTE_GERRIT_URL),$(ASTUTE_GERRIT_COMMIT))) -$(eval $(call build_repo,fuel-library,$(FUELLIB_REPO),$(FUELLIB_COMMIT),$(FUELLIB_GERRIT_URL),$(FUELLIB_GERRIT_COMMIT))) -$(eval $(call build_repo,fuel-ostf,$(OSTF_REPO),$(OSTF_COMMIT),$(OSTF_GERRIT_URL),$(OSTF_GERRIT_COMMIT))) -$(eval $(call build_repo,fuelmenu,$(FUELMENU_REPO),$(FUELMENU_COMMIT),$(FUELMENU_GERRIT_URL),$(FUELMENU_GERRIT_COMMIT))) -$(eval $(call build_repo,shotgun,$(SHOTGUN_REPO),$(SHOTGUN_COMMIT),$(SHOTGUN_GERRIT_URL),$(SHOTGUN_GERRIT_COMMIT))) -$(eval $(call build_repo,network-checker,$(NETWORKCHECKER_REPO),$(NETWORKCHECKER_COMMIT),$(NETWORKCHECKER_GERRIT_URL),$(NETWORKCHECKER_GERRIT_COMMIT))) -$(eval $(call build_repo,fuel-ui,$(FUEL_UI_REPO),$(FUEL_UI_COMMIT),$(FUEL_UI_GERRIT_URL),$(FUEL_UI_GERRIT_COMMIT))) - -$(BUILD_DIR)/repos/fuel-main.done: - ln -s $(SOURCE_DIR) $(BUILD_DIR)/repos/fuel-main - $(ACTION.TOUCH) -$(BUILD_DIR)/repos/repos.done: $(BUILD_DIR)/repos/fuel-main.done $(BUILD_DIR)/repos/fuel-library$(FUEL_LIBRARY_VERSION).done - -#FIXME(aglarendil): make repos generation uniform - -$(BUILD_DIR)/repos/fuel-library$(FUEL_LIBRARY_VERSION).done: $(BUILD_DIR)/repos/fuel-library.done - ln -s $(BUILD_DIR)/repos/fuel-library $(BUILD_DIR)/repos/fuel-library$(FUEL_LIBRARY_VERSION) - $(ACTION.TOUCH) - -$(BUILD_DIR)/repos/repos.done: - $(ACTION.TOUCH) diff --git a/requirements-fuel-rpm.txt b/requirements-fuel-rpm.txt deleted file mode 100644 index 81185012c..000000000 --- a/requirements-fuel-rpm.txt +++ /dev/null @@ -1,26 +0,0 @@ -fencing-agent -fuel -fuel-agent -fuel-bootstrap-cli -fuel-ha-utils -fuel-library -fuelmenu -fuel-migrate -fuel-misc -fuel-nailgun -fuel-notify -fuel-openstack-metadata -fuel-ostf -fuel-rabbit-fence -fuel-release -fuel-umm -ironic-fa-bootstrap-configs -nailgun-agent -nailgun-mcagents -network-checker -python-fuelclient -python-packetary -python-timmy -rubygem-astute -send2syslog -shotgun diff --git a/requirements-rpm.txt b/requirements-rpm.txt deleted file mode 100644 index f82272798..000000000 --- a/requirements-rpm.txt +++ /dev/null @@ -1,276 +0,0 @@ -apr-util -atop -augeas -augeas-libs -bakefile -@Base -bash -bind -bzip2 -cloud-init -cloud-utils -cobbler -cobbler-web -@Core -createrepo -cronie -cronie-anacron -crontabs -Cython -daemonize -debootstrap -deltarpm -dhcp -dnsmasq -docker -dpkg -dpkg-dev -dpkg-devel -erlang -ethtool -euca2ools -fabric -fence-agents-all -gdisk -genisoimage -GeoIP -git -gperftools -grub2 -grub2-efi -grub2-efi-modules -grub2-tools -gv -httpd -iproute -iptables -ipxe-roms -kernel -kernel-devel -kernel-headers -leveldb -libevent-devel -libiscsi -libmlx4 -libunwind -libusbx -libvirt-client -libvirt-python -libyaml -linux-firmware -logrotate -lrzip -lshw -lvm2 -mailcap -mcollective -mdadm -mod_wsgi -monit -mtools -MySQL-python -mysql-wsrep-5.6 -nginx -nmap-ncat -nodejs-nailgun -openssh-clients -openssl-devel -openstack-keystone -openstack-selinux -os-client-config -postgresql -postgresql-devel -postgresql-libs -postgresql-server -puppet -pydot-ng -pyparsing -python-alembic -python-amqp -python-amqplib -python-anyjson -python-appdirs -python-babel -python-backports -python-backports-ssl_match_hostname -python-boto -python-ceilometerclient -python-chardet -python-cheetah -python-cinderclient -python-cliff -python-cliff-tablib -python-cmd2 -python-coverage -python-crypto -python-daemon -python-daemonize -python-decorator -python-django -python-docker-py -python-dogpile-cache -python-dogpile-core -python-ecdsa -python-editor -python-empy -python-ethtool -python-eventlet -python-flask -python-futures -python-fysom -python-gevent -python-greenlet -python-heatclient -python-httplib2 -python-imgcreate -python-ipaddr -python-ironicclient -python-iso8601 -python-itsdangerous -python-jinja2 -python-jsonpatch -python-jsonpointer -python-jsonschema -python-keyring -python-keystoneclient -python-keystonemiddleware -python-kombu -python-ldappool -python-logutils -python-lxml -python-mako -python-markdown -python-markupsafe -python-memcached -python-migrate -python-muranoclient -python-netaddr -python-netifaces -python-networkx-core -python-neutronclient -python-nose -python-novaclient -python-oauthlib -python-openstackclient -python-oslo-config -python-oslo-db -python-oslo-i18n -python-oslo-messaging -python-oslo-serialization -python-oslo-sphinx -python-oslo-utils -python-paramiko -python-passlib -python-paste -python-paste-deploy -python-pbr -python-pecan -python-pip -python-ply -python-posix_ipc -python-psycopg2 -python-pycadf -python-pygments -python-pypcap -python-repoze-lru -python-requests -python-rhsm -python-routes -python-saharaclient -python-setuptools -python-simplegeneric -python-simplejson -python-singledispatch -python-six -python-sqlalchemy -python-stevedore -python-suds -python-swiftclient -python-tablib -python-testresources -python-unicodecsv -python-unittest2 -python-urllib3 -python-urwid -python-warlock -python-webob -python-webpy -python-websocket-client -python-websockify -python-webtest -python-werkzeug -python-wsgilog -python-wsgiref -python-yaql -pytz -PyYAML -qemu-img -rabbitmq-server -rpm -rpm-build -rsync -ruby -ruby-augeas -ruby-devel -rubygem-activesupport -rubygem-amq-protocol -rubygem-bunny -rubygem-cstruct -rubygem-extlib -rubygem-ffi -rubygem-ffi-yajl -rubygem-httpclient -rubygem-i18n -rubygem-inifile -rubygem-ipaddress -rubygem-json -rubygem-librarian-puppet-simple -rubygem-mcollective-client -rubygem-mime-types -rubygem-minitest -rubygem-mixlib-cli -rubygem-mixlib-config -rubygem-mixlib-shellout -rubygem-netaddr -rubygem-net-ssh -rubygem-net-ssh-gateway -rubygem-net-ssh-multi -rubygem-ohai -rubygem-openstack -rubygem-raemon -rubygem-rdoc -rubygem-rest-client -rubygem-rethtool -rubygems -rubygem-stomp -rubygem-symboltable -rubygem-systemu -rubygem-thread_safe -rubygem-tzinfo -rubygem-wmi-lite -rubygem-yajl-ruby -ruby-libs -ruby-shadow -scapy -screen -seabios -selinux-policy -send2syslog -snappy -socat -sudo -supervisor -syslinux -sysstat -tar -tftp-server -tmux -uwsgi -uwsgi-plugin-common -uwsgi-plugin-python -vim -vim-minimal -wxGTK -xinetd -yum -yum-plugin-priorities diff --git a/rules.mk b/rules.mk deleted file mode 100644 index 511b1377a..000000000 --- a/rules.mk +++ /dev/null @@ -1,46 +0,0 @@ -define ACTION.COPY -@mkdir -p $(@D) -cp $< $@ -endef - -define ACTION.TOUCH -@mkdir -p $(@D) -touch $@ -endef - -# This macros is to make targets dependent on variables -# It writes variable value into temporary file varname.tmp, -# then it compares temporary file with the varname.dep file. -# If there is a difference between them, varname.dep will be updated -# and the target which depends on it will be rebuilt. -# Example: -# target: $(call depv,varname) -DEPV_DIR:=$(BUILD_DIR)/depv -define depv -$(shell mkdir -p $(DEPV_DIR)) -$(shell echo "$($1)" > $(DEPV_DIR)/$1.tmp) -$(shell diff >/dev/null 2>&1 $(DEPV_DIR)/$1.tmp $(DEPV_DIR)/$1.dep \ - || mv $(DEPV_DIR)/$1.tmp $(DEPV_DIR)/$1.dep) -$(DEPV_DIR)/$1.dep -endef - -define NEWLINE - - -endef - -$(BUILD_DIR)/%/.dir: - mkdir -p $(@D) - @touch $@ - -assert-variable=$(if $($1),,$(error Variable $1 need to be defined)) -find-files=$(shell test -e $1 && find $1 -type f 2> /dev/null) - -# uppercase conversion routine -# usage: UPPER_VAR = $(call uc,$(VAR)) -uc = $(shell echo $(1) | tr a-z A-Z) - -comma:=, - -space:= -space+= diff --git a/sandbox.mk b/sandbox.mk deleted file mode 100644 index 9d34dc913..000000000 --- a/sandbox.mk +++ /dev/null @@ -1,268 +0,0 @@ -.PHONY: show-ubuntu-sandbox-repos show-centos-sandbox-repos - -define yum_local_repo -[upstream-local-mirror] -name=Local upstream mirror -baseurl=file:///mirrors/centos/os/x86_64 -gpgcheck=0 -enabled=1 -priority=10 -endef - -define yum_local_mos_repo -[mos-local-mirror] -name=Local mirror -baseurl=file:///mirrors/mos-centos -gpgcheck=0 -enabled=1 -priority=10 -endef - -define yum_upstream_repo -[upstream] -name=Upstream mirror -baseurl=$(SANDBOX_MIRROR_CENTOS_UPSTREAM)/os/$(CENTOS_ARCH)/ -gpgcheck=0 -priority=1 -sslverify=False - -[upstream-updates] -name=Upstream mirror -baseurl=$(SANDBOX_MIRROR_CENTOS_UPSTREAM)/updates/$(CENTOS_ARCH)/ -gpgcheck=0 -priority=1 -sslverify=False -endef - -define yum_epel_repo -[epel] -name=epel mirror -baseurl=$(SANDBOX_MIRROR_EPEL)/$(CENTOS_MAJOR)/$(CENTOS_ARCH)/ -gpgcheck=0 -priority=3 -endef - -ifdef EXTRA_RPM_BUILDDEP_REPO -define yum_extra_build_repo -[extra_build] -name=Extra Build -baseurl=$(EXTRA_RPM_BUILDDEP_REPO) -gpgcheck=0 -priority=2 -endef -endif - -define sandbox_yum_conf -[main] -cachedir=/tmp/cache -keepcache=0 -debuglevel=2 -logfile=/tmp/yum.log -exclude=*.i686.rpm -exactarch=1 -obsoletes=1 -gpgcheck=0 -plugins=1 -pluginpath=/etc/yum-plugins -pluginconfpath=/etc/yum/pluginconf.d -reposdir=/etc/yum.repos.d -sslverify=False -endef - -define external_sandbox_yum_conf -[main] -cachedir=$(SANDBOX)/cache -keepcache=0 -debuglevel=2 -logfile=$(SANDBOX)/yum.log -exclude=*.i686.rpm -exactarch=1 -obsoletes=1 -gpgcheck=0 -plugins=1 -pluginpath=$(SANDBOX)/etc/yum-plugins -pluginconfpath=$(SANDBOX)/etc/yum/pluginconf.d -reposdir=$(SANDBOX)/etc/yum.repos.d -sslverify=False -endef - -SANDBOX_PACKAGES:=bash yum - -define SANDBOX_UP -echo "Starting SANDBOX up" -mkdir -p $(SANDBOX)/etc/yum.repos.d -cat > $(SANDBOX)/etc/yum.conf < $(SANDBOX)/etc/external.yum.conf < $(SANDBOX)/etc/yum.repos.d/base.repo < $(SANDBOX)/etc/yum/pluginconf.d/priorities.conf << EOF -[main] -enabled=1 -check_obsoletes=1 -full_match=1 -EOF -sudo rpm -i --root=$(SANDBOX) `find $(LOCAL_MIRROR_CENTOS_OS_BASEURL) -name "centos-release*rpm" | head -1` || \ -echo "centos-release already installed" -sudo rm -vf $(SANDBOX)/etc/yum.repos.d/Cent* -sudo /bin/sh -c 'export TMPDIR=$(SANDBOX)/tmp/yum TMP=$(SANDBOX)/tmp/yum; yum -c $(SANDBOX)/etc/external.yum.conf --installroot=$(SANDBOX) -y --nogpgcheck install yum' -echo 'Rebuilding RPM DB' -sudo rpm --root=$(SANDBOX) --rebuilddb -echo 'Installing packages for Sandbox' -mount | grep -q $(SANDBOX)/mirrors || sudo mount --bind $(LOCAL_MIRROR) $(SANDBOX)/mirrors -mount | grep -q $(SANDBOX)/proc || sudo mount --bind /proc $(SANDBOX)/proc -mount | grep -q $(SANDBOX)/dev || sudo mount --bind /dev $(SANDBOX)/dev -# after installing yum, let's add MOS repos from mounted /mirrors -cat > $(SANDBOX)/etc/yum.repos.d/base.repo < $(BUILD_DIR)/policy-rc.d << EOF -#!/bin/sh -# suppress services start in the staging chroots -exit 101 -EOF -chmod 755 $(BUILD_DIR)/policy-rc.d -mkdir -p $(SANDBOX_UBUNTU)/etc/init.d -touch $(SANDBOX_UBUNTU)/etc/init.d/.legacy-bootordering -mkdir -p $(SANDBOX_UBUNTU)/usr/sbin -cp -a $(BUILD_DIR)/policy-rc.d $(SANDBOX_UBUNTU)/usr/sbin -echo "Running debootstrap" -sudo debootstrap --no-check-gpg --include=ca-certificates --arch=$(UBUNTU_ARCH) $(MIRROR_UBUNTU_SUITE) $(SANDBOX_UBUNTU) $(MIRROR_UBUNTU_METHOD)://$(MIRROR_UBUNTU)$(MIRROR_UBUNTU_ROOT) -if [ -e $(SANDBOX_UBUNTU)/etc/resolv.conf ]; then sudo cp -a $(SANDBOX_UBUNTU)/etc/resolv.conf $(SANDBOX_UBUNTU)/etc/resolv.conf.orig; fi -sudo cp /etc/resolv.conf $(SANDBOX_UBUNTU)/etc/resolv.conf -if [ -e $(SANDBOX_UBUNTU)/etc/hosts ]; then sudo cp -a $(SANDBOX_UBUNTU)/etc/hosts $(SANDBOX_UBUNTU)/etc/hosts.orig; fi -sudo cp /etc/hosts $(SANDBOX_UBUNTU)/etc/hosts -echo "Generating utf8 locale" -sudo chroot $(SANDBOX_UBUNTU) /usr/bin/env -i \ - LC_ALL=C \ - DEBIAN_FRONTEND=noninteractive \ - DEBCONF_NONINTERACTIVE_SEEN=true \ - /bin/sh -c 'locale-gen en_US.UTF-8; dpkg-reconfigure locales' -echo "Preparing directory for chroot local mirror" -sudo mkdir -p $(SANDBOX_UBUNTU)/etc/apt/preferences.d/ -echo "Generating pinning file for Ubuntu SandBox" -cat > $(BUILD_DIR)/mirror/ubuntu/preferences << EOF -$(apt_preferences) -EOF -sudo cp $(BUILD_DIR)/mirror/ubuntu/preferences $(SANDBOX_UBUNTU)/etc/apt/preferences.d/ -echo "Configuring apt sources.list" -cat > $(BUILD_DIR)/mirror/ubuntu/sources.list << EOF -$(apt_sources_list) -EOF -sudo cp $(BUILD_DIR)/mirror/ubuntu/sources.list $(SANDBOX_UBUNTU)/etc/apt/ -sudo cp $(BUILD_DIR)/policy-rc.d $(SANDBOX_UBUNTU)/usr/sbin -echo "Allowing using unsigned repos" -echo "APT::Get::AllowUnauthenticated 1;" | sudo tee $(SANDBOX_UBUNTU)/etc/apt/apt.conf.d/02mirantis-unauthenticated -if [ "$(SANDBOX_COPY_CERTS)" = "1" ] ; then -echo "Copying local certificates and CA to chroot" -sudo bash -c "mkdir -p $(SANDBOX_UBUNTU)/usr/share/ca-certificates/ ; rsync -arzL /etc/ssl/certs/ $(SANDBOX_UBUNTU)/usr/share/ca-certificates/local/" -echo "Acquire::https { Verify-Peer \"true\"; Verify-Host \"true\"; }; " | sudo tee -a $(SANDBOX_UBUNTU)/etc/apt/apt.conf.d/05-local-ssl-certs -sudo chroot $(SANDBOX_UBUNTU) sh -xc "(cd /usr/share/ca-certificates; find local -type f) >> /etc/ca-certificates.conf" -sudo chroot $(SANDBOX_UBUNTU) update-ca-certificates -fi -echo "Updating apt package database" -sudo chroot $(SANDBOX_UBUNTU) bash -c "(mkdir -p /tmp/user/0)" -sudo chroot $(SANDBOX_UBUNTU) apt-get update -if ! mountpoint -q $(SANDBOX_UBUNTU)/proc; then sudo mount -t proc sandboxproc $(SANDBOX_UBUNTU)/proc; fi -echo "Installing additional packages: $(SANDBOX_DEB_PKGS)" -sudo chroot $(SANDBOX_UBUNTU) env LC_ALL=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true apt-get dist-upgrade --yes -test -n "$(SANDBOX_DEB_PKGS)" && sudo chroot $(SANDBOX_UBUNTU) env LC_ALL=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true apt-get install --yes $(SANDBOX_DEB_PKGS) -echo "SANDBOX_UBUNTU_UP: done" -endef - -define SANDBOX_UBUNTU_DOWN - if mountpoint -q $(SANDBOX_UBUNTU)/proc; then sudo umount $(SANDBOX_UBUNTU)/proc; fi - sudo umount $(SANDBOX_UBUNTU)/tmp/apt || true -endef - -show-ubuntu-sandbox-repos: export apt_source_content:=$(apt_sources_list) -show-ubuntu-sandbox-repos: export apt_pinning_content:=$(apt_preferences) -show-ubuntu-sandbox-repos: - /bin/echo -e "$${apt_source_content}" - /bin/echo -e "$${apt_pinning_content}" - -show-centos-sandbox-repos: export sandbox_yum_conf_content:=$(sandbox_yum_conf) -show-centos-sandbox-repos: export yum_upstream_repo_content:=$(yum_upstream_repo) -show-centos-sandbox-repos: export yum_epel_repo_content:=$(yum_epel_repo) -show-centos-sandbox-repos: export yum_local_repo_content:=$(yum_local_repo) -show-centos-sandbox-repos: export yum_local_mos_repo_content:=$(yum_local_mos_repo) -show-centos-sandbox-repos: export yum_extra_build_repo_content:=$(yum_extra_build_repo) -show-centos-sandbox-repos: - /bin/echo -e "$${sandbox_yum_conf_content}\n" - /bin/echo -e "$${yum_upstream_repo_content}\n" - /bin/echo -e "$${yum_epel_repo_content}\n" - /bin/echo -e "$${yum_local_repo_content}\n" - /bin/echo -e "$${yum_local_mos_repo_content}\n" - /bin/echo -e "$${yum_extra_build_repo_content}\n" diff --git a/specs/fuel-main.spec b/specs/fuel-main.spec deleted file mode 100644 index 54fcad2b0..000000000 --- a/specs/fuel-main.spec +++ /dev/null @@ -1,105 +0,0 @@ -#TEMP fixme -%define repo_name fuel-main - -%define name fuel -%{!?version: %define version 10.0.0} -%{!?fuel_release: %define fuel_release 10.0} -%{!?release: %define release 1} - -Name: %{name} -Summary: Fuel for OpenStack -URL: http://mirantis.com -Version: %{version} -Release: %{release} -Source0: %{name}-%{version}.tar.gz -License: Apache -BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot -Prefix: %{_prefix} -BuildArch: noarch -Requires: fuel-library10.0 -Requires: fuelmenu >= %{version} -Requires: fuel-release >= %{version} -Requires: network-checker >= %{version} -Requires: python-fuelclient >= %{version} -Requires: shotgun >= %{version} -Requires: yum - -%description -Fuel for OpenStack is a lifecycle management utility for -managing OpenStack. - -%prep -%setup -cq -n %{name}-%{version} - -%build - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/etc -mkdir -p %{buildroot}/etc/yum/vars/ -mkdir -p %{buildroot}/etc/yum.repos.d -echo %{fuel_release} > %{buildroot}%{_sysconfdir}/fuel_release -echo %{fuel_release} > %{buildroot}%{_sysconfdir}/yum/vars/fuelver -# copy GPG key -install -D -m 644 %{_builddir}/%{name}-%{version}/fuel-release/RPM-GPG-KEY-mos %{buildroot}/etc/pki/fuel-gpg/RPM-GPG-KEY-mos -# copy yum repos and mirror lists to /etc/yum.repos.d -for file in %{_builddir}/%{name}-%{version}/fuel-release/*.repo ; do - install -D -m 644 "$file" %{buildroot}/etc/yum.repos.d -done -install -D -p -m 755 %{_builddir}/%{name}-%{version}/iso/bootstrap_admin_node.sh %{buildroot}%{_sbindir}/bootstrap_admin_node.sh -install -D -p -m 755 %{_builddir}/%{name}-%{version}/iso/fix_default_repos.py %{buildroot}%{_sbindir}/fix_default_repos.py -install -D -p -m 755 %{_builddir}/%{name}-%{version}/fuel-release/override_rpm_repos.py %{buildroot}%{_sbindir}/override_rpm_repos.py - -%clean -rm -rf %{buildroot} - -%files -%defattr(-,root,root) - - -%package -n fuel-release - -Summary: Fuel release package -Version: %{version} -Release: %{release} -License: Apache -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -URL: http://github.com/Mirantis -Requires: python -Requires: PyYAML >= 3.10 - -%description -n fuel-release -This packages provides /etc/fuel_release file -and Yum configuration for Fuel online repositories. - -%files -n fuel-release -%defattr(-,root,root) -%{_sysconfdir}/fuel_release -%{_sbindir}/override_rpm_repos.py -%config(noreplace) %attr(0644,root,root) /etc/yum/vars/fuelver -%config(noreplace) %attr(0644,root,root) /etc/yum.repos.d/* -%dir /etc/pki/fuel-gpg -/etc/pki/fuel-gpg/* - -%post -n fuel-release -if [[ -f /root/override_rpm_repos.yaml ]]; then - rm -f /etc/yum.repos.d/*.repo - override_rpm_repos.py --repositories-file /root/override_rpm_repos.yaml --output-file /etc/yum.repos.d/overriden.repo -fi - -%package -n fuel-setup - -Summary: Fuel deployment script package -Version: %{version} -Release: %{release} -License: Apache -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -URL: http://github.com/Mirantis - -%description -n fuel-setup -This packages provides script to deploy Fuel components. - -%files -n fuel-setup -%defattr(-,root,root) -%{_sbindir}/bootstrap_admin_node.sh -%{_sbindir}/fix_default_repos.py