diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 5efbc5c..7267728 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -28,15 +28,21 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' cache: maven + - name: Build with Maven run: mvn -B package -Dquarkus.test.profile.tags='ci' --file pom.xml + native-check: + name: Perform native build check with default platform + uses: ./.github/workflows/native-build.yml + # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive # - name: Update dependency graph # uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 diff --git a/.github/workflows/native-build.yml b/.github/workflows/native-build.yml index 62e86d2..325e678 100644 --- a/.github/workflows/native-build.yml +++ b/.github/workflows/native-build.yml @@ -2,16 +2,25 @@ name: Native build test on: workflow_dispatch: + inputs: + platform: + required: false + description: Binary platform + type: string + default: "macOS-latest" + workflow_call: + inputs: + platform: + required: false + description: Binary platform + type: string + default: "macOS-latest" jobs: # Build native executable per runner package: - name: 'Build with Graal on ${{ matrix.os }}' - strategy: - fail-fast: true - matrix: - os: [ ubuntu-latest, macOS-latest, macos-13 ] - runs-on: ${{ matrix.os }} + name: 'Build with Graal on ${{ inputs.platform }}' + runs-on: ${{ inputs.platform }} steps: - name: 'Check out repository' uses: actions/checkout@v4 @@ -31,7 +40,7 @@ jobs: - name: 'Build project' run: mvn install -DskipTests - + - name: 'Build Native Image' run: | pushd server @@ -49,21 +58,3 @@ jobs: with: name: power-server-${{ runner.os }}-${{ runner.arch }} path: server/target/distributions/*.tar.gz - - check: - needs: package - runs-on: ubuntu-latest - steps: - - name: 'Download all build artifacts' - uses: actions/download-artifact@v4 - with: - path: artifacts - pattern: power-server-* - merge-multiple: true - - - name: 'Release with JReleaser' - env: - JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - ls -la artifacts - mvn -ntp -B --file server/pom.xml -Prelease -DartifactsDir=artifacts jreleaser:full-release -Djreleaser.dry.run=true -Djreleaser.select.current.platform \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e21e276..0ef49c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -78,50 +78,13 @@ jobs: # Build native executable per runner package: if: needs.maven-release.outputs.already_released != 'true' - needs: [ maven-release ] - name: 'Build with Graal on ${{ matrix.os }}' + needs: [maven-release] strategy: - fail-fast: true matrix: os: [ ubuntu-latest, macOS-latest, macos-13 ] - runs-on: ${{ matrix.os }} - steps: - - name: 'Check out repository' - uses: actions/checkout@v4 - - - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '21' - cache: 'maven' - - - uses: graalvm/setup-graalvm@v1 - with: - java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - native-image-job-reports: 'true' - - - name: 'Build project' - run: mvn install -DskipTests - - - name: 'Build Native Image' - run: | - pushd server - mvn -ntp -B --file pom.xml -Pnative package -DskipTests - popd - - - name: 'Create distribution' - run: | - pushd server - mvn -ntp -B --file pom.xml -Pdist package -DskipTests - popd - - - name: 'Upload build artifact' - uses: actions/upload-artifact@v4 - with: - name: power-server-${{ runner.os }}-${{ runner.arch }} - path: server/target/distributions/*.tar.gz + uses: ./.github/workflows/native-build.yml + with: + platform: ${{ matrix.os }} # Collect all executables and release release: diff --git a/server/src/main/java/net/laprun/sustainability/power/Security.java b/server/src/main/java/net/laprun/sustainability/power/Security.java index 46af7e3..a2db4aa 100644 --- a/server/src/main/java/net/laprun/sustainability/power/Security.java +++ b/server/src/main/java/net/laprun/sustainability/power/Security.java @@ -12,18 +12,14 @@ @Singleton public class Security { - private final static boolean isRoot; + private static Boolean isRoot; public static final String SECRET_PROPERTY_KEY = "power-server.sudo.secret"; - static { - isRoot = isRunningAsAdministrator(); - } - private final String pwd; public Security(SmallRyeConfig config) { pwd = config.getConfigValue(SECRET_PROPERTY_KEY).getValue(); - if (pwd == null && !isRoot) { + if (pwd == null && !isRunningAsAdministrator()) { throw new IllegalStateException( "This application requires sudo access. Either provide a sudo secret using the 'power-server.sudo.secret' property or run using sudo."); } @@ -32,26 +28,29 @@ public Security(SmallRyeConfig config) { // figure out if we're running as admin by trying to write a system-level preference // see: https://stackoverflow.com/a/23538961/5752008 private synchronized static boolean isRunningAsAdministrator() { - final var preferences = Preferences.systemRoot(); + if (isRoot == null) { + final var preferences = Preferences.systemRoot(); - // avoid outputting errors - System.setErr(new PrintStream(new OutputStream() { - @Override - public void write(int b) { - } - })); + // avoid outputting errors + System.setErr(new PrintStream(new OutputStream() { + @Override + public void write(int b) { + } + })); - try { - preferences.put("foo", "bar"); // SecurityException on Windows - preferences.remove("foo"); - preferences.flush(); // BackingStoreException on Linux and macOS - return true; - } catch (Exception exception) { - return false; - } finally { - System.setErr(System.err); + try { + preferences.put("foo", "bar"); // SecurityException on Windows + preferences.remove("foo"); + preferences.flush(); // BackingStoreException on Linux and macOS + isRoot = true; + } catch (Exception exception) { + isRoot = false; + } finally { + System.setErr(System.err); + } } + return isRoot; } public Process execPowermetrics(String... options) throws IOException { @@ -70,7 +69,7 @@ public Process sudo(String... cmd) throws IOException { throw new IllegalArgumentException("No command specified to run with sudo"); } - if (!isRoot) { + if (!isRunningAsAdministrator()) { final var args = new String[cmd.length + 2]; args[0] = "sudo"; args[1] = "-S";