From 44a03f5f376c951d09109a332951a4ffacb72a6c Mon Sep 17 00:00:00 2001
From: Joao Afonso <joao.afonso@cern.ch>
Date: Tue, 15 Nov 2022 16:49:41 +0100
Subject: [PATCH] Merge release v4.7.12-2/v5.7.12-2 changes into main

---
 ReleaseNotes.md                               |   6 +
 cta-release/CMakeLists.txt                    |   2 +
 cta-release/ceph.repo                         |   8 --
 cta-release/cta-ceph.repo                     |   9 ++
 ...epend.repo => cta-eos-citrine-depend.repo} |   6 +-
 ...{eos-citrine.repo => cta-eos-citrine.repo} |   6 +-
 cta-release/cta-eos-diopside-depend.repo      |   6 +
 cta-release/cta-eos-diopside.repo             |   7 +
 ...{eos-quarkdb.repo => cta-eos-quarkdb.repo} |   4 +-
 ...nt.repo => cta-oracle-instant-client.repo} |   4 +-
 cta-release/cta-public.repo                   |  29 +++-
 cta-release/cta-release.conf                  |   3 +
 cta-release/cta-versionlock                   | 136 +++++++++++++++++-
 cta-release/cta-xrootd.repo                   |   8 ++
 cta.spec.in                                   |  17 ++-
 15 files changed, 220 insertions(+), 31 deletions(-)
 delete mode 100644 cta-release/ceph.repo
 create mode 100644 cta-release/cta-ceph.repo
 rename cta-release/{eos-citrine-depend.repo => cta-eos-citrine-depend.repo} (78%)
 rename cta-release/{eos-citrine.repo => cta-eos-citrine.repo} (84%)
 create mode 100644 cta-release/cta-eos-diopside-depend.repo
 create mode 100644 cta-release/cta-eos-diopside.repo
 rename cta-release/{eos-quarkdb.repo => cta-eos-quarkdb.repo} (87%)
 rename cta-release/{oracle-instant-client.repo => cta-oracle-instant-client.repo} (83%)
 create mode 100644 cta-release/cta-release.conf
 create mode 100644 cta-release/cta-xrootd.repo

diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index 032e1521e9..7650dfdc1f 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -37,6 +37,12 @@
 - cta/CTA#182 - Fix cta_valgrind error
 - cta/CTA#197 - Include order in XrdSsiCtaRequestMessage.cpp
 
+# v4.7.12-2
+
+## Summary
+### Building and Packaging
+- cta/CTA#15 - Repackaging CTA for easy installation of public RPMs
+
 # v4.7.12-1
 
 ## Summary
diff --git a/cta-release/CMakeLists.txt b/cta-release/CMakeLists.txt
index 0604266ff7..3b0ce4ffbb 100644
--- a/cta-release/CMakeLists.txt
+++ b/cta-release/CMakeLists.txt
@@ -101,5 +101,7 @@ install (FILES ${KEY_FILES}
   DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/pki/rpm-gpg)
 install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/versionlock.cta
   DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/yum/pluginconf.d)
+install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-release.conf
+  DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cta)
 install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-versionlock
   DESTINATION usr/${CMAKE_INSTALL_BINDIR})
diff --git a/cta-release/ceph.repo b/cta-release/ceph.repo
deleted file mode 100644
index 8dcb736696..0000000000
--- a/cta-release/ceph.repo
+++ /dev/null
@@ -1,8 +0,0 @@
-[Ceph]
-name=Ceph packages for $basearch
-baseurl=http://download.ceph.com/rpm-nautilus/el$releasever/$basearch
-enabled=1
-gpgcheck=1
-protect=1
-type=rpm-md
-gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ceph
diff --git a/cta-release/cta-ceph.repo b/cta-release/cta-ceph.repo
new file mode 100644
index 0000000000..a14c1028bf
--- /dev/null
+++ b/cta-release/cta-ceph.repo
@@ -0,0 +1,9 @@
+[cta-ceph]
+name=Ceph version 15.2.15 packages for $basearch
+baseurl=http://download.ceph.com/rpm-15.2.15/el$releasever/$basearch
+enabled=0
+priority=4
+gpgcheck=1
+protect=1
+type=rpm-md
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ceph
diff --git a/cta-release/eos-citrine-depend.repo b/cta-release/cta-eos-citrine-depend.repo
similarity index 78%
rename from cta-release/eos-citrine-depend.repo
rename to cta-release/cta-eos-citrine-depend.repo
index cd56da9355..39c05ea6be 100644
--- a/cta-release/eos-citrine-depend.repo
+++ b/cta-release/cta-eos-citrine-depend.repo
@@ -1,6 +1,6 @@
-[eos-citrine-depend]
+[cta-eos-citrine-depend]
 name=dependencies for EOS citrine releases from EOS project
 baseurl=http://storage-ci.web.cern.ch/storage-ci/eos/citrine-depend/el-$releasever/$basearch/
-enabled=1
+enabled=0
 gpgcheck=0
-priority=10
+priority=4
diff --git a/cta-release/eos-citrine.repo b/cta-release/cta-eos-citrine.repo
similarity index 84%
rename from cta-release/eos-citrine.repo
rename to cta-release/cta-eos-citrine.repo
index 67b7de8d00..af2f12f5cb 100644
--- a/cta-release/eos-citrine.repo
+++ b/cta-release/cta-eos-citrine.repo
@@ -1,7 +1,7 @@
-[eos-citrine]
+[cta-eos-citrine]
 name=EOS citrine releases from EOS project
 baseurl=http://storage-ci.web.cern.ch/storage-ci/eos/citrine/tag/testing/el-$releasever/$basearch/
-enabled=1
+enabled=0
 gpgcheck=1
-priority=10
+priority=4
 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-storageci
diff --git a/cta-release/cta-eos-diopside-depend.repo b/cta-release/cta-eos-diopside-depend.repo
new file mode 100644
index 0000000000..4332a9b62c
--- /dev/null
+++ b/cta-release/cta-eos-diopside-depend.repo
@@ -0,0 +1,6 @@
+[cta-eos-diopside-depend]
+name=dependencies for EOS diopside releases from EOS project
+baseurl=http://storage-ci.web.cern.ch/storage-ci/eos/diopside-depend/el-$releasever/$basearch/
+enabled=0
+gpgcheck=0
+priority=4
\ No newline at end of file
diff --git a/cta-release/cta-eos-diopside.repo b/cta-release/cta-eos-diopside.repo
new file mode 100644
index 0000000000..3a9cd57f06
--- /dev/null
+++ b/cta-release/cta-eos-diopside.repo
@@ -0,0 +1,7 @@
+[cta-eos-diopside]
+name=EOS diopside releases from EOS project
+baseurl=http://storage-ci.web.cern.ch/storage-ci/eos/diopside/tag/testing/el-$releasever/$basearch/
+enabled=0
+gpgcheck=1
+priority=4
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-storageci
\ No newline at end of file
diff --git a/cta-release/eos-quarkdb.repo b/cta-release/cta-eos-quarkdb.repo
similarity index 87%
rename from cta-release/eos-quarkdb.repo
rename to cta-release/cta-eos-quarkdb.repo
index 9137a09329..f935aa1d82 100644
--- a/cta-release/eos-quarkdb.repo
+++ b/cta-release/cta-eos-quarkdb.repo
@@ -1,7 +1,7 @@
-[eos-quarkdb]
+[cta-eos-quarkdb]
 name=EOS quarkdb releases from EOS project
 baseurl=http://storage-ci.web.cern.ch/storage-ci/quarkdb/tag/el$releasever/$basearch/
-enabled=1
+enabled=0
 gpgcheck=1
 priority=10
 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-storageci
diff --git a/cta-release/oracle-instant-client.repo b/cta-release/cta-oracle-instant-client.repo
similarity index 83%
rename from cta-release/oracle-instant-client.repo
rename to cta-release/cta-oracle-instant-client.repo
index b9a500505b..7652456d09 100644
--- a/cta-release/oracle-instant-client.repo
+++ b/cta-release/cta-oracle-instant-client.repo
@@ -1,7 +1,7 @@
-[oracle-instant-client]
+[cta-oracle-instant-client]
 name=Oracle instant client
 baseurl=https://yum.oracle.com/repo/OracleLinux/OL$releasever/oracle/instantclient/$basearch
 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
 gpgcheck=1
-enabled=1
+enabled=0
 priority=1
diff --git a/cta-release/cta-public.repo b/cta-release/cta-public.repo
index d1020dd691..00889e8bc3 100644
--- a/cta-release/cta-public.repo
+++ b/cta-release/cta-public.repo
@@ -1,6 +1,27 @@
-[cta-public]
-name=CTA public releases for CTA project
-baseurl=https://cta-public-repo.web.cern.ch/$releasever/$basearch/
-enabled=1
+[cta-public-4]
+name=CTA public releases for CTA 4 project
+baseurl=https://cta-public-repo.web.cern.ch/cta-4/el-$releasever/cta/
+enabled=0
 gpgcheck=0
 priority=10
+
+[cta-public-4-depend]
+name=CTA public releases for CTA 4 project - dependencies
+baseurl=https://cta-public-repo.web.cern.ch/cta-4/el-$releasever/cta-dependencies/
+enabled=0
+gpgcheck=0
+priority=3
+
+[cta-public-5]
+name=CTA public releases for CTA 5 project
+baseurl=https://cta-public-repo.web.cern.ch/cta-5/el-$releasever/cta/
+enabled=0
+gpgcheck=0
+priority=10
+
+[cta-public-5-depend]
+name=CTA public releases for CTA 5 project - dependencies
+baseurl=https://cta-public-repo.web.cern.ch/cta-5/el-$releasever/cta-dependencies/
+enabled=0
+gpgcheck=0
+priority=3
\ No newline at end of file
diff --git a/cta-release/cta-release.conf b/cta-release/cta-release.conf
new file mode 100644
index 0000000000..291c56ddf9
--- /dev/null
+++ b/cta-release/cta-release.conf
@@ -0,0 +1,3 @@
+{
+   "eos_major_version": 4
+}
\ No newline at end of file
diff --git a/cta-release/cta-versionlock b/cta-release/cta-versionlock
index b2bf348dac..7e5f0f5884 100755
--- a/cta-release/cta-versionlock
+++ b/cta-release/cta-versionlock
@@ -7,16 +7,19 @@ import json
 import rpm
 from rpmUtils.miscutils import splitFilename
 from collections import defaultdict
+import yum
 
+conf_file = '/etc/cta/cta-release.conf'
 
 vfiles = {
   'cta': '/etc/yum/pluginconf.d/versionlock.cta', 
   'yum': '/etc/yum/pluginconf.d/versionlock.list'
 }
-actions = ('help', 'check', 'apply', 'forceupdate', 'checkpkg', 'remove')
+actions = ('help', 'check', 'apply', 'forceupdate', 'checkpkg', 'remove', 'config')
 retcode = 0
 jsonoutput = False
 no_vlock = '/etc/cta.novlock'
+eos_version=0
 
 try:
   FileNotFoundError
@@ -28,18 +31,97 @@ def usage():
   print("\n%s: command line tool to manage cta packages versionlock\n \
 \n \
 usage: %s help|check|apply|forceupdate|checkpkg|remove [--json]\n \
+       %s config eos4|eos5 [--json]\n \
   help: print this message\n \
   check: show consistency of versionlock.list with cta versionlock requirements\n \
   apply: add cta versions to versionlock.list\n \
   forceupdate: add cta versions to versionlock.list and overwrite already defined packages\n \
   checkpkg: check consistency between installed packages and cta versionlock requirements\n \
   remove: remove all cta packages and dependencies from versionlock.list\n \
+  config eos4|eos5: select EOS version\n \
   [--json]: format output in json\n \
   \n \
   to prevent cta-versionlock to alter versionlock.list create a %s file.\n \
-  " % (sys.argv[0], sys.argv[0], no_vlock))
+  " % (sys.argv[0], sys.argv[0], sys.argv[0], no_vlock))
   exit(1)
 
+START_EXPR = "\s*#+\s*%s-START\s*#+"
+END_EXPR = "\s*#+\s*%s-END\s*#+"
+
+yb = yum.YumBase()
+yb.preconf.debuglevel = 0
+yb.preconf.errorlevel = 0
+repos_all = [repo.id for repo in yb.repos.findRepos("cta-*")]
+
+with open(conf_file) as f:
+  cta_conf_json = json.load(f)
+
+def get_repo_set_for_eos_version(eos_major_version):
+  if eos_major_version == 4:
+    return {repo_id for repo_id in repos_all if "eos" in repo_id and "diopside" not in repo_id}
+  elif eos_major_version == 5:
+    return {repo_id for repo_id in repos_all if "eos" in repo_id and "citrine" not in repo_id}
+  else:
+    raise RuntimeError("Unknown EOS major version '%s'." % eos_major_version)
+
+def get_repo_set_for_cta_version(cta_major_version):
+  if cta_major_version == 4:
+    return {repo_id for repo_id in repos_all if "eos" not in repo_id and "public-5" not in repo_id}
+  elif cta_major_version == 5:
+    return {repo_id for repo_id in repos_all if "eos" not in repo_id and "public-4" not in repo_id}
+  else:
+    raise RuntimeError("Unknown CTA major version '%s'." % cta_major_version)
+
+repos_selected = set()
+repos_selected |= get_repo_set_for_cta_version(cta_conf_json["cta_major_version"])
+repos_selected |= get_repo_set_for_eos_version(cta_conf_json["eos_major_version"])
+
+def switch_repos(repo_id_list, enable):
+  for repo_id in repo_id_list:
+    yb.repos.enableRepo(repo_id) if enable else yb.repos.disableRepo(repo_id)
+    repo_obj = yb.repos.findRepos(repo_id)[0]
+    with open(repo_obj.repofile, "w") as f:
+      repo_obj.write(f, always=("enabled",))
+
+def enable_repos(repo_id_list):
+  switch_repos(repo_id_list, True)
+
+def disable_repos(repo_id_list):
+  switch_repos(repo_id_list, False)
+
+def switch_packages(file_path, key, enable_packages):
+
+  start_expr_key = START_EXPR % key
+  end_expr_key = END_EXPR % key
+
+  new_lines = []
+
+  with open(file_path) as f:
+    plist = f.read().splitlines()
+    found_key = False
+    for p in plist:
+
+      if not found_key and re.match(start_expr_key, p):
+        found_key = True
+        new_lines.append(p)
+        continue
+
+      if found_key and re.match(end_expr_key, p):
+        found_key = False
+        new_lines.append(p)
+        continue
+
+      if found_key and enable_packages and p.startswith('#'):
+        new_lines.append(p[1:].strip())
+      elif found_key and not enable_packages and not p.startswith('#'):
+        new_lines.append("# " + p.strip())
+      else:
+        new_lines.append(p.strip())
+
+  with open(file_path, 'w') as f:
+    for p in new_lines:
+      f.write(p + '\n')
+
 def _exit():
   printer(message)
   exit(retcode)
@@ -144,25 +226,53 @@ def clearVfile(pkglist):
 
 
 # check arguments
-if not 2 <= len(sys.argv) <= 3:
+if not 2 <= len(sys.argv) <= 4:
   usage()
 
 for arg in sys.argv[1:]:
   if arg == '--json':
     jsonoutput = True
+  elif arg == 'eos4':
+    eos_version=4
+  elif arg == 'eos5':
+    eos_version=5
   elif arg in actions:
     action = arg
   else:
     print("Error: option %s is not valid" % sys.argv[1])
     usage()
 
+if (action == 'help'):
+  usage()
+
+if not eos_version and (action == 'config'):
+  print("Error: no EOS version was provided")
+  usage()
+
+message = defaultdict(dict)
+
+if (action == 'config'):
+  if eos_version is 4:
+    message['title'] = "Enabling EOS-4 dependencies"
+    cta_conf_json["eos_major_version"] = 4
+    switch_packages(vfiles['cta'], "EOS-4", True)
+    switch_packages(vfiles['cta'], "EOS-5", False)
+  elif eos_version is 5:
+    message['title'] = "Enabling EOS-5 dependencies"
+    cta_conf_json["eos_major_version"] = 5
+    switch_packages(vfiles['cta'], "EOS-4", False)
+    switch_packages(vfiles['cta'], "EOS-5", True)
+  repos_selected = set()
+  repos_selected | get_repo_set_for_cta_version(cta_conf_json["cta_major_version"])
+  repos_selected |= get_repo_set_for_eos_version(cta_conf_json["eos_major_version"])
+  # Update value in config file
+  with open(conf_file, "w") as f:
+    f.write(json.dumps(cta_conf_json))
+  _exit()
+
 # check if CTA packages exist in versionlock.list (ignore arch)
 versions = readVer(vfiles)
 versionlock = checkVfile(versions['cta'])
-message = defaultdict(dict)
-
-if (action == 'help'):
-  usage()
 
 # return versionlock summary
 if (action == 'check'):
@@ -176,6 +286,10 @@ if (action == 'check'):
 # add CTA packages to versionlock.list
 elif (action == 'apply'):
   message['title'] = "Adding CTA packages and dependencies to versionlock.list"
+
+  # Enable CTA repos
+  enable_repos(repos_selected)
+
   if os.path.isfile(no_vlock):
     message['adding']['count'] = 0
     message['adding']['content'] = [ "cta_novlock file present, doing nothing" ]
@@ -197,6 +311,10 @@ elif (action == 'apply'):
 # add CTA packages and overwrite existing versions in versionlock.list
 elif (action == 'forceupdate'):
   message['title'] = "Adding and updating CTA packages and dependencies in versionlock.list"
+
+  # Enable CTA repos
+  enable_repos(repos_selected)
+
   if os.path.isfile(no_vlock):
     message['updating']['count'] = 0
     message['updating']['content'] = [ "cta_novlock file present, doing nothing" ]
@@ -227,6 +345,10 @@ elif (action == 'checkpkg'):
 # remove CTA related packages from versionlock.list
 elif (action == 'remove'):
   message['title'] = "Removing CTA packages and dependencies from versionlock.list"
+
+  # Disable all CTA repos
+  disable_repos(repos_all)
+
   if os.path.isfile(no_vlock):
     message['removing']['count'] = 0
     message['removing']['content'] = [ "cta_novlock file present, doing nothing" ]
diff --git a/cta-release/cta-xrootd.repo b/cta-release/cta-xrootd.repo
new file mode 100644
index 0000000000..9ff8181585
--- /dev/null
+++ b/cta-release/cta-xrootd.repo
@@ -0,0 +1,8 @@
+[cta-xrootd]
+name=XRootD Stable repository
+baseurl=https://xrootd.slac.stanford.edu/binaries/stable/slc/7/$basearch http://xrootd.cern.ch/sw/repos/stable/slc/7/$basearch
+gpgcheck=1
+priority=4
+enabled=0
+protect=0
+gpgkey=http://xrootd.cern.ch/sw/releases/RPM-GPG-KEY.txt
\ No newline at end of file
diff --git a/cta.spec.in b/cta.spec.in
index 18368ef8a4..e86556a930 100644
--- a/cta.spec.in
+++ b/cta.spec.in
@@ -560,6 +560,9 @@ Currently contains a helper for the client-ar script, which should be installed
 Summary: Repository configuration for CTA and its dependencies
 Group: Application/CTA
 Requires: yum-plugin-versionlock
+Requires: yum-plugin-priorities
+Requires: python
+Requires: jq
 %description -n cta-release
 Repository configuration for CTA and its dependencies
 This package contains .repo files, gpg keys and yum-versionlock configuration for CTA
@@ -568,16 +571,23 @@ This package contains .repo files, gpg keys and yum-versionlock configuration fo
 %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/yum.repos.d/*
 %attr(0644,root,root) %{_sysconfdir}/pki/rpm-gpg/*
 %attr(0644,root,root) %{_sysconfdir}/yum/pluginconf.d/versionlock.cta
+%attr(0644,root,root) %{_sysconfdir}/cta/cta-release.conf
 %attr(0755,root,root) %{_bindir}/cta-versionlock
 
-%posttrans -n cta-release
-/usr/bin/cta-versionlock apply
+%post -n cta-release
+# Add CTA version to cta-release.conf file
+cta_major_version=$(echo "%{ctaVersion}" | cut -d '.' -f 1)
+echo $(jq --argjson CTA_MAJOR_VERSION $cta_major_version '. += {"cta_major_version": $CTA_MAJOR_VERSION}' %{_sysconfdir}/cta/cta-release.conf) > %{_sysconfdir}/cta/cta-release.conf
 
 %preun -n cta-release
+/usr/bin/cta-versionlock config eos4
+/usr/bin/cta-versionlock remove
+/usr/bin/cta-versionlock config eos5
 /usr/bin/cta-versionlock remove
 
 
 %changelog
+
 * Tue Nov 08 2022 Jorge Camarero Vera <jorge.camarero@cern.ch> - 4.7.13-2
 - Fix gitlab release tagging pipeline
 
@@ -586,6 +596,9 @@ This package contains .repo files, gpg keys and yum-versionlock configuration fo
 - Change Owner Identifier in the header of Tapes
 - Tool to update the storage class
 
+* Thu Oct 27 2022 Joao Afonso <joao.afonso@cern.ch> - 4.7.12-2
+- Repackaging CTA for easy installation of public RPMs
+
 * Tue Oct 04 2022 Joao Afonso <joao.afonso@cern.ch> - 4.7.12-1
 - Various fixes and improvements to CTA, see ReleaseNotes.md for details
 - Performance improvement: optimized DB queries for getting tape drive states
-- 
GitLab