diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4e8f60f..50a3471 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -53,6 +53,7 @@ website_job: - website variables: NAME: ubuntu-2204 + TARGET_BASE_IMAGE: docker.io/library/ubuntu:22.04 pages: stage: pages diff --git a/ci/buildenv/almalinux-10.sh b/ci/buildenv/almalinux-10.sh new file mode 100644 index 0000000..38b5861 --- /dev/null +++ b/ci/buildenv/almalinux-10.sh @@ -0,0 +1,28 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + dnf update -y + dnf install 'dnf-command(config-manager)' -y + dnf config-manager --set-enabled -y crb + dnf install -y epel-release + dnf install almalinux-release-devel -y + dnf config-manager --set-enabled -y devel + dnf install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-21-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build + rpm -qa | sort > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/almalinux-9.sh b/ci/buildenv/almalinux-9.sh new file mode 100644 index 0000000..38b5861 --- /dev/null +++ b/ci/buildenv/almalinux-9.sh @@ -0,0 +1,28 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + dnf update -y + dnf install 'dnf-command(config-manager)' -y + dnf config-manager --set-enabled -y crb + dnf install -y epel-release + dnf install almalinux-release-devel -y + dnf config-manager --set-enabled -y devel + dnf install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-21-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build + rpm -qa | sort > /packages.txt +} + +export LANG="en_US.UTF-8" diff --git a/ci/buildenv/almalinux-8.sh b/ci/buildenv/centos-stream-10.sh similarity index 73% rename from ci/buildenv/almalinux-8.sh rename to ci/buildenv/centos-stream-10.sh index 4478e4f..4ab6f19 100644 --- a/ci/buildenv/almalinux-8.sh +++ b/ci/buildenv/centos-stream-10.sh @@ -5,18 +5,19 @@ # https://gitlab.com/libvirt/libvirt-ci function install_buildenv() { - dnf update -y + dnf distro-sync -y dnf install 'dnf-command(config-manager)' -y - dnf config-manager --set-enabled -y powertools - dnf install -y centos-release-advanced-virtualization + dnf config-manager --set-enabled -y crb dnf install -y epel-release dnf install -y \ ant \ + ant-junit \ ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ + junit \ libvirt-devel \ rpm-build rpm -qa | sort > /packages.txt diff --git a/ci/buildenv/centos-stream-8.sh b/ci/buildenv/centos-stream-9.sh similarity index 77% rename from ci/buildenv/centos-stream-8.sh rename to ci/buildenv/centos-stream-9.sh index a78bbc6..66904b2 100644 --- a/ci/buildenv/centos-stream-8.sh +++ b/ci/buildenv/centos-stream-9.sh @@ -7,17 +7,18 @@ function install_buildenv() { dnf distro-sync -y dnf install 'dnf-command(config-manager)' -y - dnf config-manager --set-enabled -y powertools - dnf install -y centos-release-advanced-virtualization + dnf config-manager --set-enabled -y crb dnf install -y epel-release dnf install -y epel-next-release dnf install -y \ ant \ + ant-junit \ ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ + junit \ libvirt-devel \ rpm-build rpm -qa | sort > /packages.txt diff --git a/ci/buildenv/debian-11.sh b/ci/buildenv/debian-12.sh similarity index 100% rename from ci/buildenv/debian-11.sh rename to ci/buildenv/debian-12.sh diff --git a/ci/buildenv/ubuntu-2004.sh b/ci/buildenv/debian-13.sh similarity index 94% rename from ci/buildenv/ubuntu-2004.sh rename to ci/buildenv/debian-13.sh index d2f6a77..b294b6d 100644 --- a/ci/buildenv/ubuntu-2004.sh +++ b/ci/buildenv/debian-13.sh @@ -17,7 +17,7 @@ function install_buildenv() { libjna-java \ libvirt-dev \ locales \ - openjdk-17-jdk-headless + openjdk-21-jdk-headless sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen dpkg-reconfigure locales dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt diff --git a/ci/buildenv/debian-sid.sh b/ci/buildenv/debian-sid.sh index d2f6a77..b294b6d 100644 --- a/ci/buildenv/debian-sid.sh +++ b/ci/buildenv/debian-sid.sh @@ -17,7 +17,7 @@ function install_buildenv() { libjna-java \ libvirt-dev \ locales \ - openjdk-17-jdk-headless + openjdk-21-jdk-headless sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen dpkg-reconfigure locales dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt diff --git a/ci/buildenv/fedora-38.sh b/ci/buildenv/fedora-42.sh similarity index 92% rename from ci/buildenv/fedora-38.sh rename to ci/buildenv/fedora-42.sh index 46b5102..70ab49a 100644 --- a/ci/buildenv/fedora-38.sh +++ b/ci/buildenv/fedora-42.sh @@ -12,7 +12,7 @@ function install_buildenv() { ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ diff --git a/ci/buildenv/fedora-39.sh b/ci/buildenv/fedora-43.sh similarity index 92% rename from ci/buildenv/fedora-39.sh rename to ci/buildenv/fedora-43.sh index 46b5102..70ab49a 100644 --- a/ci/buildenv/fedora-39.sh +++ b/ci/buildenv/fedora-43.sh @@ -12,7 +12,7 @@ function install_buildenv() { ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ diff --git a/ci/buildenv/fedora-rawhide.sh b/ci/buildenv/fedora-rawhide.sh index 1ba76e7..0e3c619 100644 --- a/ci/buildenv/fedora-rawhide.sh +++ b/ci/buildenv/fedora-rawhide.sh @@ -13,7 +13,7 @@ function install_buildenv() { ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ diff --git a/ci/buildenv/opensuse-leap-15.sh b/ci/buildenv/opensuse-leap-15.sh index e0a14fb..9cfdf13 100644 --- a/ci/buildenv/opensuse-leap-15.sh +++ b/ci/buildenv/opensuse-leap-15.sh @@ -6,13 +6,14 @@ function install_buildenv() { zypper update -y + zypper addrepo -fc https://download.opensuse.org/update/leap/15.6/backports/openSUSE:Backports:SLE-15-SP6:Update.repo zypper install -y \ ant \ ant-junit \ ca-certificates \ git \ glibc-locale \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ diff --git a/ci/buildenv/ubuntu-2204.sh b/ci/buildenv/ubuntu-2204.sh index a022f83..b294b6d 100644 --- a/ci/buildenv/ubuntu-2204.sh +++ b/ci/buildenv/ubuntu-2204.sh @@ -12,43 +12,15 @@ function install_buildenv() { ant \ ant-optional \ ca-certificates \ - ccache \ - cpp \ - gcc \ - gettext \ git \ junit \ - libc6-dev \ - libglib2.0-dev \ - libgnutls28-dev \ libjna-java \ - libnl-3-dev \ - libnl-route-3-dev \ - libtirpc-dev \ libvirt-dev \ - libxml2-dev \ - libxml2-utils \ locales \ - make \ - meson \ - ninja-build \ - openjdk-17-jdk-headless \ - perl-base \ - pkgconf \ - python3 \ - python3-docutils \ - xsltproc + openjdk-21-jdk-headless sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen dpkg-reconfigure locales - rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt - mkdir -p /usr/libexec/ccache-wrappers - ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc - ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc } -export CCACHE_WRAPPERSDIR="/usr/libexec/ccache-wrappers" export LANG="en_US.UTF-8" -export MAKE="/usr/bin/make" -export NINJA="/usr/bin/ninja" -export PYTHON="/usr/bin/python3" diff --git a/ci/buildenv/ubuntu-2404.sh b/ci/buildenv/ubuntu-2404.sh new file mode 100644 index 0000000..d2eb642 --- /dev/null +++ b/ci/buildenv/ubuntu-2404.sh @@ -0,0 +1,54 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +function install_buildenv() { + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get dist-upgrade -y + apt-get install --no-install-recommends -y \ + ant \ + ant-optional \ + ca-certificates \ + ccache \ + cpp \ + gcc \ + gettext \ + git \ + junit \ + libc6-dev \ + libglib2.0-dev \ + libgnutls28-dev \ + libjna-java \ + libnl-3-dev \ + libnl-route-3-dev \ + libtirpc-dev \ + libvirt-dev \ + libxml2-dev \ + libxml2-utils \ + locales \ + make \ + meson \ + ninja-build \ + openjdk-21-jdk-headless \ + perl-base \ + pkgconf \ + python3 \ + python3-docutils \ + xsltproc + sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen + dpkg-reconfigure locales + rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED + dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt + mkdir -p /usr/libexec/ccache-wrappers + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +} + +export CCACHE_WRAPPERSDIR="/usr/libexec/ccache-wrappers" +export LANG="en_US.UTF-8" +export MAKE="/usr/bin/make" +export NINJA="/usr/bin/ninja" +export PYTHON="/usr/bin/python3" diff --git a/ci/containers/almalinux-10.Dockerfile b/ci/containers/almalinux-10.Dockerfile new file mode 100644 index 0000000..4c138b6 --- /dev/null +++ b/ci/containers/almalinux-10.Dockerfile @@ -0,0 +1,30 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM docker.io/library/almalinux:10 + +RUN dnf update -y && \ + dnf install 'dnf-command(config-manager)' -y && \ + dnf config-manager --set-enabled -y crb && \ + dnf install -y epel-release && \ + dnf install almalinux-release-devel -y && \ + dnf config-manager --set-enabled -y devel && \ + dnf install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-21-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + dnf autoremove -y && \ + dnf clean all -y && \ + rpm -qa | sort > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/almalinux-9.Dockerfile b/ci/containers/almalinux-9.Dockerfile new file mode 100644 index 0000000..a7843d0 --- /dev/null +++ b/ci/containers/almalinux-9.Dockerfile @@ -0,0 +1,30 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM docker.io/library/almalinux:9 + +RUN dnf update -y && \ + dnf install 'dnf-command(config-manager)' -y && \ + dnf config-manager --set-enabled -y crb && \ + dnf install -y epel-release && \ + dnf install almalinux-release-devel -y && \ + dnf config-manager --set-enabled -y devel && \ + dnf install -y \ + ant \ + ant-junit \ + ca-certificates \ + git \ + glibc-langpack-en \ + java-21-openjdk-headless \ + jna \ + junit \ + libvirt-devel \ + rpm-build && \ + dnf autoremove -y && \ + dnf clean all -y && \ + rpm -qa | sort > /packages.txt + +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/almalinux-8.Dockerfile b/ci/containers/centos-stream-10.Dockerfile similarity index 66% rename from ci/containers/almalinux-8.Dockerfile rename to ci/containers/centos-stream-10.Dockerfile index 644e254..c4a9060 100644 --- a/ci/containers/almalinux-8.Dockerfile +++ b/ci/containers/centos-stream-10.Dockerfile @@ -4,24 +4,25 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM docker.io/library/almalinux:8 +FROM quay.io/centos/centos:stream10 -RUN dnf update -y && \ +RUN dnf distro-sync -y && \ dnf install 'dnf-command(config-manager)' -y && \ - dnf config-manager --set-enabled -y powertools && \ - dnf install -y centos-release-advanced-virtualization && \ + dnf config-manager --set-enabled -y crb && \ dnf install -y epel-release && \ dnf install -y \ ant \ + ant-junit \ ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ + junit \ libvirt-devel \ rpm-build && \ dnf autoremove -y && \ dnf clean all -y && \ rpm -qa | sort > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/centos-stream-8.Dockerfile b/ci/containers/centos-stream-9.Dockerfile similarity index 71% rename from ci/containers/centos-stream-8.Dockerfile rename to ci/containers/centos-stream-9.Dockerfile index 715f7c3..501aae6 100644 --- a/ci/containers/centos-stream-8.Dockerfile +++ b/ci/containers/centos-stream-9.Dockerfile @@ -4,25 +4,26 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM quay.io/centos/centos:stream8 +FROM quay.io/centos/centos:stream9 RUN dnf distro-sync -y && \ dnf install 'dnf-command(config-manager)' -y && \ - dnf config-manager --set-enabled -y powertools && \ - dnf install -y centos-release-advanced-virtualization && \ + dnf config-manager --set-enabled -y crb && \ dnf install -y epel-release && \ dnf install -y epel-next-release && \ dnf install -y \ ant \ + ant-junit \ ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ + junit \ libvirt-devel \ rpm-build && \ dnf autoremove -y && \ dnf clean all -y && \ rpm -qa | sort > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/ubuntu-2004.Dockerfile b/ci/containers/debian-12.Dockerfile similarity index 93% rename from ci/containers/ubuntu-2004.Dockerfile rename to ci/containers/debian-12.Dockerfile index 6a39f5e..c7477ab 100644 --- a/ci/containers/ubuntu-2004.Dockerfile +++ b/ci/containers/debian-12.Dockerfile @@ -4,7 +4,7 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM docker.io/library/ubuntu:20.04 +FROM docker.io/library/debian:12-slim RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ @@ -26,4 +26,4 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg-reconfigure locales && \ dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/debian-11.Dockerfile b/ci/containers/debian-13.Dockerfile similarity index 88% rename from ci/containers/debian-11.Dockerfile rename to ci/containers/debian-13.Dockerfile index ea3520b..f895a9b 100644 --- a/ci/containers/debian-11.Dockerfile +++ b/ci/containers/debian-13.Dockerfile @@ -4,7 +4,7 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM docker.io/library/debian:11-slim +FROM docker.io/library/debian:13-slim RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ @@ -19,11 +19,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libjna-java \ libvirt-dev \ locales \ - openjdk-17-jdk-headless && \ + openjdk-21-jdk-headless && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales && \ dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/debian-sid.Dockerfile b/ci/containers/debian-sid.Dockerfile index 03d2f57..9ec4042 100644 --- a/ci/containers/debian-sid.Dockerfile +++ b/ci/containers/debian-sid.Dockerfile @@ -19,11 +19,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libjna-java \ libvirt-dev \ locales \ - openjdk-17-jdk-headless && \ + openjdk-21-jdk-headless && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales && \ dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/fedora-38.Dockerfile b/ci/containers/fedora-42.Dockerfile similarity index 88% rename from ci/containers/fedora-38.Dockerfile rename to ci/containers/fedora-42.Dockerfile index c53703a..d19ea84 100644 --- a/ci/containers/fedora-38.Dockerfile +++ b/ci/containers/fedora-42.Dockerfile @@ -4,7 +4,7 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM registry.fedoraproject.org/fedora:38 +FROM registry.fedoraproject.org/fedora:42 RUN dnf install -y nosync && \ printf '#!/bin/sh\n\ @@ -23,7 +23,7 @@ exec "$@"\n' > /usr/bin/nosync && \ ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ @@ -32,4 +32,4 @@ exec "$@"\n' > /usr/bin/nosync && \ nosync dnf clean all -y && \ rpm -qa | sort > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/fedora-39.Dockerfile b/ci/containers/fedora-43.Dockerfile similarity index 88% rename from ci/containers/fedora-39.Dockerfile rename to ci/containers/fedora-43.Dockerfile index 9cb7d0b..1a32678 100644 --- a/ci/containers/fedora-39.Dockerfile +++ b/ci/containers/fedora-43.Dockerfile @@ -4,7 +4,7 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM registry.fedoraproject.org/fedora:39 +FROM registry.fedoraproject.org/fedora:43 RUN dnf install -y nosync && \ printf '#!/bin/sh\n\ @@ -23,7 +23,7 @@ exec "$@"\n' > /usr/bin/nosync && \ ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ @@ -32,4 +32,4 @@ exec "$@"\n' > /usr/bin/nosync && \ nosync dnf clean all -y && \ rpm -qa | sort > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/fedora-rawhide.Dockerfile b/ci/containers/fedora-rawhide.Dockerfile index 8fb86c0..1aa1d85 100644 --- a/ci/containers/fedora-rawhide.Dockerfile +++ b/ci/containers/fedora-rawhide.Dockerfile @@ -24,7 +24,7 @@ exec "$@"\n' > /usr/bin/nosync && \ ca-certificates \ git \ glibc-langpack-en \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ @@ -33,4 +33,4 @@ exec "$@"\n' > /usr/bin/nosync && \ nosync dnf clean all -y && \ rpm -qa | sort > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/opensuse-leap-15.Dockerfile b/ci/containers/opensuse-leap-15.Dockerfile index 263f09f..a5c2dd0 100644 --- a/ci/containers/opensuse-leap-15.Dockerfile +++ b/ci/containers/opensuse-leap-15.Dockerfile @@ -4,16 +4,17 @@ # # https://gitlab.com/libvirt/libvirt-ci -FROM registry.opensuse.org/opensuse/leap:15.5 +FROM registry.opensuse.org/opensuse/leap:15.6 RUN zypper update -y && \ + zypper addrepo -fc https://download.opensuse.org/update/leap/15.6/backports/openSUSE:Backports:SLE-15-SP6:Update.repo && \ zypper install -y \ ant \ ant-junit \ ca-certificates \ git \ glibc-locale \ - java-11-openjdk-headless \ + java-21-openjdk-headless \ jna \ junit \ libvirt-devel \ @@ -21,4 +22,4 @@ RUN zypper update -y && \ zypper clean --all && \ rpm -qa | sort > /packages.txt -ENV LANG "en_US.UTF-8" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/ubuntu-2204.Dockerfile b/ci/containers/ubuntu-2204.Dockerfile index 6390620..a6531cf 100644 --- a/ci/containers/ubuntu-2204.Dockerfile +++ b/ci/containers/ubuntu-2204.Dockerfile @@ -14,44 +14,16 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ ant \ ant-optional \ ca-certificates \ - ccache \ - cpp \ - gcc \ - gettext \ git \ junit \ - libc6-dev \ - libglib2.0-dev \ - libgnutls28-dev \ libjna-java \ - libnl-3-dev \ - libnl-route-3-dev \ - libtirpc-dev \ libvirt-dev \ - libxml2-dev \ - libxml2-utils \ locales \ - make \ - meson \ - ninja-build \ - openjdk-17-jdk-headless \ - perl-base \ - pkgconf \ - python3 \ - python3-docutils \ - xsltproc && \ + openjdk-21-jdk-headless && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales && \ - rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED && \ - dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \ - mkdir -p /usr/libexec/ccache-wrappers && \ - ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \ - ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc + dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" -ENV LANG "en_US.UTF-8" -ENV MAKE "/usr/bin/make" -ENV NINJA "/usr/bin/ninja" -ENV PYTHON "/usr/bin/python3" +ENV LANG="en_US.UTF-8" diff --git a/ci/containers/ubuntu-2404.Dockerfile b/ci/containers/ubuntu-2404.Dockerfile new file mode 100644 index 0000000..cbdb9a6 --- /dev/null +++ b/ci/containers/ubuntu-2404.Dockerfile @@ -0,0 +1,57 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool manifest ci/manifest.yml +# +# https://gitlab.com/libvirt/libvirt-ci + +FROM docker.io/library/ubuntu:24.04 + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ + ant \ + ant-optional \ + ca-certificates \ + ccache \ + cpp \ + gcc \ + gettext \ + git \ + junit \ + libc6-dev \ + libglib2.0-dev \ + libgnutls28-dev \ + libjna-java \ + libnl-3-dev \ + libnl-route-3-dev \ + libtirpc-dev \ + libvirt-dev \ + libxml2-dev \ + libxml2-utils \ + locales \ + make \ + meson \ + ninja-build \ + openjdk-21-jdk-headless \ + perl-base \ + pkgconf \ + python3 \ + python3-docutils \ + xsltproc && \ + eatmydata apt-get autoremove -y && \ + eatmydata apt-get autoclean -y && \ + sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ + dpkg-reconfigure locales && \ + rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED && \ + dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \ + mkdir -p /usr/libexec/ccache-wrappers && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc + +ENV CCACHE_WRAPPERSDIR="/usr/libexec/ccache-wrappers" +ENV LANG="en_US.UTF-8" +ENV MAKE="/usr/bin/make" +ENV NINJA="/usr/bin/ninja" +ENV PYTHON="/usr/bin/python3" diff --git a/ci/gitlab.yml b/ci/gitlab.yml index 7bb68b8..0e6de9f 100644 --- a/ci/gitlab.yml +++ b/ci/gitlab.yml @@ -11,8 +11,11 @@ # - RUN_PIPELINE - force creation of a CI pipeline when # pushing to a branch in a forked repository. Official # CI pipelines are triggered when merge requests are -# created/updated. Setting this variable to a non-empty -# value allows CI testing prior to opening a merge request. +# created/updated. Setting this variable allows CI +# testing prior to opening a merge request. A value +# of "0" will create the pipeline but leave all jobs +# to be manually started, while "1" will immediately +# run all default jobs. # # - RUN_PIPELINE_UPSTREAM_ENV - same semantics as RUN_PIPELINE, # but uses the CI environment (containers) from the upstream project @@ -38,11 +41,13 @@ # # Aliases can be set for common usage # -# $ git config --local alias.push-ci "push -o ci.variable=RUN_PIPELINE=1" +# $ git config --local alias.push-ci "push -o ci.variable=RUN_PIPELINE=0" +# $ git config --local alias.push-ci-now "push -o ci.variable=RUN_PIPELINE=1" # # Allowing the less verbose invocation # -# $ git push-ci +# $ git push-ci (create pipeline but don't start jobs) +# $ git push-ci-now (create pipeline and start default jobs) # # Pipeline variables can also be set in the repository # pipeline config globally, or set against scheduled pipelines @@ -50,6 +55,7 @@ variables: RUN_UPSTREAM_NAMESPACE: libvirt + CONTAINER_UPSTREAM_NAMESPACE: libvirt FF_SCRIPT_SECTIONS: 1 diff --git a/ci/gitlab/build-templates.yml b/ci/gitlab/build-templates.yml index fae09ac..1eb7ccf 100644 --- a/ci/gitlab/build-templates.yml +++ b/ci/gitlab/build-templates.yml @@ -35,7 +35,7 @@ fi - cat /packages.txt variables: - IMAGE: $CI_REGISTRY/$RUN_UPSTREAM_NAMESPACE/libvirt-java/ci-$NAME:latest + IMAGE: $CI_REGISTRY/$CONTAINER_UPSTREAM_NAMESPACE/libvirt-java/ci-$NAME:latest rules: ### PUSH events @@ -47,19 +47,27 @@ when: on_success # forks: pushes to a branch when a pipeline run in upstream env is explicitly requested - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV && $JOB_OPTIONAL' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV == "0"' when: manual allow_failure: true - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV == "1" && $JOB_OPTIONAL' + when: manual + allow_failure: true + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV == "1"' when: on_success # forks: pushes to branches with pipeline requested - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE && $JOB_OPTIONAL' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE == "0"' + when: manual + allow_failure: true + variables: + IMAGE: $TARGET_BASE_IMAGE + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE == "1" && $JOB_OPTIONAL' when: manual allow_failure: true variables: IMAGE: $TARGET_BASE_IMAGE - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE == "1"' when: on_success variables: IMAGE: $TARGET_BASE_IMAGE diff --git a/ci/gitlab/builds.yml b/ci/gitlab/builds.yml index bb513af..c911807 100644 --- a/ci/gitlab/builds.yml +++ b/ci/gitlab/builds.yml @@ -7,39 +7,74 @@ # Native build jobs -x86_64-almalinux-8: +x86_64-almalinux-9: extends: .native_build_job needs: - - job: x86_64-almalinux-8-container + - job: x86_64-almalinux-9-container optional: true allow_failure: false variables: - NAME: almalinux-8 - TARGET_BASE_IMAGE: docker.io/library/almalinux:8 + NAME: almalinux-9 + TARGET_BASE_IMAGE: docker.io/library/almalinux:9 TESTS: skip -x86_64-centos-stream-8: +x86_64-almalinux-10: extends: .native_build_job needs: - - job: x86_64-centos-stream-8-container + - job: x86_64-almalinux-10-container optional: true allow_failure: false variables: - NAME: centos-stream-8 - TARGET_BASE_IMAGE: quay.io/centos/centos:stream8 + NAME: almalinux-10 + TARGET_BASE_IMAGE: docker.io/library/almalinux:10 TESTS: skip -x86_64-debian-11: +x86_64-centos-stream-9: extends: .native_build_job needs: - - job: x86_64-debian-11-container + - job: x86_64-centos-stream-9-container optional: true allow_failure: false variables: - NAME: debian-11 - TARGET_BASE_IMAGE: docker.io/library/debian:11-slim + NAME: centos-stream-9 + TARGET_BASE_IMAGE: quay.io/centos/centos:stream9 + TESTS: skip + + +x86_64-centos-stream-10: + extends: .native_build_job + needs: + - job: x86_64-centos-stream-10-container + optional: true + allow_failure: false + variables: + NAME: centos-stream-10 + TARGET_BASE_IMAGE: quay.io/centos/centos:stream10 + TESTS: skip + + +x86_64-debian-12: + extends: .native_build_job + needs: + - job: x86_64-debian-12-container + optional: true + allow_failure: false + variables: + NAME: debian-12 + TARGET_BASE_IMAGE: docker.io/library/debian:12-slim + + +x86_64-debian-13: + extends: .native_build_job + needs: + - job: x86_64-debian-13-container + optional: true + allow_failure: false + variables: + NAME: debian-13 + TARGET_BASE_IMAGE: docker.io/library/debian:13-slim x86_64-debian-sid: @@ -47,32 +82,32 @@ x86_64-debian-sid: needs: - job: x86_64-debian-sid-container optional: true - allow_failure: false + allow_failure: true variables: NAME: debian-sid TARGET_BASE_IMAGE: docker.io/library/debian:sid-slim -x86_64-fedora-38: +x86_64-fedora-42: extends: .native_build_job needs: - - job: x86_64-fedora-38-container + - job: x86_64-fedora-42-container optional: true allow_failure: false variables: - NAME: fedora-38 - TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:38 + NAME: fedora-42 + TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:42 -x86_64-fedora-39: +x86_64-fedora-43: extends: .native_build_job needs: - - job: x86_64-fedora-39-container + - job: x86_64-fedora-43-container optional: true allow_failure: false variables: - NAME: fedora-39 - TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:39 + NAME: fedora-43 + TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:43 x86_64-fedora-rawhide: @@ -80,7 +115,7 @@ x86_64-fedora-rawhide: needs: - job: x86_64-fedora-rawhide-container optional: true - allow_failure: false + allow_failure: true variables: NAME: fedora-rawhide TARGET_BASE_IMAGE: registry.fedoraproject.org/fedora:rawhide @@ -94,37 +129,37 @@ x86_64-opensuse-leap-15: allow_failure: false variables: NAME: opensuse-leap-15 - TARGET_BASE_IMAGE: registry.opensuse.org/opensuse/leap:15.5 + TARGET_BASE_IMAGE: registry.opensuse.org/opensuse/leap:15.6 -x86_64-ubuntu-2004: +x86_64-ubuntu-2204: extends: .native_build_job needs: - - job: x86_64-ubuntu-2004-container + - job: x86_64-ubuntu-2204-container optional: true allow_failure: false variables: - NAME: ubuntu-2004 - TARGET_BASE_IMAGE: docker.io/library/ubuntu:20.04 + NAME: ubuntu-2204 + TARGET_BASE_IMAGE: docker.io/library/ubuntu:22.04 -x86_64-ubuntu-2204: +x86_64-ubuntu-2404: extends: .native_build_job needs: - - job: x86_64-ubuntu-2204-container + - job: x86_64-ubuntu-2404-container optional: true allow_failure: false variables: - NAME: ubuntu-2204 - TARGET_BASE_IMAGE: docker.io/library/ubuntu:22.04 + NAME: ubuntu-2404 + TARGET_BASE_IMAGE: docker.io/library/ubuntu:24.04 -x86_64-ubuntu-2204-git: +x86_64-ubuntu-2404-git: extends: .native_git_build_job needs: - - job: x86_64-ubuntu-2204-container + - job: x86_64-ubuntu-2404-container optional: true allow_failure: false variables: - NAME: ubuntu-2204 - TARGET_BASE_IMAGE: docker.io/library/ubuntu:22.04 + NAME: ubuntu-2404 + TARGET_BASE_IMAGE: docker.io/library/ubuntu:24.04 diff --git a/ci/gitlab/containers.yml b/ci/gitlab/containers.yml index d58bdc6..90693fa 100644 --- a/ci/gitlab/containers.yml +++ b/ci/gitlab/containers.yml @@ -7,51 +7,72 @@ # Native container jobs -x86_64-almalinux-8-container: +x86_64-almalinux-9-container: extends: .container_job allow_failure: false variables: - NAME: almalinux-8 + NAME: almalinux-9 -x86_64-centos-stream-8-container: +x86_64-almalinux-10-container: extends: .container_job allow_failure: false variables: - NAME: centos-stream-8 + NAME: almalinux-10 -x86_64-debian-11-container: +x86_64-centos-stream-9-container: extends: .container_job allow_failure: false variables: - NAME: debian-11 + NAME: centos-stream-9 -x86_64-debian-sid-container: +x86_64-centos-stream-10-container: + extends: .container_job + allow_failure: false + variables: + NAME: centos-stream-10 + + +x86_64-debian-12-container: + extends: .container_job + allow_failure: false + variables: + NAME: debian-12 + + +x86_64-debian-13-container: extends: .container_job allow_failure: false + variables: + NAME: debian-13 + + +x86_64-debian-sid-container: + extends: .container_job + allow_failure: true variables: NAME: debian-sid -x86_64-fedora-38-container: +x86_64-fedora-42-container: extends: .container_job allow_failure: false variables: - NAME: fedora-38 + NAME: fedora-42 -x86_64-fedora-39-container: +x86_64-fedora-43-container: extends: .container_job allow_failure: false variables: - NAME: fedora-39 + NAME: fedora-43 x86_64-fedora-rawhide-container: extends: .container_job - allow_failure: false + allow_failure: true variables: NAME: fedora-rawhide @@ -63,15 +84,15 @@ x86_64-opensuse-leap-15-container: NAME: opensuse-leap-15 -x86_64-ubuntu-2004-container: +x86_64-ubuntu-2204-container: extends: .container_job allow_failure: false variables: - NAME: ubuntu-2004 + NAME: ubuntu-2204 -x86_64-ubuntu-2204-container: +x86_64-ubuntu-2404-container: extends: .container_job allow_failure: false variables: - NAME: ubuntu-2204 + NAME: ubuntu-2404 diff --git a/ci/gitlab/sanity-checks.yml b/ci/gitlab/sanity-checks.yml index d2b1768..b568015 100644 --- a/ci/gitlab/sanity-checks.yml +++ b/ci/gitlab/sanity-checks.yml @@ -18,9 +18,13 @@ check-dco: when: on_success # forks: pushes to branches with pipeline requested (including upstream env pipelines) - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE == "0"' + when: manual + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE == "1"' when: on_success - - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE_UPSTREAM_ENV' + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE_UPSTREAM_ENV == "0"' + when: manual + - if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $RUN_PIPELINE_UPSTREAM_ENV == "1"' when: on_success # upstream+forks: that's all folks diff --git a/ci/manifest.yml b/ci/manifest.yml index 098263a..4243abc 100644 --- a/ci/manifest.yml +++ b/ci/manifest.yml @@ -1,43 +1,57 @@ projects: - libvirt-java - - libvirt+dist + - https://gitlab.com/libvirt/libvirt/-/raw/master/ci/lcitool/projects/libvirt+dist.yml gitlab: namespace: libvirt project: libvirt-java targets: - almalinux-8: + almalinux-9: jobs: - arch: x86_64 variables: TESTS: skip - centos-stream-8: + almalinux-10: jobs: - arch: x86_64 variables: TESTS: skip - debian-11: x86_64 + centos-stream-9: + jobs: + - arch: x86_64 + variables: + TESTS: skip + + centos-stream-10: + jobs: + - arch: x86_64 + variables: + TESTS: skip + + debian-12: x86_64 + + debian-13: x86_64 debian-sid: x86_64 - fedora-38: x86_64 + fedora-42: x86_64 - fedora-39: x86_64 + fedora-43: x86_64 fedora-rawhide: x86_64 opensuse-leap-15: x86_64 - ubuntu-2004: x86_64 + ubuntu-2204: x86_64 - ubuntu-2204: + ubuntu-2404: projects: - libvirt-java - - libvirt+dist - - libvirt+minimal + - https://gitlab.com/libvirt/libvirt/-/raw/master/ci/lcitool/projects/libvirt+minimal.yml + - https://gitlab.com/libvirt/libvirt/-/raw/master/ci/lcitool/projects/libvirt+dist.yml jobs: - arch: x86_64 diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index 28f7a6c..57727b4 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -18,6 +18,7 @@ import static org.libvirt.BitFlagsHelper.OR; import com.sun.jna.Memory; +import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.LongByReference; @@ -1499,17 +1500,14 @@ public Domain[] listAllDomains(int flags) throws LibvirtException { DomainByReference domainByReference = new DomainByReference(); int domainsCount = processError(libvirt.virConnectListAllDomains(vcp, domainByReference, flags)); - Pointer[] pointerArray = domainByReference.getValue().getPointerArray(0, domainsCount); - if (domainsCount > 0) { - Domain[] domains = new Domain[domainsCount]; - for (int i = 0; i < domainsCount; i++) { - domains[i] = new Domain(this, new DomainPointer(pointerArray[i])); - } - - return domains; + Pointer pointer = domainByReference.getValue(); + Domain[] domains = new Domain[domainsCount]; + for (int i = 0; i < domainsCount; i++) { + domains[i] = new Domain(this, new DomainPointer(pointer.getPointer(i * Native.POINTER_SIZE))); } + Library.free(pointer); - return new Domain[]{}; + return domains; } /** diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index 72a9225..4acd6fe 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -16,6 +16,7 @@ import org.libvirt.event.RebootListener; import org.libvirt.jna.CString; import org.libvirt.jna.CStringByReference; +import org.libvirt.jna.DomainCheckpointPointer; import org.libvirt.jna.DomainPointer; import org.libvirt.jna.DomainSnapshotPointer; import org.libvirt.jna.Libvirt; @@ -57,6 +58,132 @@ private static int bit(final int i) { * TODO: get generated constants from libvirt */ + public static final class JobOperation { + /** + * @see + * Libvirt Documentation + */ + public static final int UNKNOWN = 0; + /** + * @see + * Libvirt Documentation + */ + public static final int START = 1; + + /** + * @see + * Libvirt Documentation + */ + public static final int SAVE = 2; + /** + * @see + * Libvirt Documentation + */ + public static final int RESTORE = 3; + + /** + * @see + * Libvirt Documentation + */ + public static final int MIGRATION_IN = 4; + + /** + * @see + * Libvirt Documentation + */ + public static final int MIGRATION_OUT = 5; + /** + * @see + * Libvirt Documentation + */ + public static final int SNAPSHOT = 6; + + /** + * @see + * Libvirt Documentation + */ + public static final int SNAPSHOT_REVERT = 7; + + /** + * @see + * Libvirt Documentation + */ + public static final int DUMP = 8; + + /** + * @see + * Libvirt Documentation + */ + public static final int BACKUP = 9; + + /** + * @see + * Libvirt Documentation + */ + public static final int SNAPSHOT_DELETE = 10; + /** + * @see + * Libvirt Documentation + */ + public static final int LAST = 11; + } + + public static final class BlockJobType { + /** + * Placeholder + * + * @see + * Libvirt Documentation + */ + public static int UNKNOWN = 0; + + /** + * Block Pull (virDomainBlockPull, or virDomainBlockRebase without flags), job ends on completion + * + * @see + * Libvirt Documentation + */ + public static int PULL = 1; + + /** + * Block Copy (virDomainBlockCopy, or virDomainBlockRebase with flags), job exists as long as mirroring is active + * + * @see + * Libvirt Documentation + */ + public static int COPY = 2; + + /** + * Block Commit (virDomainBlockCommit without flags), job ends on completion + * + * @see + * Libvirt Documentation + */ + public static int COMMIT = 3; + + /** + * Active Block Commit (virDomainBlockCommit with flags), job exists as long as sync is active + * + * @see + * Libvirt Documentation + */ + public static int ACTIVE_COMMIT = 4; + + /** + * Backup (virDomainBackupBegin) + * + * @see + * Libvirt Documentation + */ + public static int BACKUP = 5; + + /** + * @see + * Libvirt Documentation + */ + public static int LAST = 6; + } + public static final class BlockCommitFlags { /** NULL base means next backing file, not whole chain */ public static int SHALLOW = bit(0); @@ -123,7 +250,7 @@ public static final class BlockCopyParameters { /** * Contains multiple constants that defines "virDomainMigrate* params" multiple field. * @see Libvirt domain documentation., and - * libvirt-domain.h. + * libvirt-domain.h */ public static final class DomainMigrateParameters { /** @@ -339,6 +466,31 @@ public static final class BlockResizeFlags { public static final int BYTES = 1; } + public static final class JobType { + /** No job is active **/ + public static int NONE = bit(0); + + /** Job with a finite completion time **/ + public static int BOUNDED = bit(1); + + /** Job without a finite completion time **/ + public static int UNBOUNDED = bit(2); + + /** Job has finished, but isn't cleaned up **/ + public static int COMPLETED = bit(3); + + /** Job hit error, but isn't cleaned up **/ + public static int FAILED = bit(4); + + /** Job was aborted, but isn't cleaned up **/ + public static int CANCELLED = bit(5); + } + + public static final class GetJobStatsFlags { + public static int COMPLETED = bit(0); + public static int KEEP_COMPLETED = bit(1); + } + public static final class CreateFlags { /** Default behavior */ public static final int NONE = 0; @@ -496,6 +648,101 @@ public static final class RebootFlags { public static final int PARAVIRT = bit(4); } + public static final class DomainBackupBeginFlags { + /** + * reuse separately provided images + * + * @see + * Libvirt Documentation + */ + public static final int REUSE_EXTERNAL = bit(0); + } + + public static final class DomainGetJobStatsFlags { + /** + * return stats of a recently completed job + * + * @see + * Libvirt Documentation + */ + public static final int COMPLETED = bit(0); + + /** + * don't remove completed stats when reading them + * + * @see + * Libvirt Documentation + */ + public static final int KEEP_COMPLETED = bit(1); + } + + public static final class CheckpointCreateFlags { + + /** Restore or alter metadata (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int REDEFINE = bit(0); + + /** use guest agent to quiesce all mounted file + * systems within the domain (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int QUIESCE = bit(1); + + /** validate disk data state when redefining + * a checkpoint (Since: 6.10.0) + * + * @see + * Libvirt Documentation + */ + public static final int REDEFINE_VALIDATE = bit(2); + } + + public static final class CheckpointListFlags { + + /** List all descendants, not just children, when + * listing a checkpoint (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int DESCENDANTS = bit(0); + + /** Filter by checkpoints with no parents, when + * listing a domain (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int ROOTS = bit(0); + + /** Ensure parents occur before children in + * the resulting list (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int TOPOLOGICAL = bit(1); + + /** Filter by checkpoints with no children (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int LEAVES = bit(2); + + /** Filter by checkpoints that have children (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int NO_LEAVES = bit(3); + } + public static final class SnapshotCreateFlags { /** Restore or alter metadata */ @@ -752,6 +999,35 @@ public void attachDeviceFlags(final String xmlDesc, final int flags) processError(libvirt.virDomainAttachDeviceFlags(vdp, xmlDesc, flags)); } + /** + * Start a point-in-time backup job for the specified disks of a running domain. + * + * @see + * Libvirt Documentation + * @param backupXML contains details about the backup in the top-level element + * @param checkpointXML description of a checkpoint to create or null + * @param flags the an OR'ed set of {@link DomainBackupBeginFlags} + * @throws LibvirtException + */ + public void backupBegin(final String backupXML, final String checkpointXML, int flags) + throws LibvirtException { + processError(libvirt.virDomainBackupBegin(vdp, backupXML, checkpointXML, flags)); + } + + /** + * Queries the configuration of the active backup job. + * @see + Libvirt Documentation + * @param flags extra flags; not used yet, so callers should always pass 0 + * @returnthe XML document + * @throws LibvirtException + */ + public String getBackupXMLDesc(final int flags) throws LibvirtException { + CString result = libvirt.virDomainBackupGetXMLDesc(vdp, flags); + processError(result); + return result.toString(); + } + /** * This function migrates domain's live block device (disk) to another * block device. @@ -1092,7 +1368,7 @@ public DomainInfo getInfo() throws LibvirtException { * @see Libvirt * Documentation - * @return a DomainJobInfo object describing this domain + * @return a DomainJobInfo object * @throws LibvirtException */ public DomainJobInfo getJobInfo() throws LibvirtException { @@ -1101,6 +1377,29 @@ public DomainJobInfo getJobInfo() throws LibvirtException { return new DomainJobInfo(vInfo); } + /** + * Extract information about progress of a background job on a domain. Will + * return an error if the domain is not active. + * + * @see Libvirt + * Documentation + * @param flags + * flags + * @return a DomainJobStats object + * @throws LibvirtException + */ + public DomainJobStats getJobStats(final int flags) throws LibvirtException { + IntByReference type = new IntByReference(); + PointerByReference params = new PointerByReference(); + IntByReference nParams = new IntByReference(); + + processError(libvirt.virDomainGetJobStats(vdp, type, params, nParams, flags)); + + TypedParameter[] stats = TypedParameter.fromPointer(params.getValue(), nParams.getValue()); + return new DomainJobStats(type.getValue(), stats); + } + /** * Retrieve the maximum amount of physical memory allocated to a domain. * @@ -1504,6 +1803,28 @@ public void memoryPeek(final long start, final ByteBuffer buffer, assert buffer.position() == buffer.limit(); } + /** + * This function provides cpu statistics for the domain. + * + * @param start_cpu + * which cpu to start with, or -1 for summary + * @param ncpus + * how many cpus to query + * @return the collection of stats + * @throws LibvirtException + */ + public TypedParameter[] getCPUStats(final int start_cpu, final int ncpus) + throws LibvirtException { + int number = processError(libvirt.virDomainGetCPUStats(vdp, null, 0, start_cpu, ncpus, 0)); + virTypedParameter[] params = new virTypedParameter[number]; + int result = processError(libvirt.virDomainGetCPUStats(vdp, params, number, start_cpu, ncpus, 0)); + TypedParameter[] returnStats = new TypedParameter[result]; + for (int x = 0; x < result; x++) { + returnStats[x] = TypedParameter.create(params[x]); + } + return returnStats; + } + /** * This function provides memory statistics for the domain. * @@ -1671,6 +1992,11 @@ public Domain migrate(final Connect dconn, final long flags, * after the returned domain object is no longer needed. *

* For more informations, please @see virDomainMigrate3 + * + * @deprecated + * use {@link migrate(Connect, TypedParameter[], int) + * migrate(Connect, TypedParameter[], int)} + * instaed * @param dconn * destination host (a Connect object) * @param params @@ -1684,10 +2010,52 @@ public Domain migrate(final Connect dconn, final long flags, * connection (dconn). * @throws LibvirtException */ + @Deprecated public Domain migrate(final Connect dconn, final TypedParameter[] params, long flags) throws LibvirtException { assert params != null : "migrate Typed parameters cannot be null"; virTypedParameter[] virTypedParameters = generateNativeVirTypedParameters(params); - DomainPointer newPtr = processError(libvirt.virDomainMigrate3(vdp, dconn.vcp, virTypedParameters, params.length, new NativeLong(flags))); + DomainPointer newPtr = processError(libvirt.virDomainMigrate3(vdp, dconn.vcp, virTypedParameters, params.length, (int)flags)); + return new Domain(dconn, newPtr); + } + + /** + * Migrate the domain object from its current host to the destination host + * given by {@code dconn} (a connection to the destination host). + *

See {@link DomainMigrateParameters DomainMigrateParameters} for + * detailed description of individual {@code params}. + *

See {@link MigrateFlags MigrateFlags} documentation for description + * of individual {@code flags}. {@link MigrateFlags#TUNNELED TUNNELED} + * and {@link MigrateFlags#PEER2PEER PEER2PEER} are not supported by this + * API, use {@link migrateToURI(String, TypedParameter[], int) + * migrateToURI(String, TypedParameter[], int)} instead. + *

There are many limitations on migration imposed by the underlying + * technology - for example it may not be possible to migrate between + * different processors even with the same architecture, or between different + * types of hypervisor. + *

{@link free} should be used to free the resources + * after the returned domain object is no longer needed. + * + * @see + * virDomainMigrate3 + * + * @param dconn + * destination host (a Connect object) + * @param params + * (optional) migration parameters + * + * @param flags + * bitwise-OR of {@link MigrateFlags MigrateFlags} + * @return + * the new domain object if the migration was successful. Note that + * the new domain object exists in the scope of the destination + * connection ({@code dconn}). + * @throws LibvirtException on failure + */ + public Domain migrate(final Connect dconn, final TypedParameter[] params, int flags) throws LibvirtException { + assert params != null : "migrate Typed parameters cannot be null"; + virTypedParameter[] virTypedParameters = generateNativeVirTypedParameters(params); + DomainPointer newPtr = processError(libvirt.virDomainMigrate3(vdp, dconn.vcp, virTypedParameters, params.length, flags)); return new Domain(dconn, newPtr); } @@ -1735,6 +2103,41 @@ public int migrateSetMaxDowntime(final long downtime) return processError(libvirt.virDomainMigrateSetMaxDowntime(vdp, downtime, 0)); } + /** + * Migrate the domain object from its current host to the destination + * denoted by a given URI. + *

+ * The destination is given either in dconnuri (if the + * {@link MigrateFlags#PEER2PEER PEER2PEER} + * is flag set), or in miguri (if neither the + * {@link MigrateFlags#PEER2PEER PEER2PEER} nor the + * {@link MigrateFlags#TUNNELED TUNNELED} migration + * flag is set in flags). + * + * @see + * virDomainMigrateToURI + * + * @param dconnuri + * (optional) URI for target libvirtd if @flags includes PEER2PEER + * @param params + * (optional) Migration parameters + * @param flags + * Controls the migrate + * @return 0 if successful + * @throws LibvirtException + */ + public int migrateToURI(final String dconnuri, + final TypedParameter[] params, + final int flags) + throws LibvirtException { + assert params != null : "migrate Typed parameters cannot be null"; + virTypedParameter[] input = generateNativeVirTypedParameters(params); + return processError(libvirt.virDomainMigrateToURI3(vdp, dconnuri, + input, input.length, + flags)); + } + /** * Migrate the domain object from its current host to the destination * denoted by a given URI. @@ -2196,6 +2599,141 @@ public void shutdown() throws LibvirtException { processError(libvirt.virDomainShutdown(vdp)); } + /** + * Creates a new checkpoint of a domain based on the checkpoint xml contained in + * xmlDesc. + * + * @see Libvirt + * Documentation + * @param xmlDesc + * string containing an XML description of the checkpoint + * @param flags + * flags for creating the checkpoint, see the {@link CheckpointCreateFlags} for the flag options + * @return the checkpoint + * @throws LibvirtException + */ + public DomainCheckpoint checkpointCreateXML(final String xmlDesc, final int flags) + throws LibvirtException { + DomainCheckpointPointer ptr = processError(libvirt.virDomainCheckpointCreateXML(vdp, xmlDesc, flags)); + return new DomainCheckpoint(virConnect, ptr); + } + + /** + * Creates a new checkpoint of a domain based on the checkpoint xml contained in + * xmlDesc. + *

+ * This is just a convenience method, it has the same effect + * as calling {@code checkpointCreateXML(xmlDesc, 0);}. + * + * @see #checkpointCreateXML(String, int) + * @see Libvirt + * Documentation + * @param xmlDesc + * string containing an XML description of the checkpoint + * @return the checkpoint, or null on Error + * @throws LibvirtException + */ + public DomainCheckpoint checkpointCreateXML(final String xmlDesc) + throws LibvirtException { + return checkpointCreateXML(xmlDesc, 0); + } + + /** + * Array of domain checkpoints for the given domain. + * + * @see Libvirt + * Documentation + * + * @param flags + * flags for list the checkpoint, see the {@link CheckpointListFlags} for the flag options + * @return Array with domain checkpoints of the given domain + * @throws LibvirtException + */ + public DomainCheckpoint[] listAllCheckpoints(int flags) throws LibvirtException { + PointerByReference checkpoints = new PointerByReference(); + int count = libvirt.virDomainListAllCheckpoints(vdp, checkpoints, flags); + if (checkpoints.getValue() == null) { + if (count != 0) { + processError(count); + throw new IllegalStateException("virDomainListAllCheckpoints returned " + count); + } + return new DomainCheckpoint[0]; + } + + try { + if (count < 0) { + processError(count); + throw new IllegalStateException("virDomainListAllCheckpoints returned " + count); + } + DomainCheckpoint[] result = new DomainCheckpoint[count]; + Pointer arrayPtr = checkpoints.getValue(); + for (int i = 0; i < count; i++) { + Pointer p = arrayPtr.getPointer((long) i * Native.POINTER_SIZE); + result[i] = new DomainCheckpoint(virConnect, new DomainCheckpointPointer(p)); + } + return result; + } finally { + Library.free(checkpoints.getValue()); + } + } + + /** + * Retrieve a checkpoint based on its name + * + * @see Libvirt + * Documentation + * @param name + * name for the domain checkpoint + * @return The domain checkpoint or null in case of not found + * @throws LibvirtException + */ + public DomainCheckpoint checkpointLookupByName(final String name) + throws LibvirtException { + DomainCheckpointPointer ptr = libvirt.virDomainCheckpointLookupByName(vdp, name, 0); + if (ptr == null) { + return null; + } + return new DomainCheckpoint(virConnect, ptr); + } + + /** + * Array of domain checkpoint names for the given domain. With the option to pass flags. + * + * This is a helper function, internally, call to listAllCheckpoints(flags), and it only get the names. + * @param flags {@link CheckpointListFlags} + * @return Array of names, or null if an error + * @throws LibvirtException + */ + public String[] checkpointListNames(final int flags) throws LibvirtException { + DomainCheckpoint[] checkpoints = listAllCheckpoints(flags); + if(checkpoints.length > 0) { + String[] names = new String[checkpoints.length]; + for(int i = 0; i < checkpoints.length; i++) { + names[i] = checkpoints[i].getName(); + } + return names; + } + return Library.NO_STRINGS; + } + + /** + * Array of domain checkpoint names for the given domain. + *

+ * This is just a convenience method, it has the same effect + * as calling {@code checkpointListNames(0);}. + * + * @see #checkpointListNames(int) + * @return The list of names, or null if an error + * @throws LibvirtException + */ + public String[] checkpointListNames() throws LibvirtException { + return checkpointListNames(0); + } + /** * Creates a new snapshot of a domain based on the snapshot xml contained in * xmlDesc. diff --git a/src/main/java/org/libvirt/DomainCheckpoint.java b/src/main/java/org/libvirt/DomainCheckpoint.java new file mode 100644 index 0000000..708ae88 --- /dev/null +++ b/src/main/java/org/libvirt/DomainCheckpoint.java @@ -0,0 +1,252 @@ +package org.libvirt; + +import org.libvirt.jna.DomainCheckpointPointer; + +import com.sun.jna.Pointer; +import com.sun.jna.ptr.PointerByReference; + +import static org.libvirt.Library.libvirt; + +import org.libvirt.Domain.CheckpointListFlags; + +import com.sun.jna.Native; + + +import static org.libvirt.ErrorHandler.processError; + +public class DomainCheckpoint { + + private static int bit(final int i) { + return 1 << i; + } + + public static final class CheckpointDeleteFlags { + /** + * Also delete children (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int CHILDREN = bit(0); + + /** + * Delete just metadata (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int METADATA_ONLY = bit(1); + + /** + * Delete just children (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int CHILDREN_ONLY = bit(2); + } + + public static final class XMLFlags { + /** Include sensitive data (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int SECURE = bit(0); + + /** Supress subelement (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int NO_DOMAIN = bit(1); + + /** Include dynamic per- size (Since: 5.6.0) + * + * @see + * Libvirt Documentation + */ + public static final int XML_SIZE = bit(2); + } + + /** + * the native virDomainCheckpointPtr. + */ + DomainCheckpointPointer vdcp; + + /** + * The Connect Object that represents the Hypervisor of this Domain Checkpoint + */ + private final Connect virConnect; + + + /** + * Constructs a DomainCheckpoint object from a known native DomainCheckpointPointer, and a + * Connect object. + * + * @param virConnect + * the Domain's hypervisor + * @param vdcp + * the native virDomainCheckpointPtr + */ + public DomainCheckpoint(final Connect virConnect, + final DomainCheckpointPointer vdcp) { + this.vdcp = vdcp; + this.virConnect = virConnect; + } + + /** + * Delete the domain checkpoint + * + * @see Libvirt + * Documentation + * @param flags see {@link CheckpointDeleteFlags} + * controls the deletion + * @return ignore (always 0) + * @throws LibvirtException + */ + public int delete(final int flags) throws LibvirtException { + int success = 0; + if (vdcp != null) { + success = processError(libvirt.virDomainCheckpointDelete(vdcp, flags)); + } + + return success; + } + + @Override + protected void finalize() throws LibvirtException { + free(); + } + + /** + * Frees this domaincheckpoint object. The running instance is kept alive. The data + * structure is freed and should not be used thereafter. + * + * @throws LibvirtException + * @return number of references left (>= 0) + */ + public int free() throws LibvirtException { + int success = 0; + if (vdcp != null) { + success = processError(libvirt.virDomainCheckpointFree(vdcp)); + vdcp = null; + } + + return success; + } + + /** + * Fetches an XML document describing attributes of the domain checkpoint, without + * security-sensitive data. + * + * @see + * Libvirt Documentation + * @return the XML document + * @throws org.libvirt.LibvirtException + */ + public String getXMLDesc() throws LibvirtException { + return getXMLDesc(0); + } + + /** + * Fetches an XML document describing attributes of the domain checkpoint. + * + * @see + * Libvirt Documentation + * @param flags see {@link XMLFlags} + * controls the information + * @return the XML document + * @throws org.libvirt.LibvirtException + */ + public String getXMLDesc(final int flags) throws LibvirtException { + return processError(libvirt.virDomainCheckpointGetXMLDesc(vdcp, flags)).toString(); + } + + /** + * Get the public name for that checkpoint + * + * @return the name, null if there is no name + * @throws LibvirtException + */ + public String getName() throws LibvirtException { + return processError(libvirt.virDomainCheckpointGetName(vdcp)); + } + + /** + * Array of domain checkpoints children for the given domain checkpoint. + * + * @see Libvirt + * Documentation + * @param flags + * flags for list the checkpoints, see the {@link CheckpointListFlags} for the flag options + * @return Array with children checkpoints of the given domain checkpoint + * @throws LibvirtException + */ + public DomainCheckpoint[] listAllChildren(int flags) throws LibvirtException { + PointerByReference checkpoints = new PointerByReference(); + int count = libvirt.virDomainCheckpointListAllChildren(vdcp, checkpoints, flags); + if (checkpoints.getValue() == null) { + if (count != 0) { + processError(count); + throw new IllegalStateException("virDomainListAllCheckpoints returned " + count); + } + return new DomainCheckpoint[0]; + } + DomainCheckpoint[] result = new DomainCheckpoint[count]; + try { + if (count < 0) { + processError(count); + throw new IllegalStateException("virDomainListAllCheckpoints returned " + count); + } + + Pointer arrayPtr = checkpoints.getValue(); + for (int i = 0; i < count; i++) { + Pointer p = arrayPtr.getPointer((long) i * Native.POINTER_SIZE); + result[i] = new DomainCheckpoint(virConnect, new DomainCheckpointPointer(p)); + } + + return result; + } finally { + Library.free(checkpoints.getValue()); + } + } + + /** + * Get the parent checkpoint for checkpoint, if any. + * + * @see Libvirt + * Documentation + * @param flags + * extra flags + * @return a domain checkpoint or null if the given domain checkpoint is root + * @throws LibvirtException + */ + public DomainCheckpoint getParent(int flags) throws LibvirtException { + DomainCheckpointPointer parent = libvirt.virDomainCheckpointGetParent(vdcp, flags); + if(parent == null) + return null; + return new DomainCheckpoint(virConnect, parent); + } + + /** + * Get the parent checkpoint for checkpoint, if any. + * + * This is just a convenience method, it has the same effect + * as calling {@code getParent(0);}. + * + * @see #getParent(int) + * @see Libvirt + * Documentation + * @return a domain checkpoint or null if the given domain checkpoint is root + * @throws LibvirtException + */ + public DomainCheckpoint getParent() throws LibvirtException { + return getParent(0); + } + +} diff --git a/src/main/java/org/libvirt/DomainJobStats.java b/src/main/java/org/libvirt/DomainJobStats.java new file mode 100644 index 0000000..7972283 --- /dev/null +++ b/src/main/java/org/libvirt/DomainJobStats.java @@ -0,0 +1,11 @@ +package org.libvirt; + +public class DomainJobStats { + public int type; + public TypedParameter[] stats; + + public DomainJobStats(int type, TypedParameter[] stats) { + this.type = type; + this.stats = stats; + } +} diff --git a/src/main/java/org/libvirt/ErrorException.java b/src/main/java/org/libvirt/ErrorException.java index 86b3314..8d30ecf 100644 --- a/src/main/java/org/libvirt/ErrorException.java +++ b/src/main/java/org/libvirt/ErrorException.java @@ -7,6 +7,7 @@ * @author stoty * @deprecated */ +@Deprecated public class ErrorException extends Exception { private static final long serialVersionUID = -4329050530233404971L; diff --git a/src/main/java/org/libvirt/TypedParameter.java b/src/main/java/org/libvirt/TypedParameter.java index 4474d65..77f280a 100644 --- a/src/main/java/org/libvirt/TypedParameter.java +++ b/src/main/java/org/libvirt/TypedParameter.java @@ -1,22 +1,22 @@ package org.libvirt; import com.sun.jna.Native; +import com.sun.jna.Pointer; import org.libvirt.jna.Libvirt; import org.libvirt.jna.virTypedParameter; import org.libvirt.jna.virTypedParameterValue; -import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.Arrays; public abstract class TypedParameter { - protected static final int TYPED_PARAM_INT = 1; - protected static final int TYPED_PARAM_UINT = 2; - protected static final int TYPED_PARAM_LONG = 3; - protected static final int TYPED_PARAM_ULONG = 4; - protected static final int TYPED_PARAM_DOUBLE = 5; - protected static final int TYPED_PARAM_BOOLEAN = 6; - protected static final int TYPED_PARAM_STRING = 7; + protected static final int TYPED_PARAM_INT = virTypedParameter.TYPED_PARAM_INT; + protected static final int TYPED_PARAM_UINT = virTypedParameter.TYPED_PARAM_UINT; + protected static final int TYPED_PARAM_LONG = virTypedParameter.TYPED_PARAM_LONG; + protected static final int TYPED_PARAM_ULONG = virTypedParameter.TYPED_PARAM_ULONG; + protected static final int TYPED_PARAM_DOUBLE = virTypedParameter.TYPED_PARAM_DOUBLE; + protected static final int TYPED_PARAM_BOOLEAN = virTypedParameter.TYPED_PARAM_BOOLEAN; + protected static final int TYPED_PARAM_STRING = virTypedParameter.TYPED_PARAM_STRING; /** * Parameter name @@ -44,6 +44,8 @@ public abstract class TypedParameter { */ public abstract String getValueAsString(); + private static final TypedParameter[] EMPTY = new TypedParameter[0]; + public static TypedParameter create(final virTypedParameter vParam) { TypedParameter returnValue = null; if (vParam != null) { @@ -126,4 +128,19 @@ public static byte[] copyOf(final byte[] original, final int length) { System.arraycopy(original, 0, returnValue, 0, originalLength); return returnValue; } + + public static TypedParameter[] fromPointer(Pointer ptr, int n) { + if (n == 0) { + return EMPTY; + } + virTypedParameter param = new virTypedParameter(ptr); + param.read(); + virTypedParameter[] params = (virTypedParameter[]) param.toArray(n); + TypedParameter[] stats = new TypedParameter[n]; + for (int i = 0; i < n; i++) { + stats[i] = TypedParameter.create(params[i]); + } + Libvirt.INSTANCE.virTypedParamsFree(ptr, n); + return stats; + } } diff --git a/src/main/java/org/libvirt/jna/DomainCheckpointPointer.java b/src/main/java/org/libvirt/jna/DomainCheckpointPointer.java new file mode 100644 index 0000000..2716e80 --- /dev/null +++ b/src/main/java/org/libvirt/jna/DomainCheckpointPointer.java @@ -0,0 +1,18 @@ +package org.libvirt.jna; + +import com.sun.jna.Pointer; +import com.sun.jna.PointerType; + +/** + * Pointer class to provide type safety to the jna interface. + */ +public class DomainCheckpointPointer extends PointerType { + + public DomainCheckpointPointer() { + } + + public DomainCheckpointPointer(Pointer p) { + super(p); + } +} + diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index 8cd6448..698fbad 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -23,8 +23,6 @@ * Known api calls to be missing * LIBVIRT_0.1.0 * virDefaultErrorFunc - * virConnCopyLastError - * virFreeError * * LIBVIRT_0_5.0 * virEventRegisterImpl @@ -312,6 +310,7 @@ int virGetVersion(LongByReference libVer, String type, LongByReference typeVer); int virInitialize(); int virCopyLastError(virError error); + int virResetError(virError error); virError virGetLastError(); void virResetLastError(); void virSetErrorFunc(Pointer userData, VirErrorCallback callback); @@ -325,6 +324,8 @@ int virGetVersion(LongByReference libVer, String type, int virDomainAttachDevice(DomainPointer virDomainPtr, String deviceXML); int virDomainAttachDeviceFlags(DomainPointer virDomainPtr, String deviceXML, int flags); + int virDomainBackupBegin(DomainPointer virDomainPtr, String backupXML, String checkpointXML, int flags); + CString virDomainBackupGetXMLDesc(DomainPointer virDomainPtr, int flags); int virDomainBlockCommit(DomainPointer virDomainPtr, String disk, String base, String top, long bandwidth, int flags); int virDomainBlockCopy(DomainPointer virDomainPtr, String disk, @@ -359,6 +360,8 @@ int virDomainGetBlockInfo(DomainPointer virDomainPtr, String path, int virDomainGetID(DomainPointer virDomainPtr); int virDomainGetInfo(DomainPointer virDomainPtr, virDomainInfo vInfo); int virDomainGetJobInfo(DomainPointer virDomainPtr, virDomainJobInfo vInfo); + int virDomainGetJobStats(DomainPointer virDomainPtr, IntByReference type, PointerByReference params, + IntByReference nparams, int flags); NativeLong virDomainGetMaxMemory(DomainPointer virDomainPtr); int virDomainGetMaxVcpus(DomainPointer virDomainPtr); String virDomainGetMetadata(DomainPointer virDomainPtr, int type, String uri, int flags); @@ -404,11 +407,23 @@ DomainPointer virDomainMigrate2(DomainPointer virDomainPtr, ConnectionPointer virConnectPtr, String dxml, NativeLong flags, String dname, String uri, NativeLong bandwidth); + /** + * @deprecated use {@link virDomainMigrate3(DomainPointer, + * ConnectionPointer, virTypedParameter[], int, int) + * virDomainMigrate3(DomainPointer, ConnectionPointer, + * virTypedParameter[], int, int)} instead. + */ + @Deprecated DomainPointer virDomainMigrate3(DomainPointer virDomainPtr, ConnectionPointer virConnectPtr, virTypedParameter[] params, int nparams, NativeLong flags); + DomainPointer virDomainMigrate3(DomainPointer virDomainPtr, + ConnectionPointer virConnectPtr, + virTypedParameter[] params, + int nparams, + int flags); int virDomainMigrateSetMaxDowntime(DomainPointer virDomainPtr, long downtime, int flags); int virDomainMigrateToURI(DomainPointer virDomainPtr, String duri, @@ -417,8 +432,14 @@ int virDomainMigrateToURI2(DomainPointer virDomainPtr, String dconnuri, String miguri, String dxml, NativeLong flags, String dname, NativeLong bandwidth); + int virDomainMigrateToURI3(DomainPointer virDomainPtr, + String dconnuri, + virTypedParameter[] params, int nparams, + int flags); int virDomainMemoryStats(DomainPointer virDomainPtr, virDomainMemoryStats[] stats, int nrStats, int flags); + int virDomainGetCPUStats(DomainPointer virDomainPtr, + virTypedParameter[] params, int nparams, int start_cpu, int ncpus, int flags); int virDomainPinVcpu(DomainPointer virDomainPtr, int vcpu, byte[] cpumap, int maplen); int virDomainPMSuspendForDuration(DomainPointer virDomainPtr, @@ -616,6 +637,31 @@ int virStreamSendAll(StreamPointer virStreamPtr, int virStreamRecvAll(StreamPointer virStreamPtr, Libvirt.VirStreamSinkFunc handler, Pointer opaque); + //DomainCheckpoint Methods + String virDomainCheckpointGetName(DomainCheckpointPointer virDomainCheckpointPtr); + DomainPointer virDomainCheckpointGetDomain(DomainCheckpointPointer virDomainCheckpointPtr); + ConnectionPointer virDomainCheckpointGetConnect(DomainCheckpointPointer checkpoint); + DomainCheckpointPointer virDomainCheckpointCreateXML(DomainPointer virDomainPtr, + String xmlDesc, int flags); + CString virDomainCheckpointGetXMLDesc(DomainCheckpointPointer virDomainCheckpointPtr, + int flags); + int virDomainListAllCheckpoints(DomainPointer virDomainPtr, + PointerByReference virDomainCheckpointsPtr, + int flags); + int virDomainCheckpointListAllChildren(DomainCheckpointPointer virDomainCheckpointPtr, + PointerByReference virDomainCheckpointChildrenPtr, + int flags); + DomainCheckpointPointer virDomainCheckpointLookupByName(DomainPointer virDomainPtr, + String name, int flags); + DomainCheckpointPointer virDomainCheckpointGetParent(DomainCheckpointPointer virDomainCheckpointPtr, + int flags); + int virDomainCheckpointDelete(DomainCheckpointPointer virDomainCheckpointPtr, + int flags); + + int virDomainCheckpointRef(DomainCheckpointPointer checkpoint); + + int virDomainCheckpointFree(DomainCheckpointPointer virDomainCheckpointPtr); + //DomainSnapshot Methods DomainSnapshotPointer virDomainSnapshotCreateXML(DomainPointer virDomainPtr, String xmlDesc, int flags); @@ -656,4 +702,6 @@ int virEventAddTimeout(int milliSeconds, VirEventTimeoutCallback cb, int virDomainSetUserPassword(DomainPointer virDomainPtr, String user, String password, int flags); + + void virTypedParamsFree(Pointer params, int nparams); } diff --git a/src/main/java/org/libvirt/jna/virTypedParameter.java b/src/main/java/org/libvirt/jna/virTypedParameter.java index 992ffad..6a5fd78 100644 --- a/src/main/java/org/libvirt/jna/virTypedParameter.java +++ b/src/main/java/org/libvirt/jna/virTypedParameter.java @@ -1,5 +1,6 @@ package org.libvirt.jna; +import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; @@ -12,10 +13,34 @@ * virMemoryParameter since Libvirt 0.9.2. */ public class virTypedParameter extends Structure { + public static final int TYPED_PARAM_INT = 1; + public static final int TYPED_PARAM_UINT = 2; + public static final int TYPED_PARAM_LONG = 3; + public static final int TYPED_PARAM_ULONG = 4; + public static final int TYPED_PARAM_DOUBLE = 5; + public static final int TYPED_PARAM_BOOLEAN = 6; + public static final int TYPED_PARAM_STRING = 7; + public byte[] field = new byte[Libvirt.VIR_TYPED_PARAM_FIELD_LENGTH]; public int type; public virTypedParameterValue value; + public virTypedParameter(){ + super(); + } + + public virTypedParameter(Pointer p) { + super(p); + } + + @Override + public void read() { + super.read(); + if (type == TYPED_PARAM_STRING) { + value.readField("s"); + } + } + private static final List FIELDS = Arrays.asList( "field", "type", "value"); diff --git a/src/test/java/org/libvirt/TestJavaBindings.java b/src/test/java/org/libvirt/TestJavaBindings.java index 79173c4..5fa2fb2 100644 --- a/src/test/java/org/libvirt/TestJavaBindings.java +++ b/src/test/java/org/libvirt/TestJavaBindings.java @@ -1,5 +1,6 @@ package org.libvirt; +import org.libvirt.Domain.CheckpointListFlags; import org.libvirt.event.*; import java.nio.ByteBuffer; @@ -8,6 +9,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.regex.Pattern; @@ -61,7 +63,7 @@ public void testConnection() throws Exception { assertEquals("conn.getVersion()", 2, conn.getVersion()); assertTrue("conn.isAlive", conn.isAlive()); assertTrue("conn.isEncrypted", conn.isEncrypted() == 0); - assertTrue("conn.isSecure", conn.isSecure() == 1); + assertTrue("conn.isSecure", conn.isSecure() == 1); } /* @@ -110,8 +112,8 @@ public void testNetworkCreate() throws Exception { assertEquals("Number of defined networks", 1, conn.numOfDefinedNetworks()); assertEquals("Number of listed defined networks", 1, conn.listDefinedNetworks().length); assertTrue("Network1 should not be persistent", network1.isPersistent() == 0); - assertTrue("Network1 should not be active", network1.isActive() == 1); - assertTrue("Network2 should be active", network2.isActive() == 0); + assertTrue("Network1 should not be active", network1.isActive() == 1); + assertTrue("Network2 should be active", network2.isActive() == 0); this.validateNetworkData(network2); this.validateNetworkData(conn.networkLookupByName("deftest")); this.validateNetworkData(conn.networkLookupByUUID(UUIDArray)); @@ -157,8 +159,8 @@ public void testDomainCreate() throws Exception { assertEquals("Number of defined domains", 1, conn.numOfDefinedDomains()); assertEquals("Number of listed defined domains", 1, conn.listDefinedDomains().length); assertTrue("Domain1 should be persistent", dom1.isPersistent() == 1); - assertTrue("Domain1 should not be active", dom1.isActive() == 0); - assertTrue("Domain2 should be active", dom2.isActive() == 1); + assertTrue("Domain1 should not be active", dom1.isActive() == 0); + assertTrue("Domain2 should be active", dom2.isActive() == 1); this.validateDomainData(dom2); this.validateDomainData(conn.domainLookupByName("createst")); this.validateDomainData(conn.domainLookupByUUID(UUIDArray)); @@ -187,15 +189,24 @@ private void validateDomainData(Domain dom) throws Exception { System.out.println(c.getTypeAsString() + ":" + c.field + ":" + c.getValueAsString()); } - dom.getSchedulerParameters() ; - + dom.getSchedulerParameters(); + SchedUintParameter[] pars = new SchedUintParameter[1]; pars[0] = new SchedUintParameter(); pars[0].field = "weight"; pars[0].value = 100; dom.setSchedulerParameters(pars); - - dom.getSchedulerParameters() ; + + dom.getSchedulerParameters(); + + TypedParameter[] cpuStats = dom.getCPUStats(-1, 1); + assertEquals(3, cpuStats.length); + assertEquals("cpu_time", cpuStats[0].field); + assertEquals("48772617035", cpuStats[0].getValueAsString()); + assertEquals("user_time", cpuStats[1].field); + assertEquals("5540000000", cpuStats[1].getValueAsString()); + assertEquals("system_time", cpuStats[2].field); + assertEquals("6460000000", cpuStats[2].getValueAsString()); } public void testInterfaces() throws Exception { @@ -207,7 +218,7 @@ public void testInterfaces() throws Exception { assertEquals("virtInterfaceGetName", "eth1", virtInt.getName()); assertEquals("virtInterfaceGetMACString", "aa:bb:cc:dd:ee:ff", virtInt.getMACString()); assertNotNull("virtInterfaceGetXMLDesc", virtInt.getXMLDescription(0)); - assertTrue("virInterfaceIsActive", virtInt.isActive() == 1); + assertTrue("virInterfaceIsActive", virtInt.isActive() == 1); System.out.println(virtInt.getXMLDescription(0)); String newXML = "" + "" @@ -234,7 +245,7 @@ public void testAccessAfterClose() throws Exception { } assertNotNull(virException); } - + public void testStoragePool() throws Exception { StoragePool pool1 = conn.storagePoolDefineXML("" + " pool1" @@ -245,14 +256,14 @@ public void testStoragePool() throws Exception { + "", 0) ; StoragePool defaultPool = conn.storagePoolLookupByName("default-pool"); assertEquals("numOfStoragePools:", 1, conn.numOfStoragePools()); - assertEquals("numOfDefinedStoragePools:", 1, conn.numOfDefinedStoragePools()); + assertEquals("numOfDefinedStoragePools:", 1, conn.numOfDefinedStoragePools()); assertNotNull("The pool should not be null", pool1); - assertNotNull("The default pool should not be null", defaultPool); + assertNotNull("The default pool should not be null", defaultPool); assertEquals("The names should match", defaultPool.getName(), "default-pool"); - assertEquals("The uids should match", pool1.getUUIDString(), "004c96e1-2d78-c30f-5aa5-f03c87d21e67"); + assertEquals("The uids should match", pool1.getUUIDString(), "004c96e1-2d78-c30f-5aa5-f03c87d21e67"); assertTrue("pool1 should be persistent", pool1.isPersistent() == 1); - assertTrue("pool1 should not be active", pool1.isActive() == 0); - assertTrue("Domain2 should be active", defaultPool.isActive() == 1); + assertTrue("pool1 should not be active", pool1.isActive() == 0); + assertTrue("Domain2 should be active", defaultPool.isActive() == 1); } public void testDomainEvents() throws Exception { @@ -401,4 +412,234 @@ public void testDomainInterfaceAddresses() throws LibvirtException { dom.undefine(); } } + + /** + * Helper function to create test domains + * @param domainName - Domain name + * @return Domain created + * @throws LibvirtException + */ + private Domain createDomainToCheckpointTest(String domainName) throws LibvirtException{ + String domainXML = "\n" + + " " + domainName + "\n" + + " 512\n" + + " 1\n" + + " \n" + + " hvm\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + Domain domain = conn.domainDefineXML(domainXML); + return domain; + } + + /** + * Check if throw an error when try to create a checkpoint in a inactive domain + * @throws LibvirtException + */ + public void testDomainCheckpointCreateThrowError() throws LibvirtException { + Domain domain = createDomainToCheckpointTest("test-vm-checkpoint-create-throw-error"); + String domainCheckpointXML = "\n" + + "\n" + + " test-checkpoint-create-1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + LibvirtException virException = null; + try { + domain.checkpointCreateXML(domainCheckpointXML, 0); + fail("Exception should be raised because the checkpoint can not perform in a stopped domain"); + } catch(LibvirtException e) { + virException = e; + } + assertNotNull(virException); + } + + /** + * Check methods to create and destroy checkpoints of a domain + * @throws LibvirtException + */ + public void testDomainCheckpointCreateAndDestroy() throws LibvirtException { + Domain domain = createDomainToCheckpointTest("test-vm-checkpoint-create"); + domain.create(); + assertEquals("The virtual machine should not have checkpoints", 0, domain.listAllCheckpoints(0).length); + String domainCheckpointXML = "\n" + + "\n" + + " test-checkpoint-create-1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + DomainCheckpoint domainCheckpoint1 = domain.checkpointCreateXML(domainCheckpointXML, 0); + + assertEquals("The checkpoint was not created", 1, domain.listAllCheckpoints(0).length); + domainCheckpointXML = "\n" + + "\n" + + " test-checkpoint-create-2\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + DomainCheckpoint domainCheckpoint2 = domain.checkpointCreateXML(domainCheckpointXML, 0); + assertEquals("The second checkpoint was not created", 2, domain.listAllCheckpoints(0).length); + domainCheckpoint2.delete(DomainCheckpoint.CheckpointDeleteFlags.CHILDREN); + assertEquals("The checkpoint 2 was not deleted", 1, domain.listAllCheckpoints(0).length); + domainCheckpoint1.delete(DomainCheckpoint.CheckpointDeleteFlags.CHILDREN); + assertEquals("The checkpoint 1 was not deleted", 0, domain.listAllCheckpoints(0).length); + } + + /** + * Check methods inside DomainCheckpoint class, like getName, getXMLDesc,... + * @throws LibvirtException + */ + public void testDomainCheckpointMethods() throws LibvirtException { + Domain domain = createDomainToCheckpointTest("test-vm-checkpoint-methods"); + domain.create(); + String domainCheckpointXML = "\n" + + "\n" + + " test-checkpoint-methods-1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + DomainCheckpoint domainCheckpoint = domain.checkpointCreateXML(domainCheckpointXML, 0); + assertEquals("The names should match", "test-checkpoint-methods-1", domainCheckpoint.getName()); + + + String domainCheckpointXMLDesc = domainCheckpoint.getXMLDesc(0); + assertTrue("The XML should contain the tag ", domainCheckpointXMLDesc.contains("")); + assertTrue("The XML should contain the name of checkpoint", domainCheckpointXMLDesc.contains("test-checkpoint-methods-1")); + assertTrue("The XML should contain one of disks to perform the checkpoint", domainCheckpointXMLDesc.contains("vda")); + } + + /** + * Check methods with hierarchy, like listAllChildren, getParent, etc. + * @throws LibvirtException + */ + public void testDomainCheckpointHierarchy() throws LibvirtException { + int NUM_CHECKPOINTS = 10; // Should be bigger than 2 + Domain domain = createDomainToCheckpointTest("test-vm-checkpoint-testDomainCheckpointHierarchy"); + domain.create(); + DomainCheckpoint[] testCheckpoints = new DomainCheckpoint[NUM_CHECKPOINTS]; + String baseCheckpointName = "test-checkpoint-"; + for(int i = 0; i < NUM_CHECKPOINTS; i++) { + String domainCheckpointXML = "\n" + + " " + baseCheckpointName + i + " \n"; // We avoid disks subelement to write less code + testCheckpoints[i] = domain.checkpointCreateXML(domainCheckpointXML, 0); + } + + // Test the lookup function + DomainCheckpoint checkpointLookedup = domain.checkpointLookupByName("test-checkpoint-1"); + // Check if the parent is "test-checkpoint-0" + assertEquals(testCheckpoints[0].getName(), checkpointLookedup.getParent(0).getName()); + + + DomainCheckpoint checkpointNotCreated = domain.checkpointLookupByName("not-created-checkpoint"); + assertNull(checkpointNotCreated); + + // Get all checkpoints in topological order + DomainCheckpoint[] domainCheckpoints = domain.listAllCheckpoints(CheckpointListFlags.TOPOLOGICAL); + assertEquals("One checkpoint was not created", NUM_CHECKPOINTS, domainCheckpoints.length); + // The checkpoints order should be the same. + for (int i = 0; i < NUM_CHECKPOINTS; i++) { + assertEquals("The created checkpoints order should be the same - " + i, testCheckpoints[i].getName(), domainCheckpoints[i].getName()); + } + assertNull(testCheckpoints[0].getParent(0)); + for (int i = 1; i < NUM_CHECKPOINTS; i++) { + assertEquals(domainCheckpoints[i-1].getName(), domainCheckpoints[i].getParent(0).getName()); + } + + // Check checkpointListNames function + String[] checkpointNames = domain.checkpointListNames(CheckpointListFlags.TOPOLOGICAL); + assertEquals("One checkpoint was not created", NUM_CHECKPOINTS, checkpointNames.length); + // The checkpoints order should be the same. + for (int i = 0; i < NUM_CHECKPOINTS; i++) { + assertEquals("The created checkpoints order should be the same - " + i, testCheckpoints[i].getName(), checkpointNames[i]); + } + + // Check listAllChildren function + DomainCheckpoint[] childrenFromFirst = domainCheckpoints[0].listAllChildren(CheckpointListFlags.DESCENDANTS); + assertEquals("One checkpoint was not created", NUM_CHECKPOINTS - 1, childrenFromFirst.length); + for(int i = 1; i < NUM_CHECKPOINTS; i++) { + assertEquals(childrenFromFirst[i-1].getName(), domainCheckpoints[i].getName()); + } + } + + public void testDomainBackupBegin() throws LibvirtException { + /** + * The driver test:///default is not compatible with virBackupBegin function. + * Discomment the test and put your own values and run. + */ + // String connectionURI = "qemu+ssh://root@fgar-libvirt/system"; + // String domainName = "deb12-1"; + // String checkpointName = "test-backup-begin-checkpoint"; + + /** + * In this test: + * - uses your local connection to search the domain. + * - Init backup of given domain. + * - Check if created correctly. + * - Delete the created checkpoint previously. + */ + + // Connect connToThisTest = new Connect(connectionURI, false); + + + // Domain domain = connToThisTest.domainLookupByName(domainName); + // assertEquals("The test domain should not have any domain checkpoint", 0, domain.listAllCheckpoints(0).length); + + // String backupXML = "\n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // " \n" + // + // ""; + + + // String checkpointXML = "\n" + + // " " + checkpointName + "\n" + + // " \n" + + // " \n" + + // " \n" + + // " \n" + + // "\n"; + // domain.backupBegin(backupXML, checkpointXML, 0); + // DomainCheckpoint domainCheckpoint = domain.checkpointLookupByName(checkpointName); + // assertEquals(checkpointName, domainCheckpoint.getName()); + // try { + // Thread.sleep(2000); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // Map jobStats = domain.getJobStats(0); + // assertTrue("The jobStats should have the key 'operation'", jobStats.containsKey("operation")); + // assertEquals("The job type should be backup", Domain.JobOperation.BACKUP +"", jobStats.get("operation").getValueAsString()); + // domain.abortJob(); + // domainCheckpoint.delete(DomainCheckpoint.CheckpointDeleteFlags.CHILDREN); + // assertEquals("The checkpoint should be removed", 0, domain.listAllCheckpoints(0).length); + } }