Skip to content

Commit

Permalink
[ci]: docker image validator (#4053)
Browse files Browse the repository at this point in the history
* [ci] #3889: add Compose validation scripts

Signed-off-by: 6r1d <[email protected]>

* Update .github/workflows/iroha2-no-incorrect-image.yml

Co-authored-by: 0x009922 <[email protected]>
Signed-off-by: Victor <[email protected]>

* Update .github/workflows/iroha2-no-incorrect-image.yml

Co-authored-by: 0x009922 <[email protected]>
Signed-off-by: Victor <[email protected]>
Signed-off-by: 6r1d <[email protected]>

* Update no-incorrect-image workflow

Signed-off-by: 6r1d <[email protected]>

* Update the Compose configurations

Signed-off-by: 6r1d <[email protected]>

---------

Signed-off-by: 6r1d <[email protected]>
Signed-off-by: Victor <[email protected]>
Co-authored-by: 0x009922 <[email protected]>
  • Loading branch information
6r1d and 0x009922 authored Jan 26, 2024
1 parent 260b648 commit 925b556
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 290 deletions.
130 changes: 130 additions & 0 deletions .github/scripts/ci_test/ci_image_scan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/env python

"""
CI script for locating the improperly configured images
in Docker's Compose files.
Scans a list of file masks/names and checks for allowed branches.
"""

from typing import List
import sys
from logging import getLogger, warning, error, info, INFO
from argparse import ArgumentParser, Namespace
from pathlib import Path
from yaml import safe_load
from yaml.error import YAMLError
from git_root import git_root

def parse_arguments() -> Namespace:
"""
Returns:
Namespace: An object containing two attributes:
- masks: A list of file masks and names provided as positional arguments.
- allow: A list of Docker images provided
to the 'allow' option, or [] if not provided.
"""
parser = ArgumentParser(description='Process some file names.')
parser.add_argument(
'--allow',
nargs='+',
help='one or more allowed image names',
default=[]
)
parser.add_argument(
'masks',
nargs='*',
help='list of file masks and exact names to be checked',
default=[]
)
return parser.parse_args()

def get_paths(file_masks: List[str], root: Path):
"""
Generate a list of pathlib.Path instances for given file masks
and filenames within a root directory.
This function searches for files in a specified root directory
matching the patterns and filenames provided in `file_masks`.
It returns a list of pathlib.Path instances for files that exist.
Patterns can include wildcards (e.g., "*.yml").
Only files that actually exist in the filesystem are included in the result.
Args:
file_masks (list of str): A list of strings representing file masks
and filenames.
File masks can include wildcard characters
(e.g., "topic.*.yml").
root (pathlib.Path):
A pathlib.Path instance representing
the root directory in which to search for files.
Returns:
list: A list containing pathlib.Path instances for each existing
file matching the file masks and filenames
in the specified root directory.
Raises:
TypeError: If `root` is not an instance of pathlib.Path.
Note:
The function does not return paths for files that do not exist.
"""
if not isinstance(root, Path):
raise TypeError("The root argument must be a pathlib.Path instance")
paths = []
for mask in file_masks:
if '*' in mask:
matching_files = root.glob(mask)
paths.extend([file for file in matching_files if file.exists()])
else:
path = root / mask
if path.exists():
paths.append(path)
else:
warning(f'File not found: {path.name}')
return paths

def validate_docker_config(compose_file: Path, allow: List[str]):
"""
Validates a single Path for a Compose config.
Returns:
(int) 1 if the image is using a config that isn't allowed,
0 otherwise
"""
status = 0
services = {}
try:
with open(compose_file, 'r', encoding='utf8') as compose_file_contents:
config_inst = safe_load(compose_file_contents.read())
if isinstance(config_inst, dict):
services = config_inst.get('services', {})
else:
error(f'Improper configuration at "{compose_file}"')
status = 1
except YAMLError:
error(f'Improper formatting at "{compose_file}"')
status = 1
for _, service in services.items():
if service.get('image', '') not in allow:
status = 1
break
return status

def main():
"""
Validate the supplied Docker configurations
and exit with an error if one of them is using
an incorrect image.
"""
getLogger().setLevel(INFO)
args = parse_arguments()
for current_file in get_paths(args.masks, git_root()):
if validate_docker_config(current_file, args.allow):
warning(f'Wrong image in "{current_file.name}"')
sys.exit(1)
info('No incorrect Compose configurations found')

if __name__ == '__main__':
main()
19 changes: 19 additions & 0 deletions .github/scripts/ci_test/git_root.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
This module contains a modified copy of git_root by Jan Tilly.
It allows to find a repo root on GitHub for the CI purposes.
https://github.com/jtilly/git_root/blob/master/git_root/git_root.py
"""

from subprocess import Popen, PIPE, DEVNULL
from os.path import abspath
from pathlib import Path

def git_root():
root = '.'
with Popen(
['git', 'rev-parse', '--show-toplevel'],
stdout=PIPE, stderr=DEVNULL
) as git_proc:
root = git_proc.communicate()[0].rstrip().decode('utf-8')
return Path(abspath(root))
1 change: 1 addition & 0 deletions .github/scripts/ci_test/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PyYAML==6.0.1
25 changes: 25 additions & 0 deletions .github/workflows/iroha2-no-incorrect-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: I2::CI::check_for_incorrect_images

on:
push:
branches:
- iroha2-dev
- iroha2-stable

jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Set up Python 3.11
uses: actions/setup-python@v1
with:
python-version: "3.11"
- uses: actions/checkout@v3
- name: Install dependencies
run: pip install -r .github/scripts/ci_test/requirements.txt --no-input
- name: Check containers on iroha2-stable branch
if: github.base_ref == 'iroha2-stable'
run: python .github/scripts/ci_test/ci_image_scan.py --allow iroha2:stable -- docker-compose*.yml
- name: Check containers on iroha2-dev branch
if: github.base_ref == 'iroha2-dev'
run: python .github/scripts/ci_test/ci_image_scan.py --allow iroha2:dev -- docker-compose*.yml
25 changes: 0 additions & 25 deletions docker-compose.dev.single.yml

This file was deleted.

80 changes: 0 additions & 80 deletions docker-compose.dev.yml

This file was deleted.

File renamed without changes.
33 changes: 16 additions & 17 deletions docker-compose.single.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
version: "3.8"
# This file is generated by iroha_swarm.
# Do not edit it manually.

version: '3.8'
services:
iroha0:
build: .
image: iroha2:lts
build: ./
platform: linux/amd64
environment:
IROHA_CHAIN_ID: 00000000-0000-0000-0000-000000000000
IROHA_CONFIG: /config/config.json
IROHA_PUBLIC_KEY: ed01208BA62848CF767D72E7F7F4B9D2D7BA07FEE33760F79ABE5597A51520E292A0CB
IROHA_PRIVATE_KEY: '{"digest_function":"ed25519","payload":"8f4c15e5d664da3f13778801d23d4e89b76e94c1b94b389544168b6cb894f84f8ba62848cf767d72e7f7f4b9d2d7ba07fee33760f79abe5597a51520e292a0cb"}'
TORII_P2P_ADDR: iroha0:1337
TORII_API_URL: iroha0:8080
TORII_TELEMETRY_URL: iroha0:8180
IROHA_PUBLIC_KEY: "ed01201C61FAF8FE94E253B93114240394F79A607B7FA55F9E5A41EBEC74B88055768B"
IROHA_PRIVATE_KEY: '{"digest_function": "ed25519", "payload": "282ED9F3CF92811C3818DBC4AE594ED59DC1A2F78E4241E31924E101D6B1FB831C61FAF8FE94E253B93114240394F79A607B7FA55F9E5A41EBEC74B88055768B"}'
SUMERAGI_TRUSTED_PEERS: '[{"address":"iroha0:1337", "public_key": "ed01201C61FAF8FE94E253B93114240394F79A607B7FA55F9E5A41EBEC74B88055768B"}]'
IROHA_GENESIS_ACCOUNT_PUBLIC_KEY: 'ed01203F4E3E98571B55514EDC5CCF7E53CA7509D89B2868E62921180A6F57C2F4E255'
IROHA_GENESIS_ACCOUNT_PRIVATE_KEY: '{"digest_function": "ed25519", "payload": "038AE16B219DA35AA036335ED0A43C28A2CC737150112C78A7B8034B9D99C9023F4E3E98571B55514EDC5CCF7E53CA7509D89B2868E62921180A6F57C2F4E255"}'
IROHA_GENESIS_WAIT_FOR_PEERS_RETRY_COUNT_LIMIT: 100
IROHA_GENESIS_WAIT_FOR_PEERS_RETRY_PERIOD_MS: 500
IROHA_GENESIS_GENESIS_SUBMISSION_DELAY_MS: 1000
IROHA_GENESIS_PUBLIC_KEY: ed01204164BF554923ECE1FD412D241036D863A6AE430476C898248B8237D77534CFC4
IROHA_GENESIS_PRIVATE_KEY: '{"digest_function":"ed25519","payload":"82b3bde54aebeca4146257da0de8d59d8e46d5fe34887dcd8072866792fcb3ad4164bf554923ece1fd412d241036d863a6ae430476c898248b8237d77534cfc4"}'
IROHA_GENESIS_FILE: /config/genesis.json
ports:
- "1337:1337"
- "8080:8080"
- "8180:8180"
- 1337:1337
- 8080:8080
volumes:
- ./configs/peer:/config
init: true
command: iroha --submit-genesis
volumes:
- './configs/peer/lts:/config'
24 changes: 0 additions & 24 deletions docker-compose.stable.single.yml

This file was deleted.

Loading

0 comments on commit 925b556

Please sign in to comment.