|
Adam Miller |
77c87c8 |
#!/usr/bin/env python
|
|
Adam Miller |
77c87c8 |
# -*- coding: utf-8 -*-
|
|
Adam Miller |
77c87c8 |
#
|
|
Adam Miller |
77c87c8 |
# push-two-week-atomic.py - An utility to sync two-week Atomic releases
|
|
Adam Miller |
77c87c8 |
#
|
|
Adam Miller |
77c87c8 |
# For more information about two-week Atomic releases please visit:
|
|
Adam Miller |
77c87c8 |
# https://fedoraproject.org/wiki/Changes/Two_Week_Atomic
|
|
Adam Miller |
77c87c8 |
#
|
|
Adam Miller |
77c87c8 |
# Copyright (C) 2015 Red Hat, Inc.
|
|
Adam Miller |
77c87c8 |
# SPDX-License-Identifier: GPL-2.0+
|
|
Adam Miller |
77c87c8 |
#
|
|
Adam Miller |
77c87c8 |
# Authors:
|
|
Adam Miller |
77c87c8 |
# Adam Miller <maxamillion@fedoraproject.org>
|
|
|
9a90d4e |
# Patrick Uiterwijk <puiterwijk@redhat.com>
|
|
Adam Miller |
77c87c8 |
#
|
|
Adam Miller |
77c87c8 |
# Exit codes:
|
|
Adam Miller |
77c87c8 |
# 0 - Success
|
|
Adam Miller |
77c87c8 |
# 1 - required arg missing
|
|
Adam Miller |
77c87c8 |
# 2 - no successful AutoCloud builds found
|
|
Adam Miller |
77c87c8 |
# 3 - subcommand failed, error message will be logged.
|
|
|
f1bbd15 |
# 4 - execution canceled by user
|
|
|
47a9c74 |
# 5 - masher lock file found
|
|
Adam Miller |
77c87c8 |
#
|
|
Adam Miller |
77c87c8 |
#
|
|
|
44c5f0d |
# NOTE: This is bad and I feel bad for having written it, here there be dragons
|
|
|
9a90d4e |
# NOTE2: The atomic tree ref code is also ugly. Blame to Patrick, credits to Adam.
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
import os
|
|
Adam Miller |
77c87c8 |
import sys
|
|
Adam Miller |
77c87c8 |
import json
|
|
Adam Miller |
77c87c8 |
import glob
|
|
Adam Miller |
77c87c8 |
import shutil
|
|
Adam Miller |
77c87c8 |
import fnmatch
|
|
Adam Miller |
77c87c8 |
import smtplib
|
|
Adam Miller |
77c87c8 |
import argparse
|
|
Adam Miller |
77c87c8 |
import logging
|
|
Adam Miller |
77c87c8 |
import subprocess
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
import requests
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
from email.mime.multipart import MIMEMultipart
|
|
Adam Miller |
77c87c8 |
from email.mime.text import MIMEText
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Set log level to logging.INFO
|
|
Adam Miller |
77c87c8 |
logging.basicConfig(level=logging.INFO)
|
|
Adam Miller |
77c87c8 |
log = logging.getLogger(os.path.basename(sys.argv[0]))
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Define "constants"
|
|
|
b771e5e |
ATOMIC_DIR = "/mnt/koji/mash/atomic/%s"
|
|
|
fc574dd |
PREVIOUS_MAJOR_RELEASE_FINAL_COMMIT = 'ce555fa89da934e6eef23764fb40e8333234b8b60b6f688222247c958e5ebd5b'
|
|
|
898848f |
TARGET_REF = "fedora/%s/x86_64/atomic-host"
|
|
|
a2b4b50 |
COMPOSE_BASEDIR = "/mnt/koji/compose/twoweek/"
|
|
|
47a9c74 |
MASHER_LOCKFILE_GLOB = "/mnt/koji/mash/updates/MASHING*"
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# FIXME ???? Do we need a real STMP server here?
|
|
Adam Miller |
77c87c8 |
ATOMIC_EMAIL_SMTP = "localhost"
|
|
Adam Miller |
77c87c8 |
ATOMIC_EMAIL_SENDER = "noreply@fedoraproject.org"
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
ATOMIC_EMAIL_RECIPIENTS = [
|
|
Adam Miller |
6e91fe4 |
"cloud@lists.fedoraproject.org",
|
|
Adam Miller |
6e91fe4 |
"rel-eng@lists.fedoraproject.org",
|
|
Adam Miller |
6e91fe4 |
"atomic-devel@projectatomic.io",
|
|
Adam Miller |
6e91fe4 |
"atomic-announce@projectatomic.io",
|
|
Adam Miller |
77c87c8 |
]
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Full path will be:
|
|
Adam Miller |
77c87c8 |
# /pub/alt/stage/$VERSION-$DATE/$IMAGE_TYPE/x86_64/[Images|os]/
|
|
Adam Miller |
77c87c8 |
# http://dl.fedoraproject.org/pub/alt/atomic/stable/
|
|
|
9a49e6c |
ATOMIC_STABLE_BASEDIR = "/pub/alt/atomic/stable/"
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# the modname gets used to construct the fully qualified topic, like
|
|
Adam Miller |
77c87c8 |
# 'org.fedoraproject.prod.releng.blahblahblah'
|
|
Adam Miller |
77c87c8 |
ATOMIC_FEDMSG_MODNAME = "releng"
|
|
Adam Miller |
77c87c8 |
ATOMIC_FEDMSG_CERT_PREFIX = "releng"
|
|
Adam Miller |
77c87c8 |
|
|
|
a2b4b50 |
MARK_ATOMIC_BAD_COMPOSES = None
|
|
|
a2b4b50 |
MARK_ATOMIC_GOOD_COMPOSES = None
|
|
Adam Miller |
ccedbed |
BLOCK_ATOMIC_RELEASE = None
|
|
Adam Miller |
ccedbed |
|
|
Adam Miller |
ccedbed |
try:
|
|
Adam Miller |
ccedbed |
MARK_ATOMIC_BAD_JSON_URL = \
|
|
|
a2b4b50 |
'https://pagure.io/mark-atomic-bad/raw/master/f/bad-composes.json'
|
|
Adam Miller |
ccedbed |
MARK_ATOMIC_BAD_JSON = requests.get(MARK_ATOMIC_BAD_JSON_URL).text
|
|
|
a2b4b50 |
MARK_ATOMIC_BAD_COMPOSES = json.loads(MARK_ATOMIC_BAD_JSON)[u'bad-composes']
|
|
Adam Miller |
ccedbed |
|
|
Adam Miller |
ccedbed |
BLOCK_ATOMIC_RELEASE_JSON_URL = \
|
|
Adam Miller |
ccedbed |
'https://pagure.io/mark-atomic-bad/raw/master/f/block-release.json'
|
|
Adam Miller |
ccedbed |
BLOCK_ATOMIC_RELEASE_JSON = \
|
|
Adam Miller |
ccedbed |
requests.get(BLOCK_ATOMIC_RELEASE_JSON_URL).text
|
|
Adam Miller |
ccedbed |
BLOCK_ATOMIC_RELEASE = \
|
|
Adam Miller |
ccedbed |
json.loads(BLOCK_ATOMIC_RELEASE_JSON)[u'block-release']
|
|
Adam Miller |
ccedbed |
|
|
Adam Miller |
ccedbed |
MARK_ATOMIC_GOOD_URL = \
|
|
|
a2b4b50 |
'https://pagure.io/mark-atomic-bad/raw/master/f/good-composes.json'
|
|
Adam Miller |
ccedbed |
MARK_ATOMIC_GOOD_JSON = \
|
|
Adam Miller |
ccedbed |
requests.get(MARK_ATOMIC_GOOD_URL).text
|
|
|
a2b4b50 |
MARK_ATOMIC_GOOD_COMPOSES = \
|
|
|
a2b4b50 |
json.loads(MARK_ATOMIC_GOOD_JSON)[u'good-composes']
|
|
Adam Miller |
ccedbed |
except Exception, e:
|
|
Adam Miller |
ccedbed |
log.exception(
|
|
Adam Miller |
ccedbed |
"!!!!{0}!!!!\n{0}".format("Failed to fetch or parse json", e)
|
|
Adam Miller |
ccedbed |
)
|
|
Adam Miller |
ccedbed |
sys.exit(1)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
DATAGREPPER_URL = "https://apps.fedoraproject.org/datagrepper/raw"
|
|
Adam Miller |
77c87c8 |
# delta = 2 weeks in seconds
|
|
Adam Miller |
77c87c8 |
DATAGREPPER_DELTA = 1209600
|
|
Adam Miller |
77c87c8 |
# category to filter on from datagrepper
|
|
|
c5c09ee |
DATAGREPPER_TOPIC = "org.fedoraproject.prod.autocloud.compose.complete"
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
SIGUL_SIGNED_TXT_PATH = "/tmp/signed"
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
74ce9e4 |
# Number of atomic testing composes to keep around
|
|
Adam Miller |
74ce9e4 |
ATOMIC_COMPOSE_PERSIST_LIMIT = 20
|
|
Adam Miller |
74ce9e4 |
|
|
Adam Miller |
77c87c8 |
|
|
|
19ff11e |
def construct_url(msg):
|
|
|
19ff11e |
""" Construct the final URL from koji URL.
|
|
|
19ff11e |
|
|
|
19ff11e |
Takes an autocloud fedmsg message and returns the image name and final url.
|
|
|
19ff11e |
"""
|
|
|
c5c09ee |
iul = msg[u'image_url'].split('/')
|
|
|
c5c09ee |
|
|
|
c5c09ee |
# This isn't used in the path for the destination dir, it's in there twice
|
|
|
c5c09ee |
iul.remove('compose')
|
|
|
c5c09ee |
iul.remove('compose')
|
|
|
19ff11e |
|
|
|
c5c09ee |
image_name = iul[-1]
|
|
|
c5c09ee |
image_url = os.path.join(ATOMIC_STABLE_BASEDIR, '/'.join(iul[4:]))
|
|
|
c5c09ee |
return image_name, image_url
|
|
|
19ff11e |
|
|
Adam Miller |
77c87c8 |
def get_latest_successful_autocloud_test_info(
|
|
Adam Miller |
2387a90 |
release,
|
|
Adam Miller |
77c87c8 |
datagrepper_url=DATAGREPPER_URL,
|
|
Adam Miller |
77c87c8 |
delta=DATAGREPPER_DELTA,
|
|
|
a2b4b50 |
topic=DATAGREPPER_TOPIC):
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
get_latest_successful_autocloud_test_info
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
Query datagrepper[0] to find the latest successful Atomic images via
|
|
Adam Miller |
77c87c8 |
the autocloud[1] tests.
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
return -> dict
|
|
Adam Miller |
77c87c8 |
Will return the build information of the latest successful build
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
[0] - https://apps.fedoraproject.org/datagrepper/
|
|
Adam Miller |
77c87c8 |
[1] - https://github.com/kushaldas/autocloud/
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# rows_per_page is maximum 100 from Fedora's datagrepper
|
|
Adam Miller |
77c87c8 |
request_params = {
|
|
Adam Miller |
77c87c8 |
"delta": delta,
|
|
|
a2b4b50 |
"topic": topic,
|
|
Adam Miller |
77c87c8 |
"rows_per_page": 100,
|
|
Adam Miller |
77c87c8 |
}
|
|
Adam Miller |
77c87c8 |
r = requests.get(datagrepper_url, params=request_params)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Start with page 1 response from datagrepper, grab the raw messages
|
|
Adam Miller |
77c87c8 |
# and then continue to populate the list with the rest of the pages of data
|
|
Adam Miller |
77c87c8 |
autocloud_data = r.json()[u'raw_messages']
|
|
Adam Miller |
77c87c8 |
for rpage in range(2, r.json()[u'pages']+1):
|
|
Adam Miller |
77c87c8 |
autocloud_data += requests.get(
|
|
Adam Miller |
77c87c8 |
datagrepper_url,
|
|
Adam Miller |
77c87c8 |
params=dict(page=rpage, **request_params)
|
|
Adam Miller |
77c87c8 |
).json()[u'raw_messages']
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
|
|
|
c5c09ee |
# List comprehension that will return a list of compose information from
|
|
|
c5c09ee |
# AutoCloud (the [u'msg'] payload of autocloud.compose.complete fedmsg)
|
|
|
c5c09ee |
# such that the following criteria are true:
|
|
|
c5c09ee |
#
|
|
|
c5c09ee |
# - Is an Atomic compose (i.e. 'Atomic' is in the compose id)
|
|
|
c5c09ee |
# - No compose artifacts failed the tests
|
|
|
c5c09ee |
# - This is the current Fedora release we want
|
|
|
c5c09ee |
#
|
|
|
c5c09ee |
# OR:
|
|
|
c5c09ee |
# - This compose was manually marked good
|
|
|
c5c09ee |
candidate_composes = [
|
|
|
c5c09ee |
compose[u'msg'] for compose in autocloud_data
|
|
|
c5c09ee |
if u'Atomic' in compose[u'msg'][u'id']
|
|
|
c5c09ee |
and compose[u'msg'][u'results'][u'failed'] == 0
|
|
|
c5c09ee |
and compose[u'msg'][u'release'] == str(release)
|
|
|
c5c09ee |
or compose[u'msg'][u'id'] in MARK_ATOMIC_GOOD_COMPOSES
|
|
Adam Miller |
77c87c8 |
]
|
|
Adam Miller |
77c87c8 |
|
|
|
c5c09ee |
filtered_composes = list(candidate_composes)
|
|
|
c5c09ee |
for compose in candidate_composes:
|
|
|
c5c09ee |
if compose_manually_marked_bad(compose[u'id']):
|
|
|
c5c09ee |
filtered_composes.remove(compose)
|
|
Adam Miller |
1441e42 |
|
|
|
c5c09ee |
# sc = successful compose
|
|
|
c5c09ee |
sc = filtered_composes[0]
|
|
Adam Miller |
ccedbed |
|
|
|
c5c09ee |
autocloud_info = {}
|
|
Adam Miller |
ccedbed |
|
|
|
c5c09ee |
# qcow2 image
|
|
|
c5c09ee |
qcow_msg = [
|
|
|
c5c09ee |
sc[u'results'][u'artifacts'][img] for img in sc[u'results'][u'artifacts']
|
|
|
c5c09ee |
if sc[u'results'][u'artifacts'][img][u'family'] == u'Atomic'
|
|
|
c5c09ee |
and sc[u'results'][u'artifacts'][img][u'type'] == u'qcow2'
|
|
|
c5c09ee |
][0]
|
|
|
c5c09ee |
image_name, image_url = construct_url(qcow_msg)
|
|
|
c5c09ee |
autocloud_info["atomic_qcow2"] = {
|
|
|
c5c09ee |
"compose_id": sc[u'id'],
|
|
|
c5c09ee |
"name": qcow_msg[u'name'],
|
|
|
c5c09ee |
"release": sc[u'release'],
|
|
|
c5c09ee |
"image_name": image_name,
|
|
|
c5c09ee |
"image_url": image_url,
|
|
|
c5c09ee |
}
|
|
Adam Miller |
ccedbed |
|
|
|
c5c09ee |
# raw image
|
|
|
c5c09ee |
#
|
|
|
c5c09ee |
# FIXME - This is a bit of a hack right now, but the raw image is what
|
|
|
c5c09ee |
# the qcow2 is made of so only qcow2 is tested and infers the
|
|
|
c5c09ee |
# success of both qcow2 and raw.xz
|
|
|
c5c09ee |
autocloud_info["atomic_raw"] = {
|
|
|
c5c09ee |
"compose_id": sc[u'id'],
|
|
|
c5c09ee |
"name": qcow_msg[u'name'],
|
|
|
c5c09ee |
"release": sc[u'release'],
|
|
|
c5c09ee |
"image_name": image_name.replace('qcow2', 'raw.xz'), # HACK
|
|
|
c5c09ee |
"image_url": image_url.replace('qcow2', 'raw.xz'), # HACK
|
|
|
c5c09ee |
}
|
|
Adam Miller |
ccedbed |
|
|
|
c5c09ee |
# vagrant libvirt image
|
|
|
c5c09ee |
vlibvirt_msg = [
|
|
|
c5c09ee |
sc[u'results'][u'artifacts'][img] for img in sc[u'results'][u'artifacts']
|
|
|
c5c09ee |
if sc[u'results'][u'artifacts'][img][u'family'] == u'Atomic'
|
|
|
c5c09ee |
and sc[u'results'][u'artifacts'][img][u'type'] == u'vagrant-libvirt'
|
|
|
c5c09ee |
][0]
|
|
|
c5c09ee |
image_name, image_url = construct_url(vlibvirt_msg)
|
|
|
c5c09ee |
autocloud_info["atomic_vagrant_libvirt"] = {
|
|
|
c5c09ee |
"compose_id": sc[u'id'],
|
|
|
c5c09ee |
"name": vlibvirt_msg[u'name'],
|
|
|
c5c09ee |
"release": sc[u'release'],
|
|
|
c5c09ee |
"image_name": image_name,
|
|
|
c5c09ee |
"image_url": image_url,
|
|
|
c5c09ee |
}
|
|
Adam Miller |
1441e42 |
|
|
|
c5c09ee |
# vagrant vbox image
|
|
|
c5c09ee |
vvbox_msg = [
|
|
|
c5c09ee |
sc[u'results'][u'artifacts'][img] for img in sc[u'results'][u'artifacts']
|
|
|
c5c09ee |
if sc[u'results'][u'artifacts'][img][u'family'] == u'Atomic'
|
|
|
c5c09ee |
and sc[u'results'][u'artifacts'][img][u'type'] == u'vagrant-virtualbox'
|
|
|
c5c09ee |
][0]
|
|
|
c5c09ee |
image_name, image_url = construct_url(vvbox_msg)
|
|
|
c5c09ee |
autocloud_info["atomic_vagrant_virtualbox"] = {
|
|
|
c5c09ee |
"compose_id": sc[u'id'],
|
|
|
c5c09ee |
"name": vvbox_msg[u'name'],
|
|
|
c5c09ee |
"release": sc[u'release'],
|
|
|
c5c09ee |
"image_name": image_name,
|
|
|
c5c09ee |
"image_url": image_url,
|
|
|
c5c09ee |
}
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
1441e42 |
return autocloud_info
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
|
|
|
a2b4b50 |
def compose_manually_marked_bad(compose_id, bad_composes=MARK_ATOMIC_BAD_COMPOSES):
|
|
Adam Miller |
77c87c8 |
"""
|
|
|
a2b4b50 |
compose_manually_marked_bad
|
|
Adam Miller |
77c87c8 |
|
|
|
a2b4b50 |
Check for a compose that has been marked bad manually
|
|
Adam Miller |
77c87c8 |
|
|
|
a2b4b50 |
compose_id
|
|
|
a2b4b50 |
Compose id of most recently found auto-tested good compose build
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
return -> bool
|
|
Adam Miller |
77c87c8 |
True if the build was marked bad, else False
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
|
|
|
a2b4b50 |
bad = [c for c in bad_composes if c == compose_id]
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
return len(bad) > 0
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
def send_atomic_announce_email(
|
|
Adam Miller |
77c87c8 |
email_filelist,
|
|
Adam Miller |
77c87c8 |
mail_receivers=ATOMIC_EMAIL_RECIPIENTS,
|
|
Adam Miller |
77c87c8 |
sender_email=ATOMIC_EMAIL_SENDER,
|
|
Colin Walters |
bf45b6b |
sender_smtp=ATOMIC_EMAIL_SMTP,
|
|
Colin Walters |
bf45b6b |
tree_commit=None,
|
|
Colin Walters |
bf45b6b |
tree_version=None):
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
send_atomic_announce_email
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
Send the atomic announce email to the desired recipients
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
released_artifacts = []
|
|
Adam Miller |
77c87c8 |
released_checksums = []
|
|
Adam Miller |
77c87c8 |
for e_file in email_filelist:
|
|
Adam Miller |
77c87c8 |
if "CHECKSUM" in e_file:
|
|
Adam Miller |
77c87c8 |
released_checksums.append(
|
|
|
34eaf97 |
"https://alt.fedoraproject.org{}".format(e_file)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
else:
|
|
Adam Miller |
77c87c8 |
released_artifacts.append(
|
|
|
34eaf97 |
"https://alt.fedoraproject.org{}".format(e_file)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
msg = MIMEMultipart()
|
|
Adam Miller |
77c87c8 |
msg['To'] = "; ".join(mail_receivers)
|
|
Adam Miller |
77c87c8 |
msg['From'] = "noreply@fedoraproject.org"
|
|
Adam Miller |
77c87c8 |
msg['Subject'] = "Fedora Atomic Host Two Week Release Announcement"
|
|
Adam Miller |
77c87c8 |
msg.attach(
|
|
Adam Miller |
77c87c8 |
MIMEText(
|
|
Adam Miller |
77c87c8 |
"""
|
|
Colin Walters |
b5bd2ca |
A new Fedora Atomic Host update is available via an OSTree commit:
|
|
Adam Miller |
77c87c8 |
|
|
Colin Walters |
bf45b6b |
Commit: {}
|
|
Colin Walters |
bf45b6b |
Version: {}
|
|
Colin Walters |
bf45b6b |
|
|
Colin Walters |
bf45b6b |
Existing systems can be upgraded in place via e.g. `atomic host upgrade` or
|
|
Colin Walters |
bf45b6b |
`atomic host deploy`.
|
|
Colin Walters |
bf45b6b |
|
|
Colin Walters |
bf45b6b |
Corresponding image media for new installations can be downloaded from:
|
|
Adam Miller |
d2bf3e1 |
|
|
|
17f2a8b |
https://getfedora.org/en/atomic/download/
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
Respective signed CHECKSUM files can be found here:
|
|
|
34eaf97 |
{}
|
|
Adam Miller |
77c87c8 |
|
|
|
9ec4fc8 |
For direct download, the "latest" targets are always available here:
|
|
|
5ef606f |
https://getfedora.org/atomic_iso_latest
|
|
|
9ec4fc8 |
https://getfedora.org/atomic_qcow2_latest
|
|
|
9ec4fc8 |
https://getfedora.org/atomic_raw_latest
|
|
|
9ec4fc8 |
https://getfedora.org/atomic_vagrant_libvirt_latest
|
|
|
9ec4fc8 |
https://getfedora.org/atomic_vagrant_virtualbox_latest
|
|
|
9ec4fc8 |
|
|
|
9ec4fc8 |
Filename fetching URLs are available here:
|
|
|
5ef606f |
https://getfedora.org/atomic_iso_latest_filename
|
|
|
9ec4fc8 |
https://getfedora.org/atomic_qcow2_latest_filename
|
|
|
9ec4fc8 |
https://getfedora.org/atomic_raw_latest_filename
|
|
|
9ec4fc8 |
https://getfedora.org/atomic_vagrant_libvirt_latest_filename
|
|
|
9ec4fc8 |
https://getfedora.org/atomic_vagrant_virtualbox_latest_filename
|
|
|
9ec4fc8 |
|
|
|
9ec4fc8 |
For more information about the latest targets, please reference the Fedora
|
|
|
9ec4fc8 |
Cloud Wiki space.
|
|
|
9ec4fc8 |
|
|
|
9ec4fc8 |
https://fedoraproject.org/wiki/Cloud#Quick_Links
|
|
|
9ec4fc8 |
|
|
|
9ec4fc8 |
Do note that it can take some of the mirrors up to 12 hours to "check-in" at
|
|
|
9ec4fc8 |
their own discretion.
|
|
|
9a49e6c |
|
|
Adam Miller |
77c87c8 |
Thank you,
|
|
Adam Miller |
77c87c8 |
Fedora Release Engineering
|
|
Adam Miller |
77c87c8 |
""".format(
|
|
|
a724183 |
tree_commit,
|
|
|
a724183 |
tree_version,
|
|
|
a724183 |
'\n'.join(released_checksums)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# FIXME
|
|
Adam Miller |
77c87c8 |
# Need to add package information to fill in the template email
|
|
Adam Miller |
77c87c8 |
#
|
|
Adam Miller |
77c87c8 |
# The following changes are included in this update:
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
try:
|
|
Adam Miller |
77c87c8 |
s = smtplib.SMTP(sender_smtp)
|
|
Adam Miller |
77c87c8 |
s.sendmail(sender_email, mail_receivers, msg.as_string())
|
|
Adam Miller |
77c87c8 |
except smtplib.SMTPException, e:
|
|
|
34eaf97 |
print "ERROR: Unable to send email:\n{}\n".format(e)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
def stage_atomic_release(
|
|
Adam Miller |
77c87c8 |
compose_id,
|
|
Adam Miller |
77c87c8 |
compose_basedir=COMPOSE_BASEDIR,
|
|
|
c5c09ee |
dest_base_dir=ATOMIC_STABLE_BASEDIR):
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
stage_atomic_release
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
stage the release somewhere, this will remove the old and rsync up the
|
|
Adam Miller |
77c87c8 |
new twoweek release
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
|
|
|
a2b4b50 |
source_loc = os.path.join(compose_basedir, compose_id, "compose")
|
|
|
9a49e6c |
dest_dir = os.path.join(dest_base_dir, compose_id)
|
|
Adam Miller |
77c87c8 |
|
|
|
34eaf97 |
# FIXME - need sudo until pungi perms are fixed
|
|
Adam Miller |
77c87c8 |
rsync_cmd = [
|
|
|
34eaf97 |
'sudo',
|
|
Adam Miller |
77c87c8 |
'rsync -avhHP --delete-after',
|
|
|
c5c09ee |
'--exclude Cloud/',
|
|
|
34eaf97 |
"{}/".format(source_loc),
|
|
Adam Miller |
77c87c8 |
dest_dir
|
|
Adam Miller |
77c87c8 |
]
|
|
|
a2b4b50 |
# This looks silly but it gets everything properly split for
|
|
|
a2b4b50 |
# subprocess.call but keeps it from looking messy above.
|
|
|
a2b4b50 |
rsync_cmd = ' '.join(rsync_cmd).split()
|
|
|
a2b4b50 |
if subprocess.call(rsync_cmd):
|
|
Adam Miller |
77c87c8 |
log.error(
|
|
|
34eaf97 |
"stage_atomic_release: rsync command failed: {}".format(rsync_cmd)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
exit(3)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
def sign_checksum_files(
|
|
Adam Miller |
77c87c8 |
key,
|
|
Adam Miller |
77c87c8 |
artifact_path,
|
|
Adam Miller |
77c87c8 |
signed_txt_path=SIGUL_SIGNED_TXT_PATH):
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
sign_checksum_files
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
Use sigul to sign checksum files onces we know the successfully tested
|
|
Adam Miller |
77c87c8 |
builds.
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Grab all the checksum_files
|
|
Adam Miller |
77c87c8 |
checksum_files = []
|
|
Adam Miller |
77c87c8 |
for full_dir_path, _, short_names in os.walk(artifact_path):
|
|
Adam Miller |
77c87c8 |
for sname in fnmatch.filter(short_names, '*CHECKSUM'):
|
|
Adam Miller |
77c87c8 |
checksum_files.append(
|
|
Adam Miller |
77c87c8 |
os.path.join(
|
|
Adam Miller |
77c87c8 |
full_dir_path,
|
|
Adam Miller |
77c87c8 |
sname,
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
for cfile in checksum_files:
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Check to make sure this file isn't already signed, if it is then
|
|
Adam Miller |
77c87c8 |
# don't sign it again
|
|
Adam Miller |
77c87c8 |
already_signed = False
|
|
Adam Miller |
77c87c8 |
with open(cfile, 'r') as f:
|
|
Adam Miller |
77c87c8 |
for line in f.readlines():
|
|
Adam Miller |
77c87c8 |
if "-----BEGIN PGP SIGNED MESSAGE-----" in line:
|
|
Adam Miller |
77c87c8 |
already_signed = True
|
|
Adam Miller |
77c87c8 |
break
|
|
Adam Miller |
77c87c8 |
if already_signed:
|
|
Adam Miller |
77c87c8 |
log.info(
|
|
|
34eaf97 |
"sign_checksum_files: {} is already signed".format(cfile)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
continue
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
shutil.copy(cfile, signed_txt_path)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Basically all of this is ugly and I feel bad about it.
|
|
Adam Miller |
77c87c8 |
sigulsign_cmd = [
|
|
|
34eaf97 |
"sigul sign-text -o {} {} {}".format(
|
|
Adam Miller |
77c87c8 |
signed_txt_path,
|
|
Adam Miller |
77c87c8 |
key,
|
|
Adam Miller |
77c87c8 |
cfile
|
|
Adam Miller |
77c87c8 |
),
|
|
Adam Miller |
77c87c8 |
]
|
|
Adam Miller |
77c87c8 |
|
|
|
34eaf97 |
log.info("sign_checksum_files: Signing {}".format(cfile))
|
|
|
a2b4b50 |
# This looks silly but it gets everything properly split for
|
|
|
a2b4b50 |
# subprocess.call but keeps it from looking messy above.
|
|
|
a2b4b50 |
sigulsign_cmd = ' '.join(sigulsign_cmd).split()
|
|
|
a2b4b50 |
while subprocess.call(sigulsign_cmd):
|
|
Adam Miller |
77c87c8 |
log.warn(
|
|
|
34eaf97 |
"sigul command for {} failed, retrying".format(cfile)
|
|
|
34eaf97 |
)
|
|
|
34eaf97 |
|
|
|
34eaf97 |
if subprocess.call(
|
|
|
34eaf97 |
"chgrp releng-team {}".format(signed_txt_path).split()
|
|
|
34eaf97 |
):
|
|
|
34eaf97 |
log.error(
|
|
|
34eaf97 |
"sign_checksum_files: chgrp releng-team {}".format(
|
|
|
34eaf97 |
signed_txt_path
|
|
|
34eaf97 |
)
|
|
Adam Miller |
77c87c8 |
)
|
|
|
34eaf97 |
sys.exit(3)
|
|
|
34eaf97 |
|
|
|
34eaf97 |
if subprocess.call(
|
|
|
34eaf97 |
"chmod 664 {}".format(signed_txt_path).split()
|
|
|
34eaf97 |
):
|
|
|
34eaf97 |
log.error(
|
|
|
34eaf97 |
"sign_checksum_files: chmod 644 {}".format(
|
|
|
34eaf97 |
signed_txt_path
|
|
|
34eaf97 |
)
|
|
|
34eaf97 |
)
|
|
|
34eaf97 |
sys.exit(3)
|
|
Adam Miller |
77c87c8 |
|
|
|
34eaf97 |
# FIXME - need sudo until new pungi perms are sorted out
|
|
Adam Miller |
77c87c8 |
if subprocess.call(
|
|
|
34eaf97 |
#["sg", "releng-team", "'mv {} {}'".format(signed_txt_path, cfile)]
|
|
|
34eaf97 |
"sudo mv {} {}".format(signed_txt_path, cfile).split()
|
|
Adam Miller |
77c87c8 |
):
|
|
Adam Miller |
77c87c8 |
log.error(
|
|
|
34eaf97 |
"sign_checksum_files: sudo sg releng-team 'mv {} {}' FAILED".format(
|
|
Adam Miller |
77c87c8 |
signed_txt_path,
|
|
Adam Miller |
77c87c8 |
cfile,
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
sys.exit(3)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
def fedmsg_publish(topic, msg):
|
|
Adam Miller |
77c87c8 |
""" Try to publish a message on the fedmsg bus.
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
But proceed happily if we weren't able to publish anything.
|
|
Adam Miller |
77c87c8 |
"""
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
try:
|
|
Adam Miller |
77c87c8 |
import fedmsg
|
|
Adam Miller |
77c87c8 |
import fedmsg.config
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Load config from disk with all the environment goodies.
|
|
Adam Miller |
77c87c8 |
config = fedmsg.config.load_config()
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# And overwrite some values
|
|
Adam Miller |
77c87c8 |
config['modname'] = ATOMIC_FEDMSG_MODNAME
|
|
Adam Miller |
77c87c8 |
config['cert_prefix'] = ATOMIC_FEDMSG_CERT_PREFIX
|
|
Adam Miller |
77c87c8 |
config['active'] = True
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# Send it.
|
|
Adam Miller |
77c87c8 |
fedmsg.publish(topic=topic, msg=msg, **config)
|
|
Adam Miller |
77c87c8 |
except Exception:
|
|
Adam Miller |
77c87c8 |
# If you didn't know, log.exception automatically logs the traceback.
|
|
Adam Miller |
77c87c8 |
log.exception("Failed to publish to fedmsg.")
|
|
Adam Miller |
77c87c8 |
# But by passing, we don't let the exception bubble up and kill us.
|
|
Adam Miller |
77c87c8 |
pass
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
|
|
|
9a49e6c |
def prune_old_composes(prune_base_dir, prune_limit):
|
|
Adam Miller |
74ce9e4 |
"""
|
|
|
9a49e6c |
prune_old_composes
|
|
Adam Miller |
74ce9e4 |
|
|
Adam Miller |
74ce9e4 |
Clean up old testing composes from /pub/alt/
|
|
|
9a49e6c |
|
|
|
9a49e6c |
:param prune_base_dir: str, path to base diretory needing pruning
|
|
|
9a49e6c |
:param prune_limit: int, the number of composes that should be kept,
|
|
|
9a49e6c |
pruning all others.
|
|
Adam Miller |
74ce9e4 |
"""
|
|
Adam Miller |
74ce9e4 |
|
|
Adam Miller |
74ce9e4 |
prune_candidate_dirs = os.listdir(prune_base_dir)
|
|
Adam Miller |
74ce9e4 |
|
|
|
47d879f |
if len(prune_candidate_dirs) > 2:
|
|
|
47d879f |
# Sort then reverse so we can slice the list from [0:prune_limit]
|
|
|
47d879f |
prune_candidate_dirs.sort()
|
|
|
47d879f |
prune_candidate_dirs.reverse()
|
|
|
47d879f |
|
|
|
47d879f |
for candidate_dir in prune_candidate_dirs[0:prune_limit]:
|
|
|
47d879f |
#try:
|
|
|
47d879f |
# shutil.rmtree(
|
|
|
47d879f |
# os.path.join(prune_base_dir, candidate_dir)
|
|
|
47d879f |
# )
|
|
|
47d879f |
#except OSError, e:
|
|
|
47d879f |
# log.error(
|
|
|
47d879f |
# "Error trying to remove directory: {}\n{}".format(
|
|
|
47d879f |
# candidate_dir,
|
|
|
47d879f |
# e
|
|
|
47d879f |
# )
|
|
|
47d879f |
# )
|
|
|
47d879f |
|
|
|
47d879f |
#FIXME - need to do this with sudo until pungi perms are fixed
|
|
|
47d879f |
prune_cmd = "sudo rm -fr {}".format(
|
|
|
47d879f |
os.path.join(
|
|
|
47d879f |
prune_base_dir,
|
|
|
47d879f |
candidate_dir
|
|
|
47d879f |
)
|
|
Adam Miller |
74ce9e4 |
)
|
|
|
47d879f |
if subprocess.call(prune_cmd.split()):
|
|
|
47d879f |
log.error(
|
|
|
47d879f |
"prune_old_composes: command failed: {}".format(prune_cmd)
|
|
|
47d879f |
)
|
|
Adam Miller |
74ce9e4 |
|
|
|
9bf9f51 |
def generate_static_delta(release, old_commit, new_commit):
|
|
|
9bf9f51 |
"""
|
|
|
9bf9f51 |
generate_static_delta
|
|
|
9a90d4e |
|
|
|
9bf9f51 |
Generate a static delta betwee two commits
|
|
|
9bf9f51 |
|
|
|
9bf9f51 |
:param release - the Fedora release to target (25,26,etc)
|
|
|
9bf9f51 |
:param old_commit - starting point for delta
|
|
|
9bf9f51 |
:param new_commit - ending point for delta
|
|
|
9bf9f51 |
"""
|
|
|
6fda058 |
# Run as apache user because the files we are editing/creating
|
|
|
6fda058 |
# need to be owned by the apache user
|
|
|
6fda058 |
diff_cmd = ["/usr/bin/sudo", "-u", "apache",
|
|
|
6fda058 |
"ostree", "static-delta", "generate", "--repo",
|
|
|
9a90d4e |
ATOMIC_DIR % release, "--if-not-exists", "--from", old_commit,
|
|
|
9a90d4e |
"--to", new_commit]
|
|
|
9bf9f51 |
log.info("Creating Static Delta from %s to %s" % (old_commit, new_commit))
|
|
|
9a90d4e |
if subprocess.call(diff_cmd):
|
|
|
9bf9f51 |
log.error("generate_static_delta: diff generation failed: %s", diff_cmd)
|
|
|
9a90d4e |
exit(3)
|
|
|
9a90d4e |
|
|
|
1e9c81a |
def update_ostree_summary_file(release):
|
|
|
1e9c81a |
"""
|
|
|
1e9c81a |
update_ostree_summary_file
|
|
|
1e9c81a |
|
|
|
1e9c81a |
Update the summary file for the ostree repo
|
|
|
1e9c81a |
|
|
|
1e9c81a |
:param release - the Fedora release to target (25,26,etc)
|
|
|
1e9c81a |
"""
|
|
|
1e9c81a |
# Run as apache user because the files we are editing/creating
|
|
|
1e9c81a |
# need to be owned by the apache user
|
|
|
1e9c81a |
summary_cmd = ["/usr/bin/sudo", "-u", "apache",
|
|
|
1e9c81a |
"ostree", "summary", "-u", "--repo",
|
|
|
1e9c81a |
ATOMIC_DIR % release]
|
|
|
1e9c81a |
log.info("Updating Summary file")
|
|
|
1e9c81a |
if subprocess.call(summary_cmd):
|
|
|
1e9c81a |
log.error("update_ostree_summary_file: update failed: %s", summary_cmd)
|
|
|
1e9c81a |
exit(3)
|
|
|
1e9c81a |
|
|
|
9bf9f51 |
def move_tree_commit(release, old_commit, new_commit):
|
|
|
9bf9f51 |
generate_static_delta(release=release,
|
|
|
9bf9f51 |
old_commit=old_commit,
|
|
|
9bf9f51 |
new_commit=new_commit)
|
|
|
9bf9f51 |
|
|
|
9bf9f51 |
log.info("Moving ref %s to commit %s" %(TARGET_REF, new_commit))
|
|
|
6fda058 |
reset_cmd = ['/usr/bin/sudo', '-u', 'apache',
|
|
|
6fda058 |
'ostree', 'reset', TARGET_REF % release,
|
|
|
0dae9d2 |
new_commit, '--repo', ATOMIC_DIR % release]
|
|
|
0dae9d2 |
if subprocess.call(reset_cmd):
|
|
|
0dae9d2 |
log.error("move_tree_commit: resetting ref to new commit failed: %s", reset_cmd)
|
|
|
0dae9d2 |
exit(3)
|
|
|
9a90d4e |
|
|
|
1e9c81a |
update_ostree_summary_file(release)
|
|
|
1e9c81a |
|
|
|
9a90d4e |
|
|
|
9a90d4e |
|
|
Adam Miller |
77c87c8 |
if __name__ == '__main__':
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
# get args from command line
|
|
Adam Miller |
77c87c8 |
parser = argparse.ArgumentParser()
|
|
Adam Miller |
77c87c8 |
parser.add_argument(
|
|
Adam Miller |
77c87c8 |
"-k",
|
|
Adam Miller |
77c87c8 |
"--key",
|
|
Adam Miller |
77c87c8 |
help="signing key to use with sigul",
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
2387a90 |
parser.add_argument(
|
|
Adam Miller |
2387a90 |
"-r",
|
|
Adam Miller |
2387a90 |
"--release",
|
|
|
47a9c74 |
help="Fedora Release to target for release (Ex: 24, 25, rawhide)",
|
|
|
47a9c74 |
)
|
|
|
47a9c74 |
parser.add_argument(
|
|
|
47a9c74 |
"-f",
|
|
|
47a9c74 |
"--force",
|
|
|
47a9c74 |
type=bool,
|
|
|
47a9c74 |
default=False,
|
|
|
47a9c74 |
help="Force the release even if masher lock files are found (check with RelEng first)",
|
|
Adam Miller |
2387a90 |
)
|
|
Adam Miller |
77c87c8 |
pargs = parser.parse_args()
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
if not pargs.key:
|
|
Adam Miller |
77c87c8 |
log.error("No key passed, see -h for help")
|
|
Adam Miller |
77c87c8 |
sys.exit(1)
|
|
Adam Miller |
2387a90 |
if not pargs.release:
|
|
Adam Miller |
2387a90 |
log.error("No release arg passed, see -h for help")
|
|
Adam Miller |
2387a90 |
sys.exit(1)
|
|
Adam Miller |
77c87c8 |
|
|
|
47a9c74 |
log.info("Checking for masher lock files")
|
|
|
47a9c74 |
if glob.glob(MASHER_LOCKFILE_GLOB) and not pargs.force:
|
|
|
47a9c74 |
errmsg = """
|
|
|
47a9c74 |
Masher file found, must --force to proceed.
|
|
|
47a9c74 |
|
|
|
47a9c74 |
MAKE SURE YOU KNOW WHAT YOU ARE DOING, WHEN IN DOUBT CHECK WITH
|
|
|
47a9c74 |
#fedora-releng on irc.freenode.net TO VERIFY WE ARE SAFE TO NOT
|
|
|
47a9c74 |
BREAK MASHER
|
|
|
47a9c74 |
"""
|
|
|
47a9c74 |
log.error(errmsg)
|
|
|
47a9c74 |
sys.exit(5)
|
|
|
47a9c74 |
|
|
|
47a9c74 |
|
|
|
47a9c74 |
|
|
Adam Miller |
a8e752a |
log.info("Checking to make sure release is not currently blocked")
|
|
Adam Miller |
a8e752a |
if BLOCK_ATOMIC_RELEASE:
|
|
Adam Miller |
a8e752a |
log.info("Release Blocked: Exiting.")
|
|
Adam Miller |
a8e752a |
sys.exit(0)
|
|
Adam Miller |
a8e752a |
|
|
Adam Miller |
77c87c8 |
log.info("Querying datagrepper for latest AutoCloud successful tests")
|
|
Adam Miller |
77c87c8 |
# Acquire the latest successful builds from datagrepper
|
|
Adam Miller |
2387a90 |
tested_autocloud_info = get_latest_successful_autocloud_test_info(
|
|
Adam Miller |
2387a90 |
pargs.release
|
|
Adam Miller |
2387a90 |
)
|
|
|
c5c09ee |
|
|
|
c5c09ee |
# FIXME - DEBUGGING
|
|
|
c5c09ee |
log.info("{}\n{}".format("TESTED_AUTOCLOUD_INFO", json.dumps(tested_autocloud_info, indent=2)))
|
|
|
c5c09ee |
|
|
Adam Miller |
77c87c8 |
log.info("Query to datagrepper complete")
|
|
Adam Miller |
77c87c8 |
# If the dict is empty, there were no successful builds in the last two
|
|
Adam Miller |
77c87c8 |
# weeks, error accordingly
|
|
Adam Miller |
77c87c8 |
if not tested_autocloud_info:
|
|
Adam Miller |
77c87c8 |
log.error("No successful builds found")
|
|
Adam Miller |
77c87c8 |
sys.exit(2)
|
|
Adam Miller |
77c87c8 |
|
|
|
9a90d4e |
log.info("Extracting compose_id from tested autocloud data")
|
|
|
9a90d4e |
compose_id = tested_autocloud_info['atomic_qcow2']['compose_id']
|
|
|
9a90d4e |
|
|
|
9a90d4e |
# TODO: https://github.com/kushaldas/tunirtests/pull/59 will allow us to
|
|
|
9a90d4e |
# extract this from the autocloud test results.
|
|
|
9a90d4e |
print('Releasing compose %s' % compose_id)
|
|
|
9a90d4e |
tree_commit = None
|
|
Colin Walters |
bf45b6b |
tree_version = None
|
|
|
9a90d4e |
while not tree_commit:
|
|
|
9a90d4e |
tree_commit = raw_input('Tree commit: ').strip()
|
|
Colin Walters |
bf45b6b |
try:
|
|
Colin Walters |
bf45b6b |
print("Validating and finding version of {}".format(tree_commit))
|
|
|
abf16c3 |
tree_version = subprocess.check_output(['/usr/bin/ostree', '--repo=' + ATOMIC_DIR % pargs.release, 'show', '--print-metadata-key=version', tree_commit])
|
|
Colin Walters |
bf45b6b |
except subprocess.CalledProcessError as e:
|
|
|
114ffb9 |
print('Error when validating commit: %s. Try again.' % tree_commit)
|
|
|
9a90d4e |
tree_commit = None
|
|
Colin Walters |
bf45b6b |
continue
|
|
Colin Walters |
bf45b6b |
# It's in GVariant print format by default, we can make this less hacky when
|
|
Colin Walters |
bf45b6b |
# porting to use libostree.
|
|
|
5c287ae |
tree_version = tree_version.replace("'", "")
|
|
|
9a90d4e |
|
|
|
2ad8a41 |
rev_parse_cmd = ['/usr/bin/ostree', 'rev-parse', '--repo',
|
|
|
2ad8a41 |
ATOMIC_DIR % pargs.release, TARGET_REF % pargs.release]
|
|
|
0dae9d2 |
previous_commit = subprocess.check_output(rev_parse_cmd).strip()
|
|
|
9a90d4e |
|
|
|
47a9c74 |
# This could happen if there was a failure in this script sending the email
|
|
|
f1bbd15 |
# or anything after the commit has already been moved.
|
|
|
f1bbd15 |
if previous_commit == tree_commit:
|
|
|
f1bbd15 |
answer = raw_input('ref is already at that commit, are you sure?: (y/n)').strip()
|
|
|
f1bbd15 |
if answer.lower() != 'y':
|
|
|
f1bbd15 |
sys.exit(4)
|
|
|
f1bbd15 |
|
|
Adam Miller |
77c87c8 |
log.info("Sending fedmsg releng.atomic.twoweek.begin")
|
|
Adam Miller |
77c87c8 |
fedmsg_publish(
|
|
Adam Miller |
77c87c8 |
topic="atomic.twoweek.begin",
|
|
Adam Miller |
77c87c8 |
msg=dict(**tested_autocloud_info)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
|
|
|
9a49e6c |
log.info("Signing image metadata - compose")
|
|
Adam Miller |
77c87c8 |
sign_checksum_files(
|
|
Adam Miller |
77c87c8 |
pargs.key,
|
|
Adam Miller |
2387a90 |
os.path.join(COMPOSE_BASEDIR, compose_id),
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
|
|
|
f1bbd15 |
# If we are already at the new commit then there is nothing to do
|
|
|
f1bbd15 |
if previous_commit == tree_commit:
|
|
|
f1bbd15 |
log.info("Tree commit is already at %s. Skipping move", tree_commit)
|
|
|
f1bbd15 |
else:
|
|
|
f1bbd15 |
log.info("Moving tree commit %s => %s (%s)", previous_commit, tree_commit, tree_version)
|
|
|
f1bbd15 |
move_tree_commit(pargs.release, previous_commit, tree_commit)
|
|
|
9a90d4e |
|
|
|
2e550c0 |
# Also, if existing previous release commit is defined, then
|
|
|
2e550c0 |
# generate a static delta from it
|
|
|
2e550c0 |
if PREVIOUS_MAJOR_RELEASE_FINAL_COMMIT is not None:
|
|
|
2e550c0 |
generate_static_delta(release=pargs.release,
|
|
|
2e550c0 |
old_commit=PREVIOUS_MAJOR_RELEASE_FINAL_COMMIT,
|
|
|
2e550c0 |
new_commit=tree_commit)
|
|
|
2e550c0 |
update_ostree_summary_file(pargs.release)
|
|
|
2e550c0 |
|
|
Adam Miller |
77c87c8 |
log.info("Staging release content in /pub/alt/atomic/stable/")
|
|
Adam Miller |
77c87c8 |
stage_atomic_release(compose_id)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
log.info("Sending fedmsg releng.atomic.twoweek.complete")
|
|
Adam Miller |
77c87c8 |
fedmsg_publish(
|
|
Adam Miller |
77c87c8 |
topic="atomic.twoweek.complete",
|
|
Adam Miller |
77c87c8 |
msg=dict(**tested_autocloud_info)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
77c87c8 |
log.info("Sending Two Week Atomic announcement email")
|
|
Adam Miller |
77c87c8 |
# Find all the Atomic images and CHECKSUM files to include in the email
|
|
Adam Miller |
77c87c8 |
email_filelist = []
|
|
|
9a49e6c |
for full_dir_path, _, short_names in \
|
|
|
47d879f |
os.walk(os.path.join(ATOMIC_STABLE_BASEDIR, compose_id)):
|
|
Adam Miller |
77c87c8 |
for sname in fnmatch.filter(short_names, '*Atomic*'):
|
|
Adam Miller |
77c87c8 |
email_filelist.append(
|
|
Adam Miller |
77c87c8 |
os.path.join(
|
|
Adam Miller |
77c87c8 |
full_dir_path,
|
|
Adam Miller |
77c87c8 |
sname,
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
)
|
|
Adam Miller |
77c87c8 |
for c_file in glob.glob(os.path.join(full_dir_path, "*CHECKSUM")):
|
|
Adam Miller |
77c87c8 |
email_filelist.append(c_file)
|
|
|
a2b4b50 |
|
|
Colin Walters |
bf45b6b |
send_atomic_announce_email(set(email_filelist), tree_commit=tree_commit,
|
|
Colin Walters |
bf45b6b |
tree_version=tree_version)
|
|
Adam Miller |
77c87c8 |
|
|
|
c5c09ee |
# FIXME - The logic in this functioni is broken, leave it disabled for now
|
|
|
c5c09ee |
#log.info("Pruning old Atomic test composes")
|
|
|
c5c09ee |
#prune_old_composes(ATOMIC_STABLE_BASEDIR, 2)
|
|
Adam Miller |
74ce9e4 |
|
|
Adam Miller |
77c87c8 |
log.info("Two Week Atomic Release Complete!")
|
|
Adam Miller |
77c87c8 |
|
|
Adam Miller |
7cf81a4 |
print("############REMINDER##########\n#\n#\n")
|
|
|
34eaf97 |
print("Reset the block-release value to false in {}".format(
|
|
Adam Miller |
7cf81a4 |
"https://pagure.io/mark-atomic-bad"
|
|
Adam Miller |
7cf81a4 |
))
|
|
Adam Miller |
7cf81a4 |
|
|
Adam Miller |
77c87c8 |
# vim: set expandtab sw=4 sts=4 ts=4
|