From d7b08057f4a2a956da789e345037d28a8e5d40d8 Mon Sep 17 00:00:00 2001 From: Jean-Louis Dupond Date: Mon, 20 Oct 2025 14:08:11 +0200 Subject: [PATCH 1/5] Post Release 1.7.4 Signed-off-by: Jean-Louis Dupond --- .automation/build-srpm.sh | 2 +- .copr/Makefile | 4 ++-- configure.ac | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.automation/build-srpm.sh b/.automation/build-srpm.sh index cd2270c..4d88d65 100755 --- a/.automation/build-srpm.sh +++ b/.automation/build-srpm.sh @@ -17,7 +17,7 @@ make clean # build tarballs make dist -# SUFFIX=".$(date -u +%Y%m%d%H%M%S).git$(git rev-parse --short HEAD)" +SUFFIX=".$(date -u +%Y%m%d%H%M%S).git$(git rev-parse --short HEAD)" # Build SRPMs rpmbuild \ diff --git a/.copr/Makefile b/.copr/Makefile index dac2433..073e537 100644 --- a/.copr/Makefile +++ b/.copr/Makefile @@ -29,8 +29,8 @@ git-safe: git config --global --add safe.directory "$(shell pwd)" srpm: installdeps git-safe - # $(eval SUFFIX=$(shell sh -c " echo '.$$(date -u +%Y%m%d%H%M%S).git$$(git rev-parse --short HEAD)'")) + $(eval SUFFIX=$(shell sh -c " echo '.$$(date -u +%Y%m%d%H%M%S).git$$(git rev-parse --short HEAD)'")) # changing the spec file as passing -D won't preserve the suffix when rebuilding in mock - # sed "s:%{?release_suffix}:${SUFFIX}:" -i vdsm-jsonrpc-java.spec.in + sed "s:%{?release_suffix}:${SUFFIX}:" -i vdsm-jsonrpc-java.spec.in .automation/build-srpm.sh cp rpmbuild/SRPMS/$(shell sh -c "basename '$(spec)'|cut -f1 -d.")*.src.rpm $(outdir) diff --git a/configure.ac b/configure.ac index 3746016..539e3a4 100644 --- a/configure.ac +++ b/configure.ac @@ -21,13 +21,13 @@ AC_PREREQ(2.60) define([VERSION_MAJOR], [1]) define([VERSION_MINOR], [7]) -define([VERSION_FIX], [4]) +define([VERSION_FIX], [5]) define([VERSION_NUMBER], VERSION_MAJOR[.]VERSION_MINOR[.]VERSION_FIX) define([VERSION_SUFFIX], []) AC_INIT([vdsm-jsonrpc-java], VERSION_NUMBER[]VERSION_SUFFIX) PACKAGE_RPM_VERSION="VERSION_NUMBER" -PACKAGE_RPM_RELEASE="1" +PACKAGE_RPM_RELEASE="0" PACKAGE_MAVEN_VERSION="VERSION_MAJOR.VERSION_MINOR.VERSION_FIX" AC_SUBST([PACKAGE_RPM_VERSION]) AC_SUBST([PACKAGE_RPM_RELEASE]) From b1f464894078b569a67ddd685dbf55b9f80bb01a Mon Sep 17 00:00:00 2001 From: Jean-Louis Dupond Date: Fri, 17 Jul 2026 13:31:20 +0200 Subject: [PATCH 2/5] build: update build flow - Update the way version tags are added during build. Now we can tag a commit in github, and the correct version string will be used for the builds. - Run the workflow on any tag, so it builds tags in branches also. - Drop copr Signed-off-by: Jean-Louis Dupond --- .automation/build-rpm.sh | 16 ----- .automation/build-srpm.sh | 26 -------- .copr/Makefile | 36 ----------- .github/workflows/build.yml | 123 +++++++++++++++++++++++++----------- .gitignore | 2 - Makefile.am | 22 ++++++- README.md | 1 - configure.ac | 8 ++- 8 files changed, 112 insertions(+), 122 deletions(-) delete mode 100755 .automation/build-rpm.sh delete mode 100755 .automation/build-srpm.sh delete mode 100644 .copr/Makefile diff --git a/.automation/build-rpm.sh b/.automation/build-rpm.sh deleted file mode 100755 index dc4eab1..0000000 --- a/.automation/build-rpm.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -xe - -source $(dirname "$(readlink -f "$0")")/build-srpm.sh - -# Install build dependencies -dnf builddep -y rpmbuild/SRPMS/*src.rpm - -# Build binary package -rpmbuild \ - --define "_topmdir rpmbuild" \ - --define "_rpmdir rpmbuild" \ - --rebuild rpmbuild/SRPMS/*src.rpm - -# Move RPMs to exported artifacts -[[ -d $ARTIFACTS_DIR ]] || mkdir -p $ARTIFACTS_DIR -find rpmbuild -iname \*rpm | xargs mv -t $ARTIFACTS_DIR diff --git a/.automation/build-srpm.sh b/.automation/build-srpm.sh deleted file mode 100755 index 4d88d65..0000000 --- a/.automation/build-srpm.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -xe - -# Directory, where build artifacts will be stored, should be passed as the 1st parameter -ARTIFACTS_DIR=${1:-exported-artifacts} -export ARTIFACTS_DIR - -# Prepare source archive -[[ -d rpmbuild/SOURCES ]] || mkdir -p rpmbuild/SOURCES - -./autogen.sh --system -./configure - -# clean -rm -rf rpmbuild/SOURCES/* -make clean - -# build tarballs -make dist - -SUFFIX=".$(date -u +%Y%m%d%H%M%S).git$(git rev-parse --short HEAD)" - -# Build SRPMs -rpmbuild \ - -D "_topdir rpmbuild" \ - ${SUFFIX:+ -D "release_suffix ${SUFFIX}"} \ - -ts ./*.tar.gz diff --git a/.copr/Makefile b/.copr/Makefile deleted file mode 100644 index 073e537..0000000 --- a/.copr/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -.PHONY: installdeps srpm git-safe - -installdeps: - dnf -y install \ - apache-commons-lang3 \ - autoconf \ - automake \ - createrepo_c \ - dnf-utils \ - findutils \ - gcc \ - git \ - jackson-annotations \ - jackson-core \ - jackson-databind \ - java-21-openjdk-devel \ - javapackages-tools \ - make \ - maven-source-plugin \ - maven \ - rpm-build \ - slf4j \ - slf4j-jdk14 \ - sed - -# explicity mark the copr generated git repo directory (which is done prior to the mock -# # call to the make_srpm and will be the current pwd) as safe for git commands -git-safe: - git config --global --add safe.directory "$(shell pwd)" - -srpm: installdeps git-safe - $(eval SUFFIX=$(shell sh -c " echo '.$$(date -u +%Y%m%d%H%M%S).git$$(git rev-parse --short HEAD)'")) - # changing the spec file as passing -D won't preserve the suffix when rebuilding in mock - sed "s:%{?release_suffix}:${SUFFIX}:" -i vdsm-jsonrpc-java.spec.in - .automation/build-srpm.sh - cp rpmbuild/SRPMS/$(shell sh -c "basename '$(spec)'|cut -f1 -d.")*.src.rpm $(outdir) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3020811..bf78067 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,10 @@ +--- name: build + on: push: branches: [master] + tags: ['*'] pull_request: branches: [master] workflow_dispatch: @@ -9,60 +12,106 @@ on: jobs: build: runs-on: ubuntu-latest - name: Test and build - container: - image: quay.io/ovirt/buildcontainer:el10stream - - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - name: Run maven build - run: | - ./autogen.sh - ./configure - mvn test -P\!slow-tests-disabled - - build-rpms: - runs-on: ubuntu-latest - needs: build + permissions: + contents: read strategy: fail-fast: false matrix: include: + - name: almalinux-9 + shortcut: el9 + container-name: almalinux9 + - name: almalinux-10 + shortcut: el10 + container-name: almalinux10 - name: centos-stream-9 - shortcut: cs9 + shortcut: el9s container-name: el9stream - name: centos-stream-10 - shortcut: cs10 + shortcut: el10s container-name: el10stream - name: ${{ matrix.name }} - - env: - ARTIFACTS_DIR: exported-artifacts - + name: Build on ${{ matrix.name }} container: image: quay.io/ovirt/buildcontainer:${{ matrix.container-name }} steps: + - name: Checkout sources + uses: actions/checkout@v7 - - name: Checkout sources - uses: ovirt/checkout-action@main + - name: Mark repository as safe + run: git config --global --add safe.directory "$(pwd)" - - name: Mark git repo as safe - run: git config --global --add safe.directory $(pwd) + - name: Install dependencies + run: | + dnf install -y \ + apache-commons-lang3 \ + autoconf \ + automake \ + gcc \ + git \ + jackson-annotations \ + jackson-core \ + jackson-databind \ + java-21-openjdk-devel \ + javapackages-tools \ + junit \ + make \ + maven \ + maven-local-openjdk21 \ + maven-source-plugin \ + mockito \ + rpm-build \ + slf4j \ + slf4j-jdk14 + + - name: Set build environment + run: | + TAG=$(git tag --points-at HEAD | head -1) + if [[ -n "$TAG" ]]; then + if [[ "$TAG" =~ -([0-9]+)$ ]]; then + echo "PACKAGE_RPM_RELEASE=${BASH_REMATCH[1]}" >> $GITHUB_ENV + else + echo "PACKAGE_RPM_RELEASE=1" >> $GITHUB_ENV + fi + else + echo "RELEASE_SUFFIX=.$(date --utc +%Y%m%d%H%M%S).git$(git rev-parse --short HEAD)" >> $GITHUB_ENV + fi + + - name: Autogen + run: ./autogen.sh + + - name: Configure + run: ./configure + + - name: Run tests + run: mvn test -P\!slow-tests-disabled + + - name: Build RPM + run: make -j rpm + + - name: Collect artifacts + run: | + mkdir -p exported-artifacts + find tmp.repos -iname \*rpm -exec mv "{}" exported-artifacts/ \; + mv ./*tar.gz exported-artifacts/ - - name: Perform build - run: | - .automation/build-rpm.sh $ARTIFACTS_DIR + - name: Upload artifacts + uses: actions/upload-artifact@v7 + with: + name: rpm-${{ matrix.shortcut }} + path: exported-artifacts - - name: Upload artifacts - uses: ovirt/upload-rpms-action@main - with: - directory: ${{ env.ARTIFACTS_DIR }} + publish-rpms: + permissions: + artifact-metadata: read + needs: build + if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} + uses: ovirt/ovirt-workflows/.github/workflows/publish-rpms.yml@main + secrets: inherit publish-snapshot: - needs: build-rpms + needs: build if: ${{ github.ref == 'refs/heads/master' }} runs-on: ubuntu-latest name: Publish snapshot to maven central @@ -72,13 +121,13 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Mark git repo as safe run: git config --global --add safe.directory $(pwd) - name: Use cache for maven - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.gitignore b/.gitignore index 15930d6..af698c2 100644 --- a/.gitignore +++ b/.gitignore @@ -34,5 +34,3 @@ pom.xml *.iws *.iml -# Not autogenerated! -\!.copr/Makefile diff --git a/Makefile.am b/Makefile.am index c782b52..bd2140f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,7 +19,27 @@ AUTOMAKE_OPTIONS = foreign 1.9 ACLOCAL_AMFLAGS = -I m4 +SHELL := /bin/bash +TMPREPOS = tmp.repos +RPMBUILD_ARGS := --define="_topdir `pwd`/$(TMPREPOS)" +RPMBUILD_ARGS += $(if $(RELEASE_SUFFIX), --define="release_suffix $(RELEASE_SUFFIX)") + +srpm: dist + rm -fr "$(TMPREPOS)" + mkdir -p $(TMPREPOS)/{SPECS,RPMS,SRPMS,SOURCES} + rpmbuild $(RPMBUILD_ARGS) -ts "$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.gz" + @echo + @echo "srpm available at '$(TMPREPOS)'" + @echo + +rpm: srpm + rpmbuild $(RPMBUILD_ARGS) --rebuild "$(TMPREPOS)"/SRPMS/*.src.rpm + @echo + @echo "rpm(s) available at '$(TMPREPOS)'" + @echo + +.PHONY: srpm rpm MAINTAINERCLEANFILES = \ config.log config.status \ $(srcdir)/Makefile.in \ @@ -46,7 +66,7 @@ dist_noinst_DATA = \ $(NULL) clean-local: - rm -fr target + rm -fr target tmp.repos if !WITH_DIST_ONLY $(MVN) clean endif diff --git a/README.md b/README.md index 781b633..8646f39 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # JSON RPC Java client (vdsm-jsonrpc-java) for oVirt -[![Copr build status](https://copr.fedorainfracloud.org/coprs/ovirt/ovirt-master-snapshot/package/vdsm-jsonrpc-java/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/ovirt/ovirt-master-snapshot/package/vdsm-jsonrpc-java/) [![Maven Central](https://img.shields.io/maven-central/v/org.ovirt.vdsm-jsonrpc-java/vdsm-jsonrpc-java-client.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/org.ovirt.vdsm-jsonrpc-java/vdsm-jsonrpc-java-client) Welcome to the vdsm-jsonrpc-java source repository. diff --git a/configure.ac b/configure.ac index 539e3a4..bf69377 100644 --- a/configure.ac +++ b/configure.ac @@ -23,11 +23,13 @@ define([VERSION_MAJOR], [1]) define([VERSION_MINOR], [7]) define([VERSION_FIX], [5]) define([VERSION_NUMBER], VERSION_MAJOR[.]VERSION_MINOR[.]VERSION_FIX) -define([VERSION_SUFFIX], []) -AC_INIT([vdsm-jsonrpc-java], VERSION_NUMBER[]VERSION_SUFFIX) +AC_INIT([vdsm-jsonrpc-java], VERSION_NUMBER) PACKAGE_RPM_VERSION="VERSION_NUMBER" -PACKAGE_RPM_RELEASE="0" +AC_ARG_VAR([PACKAGE_RPM_RELEASE], + [RPM release field (default: 0.master for development, release number for release builds)]) +AS_IF([test -z "$PACKAGE_RPM_RELEASE"], + [PACKAGE_RPM_RELEASE="0.master"]) PACKAGE_MAVEN_VERSION="VERSION_MAJOR.VERSION_MINOR.VERSION_FIX" AC_SUBST([PACKAGE_RPM_VERSION]) AC_SUBST([PACKAGE_RPM_RELEASE]) From 6fbcca30f21280a5cba26e2a95b893760e56ed2c Mon Sep 17 00:00:00 2001 From: Jean-Louis Dupond Date: Fri, 17 Jul 2026 14:02:05 +0200 Subject: [PATCH 3/5] client: Add SO_REUSEADDR Add SO_REUSEADDR to the server and client socket, so we can reuse ports in TIME_WAIT state. Signed-off-by: Jean-Louis Dupond --- .../ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java | 3 +++ .../ovirt/vdsm/jsonrpc/client/reactors/ReactorTestCase.java | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/src/main/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java b/client/src/main/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java index d83704a..b79f448 100644 --- a/client/src/main/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java +++ b/client/src/main/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.net.InetSocketAddress; +import java.net.StandardSocketOptions; import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; @@ -45,6 +46,7 @@ private ServerSocketChannel setupChannel(InetSocketAddress address) serverSocketChannel.configureBlocking(false); try { + serverSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true); serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT, this); log.debug("Binding to {}", address); serverSocketChannel.bind(address); @@ -77,6 +79,7 @@ public ReactorClient accept() { return null; } conn.configureBlocking(false); + conn.setOption(StandardSocketOptions.SO_REUSEADDR, true); InetSocketAddress address = (InetSocketAddress) conn.getRemoteAddress(); client = this.reactor.createConnectedClient(this.reactor, diff --git a/client/src/test/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorTestCase.java b/client/src/test/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorTestCase.java index 6ecf597..05e19fa 100644 --- a/client/src/test/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorTestCase.java +++ b/client/src/test/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorTestCase.java @@ -118,10 +118,6 @@ public void testNotConnectedRetry() throws InterruptedException, TimeoutExceptio assertTrue(closeTask.isDone()); futureListener = this.reactorForListener.createListener(HOSTNAME, - //fixme this port is occasionally not free. Most likely it is because of combination of - // 1. its state in TIME_WAIT where it enters after listener.close() - // 2. and delayed TCP packets(fragments) more details at [1] - // [1] https://vincent.bernat.ch/en/blog/2014-tcp-time-wait-state-linux port, _client -> _client.addEventListener(_client::sendMessage)); From cf479f76ae1cfcbefc42ac065917b534d1f08895 Mon Sep 17 00:00:00 2001 From: Jean-Louis Dupond Date: Mon, 24 Aug 2026 11:09:34 +0200 Subject: [PATCH 4/5] test: fix race condition Join the generator thread in order to make sure it fully finished before trying to read the values from it. Signed-off-by: Jean-Louis Dupond --- .../vdsm/jsonrpc/client/events/EventsThroughputTestCase.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/test/java/org/ovirt/vdsm/jsonrpc/client/events/EventsThroughputTestCase.java b/client/src/test/java/org/ovirt/vdsm/jsonrpc/client/events/EventsThroughputTestCase.java index ee3ff6c..375d8d5 100644 --- a/client/src/test/java/org/ovirt/vdsm/jsonrpc/client/events/EventsThroughputTestCase.java +++ b/client/src/test/java/org/ovirt/vdsm/jsonrpc/client/events/EventsThroughputTestCase.java @@ -71,6 +71,10 @@ public void testThroughput() { Thread generator = new Thread(gen); generator.start(); gen.stop(TIMEOUT); + try { + generator.join(); + } catch (InterruptedException ignored) { + } unsubscribe(); } System.out.println("Min value " + Collections.min(this.result)); From a34a7d8eca1261c4458023047270ddde2bb573e8 Mon Sep 17 00:00:00 2001 From: Jean-Louis Dupond Date: Mon, 24 Aug 2026 14:03:05 +0200 Subject: [PATCH 5/5] client: run selectNow in order to flush the reactor When running the ServerSockerChannel with a Selector, the close() call doesn't directly close the socket. This only happens after we trigger the socket again. So call selectNow() in order to really close the socket so we can rebind it. See https://bugs.openjdk.org/browse/JDK-5073504 Signed-off-by: Jean-Louis Dupond --- .../ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/src/main/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java b/client/src/main/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java index b79f448..fe7557c 100644 --- a/client/src/main/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java +++ b/client/src/main/java/org/ovirt/vdsm/jsonrpc/client/reactors/ReactorListener.java @@ -99,6 +99,12 @@ public Future close() { } catch (IOException e) { // Ignore } + // flush the cancelled key so the OS port is released before the next bind + try { + selector.selectNow(); + } catch (IOException e) { + // Ignore + } return null; }); this.reactor.queueFuture(task);