Skip to content
Snippets Groups Projects
Commit 359714a2 authored by Alex Iribarren's avatar Alex Iribarren Committed by Alex Iribarren
Browse files

Add sanity check for repos

parent dfce1681
No related branches found
No related tags found
No related merge requests found
......@@ -11,6 +11,10 @@ prepare_dirs:
- reposync/gpgkeys/
- reposync/prod.repos.d/
expire_in: 1 day
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
generate_jobs:
stage: prepare
......@@ -23,6 +27,20 @@ generate_jobs:
paths:
- '*.nomad'
expire_in: 1 day
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
sanity_check:
stage: prepare
image: gitlab-registry.cern.ch/linuxsupport/alma9-base:latest
script:
- dnf install -y python3-pip python3-pyyaml
- pip install configparser==4.0.2
- rm -rf /etc/pki/rpm-gpg/
- cp -r gpgkeys /etc/pki/rpm-gpg/
- ./sanityCheck.py -c ${REPOSCONF} -y ${REPOS}
build_reposync:
extends: .build_image
......@@ -32,6 +50,10 @@ build_reposync:
TO: $CI_REGISTRY_IMAGE/reposync
PARENT_PIPELINE_ID: ${CI_PIPELINE_ID}
ARTIFACT_JOB: prepare_dirs
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
stop_deleted:
extends: .nomad
......@@ -46,3 +68,35 @@ stop_deleted:
echo -e "\nDeleting job ${JOB}:"
nomad job stop -verbose ${JOB} || true
done
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
yaml_lint:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
deploy_test:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
deploy:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
# Only run on default branch or tags
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_TAG
deploy_dev:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
# Except on default branch or tags, but not on merge requests
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
when: manual
- when: never
#!/usr/bin/python3
import sys
import os
import getopt
import yaml
import configparser
from configparser import DuplicateSectionError
import dnf
try:
opts, args = getopt.getopt(sys.argv[1:], "c:y:", ["config=", "yumdir="])
except getopt.GetoptError:
print('sanityCheck.py -c <configfile> -y <yumdir>')
sys.exit(1)
config_name = None
for opt, arg in opts:
if opt in ("-c", "--config"):
config_name = arg
elif opt in ("-y", "--yumdir"):
yumdir_name = arg
if not config_name:
print('Missing config file')
sys.exit(1)
if not yumdir_name:
print('Missing yum.repos.d/ directory')
sys.exit(1)
with open(config_name, 'r') as configfile:
config = yaml.safe_load(configfile)
try:
def_schedule = config['defaults']['schedule']
def_checksum = config['defaults']['checksum']
def_pathroot = config['defaults']['pathroot']
def_pathcut = config['defaults']['pathcut']
def_reposync = config['defaults']['run_reposync']
def_runcustomscript = config['defaults']['run_customscript']
def_customscript = config['defaults']['customscript']
def_skippackagecount = config['defaults']['skip_package_count']
except IndexError:
print('Missing configuration options')
sys.exit(2)
ERRORS = WARNINGS = 0
def error(text):
global ERRORS
print(f'\033[91mERROR: {text}\033[0m')
ERRORS += 1
def warning(text):
global WARNINGS
print(f'\033[93mWarning: {text}\033[0m')
WARNINGS += 1
GPG_KEYS = sorted(os.listdir('/etc/pki/rpm-gpg/'))
# This isn't actually a GPG key, so we'll remove it
try:
GPG_KEYS.remove('keyID.sh')
except ValueError:
pass
for repofile in sorted(os.listdir(yumdir_name)):
print()
print(f'Loading {repofile}...')
try:
repoconfig = configparser.ConfigParser(interpolation=None)
with open(os.path.join(yumdir_name, repofile), 'r') as f:
repoconfig.read_file(f)
except IOError as e:
error('ERROR: unable to read repo {0}: {1}'.format(os.path.join(yumdir_name, repofile), str(e)))
continue
except DuplicateSectionError as e:
error('ERROR: duplicate declaration in repo {0}: {1}'.format(os.path.join(yumdir_name, repofile), str(e)))
continue
# We're going to load each repo one by one because we want to see ALL the errors
# Otherwise, DNF will stop at just the first one.
for rid in repoconfig.sections():
try:
RUN_REPOSYNC = config[repofile]['run_reposync']
except KeyError:
RUN_REPOSYNC = def_reposync
try:
CUSTOMSCRIPT = config[repofile]['customscript']
except KeyError:
CUSTOMSCRIPT = def_customscript
if not repoconfig[rid].getboolean('enabled', True):
warning(f'Repo {rid} is disabled')
# If this is a Red Hat repo, we're not going to bother setting up the certs
if CUSTOMSCRIPT == 'bash /root/rhn_update_cert_symlink.sh':
print(f"Skipping {rid} as it is a Red Hat repo, and this script isn't clever enough to handle it")
continue
base = dnf.Base()
baseurl = repoconfig[rid].get('baseurl', None)
del repoconfig[rid]['baseurl']
if not baseurl:
error(f'Repo {rid} is missing baseurl')
repo = base.repos.add_new_repo(rid, base.conf, baseurl=[baseurl], **repoconfig[rid])
if not repo.gpgkey:
warning(f'Warning: Repo {rid} is missing gpgkey')
else:
for key in repo.gpgkey:
if not key.startswith('file://'):
error(f'Error: Repo {rid} gpgkey {key} is not a file:// URL')
elif not os.path.exists(key.replace('file://', '')):
error(f'Error: Repo {rid} gpgkey {key.replace("file://", "")} does not exist')
else:
try:
GPG_KEYS.remove(key.replace('file:///etc/pki/rpm-gpg/', ''))
except ValueError:
pass
# If we're not running reposync, there's no point checking this repo
if not RUN_REPOSYNC:
print(f'Skipping {rid} as reposync is disabled')
continue
try:
repo.load()
except dnf.exceptions.RepoError as e:
error(f"Failed to load repository {rid}: {e}")
continue
print()
if GPG_KEYS:
print('The following GPG keys may no longer be needed: (DOUBLE CHECK BEFORE DELETING!!)')
for key in GPG_KEYS:
print(f' {key}')
print()
if WARNINGS:
print(f'Warnings: {WARNINGS}')
if ERRORS:
print(f'\033[91mErrors: {ERRORS}\033[0m')
sys.exit(ERRORS)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment