Compare commits

..
Author SHA1 Message Date
dboreham 5e7b51ee6a Update version
Former-commit-id: 6ae86dbcec
2023-01-19 14:19:39 -07:00
dboreham 50103fcc9c Merge pull request #137 from cerc-io/dboreham/missing-stack-error
Error check stack config

Former-commit-id: edbf674df7
2023-01-19 14:14:34 -07:00
dboreham edb7346f31 Error check stack config
Former-commit-id: d454a4ffc1
2023-01-19 14:13:57 -07:00
dboreham 377d18d540 Merge pull request #136 from cerc-io/dboreham/small-fixes
Some small fixes

Former-commit-id: cefe10d124
2023-01-19 13:39:06 -07:00
dboreham 6ed90536cf Implement continue on error for npm builds
Former-commit-id: 34aa613d04
2023-01-19 13:38:04 -07:00
dboreham 7d00228ca2 Remove result code check
Former-commit-id: 6faa933d42
2023-01-19 13:30:01 -07:00
dboreham 8f9f23b1c4 Implement stop on error building containers
Former-commit-id: bbbb57ec06
2023-01-19 13:20:53 -07:00
dboreham 429e04f81d Catch docker run exceptions
Former-commit-id: 68c7f91052
2023-01-19 13:00:35 -07:00
dboreham 7a9926b695 Remove extraneous stderr output
Former-commit-id: 3b5efc8f0f
2023-01-19 13:00:06 -07:00
dboreham 0372504f44 Merge pull request #135 from cerc-io/dboreham/fix-npm-builds
Fix various npm build issues

Former-commit-id: d94ed55642
2023-01-19 11:34:19 -07:00
dboreham b29537ad7c Fix various npm build issues
Former-commit-id: 9fb96d8458
2023-01-19 11:33:34 -07:00
dboreham 1cf58c900e Update version
Former-commit-id: d05a47946a
2023-01-18 22:07:04 -07:00
10 changed files with 101 additions and 54 deletions
+15 -12
View File
@@ -1,4 +1,4 @@
# Copyright © 2022 Cerc
# Copyright © 2022, 2023 Cerc
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -21,13 +21,13 @@
# TODO: display the available list of containers; allow re-build of either all or specific containers
import os
import sys
from decouple import config
import subprocess
import click
import importlib.resources
from pathlib import Path
import yaml
from .util import include_exclude_check
from .util import include_exclude_check, get_parsed_stack_config
# TODO: find a place for this
# epilog="Config provided either in .env or settings.ini or env vars: CERC_REPO_BASE_DIR (defaults to ~/cerc)"
@@ -45,6 +45,7 @@ def command(ctx, include, exclude):
dry_run = ctx.obj.dry_run
local_stack = ctx.obj.local_stack
stack = ctx.obj.stack
continue_on_error = ctx.obj.continue_on_error
# See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure
container_build_dir = Path(__file__).absolute().parent.joinpath("data", "container-build")
@@ -68,13 +69,8 @@ def command(ctx, include, exclude):
containers_in_scope = []
if stack:
# In order to be compatible with Python 3.8 we need to use this hack to get the path:
# See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure
stack_file_path = Path(__file__).absolute().parent.joinpath("data", "stacks", stack, "stack.yml")
with stack_file_path:
stack_config = yaml.safe_load(open(stack_file_path, "r"))
# TODO: syntax check the input here
containers_in_scope = stack_config['containers']
stack_config = get_parsed_stack_config(stack)
containers_in_scope = stack_config['containers']
else:
containers_in_scope = all_containers
@@ -112,8 +108,15 @@ def command(ctx, include, exclude):
if verbose:
print(f"Executing: {build_command}")
build_result = subprocess.run(build_command, shell=True, env=container_build_env)
# TODO: check result in build_result.returncode
print(f"Result is: {build_result}")
if verbose:
print(f"Return code is: {build_result.returncode}")
if build_result.returncode != 0:
print(f"Error running build for {container}")
if not continue_on_error:
print("FATAL Error: container build failed and --continue-on-error not set, exiting")
sys.exit(1)
else:
print("****** Container Build Error, continuing because --continue-on-error is set")
else:
print("Skipped")
+30 -24
View File
@@ -1,4 +1,4 @@
# Copyright © 2022 Cerc
# Copyright © 2022, 2023 Cerc
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -19,13 +19,12 @@
# CERC_REPO_BASE_DIR defaults to ~/cerc
import os
import sys
from decouple import config
import click
import importlib.resources
from pathlib import Path
from python_on_whales import docker
import yaml
from .util import include_exclude_check
from python_on_whales import docker, DockerException
from .util import include_exclude_check, get_parsed_stack_config
@click.command()
@click.option('--include', help="only build these packages")
@@ -40,6 +39,7 @@ def command(ctx, include, exclude):
local_stack = ctx.obj.local_stack
debug = ctx.obj.debug
stack = ctx.obj.stack
continue_on_error = ctx.obj.continue_on_error
if local_stack:
dev_root_path = os.getcwd()[0:os.getcwd().rindex("stack-orchestrator")]
@@ -60,13 +60,9 @@ def command(ctx, include, exclude):
packages_in_scope = []
if stack:
# In order to be compatible with Python 3.8 we need to use this hack to get the path:
# See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure
stack_file_path = Path(__file__).absolute().parent.joinpath("data", "stacks", stack, "stack.yml")
with stack_file_path:
stack_config = yaml.safe_load(open(stack_file_path, "r"))
# TODO: syntax check the input here
packages_in_scope = stack_config['npms']
stack_config = get_parsed_stack_config(stack)
# TODO: syntax check the input here
packages_in_scope = stack_config['npms']
else:
packages_in_scope = all_packages
@@ -84,18 +80,28 @@ def command(ctx, include, exclude):
if verbose:
print(f"Executing: {build_command}")
envs = {"CERC_NPM_AUTH_TOKEN": os.environ["CERC_NPM_AUTH_TOKEN"]} | ({"CERC_SCRIPT_DEBUG": "true"} if debug else {})
build_result = docker.run("cerc/builder-js",
remove=True,
interactive=True,
tty=True,
user=f"{os.getuid()}:{os.getgid()}",
envs=envs,
add_hosts=[("gitea.local", "host-gateway")],
volumes=[(repo_full_path, "/workspace")],
command=build_command
)
# TODO: check result in build_result.returncode
print(f"Result is: {build_result}")
try:
docker.run("cerc/builder-js",
remove=True,
interactive=True,
tty=True,
user=f"{os.getuid()}:{os.getgid()}",
envs=envs,
add_hosts=[("gitea.local", "host-gateway")],
volumes=[(repo_full_path, "/workspace")],
command=build_command
)
# Note that although the docs say that build_result should contain
# the command output as a string, in reality it is always the empty string.
# Since we detect errors via catching exceptions below, we can safely ignore it here.
except DockerException as e:
print(f"Error executing build for {package} in container:\n {e}")
if not continue_on_error:
print("FATAL Error: build failed and --continue-on-error not set, exiting")
sys.exit(1)
else:
print("****** Build Error, continuing because --continue-on-error is set")
else:
print("Skipped")
@@ -13,6 +13,8 @@ if [[ -z "${CERC_NPM_AUTH_TOKEN}" ]]; then
echo "CERC_NPM_AUTH_TOKEN is not set" >&2
exit 1
fi
# Exit on error
set -e
local_npm_registry_url=$1
package_publish_version=$2
# TODO: make this a paramater and allow a list of scopes
@@ -17,6 +17,8 @@ if [[ $# -eq 2 ]]; then
else
package_publish_version=$( cat package.json | jq -r .version )
fi
# Exit on error
set -e
# Get the name of this package from package.json since we weren't passed that
package_name=$( cat package.json | jq -r .name )
local_npm_registry_url=$1
@@ -24,7 +26,7 @@ npm config set @lirewine:registry ${local_npm_registry_url}
npm config set @cerc-io:registry ${local_npm_registry_url}
npm config set -- ${local_npm_registry_url}:_authToken ${CERC_NPM_AUTH_TOKEN}
# First check if the version of this package we're trying to build already exists in the registry
package_exists=$( yarn info --json ${package_name}@${package_publish_version} | jq -r .data.dist.tarball )
package_exists=$( yarn info --json ${package_name}@${package_publish_version} 2>/dev/null | jq -r .data.dist.tarball )
if [[ ! -z "$package_exists" && "$package_exists" != "null" ]]; then
echo "${package_publish_version} of ${package_name} already exists in the registry, skipping build"
exit 0
@@ -14,14 +14,23 @@ if [[ $# -ne 2 ]]; then
echo "Illegal number of parameters" >&2
exit 1
fi
# Exit on error
set -e
target_package=$1
local_npm_registry_url=$2
# TODO: use jq rather than sed here:
versioned_target_package=$(grep ${target_package} package.json | sed -e 's#[[:space:]]\{1,\}\"\('${target_package}'\)\":[[:space:]]\{1,\}\"\(.*\)\",#\1@\2#' )
# Use yarn info to get URL checksums etc from the new registry
yarn_info_output=$(yarn info --json $versioned_target_package 2>/dev/null)
# Code below parses out the values we need
# First check if the target version actually exists.
# If it doesn't exist there will be no .data.dist.tarball element,
# and jq will output the string "null"
package_tarball=$(echo $yarn_info_output | jq -r .data.dist.tarball)
if [[ $package_tarball == "null" ]]; then
echo "FATAL: Target package version ($versioned_target_package) not found" >&2
exit 1
fi
# Code below parses out the values we need
# When running inside a container, the registry can return a URL with the wrong host name due to proxying
# so we need to check if that has happened and fix the URL if so.
if ! [[ "${package_tarball}" =~ ^${local_npm_registry_url}.* ]]; then
@@ -33,6 +42,7 @@ package_integrity=$(echo $yarn_info_output | jq -r .data.dist.integrity)
package_shasum=$(echo $yarn_info_output | jq -r .data.dist.shasum)
package_resolved=${package_tarball}#${package_shasum}
# Some strings need to be escaped so they work when passed to sed later
escaped_package_integrity=$(printf '%s\n' "$package_integrity" | sed -e 's/[\/&]/\\&/g')
escaped_package_resolved=$(printf '%s\n' "$package_resolved" | sed -e 's/[\/&]/\\&/g')
escaped_target_package=$(printf '%s\n' "$target_package" | sed -e 's/[\/&]/\\&/g')
if [ -n "$CERC_SCRIPT_VERBOSE" ]; then
@@ -44,4 +54,4 @@ fi
# Use magic sed regex to replace the values in yarn.lock
# Note: yarn.lock is not json so we can not use jq for this
sed -i -e '/^\"'${escaped_target_package}'.*\":$/ , /^\".*$/ s/^\([[:space:]]\{1,\}resolved \).*$/\1'\"${escaped_package_resolved}\"'/' yarn.lock
sed -i -e '/^\"'${escaped_target_package}'.*\":$/ , /^\".*$/ s/^\([[:space:]]\{1,\}integrity \).*$/\1'${package_integrity}'/' yarn.lock
sed -i -e '/^\"'${escaped_target_package}'.*\":$/ , /^\".*$/ s/^\([[:space:]]\{1,\}integrity \).*$/\1'${escaped_package_integrity}'/' yarn.lock
@@ -1,5 +1,6 @@
version: "1.0"
name: fixturenet-laconicd
description: "A laconicd fixturenet"
repos:
- cerc-io/laconicd
- cerc-io/laconic-sdk
+1 -1
View File
@@ -1,2 +1,2 @@
# This file should be re-generated running: scripts/update-version-file.sh script
v1.0.10-alpha-4e1366d
v1.0.11-alpha-edbf674
+5 -10
View File
@@ -1,4 +1,4 @@
# Copyright © 2022 Cerc
# Copyright © 2022, 2023 Cerc
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -22,8 +22,7 @@ from python_on_whales import DockerClient
import click
import importlib.resources
from pathlib import Path
import yaml
from .util import include_exclude_check
from .util import include_exclude_check, get_parsed_stack_config
@click.command()
@@ -62,13 +61,9 @@ def command(ctx, include, exclude, cluster, command, services):
pods_in_scope = []
if stack:
# In order to be compatible with Python 3.8 we need to use this hack to get the path:
# See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure
stack_file_path = Path(__file__).absolute().parent.joinpath("data", "stacks", stack, "stack.yml")
with stack_file_path:
stack_config = yaml.safe_load(open(stack_file_path, "r"))
# TODO: syntax check the input here
pods_in_scope = stack_config['pods']
stack_config = get_parsed_stack_config(stack)
# TODO: syntax check the input here
pods_in_scope = stack_config['pods']
else:
pods_in_scope = all_pods
+27 -1
View File
@@ -1,4 +1,4 @@
# Copyright © 2022 Cerc
# Copyright © 2022, 2023 Cerc
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -13,6 +13,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
import os.path
import sys
import yaml
from pathlib import Path
def include_exclude_check(s, include, exclude):
if include is None and exclude is None:
return True
@@ -22,3 +28,23 @@ def include_exclude_check(s, include, exclude):
if exclude is not None:
exclude_list = exclude.split(",")
return s not in exclude_list
def get_parsed_stack_config(stack):
# In order to be compatible with Python 3.8 we need to use this hack to get the path:
# See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure
stack_file_path = Path(__file__).absolute().parent.joinpath("data", "stacks", stack, "stack.yml")
try:
with stack_file_path:
stack_config = yaml.safe_load(open(stack_file_path, "r"))
return stack_config
except FileNotFoundError as error:
# We try here to generate a useful diagnostic error
# First check if the stack directory is present
stack_directory = stack_file_path.parent
if os.path.exists(stack_directory):
print(f"Error: stack.yml file is missing from stack: {stack}")
else:
print(f"Error: stack: {stack} does not exist")
print(f"Exiting, error: {error}")
sys.exit(1)
+5 -3
View File
@@ -27,13 +27,14 @@ CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
# TODO: this seems kind of weird and heavy on boilerplate -- check it is
# the best Python can do for us.
class Options(object):
def __init__(self, stack, quiet, verbose, dry_run, local_stack, debug):
def __init__(self, stack, quiet, verbose, dry_run, local_stack, debug, continue_on_error):
self.stack = stack
self.quiet = quiet
self.verbose = verbose
self.dry_run = dry_run
self.local_stack = local_stack
self.debug = debug
self.continue_on_error = continue_on_error
@click.group(context_settings=CONTEXT_SETTINGS)
@@ -43,11 +44,12 @@ class Options(object):
@click.option('--dry-run', is_flag=True, default=False)
@click.option('--local-stack', is_flag=True, default=False)
@click.option('--debug', is_flag=True, default=False)
@click.option('--continue-on-error', is_flag=True, default=False)
# See: https://click.palletsprojects.com/en/8.1.x/complex/#building-a-git-clone
@click.pass_context
def cli(ctx, stack, quiet, verbose, dry_run, local_stack, debug):
def cli(ctx, stack, quiet, verbose, dry_run, local_stack, debug, continue_on_error):
"""Laconic Stack Orchestrator"""
ctx.obj = Options(stack, quiet, verbose, dry_run, local_stack, debug)
ctx.obj = Options(stack, quiet, verbose, dry_run, local_stack, debug, continue_on_error)
cli.add_command(setup_repositories.command, "setup-repositories")