diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index c1ac72c4b1..a1dc5f960a 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -143,4 +143,4 @@ jobs:
- name: "Run tests"
run: |
cd behave
- behave -Dosc=../osc-wrapper.py -Dmax_podman_containers=2
+ behave -Dosc=../osc-wrapper.py -Dpodman_max_containers=2
diff --git a/behave/Containerfile b/behave/Containerfile
index c30263d5d6..3c1dffe2a9 100644
--- a/behave/Containerfile
+++ b/behave/Containerfile
@@ -1,13 +1,18 @@
FROM opensuse/leap:15.6
-RUN zypper ar --repo http://download.opensuse.org/repositories/OBS:/Server:/Unstable/15.6/OBS:Server:Unstable.repo
-RUN zypper -n --gpg-auto-import-keys refresh
+RUN zypper -n modifyrepo --disable repo-openh264 || : \
+ && zypper ar --repo http://download.opensuse.org/repositories/OBS:/Server:/Unstable/15.6/OBS:Server:Unstable.repo \
+ && zypper ar --repo http://download.opensuse.org/repositories/devel:/tools:/scm/15.6/devel:tools:scm.repo \
+ && zypper -n --gpg-auto-import-keys refresh
+
RUN zypper -n install \
bash \
bash-completion \
git \
+ gitea \
less \
obs-api \
+ obs-gitea-bridge \
obs-server \
obs-signd \
obs-worker \
@@ -16,6 +21,7 @@ RUN zypper -n install \
openssl \
perl-XML-SAX \
rpm-build \
+ sqlite3 \
systemd \
vim \
&& rm -rf /var/cache/zypp/*
@@ -25,6 +31,7 @@ COPY container-files/ /
RUN /bin/bash /opt/setup/setup.sh \
&& /bin/bash /opt/setup/initial-data.sh \
&& /bin/bash /opt/setup/prebuilt-rpms.sh \
+ && /bin/bash /opt/setup/gitea.sh \
&& rm -rf /var/log/apache2/* \
&& rm -rf /srv/obs/log/* \
&& rm -rf /srv/obs/service/log/* \
diff --git a/behave/container-files/etc/gitea/conf/app.ini b/behave/container-files/etc/gitea/conf/app.ini
new file mode 100644
index 0000000000..642137c383
--- /dev/null
+++ b/behave/container-files/etc/gitea/conf/app.ini
@@ -0,0 +1,36 @@
+WORK_PATH = /var/lib/gitea
+
+[server]
+CERT_FILE = /etc/gitea/https/cert.pem
+KEY_FILE = /etc/gitea/https/key.pem
+STATIC_ROOT_PATH = /usr/share/gitea
+APP_DATA_PATH = /var/lib/gitea/data
+PPROF_DATA_PATH = /var/lib/gitea/data/tmp/pprof
+PROTOCOL = http
+HTTP_PORT = 3000
+DISABLE_SSH = false
+START_SSH_SERVER = true
+SSH_PORT = 3022
+LFS_START_SERVER = true
+
+[lfs]
+PATH = /var/lib/gitea/data/lfs
+
+[database]
+DB_TYPE = sqlite3
+PATH = /var/lib/gitea/data/gitea.db
+
+[security]
+INSTALL_LOCK = true
+
+[oauth2]
+ENABLED = false
+
+[log]
+ROOT_PATH = /var/log/gitea
+MODE = console, file
+; Either "Trace", "Debug", "Info", "Warn", "Error" or "None", default is "Info"
+LEVEL = Debug
+
+[service]
+ENABLE_BASIC_AUTHENTICATION = true
diff --git a/behave/container-files/etc/systemd/system/gitea-configure-from-env.service b/behave/container-files/etc/systemd/system/gitea-configure-from-env.service
new file mode 100644
index 0000000000..1e73ca96ce
--- /dev/null
+++ b/behave/container-files/etc/systemd/system/gitea-configure-from-env.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Configure /etc/gitea/conf/app.ini from environmental variables
+
+[Service]
+Type=oneshot
+User=root
+Group=root
+PassEnvironment=GITEA_SERVER_HTTP_PORT
+PassEnvironment=GITEA_SERVER_SSH_PORT
+ExecStart=bash -c /usr/bin/gitea-configure-from-env
+
+[Install]
+RequiredBy=gitea.service
diff --git a/behave/container-files/etc/systemd/system/gitea-fix-var-lib-gitea-data.service b/behave/container-files/etc/systemd/system/gitea-fix-var-lib-gitea-data.service
new file mode 100644
index 0000000000..ff33e28f16
--- /dev/null
+++ b/behave/container-files/etc/systemd/system/gitea-fix-var-lib-gitea-data.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Fix /var/lib/gitea/data by copying it back and forth to the same overlayfs layer
+
+[Service]
+Type=oneshot
+User=gitea
+Group=gitea
+ExecStart=/bin/bash -c 'mv /var/lib/gitea/data /var/lib/gitea/data.backup && mkdir -p /var/lib/gitea/data && cp -a /var/lib/gitea/data.backup/* /var/lib/gitea/data/'
+
+[Install]
+RequiredBy=gitea.service
diff --git a/behave/container-files/etc/systemd/system/obs-configure-from-env.service b/behave/container-files/etc/systemd/system/obs-configure-from-env.service
new file mode 100644
index 0000000000..7afe898fd9
--- /dev/null
+++ b/behave/container-files/etc/systemd/system/obs-configure-from-env.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Configure OBS from environmental variables
+
+[Service]
+Type=oneshot
+User=root
+Group=root
+PassEnvironment=OBS_PROXY_AUTH
+ExecStart=bash -c /usr/bin/obs-configure-from-env
+
+[Install]
+RequiredBy=apache2.service
diff --git a/behave/container-files/opt/setup/fixtures/pac/test-GitPkgA.xml b/behave/container-files/opt/setup/fixtures/pac/test-GitPkgA.xml
new file mode 100644
index 0000000000..5c5f64331c
--- /dev/null
+++ b/behave/container-files/opt/setup/fixtures/pac/test-GitPkgA.xml
@@ -0,0 +1,5 @@
+
+
+
+ http://localhost:3000/pool/test-GitPkgA#factory
+
diff --git a/behave/container-files/opt/setup/gitea.sh b/behave/container-files/opt/setup/gitea.sh
new file mode 100644
index 0000000000..b435002bd3
--- /dev/null
+++ b/behave/container-files/opt/setup/gitea.sh
@@ -0,0 +1,143 @@
+set -x
+set -e
+
+
+TOPDIR=$(dirname $(readlink -f "$0"))
+source "$TOPDIR/common.sh"
+
+
+OSC="osc -A https://localhost"
+
+
+chown gitea:gitea /etc/gitea/conf/app.ini
+
+DB_PATH=/var/lib/gitea/data/gitea.db
+
+# create the database
+su - gitea -c 'gitea migrate'
+
+
+# to generate an access token for testing, use the following Python code:
+# from hashlib import pbkdf2_hmac
+# char = b"1"
+# print(pbkdf2_hmac(hash_name="sha256", password=40*char, salt=10*char, iterations=10000, dklen=50).hex())
+
+
+# user #1: Admin, password=opensuse
+# gitea refuses to create user 'admin'; let's create 'admin1' and rename it in the database
+su - gitea -c 'gitea admin user create --username Admin1 --password opensuse --email admin@example.com --must-change-password=false --admin'
+su - gitea -c "echo \"update user set lower_name='admin', name='Admin' where lower_name = 'admin1';\" | sqlite3 $DB_PATH"
+su - gitea -c "echo \"INSERT INTO access_token (uid, name, token_hash, token_salt, token_last_eight, scope, created_unix, updated_unix) VALUES (1, 'admin', '2da98f9cae724ae30563e3ba9663afb24af91019d04736523f1762eed291c449aebbbb749571958e1811588b33e64ae86bd7', '1111111111', '11111111', 'all', 0, 0);\" | sqlite3 $DB_PATH"
+export TOKEN_ADMIN='1111111111111111111111111111111111111111'
+
+
+# user #2: Alice, password=opensuse
+su - gitea -c 'gitea admin user create --username Alice --password opensuse --email alice@example.com --must-change-password=false'
+#su - gitea -c "echo \"update user set must_change_password=0 where lower_name = 'alice';\" | sqlite3 $DB_PATH"
+su - gitea -c "echo \"INSERT INTO access_token (uid, name, token_hash, token_salt, token_last_eight, scope, created_unix, updated_unix) VALUES (2, 'alice', '5aeaf57e2c156673a566815b5a5739f9aa25bc3ac0a3c9e942f31361230e1f26983f6b2abfd009358202fc2e02c8137693ee', 'aaaaaaaaaa', 'aaaaaaaa', 'all', 0, 0);\" | sqlite3 $DB_PATH"
+export TOKEN_ALICE='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+
+#sqlite> update access_token set scope='read:repository,write:repository,read:user' where id in (2,3);
+#read:issue
+
+# user #3 Bob, password=opensuse
+su - gitea -c 'gitea admin user create --username Bob --password opensuse --email bob@example.com --must-change-password=false'
+#su - gitea -c "echo \"update user set must_change_password=0 where lower_name = 'bob';\" | sqlite3 $DB_PATH"
+su - gitea -c "echo \"INSERT INTO access_token (uid, name, token_hash, token_salt, token_last_eight, scope, created_unix, updated_unix) VALUES (3, 'bob', 'b97a745cff7dabb6a767c4e993609ef41c54b8f722f9ff88b4232430e087751d54436fec1240f056585b270f432efb02d188', 'bbbbbbbbbb', 'bbbbbbbb', 'all', 0, 0);\" | sqlite3 $DB_PATH"
+export TOKEN_BOB='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
+
+
+systemctl enable gitea
+systemctl enable gitea-configure-from-env
+systemctl enable gitea-fix-var-lib-gitea-data
+
+
+su - gitea -c 'gitea' 2>&1 >/dev/null &
+sleep 15
+
+
+function create_org {
+ org="$1"
+ curl \
+ -X POST \
+ -H "Authorization: token $TOKEN_ADMIN" \
+ -H "Content-type: application/json" \
+ --data "{\"username\": \"$org\"}" \
+ "http://localhost:3000/api/v1/orgs"
+}
+
+
+function create_org_repo {
+ org="$1"
+ repo="$2"
+ curl \
+ -X POST \
+ -H "Authorization: token $TOKEN_ADMIN" \
+ -H "Content-type: application/json" \
+ --data "{\"name\": \"$repo\", \"default_branch\": \"factory\"}" \
+ "http://localhost:3000/api/v1/orgs/$org/repos"
+}
+
+
+function add_ssh_key {
+ user="$1"
+ token="$2"
+ ssh_key_path="$3"
+
+ key="$(cat $ssh_key_path)"
+ curl \
+ -X POST \
+ -H "Authorization: token $token" \
+ -H "Content-type: application/json" \
+ --data "{\"key\": \"$key\", \"title\": \"$(echo $key | cut -d ' ' -f 3-)\"}" \
+ "http://localhost:3000/api/v1/user/keys"
+}
+
+
+create_org pool
+create_org_repo pool test-GitPkgA
+add_ssh_key admin $TOKEN_ADMIN /root/.ssh/admin.pub
+add_ssh_key alice $TOKEN_ALICE /root/.ssh/alice.pub
+add_ssh_key bob $TOKEN_BOB /root/.ssh/bob.pub
+
+
+# create test-GitPkgA package based on test-PkgA
+# * change the package name
+# * use changelog dates as commit/commiter dates for reproducibility
+
+GITDIR="$(mktemp -d)"
+pushd "$GITDIR"
+
+git init --initial-branch factory
+# git commiter equals to the configured user
+git config user.name "Geeko Packager"
+git config user.email "email@example.com"
+
+cp -a "$TOPDIR"/fixtures/pac/test-pkgA-1.spec test-GitPkgA.spec
+cp -a "$TOPDIR"/fixtures/pac/test-pkgA-1.changes test-GitPkgA.changes
+sed 's@test-pkgA@test-GitPkgA@' -i *
+git add *
+DATE="2022-01-03 11:22:33 UTC"
+GIT_COMMITTER_DATE="$DATE" git commit -a -m "Initial commit" --date "$DATE"
+
+cp -a "$TOPDIR"/fixtures/pac/test-pkgA-2.spec test-GitPkgA.spec
+cp -a "$TOPDIR"/fixtures/pac/test-pkgA-2.changes test-GitPkgA.changes
+sed 's@test-pkgA@test-GitPkgA@' -i *
+git add *
+DATE="2022-01-04 11:22:33 UTC"
+GIT_COMMITTER_DATE="$DATE" git commit -a -m "Version 2" --date "$DATE"
+
+cp -a "$TOPDIR"/fixtures/pac/test-pkgA-3.spec test-GitPkgA.spec
+cp -a "$TOPDIR"/fixtures/pac/test-pkgA-3.changes test-GitPkgA.changes
+sed 's@test-pkgA@test-GitPkgA@' -i *
+git add *
+DATE="2022-01-05 11:22:33 UTC"
+GIT_COMMITTER_DATE="$DATE" git commit -a -m "Version 3" --date "$DATE"
+
+git remote add origin http://admin:opensuse@localhost:3000/pool/test-GitPkgA.git
+git push --set-upstream origin factory
+
+popd
+
+# create test-GitPkgA package in test:factory that has scmsync set to gitea
+$OSC api -X PUT '/source/test:factory/test-GitPkgA/_meta' --file "$TOPDIR"/fixtures/pac/test-GitPkgA.xml
diff --git a/behave/container-files/opt/setup/setup.sh b/behave/container-files/opt/setup/setup.sh
index 17580006ea..b4bf78d117 100644
--- a/behave/container-files/opt/setup/setup.sh
+++ b/behave/container-files/opt/setup/setup.sh
@@ -32,6 +32,9 @@ sed -i 's!^!!' /etc/apache2/vhosts.d
sed -i 's!^!!' /etc/apache2/vhosts.d/obs.conf
sed -i 's!^Listen 82$!Listen 82\nListen 1082\nListen 1443!' /etc/apache2/vhosts.d/obs.conf
+# forward X-Username HTTP header to HTTP_X_USERNAME variable that is needed for OBS proxy auth
+sed -i 's@^\(.*SSLEngine.*\)@ # the variable is used when OBS proxy auth is on\n SetEnvIf X-Username "(.*)" HTTP_X_USERNAME=$1\n\n\1@' /etc/apache2/vhosts.d/obs.conf
+
# enable apache mods
APACHE_MODS="passenger rewrite proxy proxy_http xforward headers ssl socache_shmcb"
@@ -144,3 +147,5 @@ sed -i '/^BindsTo *=.*/d; s/^WantedBy *=.*/WantedBy = default.target/' /usr/lib/
# OBS worker
# systemctl enable obsworker
+
+systemctl enable obs-configure-from-env
diff --git a/behave/container-files/root/.ssh/admin b/behave/container-files/root/.ssh/admin
new file mode 100644
index 0000000000..9f8d1d9a7e
--- /dev/null
+++ b/behave/container-files/root/.ssh/admin
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBqN71PEkPcdLHUG+oMKpAmnDAgdcuS4V3hEyRWaVf+iQAAAJh1HuOIdR7j
+iAAAAAtzc2gtZWQyNTUxOQAAACBqN71PEkPcdLHUG+oMKpAmnDAgdcuS4V3hEyRWaVf+iQ
+AAAEAqkTwb9syNHFuOFoy/UJgZGoHHX7zSMx7X10GmhgeIBGo3vU8SQ9x0sdQb6gwqkCac
+MCB1y5LhXeETJFZpV/6JAAAAEGFkbWluQGdpdGVhLXRlc3QBAgMEBQ==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/behave/container-files/root/.ssh/admin.pub b/behave/container-files/root/.ssh/admin.pub
new file mode 100644
index 0000000000..c271172668
--- /dev/null
+++ b/behave/container-files/root/.ssh/admin.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGo3vU8SQ9x0sdQb6gwqkCacMCB1y5LhXeETJFZpV/6J admin@gitea-test
diff --git a/behave/container-files/root/.ssh/alice b/behave/container-files/root/.ssh/alice
new file mode 100644
index 0000000000..fe30e07d9b
--- /dev/null
+++ b/behave/container-files/root/.ssh/alice
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBjDWj0eVxs8MzCGGrlEVekrafN+SaLymKSRHkeHefmFAAAAJhrDGRKawxk
+SgAAAAtzc2gtZWQyNTUxOQAAACBjDWj0eVxs8MzCGGrlEVekrafN+SaLymKSRHkeHefmFA
+AAAEDAwkWtXW0L35H8L4Can51HQh8JReoINka/SbeHflG2+mMNaPR5XGzwzMIYauURV6St
+p835JovKYpJEeR4d5+YUAAAAEGFsaWNlQGdpdGVhLXRlc3QBAgMEBQ==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/behave/container-files/root/.ssh/alice.pub b/behave/container-files/root/.ssh/alice.pub
new file mode 100644
index 0000000000..0e0f3488ee
--- /dev/null
+++ b/behave/container-files/root/.ssh/alice.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGMNaPR5XGzwzMIYauURV6Stp835JovKYpJEeR4d5+YU alice@gitea-test
diff --git a/behave/container-files/root/.ssh/bob b/behave/container-files/root/.ssh/bob
new file mode 100644
index 0000000000..505a49c4eb
--- /dev/null
+++ b/behave/container-files/root/.ssh/bob
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACCB3UPX7odgSnmMTKiD3SFI7U6DF7QU5RXoLAwDz0zPKAAAAJhCzJXDQsyV
+wwAAAAtzc2gtZWQyNTUxOQAAACCB3UPX7odgSnmMTKiD3SFI7U6DF7QU5RXoLAwDz0zPKA
+AAAECYDWlFAzIcdQsOV07CJXRYWoynJSNUsPzvGZDk4/tX+4HdQ9fuh2BKeYxMqIPdIUjt
+ToMXtBTlFegsDAPPTM8oAAAADmJvYkBnaXRlYS10ZXN0AQIDBAUGBw==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/behave/container-files/root/.ssh/bob.pub b/behave/container-files/root/.ssh/bob.pub
new file mode 100644
index 0000000000..050b44e321
--- /dev/null
+++ b/behave/container-files/root/.ssh/bob.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHdQ9fuh2BKeYxMqIPdIUjtToMXtBTlFegsDAPPTM8o bob@gitea-test
diff --git a/behave/container-files/usr/bin/gitea-configure-from-env b/behave/container-files/usr/bin/gitea-configure-from-env
new file mode 100755
index 0000000000..c3d7a69523
--- /dev/null
+++ b/behave/container-files/usr/bin/gitea-configure-from-env
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+CONF='/etc/gitea/conf/app.ini'
+
+if [ -n "${GITEA_SERVER_HTTP_PORT}" ]; then
+ sed -i "s@^HTTP_PORT =.*@HTTP_PORT = ${GITEA_SERVER_HTTP_PORT}@" "${CONF}"
+fi
+
+if [ -n "${GITEA_SERVER_SSH_PORT}" ]; then
+ sed -i "s@^SSH_PORT =.*@SSH_PORT = ${GITEA_SERVER_SSH_PORT}@" "${CONF}"
+fi
diff --git a/behave/container-files/usr/bin/obs-configure-from-env b/behave/container-files/usr/bin/obs-configure-from-env
new file mode 100755
index 0000000000..e0b360d996
--- /dev/null
+++ b/behave/container-files/usr/bin/obs-configure-from-env
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+CONF='/srv/www/obs/api/config/options.yml'
+
+if [ "${OBS_PROXY_AUTH}" -eq 1 ]; then
+ # enable proxy auth in OBS if $OBS_PROXY_AUTH is set to 1
+ sed -i 's@^[ #]*proxy_auth_mode: .*@ proxy_auth_mode: :on@' "${CONF}"
+ sed -i 's@^[ #]*proxy_auth_login_page: .*@ proxy_auth_login_page: https://my-idp.example.com/login@' "${CONF}"
+ sed -i 's@^[ #]*proxy_auth_logout_page: .*@ proxy_auth_logout_page: https://my-idp.example.com/logout@' "${CONF}"
+
+ # if this is not set, any changes to the tokens fail
+ sed -i 's@^[ #]*proxy_auth_account_page: .*@ proxy_auth_account_page: https://my-idp.example.com/myaccount@' "${CONF}"
+fi
diff --git a/behave/container-run.sh b/behave/container-run.sh
index 05b2d9e55c..ec5bdc293d 100755
--- a/behave/container-run.sh
+++ b/behave/container-run.sh
@@ -14,6 +14,9 @@ podman run \
--cap-add SYS_PTRACE \
-p 1443:443 \
-p 1082:82 \
+ -p 3000:3000 \
+ -p 3001:3000 \
+ -p 3022:3022 \
obs-server
sleep 0.5
diff --git a/behave/features/add.feature b/behave/features/add.feature
index 3fbc0d93a7..a03fc30130 100644
--- a/behave/features/add.feature
+++ b/behave/features/add.feature
@@ -5,7 +5,9 @@ Scenario: Run `osc add` on a new file in a package
Given I set working directory to "{context.osc.temp}"
And I execute osc with args "checkout test:factory test-pkgA"
And I set working directory to "{context.osc.temp}/test:factory/test-pkgA"
- And I copy file "{context.fixtures}/pac/test-pkgA-1.spec" to "{context.osc.temp}/test:factory/test-pkgA/new_file"
+ And I create file "{context.osc.temp}/test:factory/test-pkgA/new_file" with perms "0644"
+ """
+ """
And I execute osc with args "status --verbose"
And stdout is
"""
diff --git a/behave/features/createrequest.feature b/behave/features/createrequest.feature
index ee9839665e..1cd95c508b 100644
--- a/behave/features/createrequest.feature
+++ b/behave/features/createrequest.feature
@@ -12,7 +12,9 @@ Background:
@destructive
Scenario: Run `osc createrequest`
- When I copy file "{context.fixtures}/pac/test-pkgA-1.spec" to "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/new_file"
+ When I create file "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/new_file" with perms "0644"
+ """
+ """
And I execute osc with args "add new_file"
And I execute osc with args "ci -m 'commit description'"
And I execute osc with args "createrequest -a submit -m 'request description'"
@@ -21,14 +23,18 @@ Scenario: Run `osc createrequest`
@destructive
Scenario: Run `osc createrequest --supersede`
- Given I copy file "{context.fixtures}/pac/test-pkgA-1.spec" to "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/new_file"
+ Given I create file "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/new_file" with perms "0644"
+ """
+ """
And I execute osc with args "add new_file"
And I execute osc with args "ci -m 'commit description'"
And I execute osc with args "createrequest -a submit -m 'request description'"
And the exit code is 0
And I execute osc with args "api /request/1"
And stdout doesn't contain ""
- When I copy file "{context.fixtures}/pac/test-pkgA-1.spec" to "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/another_file"
+ When I create file "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/another_file" with perms "0644"
+ """
+ """
And I execute osc with args "add new_file"
And I execute osc with args "ci -m 'commit description'"
And I execute osc with args "createrequest -a submit -m 'request description' --supersede 1"
diff --git a/behave/features/environment.py b/behave/features/environment.py
index ee6a154271..1425283680 100644
--- a/behave/features/environment.py
+++ b/behave/features/environment.py
@@ -33,7 +33,10 @@ def after_scenario(context, scenario):
# we must use an existing podman instance defined in `before_all` due to context attribute life-cycle:
# https://behave.readthedocs.io/en/stable/context_attributes.html
context.podman.new_container()
+
context.osc.clear()
+ context.osc_git.clear()
+
common.check_exit_code(context)
@@ -54,8 +57,17 @@ def before_all(context):
if "osc" in context.config.userdata:
context.config.userdata["osc"] = os.path.abspath(os.path.expanduser(context.config.userdata["osc"]))
+ if "osc-git" in context.config.userdata:
+ context.config.userdata["osc-git"] = os.path.abspath(os.path.expanduser(context.config.userdata["osc-git"]))
+
# absolute path to .../behave/fixtures
- context.fixtures = os.path.join(os.path.dirname(__file__), "..", "fixtures")
+ context.fixtures = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "fixtures"))
+
+ # fix ssh-key perms
+ ssh_dir = os.path.join(context.fixtures, "ssh-keys")
+ for fn in os.listdir(ssh_dir):
+ ssh_key = os.path.join(ssh_dir, fn)
+ os.chmod(ssh_key, 0o600)
podman_max_containers = context.config.userdata.get("podman_max_containers", None)
if podman_max_containers:
@@ -64,9 +76,11 @@ def before_all(context):
else:
context.podman = podman.Podman(context, container_name="osc-behave")
context.osc = osc.Osc(context)
+ context.osc_git = osc.OscGit(context)
def after_all(context):
+ del context.osc_git
del context.osc
context.podman.kill()
del context.podman
diff --git a/behave/features/git-clone.feature b/behave/features/git-clone.feature
new file mode 100644
index 0000000000..1b258d686a
--- /dev/null
+++ b/behave/features/git-clone.feature
@@ -0,0 +1,24 @@
+Feature: `osc-git clone` command
+
+
+Background:
+ Given I set working directory to "{context.osc.temp}"
+
+
+@destructive
+Scenario: Clone a git repo
+ When I execute osc-git with args "clone pool test-GitPkgA --no-ssh-strict-host-key-checking"
+ Then the exit code is 0
+ And stdout is
+ """
+ """
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): admin
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Admin
+
+ Cloning into 'test-GitPkgA'...
+ """
diff --git a/behave/features/git-fork.feature b/behave/features/git-fork.feature
new file mode 100644
index 0000000000..6754e19eb7
--- /dev/null
+++ b/behave/features/git-fork.feature
@@ -0,0 +1,117 @@
+Feature: `osc-git fork` command
+
+
+Background:
+ Given I set working directory to "{context.osc.temp}"
+
+
+@destructive
+Scenario: Fork a git repo
+ When I execute osc-git with args "fork pool test-GitPkgA"
+ Then the exit code is 0
+ And stdout is
+ """
+ """
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): admin
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Admin
+
+ Forking git repo pool/test-GitPkgA ...
+ * Fork created: Admin/test-GitPkgA
+ """
+
+
+@destructive
+Scenario: Fork a git repo twice under different names
+ When I execute osc-git with args "fork pool test-GitPkgA"
+ Then the exit code is 0
+ And stdout is
+ """
+ """
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): admin
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Admin
+
+ Forking git repo pool/test-GitPkgA ...
+ * Fork created: Admin/test-GitPkgA
+ """
+ When I execute osc-git with args "fork pool test-GitPkgA --new-repo-name=new-package"
+ Then the exit code is 0
+ And stdout is
+ """
+ """
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): admin
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Admin
+
+ Forking git repo pool/test-GitPkgA ...
+ * Fork already exists: Admin/test-GitPkgA
+ * WARNING: Using an existing fork with a different name than requested
+ """
+
+
+@destructive
+Scenario: Fork a git repo from pool and fork someone else's fork of the same repo
+ When I execute osc-git with args "fork pool test-GitPkgA"
+ Then the exit code is 0
+ And stdout is
+ """
+ """
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): admin
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Admin
+
+ Forking git repo pool/test-GitPkgA ...
+ * Fork created: Admin/test-GitPkgA
+ """
+ When I execute osc-git with args "fork -G alice pool test-GitPkgA --new-repo-name=test-GitPkgA-alice"
+ Then the exit code is 0
+ And stdout is
+ """
+ """
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): alice
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Alice
+
+ Forking git repo pool/test-GitPkgA ...
+ * Fork created: Alice/test-GitPkgA-alice
+ """
+ # this succeeds with 202 and the requested fork is NOT created
+ When I execute osc-git with args "fork Alice test-GitPkgA-alice"
+ Then the exit code is 0
+ And stdout is
+ """
+ """
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): admin
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Admin
+
+ Forking git repo Alice/test-GitPkgA-alice ...
+ * Fork created: Admin/test-GitPkgA-alice
+ """
+ When I execute osc-git with args "clone Admin test-GitPkgA-alice --no-ssh-strict-host-key-checking"
+ Then the exit code is 0
diff --git a/behave/features/git-login.feature b/behave/features/git-login.feature
new file mode 100644
index 0000000000..e8cadf271d
--- /dev/null
+++ b/behave/features/git-login.feature
@@ -0,0 +1,120 @@
+Feature: `osc-git login` command for managing credentials entries for Gitea instances
+
+
+Background:
+ When I execute osc-git with args "login list"
+ Then stdout is
+ """
+ Name : admin
+ Default : true
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Admin
+ SSH Key : {context.fixtures}/ssh-keys/admin
+
+ Name : alice
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Alice
+ SSH Key : {context.fixtures}/ssh-keys/alice
+
+ Name : bob
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Bob
+ SSH Key : {context.fixtures}/ssh-keys/bob
+ """
+
+
+Scenario: Add a credentials login entry
+ When I execute osc-git with args "login add example1 --url https://gitea.example.com --user Admin --token 1234"
+ Then the exit code is 0
+ And stderr is
+ """
+ Adding a Gitea credentials entry with name 'example1' ...
+ * Config path: {context.osc_git.config}
+ """
+ And stdout is
+ """
+ Added entry:
+ Name : example1
+ URL : https://gitea.example.com
+ User : Admin
+ """
+ When I execute osc-git with args "login list"
+ Then stdout is
+ """
+ Name : admin
+ Default : true
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Admin
+ SSH Key : {context.fixtures}/ssh-keys/admin
+
+ Name : alice
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Alice
+ SSH Key : {context.fixtures}/ssh-keys/alice
+
+ Name : bob
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Bob
+ SSH Key : {context.fixtures}/ssh-keys/bob
+
+ Name : example1
+ URL : https://gitea.example.com
+ User : Admin
+ """
+
+
+Scenario: Remove a credentials login entry
+ When I execute osc-git with args "login remove admin"
+ Then the exit code is 0
+ And stderr is
+ """
+ Removing a Gitea credentials entry with name 'admin' ...
+ * Config path: {context.osc_git.config}
+ """
+ And stdout is
+ """
+ Removed entry:
+ Name : admin
+ Default : true
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Admin
+ SSH Key : {context.fixtures}/ssh-keys/admin
+ """
+ When I execute osc-git with args "login list"
+ Then stdout is
+ """
+ Name : alice
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Alice
+ SSH Key : {context.fixtures}/ssh-keys/alice
+
+ Name : bob
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Bob
+ SSH Key : {context.fixtures}/ssh-keys/bob
+ """
+
+
+Scenario: Update a credentials login entry
+ When I execute osc-git with args "login update admin --new-name=NEW_NAME --new-url=NEW_URL --new-user=NEW_USER --new-token=NEW_TOKEN --new-ssh-key="
+ Then the exit code is 0
+ And stderr is
+ """
+ Updating a Gitea credentials entry with name 'admin' ...
+ * Config path: {context.osc_git.config}
+ """
+ And stdout is
+ """
+ Original entry:
+ Name : admin
+ Default : true
+ URL : http://localhost:{context.podman.container.ports[gitea_http]}
+ User : Admin
+ SSH Key : {context.fixtures}/ssh-keys/admin
+
+ Updated entry:
+ Name : NEW_NAME
+ Default : true
+ URL : NEW_URL
+ User : NEW_USER
+ """
diff --git a/behave/features/git-ssh-key.feature b/behave/features/git-ssh-key.feature
new file mode 100644
index 0000000000..cf04bade2c
--- /dev/null
+++ b/behave/features/git-ssh-key.feature
@@ -0,0 +1,99 @@
+Feature: `osc-git ssh-key` command for managing public ssh key stored in a Gitea instance
+
+
+# when adding a ssh key that is already added to *any* user account, the following error pops up:
+# ERROR: 422 Unprocessable Entity: b'{"message":"Key content has been used as non-deploy key","url":"http://localhost:3000/api/swagger"}\n'
+
+
+Background:
+ When I execute osc-git with args "ssh-key list"
+ Then stdout is
+ """
+ ID : 1
+ Title : admin@gitea-test
+ Key : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGo3vU8SQ9x0sdQb6gwqkCacMCB1y5LhXeETJFZpV/6J admin@gitea-test
+ """
+
+
+@destructive
+Scenario: Add a public ssh key entry
+ # to be able to use the key, we need to remove it from Bob's account first
+ Given I execute osc-git with args "-G bob ssh-key remove 3"
+ When I execute osc-git with args "ssh-key add --key='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHdQ9fuh2BKeYxMqIPdIUjtToMXtBTlFegsDAPPTM8o bob@gitea-test'"
+ Then the exit code is 0
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): admin
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Admin
+ """
+ And stdout is
+ """
+ Added entry:
+ ID : 4
+ Title : bob@gitea-test
+ Key : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHdQ9fuh2BKeYxMqIPdIUjtToMXtBTlFegsDAPPTM8o bob@gitea-test
+ """
+ When I execute osc-git with args "ssh-key list"
+ Then stdout is
+ """
+ ID : 1
+ Title : admin@gitea-test
+ Key : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGo3vU8SQ9x0sdQb6gwqkCacMCB1y5LhXeETJFZpV/6J admin@gitea-test
+
+ ID : 4
+ Title : bob@gitea-test
+ Key : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHdQ9fuh2BKeYxMqIPdIUjtToMXtBTlFegsDAPPTM8o bob@gitea-test
+ """
+
+
+@destructive
+Scenario: Add a public ssh key entry from a .pub file
+ # to be able to use the key, we need to remove it from Bob's account first
+ Given I execute osc-git with args "-G bob ssh-key remove 3"
+ When I execute osc-git with args "ssh-key add --key-path='{context.fixtures}/ssh-keys/bob.pub'"
+ Then the exit code is 0
+ And stderr is
+ """
+ Using the following Gitea settings:
+ * Config path: {context.osc_git.config}
+ * Login (name of the entry in the config file): admin
+ * URL: http://localhost:{context.podman.container.ports[gitea_http]}
+ * User: Admin
+ """
+ And stdout is
+ """
+ Added entry:
+ ID : 4
+ Title : bob@gitea-test
+ Key : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHdQ9fuh2BKeYxMqIPdIUjtToMXtBTlFegsDAPPTM8o bob@gitea-test
+ """
+ When I execute osc-git with args "ssh-key list"
+ Then stdout is
+ """
+ ID : 1
+ Title : admin@gitea-test
+ Key : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGo3vU8SQ9x0sdQb6gwqkCacMCB1y5LhXeETJFZpV/6J admin@gitea-test
+
+ ID : 4
+ Title : bob@gitea-test
+ Key : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHdQ9fuh2BKeYxMqIPdIUjtToMXtBTlFegsDAPPTM8o bob@gitea-test
+ """
+
+
+@destructive
+Scenario: Remove a public ssh key entry by its id
+ When I execute osc-git with args "ssh-key remove 1"
+ Then stdout is
+ """
+ Removed entry:
+ ID : 1
+ Title : admin@gitea-test
+ Key : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGo3vU8SQ9x0sdQb6gwqkCacMCB1y5LhXeETJFZpV/6J admin@gitea-test
+ """
+ When I execute osc-git with args "ssh-key list"
+ Then stdout is
+ """
+ """
diff --git a/behave/features/list.feature b/behave/features/list.feature
index e904bc49b0..6643045835 100644
--- a/behave/features/list.feature
+++ b/behave/features/list.feature
@@ -25,6 +25,7 @@ Scenario: Run `osc list` on a project to display project packages
multibuild-pkg
multibuild-pkg:flavor1
multibuild-pkg:flavor2
+ test-GitPkgA
test-pkgA
test-pkgB
"""
diff --git a/behave/features/results.feature b/behave/features/results.feature
index 1ed2aa25c7..5e9253992e 100644
--- a/behave/features/results.feature
+++ b/behave/features/results.feature
@@ -12,14 +12,14 @@ Scenario: Run `osc results` with no arguments
Scenario: Run `osc results /`
When I execute osc with args "results test:factory/multibuild-pkg"
- Then stdout is
+ Then stdout matches
"""
- standard x86_64 multibuild-pkg disabled
- standard x86_64 multibuild-pkg:flavor1 disabled
- standard x86_64 multibuild-pkg:flavor2 disabled
- standard i586 multibuild-pkg disabled
- standard i586 multibuild-pkg:flavor1 disabled
- standard i586 multibuild-pkg:flavor2 disabled
+ standard x86_64 multibuild-pkg disabled\*?
+ standard x86_64 multibuild-pkg:flavor1 disabled\*?
+ standard x86_64 multibuild-pkg:flavor2 disabled\*?
+ standard i586 multibuild-pkg disabled\*?
+ standard i586 multibuild-pkg:flavor1 disabled\*?
+ standard i586 multibuild-pkg:flavor2 disabled\*?
"""
@@ -28,23 +28,23 @@ Scenario: Run `osc results` from a package checkout
And I execute osc with args "checkout test:factory/multibuild-pkg"
And I set working directory to "{context.osc.temp}/test:factory/multibuild-pkg"
When I execute osc with args "results"
- Then stdout is
+ Then stdout matches
"""
- standard x86_64 multibuild-pkg disabled
- standard x86_64 multibuild-pkg:flavor1 disabled
- standard x86_64 multibuild-pkg:flavor2 disabled
- standard i586 multibuild-pkg disabled
- standard i586 multibuild-pkg:flavor1 disabled
- standard i586 multibuild-pkg:flavor2 disabled
+ standard x86_64 multibuild-pkg disabled\*?
+ standard x86_64 multibuild-pkg:flavor1 disabled\*?
+ standard x86_64 multibuild-pkg:flavor2 disabled\*?
+ standard i586 multibuild-pkg disabled\*?
+ standard i586 multibuild-pkg:flavor1 disabled\*?
+ standard i586 multibuild-pkg:flavor2 disabled\*?
"""
Scenario: Run `osc results /`, no multibuild flavors
When I execute osc with args "results test:factory/multibuild-pkg --no-multibuild"
- Then stdout is
+ Then stdout matches
"""
- standard x86_64 multibuild-pkg disabled
- standard i586 multibuild-pkg disabled
+ standard x86_64 multibuild-pkg disabled\*?
+ standard i586 multibuild-pkg disabled\*?
"""
@@ -53,10 +53,10 @@ Scenario: Run `osc results` from a package checkout, multibuild flavor specified
And I execute osc with args "checkout test:factory/multibuild-pkg"
And I set working directory to "{context.osc.temp}/test:factory/multibuild-pkg"
When I execute osc with args "results -M flavor1"
- Then stdout is
+ Then stdout matches
"""
- standard x86_64 multibuild-pkg:flavor1 disabled
- standard i586 multibuild-pkg:flavor1 disabled
+ standard x86_64 multibuild-pkg:flavor1 disabled\*?
+ standard i586 multibuild-pkg:flavor1 disabled\*?
"""
Scenario: Run `osc results /`, specified output format
@@ -76,12 +76,12 @@ Scenario: Run `osc results /`, csv output
When I execute osc with args "results test:factory/multibuild-pkg --csv"
Then stdout matches
"""
- "standard","x86_64","multibuild-pkg","publish.*","False","disabled",""
- "standard","x86_64","multibuild-pkg:flavor1","publish.*","False","disabled",""
- "standard","x86_64","multibuild-pkg:flavor2","publish.*","False","disabled",""
- "standard","i586","multibuild-pkg","publish.*","False","disabled",""
- "standard","i586","multibuild-pkg:flavor1","publish.*","False","disabled",""
- "standard","i586","multibuild-pkg:flavor2","publish.*","False","disabled",""
+ "standard","x86_64","multibuild-pkg","publish.*",".*","disabled",""
+ "standard","x86_64","multibuild-pkg:flavor1","publish.*",".*","disabled",""
+ "standard","x86_64","multibuild-pkg:flavor2","publish.*",".*","disabled",""
+ "standard","i586","multibuild-pkg","publish.*",".*","disabled",""
+ "standard","i586","multibuild-pkg:flavor1","publish.*",".*","disabled",""
+ "standard","i586","multibuild-pkg:flavor2","publish.*",".*","disabled",""
"""
@@ -89,8 +89,8 @@ Scenario: Run `osc results /`, csv output, multibuild flavor s
When I execute osc with args "results test:factory/multibuild-pkg --csv -M flavor1"
Then stdout matches
"""
- "standard","x86_64","multibuild-pkg:flavor1","publish.*","False","disabled",""
- "standard","i586","multibuild-pkg:flavor1","publish.*","False","disabled",""
+ "standard","x86_64","multibuild-pkg:flavor1","publish.*",".*","disabled",""
+ "standard","i586","multibuild-pkg:flavor1","publish.*",".*","disabled",""
"""
diff --git a/behave/features/steps/osc.py b/behave/features/steps/osc.py
index 53cd5271b0..b00e2cf763 100644
--- a/behave/features/steps/osc.py
+++ b/behave/features/steps/osc.py
@@ -5,18 +5,21 @@
import time
import behave
+import ruamel.yaml
from steps.common import debug
from steps.common import run_in_context
-class Osc:
+class CommandBase:
+ CONFIG_NAME: str
+
def __init__(self, context):
if not hasattr(context, "podman"):
raise RuntimeError("context doesn't have 'podman' object set")
self.context = context
- debug(self.context, "Osc.__init__()")
+ debug(self.context, f"{self.__class__.__name__}.__init__()")
self.temp = None
self.clear()
@@ -27,33 +30,84 @@ def __del__(self):
pass
def clear(self):
- debug(self.context, "Osc.clear()")
+ debug(self.context, f"{self.__class__.__name__}.clear()")
if self.temp:
shutil.rmtree(self.temp)
self.temp = tempfile.mkdtemp(prefix="osc_behave_")
- self.oscrc = os.path.join(self.temp, "oscrc")
- self.write_oscrc()
+ self.config = os.path.join(self.temp, self.CONFIG_NAME)
+ self.write_config()
+
+ def write_config(self, **kwargs):
+ raise NotImplementedError()
+
- def write_oscrc(self, username=None, password=None):
- with open(self.oscrc, "w") as f:
+class Osc(CommandBase):
+ CONFIG_NAME = "oscrc"
+
+ def write_config(self, username=None, password=None):
+ with open(self.config, "w") as f:
f.write("[general]\n")
f.write("\n")
- f.write(f"[https://localhost:{self.context.podman.container.port}]\n")
+ f.write(f"[https://localhost:{self.context.podman.container.ports['obs_https']}]\n")
f.write(f"user={username or 'Admin'}\n")
f.write(f"pass={password or 'opensuse'}\n")
f.write("credentials_mgr_class=osc.credentials.PlaintextConfigFileCredentialsManager\n")
f.write("sslcertck=0\n")
if not any((username, password)):
f.write("http_headers =\n")
- # avoid the initial 401 response by setting auth to Admin:opensuse directly
- # write the header only when the default user/pass are used
- f.write(" authorization: Basic QWRtaW46b3BlbnN1c2U=\n")
+ # avoid the initial 401 response by using proxy auth
+ f.write(" X-Username: Admin\n")
def get_cmd(self):
osc_cmd = self.context.config.userdata.get("osc", "osc")
cmd = [osc_cmd]
- cmd += ["--config", self.oscrc]
- cmd += ["-A", f"https://localhost:{self.context.podman.container.port}"]
+ cmd += ["--config", self.config]
+ cmd += ["-A", f"https://localhost:{self.context.podman.container.ports['obs_https']}"]
+ return cmd
+
+
+class OscGit(CommandBase):
+ CONFIG_NAME = "config.yml"
+
+ def write_config(self):
+ data = {
+ "logins": [
+ {
+ "name": "admin",
+ "url": f"http://localhost:{self.context.podman.container.ports['gitea_http']}",
+ "user": "Admin",
+ "token": 40 * "1",
+ "ssh_key": f"{self.context.fixtures}/ssh-keys/admin",
+ "default": True,
+ },
+ {
+ "name": "alice",
+ "url": f"http://localhost:{self.context.podman.container.ports['gitea_http']}",
+ "user": "Alice",
+ "token": 40 * "a",
+ "ssh_key": f"{self.context.fixtures}/ssh-keys/alice",
+ "default": False,
+ },
+ {
+ "name": "bob",
+ "url": f"http://localhost:{self.context.podman.container.ports['gitea_http']}",
+ "user": "Bob",
+ "token": 40 * "b",
+ "ssh_key": f"{self.context.fixtures}/ssh-keys/bob",
+ "default": False,
+ },
+ ],
+ }
+ with open(self.config, "w") as f:
+ yaml = ruamel.yaml.YAML()
+ yaml.default_flow_style = False
+ yaml.dump(data, f)
+
+ def get_cmd(self):
+ osc_cmd = self.context.config.userdata.get("osc-git", "osc-git")
+ cmd = [osc_cmd]
+ cmd += ["--gitea-config", self.config]
+ cmd += ["-G", f"admin"]
return cmd
@@ -67,9 +121,19 @@ def step_impl(context, args):
context.cmd_stderr = re.sub(r"^.*InsecureRequestWarning.*\n warnings.warn\(\n", "", context.cmd_stderr)
+@behave.step("I execute osc-git with args \"{args}\"")
+def step_impl(context, args):
+ args = args.format(context=context)
+ cmd = context.osc_git.get_cmd() + [args]
+ cmd = " ".join(cmd)
+ run_in_context(context, cmd, can_fail=True)
+ # remove InsecureRequestWarning that is irrelevant to the tests
+ context.cmd_stderr = re.sub(r"^.*InsecureRequestWarning.*\n warnings.warn\(\n", "", context.cmd_stderr)
+
+
@behave.step("I configure osc user \"{username}\" with password \"{password}\"")
def step_impl(context, username, password):
- context.osc.write_oscrc(username=username, password=password)
+ context.osc.write_config(username=username, password=password)
@behave.step('I wait for osc results for "{project}" "{package}"')
diff --git a/behave/features/steps/podman.py b/behave/features/steps/podman.py
index ebb6a36900..d05b172500 100644
--- a/behave/features/steps/podman.py
+++ b/behave/features/steps/podman.py
@@ -1,10 +1,23 @@
+import contextlib
import queue
+import socket
import subprocess
import threading
+import behave
+
from steps.common import debug
+@contextlib.contextmanager
+def get_free_port():
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+ s.bind(("0.0.0.0", 0))
+ s.listen()
+ port = s.getsockname()[1]
+ yield port
+
+
class Podman:
def __init__(self, context, container_name):
self.context = context
@@ -33,6 +46,8 @@ def new_container(self):
# no need to stop the running container
# becuse the new container replaces an old container with the identical name
self.container = Container(self.context, name=self.container_name)
+ self.container.wait_on_systemd()
+ debug(self.context, f"> {self.container}")
class ThreadedPodman:
@@ -96,6 +111,7 @@ def container_producer(self):
else:
container_name = None
container = Container(self.context, name=container_name)
+ debug(self.context, f"ThreadedPodman.container_producer() - container created: {self.container_name_num}")
self.container_producer_queue.put(container, block=True)
self.container_producer_queue_is_stopped.set()
@@ -111,6 +127,7 @@ def new_container(self):
if getattr(self, "container", None):
self.container_consumer_queue.put(self.container)
self.container = self.container_producer_queue.get(block=True)
+ self.container.wait_on_systemd()
debug(self.context, f"> {self.container}")
@@ -120,7 +137,7 @@ def __init__(self, context, name=None):
debug(self.context, "Container.__init__()")
self.container_name = name
self.container_id = None
- self.port = None
+ self.ports = {}
self.start()
def __del__(self):
@@ -131,7 +148,7 @@ def __del__(self):
def __repr__(self):
result = super().__repr__()
- result += f"(port:{self.port}, id:{self.container_id}, name:{self.container_name})"
+ result += f"(id:{self.container_id}, name:{self.container_name})"
return result
def _run(self, args, check=True):
@@ -149,7 +166,7 @@ def _run(self, args, check=True):
debug(self.context, "> stderr:", proc.stderr)
return proc
- def start(self):
+ def start(self, use_proxy_auth: bool = True):
debug(self.context, "Container.start()")
args = [
"run",
@@ -166,18 +183,49 @@ def start(self):
"--detach",
"--interactive",
"--tty",
- "-p", "443",
+ ]
+
+ with get_free_port() as obs_https, get_free_port() as gitea_http, get_free_port() as gitea_ssh:
+ # we're using all context managers to reserve all ports at once
+ # and close the gap between releasing them and using again in podman
+ self.ports = {
+ "obs_https": obs_https,
+ "gitea_http": gitea_http,
+ "gitea_ssh": gitea_ssh,
+ }
+
+ if use_proxy_auth:
+ args += [
+ # enable proxy auth to bypass http auth that is slow
+ "--env", "OBS_PROXY_AUTH=1",
+ ]
+
+ args += [
+ # obs runs always on 443 in the container
+ "-p", f"{obs_https}:443",
+
+ # gitea runs on random free ports
+ # it is configured via env variables and running gitea-configure-from-env.service inside the container
+ "-p", f"{gitea_http}:{gitea_http}",
+ "--env", f"GITEA_SERVER_HTTP_PORT={gitea_http}",
+ "-p", f"{gitea_ssh}:{gitea_ssh}",
+ "--env", f"GITEA_SERVER_SSH_PORT={gitea_ssh}",
+ ]
+
+ args += [
"obs-server"
]
proc = self._run(args)
lines = proc.stdout.strip().splitlines()
self.container_id = lines[-1]
- self.wait_on_systemd()
- self.port = self.get_port()
- def exec(self, args, check=True):
- args = ["exec", self.container_id] + args
- return self._run(args, check=check)
+ def exec(self, args, check=True, interactive=False):
+ podman_args = ["exec"]
+ if interactive:
+ podman_args += ["-it"]
+ podman_args += [self.container_id]
+ podman_args += args
+ return self._run(podman_args, check=check)
def kill(self):
if not self.container_id:
@@ -193,14 +241,17 @@ def restart(self):
self.start()
def wait_on_systemd(self):
+ debug(self.context, "Container.wait_on_systemd() - start")
self.exec(["/usr/bin/systemctl", "is-system-running", "--wait"], check=False)
-
- def get_port(self):
- args = ["port", self.container_id]
- proc = self._run(args)
- lines = proc.stdout.strip().splitlines()
- for line in lines:
- if line.startswith("443/tcp"):
- # return from: "443/tcp -> 0.0.0.0:"
- return line.split(":")[-1]
- raise RuntimeError(f"Could not determine port of container {self.container_id}")
+ debug(self.context, "Container.wait_on_systemd() - done")
+
+
+@behave.step("I start a new container without proxy auth")
+def step_impl(context):
+ context.podman.container.kill()
+ context.podman.container.container_id = None
+ context.podman.container.ports = {}
+ context.podman.container.start(use_proxy_auth=False)
+ context.podman.container.wait_on_systemd()
+ context.osc.write_config()
+ context.osc_git.write_config()
diff --git a/behave/features/submitrequest.feature b/behave/features/submitrequest.feature
index 907757e391..9499fab38f 100644
--- a/behave/features/submitrequest.feature
+++ b/behave/features/submitrequest.feature
@@ -12,7 +12,9 @@ Background:
@destructive
Scenario: Run `osc submitrequest`
- When I copy file "{context.fixtures}/pac/test-pkgA-1.spec" to "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/new_file"
+ When I create file "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/new_file" with perms "0644"
+ """
+ """
And I execute osc with args "add new_file"
And I execute osc with args "ci -m 'commit description'"
And I execute osc with args "submitrequest -m 'request description'"
@@ -21,14 +23,18 @@ Scenario: Run `osc submitrequest`
@destructive
Scenario: Run `osc submitrequest --supersede`
- Given I copy file "{context.fixtures}/pac/test-pkgA-1.spec" to "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/new_file"
+ Given I create file "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/new_file" with perms "0644"
+ """
+ """
And I execute osc with args "add new_file"
And I execute osc with args "ci -m 'commit description'"
And I execute osc with args "submitrequest -m 'request description'"
And the exit code is 0
And I execute osc with args "api /request/1"
And stdout doesn't contain ""
- When I copy file "{context.fixtures}/pac/test-pkgA-1.spec" to "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/another_file"
+ When I create file "{context.osc.temp}/home:Admin:branches:test:devel/test-pkgA/another_file" with perms "0644"
+ """
+ """
And I execute osc with args "add new_file"
And I execute osc with args "ci -m 'commit description'"
And I execute osc with args "submitrequest -m 'request description' --supersede 1"
diff --git a/behave/features/user.feature b/behave/features/user.feature
index 7127a5a86a..9ab57c32b4 100644
--- a/behave/features/user.feature
+++ b/behave/features/user.feature
@@ -1,14 +1,11 @@
Feature: Manage user accounts
-# common steps for all scenarios
-Background:
- Given I set working directory to "{context.osc.temp}"
- And I execute osc with args "api -X POST '/person?cmd=register' --file '{context.fixtures}/user/unicode.xml'"
-
-
@destructive
Scenario: Run `osc ls` under the newly created user that has a password with unicode characters
- Given I configure osc user "unicode" with password "Password with unicode characters 🚀🚀🚀"
+ Given I start a new container without proxy auth
+ And I set working directory to "{context.osc.temp}"
+ And I execute osc with args "api -X POST '/person?cmd=register' --file '{context.fixtures}/user/unicode.xml'"
+ And I configure osc user "unicode" with password "Password with unicode characters 🚀🚀🚀"
When I execute osc with args "ls test:factory"
Then the exit code is 0
diff --git a/behave/fixtures/pac/multibuild-pkg-1._multibuild b/behave/fixtures/pac/multibuild-pkg-1._multibuild
deleted file mode 120000
index dbc1b7065f..0000000000
--- a/behave/fixtures/pac/multibuild-pkg-1._multibuild
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/multibuild-pkg-1._multibuild
\ No newline at end of file
diff --git a/behave/fixtures/pac/multibuild-pkg-1.changes b/behave/fixtures/pac/multibuild-pkg-1.changes
deleted file mode 120000
index 7021ef86dc..0000000000
--- a/behave/fixtures/pac/multibuild-pkg-1.changes
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/multibuild-pkg-1.changes
\ No newline at end of file
diff --git a/behave/fixtures/pac/multibuild-pkg-1.spec b/behave/fixtures/pac/multibuild-pkg-1.spec
deleted file mode 120000
index e28c19bd24..0000000000
--- a/behave/fixtures/pac/multibuild-pkg-1.spec
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/multibuild-pkg-1.spec
\ No newline at end of file
diff --git a/behave/fixtures/pac/test-pkgA-1.changes b/behave/fixtures/pac/test-pkgA-1.changes
deleted file mode 120000
index ee5b8c2c9f..0000000000
--- a/behave/fixtures/pac/test-pkgA-1.changes
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/test-pkgA-1.changes
\ No newline at end of file
diff --git a/behave/fixtures/pac/test-pkgA-1.spec b/behave/fixtures/pac/test-pkgA-1.spec
deleted file mode 120000
index 31332c8e33..0000000000
--- a/behave/fixtures/pac/test-pkgA-1.spec
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/test-pkgA-1.spec
\ No newline at end of file
diff --git a/behave/fixtures/pac/test-pkgA-3.changes b/behave/fixtures/pac/test-pkgA-3.changes
deleted file mode 120000
index 22eaf2c47d..0000000000
--- a/behave/fixtures/pac/test-pkgA-3.changes
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/test-pkgA-3.changes
\ No newline at end of file
diff --git a/behave/fixtures/pac/test-pkgA-3.spec b/behave/fixtures/pac/test-pkgA-3.spec
deleted file mode 120000
index 40f71fafb1..0000000000
--- a/behave/fixtures/pac/test-pkgA-3.spec
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/test-pkgA-3.spec
\ No newline at end of file
diff --git a/behave/fixtures/pac/test-pkgB-1.changes b/behave/fixtures/pac/test-pkgB-1.changes
deleted file mode 120000
index 232bdf426e..0000000000
--- a/behave/fixtures/pac/test-pkgB-1.changes
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/test-pkgB-1.changes
\ No newline at end of file
diff --git a/behave/fixtures/pac/test-pkgB-1.spec b/behave/fixtures/pac/test-pkgB-1.spec
deleted file mode 120000
index b22ad3d72e..0000000000
--- a/behave/fixtures/pac/test-pkgB-1.spec
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/test-pkgB-1.spec
\ No newline at end of file
diff --git a/behave/fixtures/pac/test-pkgB-2.changes b/behave/fixtures/pac/test-pkgB-2.changes
deleted file mode 120000
index 64c40ab0e9..0000000000
--- a/behave/fixtures/pac/test-pkgB-2.changes
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/test-pkgB-2.changes
\ No newline at end of file
diff --git a/behave/fixtures/pac/test-pkgB-2.spec b/behave/fixtures/pac/test-pkgB-2.spec
deleted file mode 120000
index 754c3a44df..0000000000
--- a/behave/fixtures/pac/test-pkgB-2.spec
+++ /dev/null
@@ -1 +0,0 @@
-../../container-files/opt/setup/fixtures/pac/test-pkgB-2.spec
\ No newline at end of file
diff --git a/behave/fixtures/ssh-keys b/behave/fixtures/ssh-keys
new file mode 120000
index 0000000000..cbca196016
--- /dev/null
+++ b/behave/fixtures/ssh-keys
@@ -0,0 +1 @@
+../container-files/root/.ssh
\ No newline at end of file