Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First version of the image sync script #327

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
70447cf
First version of the image sync script
enolfc Dec 14, 2023
6c43f79
Improve following linter suggestions
enolfc Dec 14, 2023
45b7112
Start moving to a package structure
enolfc Dec 14, 2023
172231b
Run atrope within the container
enolfc Dec 15, 2023
c94ce65
Fix hepix file location
enolfc Dec 15, 2023
2b928ab
Remove non-relevant comment
enolfc Dec 15, 2023
ad4a11d
Improve dockerfile
enolfc Dec 15, 2023
5011071
Fix pip linter issue
enolfc Dec 15, 2023
bcc3bcf
Do not pin the python version
enolfc Dec 15, 2023
fdaade7
Build the atrope container
enolfc Dec 15, 2023
bd7a322
Add missing requirements
enolfc Dec 15, 2023
d7dcc54
Build docker
enolfc Dec 15, 2023
305d6c8
Merge branch 'main' into atrope
enolfc Feb 27, 2024
f47b4a2
Merge branch 'main' into atrope
enolfc Feb 28, 2024
17bc3ba
Update IISAS-FedCloud-cloud.yaml (#333)
astalosj Apr 12, 2024
5109b21
Bump github/super-linter from 5 to 6 (#335)
dependabot[bot] Apr 26, 2024
220ac5c
update site NCG-INGRID-PT (#337)
mariojmdavid May 21, 2024
5cdc2f9
Glue21 JSON (#340)
enolfc May 28, 2024
2a976bb
Add the type of provider (#342)
enolfc May 29, 2024
cd286db
Remove sites: 100IT and UPV-GRyCAP (#343)
enolfc Jun 17, 2024
a4a8f52
Bump docker/build-push-action from 5 to 6 (#345)
dependabot[bot] Jun 18, 2024
94004bd
Remove sites: UNIV-LILLE (#346)
sebastian-luna-valero Jun 20, 2024
4bb7d92
Use fedcloud secrets (#347)
enolfc Jun 24, 2024
a57eba8
Cleaning
enolfc Jun 24, 2024
e9b9ce6
Add image sync config
enolfc Jun 24, 2024
081ef5b
Some testing
enolfc Jun 25, 2024
c8425ba
Do not be so specific
enolfc Jun 25, 2024
6f3e45a
Add group id
enolfc Jun 25, 2024
debfda1
Use the existing configuration
enolfc Jun 25, 2024
a54f875
More debugging and improvements
enolfc Jun 25, 2024
bc222ae
Need the certs properly installed
enolfc Jun 26, 2024
93ab895
Renamed to image-sync
enolfc Jun 26, 2024
8ad17f3
Reorganise code (again!)
enolfc Jun 27, 2024
ba0c18f
Deploy image sync
enolfc Jun 27, 2024
90eef66
IISAS
enolfc Jul 8, 2024
f6a9457
More testing
enolfc Jul 9, 2024
645751a
Update
enolfc Jul 9, 2024
eb09e34
New template
enolfc Jul 9, 2024
4ba1759
Do not fail if no secret available
enolfc Jul 9, 2024
706bc1a
Do sync at WALTON
enolfc Jul 10, 2024
36c58a2
Fix role
enolfc Jul 10, 2024
d5e6fe6
Add disk layout
enolfc Jul 10, 2024
c508dfa
Fix sites location
enolfc Jul 10, 2024
ad691a2
Add volume
enolfc Jul 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
image:
- cloud-info
- caso
- atrope

steps:
- name: Checkout
Expand Down
54 changes: 54 additions & 0 deletions atrope/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
FROM python:3-slim as build

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# hadolint ignore=DL3008
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential gcc git curl gnupg2 \
&& curl -s https://dist.eugridpma.info/distribution/igtf/current/GPG-KEY-EUGridPMA-RPM-3 \
| apt-key add - \
&& echo "deb https://repository.egi.eu/sw/production/cas/1/current egi-igtf core" > /etc/apt/sources.list.d/igtf.list \
&& apt-get update \
&& apt-get install -y ca-policy-egi-core \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /atrope

RUN python -m venv /atrope/venv
ENV PATH="/atrope/venv/bin:$PATH"

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt \
&& cat /etc/grid-security/certificates/*.pem >> "$(python -m requests.certs)"

COPY . .

RUN pip install --no-cache-dir .

# The actual image
FROM python:3-slim

LABEL org.opencontainers.image.source=https://github.com/EGI-Federation/fedcloud-catchall-operations

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# hadolint ignore=DL3015, DL3008
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
gnupg2 qemu-utils \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /atrope

RUN groupadd -g 1999 python \
&& useradd -r -u 1999 -g python python

COPY --chown=python:python --from=build /atrope/venv ./venv

USER 1999


ENV PATH="/atrope/venv/bin:$PATH"
CMD ["sites-sync"]
Empty file added atrope/atrope_sync/__init__.py
Empty file.
168 changes: 168 additions & 0 deletions atrope/atrope_sync/sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import logging
import os
import os.path
import subprocess
import sys
import tempfile

import requests
import yaml
from oslo_config import cfg

# Configuraion
CONF = cfg.CONF
CONF.register_opts(
[
cfg.StrOpt("sites_file", default="sites.yaml"),
cfg.StrOpt("graphql_url", default="https://is.appdb.egi.eu/graphql"),
cfg.ListOpt("formats", default=[]),
cfg.StrOpt("appdb_token"),
],
group="sync",
)

# Check-in config
checkin_grp = cfg.OptGroup("checkin")
CONF.register_opts(
[
cfg.StrOpt("client_id"),
cfg.StrOpt("client_secret"),
cfg.StrOpt("scopes", default="openid profile eduperson_entitlement email"),
cfg.StrOpt(
"discovery_endpoint",
default="https://aai.egi.eu/auth/realms/egi/.well-known/openid-configuration",
),
],
group="checkin",
)


def fetch_site_info():
logging.debug("Fetching site info from AppDB")
query = """
{
siteCloudComputingEndpoints{
items{
endpointURL
site {
name
}
shares: shareList {
VO
entityCreationTime
projectID
}
}
}
}
"""
params = {"query": query}
r = requests.get(
CONF.sync.graphql_url, params=params, headers={"accept": "application/json"}
)
r.raise_for_status()
data = r.json()["data"]["siteCloudComputingEndpoints"]["items"]
return data


def dump_atrope_config(site, share, hepix_file):
config_template = """
[DEFAULT]
state_path = /atrope-state/

[glance]
auth_type = v3oidcclientcredentials
auth_url = {auth_url}
protocol = openid
identity_provider = egi.eu
client_id = {client_id}
client_secret = {client_secret}
scope = {scopes}
discovery_endpoint = {discovery_endpoint}
project_id = {project_id}
access_token_type = access_token
formats = {formats}

[dispatchers]
dispatcher = glance

[cache]
formats = {formats}

[sources]
hepix_sources = {hepix_file}
"""
formats = site.get("formats", CONF.sync.formats)
return config_template.format(
auth_url=site["endpointURL"],
client_id=CONF.checkin.client_id,
client_secret=CONF.checkin.client_secret,
scopes=CONF.checkin.scopes,
discovery_endpoint=CONF.checkin.discovery_endpoint,
project_id=share["projectID"],
formats=",".join(formats),
hepix_file=hepix_file,
)


def dump_hepix_config(share):
hepix = {
share["VO"]: {
"enabled": True,
"endorser": {
"ca": "/DC=ORG/DC=SEE-GRID/CN=SEE-GRID CA 2013",
"dn": "/DC=EU/DC=EGI/C=NL/O=Hosts/O=EGI.eu/CN=appdb.egi.eu",
},
"prefix": "EGI ",
"project": share["projectID"],
"token": CONF.sync.appdb_token,
"url": f"https://vmcaster.appdb.egi.eu/store/vo/{share['VO']}/image.list",
}
}
return yaml.dump(hepix)


def do_sync(sites_config):
sites_info = fetch_site_info()
for site in sites_info:
site_name = site["site"]["name"]
# filter out those sites that are not part of the centralised ops
if site_name not in sites_config:
logging.debug(f"Discarding site {site_name}.")
continue
site.update(sites_config[site_name])
logging.info(f"Configuring site {site_name}")
for share in site["shares"]:
logging.info(f"Configuring {share['VO']}")
with tempfile.TemporaryDirectory() as tmpdirname:
hepix_file = os.path.join(tmpdirname, "hepix.yaml")
with open(os.path.join(tmpdirname, "atrope.conf"), "w+") as f:
f.write(dump_atrope_config(site, share, hepix_file))
with open(hepix_file, "w+") as f:
f.write(dump_hepix_config(share))
cmd = [
"atrope",
"--config-dir",
tmpdirname,
"sync",
]
logging.debug(f"Running {' '.join(cmd)}")
subprocess.call(cmd)


def load_sites():
sites = {}
if os.path.exists(CONF.sync.sites_file):
with open(CONF.sync.sites_file, "r") as f:
sites = yaml.safe_load(f.read())
return sites


def main():
CONF(sys.argv[1:])
logging.basicConfig(level=logging.DEBUG)
do_sync(load_sites())


if __name__ == "__main__":
main()
24 changes: 24 additions & 0 deletions atrope/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"

[project]
name = "atrope_catchall"
version = "0.0.1"
description = "Sync images with atrope"
authors = [
{ name = "Enol Fernandez", email = "[email protected]" },
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
requires-python = ">=3.10"

[project.scripts]
sites-sync = "atrope_sync.sync:main"

[tool.setuptools.dynamic]
dependencies = {file = ["requirements.txt"]}

4 changes: 4 additions & 0 deletions atrope/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
git+https://github.com/enolfc/atrope@catchall
requests
oslo.config
PyYAML