mirror of
https://github.com/ben-grande/qusal.git
synced 2025-05-29 03:01:15 -04:00
refactor: initial commit
This commit is contained in:
commit
f6ac229306
594 changed files with 18600 additions and 0 deletions
172
salt/sys-git/README.md
Normal file
172
salt/sys-git/README.md
Normal file
|
@ -0,0 +1,172 @@
|
|||
# sys-git
|
||||
|
||||
Git operations through Qrexec in Qubes OS.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Description](#description)
|
||||
* [Alternatives comparison](#alternatives-comparison)
|
||||
* [Installation](#installation)
|
||||
* [Access control](#access-control)
|
||||
* [Usage](#usage)
|
||||
* [Initialize the server repository](#initialize-the-server-repository)
|
||||
* [Prepare the client](#prepare-the-client)
|
||||
* [Credits](#credits)
|
||||
|
||||
## Description
|
||||
|
||||
Setup a Git server called "sys-git", an offline Git Server that can be
|
||||
accessed from client qubes via Qrexec. Access control via Qrexec policy can
|
||||
restrict access to certain repositories, set of git actions for Fetch, Push
|
||||
and Init. This is an implementation of split-git.
|
||||
|
||||
## Alternatives comparison
|
||||
|
||||
The following alternatives will be compared against each other and this
|
||||
implementation:
|
||||
|
||||
- [Rudd-O/git-remote-qubes](https://github.com/Rudd-O/git-remote-qubes)
|
||||
- [QubesOS-contrib/qubes-app-split-git](https://github.com/QubesOS-contrib/qubes-app-split-git)
|
||||
- [qubes-os.org/doc/development-workflow/#git-connection-between-vms](https://www.qubes-os.org/doc/development-workflow/#git-connection-between-vms)
|
||||
|
||||
| | sys-git | git-remote-qubes | qubes-app-split-git | git-connection-between-vms |
|
||||
| :--- | :---: | :---: | :---: | :---: |
|
||||
| Codebase Size | Small | Large | Large | Small |
|
||||
| Custom Protocol | True | True | True | False |
|
||||
| Path | Repository | Absolute | Repository | Repository |
|
||||
| Repository restriction | True | False | True | True |
|
||||
| No hanging | True | True | True | False |
|
||||
| Fetch | True | True | True (only tags) | True |
|
||||
| Push | True | True | False | True |
|
||||
| Init | True | False | False | False |
|
||||
| Validates Git communication | False | False | True | False |
|
||||
| Verifies tag signature | False | False | True | False |
|
||||
|
||||
## Installation
|
||||
|
||||
- Top
|
||||
```sh
|
||||
qubesctl top.enable sys-git
|
||||
qubesctl --targets=tpl-sys-git,sys-git state.apply
|
||||
qubesctl top.disable sys-git
|
||||
```
|
||||
|
||||
- State
|
||||
<!-- pkg:begin:post-install -->
|
||||
```sh
|
||||
qubesctl state.apply sys-git.create
|
||||
qubesctl --skip-dom0 --targets=tpl-sys-git state.apply sys-git.install
|
||||
qubesctl --skip-dom0 --targets=sys-git state.apply sys-git.configure
|
||||
```
|
||||
<!-- pkg:end:post-install -->
|
||||
|
||||
Installation on the client template:
|
||||
```sh
|
||||
qubesctl --skip-dom0 --targets=tpl-dev state.apply sys-git.install-client
|
||||
```
|
||||
|
||||
## Access control
|
||||
|
||||
_Default policy_: `any qube` can `ask` via the `@default` target if you allow
|
||||
it to `Fetch` from, `Push` to and `Init` on `sys-git`.
|
||||
|
||||
__Recommended usage__:
|
||||
|
||||
- __Init__: Argument useful when allowing a qube to always create a
|
||||
repository on the server.
|
||||
- __Fetch__: Fetch can be allowed by less trusted qubes.
|
||||
- __Push__: Push should only be made by trusted qubes.
|
||||
|
||||
Allow qube `dev` to `Fetch` from `sys-git`, but ask to `Push` and `Init`:
|
||||
```qrexecpolicy
|
||||
qusal.GitFetch * dev @default allow target=sys-git
|
||||
qusal.GitPush * dev @default ask target=sys-git default_target=sys-git
|
||||
qusal.GitInit * dev @default ask target=sys-git default_target=sys-git
|
||||
qusal.GitFetch * dev @anyvm deny
|
||||
qusal.GitPush * dev @anyvm deny
|
||||
qusal.GitInit * dev @anyvm deny
|
||||
```
|
||||
|
||||
Allow qube `untrusted` to `Fetch` `repo` if using target name `sys-git` but
|
||||
deny `Push` and `Init` to any other qube:
|
||||
```qrexecpolicy
|
||||
qusal.GitFetch +repo untrusted sys-git ask target=sys-git default_target=sys-git
|
||||
qusal.GitFetch * untrusted @anyvm deny
|
||||
qusal.GitPush * untrusted @anyvm deny
|
||||
qusal.GitInit * untrusted @anyvm deny
|
||||
```
|
||||
|
||||
Deny `Fetch`, `Push` and `Init` from any qube to any other qube:
|
||||
```qrexecpolicy
|
||||
qusal.GitFetch * @anyvm @anyvm deny
|
||||
qusal.GitPush * @anyvm @anyvm deny
|
||||
qusal.GitInit * @anyvm @anyvm deny
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Initialize the server repository
|
||||
|
||||
There are a few constraints regarding repositories:
|
||||
|
||||
- Must be created under `/home/user/src` in `sys-git`;
|
||||
- Names must have only letters, numbers, hyphen, underscore and dot. Must not
|
||||
begin or end with dot, hyphen and underscore.
|
||||
|
||||
In `sys-git`, create bare repositories under `/home/user/src`.
|
||||
|
||||
From the `server`:
|
||||
```sh
|
||||
git init --bare ~/src/X.git
|
||||
```
|
||||
You must use the `.git` prefix to indicate a bare repository.
|
||||
|
||||
Or from the `client`, if the `qusal.GitInit` policy allows:
|
||||
```sh
|
||||
cd ~/path/to/repo
|
||||
git init-qrexec
|
||||
```
|
||||
|
||||
### Prepare the client
|
||||
|
||||
Qrexec protocol is supported with the following URL format:
|
||||
`qrexec://<QUBE>/<REPO>`, where the `<QUBE>` field can be a literal name or
|
||||
token and the `<REPO>` field is the name of the repository that exists on
|
||||
`sys-git` under `/home/user/src`.
|
||||
|
||||
Clone an existing repository:
|
||||
```sh
|
||||
git clone qrexec://@default/qubes-doc
|
||||
```
|
||||
|
||||
Or Initialize a new repository:
|
||||
```sh
|
||||
git init qubes-doc
|
||||
cd qubes-doc
|
||||
```
|
||||
|
||||
Add a remote using the Qrexec protocol:
|
||||
```sh
|
||||
git remote add sg qrexec://@default/qubes-doc
|
||||
```
|
||||
|
||||
Test fetching from the newly added remote:
|
||||
```sh
|
||||
git fetch sg
|
||||
```
|
||||
|
||||
Make changes to the git repository as you normally would on any system.
|
||||
|
||||
Push to the server and set it as the default upstream:
|
||||
```sh
|
||||
git push -u sg main
|
||||
```
|
||||
|
||||
Following pushes will be simpler:
|
||||
```sh
|
||||
git push
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
- [Unman](https://github.com/unman/shaker/tree/main/git)
|
8
salt/sys-git/clone.sls
Normal file
8
salt/sys-git/clone.sls
Normal file
|
@ -0,0 +1,8 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
{% from 'utils/macros/clone-template.sls' import clone_template -%}
|
||||
{{ clone_template('debian-minimal', sls_path) }}
|
10
salt/sys-git/clone.top
Normal file
10
salt/sys-git/clone.top
Normal file
|
@ -0,0 +1,10 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
base:
|
||||
'dom0':
|
||||
- match: nodegroup
|
||||
- sys-git.clone
|
13
salt/sys-git/configure.sls
Normal file
13
salt/sys-git/configure.sls
Normal file
|
@ -0,0 +1,13 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
{% if grains['nodename'] != 'dom0' -%}
|
||||
|
||||
include:
|
||||
- dev.home-cleanup
|
||||
- dotfiles.copy-git
|
||||
|
||||
{% endif -%}
|
9
salt/sys-git/configure.top
Normal file
9
salt/sys-git/configure.top
Normal file
|
@ -0,0 +1,9 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
base:
|
||||
'sys-git':
|
||||
- sys-git.configure
|
46
salt/sys-git/create.sls
Normal file
46
salt/sys-git/create.sls
Normal file
|
@ -0,0 +1,46 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
{%- from "qvm/template.jinja" import load -%}
|
||||
|
||||
include:
|
||||
- .clone
|
||||
|
||||
{% load_yaml as defaults -%}
|
||||
name: {{ slsdotpath }}
|
||||
force: True
|
||||
require:
|
||||
- sls: {{ slsdotpath }}.clone
|
||||
present:
|
||||
- template: tpl-{{ slsdotpath }}
|
||||
- label: gray
|
||||
prefs:
|
||||
- template: tpl-{{ slsdotpath }}
|
||||
- label: gray
|
||||
- netvm: ""
|
||||
- vcpus: 1
|
||||
- memory: 200
|
||||
- maxmem: 300
|
||||
features:
|
||||
- enable:
|
||||
- servicevm
|
||||
- disable:
|
||||
- service.cups
|
||||
- service.cups-browsed
|
||||
# tags:
|
||||
# - add:
|
||||
# - split-gpg2-client
|
||||
{%- endload %}
|
||||
{{ load(defaults) }}
|
||||
|
||||
"{{ slsdotpath }}-resize-private-volume":
|
||||
cmd.run:
|
||||
- name: qvm-volume resize {{ slsdotpath }}:private 20Gi
|
||||
- require:
|
||||
- qvm: {{ slsdotpath }}
|
||||
|
||||
{% from 'utils/macros/policy.sls' import policy_set with context -%}
|
||||
{{ policy_set(sls_path, '80') }}
|
10
salt/sys-git/create.top
Normal file
10
salt/sys-git/create.top
Normal file
|
@ -0,0 +1,10 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
base:
|
||||
'dom0':
|
||||
- match: nodegroup
|
||||
- sys-git.create
|
13
salt/sys-git/files/admin/policy/default.policy
Normal file
13
salt/sys-git/files/admin/policy/default.policy
Normal file
|
@ -0,0 +1,13 @@
|
|||
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
## Do not modify this file, create a new policy with with a lower number in the
|
||||
## file name instead. For example `30-user.policy`.
|
||||
qusal.GitFetch * @anyvm @default ask target={{ sls_path }} default_target={{ sls_path }}
|
||||
qusal.GitPush * @anyvm @default ask target={{ sls_path }} default_target={{ sls_path }}
|
||||
qusal.GitInit * @anyvm @default ask target={{ sls_path }} default_target={{ sls_path }}
|
||||
qusal.GitFetch * @anyvm @anyvm deny
|
||||
qusal.GitPush * @anyvm @anyvm deny
|
||||
qusal.GitInit * @anyvm @anyvm deny
|
||||
## vim:ft=qrexecpolicy
|
53
salt/sys-git/files/client/git-core/git-init-qrexec
Executable file
53
salt/sys-git/files/client/git-core/git-init-qrexec
Executable file
|
@ -0,0 +1,53 @@
|
|||
#!/bin/sh
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
set -eu
|
||||
|
||||
usage(){
|
||||
echo "Usage: ${helper} [<qube>] [<repository>]"
|
||||
echo "Note: qube defaults to '@default' and repository to the current repository"
|
||||
exit 1
|
||||
}
|
||||
|
||||
is_git_repo(){
|
||||
if ! git rev-parse --show-toplevel >/dev/null 2>&1; then
|
||||
echo "Error: Either run from inside a git repository or provide it as an argument" >&2
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
helper="${0##*/git-}"
|
||||
case "${1-}" in
|
||||
-h|--?help) usage;;
|
||||
"") qube="@default";;
|
||||
*) qube="${1}";;
|
||||
esac
|
||||
case "${2-}" in
|
||||
"") is_git_repo; repo="$(basename "$(git rev-parse --show-toplevel)")";;
|
||||
*) repo="${2}";;
|
||||
esac
|
||||
|
||||
rpc="GitInit"
|
||||
vendor="qusal"
|
||||
default_qube="sys-git"
|
||||
rpc_cmd="${vendor}.${rpc}+${repo}"
|
||||
|
||||
if command -v qrexec-client-vm >/dev/null; then
|
||||
exec qrexec-client-vm -- "${qube}" "${rpc_cmd}"
|
||||
elif command -v qrexec-client >/dev/null; then
|
||||
qubes_version="$(awk -F '=' '/^VERSION_ID=/{print $2}' /etc/os-release)"
|
||||
if test "$(echo "${qubes_version}" | tr -d ".")" -le 41; then
|
||||
if test "${qube}" = "@default"; then
|
||||
qube="${default_qube}"
|
||||
fi
|
||||
else
|
||||
policy="$(qrexec-policy --assume-yes-for-ask dom0 "${qube}" "${rpc_cmd}")"
|
||||
qube="$(echo "${policy}" | awk -F '=' '/^target=/{print $2}')"
|
||||
fi
|
||||
exec qrexec-client -d "${qube}" -- "DEFAULT:QUBESRPC ${rpc_cmd} dom0"
|
||||
else
|
||||
die "Qrexec programs not found: qrexec-client-vm, qrexec-client"
|
||||
fi
|
107
salt/sys-git/files/client/git-core/git-remote-qrexec
Executable file
107
salt/sys-git/files/client/git-core/git-remote-qrexec
Executable file
|
@ -0,0 +1,107 @@
|
|||
#!/bin/sh
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
## Portable git-remote-helper.
|
||||
## Rename this helper to git-remote-<scheme>.
|
||||
## Valid URL format: <scheme>://<authority>/<path>.
|
||||
## Supported commands: capabilities, connect.
|
||||
## Capabilities commands are sent to git-remote-<scheme>-<capability>.
|
||||
set -eu
|
||||
|
||||
usage(){
|
||||
echo "Usage: ${helper} <remote> [${scheme}://<authority>/<path>]" >&2
|
||||
}
|
||||
|
||||
die(){
|
||||
usage
|
||||
echo "Error: ${1}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
## Validate URL and return it without the scheme.
|
||||
validate_url(){
|
||||
url_valid=""
|
||||
url_check="${1?}"
|
||||
scheme_user_url="$(echo "${url_check}" | sed "s|://.*||")"
|
||||
|
||||
## Scheme must be the same as the one in the name of this script.
|
||||
## Checks if Authority and Path exist, but not if they are valid, this is
|
||||
## implementation specific and should be checked by the connect helper.
|
||||
case "${url_check}" in
|
||||
"${scheme}"://*?/*?) url_valid="$(echo "${url_check}" | sed "s|.*://||")";;
|
||||
"${scheme}"://*?) die "URL has no path to resource: '${url_check}'";;
|
||||
"${scheme}"://) die "URL has no authority: '${url_check}'";;
|
||||
*?://*) die "URL has unsupported scheme: '${scheme_user_url}'";;
|
||||
*) die "URL has no scheme: '${url_check}'";;
|
||||
esac
|
||||
|
||||
echo "${url_valid}"
|
||||
}
|
||||
|
||||
## Send capabilities to remote helper specific for that capability.
|
||||
send_cap(){
|
||||
exec_path="$(git --exec-path)"
|
||||
test -n "${exec_path}" || die "Couldn't locate Git's executables path"
|
||||
|
||||
cap="${1}"
|
||||
shift
|
||||
cap_file="${script}-${cap}"
|
||||
cap_path="${exec_path}/${cap_file}"
|
||||
|
||||
test -e "${cap_path}" || die "Git's exec path missing: '${cap_file}'"
|
||||
test -x "${cap_path}" || die "Git script is not executable: '${cap_file}'"
|
||||
|
||||
"${cap_path}" "${@}"
|
||||
}
|
||||
|
||||
## Basic requirements.
|
||||
command -v git >/dev/null || die "Command not found: 'git'"
|
||||
script="${0##*/}"
|
||||
helper="${script##git-}"
|
||||
scheme="${helper##remote-}"
|
||||
if test "${script}" != "git-remote-${scheme}" || test -z "${scheme}"; then
|
||||
die "Script must be named with the format: git-remote-<scheme>"
|
||||
fi
|
||||
|
||||
## Get remote name or show usage.
|
||||
case "${1-}" in
|
||||
-h|--?help|"") usage; exit 1;;
|
||||
*) remote="${1}";;
|
||||
esac
|
||||
|
||||
## Get URL and Push URL (fallback to URL)
|
||||
case "${2-}" in
|
||||
"")
|
||||
## Happens when 'remote-qrexec' is called directly from the command-line.
|
||||
url="$(git remote get-url "${remote}" || true)"
|
||||
pushurl="$(git remote get-url --push "${remote}" || true)"
|
||||
;;
|
||||
*) url="${2}"; pushurl="${2}";;
|
||||
esac
|
||||
|
||||
test -n "${url}" || die "Remote URL is unset"
|
||||
test -n "${pushurl}" || die "Remote Push URL is unset"
|
||||
|
||||
url="$(validate_url "${url}")"
|
||||
pushurl="$(validate_url "${pushurl}")"
|
||||
|
||||
## Communicate with the git-remote-helpers protocol.
|
||||
while read -r cmd arg; do
|
||||
case "${cmd}" in
|
||||
"") exit 0;;
|
||||
"capabilities") printf "connect\n\n";;
|
||||
"connect")
|
||||
printf "\n";
|
||||
case "${arg}" in
|
||||
git-upload-pack) send_cap "${cmd}" "${arg}" "${url}";;
|
||||
git-receive-pack) send_cap "${cmd}" "${arg}" "${pushurl}";;
|
||||
"") die "Argument can't be empty";;
|
||||
*) die "Unsupported argument: '${arg}'";;
|
||||
esac
|
||||
;;
|
||||
*) die "Unsupported command: '${cmd}'";;
|
||||
esac
|
||||
done
|
62
salt/sys-git/files/client/git-core/git-remote-qrexec-connect
Executable file
62
salt/sys-git/files/client/git-core/git-remote-qrexec-connect
Executable file
|
@ -0,0 +1,62 @@
|
|||
#!/bin/sh
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
## Should be called by git-remote-qrexec.
|
||||
set -eu
|
||||
|
||||
usage(){
|
||||
echo "Usage: ${helper} git-upload-pack|git-receive-pack <qube>/<path>"
|
||||
echo "Note: ${helper} is supposed to be called by ${parent_helper}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
die(){
|
||||
echo "Error: ${1}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
helper="${0##*/git-}"
|
||||
parent_helper="${helper%-*}"
|
||||
|
||||
case "${1-}" in
|
||||
-h|--?help|"") usage;;
|
||||
*) arg="${1}";;
|
||||
esac
|
||||
case "${2-}" in
|
||||
"") usage;;
|
||||
*) url="${2}";;
|
||||
esac
|
||||
|
||||
case "${arg}" in
|
||||
git-upload-pack) rpc=GitFetch;;
|
||||
git-receive-pack) rpc=GitPush;;
|
||||
"") die "Argument can't be empty";;
|
||||
*) die "Unsupported argument: '${arg}'";;
|
||||
esac
|
||||
|
||||
qube="$(echo "${url}" | cut -d "/" -f1)"
|
||||
repo="$(echo "${url}" | cut -d "/" -f2-)"
|
||||
test -n "${repo}" || die "Repository name can't be empty"
|
||||
vendor="qusal"
|
||||
default_qube="sys-git"
|
||||
rpc_cmd="${vendor}.${rpc}+${repo}"
|
||||
|
||||
if command -v qrexec-client-vm >/dev/null; then
|
||||
exec qrexec-client-vm -- "${qube}" "${rpc_cmd}"
|
||||
elif command -v qrexec-client >/dev/null; then
|
||||
qubes_version="$(awk -F '=' '/^VERSION_ID=/{print $2}' /etc/os-release)"
|
||||
if test "$(echo "${qubes_version}" | tr -d ".")" -le 41; then
|
||||
if test "${qube}" = "@default"; then
|
||||
qube="${default_qube}"
|
||||
fi
|
||||
else
|
||||
policy="$(qrexec-policy --assume-yes-for-ask dom0 "${qube}" "${rpc_cmd}")"
|
||||
qube="$(echo "${policy}" | awk -F '=' '/^target=/{print $2}')"
|
||||
fi
|
||||
exec qrexec-client -d "${qube}" -- "DEFAULT:QUBESRPC ${rpc_cmd} dom0"
|
||||
else
|
||||
die "Qrexec programs not found: qrexec-client-vm, qrexec-client"
|
||||
fi
|
1
salt/sys-git/files/server/rpc/qusal.GitFetch
Symbolic link
1
salt/sys-git/files/server/rpc/qusal.GitFetch
Symbolic link
|
@ -0,0 +1 @@
|
|||
qusal.GitInit
|
58
salt/sys-git/files/server/rpc/qusal.GitInit
Normal file
58
salt/sys-git/files/server/rpc/qusal.GitInit
Normal file
|
@ -0,0 +1,58 @@
|
|||
#!/bin/sh
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
set -eu
|
||||
|
||||
base_path="$HOME/src"
|
||||
repo="$QREXEC_SERVICE_ARGUMENT"
|
||||
#origin="$QREXEC_REMOTE_DOMAIN"
|
||||
|
||||
die(){
|
||||
echo "error: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
fail_invalid_name(){
|
||||
if ! (echo "$repo" | grep -q "^[A-Za-z0-9][A-Za-z0-9_.-]\+$"); then
|
||||
die "Invalid repository. Allowed chars: letters, numbers, hyphen, underscore and dot. It cannot begin with hyphen, underscore or dot."
|
||||
fi
|
||||
}
|
||||
|
||||
if ! command -v git >/dev/null; then
|
||||
die "Command not found: git"
|
||||
fi
|
||||
|
||||
fail_invalid_name
|
||||
case "$repo" in
|
||||
*".git") ;;
|
||||
*) repo="$repo.git";;
|
||||
esac
|
||||
|
||||
path="$base_path/$repo"
|
||||
action="${0##*.Git}"
|
||||
|
||||
case "$action" in
|
||||
Fetch) service=git-upload-pack;;
|
||||
Push) service=git-receive-pack;;
|
||||
Init) service="git init --bare";;
|
||||
*) die "Invalid RPC name: ${0##*/}";;
|
||||
esac
|
||||
|
||||
if test "$action" != "Init"; then
|
||||
test -d "$path" || die "Directory doesn't exist: $repo"
|
||||
git -C "$path" rev-parse >/dev/null 2>&1 || die "Not a git repository: $repo"
|
||||
is_bare="$(git -C "$path" rev-parse --is-bare-repository)"
|
||||
test "${is_bare}" = "true" || die "Not a bare repository: $repo"
|
||||
fi
|
||||
|
||||
if ! test -d "$base_path"; then
|
||||
# shellcheck disable=SC2174
|
||||
mkdir -m 0700 -p "$base_path" >/dev/null 2>&1 ||
|
||||
die "Cannot create directory: $base_path"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
exec $service -- "$path"
|
1
salt/sys-git/files/server/rpc/qusal.GitPush
Symbolic link
1
salt/sys-git/files/server/rpc/qusal.GitPush
Symbolic link
|
@ -0,0 +1 @@
|
|||
qusal.GitInit
|
14
salt/sys-git/init.top
Normal file
14
salt/sys-git/init.top
Normal file
|
@ -0,0 +1,14 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
base:
|
||||
'dom0':
|
||||
- match: nodegroup
|
||||
- sys-git.create
|
||||
'tpl-sys-git':
|
||||
- sys-git.install
|
||||
'sys-git':
|
||||
- sys-git.configure
|
48
salt/sys-git/install-client.sls
Normal file
48
salt/sys-git/install-client.sls
Normal file
|
@ -0,0 +1,48 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
include:
|
||||
- dotfiles.copy-git
|
||||
- dotfiles.copy-sh
|
||||
- dotfiles.copy-x11
|
||||
- sys-pgp.install-client
|
||||
|
||||
"{{ slsdotpath }}-updated":
|
||||
pkg.uptodate:
|
||||
- refresh: True
|
||||
|
||||
"{{ slsdotpath }}-installed":
|
||||
pkg.installed:
|
||||
- refresh: True
|
||||
- install_recommends: False
|
||||
- skip_suggestions: True
|
||||
- pkgs:
|
||||
- git
|
||||
|
||||
{% set git = {
|
||||
'Debian': {
|
||||
'exec_path': '/usr/lib/git-core',
|
||||
},
|
||||
'RedHat': {
|
||||
'exec_path': '/usr/libexec/git-core',
|
||||
},
|
||||
}.get(grains.os_family) -%}
|
||||
|
||||
"{{ slsdotpath }}-install-client-git-core-dir":
|
||||
file.recurse:
|
||||
- require:
|
||||
- pkg: {{ slsdotpath }}-installed
|
||||
- source: salt://{{ slsdotpath }}/files/client/git-core
|
||||
- name: {{ git.exec_path }}
|
||||
- file_mode: '0755'
|
||||
- dir_mode: '0755'
|
||||
- user: root
|
||||
- group: root
|
||||
- makedirs: True
|
||||
- recurse:
|
||||
- mode
|
||||
- user
|
||||
- group
|
9
salt/sys-git/install-client.top
Normal file
9
salt/sys-git/install-client.top
Normal file
|
@ -0,0 +1,9 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
base:
|
||||
'*':
|
||||
- sys-git.install-client
|
46
salt/sys-git/install.sls
Normal file
46
salt/sys-git/install.sls
Normal file
|
@ -0,0 +1,46 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
{% if grains['nodename'] != 'dom0' -%}
|
||||
|
||||
include:
|
||||
- dotfiles.copy-git
|
||||
- dotfiles.copy-sh
|
||||
- dotfiles.copy-x11
|
||||
- sys-pgp.install-client
|
||||
|
||||
"{{ slsdotpath }}-updated":
|
||||
pkg.uptodate:
|
||||
- refresh: True
|
||||
|
||||
"{{ slsdotpath }}-installed":
|
||||
pkg.installed:
|
||||
- refresh: True
|
||||
- install_recommends: False
|
||||
- skip_suggestions: True
|
||||
- pkgs:
|
||||
- git
|
||||
|
||||
"{{ slsdotpath }}-rpc":
|
||||
file.recurse:
|
||||
- name: /etc/qubes-rpc/
|
||||
- source: salt://{{ slsdotpath }}/files/server/rpc
|
||||
- user: root
|
||||
- group: root
|
||||
- file_mode: '0755'
|
||||
- dir_mode: '0755'
|
||||
- keep_symlinks: True
|
||||
- force_symlinks: True
|
||||
|
||||
"{{ slsdotpath }}-skel-repository-directory":
|
||||
file.directory:
|
||||
- name: /etc/skel/src
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: '0755'
|
||||
- makedirs: True
|
||||
|
||||
{% endif -%}
|
9
salt/sys-git/install.top
Normal file
9
salt/sys-git/install.top
Normal file
|
@ -0,0 +1,9 @@
|
|||
{#
|
||||
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
base:
|
||||
'tpl-sys-git':
|
||||
- sys-git.install
|
Loading…
Add table
Add a link
Reference in a new issue