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 @@ + + + <description/> + <scmsync>http://localhost:3000/pool/test-GitPkgA#factory</scmsync> +</package> 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!^<VirtualHost \*:82>!<VirtualHost *:82 *:1082>!' /etc/apache2/vhosts.d sed -i 's!^<VirtualHost \*:443>!<VirtualHost *:443 *:1443>!' /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 "<state name=\"superseded\">" - 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 <project>/<package>` 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 <project>/<package>`, 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 <project>/<package>`, specified output format @@ -76,12 +76,12 @@ Scenario: Run `osc results <project>/<package>`, 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 <project>/<package>`, 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 <port> from: "443/tcp -> 0.0.0.0:<port>" - 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 "<state name=\"superseded\">" - 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