certbot/tools/snap/build_remote.py

281 lines
10 KiB
Python
Raw Permalink Normal View History

Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
#!/usr/bin/env python3
import argparse
import datetime
import glob
from multiprocessing import Manager
from multiprocessing import Pool
from multiprocessing import Process
from multiprocessing.managers import SyncManager
import os
from os.path import basename
from os.path import dirname
from os.path import exists
from os.path import join
from os.path import realpath
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
import re
Do not reuse existing builds on Launchpad when executing snapcraft remote-build (#8719) We observed recently several unexpected behavior during the execution of snap jobs in Azure. In particular it seems that `snapcraft remote-build` is tending to reattach to the latest builds on Launchpad triggered by the nightly builds on master, independently from the actual branch, status of the code, or targeted architectures. Primarily if the builds on Launchpad are stalled for some reason, it blocks effectively any other Azure snap jobs until someone manually cancel the builds on Launchpad. Secondarily it means that the outcome of the builds may be inconsistent, because they can be the result of a build for the master source even if you are on a PR that modifieds these sources (including `snapcraft.yaml`). After digging in `snapcraft` source code, I realized that the signature computed to understand if a build should be resumed, is not based one some hashes against the snapcraft working directory content, but is simply a hash of the working directory absolute path *itself*. It means that every builds triggered from the working directory `/my/path/certbot` for instance, are recognized as the same unique build on Launchpad side, and may be resumed if they already exist, and so independently from the source code, `snapcraft.yaml` or targeted archs. For the record, relevant parts in `snapcraft` source code: https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/project/_project.py#L44 https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/project/_project.py#L86-L89 https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/cli/remote.py#L128-L132 This PR makes effectively the resume build mechanism effectively a noop by moving the source code first in a temporary directory with random name before running `snapcraft remote-build`. This way the signature is never the same and builds are always recognized as brand new builds. * Invalidate snapcraft remote-build cache by using a temporary workspace. * Capture one more state in the build
2021-03-22 13:39:09 -04:00
import shutil
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
import subprocess
import sys
import tempfile
from threading import Lock
import time
from typing import Dict
from typing import List
from typing import Set
from typing import Tuple
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
CERTBOT_DIR = dirname(dirname(dirname(realpath(__file__))))
PLUGINS = [basename(path) for path in glob.glob(join(CERTBOT_DIR, 'certbot-dns-*'))]
def _execute_build(
target: str, archs: Set[str], status: Dict[str, Dict[str, str]],
workspace: str) -> Tuple[int, List[str]]:
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
Do not reuse existing builds on Launchpad when executing snapcraft remote-build (#8719) We observed recently several unexpected behavior during the execution of snap jobs in Azure. In particular it seems that `snapcraft remote-build` is tending to reattach to the latest builds on Launchpad triggered by the nightly builds on master, independently from the actual branch, status of the code, or targeted architectures. Primarily if the builds on Launchpad are stalled for some reason, it blocks effectively any other Azure snap jobs until someone manually cancel the builds on Launchpad. Secondarily it means that the outcome of the builds may be inconsistent, because they can be the result of a build for the master source even if you are on a PR that modifieds these sources (including `snapcraft.yaml`). After digging in `snapcraft` source code, I realized that the signature computed to understand if a build should be resumed, is not based one some hashes against the snapcraft working directory content, but is simply a hash of the working directory absolute path *itself*. It means that every builds triggered from the working directory `/my/path/certbot` for instance, are recognized as the same unique build on Launchpad side, and may be resumed if they already exist, and so independently from the source code, `snapcraft.yaml` or targeted archs. For the record, relevant parts in `snapcraft` source code: https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/project/_project.py#L44 https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/project/_project.py#L86-L89 https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/cli/remote.py#L128-L132 This PR makes effectively the resume build mechanism effectively a noop by moving the source code first in a temporary directory with random name before running `snapcraft remote-build`. This way the signature is never the same and builds are always recognized as brand new builds. * Invalidate snapcraft remote-build cache by using a temporary workspace. * Capture one more state in the build
2021-03-22 13:39:09 -04:00
temp_workspace = None
try:
# Snapcraft remote-build has a recover feature, that will make it reconnect to an existing
# build on Launchpad if possible. However, the signature used to retrieve a potential
# build is not based on the content of the sources used to build a snap, but on a hash
# of the snapcraft current working directory (the path itself, not the content).
# It means that every build started from /my/path/to/certbot will always be considered
# as the same build, whatever the actual sources are.
# To circumvent this, we create a temporary folder and use it as a workspace to build
# the snap: this path is random, making the recover feature effectively noop.
temp_workspace = tempfile.mkdtemp()
ignore = None
if target == 'certbot':
ignore = shutil.ignore_patterns(".git", "venv*", ".tox")
shutil.copytree(workspace, temp_workspace,
dirs_exist_ok=True, symlinks=True, ignore=ignore) # type:ignore
with tempfile.TemporaryDirectory() as tempdir:
environ = os.environ.copy()
environ['XDG_CACHE_HOME'] = tempdir
process = subprocess.Popen([
'snapcraft', 'remote-build', '--launchpad-accept-public-upload',
'--build-on', ','.join(archs)],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
universal_newlines=True, env=environ, cwd=temp_workspace)
process_output: List[str] = []
for line in process.stdout:
process_output.append(line)
_extract_state(target, line, status)
if any(state for state in status[target].values() if state == 'Chroot problem'):
# On this error the snapcraft process stales. Let's finish it.
process.kill()
process_state = process.wait()
for path in glob.glob(join(temp_workspace, '*.snap')):
shutil.copy(path, workspace)
return process_state, process_output
except BaseException as e:
print(e)
sys.stdout.flush()
raise e
finally:
if temp_workspace:
shutil.rmtree(temp_workspace, ignore_errors=True)
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
def _build_snap(
target: str, archs: Set[str], status: Dict[str, Dict[str, str]],
running: Dict[str, bool], lock: Lock) -> Dict[str, str]:
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
status[target] = {arch: '...' for arch in archs}
if target == 'certbot':
workspace = CERTBOT_DIR
else:
workspace = join(CERTBOT_DIR, target)
retry = 3
while retry:
exit_code, process_output = _execute_build(target, archs, status, workspace)
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
print(f'Build {target} for {",".join(archs)} (attempt {4-retry}/3) ended with '
f'exit code {exit_code}.')
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
sys.stdout.flush()
with lock:
dump_output = exit_code != 0
failed_archs = [arch for arch in archs if status[target][arch] != 'Successfully built']
if any(arch for arch in archs if status[target][arch] == 'Chroot problem'):
print('Some builds failed with the status "Chroot problem".')
print('This status is known to make any future build fail until either '
'the source code changes or the build on Launchpad is deleted.')
print('Please fix the build appropriately before trying a new one.')
# It is useless to retry in this situation.
retry = 0
if exit_code == 0 and not failed_archs:
# We expect to have all target snaps available, or something bad happened.
snaps_list = glob.glob(join(workspace, '*.snap'))
if not len(snaps_list) == len(archs):
print('Some of the expected snaps for a successful build are missing '
f'(current list: {snaps_list}).')
dump_output = True
else:
break
if failed_archs:
# We expect each failed build to have a log file, or something bad happened.
for arch in failed_archs:
if not exists(join(workspace, f'{target}_{arch}.txt')):
dump_output = True
print(f'Missing output on a failed build {target} for {arch}.')
if dump_output:
print(f'Dumping snapcraft remote-build output build for {target}:')
print('\n'.join(process_output))
# Retry the remote build if it has been interrupted (non zero status code)
# or if some builds have failed.
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
retry = retry - 1
running[target] = False
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
return {target: workspace}
def _extract_state(project: str, output: str, status: Dict[str, Dict[str, str]]) -> None:
Do not reuse existing builds on Launchpad when executing snapcraft remote-build (#8719) We observed recently several unexpected behavior during the execution of snap jobs in Azure. In particular it seems that `snapcraft remote-build` is tending to reattach to the latest builds on Launchpad triggered by the nightly builds on master, independently from the actual branch, status of the code, or targeted architectures. Primarily if the builds on Launchpad are stalled for some reason, it blocks effectively any other Azure snap jobs until someone manually cancel the builds on Launchpad. Secondarily it means that the outcome of the builds may be inconsistent, because they can be the result of a build for the master source even if you are on a PR that modifieds these sources (including `snapcraft.yaml`). After digging in `snapcraft` source code, I realized that the signature computed to understand if a build should be resumed, is not based one some hashes against the snapcraft working directory content, but is simply a hash of the working directory absolute path *itself*. It means that every builds triggered from the working directory `/my/path/certbot` for instance, are recognized as the same unique build on Launchpad side, and may be resumed if they already exist, and so independently from the source code, `snapcraft.yaml` or targeted archs. For the record, relevant parts in `snapcraft` source code: https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/project/_project.py#L44 https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/project/_project.py#L86-L89 https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/cli/remote.py#L128-L132 This PR makes effectively the resume build mechanism effectively a noop by moving the source code first in a temporary directory with random name before running `snapcraft remote-build`. This way the signature is never the same and builds are always recognized as brand new builds. * Invalidate snapcraft remote-build cache by using a temporary workspace. * Capture one more state in the build
2021-03-22 13:39:09 -04:00
state = status[project]
if "Sending build data to Launchpad..." in output:
for arch in state.keys():
state[arch] = "Sending build data"
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
match = re.match(r'^.*arch=(\w+)\s+state=([\w ]+).*$', output)
if match:
arch = match.group(1)
state[arch] = match.group(2)
Do not reuse existing builds on Launchpad when executing snapcraft remote-build (#8719) We observed recently several unexpected behavior during the execution of snap jobs in Azure. In particular it seems that `snapcraft remote-build` is tending to reattach to the latest builds on Launchpad triggered by the nightly builds on master, independently from the actual branch, status of the code, or targeted architectures. Primarily if the builds on Launchpad are stalled for some reason, it blocks effectively any other Azure snap jobs until someone manually cancel the builds on Launchpad. Secondarily it means that the outcome of the builds may be inconsistent, because they can be the result of a build for the master source even if you are on a PR that modifieds these sources (including `snapcraft.yaml`). After digging in `snapcraft` source code, I realized that the signature computed to understand if a build should be resumed, is not based one some hashes against the snapcraft working directory content, but is simply a hash of the working directory absolute path *itself*. It means that every builds triggered from the working directory `/my/path/certbot` for instance, are recognized as the same unique build on Launchpad side, and may be resumed if they already exist, and so independently from the source code, `snapcraft.yaml` or targeted archs. For the record, relevant parts in `snapcraft` source code: https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/project/_project.py#L44 https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/project/_project.py#L86-L89 https://github.com/snapcore/snapcraft/blob/82024d3748f96fc63077de8188c5752b58d151be/snapcraft/cli/remote.py#L128-L132 This PR makes effectively the resume build mechanism effectively a noop by moving the source code first in a temporary directory with random name before running `snapcraft remote-build`. This way the signature is never the same and builds are always recognized as brand new builds. * Invalidate snapcraft remote-build cache by using a temporary workspace. * Capture one more state in the build
2021-03-22 13:39:09 -04:00
# You need to reassign the value of status[project] here (rather than doing
# something like status[project][arch] = match.group(2)) for the state change
# to propagate to other processes. See
# https://docs.python.org/3.8/library/multiprocessing.html#proxy-objects for
# more info.
status[project] = state
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
def _dump_status_helper(archs: Set[str], status: Dict[str, Dict[str, str]]) -> None:
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
headers = ['project', *archs]
print(''.join(f'| {item:<25}' for item in headers))
print(f'|{"-" * 26}' * len(headers))
for project, states in sorted(status.items()):
print(''.join(f'| {item:<25}' for item in [project, *[states[arch] for arch in archs]]))
print(f'|{"-" * 26}' * len(headers))
print()
sys.stdout.flush()
def _dump_status(
archs: Set[str], status: Dict[str, Dict[str, str]],
running: Dict[str, bool]) -> None:
while any(running.values()):
print(f'Remote build status at {datetime.datetime.now()}')
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
_dump_status_helper(archs, status)
time.sleep(10)
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
def _dump_results(
targets: Set[str], archs: Set[str], status: Dict[str, Dict[str, str]],
workspaces: Dict[str, str]) -> bool:
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
failures = False
for target in targets:
for arch in archs:
result = status[target][arch]
if result != 'Successfully built':
failures = True
build_output_path = join(workspaces[target], f'{target}_{arch}.txt')
if not exists(build_output_path):
build_output = f'No output has been dumped by snapcraft remote-build.'
else:
with open(join(workspaces[target], f'{target}_{arch}.txt')) as file_h:
build_output = file_h.read()
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
print(f'Output for failed build target={target} arch={arch}')
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
print('-------------------------------------------')
print(build_output)
print('-------------------------------------------')
print()
if not failures:
print('All builds succeeded.')
else:
print('Some builds failed.')
print()
print(f'Results for remote build finished at {datetime.datetime.now()}')
_dump_status_helper(archs, status)
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
return failures
def main():
parser = argparse.ArgumentParser()
parser.add_argument('targets', nargs='+', choices=['ALL', 'DNS_PLUGINS', 'certbot', *PLUGINS],
help='the list of snaps to build')
parser.add_argument('--archs', nargs='+', choices=['amd64', 'arm64', 'armhf'],
default=['amd64'], help='the architectures for which snaps are built')
parser.add_argument('--timeout', type=int, default=None,
help='build process will fail after the provided timeout (in seconds)')
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
args = parser.parse_args()
archs = set(args.archs)
targets = set(args.targets)
if 'ALL' in targets:
targets.remove('ALL')
targets.update(['certbot', 'DNS_PLUGINS'])
if 'DNS_PLUGINS' in targets:
targets.remove('DNS_PLUGINS')
targets.update(PLUGINS)
# If we're building anything other than just Certbot, we need to
# generate the snapcraft files for the DNS plugins.
if targets != {'certbot'}:
subprocess.run(['tools/snap/generate_dnsplugins_all.sh'],
check=True, cwd=CERTBOT_DIR)
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
print('Start remote snap builds...')
print(f' - archs: {", ".join(archs)}')
print(f' - projects: {", ".join(sorted(targets))}')
print()
manager: SyncManager = Manager()
pool = Pool(processes=len(targets))
with manager, pool:
status: Dict[str, Dict[str, str]] = manager.dict()
running = manager.dict({target: True for target in targets})
lock = manager.Lock()
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
async_results = [pool.apply_async(_build_snap, (target, archs, status, running, lock))
for target in targets]
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
process = Process(target=_dump_status, args=(archs, status, running))
process.start()
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
try:
process.join(args.timeout)
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
if process.is_alive():
raise ValueError(f"Timeout out reached ({args.timeout} seconds) during the build!")
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
workspaces = {}
for async_result in async_results:
workspaces.update(async_result.get())
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
if _dump_results(targets, archs, status, workspaces):
raise ValueError("There were failures during the build!")
finally:
process.terminate()
Build snaps using the remote-build feature (#8153) Snapcraft has a feature name `remote-build`. It allows to compile snaps using the Canonical dedicated build architecture for several architectures. Compared to the QEMU-enabled Docker approach used currently, the remote build has several advantages: * the builds are done on the native architecture, making them basically faster than what can be achieved on QEMU * it avoids to depend on `adferrand/snapcraft` (which could be otherwise be fixed with the merge of https://github.com/snapcore/snapcraft/pull/3144, but this will not happen in the short term) * when everything is good, all snaps build can be run in parallel and then can be orchestrated by one single Azure Pipeline job, since the heavy tasks are done remotely. This PR makes the necessary ajustements to use the remote build feature instead of the QEMU-enabled docker approach. One complex task was to be able to compile the `certbot` snap on `arm64` and `armhf`. Indeed on these architectures the pre-compiled wheel for `cffi` is not available. So it needs to be compiled during the snap build. Sadly, the current version of the python plugin in snapcraft is limited by the fact that `wheels` is not installed in the virtual environment set up to build the python packages, and there is no easy way to change that except by overridding the whole build process. In the long term, I think I will open a PR on `snapcraft` Git repository to provide a consistent solution. But for the short term, I used the possibility to provide arguments to the `venv` module, to add the flag `--system-site-packages`. With it, the virtual environment can use the system site package, where `wheel` is available. The other significant additions are in `tools/snap/build_remote.py` script. If invoking the remote build on a local machine is quite straight-forward, it is another story on the CI because we need build auditability and resiliency during these non-interactive actions. In particular we should avoid as possible inconsistent results on the nightly pipeline and the release pipeline. So this script wraps the `snapcraft` call into a retry logic, and improves its logs in the context of parallel builds. For the minor modifications, it is mainly about ensuring that plugins can be built (some of them also need `cffi` for instance), and simplify the Azure Pipeline since all snaps are retrieved in one go. Please note that the `test-` branches still run only the `amd64` architecture. Indeed I noticed that builds on `arm64` and `armhf` are tending to be very slow to start (up to 40 min) while the `amd64` ones wait at max 10 mins, and usually 30 seconds only when the overall load on Canonical side is low. To work on `certbot/certbot` repository, one secured file needs to be added, because `snapcraft` needs to be authenticated against Launchpad with credentials allowing remote builds. To do so, from a local machine that have this capability, one can extract the existing file at `$HOME/.local/share/snapcraft/provider/launchpad/credentials`, and register it as a secured file in Azure Pipeline with the name `snapcraftRemoteBuildCredentials`. * Define scripts * Setup pipeline to use remote builds * Focus on packaging builds * Set credentials * Setup git * Launch all builds in parallel * Add dev dependencies to build cffi and cryptography * Convert to a python logic * Reorganize the pipeline * Handle the fact that snap builds may be taken from cache * Generate constraints * Exit code * Check existence * Try to handle better non zero exit code * Add --system-site-packages to get wheel in the venv * Add executable permissions * Troubleshoot * Dynamic display, take the maximum timeout for snap build job * Allow retries if the remote build does not start * Trigger only amd64 builds for test branches * Exit properly * Update snapcraft.yaml * Fix snap run * Set secured file name * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/templates/jobs/packaging-jobs.yml Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Move order in deps * Reactivate all builds * Use Manager() as a context manager * Use Pool as a context manager * Some nice refactorings * Check snapcraft execution interruption with exit codes * Use f-string and format expressions * Start log * Consistent use of single/double quotes * Better loop to extract lines * Retry on build failures * Few optimizations Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-07-22 19:05:20 -04:00
if __name__ == '__main__':
sys.exit(main())