diff --git a/.editorconfig b/.editorconfig old mode 100755 new mode 100644 index a92f7dfd8..5f150f350 --- a/.editorconfig +++ b/.editorconfig @@ -15,6 +15,6 @@ trim_trailing_whitespace = false indent_style = space indent_size = 2 -[{**.sh,root/etc/cont-init.d/**,root/etc/services.d/**}] +[{**.sh,root/etc/s6-overlay/s6-rc.d/**,root/etc/cont-init.d/**,root/etc/services.d/**}] indent_style = space indent_size = 4 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 6209526e6..6982119e6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ * Read, and fill the Pull Request template * If this is a fix for a typo (in code, documentation, or the README) please file an issue and let us sort it out. We do not need a PR * If the PR is addressing an existing issue include, closes #\, in the body of the PR commit message -* If you want to discuss changes, you can also bring it up in [#dev-talk](https://discordapp.com/channels/354974912613449730/757585807061155840) in our [Discord server](https://discord.gg/YWrKVTn) +* If you want to discuss changes, you can also bring it up in [#dev-talk](https://discordapp.com/channels/354974912613449730/757585807061155840) in our [Discord server](https://linuxserver.io/discord) ## Common files @@ -24,10 +24,10 @@ ## Readme If you would like to change our readme, please __**do not**__ directly edit the readme, as it is auto-generated on each commit. -Instead edit the [readme-vars.yml](https://github.com/linuxserver/docker-webtop/edit/master/readme-vars.yml). +Instead edit the [readme-vars.yml](https://github.com/linuxserver/docker-webtop/edit/arch-i3/readme-vars.yml). These variables are used in a template for our [Jenkins Builder](https://github.com/linuxserver/docker-jenkins-builder) as part of an ansible play. -Most of these variables are also carried over to [docs.linuxserver.io](https://docs.linuxserver.io/images/docker-webtop) +Most of these variables are also carried over to [docs.linuxserver.io](https://docs.linuxserver.io) ### Fixing typos or clarify the text in the readme @@ -105,17 +105,17 @@ docker build \ -t linuxserver/webtop:latest . ``` -The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static` +The ARM variants can be built on x86_64 hardware and vice versa using `lscr.io/linuxserver/qemu-static` ```bash -docker run --rm --privileged multiarch/qemu-user-static:register --reset +docker run --rm --privileged lscr.io/linuxserver/qemu-static --reset ``` Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`. ## Update the changelog -If you are modifying the Dockerfiles or any of the startup scripts in [root](https://github.com/linuxserver/docker-webtop/tree/master/root), add an entry to the changelog +If you are modifying the Dockerfiles or any of the startup scripts in [root](https://github.com/linuxserver/docker-webtop/tree/arch-i3/root), add an entry to the changelog ```yml changelogs: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index a56c31311..dada5509e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,7 +1,7 @@ blank_issues_enabled: false contact_links: - name: Discord chat support - url: https://discord.gg/YWrKVTn + url: https://linuxserver.io/discord about: Realtime support / chat with the community and the team. - name: Discourse discussion forum @@ -9,5 +9,5 @@ contact_links: about: Post on our community forum. - name: Documentation - url: https://docs.linuxserver.io/images/docker-webtop + url: https://docs.linuxserver.io about: Documentation - information about all of our containers. diff --git a/.github/ISSUE_TEMPLATE/issue.bug.md b/.github/ISSUE_TEMPLATE/issue.bug.md deleted file mode 100644 index ccb097923..000000000 --- a/.github/ISSUE_TEMPLATE/issue.bug.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve - ---- -[linuxserverurl]: https://linuxserver.io -[![linuxserver.io](https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/linuxserver_medium.png)][linuxserverurl] - - - - - ------------------------------- - -## Expected Behavior - - -## Current Behavior - - -## Steps to Reproduce - - -1. -2. -3. -4. - -## Environment -**OS:** -**CPU architecture:** x86_64/arm32/arm64 -**How docker service was installed:** - - - -## Command used to create docker container (run/create/compose/screenshot) - - -## Docker logs - diff --git a/.github/ISSUE_TEMPLATE/issue.bug.yml b/.github/ISSUE_TEMPLATE/issue.bug.yml new file mode 100644 index 000000000..3e63d77b9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue.bug.yml @@ -0,0 +1,68 @@ +# Based on the issue template +name: Bug report +description: Create a report to help us improve +title: "[BUG] " +labels: [Bug] +body: + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search to see if an issue already exists for the bug you encountered. + options: + - label: I have searched the existing issues + required: true + - type: textarea + attributes: + label: Current Behavior + description: Tell us what happens instead of the expected behavior. + validations: + required: true + - type: textarea + attributes: + label: Expected Behavior + description: Tell us what should happen. + validations: + required: false + - type: textarea + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + placeholder: | + 1. In this environment... + 2. With this config... + 3. Run '...' + 4. See error... + validations: + required: true + - type: textarea + attributes: + label: Environment + description: | + examples: + - **OS**: Ubuntu 20.04 + - **How docker service was installed**: distro's packagemanager + value: | + - OS: + - How docker service was installed: + render: markdown + validations: + required: false + - type: textarea + attributes: + label: Docker creation + description: | + Command used to create docker container + Provide your docker create/run command or compose yaml snippet, or a screenshot of settings if using a gui to create the container + render: bash + validations: + required: true + - type: textarea + attributes: + description: | + Provide a full docker log, output of "docker logs webtop" + label: Container logs + placeholder: | + Output of `docker logs webtop` + render: bash + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/issue.feature.md b/.github/ISSUE_TEMPLATE/issue.feature.md deleted file mode 100644 index 20a91fdb1..000000000 --- a/.github/ISSUE_TEMPLATE/issue.feature.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project - ---- -[linuxserverurl]: https://linuxserver.io -[![linuxserver.io](https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/linuxserver_medium.png)][linuxserverurl] - -<!--- If you are new to Docker or this application our issue tracker is **ONLY** used for reporting bugs or requesting features. Please use [our discord server](https://discord.gg/YWrKVTn) for general support. ---> - -<!--- If this acts as a feature request please ask yourself if this modification is something the whole userbase will benefit from ---> -<!--- If this is a specific change for corner case functionality or plugins please look at making a Docker Mod or local script https://blog.linuxserver.io/2019/09/14/customizing-our-containers/ --> - -<!--- Provide a general summary of the request in the Title above --> - ------------------------------- - -## Desired Behavior -<!--- Tell us what should happen --> - -## Current Behavior -<!--- Tell us what happens instead of the expected behavior --> - -## Alternatives Considered -<!--- Tell us what other options you have tried or considered --> diff --git a/.github/ISSUE_TEMPLATE/issue.feature.yml b/.github/ISSUE_TEMPLATE/issue.feature.yml new file mode 100644 index 000000000..099dcdb5e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue.feature.yml @@ -0,0 +1,31 @@ +# Based on the issue template +name: Feature request +description: Suggest an idea for this project +title: "[FEAT] <title>" +labels: [enhancement] +body: + - type: checkboxes + attributes: + label: Is this a new feature request? + description: Please search to see if a feature request already exists. + options: + - label: I have searched the existing issues + required: true + - type: textarea + attributes: + label: Wanted change + description: Tell us what you want to happen. + validations: + required: true + - type: textarea + attributes: + label: Reason for change + description: Justify your request, why do you want it, what is the benefit. + validations: + required: true + - type: textarea + attributes: + label: Proposed code change + description: Do you have a potential code change in mind? + validations: + required: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b80c297e7..eefca23d7 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -21,7 +21,7 @@ ------------------------------ - - [ ] I have read the [contributing](https://github.com/linuxserver/docker-webtop/blob/master/.github/CONTRIBUTING.md) guideline and understand that I have made the correct modifications + - [ ] I have read the [contributing](https://github.com/linuxserver/docker-webtop/blob/arch-i3/.github/CONTRIBUTING.md) guideline and understand that I have made the correct modifications ------------------------------ diff --git a/.github/workflows/call_issue_pr_tracker.yml b/.github/workflows/call_issue_pr_tracker.yml new file mode 100644 index 000000000..d07cf1212 --- /dev/null +++ b/.github/workflows/call_issue_pr_tracker.yml @@ -0,0 +1,19 @@ +name: Issue & PR Tracker + +on: + issues: + types: [opened,reopened,labeled,unlabeled,closed] + pull_request_target: + types: [opened,reopened,review_requested,review_request_removed,labeled,unlabeled,closed] + pull_request_review: + types: [submitted,edited,dismissed] + +permissions: + contents: read + +jobs: + manage-project: + permissions: + issues: write + uses: linuxserver/github-workflows/.github/workflows/issue-pr-tracker.yml@v1 + secrets: inherit diff --git a/.github/workflows/call_issues_cron.yml b/.github/workflows/call_issues_cron.yml new file mode 100644 index 000000000..d79774167 --- /dev/null +++ b/.github/workflows/call_issues_cron.yml @@ -0,0 +1,16 @@ +name: Mark stale issues and pull requests +on: + schedule: + - cron: '36 11 * * *' + workflow_dispatch: + +permissions: + contents: read + +jobs: + stale: + permissions: + issues: write + pull-requests: write + uses: linuxserver/github-workflows/.github/workflows/issues-cron.yml@v1 + secrets: inherit diff --git a/.github/workflows/external_trigger.yml b/.github/workflows/external_trigger.yml index b045b4925..c0aa2156b 100644 --- a/.github/workflows/external_trigger.yml +++ b/.github/workflows/external_trigger.yml @@ -3,91 +3,145 @@ name: External Trigger Main on: workflow_dispatch: +permissions: + contents: read + jobs: - external-trigger-master: + external-trigger-arch-i3: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.3.3 + - uses: actions/checkout@v4.1.1 - name: External Trigger - if: github.ref == 'refs/heads/master' + if: github.ref == 'refs/heads/arch-i3' + env: + SKIP_EXTERNAL_TRIGGER: ${{ vars.SKIP_EXTERNAL_TRIGGER }} run: | - if [ -n "${{ secrets.PAUSE_EXTERNAL_TRIGGER_WEBTOP_MASTER }}" ]; then - echo "**** Github secret PAUSE_EXTERNAL_TRIGGER_WEBTOP_MASTER is set; skipping trigger. ****" + printf "# External trigger for docker-webtop\n\n" >> $GITHUB_STEP_SUMMARY + if grep -q "^webtop_arch-i3_" <<< "${SKIP_EXTERNAL_TRIGGER}"; then + echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` contains \`webtop_arch-i3_\`; will skip trigger if version matches." >> $GITHUB_STEP_SUMMARY + elif grep -q "^webtop_arch-i3" <<< "${SKIP_EXTERNAL_TRIGGER}"; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` contains \`webtop_arch-i3\`; skipping trigger." >> $GITHUB_STEP_SUMMARY + exit 0 + fi + echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY + echo "> External trigger running off of arch-i3 branch. To disable this trigger, add \`webtop_arch-i3\` into the Github organizational variable \`SKIP_EXTERNAL_TRIGGER\`." >> $GITHUB_STEP_SUMMARY + printf "\n## Retrieving external version\n\n" >> $GITHUB_STEP_SUMMARY + EXT_RELEASE=$(curl -u ${{ secrets.CR_USER }}:${{ secrets.CR_PAT }} -sX GET https://api.github.com/repos/linuxserver/docker-baseimage-kasmvnc/releases | jq -r 'first(.[] | select(.tag_name | startswith("arch-"))) | .tag_name' | sed 's|arch-||' | sed 's|-ls.*||') + echo "Type is \`custom_version_command\`" >> $GITHUB_STEP_SUMMARY + if grep -q "^webtop_arch-i3_${EXT_RELEASE}" <<< "${SKIP_EXTERNAL_TRIGGER}"; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` matches current external release; skipping trigger." >> $GITHUB_STEP_SUMMARY exit 0 fi - echo "**** External trigger running off of master branch. To disable this trigger, set a Github secret named \"PAUSE_EXTERNAL_TRIGGER_WEBTOP_MASTER\". ****" - echo "**** Retrieving external version ****" - EXT_RELEASE=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ - && awk '/^P:'"xfce4"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://') if [ -z "${EXT_RELEASE}" ] || [ "${EXT_RELEASE}" == "null" ]; then - echo "**** Can't retrieve external version, exiting ****" - FAILURE_REASON="Can't retrieve external version for webtop branch master" + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Can't retrieve external version, exiting" >> $GITHUB_STEP_SUMMARY + FAILURE_REASON="Can't retrieve external version for webtop branch arch-i3" GHA_TRIGGER_URL="https://github.com/linuxserver/docker-webtop/actions/runs/${{ github.run_id }}" curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 16711680, "description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n**Trigger URL:** '"${GHA_TRIGGER_URL}"' \n"}], "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} exit 1 fi - EXT_RELEASE=$(echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g') - echo "**** External version: ${EXT_RELEASE} ****" - echo "**** Retrieving last pushed version ****" + EXT_RELEASE_SANITIZED=$(echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g') + echo "Sanitized external version: \`${EXT_RELEASE_SANITIZED}\`" >> $GITHUB_STEP_SUMMARY + echo "Retrieving last pushed version" >> $GITHUB_STEP_SUMMARY image="linuxserver/webtop" - tag="latest" + tag="arch-i3" token=$(curl -sX GET \ "https://ghcr.io/token?scope=repository%3Alinuxserver%2Fwebtop%3Apull" \ | jq -r '.token') - multidigest=$(curl -s \ - --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \ - --header "Authorization: Bearer ${token}" \ - "https://ghcr.io/v2/${image}/manifests/${tag}" \ - | jq -r 'first(.manifests[].digest)') - digest=$(curl -s \ + multidigest=$(curl -s \ + --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \ + --header "Accept: application/vnd.oci.image.index.v1+json" \ + --header "Authorization: Bearer ${token}" \ + "https://ghcr.io/v2/${image}/manifests/${tag}") + if jq -e '.layers // empty' <<< "${multidigest}" >/dev/null 2>&1; then + # If there's a layer element it's a single-arch manifest so just get that digest + digest=$(jq -r '.config.digest' <<< "${multidigest}") + else + # Otherwise it's multi-arch or has manifest annotations + if jq -e '.manifests[]?.annotations // empty' <<< "${multidigest}" >/dev/null 2>&1; then + # Check for manifest annotations and delete if found + multidigest=$(jq 'del(.manifests[] | select(.annotations))' <<< "${multidigest}") + fi + if [[ $(jq '.manifests | length' <<< "${multidigest}") -gt 1 ]]; then + # If there's still more than one digest, it's multi-arch + multidigest=$(jq -r ".manifests[] | select(.platform.architecture == \"amd64\").digest?" <<< "${multidigest}") + else + # Otherwise it's single arch + multidigest=$(jq -r ".manifests[].digest?" <<< "${multidigest}") + fi + if digest=$(curl -s \ --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \ + --header "Accept: application/vnd.oci.image.manifest.v1+json" \ --header "Authorization: Bearer ${token}" \ - "https://ghcr.io/v2/${image}/manifests/${multidigest}" \ - | jq -r '.config.digest') + "https://ghcr.io/v2/${image}/manifests/${multidigest}"); then + digest=$(jq -r '.config.digest' <<< "${digest}"); + fi + fi image_info=$(curl -sL \ --header "Authorization: Bearer ${token}" \ - "https://ghcr.io/v2/${image}/blobs/${digest}" \ - | jq -r '.container_config') + "https://ghcr.io/v2/${image}/blobs/${digest}") + if [[ $(echo $image_info | jq -r '.container_config') == "null" ]]; then + image_info=$(echo $image_info | jq -r '.config') + else + image_info=$(echo $image_info | jq -r '.container_config') + fi IMAGE_RELEASE=$(echo ${image_info} | jq -r '.Labels.build_version' | awk '{print $3}') IMAGE_VERSION=$(echo ${IMAGE_RELEASE} | awk -F'-ls' '{print $1}') if [ -z "${IMAGE_VERSION}" ]; then - echo "**** Can't retrieve last pushed version, exiting ****" - FAILURE_REASON="Can't retrieve last pushed version for webtop tag latest" + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "Can't retrieve last pushed version, exiting" >> $GITHUB_STEP_SUMMARY + FAILURE_REASON="Can't retrieve last pushed version for webtop tag arch-i3" curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 16711680, "description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n"}], "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} exit 1 fi - echo "**** Last pushed version: ${IMAGE_VERSION} ****" - if [ "${EXT_RELEASE}" == "${IMAGE_VERSION}" ]; then - echo "**** Version ${EXT_RELEASE} already pushed, exiting ****" + echo "Last pushed version: \`${IMAGE_VERSION}\`" >> $GITHUB_STEP_SUMMARY + if [ "${EXT_RELEASE_SANITIZED}" == "${IMAGE_VERSION}" ]; then + echo "Sanitized version \`${EXT_RELEASE_SANITIZED}\` already pushed, exiting" >> $GITHUB_STEP_SUMMARY exit 0 - elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/master/lastBuild/api/json | jq -r '.building') == "true" ]; then - echo "**** New version ${EXT_RELEASE} found; but there already seems to be an active build on Jenkins; exiting ****" + elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/arch-i3/lastBuild/api/json | jq -r '.building') == "true" ]; then + echo "New version \`${EXT_RELEASE}\` found; but there already seems to be an active build on Jenkins; exiting" >> $GITHUB_STEP_SUMMARY exit 0 else - echo "**** New version ${EXT_RELEASE} found; old version was ${IMAGE_VERSION}. Triggering new build ****" - response=$(curl -iX POST \ - https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/master/buildWithParameters?PACKAGE_CHECK=false \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") - echo "**** Jenkins job queue url: ${response%$'\r'} ****" - echo "**** Sleeping 10 seconds until job starts ****" - sleep 10 - buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') - buildurl="${buildurl%$'\r'}" - echo "**** Jenkins job build url: ${buildurl} ****" - echo "**** Attempting to change the Jenkins job description ****" - curl -iX POST \ - "${buildurl}submitDescription" \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ - --data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ - --data-urlencode "Submit=Submit" - echo "**** Notifying Discord ****" - TRIGGER_REASON="A version change was detected for webtop tag latest. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE}" - curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, - "description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}], - "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + if [[ "${artifacts_found}" == "false" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> New version detected, but not all artifacts are published yet; skipping trigger" >> $GITHUB_STEP_SUMMARY + FAILURE_REASON="New version ${EXT_RELEASE} for webtop tag arch-i3 is detected, however not all artifacts are uploaded to upstream release yet. Will try again later." + curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, + "description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + else + printf "\n## Trigger new build\n\n" >> $GITHUB_STEP_SUMMARY + echo "New sanitized version \`${EXT_RELEASE_SANITIZED}\` found; old version was \`${IMAGE_VERSION}\`. Triggering new build" >> $GITHUB_STEP_SUMMARY + if [[ "${artifacts_found}" == "true" ]]; then + echo "All artifacts seem to be uploaded." >> $GITHUB_STEP_SUMMARY + fi + response=$(curl -iX POST \ + https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/arch-i3/buildWithParameters?PACKAGE_CHECK=false \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") + echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY + echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY + sleep 10 + buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') + buildurl="${buildurl%$'\r'}" + echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY + echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY + curl -iX POST \ + "${buildurl}submitDescription" \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ + --data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --data-urlencode "Submit=Submit" + echo "**** Notifying Discord ****" + TRIGGER_REASON="A version change was detected for webtop tag arch-i3. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE_SANITIZED}" + curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, + "description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + fi fi diff --git a/.github/workflows/external_trigger_scheduler.yml b/.github/workflows/external_trigger_scheduler.yml index 7e3c77da7..92e81f019 100644 --- a/.github/workflows/external_trigger_scheduler.yml +++ b/.github/workflows/external_trigger_scheduler.yml @@ -2,42 +2,47 @@ name: External Trigger Scheduler on: schedule: - - cron: '15 * * * *' + - cron: '27 * * * *' workflow_dispatch: +permissions: + contents: read + jobs: external-trigger-scheduler: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.3.3 + - uses: actions/checkout@v4.1.1 with: fetch-depth: '0' - name: External Trigger Scheduler run: | - echo "**** Branches found: ****" - git for-each-ref --format='%(refname:short)' refs/remotes - echo "**** Pulling the yq docker image ****" - docker pull ghcr.io/linuxserver/yq - for br in $(git for-each-ref --format='%(refname:short)' refs/remotes) + printf "# External trigger scheduler for docker-webtop\n\n" >> $GITHUB_STEP_SUMMARY + printf "Found the branches:\n\n%s\n" "$(git for-each-ref --format='- %(refname:lstrip=3)' refs/remotes)" >> $GITHUB_STEP_SUMMARY + for br in $(git for-each-ref --format='%(refname:lstrip=3)' refs/remotes) do - br=$(echo "$br" | sed 's|origin/||g') - echo "**** Evaluating branch ${br} ****" - ls_branch=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-webtop/${br}/jenkins-vars.yml \ - | docker run --rm -i --entrypoint yq ghcr.io/linuxserver/yq -r .ls_branch) - if [ "$br" == "$ls_branch" ]; then - echo "**** Branch ${br} appears to be live; checking workflow. ****" + if [[ "${br}" == "HEAD" ]]; then + printf "\nSkipping %s.\n" ${br} >> $GITHUB_STEP_SUMMARY + continue + fi + printf "\n## Evaluating \`%s\`\n\n" ${br} >> $GITHUB_STEP_SUMMARY + ls_jenkins_vars=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-webtop/${br}/jenkins-vars.yml) + ls_branch=$(echo "${ls_jenkins_vars}" | yq -r '.ls_branch') + ls_trigger=$(echo "${ls_jenkins_vars}" | yq -r '.external_type') + if [[ "${br}" == "${ls_branch}" ]] && [[ "${ls_trigger}" != "os" ]]; then + echo "Branch appears to be live and trigger is not os; checking workflow." >> $GITHUB_STEP_SUMMARY if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-webtop/${br}/.github/workflows/external_trigger.yml > /dev/null 2>&1; then - echo "**** Workflow exists. Triggering external trigger workflow for branch ${br} ****." + echo "Triggering external trigger workflow for branch." >> $GITHUB_STEP_SUMMARY curl -iX POST \ -H "Authorization: token ${{ secrets.CR_PAT }}" \ -H "Accept: application/vnd.github.v3+json" \ -d "{\"ref\":\"refs/heads/${br}\"}" \ https://api.github.com/repos/linuxserver/docker-webtop/actions/workflows/external_trigger.yml/dispatches else - echo "**** Workflow doesn't exist; skipping trigger. ****" + echo "Skipping branch due to no external trigger workflow present." >> $GITHUB_STEP_SUMMARY fi else - echo "**** ${br} appears to be a dev branch; skipping trigger. ****" + echo "Skipping branch due to being detected as dev branch or having no external version." >> $GITHUB_STEP_SUMMARY fi done diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml index 3149ff41a..bba494b5b 100644 --- a/.github/workflows/greetings.yml +++ b/.github/workflows/greetings.yml @@ -2,12 +2,18 @@ name: Greetings on: [pull_request_target, issues] +permissions: + contents: read + jobs: greeting: + permissions: + issues: write + pull-requests: write runs-on: ubuntu-latest steps: - uses: actions/first-interaction@v1 with: - issue-message: 'Thanks for opening your first issue here! Be sure to follow the [bug](https://github.com/linuxserver/docker-webtop/blob/master/.github/ISSUE_TEMPLATE/issue.bug.md) or [feature](https://github.com/linuxserver/docker-webtop/blob/master/.github/ISSUE_TEMPLATE/issue.feature.md) issue templates!' - pr-message: 'Thanks for opening this pull request! Be sure to follow the [pull request template](https://github.com/linuxserver/docker-webtop/blob/master/.github/PULL_REQUEST_TEMPLATE.md)!' + issue-message: 'Thanks for opening your first issue here! Be sure to follow the relevant issue templates, or risk having this issue marked as invalid.' + pr-message: 'Thanks for opening this pull request! Be sure to follow the [pull request template](https://github.com/linuxserver/docker-webtop/blob/arch-i3/.github/PULL_REQUEST_TEMPLATE.md)!' repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package_trigger.yml b/.github/workflows/package_trigger.yml deleted file mode 100644 index 3616a510b..000000000 --- a/.github/workflows/package_trigger.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Package Trigger Main - -on: - workflow_dispatch: - -jobs: - package-trigger-master: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2.3.3 - - - name: Package Trigger - if: github.ref == 'refs/heads/master' - run: | - if [ -n "${{ secrets.PAUSE_PACKAGE_TRIGGER_WEBTOP_MASTER }}" ]; then - echo "**** Github secret PAUSE_PACKAGE_TRIGGER_WEBTOP_MASTER is set; skipping trigger. ****" - exit 0 - fi - if [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/master/lastBuild/api/json | jq -r '.building') == "true" ]; then - echo "**** There already seems to be an active build on Jenkins; skipping package trigger ****" - exit 0 - fi - echo "**** Package trigger running off of master branch. To disable, set a Github secret named \"PAUSE_PACKAGE_TRIGGER_WEBTOP_MASTER\". ****" - response=$(curl -iX POST \ - https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/master/buildWithParameters?PACKAGE_CHECK=true \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") - echo "**** Jenkins job queue url: ${response%$'\r'} ****" - echo "**** Sleeping 10 seconds until job starts ****" - sleep 10 - buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') - buildurl="${buildurl%$'\r'}" - echo "**** Jenkins job build url: ${buildurl} ****" - echo "**** Attempting to change the Jenkins job description ****" - curl -iX POST \ - "${buildurl}submitDescription" \ - --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ - --data-urlencode "description=GHA package trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ - --data-urlencode "Submit=Submit" diff --git a/.github/workflows/package_trigger_scheduler.yml b/.github/workflows/package_trigger_scheduler.yml index ae74e6400..33b24b1de 100644 --- a/.github/workflows/package_trigger_scheduler.yml +++ b/.github/workflows/package_trigger_scheduler.yml @@ -2,49 +2,102 @@ name: Package Trigger Scheduler on: schedule: - - cron: '04 9 * * 0' + - cron: '19 3 * * 2' workflow_dispatch: +permissions: + contents: read + jobs: package-trigger-scheduler: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.3.3 + - uses: actions/checkout@v4.1.1 with: fetch-depth: '0' - name: Package Trigger Scheduler + env: + SKIP_PACKAGE_TRIGGER: ${{ vars.SKIP_PACKAGE_TRIGGER }} run: | - echo "**** Branches found: ****" - git for-each-ref --format='%(refname:short)' refs/remotes - echo "**** Pulling the yq docker image ****" - docker pull ghcr.io/linuxserver/yq - for br in $(git for-each-ref --format='%(refname:short)' refs/remotes) + printf "# Package trigger scheduler for docker-webtop\n\n" >> $GITHUB_STEP_SUMMARY + printf "Found the branches:\n\n%s\n" "$(git for-each-ref --format='- %(refname:lstrip=3)' refs/remotes)" >> $GITHUB_STEP_SUMMARY + for br in $(git for-each-ref --format='%(refname:lstrip=3)' refs/remotes) do - br=$(echo "$br" | sed 's|origin/||g') - echo "**** Evaluating branch ${br} ****" - ls_branch=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-webtop/${br}/jenkins-vars.yml \ - | docker run --rm -i --entrypoint yq ghcr.io/linuxserver/yq -r .ls_branch) - if [ "${br}" == "${ls_branch}" ]; then - echo "**** Branch ${br} appears to be live; checking workflow. ****" - if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-webtop/${br}/.github/workflows/package_trigger.yml > /dev/null 2>&1; then - echo "**** Workflow exists. Triggering package trigger workflow for branch ${br}. ****" - triggered_branches="${triggered_branches}${br} " - curl -iX POST \ - -H "Authorization: token ${{ secrets.CR_PAT }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -d "{\"ref\":\"refs/heads/${br}\"}" \ - https://api.github.com/repos/linuxserver/docker-webtop/actions/workflows/package_trigger.yml/dispatches - sleep 30 + if [[ "${br}" == "HEAD" ]]; then + printf "\nSkipping %s.\n" ${br} >> $GITHUB_STEP_SUMMARY + continue + fi + printf "\n## Evaluating \`%s\`\n\n" ${br} >> $GITHUB_STEP_SUMMARY + JENKINS_VARS=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-webtop/${br}/jenkins-vars.yml) + if ! curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-webtop/${br}/Jenkinsfile >/dev/null 2>&1; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> No Jenkinsfile found. Branch is either deprecated or is an early dev branch." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif [[ "${br}" == $(yq -r '.ls_branch' <<< "${JENKINS_VARS}") ]]; then + echo "Branch appears to be live; checking workflow." >> $GITHUB_STEP_SUMMARY + README_VARS=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-webtop/${br}/readme-vars.yml) + if [[ $(yq -r '.project_deprecation_status' <<< "${README_VARS}") == "true" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Branch appears to be deprecated; skipping trigger." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif [[ $(yq -r '.skip_package_check' <<< "${JENKINS_VARS}") == "true" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Skipping branch ${br} due to \`skip_package_check\` being set in \`jenkins-vars.yml\`." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif grep -q "^webtop_${br}" <<< "${SKIP_PACKAGE_TRIGGER}"; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Github organizational variable \`SKIP_PACKAGE_TRIGGER\` contains \`webtop_${br}\`; skipping trigger." >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " + elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/${br}/lastBuild/api/json | jq -r '.building' 2>/dev/null) == "true" ]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> There already seems to be an active build on Jenkins; skipping package trigger for ${br}" >> $GITHUB_STEP_SUMMARY + skipped_branches="${skipped_branches}${br} " else - echo "**** Workflow doesn't exist; skipping trigger. ****" + echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY + echo "> Triggering package trigger for branch ${br}" >> $GITHUB_STEP_SUMMARY + printf "> To disable, add \`webtop_%s\` into the Github organizational variable \`SKIP_PACKAGE_TRIGGER\`.\n\n" "${br}" >> $GITHUB_STEP_SUMMARY + triggered_branches="${triggered_branches}${br} " + response=$(curl -iX POST \ + https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/${br}/buildWithParameters?PACKAGE_CHECK=true \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|") + if [[ -z "${response}" ]]; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Jenkins build could not be triggered. Skipping branch." + continue + fi + echo "Jenkins [job queue url](${response%$'\r'})" >> $GITHUB_STEP_SUMMARY + echo "Sleeping 10 seconds until job starts" >> $GITHUB_STEP_SUMMARY + sleep 10 + buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url') + buildurl="${buildurl%$'\r'}" + echo "Jenkins job [build url](${buildurl})" >> $GITHUB_STEP_SUMMARY + echo "Attempting to change the Jenkins job description" >> $GITHUB_STEP_SUMMARY + if ! curl -ifX POST \ + "${buildurl}submitDescription" \ + --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \ + --data-urlencode "description=GHA package trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ + --data-urlencode "Submit=Submit"; then + echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY + echo "> Unable to change the Jenkins job description." + fi + sleep 20 fi else - echo "**** ${br} appears to be a dev branch; skipping trigger. ****" + echo "Skipping branch ${br} due to being detected as dev branch." >> $GITHUB_STEP_SUMMARY fi done - echo "**** Package check build(s) triggered for branch(es): ${triggered_branches} ****" - echo "**** Notifying Discord ****" - curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, - "description": "**Package Check Build(s) Triggered for webtop** \n**Branch(es):** '"${triggered_branches}"' \n**Build URL:** '"https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-webtop/activity/"' \n"}], - "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + if [[ -n "${triggered_branches}" ]] || [[ -n "${skipped_branches}" ]]; then + if [[ -n "${triggered_branches}" ]]; then + NOTIFY_BRANCHES="**Triggered:** ${triggered_branches} \n" + NOTIFY_BUILD_URL="**Build URL:** https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-webtop/activity/ \n" + echo "**** Package check build(s) triggered for branch(es): ${triggered_branches} ****" + fi + if [[ -n "${skipped_branches}" ]]; then + NOTIFY_BRANCHES="${NOTIFY_BRANCHES}**Skipped:** ${skipped_branches} \n" + fi + echo "**** Notifying Discord ****" + curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, + "description": "**Package Check Build(s) for webtop** \n'"${NOTIFY_BRANCHES}"''"${NOTIFY_BUILD_URL}"'"}], + "username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }} + fi diff --git a/.github/workflows/permissions.yml b/.github/workflows/permissions.yml new file mode 100644 index 000000000..02e1bdb9a --- /dev/null +++ b/.github/workflows/permissions.yml @@ -0,0 +1,12 @@ +name: Permission check +on: + pull_request_target: + paths: + - '**/run' + - '**/finish' + - '**/check' + - 'root/migrations/*' + +jobs: + permission_check: + uses: linuxserver/github-workflows/.github/workflows/init-svc-executable-permissions.yml@v1 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index 3b3846ee8..000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "30 1 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - stale-issue-message: "This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions." - stale-pr-message: "This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions." - stale-issue-label: 'no-issue-activity' - stale-pr-label: 'no-pr-activity' - days-before-stale: 30 - days-before-close: 365 - exempt-issue-labels: 'awaiting-approval,work-in-progress' - exempt-pr-labels: 'awaiting-approval,work-in-progress' - repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Dockerfile b/Dockerfile index 0515fc062..d1909b4b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,33 +1,48 @@ -FROM lsiobase/rdesktop-web:alpine +FROM ghcr.io/linuxserver/baseimage-selkies:arch # set version label ARG BUILD_DATE ARG VERSION -ARG XFCE_VERSION LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}" LABEL maintainer="thelamer" +# title +ENV TITLE="Arch i3" \ + SELKIES_WAYLAND_SOCKET_INDEX=2 RUN \ + echo "**** add icon ****" && \ + curl -o \ + /usr/share/selkies/www/icon.png \ + https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/webtop-logo.png && \ echo "**** install packages ****" && \ - apk add --no-cache \ - faenza-icon-theme \ - faenza-icon-theme-xfce4-appfinder \ - faenza-icon-theme-xfce4-panel \ - firefox-esr \ - mousepad \ - thunar \ - xfce4 \ + pacman -Sy --noconfirm --needed \ + chromium \ + i3-wm \ + i3status \ + sway \ + swaybg \ xfce4-terminal && \ - apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community \ - xfce4-pulseaudio-plugin && \ + echo "**** application tweaks ****" && \ + mv \ + /usr/bin/chromium \ + /usr/bin/chromium-real && \ + ln -s \ + /usr/sbin/xfce4-terminal \ + /usr/bin/x-terminal-emulator && \ + setcap -r \ + /usr/bin/sway && \ echo "**** cleanup ****" && \ rm -rf \ - /tmp/* + /config/.cache \ + /tmp/* \ + /var/cache/pacman/pkg/* \ + /var/lib/pacman/sync/* # add local files COPY /root / # ports and volumes EXPOSE 3000 + VOLUME /config diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 439ac8bc8..c15533cf2 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -1,33 +1,48 @@ -FROM lsiobase/rdesktop-web:arm64v8-alpine +FROM ghcr.io/linuxserver/baseimage-selkies:arm64v8-arch # set version label ARG BUILD_DATE ARG VERSION -ARG XFCE_VERSION LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}" LABEL maintainer="thelamer" +# title +ENV TITLE="Arch i3" \ + SELKIES_WAYLAND_SOCKET_INDEX=2 RUN \ + echo "**** add icon ****" && \ + curl -o \ + /usr/share/selkies/www/icon.png \ + https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/webtop-logo.png && \ echo "**** install packages ****" && \ - apk add --no-cache \ - faenza-icon-theme \ - faenza-icon-theme-xfce4-appfinder \ - faenza-icon-theme-xfce4-panel \ - firefox-esr \ - mousepad \ - thunar \ - xfce4 \ + pacman -Sy --noconfirm --needed \ + chromium \ + i3-wm \ + i3status \ + sway \ + swaybg \ xfce4-terminal && \ - apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community \ - xfce4-pulseaudio-plugin && \ + echo "**** application tweaks ****" && \ + mv \ + /usr/bin/chromium \ + /usr/bin/chromium-real && \ + ln -s \ + /usr/sbin/xfce4-terminal \ + /usr/bin/x-terminal-emulator && \ + setcap -r \ + /usr/bin/sway && \ echo "**** cleanup ****" && \ rm -rf \ - /tmp/* + /config/.cache \ + /tmp/* \ + /var/cache/pacman/pkg/* \ + /var/lib/pacman/sync/* # add local files COPY /root / # ports and volumes EXPOSE 3000 + VOLUME /config diff --git a/Dockerfile.armhf b/Dockerfile.armhf deleted file mode 100644 index 276d8de77..000000000 --- a/Dockerfile.armhf +++ /dev/null @@ -1,33 +0,0 @@ -FROM lsiobase/rdesktop-web:arm32v7-alpine - -# set version label -ARG BUILD_DATE -ARG VERSION -ARG XFCE_VERSION -LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}" -LABEL maintainer="thelamer" - - -RUN \ - echo "**** install packages ****" && \ - apk add --no-cache \ - faenza-icon-theme \ - faenza-icon-theme-xfce4-appfinder \ - faenza-icon-theme-xfce4-panel \ - firefox-esr \ - mousepad \ - thunar \ - xfce4 \ - xfce4-terminal && \ - apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community \ - xfce4-pulseaudio-plugin && \ - echo "**** cleanup ****" && \ - rm -rf \ - /tmp/* - -# add local files -COPY /root / - -# ports and volumes -EXPOSE 3000 -VOLUME /config diff --git a/Jenkinsfile b/Jenkinsfile index 1fc1ad72c..ec13cd692 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ pipeline { } // Input to determine if this is a package check parameters { - string(defaultValue: 'false', description: 'package check run', name: 'PACKAGE_CHECK') + string(defaultValue: 'false', description: 'package check run', name: 'PACKAGE_CHECK') } // Configuration for the variables used for this specific repo environment { @@ -16,35 +16,67 @@ pipeline { GITHUB_TOKEN=credentials('498b4638-2d02-4ce5-832d-8a57d01d97ab') GITLAB_TOKEN=credentials('b6f0f1dd-6952-4cf6-95d1-9c06380283f0') GITLAB_NAMESPACE=credentials('gitlab-namespace-id') - BUILD_VERSION_ARG = 'XFCE_VERSION' + DOCKERHUB_TOKEN=credentials('docker-hub-ci-pat') + QUAYIO_API_TOKEN=credentials('quayio-repo-api-token') + GIT_SIGNING_KEY=credentials('484fbca6-9a4f-455e-b9e3-97ac98785f5f') + BUILD_VERSION_ARG = 'I3_VERSION' LS_USER = 'linuxserver' LS_REPO = 'docker-webtop' CONTAINER_NAME = 'webtop' DOCKERHUB_IMAGE = 'linuxserver/webtop' DEV_DOCKERHUB_IMAGE = 'lsiodev/webtop' PR_DOCKERHUB_IMAGE = 'lspipepr/webtop' - DIST_IMAGE = 'alpine' - DIST_TAG = '3.13' - DIST_REPO = 'http://dl-cdn.alpinelinux.org/alpine/v3.13/community/' - DIST_REPO_PACKAGES = 'xfce4' + DIST_IMAGE = 'arch' MULTIARCH = 'true' CI = 'true' CI_WEB = 'true' - CI_PORT = '3000' - CI_SSL = 'false' + CI_PORT = '3001' + CI_SSL = 'true' CI_DELAY = '120' CI_DOCKERENV = 'TZ=US/Pacific' CI_AUTH = 'user:password' CI_WEBPATH = '' } stages { + stage("Set git config"){ + steps{ + sh '''#!/bin/bash + cat ${GIT_SIGNING_KEY} > /config/.ssh/id_sign + chmod 600 /config/.ssh/id_sign + ssh-keygen -y -f /config/.ssh/id_sign > /config/.ssh/id_sign.pub + echo "Using $(ssh-keygen -lf /config/.ssh/id_sign) to sign commits" + git config --global gpg.format ssh + git config --global user.signingkey /config/.ssh/id_sign + git config --global commit.gpgsign true + ''' + } + } // Setup all the basic environment variables needed for the build stage("Set ENV Variables base"){ steps{ + echo "Running on node: ${NODE_NAME}" + sh '''#! /bin/bash + echo "Pruning builder" + docker builder prune -f --builder container || : + containers=$(docker ps -q) + if [[ -n "${containers}" ]]; then + BUILDX_CONTAINER_ID=$(docker ps -qf 'name=buildx_buildkit') + for container in ${containers}; do + if [[ "${container}" == "${BUILDX_CONTAINER_ID}" ]]; then + echo "skipping buildx container in docker stop" + else + echo "Stopping container ${container}" + docker stop ${container} + fi + done + fi + docker system prune -f --volumes || : + docker image prune -af || : + ''' script{ env.EXIT_STATUS = '' env.LS_RELEASE = sh( - script: '''docker run --rm ghcr.io/linuxserver/alexeiled-skopeo sh -c 'skopeo inspect docker://docker.io/'${DOCKERHUB_IMAGE}':latest 2>/dev/null' | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''', + script: '''docker run --rm quay.io/skopeo/stable:v1 inspect docker://ghcr.io/${LS_USER}/${CONTAINER_NAME}:arch-i3 2>/dev/null | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''', returnStdout: true).trim() env.LS_RELEASE_NOTES = sh( script: '''cat readme-vars.yml | awk -F \\" '/date: "[0-9][0-9].[0-9][0-9].[0-9][0-9]:/ {print $4;exit;}' | sed -E ':a;N;$!ba;s/\\r{0,1}\\n/\\\\n/g' ''', @@ -55,11 +87,20 @@ pipeline { env.COMMIT_SHA = sh( script: '''git rev-parse HEAD''', returnStdout: true).trim() + env.GH_DEFAULT_BRANCH = sh( + script: '''git remote show origin | grep "HEAD branch:" | sed 's|.*HEAD branch: ||' ''', + returnStdout: true).trim() env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/commit/' + env.GIT_COMMIT env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DOCKERHUB_IMAGE + '/tags/' env.PULL_REQUEST = env.CHANGE_ID - env.TEMPLATED_FILES = 'Jenkinsfile README.md LICENSE .editorconfig ./.github/CONTRIBUTING.md ./.github/FUNDING.yml ./.github/ISSUE_TEMPLATE/config.yml ./.github/ISSUE_TEMPLATE/issue.bug.md ./.github/ISSUE_TEMPLATE/issue.feature.md ./.github/PULL_REQUEST_TEMPLATE.md ./.github/workflows/external_trigger_scheduler.yml ./.github/workflows/greetings.yml ./.github/workflows/package_trigger_scheduler.yml ./.github/workflows/stale.yml ./.github/workflows/external_trigger.yml ./.github/workflows/package_trigger.yml' + env.TEMPLATED_FILES = 'Jenkinsfile README.md LICENSE .editorconfig ./.github/CONTRIBUTING.md ./.github/FUNDING.yml ./.github/ISSUE_TEMPLATE/config.yml ./.github/ISSUE_TEMPLATE/issue.bug.yml ./.github/ISSUE_TEMPLATE/issue.feature.yml ./.github/PULL_REQUEST_TEMPLATE.md ./.github/workflows/external_trigger_scheduler.yml ./.github/workflows/greetings.yml ./.github/workflows/package_trigger_scheduler.yml ./.github/workflows/call_issue_pr_tracker.yml ./.github/workflows/call_issues_cron.yml ./.github/workflows/permissions.yml ./.github/workflows/external_trigger.yml' + if ( env.SYFT_IMAGE_TAG == null ) { + env.SYFT_IMAGE_TAG = 'latest' + } } + echo "Using syft image tag ${SYFT_IMAGE_TAG}" + sh '''#! /bin/bash + echo "The default github branch detected as ${GH_DEFAULT_BRANCH}" ''' script{ env.LS_RELEASE_NUMBER = sh( script: '''echo ${LS_RELEASE} |sed 's/^.*-ls//g' ''', @@ -68,7 +109,7 @@ pipeline { script{ env.LS_TAG_NUMBER = sh( script: '''#! /bin/bash - tagsha=$(git rev-list -n 1 ${LS_RELEASE} 2>/dev/null) + tagsha=$(git rev-list -n 1 arch-i3-${LS_RELEASE} 2>/dev/null) if [ "${tagsha}" == "${COMMIT_SHA}" ]; then echo ${LS_RELEASE_NUMBER} elif [ -z "${GIT_COMMIT}" ]; then @@ -101,15 +142,14 @@ pipeline { /* ######################## External Release Tagging ######################## */ - // If this is an alpine repo change for external version determine an md5 from the version string - stage("Set tag Alpine Repo"){ + // If this is a custom command to determine version use that command + stage("Set tag custom bash"){ steps{ script{ env.EXT_RELEASE = sh( - script: '''curl -sL "${DIST_REPO}x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ - && awk '/^P:'"${DIST_REPO_PACKAGES}"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://' ''', + script: ''' curl -sX GET https://api.github.com/repos/linuxserver/docker-baseimage-kasmvnc/releases | jq -r 'first(.[] | select(.tag_name | startswith("arch-"))) | .tag_name' | sed 's|arch-||' | sed 's|-ls.*||' ''', returnStdout: true).trim() - env.RELEASE_LINK = 'alpine_repo' + env.RELEASE_LINK = 'custom_command' } } } @@ -118,15 +158,39 @@ pipeline { steps{ script{ env.EXT_RELEASE_CLEAN = sh( - script: '''echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g' ''', + script: '''echo ${EXT_RELEASE} | sed 's/[~,%@+;:/ ]//g' ''', returnStdout: true).trim() + + def semver = env.EXT_RELEASE_CLEAN =~ /(\d+)\.(\d+)\.(\d+)/ + if (semver.find()) { + env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${semver[0][3]}" + } else { + semver = env.EXT_RELEASE_CLEAN =~ /(\d+)\.(\d+)(?:\.(\d+))?(.*)/ + if (semver.find()) { + if (semver[0][3]) { + env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${semver[0][3]}" + } else if (!semver[0][3] && !semver[0][4]) { + env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${(new Date()).format('YYYYMMdd')}" + } + } + } + + if (env.SEMVER != null) { + if (BRANCH_NAME != "${env.GH_DEFAULT_BRANCH}") { + env.SEMVER = "${env.SEMVER}-${BRANCH_NAME}" + } + println("SEMVER: ${env.SEMVER}") + } else { + println("No SEMVER detected") + } + } } } - // If this is a master build use live docker endpoints + // If this is a arch-i3 build use live docker endpoints stage("Set ENV live build"){ when { - branch "master" + branch "arch-i3" environment name: 'CHANGE_ID', value: '' } steps { @@ -134,21 +198,24 @@ pipeline { env.IMAGE = env.DOCKERHUB_IMAGE env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/' + env.CONTAINER_NAME env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/' + env.CONTAINER_NAME + env.QUAYIMAGE = 'quay.io/linuxserver.io/' + env.CONTAINER_NAME if (env.MULTIARCH == 'true') { - env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|arm32v7-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + env.CI_TAGS = 'amd64-arch-i3-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|arm64v8-arch-i3-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER } else { - env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + env.CI_TAGS = 'arch-i3-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER } env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER - env.META_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER - env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN + env.META_TAG = 'arch-i3-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + env.EXT_RELEASE_TAG = 'arch-i3-version-' + env.EXT_RELEASE_CLEAN + env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' + env.CITEST_IMAGETAG = 'latest' } } } // If this is a dev build use dev docker endpoints stage("Set ENV dev build"){ when { - not {branch "master"} + not {branch "arch-i3"} environment name: 'CHANGE_ID', value: '' } steps { @@ -156,15 +223,18 @@ pipeline { env.IMAGE = env.DEV_DOCKERHUB_IMAGE env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/lsiodev-' + env.CONTAINER_NAME env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/lsiodev-' + env.CONTAINER_NAME + env.QUAYIMAGE = 'quay.io/linuxserver.io/lsiodev-' + env.CONTAINER_NAME if (env.MULTIARCH == 'true') { - env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|arm32v7-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + env.CI_TAGS = 'amd64-arch-i3-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|arm64v8-arch-i3-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA } else { - env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + env.CI_TAGS = 'arch-i3-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA } env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA - env.META_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA - env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN + env.META_TAG = 'arch-i3-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + env.EXT_RELEASE_TAG = 'arch-i3-version-' + env.EXT_RELEASE_CLEAN env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DEV_DOCKERHUB_IMAGE + '/tags/' + env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' + env.CITEST_IMAGETAG = 'develop' } } } @@ -178,16 +248,19 @@ pipeline { env.IMAGE = env.PR_DOCKERHUB_IMAGE env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/lspipepr-' + env.CONTAINER_NAME env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/lspipepr-' + env.CONTAINER_NAME + env.QUAYIMAGE = 'quay.io/linuxserver.io/lspipepr-' + env.CONTAINER_NAME if (env.MULTIARCH == 'true') { - env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST + '|arm32v7-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST + env.CI_TAGS = 'amd64-arch-i3-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST + '|arm64v8-arch-i3-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST } else { - env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST + env.CI_TAGS = 'arch-i3-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST } - env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST - env.META_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST - env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN + env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST + env.META_TAG = 'arch-i3-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST + env.EXT_RELEASE_TAG = 'arch-i3-version-' + env.EXT_RELEASE_CLEAN env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/pull/' + env.PULL_REQUEST env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.PR_DOCKERHUB_IMAGE + '/tags/' + env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' + env.CITEST_IMAGETAG = 'develop' } } } @@ -204,26 +277,25 @@ pipeline { script{ env.SHELLCHECK_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/shellcheck-result.xml' } - sh '''curl -sL https://raw.githubusercontent.com/linuxserver/docker-shellcheck/master/checkrun.sh | /bin/bash''' + sh '''curl -sL https://raw.githubusercontent.com/linuxserver/docker-jenkins-builder/master/checkrun.sh | /bin/bash''' sh '''#! /bin/bash - set -e - docker pull ghcr.io/linuxserver/lsiodev-spaces-file-upload:latest docker run --rm \ - -e DESTINATION=\"${IMAGE}/${META_TAG}/shellcheck-result.xml\" \ - -e FILE_NAME="shellcheck-result.xml" \ - -e MIMETYPE="text/xml" \ - -v ${WORKSPACE}:/mnt \ - -e SECRET_KEY=\"${S3_SECRET}\" \ - -e ACCESS_KEY=\"${S3_KEY}\" \ - -t ghcr.io/linuxserver/lsiodev-spaces-file-upload:latest \ - python /upload.py''' + -v ${WORKSPACE}:/mnt \ + -e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \ + -e AWS_SECRET_ACCESS_KEY=\"${S3_SECRET}\" \ + ghcr.io/linuxserver/baseimage-alpine:3 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\ + apk add --no-cache python3 && \ + python3 -m venv /lsiopy && \ + pip install --no-cache-dir -U pip && \ + pip install --no-cache-dir s3cmd && \ + s3cmd put --no-preserve --acl-public -m text/xml /mnt/shellcheck-result.xml s3://ci-tests.linuxserver.io/${IMAGE}/${META_TAG}/shellcheck-result.xml" || :''' } } } // Use helper containers to render templated files stage('Update-Templates') { when { - branch "master" + branch "arch-i3" environment name: 'CHANGE_ID', value: '' expression { env.CONTAINER_NAME != null @@ -234,26 +306,34 @@ pipeline { set -e TEMPDIR=$(mktemp -d) docker pull ghcr.io/linuxserver/jenkins-builder:latest - docker run --rm -e CONTAINER_NAME=${CONTAINER_NAME} -e GITHUB_BRANCH=master -v ${TEMPDIR}:/ansible/jenkins ghcr.io/linuxserver/jenkins-builder:latest - # Stage 1 - Jenkinsfile update + # Cloned repo paths for templating: + # ${TEMPDIR}/docker-${CONTAINER_NAME}: Cloned branch arch-i3 of ${LS_USER}/${LS_REPO} for running the jenkins builder on + # ${TEMPDIR}/repo/${LS_REPO}: Cloned branch arch-i3 of ${LS_USER}/${LS_REPO} for commiting various templated file changes and pushing back to Github + # ${TEMPDIR}/docs/docker-documentation: Cloned docs repo for pushing docs updates to Github + # ${TEMPDIR}/unraid/docker-templates: Cloned docker-templates repo to check for logos + # ${TEMPDIR}/unraid/templates: Cloned templates repo for commiting unraid template changes and pushing back to Github + git clone --branch arch-i3 --depth 1 https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/docker-${CONTAINER_NAME} + docker run --rm -v ${TEMPDIR}/docker-${CONTAINER_NAME}:/tmp -e LOCAL=true -e PUID=$(id -u) -e PGID=$(id -g) ghcr.io/linuxserver/jenkins-builder:latest + echo "Starting Stage 1 - Jenkinsfile update" if [[ "$(md5sum Jenkinsfile | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile | awk '{ print $1 }')" ]]; then mkdir -p ${TEMPDIR}/repo git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO} cd ${TEMPDIR}/repo/${LS_REPO} - git checkout -f master + git checkout -f arch-i3 cp ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile ${TEMPDIR}/repo/${LS_REPO}/ git add Jenkinsfile git commit -m 'Bot Updating Templated Files' - git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all + git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git arch-i3 + git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git arch-i3 echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} - echo "Updating Jenkinsfile" + echo "Updating Jenkinsfile and exiting build, new one will trigger based on commit" rm -Rf ${TEMPDIR} exit 0 else echo "Jenkinsfile is up to date." fi - # Stage 2 - Delete old templates - OLD_TEMPLATES=".github/ISSUE_TEMPLATE.md" + echo "Starting Stage 2 - Delete old templates" + OLD_TEMPLATES=".github/ISSUE_TEMPLATE.md .github/ISSUE_TEMPLATE/issue.bug.md .github/ISSUE_TEMPLATE/issue.feature.md .github/workflows/call_invalid_helper.yml .github/workflows/stale.yml .github/workflows/package_trigger.yml" for i in ${OLD_TEMPLATES}; do if [[ -f "${i}" ]]; then TEMPLATES_TO_DELETE="${i} ${TEMPLATES_TO_DELETE}" @@ -263,20 +343,21 @@ pipeline { mkdir -p ${TEMPDIR}/repo git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO} cd ${TEMPDIR}/repo/${LS_REPO} - git checkout -f master + git checkout -f arch-i3 for i in ${TEMPLATES_TO_DELETE}; do git rm "${i}" done git commit -m 'Bot Updating Templated Files' - git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all + git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git arch-i3 + git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git arch-i3 echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} - echo "Deleting old templates" + echo "Deleting old/deprecated templates and exiting build, new one will trigger based on commit" rm -Rf ${TEMPDIR} exit 0 else echo "No templates to delete" fi - # Stage 3 - Update templates + echo "Starting Stage 3 - Update templates" CURRENTHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8) cd ${TEMPDIR}/docker-${CONTAINER_NAME} NEWHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8) @@ -284,50 +365,75 @@ pipeline { mkdir -p ${TEMPDIR}/repo git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO} cd ${TEMPDIR}/repo/${LS_REPO} - git checkout -f master + git checkout -f arch-i3 cd ${TEMPDIR}/docker-${CONTAINER_NAME} mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/workflows mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/ISSUE_TEMPLATE cp --parents ${TEMPLATED_FILES} ${TEMPDIR}/repo/${LS_REPO}/ || : + cp --parents readme-vars.yml ${TEMPDIR}/repo/${LS_REPO}/ || : cd ${TEMPDIR}/repo/${LS_REPO}/ if ! grep -q '.jenkins-external' .gitignore 2>/dev/null; then echo ".jenkins-external" >> .gitignore git add .gitignore fi - git add ${TEMPLATED_FILES} + git add readme-vars.yml ${TEMPLATED_FILES} git commit -m 'Bot Updating Templated Files' - git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all + git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git arch-i3 + git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git arch-i3 echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} + echo "Updating templates and exiting build, new one will trigger based on commit" + rm -Rf ${TEMPDIR} + exit 0 else echo "false" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER} + echo "No templates to update" fi - mkdir -p ${TEMPDIR}/gitbook - git clone https://github.com/linuxserver/docker-documentation.git ${TEMPDIR}/gitbook/docker-documentation - if [[ ("${BRANCH_NAME}" == "master") || ("${BRANCH_NAME}" == "main") ]] && [[ (! -f ${TEMPDIR}/gitbook/docker-documentation/images/docker-${CONTAINER_NAME}.md) || ("$(md5sum ${TEMPDIR}/gitbook/docker-documentation/images/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')") ]]; then - cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md ${TEMPDIR}/gitbook/docker-documentation/images/ - cd ${TEMPDIR}/gitbook/docker-documentation/ - git add images/docker-${CONTAINER_NAME}.md + echo "Starting Stage 4 - External repo updates: Docs, Unraid Template and Readme Sync to Docker Hub" + mkdir -p ${TEMPDIR}/docs + git clone --depth=1 https://github.com/linuxserver/docker-documentation.git ${TEMPDIR}/docs/docker-documentation + if [[ "${BRANCH_NAME}" == "${GH_DEFAULT_BRANCH}" ]] && [[ (! -f ${TEMPDIR}/docs/docker-documentation/docs/images/docker-${CONTAINER_NAME}.md) || ("$(md5sum ${TEMPDIR}/docs/docker-documentation/docs/images/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')") ]]; then + cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md ${TEMPDIR}/docs/docker-documentation/docs/images/ + cd ${TEMPDIR}/docs/docker-documentation + GH_DOCS_DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch:" | sed 's|.*HEAD branch: ||') + git add docs/images/docker-${CONTAINER_NAME}.md + echo "Updating docs repo" git commit -m 'Bot Updating Documentation' - git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git --all - fi - mkdir -p ${TEMPDIR}/unraid - git clone https://github.com/linuxserver/docker-templates.git ${TEMPDIR}/unraid/docker-templates - git clone https://github.com/linuxserver/templates.git ${TEMPDIR}/unraid/templates - if [[ -f ${TEMPDIR}/unraid/docker-templates/linuxserver.io/img/${CONTAINER_NAME}-logo.png ]]; then - sed -i "s|master/linuxserver.io/img/linuxserver-ls-logo.png|master/linuxserver.io/img/${CONTAINER_NAME}-logo.png|" ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml + git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH} --rebase + git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH} || \ + (MAXWAIT="10" && echo "Push to docs failed, trying again in ${MAXWAIT} seconds" && \ + sleep $((RANDOM % MAXWAIT)) && \ + git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH} --rebase && \ + git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git ${GH_DOCS_DEFAULT_BRANCH}) + else + echo "Docs update not needed, skipping" fi - if [[ ("${BRANCH_NAME}" == "master") || ("${BRANCH_NAME}" == "main") ]] && [[ (! -f ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml) || ("$(md5sum ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml | awk '{ print $1 }')") ]]; then - cd ${TEMPDIR}/unraid/templates/ - if grep -wq "${CONTAINER_NAME}" ${TEMPDIR}/unraid/templates/unraid/ignore.list; then - echo "Image is on the ignore list, removing Unraid template" - git rm unraid/${CONTAINER_NAME}.xml || : - git commit -m 'Bot Removing Deprecated Unraid Template' || : + if [[ "${BRANCH_NAME}" == "${GH_DEFAULT_BRANCH}" ]]; then + if [[ $(cat ${TEMPDIR}/docker-${CONTAINER_NAME}/README.md | wc -m) -gt 25000 ]]; then + echo "Readme is longer than 25,000 characters. Syncing the lite version to Docker Hub" + DH_README_SYNC_PATH="${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/README.lite" else - cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml ${TEMPDIR}/unraid/templates/unraid/ - git add unraid/${CONTAINER_NAME}.xml - git commit -m 'Bot Updating Unraid Template' + echo "Syncing readme to Docker Hub" + DH_README_SYNC_PATH="${TEMPDIR}/docker-${CONTAINER_NAME}/README.md" fi - git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git --all + if curl -s https://hub.docker.com/v2/namespaces/${DOCKERHUB_IMAGE%%/*}/repositories/${DOCKERHUB_IMAGE##*/}/tags | jq -r '.message' | grep -q 404; then + echo "Docker Hub endpoint doesn't exist. Creating endpoint first." + DH_TOKEN=$(curl -d '{"username":"linuxserverci", "password":"'${DOCKERHUB_TOKEN}'"}' -H "Content-Type: application/json" -X POST https://hub.docker.com/v2/users/login | jq -r '.token') + curl -s \ + -H "Authorization: JWT ${DH_TOKEN}" \ + -H "Content-Type: application/json" \ + -X POST \ + -d '{"name":"'${DOCKERHUB_IMAGE##*/}'", "namespace":"'${DOCKERHUB_IMAGE%%/*}'"}' \ + https://hub.docker.com/v2/repositories/ || : + fi + DH_TOKEN=$(curl -d '{"username":"linuxserverci", "password":"'${DOCKERHUB_TOKEN}'"}' -H "Content-Type: application/json" -X POST https://hub.docker.com/v2/users/login | jq -r '.token') + curl -s \ + -H "Authorization: JWT ${DH_TOKEN}" \ + -H "Content-Type: application/json" \ + -X PATCH \ + -d "{\\"full_description\\":$(jq -Rsa . ${DH_README_SYNC_PATH})}" \ + https://hub.docker.com/v2/repositories/${DOCKERHUB_IMAGE} || : + else + echo "Not the default Github branch. Skipping readme sync to Docker Hub." fi rm -Rf ${TEMPDIR}''' script{ @@ -340,7 +446,7 @@ pipeline { // Exit the build if the Templated files were just updated stage('Template-exit') { when { - branch "master" + branch "arch-i3" environment name: 'CHANGE_ID', value: '' environment name: 'FILES_UPDATED', value: 'true' expression { @@ -353,24 +459,48 @@ pipeline { } } } + // If this is a arch-i3 build check the S6 service file perms + stage("Check S6 Service file Permissions"){ + when { + branch "arch-i3" + environment name: 'CHANGE_ID', value: '' + environment name: 'EXIT_STATUS', value: '' + } + steps { + script{ + sh '''#! /bin/bash + WRONG_PERM=$(find ./ -path "./.git" -prune -o \\( -name "run" -o -name "finish" -o -name "check" \\) -not -perm -u=x,g=x,o=x -print) + if [[ -n "${WRONG_PERM}" ]]; then + echo "The following S6 service files are missing the executable bit; canceling the faulty build: ${WRONG_PERM}" + exit 1 + else + echo "S6 service file perms look good." + fi ''' + } + } + } /* ####################### - GitLab Mirroring + GitLab Mirroring and Quay.io Repo Visibility ####################### */ - // Ping into Gitlab to mirror this repo and have a registry endpoint - stage("GitLab Mirror"){ + // Ping into Gitlab to mirror this repo and have a registry endpoint & mark this repo on Quay.io as public + stage("GitLab Mirror and Quay.io Visibility"){ when { environment name: 'EXIT_STATUS', value: '' } steps{ sh '''curl -H "Content-Type: application/json" -H "Private-Token: ${GITLAB_TOKEN}" -X POST https://gitlab.com/api/v4/projects \ - -d '{"namespace_id":'${GITLAB_NAMESPACE}',\ - "name":"'${LS_REPO}'", - "mirror":true,\ - "import_url":"https://github.com/linuxserver/'${LS_REPO}'.git",\ - "issues_access_level":"disabled",\ - "merge_requests_access_level":"disabled",\ - "repository_access_level":"enabled",\ - "visibility":"public"}' ''' + -d '{"namespace_id":'${GITLAB_NAMESPACE}',\ + "name":"'${LS_REPO}'", + "mirror":true,\ + "import_url":"https://github.com/linuxserver/'${LS_REPO}'.git",\ + "issues_access_level":"disabled",\ + "merge_requests_access_level":"disabled",\ + "repository_access_level":"enabled",\ + "visibility":"public"}' ''' + sh '''curl -H "Private-Token: ${GITLAB_TOKEN}" -X PUT "https://gitlab.com/api/v4/projects/Linuxserver.io%2F${LS_REPO}" \ + -d "mirror=true&import_url=https://github.com/linuxserver/${LS_REPO}.git" ''' + sh '''curl -H "Content-Type: application/json" -H "Authorization: Bearer ${QUAYIO_API_TOKEN}" -X POST "https://quay.io/api/v1/repository${QUAYIMAGE/quay.io/}/changevisibility" \ + -d '{"visibility":"public"}' ||: ''' } } /* ############### @@ -380,13 +510,14 @@ pipeline { stage('Build-Single') { when { expression { - env.MULTIARCH == 'false' || params.PACKAGE_CHECK == 'true' + env.MULTIARCH == 'false' || params.PACKAGE_CHECK == 'true' } environment name: 'EXIT_STATUS', value: '' } steps { echo "Running on node: ${NODE_NAME}" - sh "docker build \ + sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile" + sh "docker buildx build \ --label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ --label \"org.opencontainers.image.authors=linuxserver.io\" \ --label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-webtop/packages\" \ @@ -398,9 +529,47 @@ pipeline { --label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ --label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ --label \"org.opencontainers.image.title=Webtop\" \ - --label \"org.opencontainers.image.description=[Webtop](https://github.com/linuxserver/docker-webtop) - Alpine and Ubuntu based containers containing full desktop environments in officially supported flavors accessible via any modern web browser. \" \ - --no-cache --pull -t ${IMAGE}:${META_TAG} \ + --label \"org.opencontainers.image.description=webtop image by linuxserver.io\" \ + --no-cache --pull -t ${IMAGE}:${META_TAG} --platform=linux/amd64 \ + --provenance=true --sbom=true --builder=container --load \ --build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." + sh '''#! /bin/bash + set -e + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker tag ${IMAGE}:${META_TAG} ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} + done + ''' + withCredentials([ + [ + $class: 'UsernamePasswordMultiBinding', + credentialsId: 'Quay.io-Robot', + usernameVariable: 'QUAYUSER', + passwordVariable: 'QUAYPASS' + ] + ]) { + retry_backoff(5,5) { + sh '''#! /bin/bash + set -e + echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin + echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin + echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin + echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin + + if [[ "${PACKAGE_CHECK}" != "true" ]]; then + declare -A pids + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} & + pids[$!]="$i" + done + for p in "${!pids[@]}"; do + wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* ]] && exit 1; } + done + fi + ''' + } + } } } // Build MultiArch Docker containers for push to LS Repo @@ -416,7 +585,8 @@ pipeline { stage('Build X86') { steps { echo "Running on node: ${NODE_NAME}" - sh "docker build \ + sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile" + sh "docker buildx build \ --label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ --label \"org.opencontainers.image.authors=linuxserver.io\" \ --label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-webtop/packages\" \ @@ -428,43 +598,47 @@ pipeline { --label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ --label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ --label \"org.opencontainers.image.title=Webtop\" \ - --label \"org.opencontainers.image.description=[Webtop](https://github.com/linuxserver/docker-webtop) - Alpine and Ubuntu based containers containing full desktop environments in officially supported flavors accessible via any modern web browser. \" \ - --no-cache --pull -t ${IMAGE}:amd64-${META_TAG} \ + --label \"org.opencontainers.image.description=webtop image by linuxserver.io\" \ + --no-cache --pull -t ${IMAGE}:amd64-${META_TAG} --platform=linux/amd64 \ + --provenance=true --sbom=true --builder=container --load \ --build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." - } - } - stage('Build ARMHF') { - agent { - label 'ARMHF' - } - steps { - echo "Running on node: ${NODE_NAME}" - echo 'Logging into Github' sh '''#! /bin/bash - echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin + set -e + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker tag ${IMAGE}:amd64-${META_TAG} ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} + done ''' - sh "docker build \ - --label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ - --label \"org.opencontainers.image.authors=linuxserver.io\" \ - --label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-webtop/packages\" \ - --label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-webtop\" \ - --label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-webtop\" \ - --label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \ - --label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \ - --label \"org.opencontainers.image.vendor=linuxserver.io\" \ - --label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ - --label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ - --label \"org.opencontainers.image.title=Webtop\" \ - --label \"org.opencontainers.image.description=[Webtop](https://github.com/linuxserver/docker-webtop) - Alpine and Ubuntu based containers containing full desktop environments in officially supported flavors accessible via any modern web browser. \" \ - --no-cache --pull -f Dockerfile.armhf -t ${IMAGE}:arm32v7-${META_TAG} \ - --build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." - sh "docker tag ${IMAGE}:arm32v7-${META_TAG} ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER}" - retry(5) { - sh "docker push ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER}" + withCredentials([ + [ + $class: 'UsernamePasswordMultiBinding', + credentialsId: 'Quay.io-Robot', + usernameVariable: 'QUAYUSER', + passwordVariable: 'QUAYPASS' + ] + ]) { + retry_backoff(5,5) { + sh '''#! /bin/bash + set -e + echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin + echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin + echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin + echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin + + if [[ "${PACKAGE_CHECK}" != "true" ]]; then + declare -A pids + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} & + pids[$!]="$i" + done + for p in "${!pids[@]}"; do + wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* ]] && exit 1; } + done + fi + ''' + } } - sh '''docker rmi \ - ${IMAGE}:arm32v7-${META_TAG} \ - ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} || :''' } } stage('Build ARM64') { @@ -473,11 +647,8 @@ pipeline { } steps { echo "Running on node: ${NODE_NAME}" - echo 'Logging into Github' - sh '''#! /bin/bash - echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin - ''' - sh "docker build \ + sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile.aarch64" + sh "docker buildx build \ --label \"org.opencontainers.image.created=${GITHUB_DATE}\" \ --label \"org.opencontainers.image.authors=linuxserver.io\" \ --label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-webtop/packages\" \ @@ -489,16 +660,54 @@ pipeline { --label \"org.opencontainers.image.licenses=GPL-3.0-only\" \ --label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \ --label \"org.opencontainers.image.title=Webtop\" \ - --label \"org.opencontainers.image.description=[Webtop](https://github.com/linuxserver/docker-webtop) - Alpine and Ubuntu based containers containing full desktop environments in officially supported flavors accessible via any modern web browser. \" \ - --no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} \ + --label \"org.opencontainers.image.description=webtop image by linuxserver.io\" \ + --no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} --platform=linux/arm64 \ + --provenance=true --sbom=true --builder=container --load \ --build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ." - sh "docker tag ${IMAGE}:arm64v8-${META_TAG} ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}" - retry(5) { - sh "docker push ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}" + sh '''#! /bin/bash + set -e + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker tag ${IMAGE}:arm64v8-${META_TAG} ${i}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} + done + ''' + withCredentials([ + [ + $class: 'UsernamePasswordMultiBinding', + credentialsId: 'Quay.io-Robot', + usernameVariable: 'QUAYUSER', + passwordVariable: 'QUAYPASS' + ] + ]) { + retry_backoff(5,5) { + sh '''#! /bin/bash + set -e + echo $DOCKERHUB_TOKEN | docker login -u linuxserverci --password-stdin + echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin + echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin + echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin + if [[ "${PACKAGE_CHECK}" != "true" ]]; then + declare -A pids + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + docker push ${i}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} & + pids[$!]="$i" + done + for p in "${!pids[@]}"; do + wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* ]] && exit 1; } + done + fi + ''' + } } - sh '''docker rmi \ - ${IMAGE}:arm64v8-${META_TAG} \ - ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || :''' + sh '''#! /bin/bash + containers=$(docker ps -aq) + if [[ -n "${containers}" ]]; then + docker stop ${containers} + fi + docker system prune -f --volumes || : + docker image prune -af || : + ''' } } } @@ -506,7 +715,7 @@ pipeline { // Take the image we just built and dump package versions for comparison stage('Update-packages') { when { - branch "master" + branch "arch-i3" environment name: 'CHANGE_ID', value: '' environment name: 'EXIT_STATUS', value: '' } @@ -514,42 +723,29 @@ pipeline { sh '''#! /bin/bash set -e TEMPDIR=$(mktemp -d) - if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" == "false" ]; then + if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" != "true" ]; then LOCAL_CONTAINER=${IMAGE}:amd64-${META_TAG} else LOCAL_CONTAINER=${IMAGE}:${META_TAG} fi - if [ "${DIST_IMAGE}" == "alpine" ]; then - docker run --rm --entrypoint '/bin/sh' -v ${TEMPDIR}:/tmp ${LOCAL_CONTAINER} -c '\ - apk info -v > /tmp/package_versions.txt && \ - sort -o /tmp/package_versions.txt /tmp/package_versions.txt && \ - chmod 777 /tmp/package_versions.txt' - elif [ "${DIST_IMAGE}" == "ubuntu" ]; then - docker run --rm --entrypoint '/bin/sh' -v ${TEMPDIR}:/tmp ${LOCAL_CONTAINER} -c '\ - apt list -qq --installed | sed "s#/.*now ##g" | cut -d" " -f1 > /tmp/package_versions.txt && \ - sort -o /tmp/package_versions.txt /tmp/package_versions.txt && \ - chmod 777 /tmp/package_versions.txt' - elif [ "${DIST_IMAGE}" == "fedora" ]; then - docker run --rm --entrypoint '/bin/sh' -v ${TEMPDIR}:/tmp ${LOCAL_CONTAINER} -c '\ - rpm -qa > /tmp/package_versions.txt && \ - sort -o /tmp/package_versions.txt /tmp/package_versions.txt && \ - chmod 777 /tmp/package_versions.txt' - elif [ "${DIST_IMAGE}" == "arch" ]; then - docker run --rm --entrypoint '/bin/sh' -v ${TEMPDIR}:/tmp ${LOCAL_CONTAINER} -c '\ - pacman -Q > /tmp/package_versions.txt && \ - chmod 777 /tmp/package_versions.txt' - fi + touch ${TEMPDIR}/package_versions.txt + docker run --rm \ + -v /var/run/docker.sock:/var/run/docker.sock:ro \ + -v ${TEMPDIR}:/tmp \ + ghcr.io/anchore/syft:${SYFT_IMAGE_TAG} \ + ${LOCAL_CONTAINER} -o table=/tmp/package_versions.txt NEW_PACKAGE_TAG=$(md5sum ${TEMPDIR}/package_versions.txt | cut -c1-8 ) echo "Package tag sha from current packages in buit container is ${NEW_PACKAGE_TAG} comparing to old ${PACKAGE_TAG} from github" if [ "${NEW_PACKAGE_TAG}" != "${PACKAGE_TAG}" ]; then git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/${LS_REPO} - git --git-dir ${TEMPDIR}/${LS_REPO}/.git checkout -f master + git --git-dir ${TEMPDIR}/${LS_REPO}/.git checkout -f arch-i3 cp ${TEMPDIR}/package_versions.txt ${TEMPDIR}/${LS_REPO}/ cd ${TEMPDIR}/${LS_REPO}/ wait git add package_versions.txt git commit -m 'Bot Updating Package Versions' - git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all + git pull https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git arch-i3 + git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git arch-i3 echo "true" > /tmp/packages-${COMMIT_SHA}-${BUILD_NUMBER} echo "Package tag updated, stopping build process" else @@ -567,19 +763,12 @@ pipeline { // Exit the build if the package file was just updated stage('PACKAGE-exit') { when { - branch "master" + branch "arch-i3" environment name: 'CHANGE_ID', value: '' environment name: 'PACKAGE_UPDATED', value: 'true' environment name: 'EXIT_STATUS', value: '' } steps { - sh '''#! /bin/bash - echo "Packages were updated. Cleaning up the image and exiting." - if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" == "false" ]; then - docker rmi ${IMAGE}:amd64-${META_TAG} - else - docker rmi ${IMAGE}:${META_TAG} - fi''' script{ env.EXIT_STATUS = 'ABORTED' } @@ -588,7 +777,7 @@ pipeline { // Exit the build if this is just a package check and there are no changes to push stage('PACKAGECHECK-exit') { when { - branch "master" + branch "arch-i3" environment name: 'CHANGE_ID', value: '' environment name: 'PACKAGE_UPDATED', value: 'false' environment name: 'EXIT_STATUS', value: '' @@ -597,13 +786,6 @@ pipeline { } } steps { - sh '''#! /bin/bash - echo "There are no package updates. Cleaning up the image and exiting." - if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" == "false" ]; then - docker rmi ${IMAGE}:amd64-${META_TAG} - else - docker rmi ${IMAGE}:${META_TAG} - fi''' script{ env.EXIT_STATUS = 'ABORTED' } @@ -625,23 +807,31 @@ pipeline { ]) { script{ env.CI_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/index.html' + env.CI_JSON_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/report.json' } sh '''#! /bin/bash set -e - docker pull ghcr.io/linuxserver/ci:latest + if grep -q 'docker-baseimage' <<< "${LS_REPO}"; then + echo "Detected baseimage, setting LSIO_FIRST_PARTY=true" + if [ -n "${CI_DOCKERENV}" ]; then + CI_DOCKERENV="LSIO_FIRST_PARTY=true|${CI_DOCKERENV}" + else + CI_DOCKERENV="LSIO_FIRST_PARTY=true" + fi + fi + docker pull ghcr.io/linuxserver/ci:${CITEST_IMAGETAG} if [ "${MULTIARCH}" == "true" ]; then - docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} - docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} - docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm32v7-${META_TAG} + docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} --platform=arm64 docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG} fi docker run --rm \ --shm-size=1gb \ -v /var/run/docker.sock:/var/run/docker.sock \ -e IMAGE=\"${IMAGE}\" \ - -e DELAY_START=\"${CI_DELAY}\" \ + -e DOCKER_LOGS_TIMEOUT=\"${CI_DELAY}\" \ -e TAGS=\"${CI_TAGS}\" \ -e META_TAG=\"${META_TAG}\" \ + -e RELEASE_TAG=\"arch-i3\" \ -e PORT=\"${CI_PORT}\" \ -e SSL=\"${CI_SSL}\" \ -e BASE=\"${DIST_IMAGE}\" \ @@ -651,10 +841,12 @@ pipeline { -e WEB_SCREENSHOT=\"${CI_WEB}\" \ -e WEB_AUTH=\"${CI_AUTH}\" \ -e WEB_PATH=\"${CI_WEBPATH}\" \ - -e DO_REGION="ams3" \ - -e DO_BUCKET="lsio-ci" \ - -t ghcr.io/linuxserver/ci:latest \ - python /ci/ci.py''' + -e NODE_NAME=\"${NODE_NAME}\" \ + -e SYFT_IMAGE_TAG=\"${CI_SYFT_IMAGE_TAG:-${SYFT_IMAGE_TAG}}\" \ + -e COMMIT_SHA=\"${COMMIT_SHA}\" \ + -e BUILD_NUMBER=\"${BUILD_NUMBER}\" \ + -t ghcr.io/linuxserver/ci:${CITEST_IMAGETAG} \ + python3 test_build.py''' } } } @@ -668,38 +860,25 @@ pipeline { environment name: 'EXIT_STATUS', value: '' } steps { - withCredentials([ - [ - $class: 'UsernamePasswordMultiBinding', - credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207', - usernameVariable: 'DOCKERUSER', - passwordVariable: 'DOCKERPASS' - ] - ]) { - retry(5) { - sh '''#! /bin/bash - set -e - echo $DOCKERPASS | docker login -u $DOCKERUSER --password-stdin - echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin - echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin - for PUSHIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${IMAGE}"; do - docker tag ${IMAGE}:${META_TAG} ${PUSHIMAGE}:${META_TAG} - docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:latest - docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${EXT_RELEASE_TAG} - docker push ${PUSHIMAGE}:latest - docker push ${PUSHIMAGE}:${META_TAG} - docker push ${PUSHIMAGE}:${EXT_RELEASE_TAG} - done - ''' - } + retry_backoff(5,5) { sh '''#! /bin/bash - for DELETEIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${IMAGE}"; do - docker rmi \ - ${DELETEIMAGE}:${META_TAG} \ - ${DELETEIMAGE}:${EXT_RELEASE_TAG} \ - ${DELETEIMAGE}:latest || : + set -e + for PUSHIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do + [[ ${PUSHIMAGE%%/*} =~ \\. ]] && PUSHIMAGEPLUS="${PUSHIMAGE}" || PUSHIMAGEPLUS="docker.io/${PUSHIMAGE}" + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + if [[ "${PUSHIMAGEPLUS}" == "$(cut -d "/" -f1 <<< ${i})"* ]]; then + CACHEIMAGE=${i} + fi + done + docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${META_TAG} -t ${PUSHIMAGE}:arch-i3 -t ${PUSHIMAGE}:${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \ + { if [[ "${PUSHIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + if [ -n "${SEMVER}" ]; then + docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \ + { if [[ "${PUSHIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + fi done - ''' + ''' } } } @@ -710,87 +889,48 @@ pipeline { environment name: 'EXIT_STATUS', value: '' } steps { - withCredentials([ - [ - $class: 'UsernamePasswordMultiBinding', - credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207', - usernameVariable: 'DOCKERUSER', - passwordVariable: 'DOCKERPASS' - ] - ]) { - retry(5) { - sh '''#! /bin/bash - set -e - echo $DOCKERPASS | docker login -u $DOCKERUSER --password-stdin - echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin - echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin - if [ "${CI}" == "false" ]; then - docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} - docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} - docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm32v7-${META_TAG} - docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG} - fi - for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}"; do - docker tag ${IMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} - docker tag ${IMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm32v7-${META_TAG} - docker tag ${IMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} - docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-latest - docker tag ${MANIFESTIMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm32v7-latest - docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-latest - docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} - docker tag ${MANIFESTIMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm32v7-${EXT_RELEASE_TAG} - docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} - docker push ${MANIFESTIMAGE}:amd64-${META_TAG} - docker push ${MANIFESTIMAGE}:arm32v7-${META_TAG} - docker push ${MANIFESTIMAGE}:arm64v8-${META_TAG} - docker push ${MANIFESTIMAGE}:amd64-latest - docker push ${MANIFESTIMAGE}:arm32v7-latest - docker push ${MANIFESTIMAGE}:arm64v8-latest - docker push ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} - docker push ${MANIFESTIMAGE}:arm32v7-${EXT_RELEASE_TAG} - docker push ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} - docker manifest push --purge ${MANIFESTIMAGE}:latest || : - docker manifest create ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:amd64-latest ${MANIFESTIMAGE}:arm32v7-latest ${MANIFESTIMAGE}:arm64v8-latest - docker manifest annotate ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:arm32v7-latest --os linux --arch arm - docker manifest annotate ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:arm64v8-latest --os linux --arch arm64 --variant v8 - docker manifest push --purge ${MANIFESTIMAGE}:${META_TAG} || : - docker manifest create ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} - docker manifest annotate ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:arm32v7-${META_TAG} --os linux --arch arm - docker manifest annotate ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} --os linux --arch arm64 --variant v8 - docker manifest push --purge ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} || : - docker manifest create ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm32v7-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} - docker manifest annotate ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm32v7-${EXT_RELEASE_TAG} --os linux --arch arm - docker manifest annotate ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} --os linux --arch arm64 --variant v8 - docker manifest push --purge ${MANIFESTIMAGE}:latest - docker manifest push --purge ${MANIFESTIMAGE}:${META_TAG} - docker manifest push --purge ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} - done - ''' - } + retry_backoff(5,5) { sh '''#! /bin/bash - for DELETEIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${IMAGE}"; do - docker rmi \ - ${DELETEIMAGE}:amd64-${META_TAG} \ - ${DELETEIMAGE}:amd64-latest \ - ${DELETEIMAGE}:amd64-${EXT_RELEASE_TAG} \ - ${DELETEIMAGE}:arm32v7-${META_TAG} \ - ${DELETEIMAGE}:arm32v7-latest \ - ${DELETEIMAGE}:arm32v7-${EXT_RELEASE_TAG} \ - ${DELETEIMAGE}:arm64v8-${META_TAG} \ - ${DELETEIMAGE}:arm64v8-latest \ - ${DELETEIMAGE}:arm64v8-${EXT_RELEASE_TAG} || : + set -e + for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do + [[ ${MANIFESTIMAGE%%/*} =~ \\. ]] && MANIFESTIMAGEPLUS="${MANIFESTIMAGE}" || MANIFESTIMAGEPLUS="docker.io/${MANIFESTIMAGE}" + IFS=',' read -ra CACHE <<< "$BUILDCACHE" + for i in "${CACHE[@]}"; do + if [[ "${MANIFESTIMAGEPLUS}" == "$(cut -d "/" -f1 <<< ${i})"* ]]; then + CACHEIMAGE=${i} + fi + done + docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${META_TAG} -t ${MANIFESTIMAGE}:amd64-arch-i3 -t ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \ + { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${META_TAG} -t ${MANIFESTIMAGE}:arm64v8-arch-i3 -t ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || \ + { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + if [ -n "${SEMVER}" ]; then + docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \ + { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${SEMVER} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || \ + { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + fi + done + for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do + docker buildx imagetools create -t ${MANIFESTIMAGE}:arch-i3 ${MANIFESTIMAGE}:amd64-arch-i3 ${MANIFESTIMAGE}:arm64v8-arch-i3 || \ + { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + docker buildx imagetools create -t ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} || \ + { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + docker buildx imagetools create -t ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} || \ + { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + if [ -n "${SEMVER}" ]; then + docker buildx imagetools create -t ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} || \ + { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; } + fi done - docker rmi \ - ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} \ - ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || : - ''' + ''' } } } // If this is a public release tag it in the LS Github stage('Github-Tag-Push-Release') { when { - branch "master" + branch "arch-i3" expression { env.LS_RELEASE != env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER } @@ -798,68 +938,154 @@ pipeline { environment name: 'EXIT_STATUS', value: '' } steps { - echo "Pushing New tag for current commit ${META_TAG}" - sh '''curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/git/tags \ - -d '{"tag":"'${META_TAG}'",\ - "object": "'${COMMIT_SHA}'",\ - "message": "Tagging Release '${EXT_RELEASE_CLEAN}'-ls'${LS_TAG_NUMBER}' to master",\ - "type": "commit",\ - "tagger": {"name": "LinuxServer Jenkins","email": "jenkins@linuxserver.io","date": "'${GITHUB_DATE}'"}}' ''' - echo "Pushing New release for Tag" sh '''#! /bin/bash - echo "Updating external repo packages to ${EXT_RELEASE_CLEAN}" > releasebody.json - echo '{"tag_name":"'${META_TAG}'",\ - "target_commitish": "master",\ - "name": "'${META_TAG}'",\ - "body": "**LinuxServer Changes:**\\n\\n'${LS_RELEASE_NOTES}'\\n\\n**Repo Changes:**\\n\\n' > start - printf '","draft": false,"prerelease": false}' >> releasebody.json - paste -d'\\0' start releasebody.json > releasebody.json.done - curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases -d @releasebody.json.done''' + echo "Auto-generating release notes" + if [ "$(git tag --points-at HEAD)" != "" ]; then + echo "Existing tag points to current commit, suggesting no new LS changes" + AUTO_RELEASE_NOTES="No changes" + else + AUTO_RELEASE_NOTES=$(curl -fsL -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github+json" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases/generate-notes \ + -d '{"tag_name":"'${META_TAG}'",\ + "target_commitish": "arch-i3"}' \ + | jq -r '.body' | sed 's|## What.s Changed||') + fi + echo "Pushing New tag for current commit ${META_TAG}" + curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/git/tags \ + -d '{"tag":"'${META_TAG}'",\ + "object": "'${COMMIT_SHA}'",\ + "message": "Tagging Release '${EXT_RELEASE_CLEAN}'-ls'${LS_TAG_NUMBER}' to arch-i3",\ + "type": "commit",\ + "tagger": {"name": "LinuxServer-CI","email": "ci@linuxserver.io","date": "'${GITHUB_DATE}'"}}' + echo "Pushing New release for Tag" + echo "Updating to ${EXT_RELEASE_CLEAN}" > releasebody.json + jq -n \ + --arg tag_name "$META_TAG" \ + --arg target_commitish "arch-i3" \ + --arg ci_url "${CI_URL:-N/A}" \ + --arg ls_notes "$AUTO_RELEASE_NOTES" \ + --arg remote_notes "$(cat releasebody.json)" \ + '{ + "tag_name": $tag_name, + "target_commitish": $target_commitish, + "name": $tag_name, + "body": ("**CI Report:**\\n\\n" + $ci_url + "\\n\\n**LinuxServer Changes:**\\n\\n" + $ls_notes + "\\n\\n**Remote Changes:**\\n\\n" + $remote_notes), + "draft": false, + "prerelease": true }' > releasebody.json.done + curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases -d @releasebody.json.done + ''' } } - // Use helper container to sync the current README on master to the dockerhub endpoint - stage('Sync-README') { + // Add protection to the release branch + stage('Github-Release-Branch-Protection') { when { + branch "arch-i3" environment name: 'CHANGE_ID', value: '' environment name: 'EXIT_STATUS', value: '' } steps { - withCredentials([ - [ - $class: 'UsernamePasswordMultiBinding', - credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207', - usernameVariable: 'DOCKERUSER', - passwordVariable: 'DOCKERPASS' - ] - ]) { - sh '''#! /bin/bash - set -e - TEMPDIR=$(mktemp -d) - docker pull ghcr.io/linuxserver/jenkins-builder:latest - docker run --rm -e CONTAINER_NAME=${CONTAINER_NAME} -e GITHUB_BRANCH="${BRANCH_NAME}" -v ${TEMPDIR}:/ansible/jenkins ghcr.io/linuxserver/jenkins-builder:latest - docker pull ghcr.io/linuxserver/readme-sync - docker run --rm=true \ - -e DOCKERHUB_USERNAME=$DOCKERUSER \ - -e DOCKERHUB_PASSWORD=$DOCKERPASS \ - -e GIT_REPOSITORY=${LS_USER}/${LS_REPO} \ - -e DOCKER_REPOSITORY=${IMAGE} \ - -e GIT_BRANCH=master \ - -v ${TEMPDIR}/docker-${CONTAINER_NAME}:/mnt \ - ghcr.io/linuxserver/readme-sync bash -c 'node sync' - rm -Rf ${TEMPDIR} ''' - } + echo "Setting up protection for release branch arch-i3" + sh '''#! /bin/bash + curl -H "Authorization: token ${GITHUB_TOKEN}" -X PUT https://api.github.com/repos/${LS_USER}/${LS_REPO}/branches/arch-i3/protection \ + -d $(jq -c . << EOF + { + "required_status_checks": null, + "enforce_admins": false, + "required_pull_request_reviews": { + "dismiss_stale_reviews": false, + "require_code_owner_reviews": false, + "require_last_push_approval": false, + "required_approving_review_count": 1 + }, + "restrictions": null, + "required_linear_history": false, + "allow_force_pushes": false, + "allow_deletions": false, + "block_creations": false, + "required_conversation_resolution": true, + "lock_branch": false, + "allow_fork_syncing": false, + "required_signatures": false + } +EOF + ) ''' } } // If this is a Pull request send the CI link as a comment on it stage('Pull Request Comment') { when { not {environment name: 'CHANGE_ID', value: ''} - environment name: 'CI', value: 'true' environment name: 'EXIT_STATUS', value: '' } steps { - sh '''curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/issues/${PULL_REQUEST}/comments \ - -d '{"body": "I am a bot, here are the test results for this PR: \\n'${CI_URL}' \\n'${SHELLCHECK_URL}'"}' ''' + sh '''#! /bin/bash + # Function to retrieve JSON data from URL + get_json() { + local url="$1" + local response=$(curl -s "$url") + if [ $? -ne 0 ]; then + echo "Failed to retrieve JSON data from $url" + return 1 + fi + local json=$(echo "$response" | jq .) + if [ $? -ne 0 ]; then + echo "Failed to parse JSON data from $url" + return 1 + fi + echo "$json" + } + + build_table() { + local data="$1" + + # Get the keys in the JSON data + local keys=$(echo "$data" | jq -r 'to_entries | map(.key) | .[]') + + # Check if keys are empty + if [ -z "$keys" ]; then + echo "JSON report data does not contain any keys or the report does not exist." + return 1 + fi + + # Build table header + local header="| Tag | Passed |\\n| --- | --- |\\n" + + # Loop through the JSON data to build the table rows + local rows="" + for build in $keys; do + local status=$(echo "$data" | jq -r ".[\\"$build\\"].test_success") + if [ "$status" = "true" ]; then + status="✅" + else + status="❌" + fi + local row="| "$build" | "$status" |\\n" + rows="${rows}${row}" + done + + local table="${header}${rows}" + local escaped_table=$(echo "$table" | sed 's/\"/\\\\"/g') + echo "$escaped_table" + } + + if [[ "${CI}" = "true" ]]; then + # Retrieve JSON data from URL + data=$(get_json "$CI_JSON_URL") + # Create table from JSON data + table=$(build_table "$data") + echo -e "$table" + + curl -X POST -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \ + -d "{\\"body\\": \\"I am a bot, here are the test results for this PR: \\n${CI_URL}\\n${SHELLCHECK_URL}\\n${table}\\"}" + else + curl -X POST -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \ + -d "{\\"body\\": \\"I am a bot, here is the pushed image/manifest for this PR: \\n\\n\\`${GITHUBIMAGE}:${META_TAG}\\`\\"}" + fi + ''' + } } } @@ -868,24 +1094,94 @@ pipeline { ###################### */ post { always { + sh '''#!/bin/bash + rm -rf /config/.ssh/id_sign + rm -rf /config/.ssh/id_sign.pub + git config --global --unset gpg.format + git config --global --unset user.signingkey + git config --global --unset commit.gpgsign + ''' script{ + env.JOB_DATE = sh( + script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''', + returnStdout: true).trim() if (env.EXIT_STATUS == "ABORTED"){ sh 'echo "build aborted"' - } - else if (currentBuild.currentResult == "SUCCESS"){ - sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://wiki.jenkins-ci.org/download/attachments/2916393/headshot.png","embeds": [{"color": 1681177,\ - "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** Success\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ - "username": "Jenkins"}' ${BUILDS_DISCORD} ''' - } - else { - sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://wiki.jenkins-ci.org/download/attachments/2916393/headshot.png","embeds": [{"color": 16711680,\ - "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** failure\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ + }else{ + if (currentBuild.currentResult == "SUCCESS"){ + if (env.GITHUBIMAGE =~ /lspipepr/){ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=3957028 + env.JOB_WEBHOOK_FOOTER='PR Build' + }else if (env.GITHUBIMAGE =~ /lsiodev/){ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=3957028 + env.JOB_WEBHOOK_FOOTER='Dev Build' + }else{ + env.JOB_WEBHOOK_STATUS='Success' + env.JOB_WEBHOOK_COLOUR=1681177 + env.JOB_WEBHOOK_FOOTER='Live Build' + } + }else{ + if (env.GITHUBIMAGE =~ /lspipepr/){ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=12669523 + env.JOB_WEBHOOK_FOOTER='PR Build' + }else if (env.GITHUBIMAGE =~ /lsiodev/){ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=12669523 + env.JOB_WEBHOOK_FOOTER='Dev Build' + }else{ + env.JOB_WEBHOOK_STATUS='Failure' + env.JOB_WEBHOOK_COLOUR=16711680 + env.JOB_WEBHOOK_FOOTER='Live Build' + } + } + sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"'color'": '${JOB_WEBHOOK_COLOUR}',\ + "footer": {"text" : "'"${JOB_WEBHOOK_FOOTER}"'"},\ + "timestamp": "'${JOB_DATE}'",\ + "description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** '${JOB_WEBHOOK_STATUS}'\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\ "username": "Jenkins"}' ${BUILDS_DISCORD} ''' } } } cleanup { + sh '''#! /bin/bash + echo "Pruning builder!!" + docker builder prune -f --builder container || : + containers=$(docker ps -q) + if [[ -n "${containers}" ]]; then + BUILDX_CONTAINER_ID=$(docker ps -qf 'name=buildx_buildkit') + for container in ${containers}; do + if [[ "${container}" == "${BUILDX_CONTAINER_ID}" ]]; then + echo "skipping buildx container in docker stop" + else + echo "Stopping container ${container}" + docker stop ${container} + fi + done + fi + docker system prune -f --volumes || : + docker image prune -af || : + ''' cleanWs() } } } + +def retry_backoff(int max_attempts, int power_base, Closure c) { + int n = 0 + while (n < max_attempts) { + try { + c() + return + } catch (err) { + if ((n + 1) >= max_attempts) { + throw err + } + sleep(power_base ** n) + n++ + } + } + return +} diff --git a/README.md b/README.md index 3af27394d..32d6a1831 100644 --- a/README.md +++ b/README.md @@ -1,271 +1,3 @@ -<!-- DO NOT EDIT THIS FILE MANUALLY --> -<!-- Please read the https://github.com/linuxserver/docker-webtop/blob/master/.github/CONTRIBUTING.md --> - -[![linuxserver.io](https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/linuxserver_medium.png)](https://linuxserver.io) - -[![Blog](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=Blog)](https://blog.linuxserver.io "all the things you can do with our containers including How-To guides, opinions and much more!") -[![Discord](https://img.shields.io/discord/354974912613449730.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Discord&logo=discord)](https://discord.gg/YWrKVTn "realtime support / chat with the community and the team.") -[![Discourse](https://img.shields.io/discourse/https/discourse.linuxserver.io/topics.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=discourse)](https://discourse.linuxserver.io "post on our community forum.") -[![Fleet](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=Fleet)](https://fleet.linuxserver.io "an online web interface which displays all of our maintained images.") -[![GitHub](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub&logo=github)](https://github.com/linuxserver "view the source for all of our repositories.") -[![Open Collective](https://img.shields.io/opencollective/all/linuxserver.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Supporters&logo=open%20collective)](https://opencollective.com/linuxserver "please consider helping us by either donating or contributing to our budget") - -The [LinuxServer.io](https://linuxserver.io) team brings you another container release featuring: - -* regular and timely application updates -* easy user mappings (PGID, PUID) -* custom base image with s6 overlay -* weekly base OS updates with common layers across the entire LinuxServer.io ecosystem to minimise space usage, down time and bandwidth -* regular security updates - -Find us at: - -* [Blog](https://blog.linuxserver.io) - all the things you can do with our containers including How-To guides, opinions and much more! -* [Discord](https://discord.gg/YWrKVTn) - realtime support / chat with the community and the team. -* [Discourse](https://discourse.linuxserver.io) - post on our community forum. -* [Fleet](https://fleet.linuxserver.io) - an online web interface which displays all of our maintained images. -* [GitHub](https://github.com/linuxserver) - view the source for all of our repositories. -* [Open Collective](https://opencollective.com/linuxserver) - please consider helping us by either donating or contributing to our budget - -# [linuxserver/webtop](https://github.com/linuxserver/docker-webtop) - -[![GitHub Stars](https://img.shields.io/github/stars/linuxserver/docker-webtop.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/linuxserver/docker-webtop) -[![GitHub Release](https://img.shields.io/github/release/linuxserver/docker-webtop.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/linuxserver/docker-webtop/releases) -[![GitHub Package Repository](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub%20Package&logo=github)](https://github.com/linuxserver/docker-webtop/packages) -[![GitLab Container Registry](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitLab%20Registry&logo=gitlab)](https://gitlab.com/linuxserver.io/docker-webtop/container_registry) -[![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/webtop.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=pulls&logo=docker)](https://hub.docker.com/r/linuxserver/webtop) -[![Docker Stars](https://img.shields.io/docker/stars/linuxserver/webtop.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=stars&logo=docker)](https://hub.docker.com/r/linuxserver/webtop) -[![Jenkins Build](https://img.shields.io/jenkins/build?labelColor=555555&logoColor=ffffff&style=for-the-badge&jobUrl=https%3A%2F%2Fci.linuxserver.io%2Fjob%2FDocker-Pipeline-Builders%2Fjob%2Fdocker-webtop%2Fjob%2Fmaster%2F&logo=jenkins)](https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-webtop/job/master/) -[![LSIO CI](https://img.shields.io/badge/dynamic/yaml?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=CI&query=CI&url=https%3A%2F%2Fci-tests.linuxserver.io%2Flinuxserver%2Fwebtop%2Flatest%2Fci-status.yml)](https://ci-tests.linuxserver.io/linuxserver/webtop/latest/index.html) - -[Webtop](https://github.com/linuxserver/docker-webtop) - Alpine and Ubuntu based containers containing full desktop environments in officially supported flavors accessible via any modern web browser. - -[![webtop](https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/webtop-logo.png)](https://github.com/linuxserver/docker-webtop) - -## Supported Architectures - -Our images support multiple architectures such as `x86-64`, `arm64` and `armhf`. We utilise the docker manifest for multi-platform awareness. More information is available from docker [here](https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-2.md#manifest-list) and our announcement [here](https://blog.linuxserver.io/2019/02/21/the-lsio-pipeline-project/). - -Simply pulling `ghcr.io/linuxserver/webtop` should retrieve the correct image for your arch, but you can also pull specific arch images via tags. - -The architectures supported by this image are: - -| Architecture | Tag | -| :----: | --- | -| x86-64 | amd64-latest | -| arm64 | arm64v8-latest | -| armhf | arm32v7-latest | - -## Version Tags - -This image provides various versions that are available via tags. `latest` tag usually provides the latest stable version. Others are considered under development and caution must be exercised when using them. - -| Tag | Description | -| :----: | --- | -| latest | XFCE Alpine | -| ubuntu-xfce | XFCE Ubuntu | -| alpine-kde | KDE Alpine | -| ubuntu-kde | KDE Ubuntu | -| alpine-mate | MATE Alpine | -| ubuntu-mate | MATE Ubuntu | -| alpine-i3 | i3 Alpine | -| ubuntu-i3 | i3 Ubuntu | -| alpine-openbox | Openbox Alpine | -| ubuntu-openbox | Openbox Ubuntu | -| alpine-icewm | IceWM Alpine | -| ubuntu-icewm | IceWM Ubuntu | - -## Application Setup - -The Webtop can be accessed at: - -* http://yourhost:3000/ - -By default the user/pass is abc/abc, if you change your password or want to login manually to the GUI session for any reason use the following link: - -* http://yourhost:3000/?login=true - -You can access advanced features of the Guacamole remote desktop using ctrl+alt+shift enabling you to use remote copy/paste or an onscreen keyboard. - -**Unlike our other containers these Desktops are not designed to be upgraded by Docker, you will keep your home directoy but anything you installed system level will be lost if you upgrade an existing container. To keep packages up to date instead use Ubuntu's own apt program or Alpine's apk program** - -**The KDE and i3 flavors for Ubuntu need to be run in privileged mode to function properly** - -If you ever lose your password you can always reset it by execing into the container as root: -``` -docker exec -it webtop passwd abc -``` -By default we perform all logic for the abc user and we reccomend using that user only in the container, but new users can be added as long as there is a `startwm.sh` executable script in their home directory. -All of these containers are configured with passwordless sudo, we make no efforts to secure or harden these containers and we do not reccomend ever publishing their ports to the public Internet. - -## Usage - -Here are some example snippets to help you get started creating a container. - -### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose)) - -```yaml ---- -version: "2.1" -services: - webtop: - image: ghcr.io/linuxserver/webtop - container_name: webtop - privileged: true #optional - environment: - - PUID=1000 - - PGID=1000 - - TZ=Europe/London - - SUBFOLDER=/ #optional - volumes: - - /path/to/data:/config - - /var/run/docker.sock:/var/run/docker.sock #optional - ports: - - 3000:3000 - shm_size: "1gb" #optional - restart: unless-stopped -``` - -### docker cli ([click here for more info](https://docs.docker.com/engine/reference/commandline/cli/)) - -```bash -docker run -d \ - --name=webtop \ - --privileged `#optional` \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Europe/London \ - -e SUBFOLDER=/ `#optional` \ - -p 3000:3000 \ - -v /path/to/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock `#optional` \ - --shm-size="1gb" `#optional` \ - --restart unless-stopped \ - ghcr.io/linuxserver/webtop -``` - -## Parameters - -Container images are configured using parameters passed at runtime (such as those above). These parameters are separated by a colon and indicate `<external>:<internal>` respectively. For example, `-p 8080:80` would expose port `80` from inside the container to be accessible from the host's IP on port `8080` outside the container. - -| Parameter | Function | -| :----: | --- | -| `-p 3000` | Web Desktop GUI | -| `-e PUID=1000` | for UserID - see below for explanation | -| `-e PGID=1000` | for GroupID - see below for explanation | -| `-e TZ=Europe/London` | Specify a timezone to use EG Europe/London | -| `-e SUBFOLDER=/` | Specify a subfolder to use with reverse proxies, IE `/subfolder/` | -| `-v /config` | abc users home directory | -| `-v /var/run/docker.sock` | Docker Socket on the system, if you want to use Docker in the container | -| `--shm-size=` | We set this to 1 gig to prevent modern web browsers from crashing | - -## Environment variables from files (Docker secrets) - -You can set any environment variable from a file by using a special prepend `FILE__`. - -As an example: - -```bash --e FILE__PASSWORD=/run/secrets/mysecretpassword -``` - -Will set the environment variable `PASSWORD` based on the contents of the `/run/secrets/mysecretpassword` file. - -## Umask for running applications - -For all of our images we provide the ability to override the default umask settings for services started within the containers using the optional `-e UMASK=022` setting. -Keep in mind umask is not chmod it subtracts from permissions based on it's value it does not add. Please read up [here](https://en.wikipedia.org/wiki/Umask) before asking for support. - -## User / Group Identifiers - -When using volumes (`-v` flags) permissions issues can arise between the host OS and the container, we avoid this issue by allowing you to specify the user `PUID` and group `PGID`. - -Ensure any volume directories on the host are owned by the same user you specify and any permissions issues will vanish like magic. - -In this instance `PUID=1000` and `PGID=1000`, to find yours use `id user` as below: - -```bash - $ id username - uid=1000(dockeruser) gid=1000(dockergroup) groups=1000(dockergroup) -``` - -## Docker Mods - -[![Docker Mods](https://img.shields.io/badge/dynamic/yaml?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=webtop&query=%24.mods%5B%27webtop%27%5D.mod_count&url=https%3A%2F%2Fraw.githubusercontent.com%2Flinuxserver%2Fdocker-mods%2Fmaster%2Fmod-list.yml)](https://mods.linuxserver.io/?mod=webtop "view available mods for this container.") [![Docker Universal Mods](https://img.shields.io/badge/dynamic/yaml?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=universal&query=%24.mods%5B%27universal%27%5D.mod_count&url=https%3A%2F%2Fraw.githubusercontent.com%2Flinuxserver%2Fdocker-mods%2Fmaster%2Fmod-list.yml)](https://mods.linuxserver.io/?mod=universal "view available universal mods.") - -We publish various [Docker Mods](https://github.com/linuxserver/docker-mods) to enable additional functionality within the containers. The list of Mods available for this image (if any) as well as universal mods that can be applied to any one of our images can be accessed via the dynamic badges above. - -## Support Info - -* Shell access whilst the container is running: `docker exec -it webtop /bin/bash` -* To monitor the logs of the container in realtime: `docker logs -f webtop` -* container version number - * `docker inspect -f '{{ index .Config.Labels "build_version" }}' webtop` -* image version number - * `docker inspect -f '{{ index .Config.Labels "build_version" }}' ghcr.io/linuxserver/webtop` - -## Updating Info - -Most of our images are static, versioned, and require an image update and container recreation to update the app inside. With some exceptions (ie. nextcloud, plex), we do not recommend or support updating apps inside the container. Please consult the [Application Setup](#application-setup) section above to see if it is recommended for the image. - -Below are the instructions for updating containers: - -### Via Docker Compose - -* Update all images: `docker-compose pull` - * or update a single image: `docker-compose pull webtop` -* Let compose update all containers as necessary: `docker-compose up -d` - * or update a single container: `docker-compose up -d webtop` -* You can also remove the old dangling images: `docker image prune` - -### Via Docker Run - -* Update the image: `docker pull ghcr.io/linuxserver/webtop` -* Stop the running container: `docker stop webtop` -* Delete the container: `docker rm webtop` -* Recreate a new container with the same docker run parameters as instructed above (if mapped correctly to a host folder, your `/config` folder and settings will be preserved) -* You can also remove the old dangling images: `docker image prune` - -### Via Watchtower auto-updater (only use if you don't remember the original parameters) - -* Pull the latest image at its tag and replace it with the same env variables in one run: - - ```bash - docker run --rm \ - -v /var/run/docker.sock:/var/run/docker.sock \ - containrrr/watchtower \ - --run-once webtop - ``` - -* You can also remove the old dangling images: `docker image prune` - -**Note:** We do not endorse the use of Watchtower as a solution to automated updates of existing Docker containers. In fact we generally discourage automated updates. However, this is a useful tool for one-time manual updates of containers where you have forgotten the original parameters. In the long term, we highly recommend using [Docker Compose](https://docs.linuxserver.io/general/docker-compose). - -### Image Update Notifications - Diun (Docker Image Update Notifier) - -* We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported. - -## Building locally - -If you want to make local modifications to these images for development purposes or just to customize the logic: - -```bash -git clone https://github.com/linuxserver/docker-webtop.git -cd docker-webtop -docker build \ - --no-cache \ - --pull \ - -t ghcr.io/linuxserver/webtop:latest . -``` - -The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static` - -```bash -docker run --rm --privileged multiarch/qemu-user-static:register --reset -``` - -Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`. - -## Versions - -* **20.04.21:** - Initial release. +<!-- DO NOT EDIT THIS FILE MANUALLY --> +<!-- Please read https://github.com/linuxserver/docker-webtop/blob/arch-i3/.github/CONTRIBUTING.md --> +Up to date documentation is available [here](https://github.com/linuxserver/docker-webtop/blob/master/README.md). diff --git a/jenkins-vars.yml b/jenkins-vars.yml index 146ba0ec9..3ef5a6a92 100644 --- a/jenkins-vars.yml +++ b/jenkins-vars.yml @@ -2,27 +2,26 @@ # jenkins variables project_name: docker-webtop -external_type: alpine_repo -release_type: stable -release_tag: latest -ls_branch: master +external_type: na +custom_version_command: "curl -sX GET https://api.github.com/repos/linuxserver/docker-baseimage-kasmvnc/releases | jq -r 'first(.[] | select(.tag_name | startswith(\"arch-\"))) | .tag_name' | sed 's|arch-||' | sed 's|-ls.*||'" +release_type: prerelease +release_tag: arch-i3 +ls_branch: arch-i3 +build_armhf: false repo_vars: - - BUILD_VERSION_ARG = 'XFCE_VERSION' + - BUILD_VERSION_ARG = 'I3_VERSION' - LS_USER = 'linuxserver' - LS_REPO = 'docker-webtop' - CONTAINER_NAME = 'webtop' - DOCKERHUB_IMAGE = 'linuxserver/webtop' - DEV_DOCKERHUB_IMAGE = 'lsiodev/webtop' - PR_DOCKERHUB_IMAGE = 'lspipepr/webtop' - - DIST_IMAGE = 'alpine' - - DIST_TAG = '3.13' - - DIST_REPO = 'http://dl-cdn.alpinelinux.org/alpine/v3.13/community/' - - DIST_REPO_PACKAGES = 'xfce4' + - DIST_IMAGE = 'arch' - MULTIARCH = 'true' - CI = 'true' - CI_WEB = 'true' - - CI_PORT = '3000' - - CI_SSL = 'false' + - CI_PORT = '3001' + - CI_SSL = 'true' - CI_DELAY = '120' - CI_DOCKERENV = 'TZ=US/Pacific' - CI_AUTH = 'user:password' diff --git a/package_versions.txt b/package_versions.txt index 799485642..a662fd9ac 100755 --- a/package_versions.txt +++ b/package_versions.txt @@ -1,260 +1,723 @@ -alpine-baselayout-3.2.0-r8 -alpine-keys-2.2-r0 -alsa-lib-1.2.4-r2 -alsa-plugins-pulse-1.2.2-r1 -apk-tools-2.12.7-r0 -at-spi2-atk-2.38.0-r0 -at-spi2-core-2.38.0-r0 -atk-2.36.0-r0 -atkmm-2.28.0-r1 -avahi-libs-0.8-r4 -bash-5.1.0-r0 -brotli-libs-1.0.9-r3 -busybox-1.32.1-r6 -c-ares-1.17.2-r0 -ca-certificates-20191127-r5 -ca-certificates-bundle-20191127-r5 -cairo-1.16.0-r2 -cairo-gobject-1.16.0-r2 -cairomm-1.14.0-r0 -containerd-1.4.8-r0 -coreutils-8.32-r2 -cups-libs-2.3.3-r1 -dbus-1.12.20-r1 -dbus-glib-0.110-r0 -dbus-libs-1.12.20-r1 -dbus-x11-1.12.20-r1 -desktop-file-utils-0.26-r0 -device-mapper-libs-2.02.187-r1 -docker-20.10.3-r1 -docker-cli-20.10.3-r1 -docker-engine-20.10.3-r1 -encodings-1.0.5-r0 -eudev-libs-3.2.9-r3 -exo-4.16.0-r0 -exo-libs-4.16.0-r0 -expat-2.2.10-r1 -faenza-icon-theme-1.3.1-r6 -faenza-icon-theme-bash-1.3.1-r6 -faenza-icon-theme-thunar-1.3.1-r6 -faenza-icon-theme-xfce4-appfinder-1.3.1-r6 -faenza-icon-theme-xfce4-panel-1.3.1-r6 -faenza-icon-theme-xterm-1.3.1-r6 -firefox-esr-78.14.0-r0 -flac-1.3.3-r0 -font-alias-1.0.3-r1 -font-cursor-misc-1.0.3-r1 -font-misc-misc-1.1.2-r1 -font-noto-0_git20190623-r2 -fontconfig-2.13.1-r3 -freerdp-libs-2.2.0-r0 -freetype-2.10.4-r1 -fribidi-1.0.10-r0 -fuse-2.9.9-r1 -fuse-common-3.10.2-r0 -garcon-0.8.0-r0 -gdk-pixbuf-2.42.4-r0 -giflib-5.2.1-r0 -glib-2.66.8-r0 -glibmm-2.64.5-r0 -gmp-6.2.1-r0 -gnutls-3.7.1-r0 -graphite2-1.3.14-r0 -gsm-1.0.19-r0 -gtk+3.0-3.24.23-r2 -gtk-update-icon-cache-2.24.33-r0 -gtkmm3-3.24.3-r0 -gtksourceview-3.24.11-r1 -harfbuzz-2.7.4-r1 -hicolor-icon-theme-0.17-r1 -iceauth-1.0.8-r0 -icu-libs-67.1-r2 -imlib2-1.7.1-r0 -ip6tables-1.8.6-r0 -iptables-1.8.6-r0 -iso-codes-4.5.0-r0 -keybinder3-0.3.2-r2 -lcms2-2.11-r0 -libacl-2.2.53-r0 -libasyncns-0.8-r1 -libattr-2.4.48-r0 -libblkid-2.36.1-r1 -libbsd-0.10.0-r0 -libbz2-1.0.8-r1 -libc-utils-0.7.2-r3 -libcanberra-0.30-r5 -libcanberra-gtk3-0.30-r5 -libcanberra-pulse-0.30-r5 -libcap-2.46-r0 -libcrypto1.1-1.1.1l-r0 -libcurl-7.79.0-r0 -libdrm-2.4.104-r0 -libedit-20191231.3.1-r1 -libepoxy-1.5.5-r0 -libevent-2.1.12-r1 -libexif-0.6.22-r0 -libffi-3.3-r2 -libfontenc-1.1.4-r0 -libgcc-10.2.1_pre1-r3 -libgomp-10.2.1_pre1-r3 -libgtop-2.40.0-r0 -libgudev-234-r0 -libice-1.0.10-r0 -libid3tag-0.15.1b-r8 -libintl-0.20.2-r2 -libjpeg-turbo-2.1.0-r0 -libltdl-2.4.6-r7 -libmnl-1.0.4-r1 -libmount-2.36.1-r1 -libnftnl-libs-1.1.8-r0 -libnotify-0.7.9-r1 -libogg-1.3.4-r0 -libpciaccess-0.16-r0 -libpng-1.6.37-r1 -libproc-3.3.16-r0 -libpulse-14.1-r0 -libpulse-mainloop-glib-14.1-r0 -librsvg-2.50.4-r0 -libseccomp-2.5.1-r1 -libsigc++-2.10.6-r0 -libsm-1.2.3-r0 -libsndfile-1.0.29-r1 -libssl1.1-1.1.1l-r0 -libstdc++-10.2.1_pre1-r3 -libtasn1-4.16.0-r1 -libtls-standalone-2.9.1-r1 -libunistring-0.9.10-r0 -libusb-1.0.24-r1 -libuuid-2.36.1-r1 -libvorbis-1.3.7-r0 -libvpx-1.9.0-r0 -libwebp-1.1.0-r0 -libwnck3-3.36.0-r0 -libx11-1.7.1-r0 -libxau-1.0.9-r0 -libxaw-1.0.13-r3 -libxcb-1.14-r1 -libxcomposite-0.4.5-r0 -libxcursor-1.2.0-r0 -libxdamage-1.1.5-r1 -libxdmcp-1.1.3-r0 -libxext-1.3.4-r0 -libxfce4ui-4.16.0-r1 -libxfce4util-4.16.0-r0 -libxfixes-5.0.3-r2 -libxfont2-2.0.5-r0 -libxft-2.3.3-r0 -libxi-1.7.10-r0 -libxinerama-1.1.4-r1 -libxkbcommon-1.0.3-r0 -libxkbfile-1.1.0-r0 -libxklavier-5.4-r5 -libxml2-2.9.12-r0 -libxmu-1.1.3-r0 -libxpm-3.5.13-r0 -libxpresent-1.0.0-r0 -libxrandr-1.5.2-r1 -libxrender-0.9.10-r3 -libxres-1.2.0-r2 -libxshmfence-1.3-r1 -libxt-1.2.1-r0 -libxtst-1.2.3-r3 -libxxf86vm-1.1.4-r2 -linux-pam-1.5.1-r0 -mcookie-2.36.1-r1 -mesa-20.3.3-r0 -mesa-gbm-20.3.3-r0 -mesa-gl-20.3.3-r0 -mesa-glapi-20.3.3-r0 -mkfontscale-1.2.1-r1 -mousepad-0.5.2-r0 -mozjs78-78.14.0-r0 -musl-1.2.2-r1 -musl-utils-1.2.2-r1 -ncurses-libs-6.2_p20210109-r0 -ncurses-terminfo-base-6.2_p20210109-r0 -nettle-3.7.2-r0 -nghttp2-libs-1.42.0-r1 -nodejs-14.17.6-r0 -nspr-4.31-r0 -nss-3.66-r0 -openbox-3.6.1-r2 -openbox-libs-3.6.1-r2 -openjpeg-2.4.0-r1 -openssh-client-8.4_p1-r3 -openssh-keygen-8.4_p1-r3 -openssl-1.1.1l-r0 -opus-1.3.1-r1 -orc-0.4.32-r0 -ossp-uuid-1.6.2-r1 -p11-kit-0.23.22-r0 -pango-1.48.2-r0 -pangomm-2.42.2-r0 -pavucontrol-4.0-r0 -pcre-8.44-r0 -pcre2-10.36-r0 -pixman-0.40.0-r2 -pkgconf-1.7.3-r0 -polkit-0.118-r0 -poppler-20.12.1-r0 -poppler-glib-20.12.1-r0 -procps-3.3.16-r0 -pulseaudio-14.1-r0 -pulseaudio-alsa-14.1-r0 -readline-8.1.0-r0 -runc-1.0.0_rc95-r0 -s6-ipcserver-2.10.0.0-r0 -scanelf-1.2.8-r0 -shadow-4.8.1-r0 -shared-mime-info-2.0-r0 -skalibs-2.10.0.0-r0 -sound-theme-freedesktop-0.8-r0 -soxr-0.1.3-r2 -speexdsp-1.2.0-r0 -sqlite-libs-3.34.1-r0 -ssl_client-1.32.1-r6 -startup-notification-0.12-r4 -sudo-1.9.5p2-r0 -tdb-libs-1.4.3-r0 -thunar-4.16.2-r0 -thunar-volman-4.16.0-r0 -tiff-4.2.0-r0 -tini-static-0.19.0-r0 -ttf-dejavu-2.37-r1 -tumbler-4.16.0-r0 -tzdata-2021a-r0 -upower-0.99.11-r0 -util-macros-1.19.2-r1 -utmps-0.1.0.0-r0 -vte3-0.62.2-r0 -wayland-libs-client-1.18.0-r5 -wayland-libs-cursor-1.18.0-r5 -wayland-libs-egl-1.18.0-r5 -wayland-libs-server-1.18.0-r5 -websocat-1.8.1-r0 -xauth-1.1-r0 -xcb-util-0.4.0-r3 -xfce4-4.16-r0 -xfce4-appfinder-4.16.0-r0 -xfce4-panel-4.16.0-r0 -xfce4-power-manager-4.16.0-r0 -xfce4-pulseaudio-plugin-0.4.3-r2 -xfce4-session-4.16.0-r0 -xfce4-settings-4.16.0-r0 -xfce4-terminal-0.8.9.2-r0 -xfconf-4.16.0-r0 -xfdesktop-4.16.0-r0 -xfwm4-4.16.1-r0 -xinit-1.4.1-r0 -xkbcomp-1.4.4-r0 -xkeyboard-config-2.31-r0 -xmodmap-1.0.10-r0 -xorg-server-1.20.13-r0 -xorg-server-common-1.20.13-r0 -xorgxrdp-0.2.16-r0 -xrdb-1.2.1-r0 -xrdp-0.9.16-r1 -xterm-367-r0 -xz-5.2.5-r0 -xz-libs-5.2.5-r0 -zlib-1.2.11-r3 +NAME VERSION TYPE +Simple Launcher 1.1.0.14 binary (+5 duplicates) +abseil-cpp 20250814.1-1 alpm +acl 2.3.2-1 alpm +adwaita-cursors 49.0-1 alpm +adwaita-fonts 49.0-2 alpm +adwaita-icon-theme 49.0-1 alpm +adwaita-icon-theme-legacy 46.2-3 alpm +aiofiles 25.1.0 python +aiohappyeyeballs 2.6.1 python +aiohttp 3.13.3 python +aioice 0.10.2 python +aiosignal 1.4.0 python +alsa-lib 1.2.15.1-1 alpm +alsa-topology-conf 1.2.5.1-4 alpm +alsa-ucm-conf 1.2.15.1-1 alpm +archlinux-keyring 20251116-1 alpm +at-spi2-core 2.58.2-1 alpm +attr 2.5.2-1 alpm +attrs 25.4.0 python +audit 4.1.2-1 alpm +autocommand 2.2.2 python +autoconf 2.72-1 alpm +automake 1.18.1-1 alpm +av 14.4.0 python +avahi 1:0.9rc2-1 alpm +backports-tarfile 1.2.0 python +base-devel 1-2 alpm +bash 5.3.9-1 alpm +binutils 2.45.1-1 alpm +bison 3.8.2-8 alpm +brotli 1.1.0-3 alpm +bubblewrap 0.11.0-1 alpm +busybox 1.36.1-2 alpm +bzip2 1.0.8-6 alpm +ca-certificates 20240618-1 alpm +ca-certificates-mozilla 3.119.1-1 alpm +ca-certificates-utils 20240618-1 alpm +cairo 1.18.4-1 alpm +catatonit 0.2.1-2 alpm +cffi 2.0.0 python +chromium 143.0.7499.169-1 alpm +cli UNKNOWN binary +cli-32 UNKNOWN binary +cli-64 UNKNOWN binary +cli-arm64 UNKNOWN binary +cmake 4.2.1-1 alpm +command-line-arguments UNKNOWN go-module +confuse 3.3-4 alpm +containerd 2.2.1-1 alpm +coreutils 9.9-1 alpm +cppdap 1.58.0-2 alpm +cryptography 46.0.3 python +cryptsetup 2.8.3-1 alpm +curl 8.17.0-2 alpm +dario.cat/mergo v1.0.2 go-module +dav1d 1.5.3-1 alpm +db5.3 5.3.28-5 alpm +dbus 1.16.2-1 alpm +dbus-broker 37-2 alpm +dbus-broker-units 37-2 alpm +dbus-units 37-2 alpm +dconf 0.49.0-1 alpm +debugedit 5.2-1 alpm +default-cursors 3-1 alpm +desktop-file-utils 0.28-1 alpm +device-mapper 2.03.38-1 alpm +diffutils 3.12-2 alpm +distro 1.9.0 python +dnspython 2.8.0 python +docker 1:29.1.3-1 alpm +docker-compose 5.0.1-1 alpm +duktape 2.7.0-7 alpm +dunst 1.13.0-1 alpm +e2fsprogs 1.47.3-2 alpm +evdev 1.9.2 python +expat 2.7.3-1 alpm +fakeroot 1.37.1.2-1 alpm +fcft 3.3.3-1 alpm +fftw 3.3.10-7 alpm +file 5.46-5 alpm +filesystem 2025.10.12-1 alpm +findutils 4.10.0-3 alpm +flac 1.5.0-1 alpm +flex 2.6.4-5 alpm +fontconfig 2:2.17.1-1 alpm +foot 1.25.0-1 alpm +freetype2 2.14.1-1 alpm +fribidi 1.0.16-2 alpm +frozenlist 1.8.0 python +fuse-common 3.17.4-1 alpm +fuse-overlayfs 1.16-1 alpm +fuse3 3.17.4-1 alpm +gawk 5.3.2-1 alpm +gc 8.2.10-2 alpm +gcc 15.2.1+r301+gf24307422d1d-1 alpm +gcc-libs 15.2.1+r301+gf24307422d1d-1 alpm +gdbm 1.26-1 alpm +gdk-pixbuf2 2.44.4-1 alpm +gettext 0.26-1 alpm +giflib 5.2.2-2 alpm +github.com/AlecAivazis/survey/v2 v2.3.7 go-module +github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e go-module +github.com/Microsoft/hcsshim v0.14.0-rc.1 go-module (+1 duplicate) +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d go-module +github.com/beorn7/perks v1.0.1 go-module (+2 duplicates) +github.com/buger/goterm v1.0.4 go-module +github.com/cenkalti/backoff/v4 v4.3.0 go-module +github.com/cenkalti/backoff/v5 v5.0.3 go-module +github.com/cespare/xxhash/v2 v2.3.0 go-module (+2 duplicates) +github.com/checkpoint-restore/checkpointctl v1.4.0 go-module +github.com/checkpoint-restore/go-criu/v7 v7.2.0 go-module (+1 duplicate) +github.com/cilium/ebpf v0.16.0 go-module (+2 duplicates) +github.com/cilium/ebpf v0.17.3 go-module +github.com/compose-spec/compose-go/v2 v2.10.0 go-module +github.com/containerd/btrfs/v2 v2.0.0 go-module +github.com/containerd/cgroups/v3 v3.1.2 go-module (+2 duplicates) +github.com/containerd/console v1.0.5 go-module (+4 duplicates) +github.com/containerd/containerd/api v1.10.0 go-module (+4 duplicates) +github.com/containerd/containerd/v2 v2.2.1+dirty go-module (+3 duplicates) +github.com/containerd/containerd/v2 v2.2.1-0.20251115011841-efd86f2b0bc2 go-module +github.com/containerd/continuity v0.4.5 go-module (+4 duplicates) +github.com/containerd/errdefs v1.0.0 go-module (+4 duplicates) +github.com/containerd/errdefs/pkg v0.3.0 go-module (+4 duplicates) +github.com/containerd/fifo v1.1.0 go-module (+3 duplicates) +github.com/containerd/go-cni v1.1.13 go-module (+1 duplicate) +github.com/containerd/go-runc v1.1.0 go-module (+2 duplicates) +github.com/containerd/imgcrypt/v2 v2.0.1 go-module +github.com/containerd/log v0.1.0 go-module (+4 duplicates) +github.com/containerd/nri v0.11.0 go-module +github.com/containerd/otelttrpc v0.1.0 go-module +github.com/containerd/platforms v1.0.0-rc.2 go-module (+3 duplicates) +github.com/containerd/plugin v1.0.0 go-module (+3 duplicates) +github.com/containerd/ttrpc v1.2.7 go-module (+4 duplicates) +github.com/containerd/typeurl/v2 v2.2.3 go-module (+4 duplicates) +github.com/containerd/zfs/v2 v2.0.0 go-module +github.com/containernetworking/cni v1.3.0 go-module (+1 duplicate) +github.com/containernetworking/plugins v1.9.0 go-module +github.com/containers/ocicrypt v1.2.1 go-module +github.com/coreos/go-systemd/v22 v22.6.0 go-module (+3 duplicates) +github.com/cyphar/filepath-securejoin v0.5.1 go-module (+2 duplicates) +github.com/cyphar/filepath-securejoin v0.6.1 go-module +github.com/davecgh/go-spew v1.1.1 go-module (+1 duplicate) +github.com/distribution/reference v0.6.0 go-module (+3 duplicates) +github.com/docker/buildx v0.30.1 go-module +github.com/docker/cli v28.5.2+incompatible go-module +github.com/docker/cli-docs-tool v0.11.0 go-module +github.com/docker/cli/cmd/docker UNKNOWN go-module +github.com/docker/compose/v5 UNKNOWN go-module +github.com/docker/distribution v2.8.3+incompatible go-module +github.com/docker/docker v28.5.2+incompatible go-module +github.com/docker/docker-credential-helpers v0.9.3 go-module +github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c go-module +github.com/docker/go-connections v0.6.0 go-module +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c go-module +github.com/docker/go-metrics v0.0.1 go-module (+2 duplicates) +github.com/docker/go-units v0.5.0 go-module (+4 duplicates) +github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 go-module +github.com/emicklei/go-restful/v3 v3.13.0 go-module +github.com/felixge/httpsnoop v1.0.4 go-module (+3 duplicates) +github.com/fsnotify/fsnotify v1.9.0 go-module (+1 duplicate) +github.com/fvbommel/sortorder v1.1.0 go-module +github.com/fxamacker/cbor/v2 v2.9.0 go-module (+1 duplicate) +github.com/go-jose/go-jose/v4 v4.1.2 go-module +github.com/go-logr/logr v1.4.3 go-module (+3 duplicates) +github.com/go-logr/stdr v1.2.2 go-module (+3 duplicates) +github.com/go-viper/mapstructure/v2 v2.4.0 go-module +github.com/godbus/dbus/v5 v5.1.0 go-module (+3 duplicates) +github.com/gofrs/flock v0.13.0 go-module +github.com/gogo/protobuf v1.3.2 go-module (+4 duplicates) +github.com/golang-jwt/jwt/v5 v5.3.0 go-module +github.com/golang/protobuf v1.5.4 go-module (+1 duplicate) +github.com/google/go-cmp v0.7.0 go-module (+4 duplicates) +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 go-module +github.com/google/uuid v1.6.0 go-module (+1 duplicate) +github.com/gorilla/mux v1.8.1 go-module +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 go-module +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 go-module +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 go-module +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 go-module +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 go-module +github.com/hashicorp/errwrap v1.1.0 go-module +github.com/hashicorp/go-multierror v1.1.1 go-module +github.com/hashicorp/go-version v1.8.0 go-module +github.com/in-toto/in-toto-golang v0.9.0 go-module +github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf go-module +github.com/intel/goresctrl v0.10.0 go-module (+1 duplicate) +github.com/jonboulle/clockwork v0.5.0 go-module +github.com/json-iterator/go v1.1.12 go-module +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 go-module +github.com/klauspost/compress v1.18.1 go-module (+3 duplicates) +github.com/knqyf263/go-plugin v0.9.0 go-module +github.com/mattn/go-colorable v0.1.14 go-module +github.com/mattn/go-isatty v0.0.20 go-module +github.com/mattn/go-runewidth v0.0.16 go-module +github.com/mattn/go-shellwords v1.0.12 go-module +github.com/mdlayher/socket v0.5.1 go-module (+2 duplicates) +github.com/mdlayher/vsock v1.2.1 go-module (+2 duplicates) +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b go-module +github.com/miekg/pkcs11 v1.1.1 go-module +github.com/mistifyio/go-zfs/v3 v3.0.1 go-module +github.com/mitchellh/hashstructure/v2 v2.0.2 go-module +github.com/moby/buildkit v0.26.3 go-module +github.com/moby/docker-image-spec v1.3.1 go-module +github.com/moby/go-archive v0.1.0 go-module +github.com/moby/locker v1.0.1 go-module (+3 duplicates) +github.com/moby/moby/v2/cmd/docker-proxy UNKNOWN go-module +github.com/moby/moby/v2/cmd/dockerd UNKNOWN go-module +github.com/moby/patternmatcher v0.6.0 go-module +github.com/moby/spdystream v0.5.0 go-module +github.com/moby/sys/atomicwriter v0.1.0 go-module +github.com/moby/sys/capability v0.4.0 go-module (+3 duplicates) +github.com/moby/sys/mountinfo v0.7.2 go-module (+4 duplicates) +github.com/moby/sys/sequential v0.6.0 go-module +github.com/moby/sys/signal v0.7.1 go-module (+3 duplicates) +github.com/moby/sys/symlink v0.3.0 go-module (+1 duplicate) +github.com/moby/sys/user v0.4.0 go-module (+4 duplicates) +github.com/moby/sys/userns v0.1.0 go-module (+5 duplicates) +github.com/moby/term v0.5.2 go-module +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd go-module +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee go-module +github.com/morikuni/aec v1.1.0 go-module +github.com/mrunalp/fileutils v0.5.1 go-module +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 go-module (+2 duplicates) +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f go-module +github.com/opencontainers/cgroups v0.0.6 go-module +github.com/opencontainers/go-digest v1.0.0 go-module (+4 duplicates) +github.com/opencontainers/image-spec v1.1.1 go-module (+4 duplicates) +github.com/opencontainers/runc UNKNOWN go-module +github.com/opencontainers/runtime-spec v1.3.0 go-module (+4 duplicates) +github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116 go-module (+1 duplicate) +github.com/opencontainers/selinux v1.13.0 go-module +github.com/opencontainers/selinux v1.13.1 go-module (+2 duplicates) +github.com/pelletier/go-toml v1.9.5 go-module +github.com/pelletier/go-toml/v2 v2.2.4 go-module (+1 duplicate) +github.com/pkg/errors v0.9.1 go-module +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 go-module +github.com/pmezard/go-difflib v1.0.0 go-module +github.com/prometheus/client_golang v1.23.2 go-module (+2 duplicates) +github.com/prometheus/client_model v0.6.2 go-module (+2 duplicates) +github.com/prometheus/common v0.66.1 go-module (+2 duplicates) +github.com/prometheus/procfs v0.16.1 go-module (+2 duplicates) +github.com/rivo/uniseg v0.2.0 go-module +github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 go-module +github.com/seccomp/libseccomp-golang v0.11.1 go-module +github.com/secure-systems-lab/go-securesystemslib v0.9.1 go-module +github.com/shibumi/go-pathspec v1.3.0 go-module +github.com/sirupsen/logrus v1.9.3 go-module (+5 duplicates) +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 go-module +github.com/smallstep/pkcs7 v0.1.1 go-module +github.com/spf13/cobra v1.10.2 go-module +github.com/spf13/pflag v1.0.10 go-module +github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 go-module +github.com/stretchr/testify v1.11.1 go-module +github.com/tchap/go-patricia/v2 v2.3.3 go-module +github.com/tetratelabs/wazero v1.10.1 go-module +github.com/theupdateframework/notary v0.7.0 go-module +github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 go-module +github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 go-module +github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f go-module +github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 go-module +github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea go-module +github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab go-module +github.com/urfave/cli v1.22.17 go-module +github.com/urfave/cli/v2 v2.27.7 go-module (+2 duplicates) +github.com/vishvananda/netlink v1.3.1 go-module (+1 duplicate) +github.com/vishvananda/netns v0.0.5 go-module (+1 duplicate) +github.com/x448/float16 v0.8.4 go-module (+1 duplicate) +github.com/xhit/go-str2duration/v2 v2.1.0 go-module +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 go-module (+2 duplicates) +glib-networking 1:2.80.1-1 alpm +glib2 2.86.3-1 alpm +glibc 2.42+r33+gde1fe81f4714-1 alpm +glycin 2.0.7-1 alpm +gmp 6.3.0-2 alpm +gnulib-l10n 20241231-1 alpm +gnupg 2.4.9-1 alpm +gnutls 3.8.11-2 alpm +go.etcd.io/bbolt v1.4.3 go-module +go.opentelemetry.io/auto/sdk v1.1.0 go-module (+2 duplicates) +go.opentelemetry.io/auto/sdk v1.2.1 go-module +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 go-module +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 go-module +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 go-module +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 go-module (+2 duplicates) +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 go-module +go.opentelemetry.io/otel v1.37.0 go-module (+2 duplicates) +go.opentelemetry.io/otel v1.38.0 go-module +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 go-module +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 go-module +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 go-module +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 go-module +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 go-module +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 go-module +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 go-module +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 go-module +go.opentelemetry.io/otel/metric v1.37.0 go-module (+2 duplicates) +go.opentelemetry.io/otel/metric v1.38.0 go-module +go.opentelemetry.io/otel/sdk v1.37.0 go-module +go.opentelemetry.io/otel/sdk v1.38.0 go-module +go.opentelemetry.io/otel/sdk/metric v1.38.0 go-module +go.opentelemetry.io/otel/trace v1.37.0 go-module (+2 duplicates) +go.opentelemetry.io/otel/trace v1.38.0 go-module +go.opentelemetry.io/proto/otlp v1.5.0 go-module +go.opentelemetry.io/proto/otlp v1.7.1 go-module +go.uber.org/mock v0.6.0 go-module +go.yaml.in/yaml/v2 v2.4.2 go-module (+3 duplicates) +go.yaml.in/yaml/v4 v4.0.0-rc.3 go-module +golang.org/x/crypto v0.45.0 go-module (+1 duplicate) +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f go-module (+2 duplicates) +golang.org/x/mod v0.29.0 go-module (+1 duplicate) +golang.org/x/net v0.43.0 go-module +golang.org/x/net v0.47.0 go-module (+4 duplicates) +golang.org/x/oauth2 v0.30.0 go-module +golang.org/x/sync v0.18.0 go-module (+3 duplicates) +golang.org/x/sync v0.19.0 go-module +golang.org/x/sys v0.37.0 go-module +golang.org/x/sys v0.38.0 go-module (+3 duplicates) +golang.org/x/sys v0.39.0 go-module +golang.org/x/term v0.37.0 go-module (+1 duplicate) +golang.org/x/text v0.31.0 go-module (+3 duplicates) +golang.org/x/time v0.14.0 go-module (+1 duplicate) +google-crc32c 1.8.0 python +google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b go-module +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 go-module +google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b go-module (+3 duplicates) +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 go-module +google.golang.org/grpc v1.76.0 go-module (+3 duplicates) +google.golang.org/grpc v1.77.0 go-module +google.golang.org/protobuf v1.36.10 go-module (+4 duplicates) +google.golang.org/protobuf v1.36.8 go-module +gopkg.in/inf.v0 v0.9.1 go-module (+1 duplicate) +gopkg.in/ini.v1 v1.67.0 go-module +gopkg.in/yaml.v3 v3.0.1 go-module (+2 duplicates) +gperftools 2.17.2-1 alpm +gpgme 2.0.1-1 alpm +gputil 1.4.0 python +graphite 1:1.3.14-5 alpm +grep 3.12-2 alpm +groff 1.23.0-7 alpm +gsettings-desktop-schemas 49.1-1 alpm +gsettings-system-schemas 49.1-1 alpm +gtest 1.17.0-1 alpm +gtk-layer-shell 0.10.0-1 alpm +gtk-update-icon-cache 1:4.20.3-1 alpm +gtk3 1:3.24.51-1 alpm +gui UNKNOWN binary +gui-32 UNKNOWN binary +gui-64 UNKNOWN binary +gui-arm64 UNKNOWN binary +guile 3.0.11-1 alpm +gzip 1.14-2 alpm +harfbuzz 12.3.0-1 alpm +hicolor-icon-theme 0.18-1 alpm +highway 1.3.0-1 alpm +hwdata 0.402-1 alpm +i3-wm 4.25-1 alpm +i3status 2.15-1 alpm +iana-etc 20251215-1 alpm +icu 78.1-1 alpm +idna 3.11 python +ifaddr 0.2.0 python +imlib2 1.12.6-1 alpm +importlib-metadata 8.0.0 python +inetutils 2.6-1 alpm +inflect 7.3.1 python +intel-gmmlib 22.8.2-1 alpm +intel-media-driver 25.3.4-1 alpm +iproute2 6.18.0-1 alpm +iptables 1:1.8.11-2 alpm +iso-codes 4.20.1-1 alpm +jansson 2.14.1-1 alpm +jaraco-collections 5.1.0 python +jaraco-context 5.3.0 python +jaraco-functools 4.0.1 python +jaraco-text 3.12.1 python +jbigkit 2.1-8 alpm +jpegxl UNKNOWN java-archive +jq 1.7.1 binary +jq 1.8.1-1 alpm +json-c 0.18-2 alpm +json-glib 1.10.8-1 alpm +jsoncpp 1.9.6-3 alpm +k8s.io/api v0.34.1 go-module +k8s.io/apimachinery v0.34.1 go-module (+1 duplicate) +k8s.io/client-go v0.34.1 go-module +k8s.io/cri-api v0.34.1 go-module (+1 duplicate) +k8s.io/klog/v2 v2.130.1 go-module +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 go-module +kbd 2.9.0-1 alpm +kernel.org/pub/linux/libs/security/libcap/cap v1.2.77 go-module +kernel.org/pub/linux/libs/security/libcap/psx v1.2.77 go-module +keyutils 1.6.3-3 alpm +kmod 34.2-1 alpm +krb5 1.21.3-2 alpm +l-smash 2.14.5-4 alpm +labwc 0.9.3-1 alpm +lame 3.100-6 alpm +lcms2 2.17-1 alpm +leancrypto 1.6.0-1 alpm +less 1:685-1 alpm +libarchive 3.8.4-1 alpm +libassuan 3.0.0-1 alpm +libasyncns 1:0.8+r3+g68cd5af-3 alpm +libbpf 1.6.2-1 alpm +libbsd 0.12.2-2 alpm +libcacard 2.8.1-1 alpm +libcap 2.77-1 alpm +libcap-ng 0.8.5-3 alpm +libcloudproviders 0.4.0-1 alpm +libcolord 1.4.8-1 alpm +libcups 2:2.4.16-1 alpm +libdaemon 0.14-6 alpm +libdatrie 0.2.14-1 alpm +libdecor 0.2.5-1 alpm +libdeflate 1.25-1 alpm +libdisplay-info 0.3.0-1 alpm +libdrm 2.4.131-1 alpm +libedit 20250104_3.1-1 alpm +libei 1.5.0-1 alpm +libelf 0.194-1 alpm +libepoxy 1.5.10-3 alpm +libev 4.33-5 alpm +libevdev 1.13.6-1 alpm +libevent 2.1.12-4 alpm +libffi 3.5.2-1 alpm +libfontenc 1.1.8-1 alpm +libgcrypt 1.11.2-1 alpm +libglvnd 1.7.0-3 alpm +libgpg-error 1.58-1 alpm +libgtop 2.41.3-2 alpm +libgudev 238-3 alpm +libice 1.1.2-1 alpm +libidn2 2.3.8-1 alpm +libinput 1.30.1-1 alpm +libisl 0.27-1 alpm +libjpeg-turbo 3.1.2-1 alpm +libjxl 0.11.1-5 alpm +libksba 1.6.7-2 alpm +libldap 2.6.10-2 alpm +libliftoff 0.5.0-1 alpm +libmakepkg-dropins 18-1 alpm +libmd 1.1.0-2 alpm +libmnl 1.0.5-2 alpm +libmpc 1.3.1-2 alpm +libnetfilter_conntrack 1.0.9-2 alpm +libnfnetlink 1.0.2-2 alpm +libnftnl 1.3.1-1 alpm +libnghttp2 1.68.0-1 alpm +libnghttp3 1.14.0-1 alpm +libnl 3.12.0-1 alpm +libnotify 0.8.7-2 alpm +libnsl 2.0.1-1 alpm +libogg 1.3.6-1 alpm +libp11-kit 0.25.10-2 alpm +libpcap 1.10.5-3 alpm +libpciaccess 0.18.1-2 alpm +libpng 1.6.53-1 alpm +libproxy 0.5.12-1 alpm +libpsl 0.21.5-2 alpm +libpulse 17.0+r98+gb096704c0-1 alpm +librsvg 2:2.61.3-1 alpm +libsasl 2.1.28-5 alpm +libseccomp 2.5.6-1 alpm +libsecret 0.21.7-1 alpm +libsfdo 0.1.4-1 alpm +libsm 1.2.6-1 alpm +libsndfile 1.2.2-4 alpm +libsoup3 3.6.5-1 alpm +libsoxr 0.1.3-4 alpm +libssh2 1.11.1-1 alpm +libstemmer 3.0.1-1 alpm +libsysprof-capture 49.0-1 alpm +libtasn1 4.20.0-1 alpm +libthai 0.1.29-3 alpm +libtiff 4.7.1-1 alpm +libtirpc 1.3.7-1 alpm +libtool 2.6.0-1 alpm +libunistring 1.3-1 alpm +libunwind 1.8.2-1 alpm +libusb 1.0.29-1 alpm +libutempter 1.2.3-1 alpm +libutf8proc 2.10.0-2 alpm +libuv 1.51.0-1 alpm +libva 2.22.0-1 alpm +libverto 0.3.2-5 alpm +libvorbis 1.3.7-4 alpm +libwacom 2.17.0-1 alpm +libwebp 1.6.0-2 alpm +libx11 1.8.12-2 alpm +libxau 1.0.12-1 alpm +libxaw 1.0.16-1 alpm +libxcb 1.17.0-1 alpm +libxcomposite 0.4.6-2 alpm +libxcrypt 4.5.2-1 alpm +libxcursor 1.2.3-1 alpm +libxcvt 0.1.3-1 alpm +libxdamage 1.1.6-2 alpm +libxdmcp 1.1.5-1 alpm +libxext 1.3.6-1 alpm +libxfce4ui 4.20.2-1 alpm +libxfce4util 4.20.1-1 alpm +libxfixes 6.0.2-1 alpm +libxfont2 2.0.7-1 alpm +libxft 2.3.9-1 alpm +libxi 1.8.2-1 alpm +libxinerama 1.1.5-2 alpm +libxkbcommon 1.13.1-1 alpm +libxkbcommon-x11 1.13.1-1 alpm +libxkbfile 1.1.3-1 alpm +libxml2 2.15.1-4 alpm +libxmu 1.2.1-1 alpm +libxpm 3.5.17-2 alpm +libxrandr 1.5.4-1 alpm +libxrender 0.9.12-1 alpm +libxshmfence 1.3.3-1 alpm +libxslt 1.1.45-1 alpm +libxss 1.2.5-1 alpm +libxt 1.3.1-1 alpm +libxtst 1.2.5-1 alpm +libxv 1.0.13-1 alpm +libxvmc 1.0.14-1 alpm +libxxf86vm 1.1.6-1 alpm +linux-api-headers 6.17-1 alpm +linux-headers 6.18.3.arch1-1 alpm +llvm-libs 21.1.6-1 alpm +lm_sensors 1:3.6.2-1 alpm +lmdb 0.9.33-1 alpm +lua 5.4.8-2 alpm +luit 20250912-1 alpm +lz4 1:1.10.0-2 alpm +lzo 2.10-5 alpm +m4 1.4.20-1 alpm +mailcap 2.1.54-2 alpm +make 4.4.1-2 alpm +mesa 1:25.3.3-1 alpm +minizip 1:1.3.1-2 alpm +more-itertools 10.3.0 python +mpdecimal 4.0.1-1 alpm +mpfr 4.2.2-1 alpm +mpg123 1.33.4-1 alpm +msgpack 1.1.2 python +mtdev 1.1.7-1 alpm +multidict 6.7.0 python +my-test-package 1.0 python +ncurses 6.5-4 alpm +nettle 3.10.2-1 alpm +nftables 0.1 python +nftables 1:1.1.6-1 alpm +nginx 1.28.1-1 alpm +nginx-mod-fancyindex 0.5.2-1 alpm +nginx-mod-fancyindex-debug 0.5.2-1 alpm +noto-fonts 1:2026.01.01-1 alpm +noto-fonts-cjk 20240730-1 alpm +noto-fonts-emoji 1:2.051-1 alpm +npth 1.8-1 alpm +nspr 4.38.2-1 alpm +nss 3.119.1-1 alpm +nvidia-cuda-nvrtc 13.1.80 python +oniguruma 6.9.10-1 alpm +openbox 3.6.1-14 alpm +openbsd-netcat 1.234_1-1 alpm +openssh 10.2p1-2 alpm +openssl 3.6.0-1 alpm +opus 1.6-1 alpm +orc 0.4.41-1 alpm +p11-kit 0.25.10-2 alpm +packaging 24.2 python +pacman 7.1.0.r7.gb9f7d4a-1 alpm +pacman-mirrorlist 20251021-1 alpm +pahole 1:1.31-1 alpm +pam 1.7.1-1 alpm +pambase 20250719-1 alpm +pango 1:1.57.0-2 alpm +pasimple 0.0.3 python +patch 2.8-1 alpm +pciutils 3.14.0-1 alpm +pcmflux 1.0.7 python +pcre2 10.47-1 alpm +pcsclite 2.4.0-3 alpm +perl 5.42.0-1 alpm +pillow 12.1.0 python +pinentry 1.3.2-2 alpm +pip 25.3 python +pixelflux 1.5.4 python +pixman 0.46.4-1 alpm +pkgconf 2.5.1-1 alpm +platformdirs 4.2.2 python +polkit 127-3 alpm +popt 1.19-2 alpm +procps-ng 4.0.5-3 alpm +prometheus-client 0.23.1 python +propcache 0.4.1 python +psmisc 23.7-1 alpm +psutil 7.2.1 python +pulseaudio 17.0+r98+gb096704c0-1 alpm +pulsectl 24.12.0 python +pycparser 2.23 python +pyee 13.0.0 python +pylibsrtp 1.0.0 python +pynput 1.8.1 python +pyopenssl 25.3.0 python +python 3.13.11-1 alpm +python-xlib 0.33 python +readline 8.3.003-1 alpm +rhash 1.4.6-1 alpm +rtkit 0.14-1 alpm +runc 1.4.0-1 alpm +seatd 0.9.1-1 alpm +sed 4.9-3 alpm +selkies 0.0.0 python +setuptools 80.9.0 python +shadow 4.18.0-1 alpm +shared-mime-info 2.4-2 alpm +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 go-module (+1 duplicate) +sigs.k8s.io/randfill v1.0.0 go-module +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 go-module +sigs.k8s.io/yaml v1.6.0 go-module (+1 duplicate) +six 1.17.0 python +speexdsp 1.2.1-2 alpm +spice 0.16.0-2 alpm +spice-protocol 0.14.5-1 alpm +spirv-tools 1:1.4.335.0-1 alpm +sqlite 3.51.1-1 alpm +st 0.9.3-1 alpm +st-debug 0.9.3-1 alpm +startup-notification 0.12-9 alpm +stdlib go1.25.3 go-module +stdlib go1.25.4 go-module +stdlib go1.25.5 go-module (+7 duplicates) +sudo 1.9.17.p2-1 alpm +sway 1:1.11-1 alpm +swaybg 1.2.1-1 alpm +systemd 259-1 alpm +systemd-libs 259-1 alpm +tags.cncf.io/container-device-interface v1.1.0 go-module (+2 duplicates) +tags.cncf.io/container-device-interface/specs-go v1.1.0 go-module (+1 duplicate) +tar 1.35-2 alpm +tdb 1.4.14-1 alpm +texinfo 7.2-1 alpm +tinysparql 3.10.1-2 alpm +tomli 2.0.1 python +tpm2-tss 4.1.3-1 alpm +ttf-liberation 2.1.5-2 alpm +turbojpeg UNKNOWN java-archive +typeguard 4.3.0 python +typing-extensions 4.12.2 python +typing-extensions 4.15.0 python +tzdata 2025c-1 alpm +util-linux 2.41.3-1 alpm +util-linux-libs 2.41.3-1 alpm +vte-common 0.82.3-1 alpm +vte3 0.82.3-1 alpm +vulkan-icd-loader 1.4.335.0-1 alpm +vulkan-intel 1:25.3.3-1 alpm +vulkan-mesa-implicit-layers 1:25.3.3-1 alpm +vulkan-radeon 1:25.3.3-1 alpm +vulkan-tools 1.4.335.0-1 alpm +watchdog 6.0.0 python +wayland 1.24.0-1 alpm +webrtc-audio-processing-1 1.3-5 alpm +websockets 15.0.1 python +wheel 0.45.1 python +which 2.23-1 alpm +wl-clipboard 1:2.2.1-3 alpm +wlr-randr 0.5.0-1 alpm +wlroots0.19 0.19.2-2 alpm +wtype 0.4-2 alpm +x264 3:0.165.r3222.b35605a-2 alpm +xbitmaps 1.1.3-2 alpm +xcb-proto 1.17.0-3 alpm +xcb-util 0.4.1-2 alpm +xcb-util-cursor 0.1.6-1 alpm +xcb-util-errors 1.0.1-2 alpm +xcb-util-image 0.4.1-3 alpm +xcb-util-keysyms 0.4.1-5 alpm +xcb-util-renderutil 0.3.10-2 alpm +xcb-util-wm 0.4.2-2 alpm +xcb-util-xrm 1.3-4 alpm +xclip 0.13-6 alpm +xcursor-themes 1.0.7-2 alpm +xdg-utils 1.2.1-2 alpm +xdotool 3.20211022.1-2 alpm +xf86-input-libinput 1.5.0-1 alpm +xf86-video-amdgpu 25.0.0-1 alpm +xf86-video-ati 1:22.0.0-2 alpm +xf86-video-intel 1:2.99.917+939+g4a64400e-1 alpm +xf86-video-nouveau 1.0.18-1 alpm +xf86-video-qxl 0.1.6-2 alpm +xfce4-terminal 1.1.5-2 alpm +xfconf 4.20.0-2 alpm +xkbcommon 1.5.1 python +xkeyboard-config 2.46-1 alpm +xorg-font-util 1.4.1-2 alpm +xorg-fonts-100dpi 1.0.4-3 alpm +xorg-fonts-75dpi 1.0.4-2 alpm +xorg-fonts-alias-100dpi 1.0.5-1 alpm +xorg-fonts-alias-75dpi 1.0.5-1 alpm +xorg-fonts-alias-misc 1.0.5-1 alpm +xorg-fonts-encodings 1.1.0-1 alpm +xorg-fonts-misc 1.0.4-2 alpm +xorg-server 21.1.21-1 alpm +xorg-server-common 21.1.21-1 alpm +xorg-server-xvfb 21.1.21-1 alpm +xorg-setxkbmap 1.3.4-2 alpm +xorg-xauth 1.1.5-1 alpm +xorg-xkbcomp 1.5.0-1 alpm +xorg-xprop 1.2.8-1 alpm +xorg-xrandr 1.5.3-1 alpm +xorg-xrdb 1.2.2-2 alpm +xorg-xset 1.2.5-2 alpm +xorg-xwayland 24.1.9-1 alpm +xorgproto 2025.1-1 alpm +xsel 1.2.1-2 alpm +xsettingsd 1.0.2-3 alpm +xterm 406-1 alpm +xxhash 0.8.3-1 alpm +xz 5.8.2-1 alpm +yajl 2.1.0-6 alpm +yarl 1.22.0 python +zipp 3.19.2 python +zlib 1:1.3.1-2 alpm +zstd 1.5.7-2 alpm diff --git a/readme-vars.yml b/readme-vars.yml index 28b85b876..1a78df752 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -2,80 +2,7 @@ # project information project_name: webtop -project_url: "https://github.com/linuxserver/docker-webtop" -project_logo: "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/webtop-logo.png" -project_blurb: | - [{{ project_name|capitalize }}]({{ project_url }}) - Alpine and Ubuntu based containers containing full desktop environments in officially supported flavors accessible via any modern web browser. -project_lsio_github_repo_url: "https://github.com/linuxserver/docker-{{ project_name }}" - -# supported architectures -available_architectures: - - { arch: "{{ arch_x86_64 }}", tag: "amd64-latest"} - - { arch: "{{ arch_arm64 }}", tag: "arm64v8-latest"} - - { arch: "{{ arch_armhf }}", tag: "arm32v7-latest"} - -# development version -development_versions: true -development_versions_items: - - { tag: "latest", desc: "XFCE Alpine" } - - { tag: "ubuntu-xfce", desc: "XFCE Ubuntu" } - - { tag: "alpine-kde", desc: "KDE Alpine" } - - { tag: "ubuntu-kde", desc: "KDE Ubuntu" } - - { tag: "alpine-mate", desc: "MATE Alpine" } - - { tag: "ubuntu-mate", desc: "MATE Ubuntu" } - - { tag: "alpine-i3", desc: "i3 Alpine" } - - { tag: "ubuntu-i3", desc: "i3 Ubuntu" } - - { tag: "alpine-openbox", desc: "Openbox Alpine" } - - { tag: "ubuntu-openbox", desc: "Openbox Ubuntu" } - - { tag: "alpine-icewm", desc: "IceWM Alpine" } - - { tag: "ubuntu-icewm", desc: "IceWM Ubuntu" } - -# container parameters -privileged: "optional" -param_container_name: "{{ project_name }}" -param_usage_include_vols: true -param_volumes: - - { vol_path: "/config", vol_host_path: "/path/to/data", desc: "abc users home directory" } -param_usage_include_ports: true -param_ports: - - { external_port: "3000", internal_port: "3000", port_desc: "Web Desktop GUI" } -param_usage_include_env: true -param_env_vars: - - { env_var: "TZ", env_value: "Europe/London", desc: "Specify a timezone to use EG Europe/London"} -# optional variables -opt_param_usage_include_env: true -opt_param_env_vars: - - { env_var: "SUBFOLDER", env_value: "/", desc: "Specify a subfolder to use with reverse proxies, IE `/subfolder/`"} -opt_param_usage_include_vols: true -opt_param_volumes: - - { vol_path: "/var/run/docker.sock", vol_host_path: "/var/run/docker.sock", desc: "Docker Socket on the system, if you want to use Docker in the container" } -opt_custom_params: - - { name: "shm-size", name_compose: "shm_size", value: "1gb",desc: "We set this to 1 gig to prevent modern web browsers from crashing" } - -# application setup block -app_setup_block_enabled: true -app_setup_block: | - The Webtop can be accessed at: - - * http://yourhost:3000/ - - By default the user/pass is abc/abc, if you change your password or want to login manually to the GUI session for any reason use the following link: - - * http://yourhost:3000/?login=true - - You can access advanced features of the Guacamole remote desktop using ctrl+alt+shift enabling you to use remote copy/paste or an onscreen keyboard. - - **Unlike our other containers these Desktops are not designed to be upgraded by Docker, you will keep your home directoy but anything you installed system level will be lost if you upgrade an existing container. To keep packages up to date instead use Ubuntu's own apt program or Alpine's apk program** - - **The KDE and i3 flavors for Ubuntu need to be run in privileged mode to function properly** - - If you ever lose your password you can always reset it by execing into the container as root: - ``` - docker exec -it webtop passwd abc - ``` - By default we perform all logic for the abc user and we reccomend using that user only in the container, but new users can be added as long as there is a `startwm.sh` executable script in their home directory. - All of these containers are configured with passwordless sudo, we make no efforts to secure or harden these containers and we do not reccomend ever publishing their ports to the public Internet. - -# changelog -changelogs: - - { date: "20.04.21:", desc: "Initial release." } +full_custom_readme: | + {% raw -%} + Up to date documentation is available [here](https://github.com/linuxserver/docker-webtop/blob/master/README.md). + {%- endraw %} diff --git a/root/defaults/startwm.sh b/root/defaults/startwm.sh index f60ea511e..131f5ae22 100755 --- a/root/defaults/startwm.sh +++ b/root/defaults/startwm.sh @@ -1,3 +1,13 @@ #!/bin/bash -/usr/bin/pulseaudio --start -/usr/bin/startxfce4 > /dev/null 2>&1 + +# Enable Nvidia GPU support if detected +if which nvidia-smi > /dev/null 2>&1 && ls -A /dev/dri 2>/dev/null && [ "${DISABLE_ZINK}" == "false" ]; then + export LIBGL_KOPPER_DRI2=1 + export MESA_LOADER_DRIVER_OVERRIDE=zink + export GALLIUM_DRIVER=zink +fi + +# Launch DE +setterm blank 0 +setterm powerdown 0 +/usr/bin/i3 > /dev/null 2>&1 diff --git a/root/defaults/startwm_wayland.sh b/root/defaults/startwm_wayland.sh new file mode 100755 index 000000000..d3872c59f --- /dev/null +++ b/root/defaults/startwm_wayland.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# Launch DE +setterm blank 0 +setterm powerdown 0 +WAYLAND_DISPLAY=wayland-1 /usr/bin/sway > /dev/null 2>&1 diff --git a/root/usr/bin/chromium b/root/usr/bin/chromium new file mode 100755 index 000000000..58df5efd9 --- /dev/null +++ b/root/usr/bin/chromium @@ -0,0 +1,15 @@ +#! /bin/bash + +BIN=/usr/bin/chromium-real + +# Cleanup +if ! pgrep chromium > /dev/null;then + rm -f $HOME/.config/chromium/Singleton* +fi + +# Run normally on privved containers or modified un non priv +if grep -q 'Seccomp:.0' /proc/1/status; then + ${BIN} --password-store=basic "$@" +else + ${BIN} --password-store=basic --no-sandbox --test-type "$@" +fi