Add support for SSH deploy key cloning
This commit is contained in:
parent
54d5837515
commit
d366f08a3f
10
README.md
10
README.md
|
@ -117,3 +117,13 @@ You can extrapolate from here how to leverage Basic Builder to perform other tas
|
||||||
**NOTE:** The commands specified in `.bbuilder-tasks.yaml` are always run relative to the root of the repository on the relevant `ref`, either a branch for `push` events, or a tag for `create` or `release` events.
|
**NOTE:** The commands specified in `.bbuilder-tasks.yaml` are always run relative to the root of the repository on the relevant `ref`, either a branch for `push` events, or a tag for `create` or `release` events.
|
||||||
|
|
||||||
**NOTE:** The commands specified in `.bbuilder-tasks.yaml` are run with the privileges of the `bbuilder worker` process. Normally, this should not be `root`, but if it does need to be, **be very careful and remember that Basic Builder is implicitly trusting the content of this configuration in all repositories it is configured for**.
|
**NOTE:** The commands specified in `.bbuilder-tasks.yaml` are run with the privileges of the `bbuilder worker` process. Normally, this should not be `root`, but if it does need to be, **be very careful and remember that Basic Builder is implicitly trusting the content of this configuration in all repositories it is configured for**.
|
||||||
|
|
||||||
|
## Cloning Repositories
|
||||||
|
|
||||||
|
The Basic Builder worker will, by default, attempt to clone repositories via HTTP(S). This may cause problems if the repository is private however. To work around this, Basic Builder supports de;poy keys, i.e. dedicated SSH keypairs that the system can use to clone a repository over SSH instead of HTTP(S).
|
||||||
|
|
||||||
|
To activate this functionality, you can use the `-k`/`--ssh-key` option to the `bbuilder worker` command or the `BB_SSH_KEY` environment variable to set a path to an SSH private key which will be used.
|
||||||
|
|
||||||
|
This key should be kept secure and only readable by the Basic Builder user.
|
||||||
|
|
||||||
|
On the repository side, the key should be added as a deploy key (e.g. in Gitea, under the repository `Settings` -> `Deploy Keys`) for the specific repositories that require it.
|
||||||
|
|
|
@ -32,10 +32,21 @@ def print_version(ctx, param, value):
|
||||||
default=1, show_default=True,
|
default=1, show_default=True,
|
||||||
help='The concurrency of the Celery worker. Envvar: BB_CONCURRENCY'
|
help='The concurrency of the Celery worker. Envvar: BB_CONCURRENCY'
|
||||||
)
|
)
|
||||||
def cli_worker(concurrency):
|
@click.option(
|
||||||
|
'-k', '--ssh-key', 'ssh_key', envvar='BB_SSH_KEY',
|
||||||
|
default=None,
|
||||||
|
help='An SSH private key (deploy key) to clone repositories. Envvar: BB_SSH_KEY'
|
||||||
|
)
|
||||||
|
def cli_worker(concurrency, ssh_key):
|
||||||
"""
|
"""
|
||||||
Run a Basic Builder worker
|
Run a Basic Builder worker
|
||||||
|
|
||||||
|
Note: If '-s'/'--ssh-key'/'BB_SSH_KEY' is not specified, Basic Builder will attempt to clone repositories over HTTP(S) instead. They must be publicly accessible without anthentication in this case.
|
||||||
"""
|
"""
|
||||||
|
if ssh_key == '':
|
||||||
|
ssh_key = None
|
||||||
|
config['ssh_key'] = ssh_key
|
||||||
|
|
||||||
celery = Celery('bbuilder', broker=config['broker'])
|
celery = Celery('bbuilder', broker=config['broker'])
|
||||||
|
|
||||||
@celery.task(bind=True)
|
@celery.task(bind=True)
|
||||||
|
|
|
@ -32,7 +32,7 @@ def create_workdir(config, task_id):
|
||||||
rmtree(workdir)
|
rmtree(workdir)
|
||||||
|
|
||||||
|
|
||||||
def handle_event_gitea(request):
|
def handle_event_gitea(request, config):
|
||||||
event = request[0].get('X-Gitea-Event', None)
|
event = request[0].get('X-Gitea-Event', None)
|
||||||
if event is None:
|
if event is None:
|
||||||
meta = f'FATAL: No X-Gitea-Event header in request'
|
meta = f'FATAL: No X-Gitea-Event header in request'
|
||||||
|
@ -47,6 +47,9 @@ def handle_event_gitea(request):
|
||||||
if repository is None:
|
if repository is None:
|
||||||
meta = f'FATAL: No repository information in request JSON body'
|
meta = f'FATAL: No repository information in request JSON body'
|
||||||
raise TaskFailure(meta)
|
raise TaskFailure(meta)
|
||||||
|
if config['ssh_key'] is not None:
|
||||||
|
clone_url = repository.get('ssh_url')
|
||||||
|
else:
|
||||||
clone_url = repository.get('clone_url')
|
clone_url = repository.get('clone_url')
|
||||||
|
|
||||||
# Get the event action (only relevant to Release events)
|
# Get the event action (only relevant to Release events)
|
||||||
|
@ -92,8 +95,12 @@ def handle_event_gitea(request):
|
||||||
return event, event_action, clone_url, ref
|
return event, event_action, clone_url, ref
|
||||||
|
|
||||||
|
|
||||||
def clone_repository(clone_url):
|
def clone_repository(clone_url, config):
|
||||||
print(f"Cloning repository...")
|
print(f"Cloning repository...")
|
||||||
|
if config['ssh_key'] is not None:
|
||||||
|
ssh_key_file = config['ssh_key']
|
||||||
|
os.environ['GIT_SSH_COMMAND='] = f'ssh -i {ssh_key_file} -o IdentitiesOnly=yes'
|
||||||
|
|
||||||
os.system(f'git clone {clone_url} repo')
|
os.system(f'git clone {clone_url} repo')
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,7 +145,7 @@ def do_task(self, config, hooktype, request):
|
||||||
meta = f'FATAL: Hook type "{hooktype}" is not valid.'
|
meta = f'FATAL: Hook type "{hooktype}" is not valid.'
|
||||||
raise TaskFailure(meta)
|
raise TaskFailure(meta)
|
||||||
|
|
||||||
event, event_action, clone_url, ref = hooktype_dict.get(hooktype)(request)
|
event, event_action, clone_url, ref = hooktype_dict.get(hooktype)(request, config)
|
||||||
|
|
||||||
print(f"Event type: {event}")
|
print(f"Event type: {event}")
|
||||||
print(f"Clone URL: {clone_url}")
|
print(f"Clone URL: {clone_url}")
|
||||||
|
|
|
@ -6,3 +6,4 @@ BB_LISTEN_ADDR="0.0.0.0"
|
||||||
BB_LISTEN_PORT="7999"
|
BB_LISTEN_PORT="7999"
|
||||||
BB_AUTH_KEY="I'mALittleTeapot"
|
BB_AUTH_KEY="I'mALittleTeapot"
|
||||||
BB_CONCURRENCY=1
|
BB_CONCURRENCY=1
|
||||||
|
BB_SSH_KEY="/path/to/deploy/id_ed25519"
|
||||||
|
|
Loading…
Reference in New Issue