├── .github ├── CODEOWNERS ├── dependabot.yml └── renovate.json ├── bin ├── branding-files.list ├── branding.list ├── test_branding.py ├── branding.py └── indexGenerator.py ├── credentials ├── test.pkcs12.password.txt ├── test.gpg.password.txt ├── test.keychain.password.txt ├── test.gpg ├── sandbox.gpg ├── test.pkcs12 ├── test.keychain ├── test.secret.gpg ├── apple.conf ├── ssh │ ├── id_rsa.pub │ ├── known_hosts │ └── id_rsa ├── Makefile ├── test.mk ├── test.csr ├── test.crt ├── test.key ├── README.md └── test.ascii.key ├── deb ├── build │ ├── debian │ │ ├── source │ │ │ └── format │ │ ├── jenkins.install │ │ ├── rules │ │ ├── jenkins.logrotate │ │ ├── copyright │ │ ├── control │ │ ├── jenkins.dirs │ │ ├── jenkins.postrm │ │ ├── jenkins.postinst │ │ ├── jenkins.default │ │ └── jenkins.init │ └── build.sh ├── publish │ ├── contents │ │ └── binary │ │ │ └── .htaccess │ ├── release.conf │ └── publish.sh └── setup.sh ├── systemd ├── jenkins.conf ├── jenkins.sh ├── jenkins.service └── migrate.sh ├── branding ├── jenkins-rc.mk ├── jenkins-stable.mk ├── jenkins-stable-rc.mk ├── jenkins.mk ├── jenkins-experimental.mk ├── description-file ├── common ├── test.mk ├── license-mit └── README.md ├── templates ├── index.html ├── header.root.html ├── header.msi.html ├── footer.html ├── header.war.html ├── header.rpm.html ├── header.debian.html └── base.html ├── msi ├── build │ ├── nuget.exe │ ├── .gitignore │ ├── banner.bmp │ ├── jenkins.bmp │ ├── jenkins.ico │ ├── packages.config │ ├── jenkins.exe.config │ ├── License.rtf │ ├── jenkins_en-US.wxl │ ├── build.ps1 │ ├── jenkins.wixproj │ └── Update-JenkinsVersion.ps1 ├── publish │ ├── publish.sh │ └── publish.ps1 └── docs │ └── build-msi-locally.md ├── requirements.txt ├── rpm ├── setup.sh ├── build │ ├── build.sh │ └── SPECS │ │ └── jenkins.spec └── publish │ └── publish.sh ├── .gitignore ├── molecule ├── servlet │ ├── converge.yml │ ├── molecule.yml │ ├── configure-tomcat.yml │ ├── Dockerfile.j2 │ └── verify.yml └── default │ ├── converge.yml │ ├── install-deb.yml │ ├── install-suse.yml │ ├── install-rpm.yml │ ├── Dockerfile.j2 │ ├── verify.yml │ └── molecule.yml ├── prep.sh ├── env └── test.mk ├── .gitattributes ├── war └── publish │ └── publish.sh ├── docker-compose.yaml ├── setup.mk ├── Makefile ├── Jenkinsfile ├── make.ps1 ├── README.md └── pkgConfig └── httpd.conf /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jenkinsci/core 2 | -------------------------------------------------------------------------------- /bin/branding-files.list: -------------------------------------------------------------------------------- 1 | DESCRIPTION_FILE -------------------------------------------------------------------------------- /credentials/test.pkcs12.password.txt: -------------------------------------------------------------------------------- 1 | s3cr3t -------------------------------------------------------------------------------- /credentials/test.gpg.password.txt: -------------------------------------------------------------------------------- 1 | s3cr3t 2 | -------------------------------------------------------------------------------- /credentials/test.keychain.password.txt: -------------------------------------------------------------------------------- 1 | s3cr3t -------------------------------------------------------------------------------- /deb/build/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /deb/publish/contents/binary/.htaccess: -------------------------------------------------------------------------------- 1 | Options -Indexes 2 | -------------------------------------------------------------------------------- /systemd/jenkins.conf: -------------------------------------------------------------------------------- 1 | D /run/jenkins 0770 jenkins jenkins - 2 | -------------------------------------------------------------------------------- /branding/jenkins-rc.mk: -------------------------------------------------------------------------------- 1 | export RELEASELINE=-rc 2 | include branding/common 3 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% include header %} 2 | {% include "footer.html" %} 3 | -------------------------------------------------------------------------------- /branding/jenkins-stable.mk: -------------------------------------------------------------------------------- 1 | export RELEASELINE=-stable 2 | include branding/common 3 | -------------------------------------------------------------------------------- /branding/jenkins-stable-rc.mk: -------------------------------------------------------------------------------- 1 | export RELEASELINE=-stable-rc 2 | include branding/common 3 | -------------------------------------------------------------------------------- /msi/build/nuget.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/msi/build/nuget.exe -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ansible==10.7.0 2 | jinja2==3.1.6 3 | molecule-plugins[docker]==23.7.0 4 | -------------------------------------------------------------------------------- /credentials/test.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/credentials/test.gpg -------------------------------------------------------------------------------- /msi/build/.gitignore: -------------------------------------------------------------------------------- 1 | msiext-1.5/ 2 | msiext-1.5.zip 3 | packages/ 4 | tmp/ 5 | bin/ 6 | obj/ 7 | -------------------------------------------------------------------------------- /msi/build/banner.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/msi/build/banner.bmp -------------------------------------------------------------------------------- /msi/build/jenkins.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/msi/build/jenkins.bmp -------------------------------------------------------------------------------- /msi/build/jenkins.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/msi/build/jenkins.ico -------------------------------------------------------------------------------- /credentials/sandbox.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/credentials/sandbox.gpg -------------------------------------------------------------------------------- /credentials/test.pkcs12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/credentials/test.pkcs12 -------------------------------------------------------------------------------- /rpm/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | sudo apt-get install -y rpm expect || true 4 | 5 | exit 0 6 | -------------------------------------------------------------------------------- /branding/jenkins.mk: -------------------------------------------------------------------------------- 1 | export RELEASELINE= 2 | export ORGANIZATION=jenkins.io 3 | include branding/common 4 | -------------------------------------------------------------------------------- /credentials/test.keychain: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/credentials/test.keychain -------------------------------------------------------------------------------- /credentials/test.secret.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/packaging/HEAD/credentials/test.secret.gpg -------------------------------------------------------------------------------- /deb/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | sudo apt-get install -y devscripts apt-utils || true 4 | 5 | exit 0 6 | -------------------------------------------------------------------------------- /branding/jenkins-experimental.mk: -------------------------------------------------------------------------------- 1 | export RELEASELINE=-experimental 2 | export ORGANIZATION=jenkins.io 3 | include branding/common 4 | -------------------------------------------------------------------------------- /deb/build/debian/jenkins.install: -------------------------------------------------------------------------------- 1 | @@ARTIFACTNAME@@ usr/bin 2 | @@ARTIFACTNAME@@.war usr/share/java 3 | migrate usr/share/@@ARTIFACTNAME@@ 4 | -------------------------------------------------------------------------------- /msi/build/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.msi 2 | *.war 3 | *.zip 4 | *.deb 5 | *.rpm 6 | *.log 7 | target 8 | generated 9 | .iml 10 | .idea/ 11 | *.orig 12 | 13 | venv/ 14 | pkg.jenkins.io/ 15 | -------------------------------------------------------------------------------- /molecule/servlet/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | tasks: 5 | - include_tasks: configure-tomcat.yml 6 | when: ansible_hostname == 'tomcat-10' 7 | -------------------------------------------------------------------------------- /deb/publish/release.conf: -------------------------------------------------------------------------------- 1 | // Used to drive apt-ftparchive 2 | APT::FTPArchive::Release::Origin "jenkins.io"; 3 | APT::FTPArchive::Release::Suite "binary"; 4 | APT::FTPArchive::Release::Architectures "all"; 5 | 6 | -------------------------------------------------------------------------------- /deb/build/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ 5 | 6 | # debian doesn't support the zstd compression which is the default on Ubuntu 7 | # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=892664 8 | override_dh_builddeb: 9 | dh_builddeb -- -Zxz 10 | -------------------------------------------------------------------------------- /msi/build/jenkins.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 2 | --- 3 | version: 2 4 | updates: 5 | - package-ecosystem: "pip" 6 | directory: "/" 7 | schedule: 8 | interval: "weekly" 9 | -------------------------------------------------------------------------------- /deb/build/debian/jenkins.logrotate: -------------------------------------------------------------------------------- 1 | /var/log/@@ARTIFACTNAME@@/@@ARTIFACTNAME@@.log /var/log/@@ARTIFACTNAME@@/access_log { 2 | weekly 3 | copytruncate 4 | missingok 5 | rotate 52 6 | compress 7 | delaycompress 8 | notifempty 9 | } 10 | -------------------------------------------------------------------------------- /templates/header.root.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Jenkins Core Packages{% endblock %} 4 | 5 | {% block distribution_instruction %}{% endblock %} 6 | {% block java_instructions %}{% endblock %} 7 | 8 | {% block individual_package_instruction %}{% endblock %} 9 | -------------------------------------------------------------------------------- /credentials/apple.conf: -------------------------------------------------------------------------------- 1 | [ req ] 2 | distinguished_name = req_name 3 | prompt = no 4 | [ req_name ] 5 | CN = my-test-installer 6 | [ extensions ] 7 | basicConstraints=critical,CA:false 8 | keyUsage=critical,digitalSignature 9 | extendedKeyUsage=critical,1.2.840.113635.100.4.13 10 | 1.2.840.113635.100.6.1.14=critical,DER:0500 11 | -------------------------------------------------------------------------------- /templates/header.msi.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block distribution_instruction %} 4 | 5 |

6 | This is the MSI package repository of {{product_name}} for installation. 7 |

8 | {% endblock %} 9 | 10 | {% block individual_package_instruction %}{% endblock %} 11 | {% block java_instructions %}{% endblock %} 12 | -------------------------------------------------------------------------------- /bin/branding.list: -------------------------------------------------------------------------------- 1 | PRODUCTNAME 2 | ARTIFACTNAME 3 | CAMELARTIFACTNAME 4 | VENDOR 5 | SUMMARY 6 | PORT 7 | MSI_PRODUCTCODE 8 | AUTHOR 9 | LICENSE 10 | HOMEPAGE 11 | CHANGELOG_PAGE 12 | ORGANIZATION 13 | ---------------------------------- 14 | RELEASELINE 15 | RPM_URL 16 | DEB_URL 17 | LICENSE_TEXT 18 | LICENSE_TEXT_DEB 19 | LICENSE_TEXT_COMMENTED 20 | -------------------------------------------------------------------------------- /molecule/servlet/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | platforms: 7 | - name: tomcat-10 8 | image: tomcat:10-jdk21-temurin 9 | volumes: 10 | - ${MOLECULE_PROJECT_DIRECTORY}/jenkins.war:/usr/local/tomcat/webapps/jenkins.war 11 | provisioner: 12 | name: ansible 13 | verifier: 14 | name: ansible 15 | -------------------------------------------------------------------------------- /molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | tasks: 6 | - include_tasks: install-deb.yml 7 | when: ansible_os_family == 'Debian' 8 | - include_tasks: install-rpm.yml 9 | when: ansible_os_family == 'RedHat' 10 | - include_tasks: install-suse.yml 11 | when: ansible_os_family == 'Suse' 12 | -------------------------------------------------------------------------------- /deb/build/debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: Jenkins 3 | Upstream-Contact: http://jenkins.io/ 4 | Source: https://github.com/jenkinsci/jenkins 5 | 6 | Files: * 7 | Copyright: 2004-, @@AUTHOR@@, Sun Microsystems, Inc., and a number of other of contributors 8 | License: @@LICENSE@@ 9 | @@LICENSE_TEXT_DEB@@ 10 | -------------------------------------------------------------------------------- /credentials/ssh/id_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDptAk3xx4vlPsVo2zZB1IScaAsrLnO+m45EMkt3RD/BObkNUxXGonNPyEK0vtrgPU0E9oGbqkC+XEKcoyF1nBKL57bO7NGiQ66K+UAfKJXuV70ufUr+kqQNyEAjPw/dhYu3VhkkRENQjyddb0wLxk4S38i52YtOxlBxKvyVc4UjA1l7hv81Kv/2zG9KdhCrDmrqPVnF2Nb8q1c9BqlT485tn/fWPNMf1b3roumgXxdijTFECEm/Ld/43FtJU+GMfjbbAcJ57J8j/4H/FiVU0LfJhHg429dsBex7AHRpGGc5+H6xKTOi04IMwFkc6MquDbswuzR1+uaPEZ98XZWr4l olblak@winterfell 2 | -------------------------------------------------------------------------------- /deb/build/debian/control: -------------------------------------------------------------------------------- 1 | Source: @@ARTIFACTNAME@@ 2 | Section: devel 3 | Priority: optional 4 | Maintainer: @@AUTHOR@@ 5 | Build-Depends: debhelper-compat (= 13) 6 | Standards-Version: 4.6.0 7 | Homepage: @@HOMEPAGE@@ 8 | 9 | Package: @@ARTIFACTNAME@@ 10 | Architecture: all 11 | Depends: ${misc:Depends}, adduser, lsb-base (>= 3.2-14), net-tools, sysvinit-utils (>= 2.88dsf-50) 12 | Pre-Depends: ${misc:Pre-Depends} 13 | Description: @@DESCRIPTION_FILE@@ 14 | -------------------------------------------------------------------------------- /credentials/ssh/known_hosts: -------------------------------------------------------------------------------- 1 | |1|3Ao1unSiaoLJcBH+jj4LxlUJvU8=|9VCo6soeOkBokfDfbckMBvnE/6k= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFnJjx5araEbR3BvluFk5ONHqZSVZW1osdn4NuC/UBFPxwcEkkECK0EHR+WTxfTLGybJCTh3H5hTDady7W0EyIs= 2 | |1|Orovxffw11DXksUZda8iwv3XcME=|OIrRb9oqBvY2esPMc+I0K70HLSs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFnJjx5araEbR3BvluFk5ONHqZSVZW1osdn4NuC/UBFPxwcEkkECK0EHR+WTxfTLGybJCTh3H5hTDady7W0EyIs= 3 | -------------------------------------------------------------------------------- /deb/build/debian/jenkins.dirs: -------------------------------------------------------------------------------- 1 | # moved from rules install 2 | usr/share/@@ARTIFACTNAME@@ 3 | 4 | # this is where JENKINS_HOME is stored, so let's leave it as is for now 5 | var/lib/@@ARTIFACTNAME@@ 6 | 7 | # Store jenkins log file in it's own directory since they can become rather large and in the future 8 | # rotating logs can be easily added. 9 | var/log/@@ARTIFACTNAME@@ 10 | 11 | # Cache directory for the unpacked jenkins.war file. 12 | var/cache/@@ARTIFACTNAME@@ 13 | -------------------------------------------------------------------------------- /branding/description-file: -------------------------------------------------------------------------------- 1 | Jenkins is the leading open source automation server supported by a large and growing community of developers, testers, designers and other people interested in continuous integration, continuous delivery and modern software delivery practices. Built on the Java Virtual Machine (JVM), it provides more than 2,000 plugins that extend Jenkins to automate with practically any technology software delivery teams use. In 2022, Jenkins reached 300,000 known installations making it the most widely deployed automation server. 2 | 3 | For more information, see https://www.jenkins.io. 4 | -------------------------------------------------------------------------------- /credentials/Makefile: -------------------------------------------------------------------------------- 1 | test.crt: test.key test.csr apple.conf 2 | openssl x509 -in test.csr -out test.crt -req -signkey test.key -days 36500 -extfile apple.conf -extensions extensions 3 | 4 | test.pkcs12: test.key test.crt 5 | openssl pkcs12 -export -inkey test.key -in test.crt -out test.pkcs12 -password pass:s3cr3t 6 | 7 | # generate keychain file to go through the signing process 8 | test.keychain: test.pkcs12 9 | @rm $@ 2>&1 > /dev/null || true 10 | security create-keychain -p s3cr3t `pwd`/test.keychain 11 | security import test.pkcs12 -k `pwd`/test.keychain -t agg -f pkcs12 -A -P s3cr3t 12 | 13 | -------------------------------------------------------------------------------- /prep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | set -o pipefail 3 | cd "$(dirname "$0")" 4 | 5 | # TODO jenkins-infra/release performs similar preparatory actions: downloading 6 | # the WAR and importing the GPG key. A common interface for the preparatory 7 | # actions should be designed that meets the needs of both local testing and 8 | # releases, ideally implemented in the Makefile. Then both this repository and 9 | # jenkins-infra/release should be refactored to consume the new functionality. 10 | 11 | if [[ ! -f $WAR ]]; then 12 | jv download 13 | fi 14 | 15 | if ! gpg --fingerprint "${GPG_KEYNAME}"; then 16 | gpg --import --batch "${GPG_FILE}" 17 | fi 18 | 19 | # produces: jenkins.war 20 | exit 0 21 | -------------------------------------------------------------------------------- /molecule/default/install-deb.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - package: 3 | name: 4 | - fontconfig 5 | state: present 6 | update_cache: true 7 | - package: 8 | name: 9 | - openjdk-17-jre 10 | state: present 11 | when: ansible_distribution == "Debian" and ansible_distribution_major_version < "13" 12 | - package: 13 | name: 14 | - openjdk-21-jre 15 | state: present 16 | when: (ansible_distribution == "Debian" and ansible_distribution_major_version == "13") or ansible_distribution == "Ubuntu" 17 | - find: 18 | paths: /var/tmp/target/debian 19 | file_type: file 20 | patterns: "*.deb" 21 | register: package_list 22 | - assert: 23 | that: 24 | - package_list.matched == 1 25 | - apt: 26 | deb: "{{ package_list.files[0].path }}" 27 | -------------------------------------------------------------------------------- /env/test.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Environment definition for dry-run of the packaging process 3 | # 4 | 5 | # where to put binary files 6 | export TESTDIR=$(realpath .)/pkg.jenkins.io 7 | export WARDIR=${TESTDIR}/war${RELEASELINE} 8 | export MSIDIR=${TESTDIR}/windows${RELEASELINE} 9 | export DEBDIR=${TESTDIR}/debian${RELEASELINE}/binary 10 | export RPMDIR=${TESTDIR}/rpm${RELEASELINE} 11 | 12 | # where to put repository index and other web contents 13 | export RPM_WEBDIR=${TESTDIR}/rpm${RELEASELINE} 14 | export DEB_WEBDIR=${TESTDIR}/debian${RELEASELINE} 15 | export MSI_WEBDIR=${TESTDIR}/windows${RELEASELINE} 16 | 17 | # URL to the aforementioned webdir. 18 | WEBSERVER=https://pkg.jenkins.io 19 | export RPM_URL=${WEBSERVER}/rpm${RELEASELINE} 20 | export DEB_URL=${WEBSERVER}/debian${RELEASELINE} 21 | -------------------------------------------------------------------------------- /molecule/servlet/configure-tomcat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - copy: 3 | dest: "/usr/local/tomcat/bin/setenv.sh" 4 | content: "export CATALINA_OPTS=-DJENKINS_HOME=/var/tmp/jenkins_home" 5 | mode: "0755" 6 | - xml: 7 | path: "/usr/local/tomcat/conf/server.xml" 8 | xpath: "/Server/Service/Engine/Host" 9 | set_children: 10 | - Valve: 11 | className: "org.apache.catalina.valves.AccessLogValve" 12 | directory: "logs" 13 | prefix: "localhost_access_log" 14 | suffix: ".txt" 15 | pattern: '%h %l %u %t "%r" %s %b' 16 | - Valve: 17 | className: "org.apache.catalina.valves.RemoteIpValve" 18 | remoteIpHeader: "X-Forwarded-For" 19 | proxiesHeader: "X-Forwarded-By" 20 | protocolHeader: "X-Forwarded-Proto" 21 | -------------------------------------------------------------------------------- /branding/common: -------------------------------------------------------------------------------- 1 | # this isn't a release line by itself but instead defines the commonality of the all OSS release lines. 2 | 3 | export PRODUCTNAME=Jenkins 4 | export ARTIFACTNAME=jenkins 5 | export CAMELARTIFACTNAME=Jenkins 6 | export VENDOR=Jenkins project 7 | export SUMMARY=Jenkins Automation Server 8 | export PORT=8080 9 | 10 | export MSI_PRODUCTCODE=415933d8-4104-47c3-aee9-66b31de07a57 11 | export AUTHOR=Kohsuke Kawaguchi 12 | export LICENSE=MIT/X License, GPL/CDDL, ASL2 13 | export HOMEPAGE=https://www.jenkins.io/ 14 | export CHANGELOG_PAGE=https://www.jenkins.io/changelog 15 | 16 | # figure out the directory of this file 17 | BRANDING_DIR:=$(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))") 18 | 19 | export DESCRIPTION_FILE=$(BRANDING_DIR)/description-file 20 | export LICENSE_FILE=$(BRANDING_DIR)/license-mit 21 | -------------------------------------------------------------------------------- /templates/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 32 | -------------------------------------------------------------------------------- /credentials/test.mk: -------------------------------------------------------------------------------- 1 | # Contains bogus keys and certificates just so that we can go through the whole motion of signing bits 2 | # For actual use, you need your own keys and valid certificates. see README.md 3 | 4 | CREDENTIAL_DIR:=$(abspath $(dir $(lastword $(MAKEFILE_LIST))))/ 5 | 6 | export GPG_KEYRING :=${CREDENTIAL_DIR}test.gpg 7 | export GPG_PUBLIC_KEY :=${CREDENTIAL_DIR}test.ascii.key 8 | export GPG_SECRET_KEYRING :=${CREDENTIAL_DIR}test.secret.gpg 9 | # file that contains GPG passphrase 10 | export GPG_PASSPHRASE_FILE:=$(CREDENTIAL_DIR)test.gpg.password.txt 11 | 12 | export PKCS12_FILE :=$(CREDENTIAL_DIR)test.pkcs12 13 | export PKCS12_PASSWORD_FILE:=$(CREDENTIAL_DIR)test.pkcs12.password.txt 14 | 15 | export KEYCHAIN_FILE :=${CREDENTIAL_DIR}test.keychain 16 | export KEYCHAIN_PASSWORD_FILE:=${CREDENTIAL_DIR}test.keychain.password.txt 17 | -------------------------------------------------------------------------------- /branding/test.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Profile for testing release process 3 | # 4 | export RELEASELINE= 5 | 6 | export PRODUCTNAME=Jenkins Test 7 | export ARTIFACTNAME=jenkinstest 8 | export CAMELARTIFACTNAME=JenkinsTest 9 | export VENDOR=Jenkins Test project 10 | export SUMMARY=Jenkins Automation Server (Test) 11 | export PORT=7777 12 | 13 | export MSI_PRODUCTCODE=e76baa9f-2bb2-49e5-b518-8a5b7d1cd084 14 | export AUTHOR=Bogus user 15 | export LICENSE=MIT/X License, GPL/CDDL, ASL2 16 | export HOMEPAGE=http://test.jenkins.io/ 17 | export CHANGELOG_PAGE=http://test.jenkins.io/changelog 18 | 19 | export ORGANIZATION=example.org 20 | 21 | # figure out the directory of this file 22 | BRANDING_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) 23 | 24 | export DESCRIPTION_FILE=$(BRANDING_DIR)/description-file 25 | export LICENSE_FILE=$(BRANDING_DIR)/license-mit 26 | -------------------------------------------------------------------------------- /molecule/default/install-suse.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - package: 3 | name: 4 | - dejavu-fonts 5 | - fontconfig 6 | - java-21-openjdk 7 | state: present 8 | update_cache: true 9 | - file: 10 | path: /var/tmp/target/credentials 11 | state: directory 12 | - copy: 13 | src: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/credentials/test.ascii.key" 14 | dest: /var/tmp/target/credentials/test.ascii.key 15 | - rpm_key: 16 | state: present 17 | key: /var/tmp/target/credentials/test.ascii.key 18 | - find: 19 | paths: /var/tmp/target/rpm 20 | file_type: file 21 | patterns: "*.rpm" 22 | register: package_list 23 | - assert: 24 | that: 25 | - package_list.matched == 1 26 | - package: 27 | name: "{{ package_list.files[0].path }}" 28 | state: present 29 | - zypper_repository: 30 | name: jenkins 31 | state: absent 32 | -------------------------------------------------------------------------------- /templates/header.war.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block distribution_instruction %} 4 | 5 |

6 | This is the WAR package repository of {{ product_name }} for installation. 7 |

8 | {% endblock %} 9 | 10 | {% block java_instructions %} 11 |

12 | You will need to explicitly install a supported Java runtime environment (JRE), 13 | e.g. Eclipse Temurin. 14 |

15 | 16 |

17 | To determine the Java version that is supported for your Jenkins environment, please refer to the Java support policy. 18 |

19 | 20 | {% endblock %} 21 | 22 | {% block individual_package_instruction %} 23 | 24 |

25 | If you need *.war for a specific version, use these. 26 |

27 | 28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /rpm/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | # prepare fresh directories 4 | D=$(mktemp -d) 5 | trap 'rm -rf "${D}"' EXIT 6 | 7 | cp -R "$(dirname "$0")"/* "${D}" 8 | mkdir -p "${D}/SOURCES" 9 | cp "${BASE}/systemd/jenkins.service" "${D}/SOURCES" 10 | cp "${BASE}/systemd/jenkins.sh" "${D}/SOURCES" 11 | cp "${BASE}/systemd/migrate.sh" "${D}/SOURCES" 12 | cp "${BASE}/systemd/jenkins.conf" "${D}/SOURCES" 13 | "${BASE}/bin/branding.py" "${D}" 14 | 15 | cp "${WAR}" "${D}/SOURCES/jenkins.war" 16 | 17 | pushd "${D}" 18 | mkdir -p BUILD RPMS SRPMS 19 | rpmbuild -ba --define="_topdir ${PWD}" --define="_tmppath ${PWD}/tmp" --define="ver ${VERSION}" SPECS/jenkins.spec 20 | 21 | # sign the results 22 | find RPMS -type f -name '*.rpm' -exec rpmsign --addsign '{}' \; 23 | find RPMS -type f -name '*.rpm' -exec rpm -qpi '{}' \; 24 | popd 25 | 26 | mkdir -p "$(dirname "${RPM}")" 27 | mv "${D}"/RPMS/noarch/*.rpm "${RPM}" 28 | 29 | exit 0 30 | -------------------------------------------------------------------------------- /deb/build/debian/jenkins.postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | case "$1" in 6 | purge) 7 | if [ -x "$(command -v deluser)" ]; then 8 | deluser --quiet --system @@ARTIFACTNAME@@ || echo "failed to remove @@ARTIFACTNAME@@ system user" >&2 9 | else 10 | userdel @@ARTIFACTNAME@@ || echo "failed to remove @@ARTIFACTNAME@@ system user" >&2 11 | fi 12 | if [ -x "$(command -v delgroup)" ]; then 13 | delgroup --quiet --system --only-if-empty @@ARTIFACTNAME@@ || echo "failed to remove @@ARTIFACTNAME@@ system user" >&2 14 | else 15 | groupdel @@ARTIFACTNAME@@ || echo "failed to remove @@ARTIFACTNAME@@ system group" >&2 16 | fi 17 | rm -rf /var/lib/@@ARTIFACTNAME@@ /var/log/@@ARTIFACTNAME@@ \ 18 | /var/run/@@ARTIFACTNAME@@ /var/cache/@@ARTIFACTNAME@@ 19 | ;; 20 | 21 | remove | upgrade | failed-upgrade | abort-install | abort-upgrade | disappear) ;; 22 | 23 | \ 24 | *) 25 | echo "postrm called with unknown argument \`$1'" >&2 26 | exit 1 27 | ;; 28 | esac 29 | 30 | #DEBHELPER# 31 | 32 | exit 0 33 | -------------------------------------------------------------------------------- /branding/license-mit: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /credentials/test.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIC/jCCAeYCAQAwgbgxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdOb3doZXJlMRUw 3 | EwYDVQQHDAxOb3doZXJlIENpdHkxHjAcBgNVBAoMFUJvZ3VzIFRlc3RpbmcgQ29t 4 | cGFueTEeMBwGA1UECwwVRG8gTm90IFVzZSBEZXBhcnRtZW50MRkwFwYDVQQDDBBN 5 | ci5TZWxmaWUgU2lnbmVyMSUwIwYJKoZIhvcNAQkBFhZub3JlcGx5QGplbmtpbnMt 6 | Y2kub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvRHgamoEgcF1 7 | FqN0YusXKWZuZL7iAy1wLs9zeUj5HxwuHmF6MBKCvF44JU3A6BIx7xOaLbb+G6qZ 8 | j0MlpVzl2ra54PWn7KffGgOF8bxJ6CnYaBXpJfrBW+ORTfbV9tGSNhqzc0Z1Gfe/ 9 | +EgFuKuD6FmPJpUIzdMFrnfs9k0In1sP+VbdlUyFsvshlv6zTmYygNKKroXODqYX 10 | YyEkS9RV3YvIzhIHx4PmTN9XIOo71ZwieRM1aVBv4lIxGqPF08f/x/fP5Nm/aWkT 11 | 7S1vQ9VGtd4J4TxVs2tlKndtUaB0wlGIEXRk0cxIQ2fFaPhnjqjo0pJJbbqFAHF0 12 | qYm4PYtyMwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAHwqbR5qArzPP/5Ck+kc 13 | OVtQnjLb3bwzCbf6vl6Zr4JNBUHGpxCgR9CvtRBh+inpn8Zh7HSSOPRCqJPTL8q7 14 | WtGRMgdLsGT0whT2UbZSpcXM4HZAQ53qsrpCRkL+k/qlbmhvgdvwYxpEv0YHI8UO 15 | 6oByogpqrRfauyts7rKQbbfuwdhNU434RpJt6484i3xQVsC/km9DGCa7hbqUvZX1 16 | EGkzX6b99KZ13ILGPkUg04xTvoxkqzXGzyO07t88nT623q2v+g16lNGN4rDczdUG 17 | IAn12+2cE405Ld7ylLuVNlsDWHsGX6TytgwMMa3ACN7vjiroCMwVnCzx5JFoIgds 18 | 2DQ= 19 | -----END CERTIFICATE REQUEST----- 20 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended", 5 | ":semanticCommitsDisabled", 6 | "schedule:earlyMondays" 7 | ], 8 | "enabledManagers": [ 9 | "npm", 10 | "custom.regex" 11 | ], 12 | "packageRules": [ 13 | { 14 | "matchDatasources": [ 15 | "npm" 16 | ], 17 | "addLabels": [ 18 | "javascript" 19 | ], 20 | "minimumReleaseAge": "3 days" 21 | } 22 | ], 23 | "customManagers": [ 24 | { 25 | "customType": "regex", 26 | "managerFilePatterns": [ 27 | "/templates/base.html/" 28 | ], 29 | "matchStrings": [ 30 | "webcomponentsjs@(?.*?)/" 31 | ], 32 | "depNameTemplate": "@webcomponents/webcomponentsjs", 33 | "datasourceTemplate": "npm" 34 | }, 35 | { 36 | "customType": "regex", 37 | "managerFilePatterns": [ 38 | "/templates/base.html/" 39 | ], 40 | "matchStrings": [ 41 | "lit@(?.*?)/" 42 | ], 43 | "depNameTemplate": "lit", 44 | "datasourceTemplate": "npm" 45 | } 46 | ], 47 | "rebaseWhen": "conflicted" 48 | } 49 | -------------------------------------------------------------------------------- /molecule/default/install-rpm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - package: 3 | name: 4 | - fontconfig 5 | state: present 6 | update_cache: true 7 | - package: 8 | name: 9 | - java-21-openjdk 10 | state: present 11 | when: ansible_distribution != 'Amazon' and (ansible_distribution != 'CentOS' or ansible_distribution_major_version != '10') 12 | - package: 13 | name: 14 | - java-21-amazon-corretto 15 | state: present 16 | when: ansible_distribution == 'Amazon' 17 | - package: 18 | name: 19 | - java-21-openjdk 20 | state: present 21 | when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '10' 22 | - file: 23 | path: /var/tmp/target/credentials 24 | state: directory 25 | - copy: 26 | src: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/credentials/test.ascii.key" 27 | dest: /var/tmp/target/credentials/test.ascii.key 28 | - rpm_key: 29 | state: present 30 | key: /var/tmp/target/credentials/test.ascii.key 31 | - find: 32 | paths: /var/tmp/target/rpm 33 | file_type: file 34 | patterns: "*.rpm" 35 | register: package_list 36 | - assert: 37 | that: 38 | - package_list.matched == 1 39 | - package: 40 | name: "{{ package_list.files[0].path }}" 41 | state: present 42 | -------------------------------------------------------------------------------- /msi/build/License.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}} 2 | {\*\generator Riched20 10.0.17134}\viewkind4\uc1 3 | \pard\sa200\sl276\slmult1\qj\b\f0\fs22\lang9 The MIT License\par 4 | \b0 Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors\par 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\par 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\par 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\par 8 | } 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Handle line endings automatically for files detected as text 2 | # and leave all files detected as binary untouched. 3 | * text=auto 4 | 5 | # Git will always convert line endings to LF on checkout. You should use this for files that must keep LF endings, even on Windows. 6 | * text eol=lf 7 | 8 | # 9 | # The above will handle all files NOT found below 10 | # 11 | # These files are text and should be normalized (Convert crlf => lf) 12 | *.css text 13 | *.groovy text 14 | *.htm text 15 | *.html text 16 | *.java text 17 | *.js text 18 | *.json text 19 | *.jelly text 20 | *.jellytag text 21 | *.less text 22 | *.properties text 23 | *.ps1 -text 24 | *.py text 25 | *.rb text 26 | *.rtf -text 27 | *.sh text 28 | *.txt text 29 | *.xml text 30 | 31 | # These files are binary and should be left untouched 32 | # (binary is a macro for -text -diff) 33 | *.bmp binary 34 | *.class binary 35 | *.gz binary 36 | *.tgz binary 37 | *.ear binary 38 | *.exe binary 39 | *.gif binary 40 | *.gpg binary 41 | *.hpi binary 42 | *.ico binary 43 | *.jar binary 44 | *.jpg binary 45 | *.jpeg binary 46 | *.keychain binary 47 | *.png binary 48 | *.war binary 49 | *.zip binary 50 | -------------------------------------------------------------------------------- /msi/publish/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | : "${AGENT_WORKDIR:=/tmp}" 6 | : "${MSI:?Require Jenkins War file}" 7 | : "${MSIDIR:? Require where to put binary files}" 8 | 9 | # $$ Contains current pid 10 | D="$AGENT_WORKDIR/$$" 11 | 12 | function clean() { 13 | rm -rf "$D" 14 | } 15 | 16 | # Generate and publish site content 17 | function generateSite() { 18 | "$BASE/bin/indexGenerator.py" \ 19 | --distribution windows \ 20 | --targetDir "$MSIDIR" 21 | } 22 | 23 | function init() { 24 | mkdir -p "$D" "${MSIDIR}/${VERSION}" 25 | } 26 | 27 | function uploadPackage() { 28 | cp "${ARTIFACTNAME}-${VERSION}${RELEASELINE}.msi" "${MSI}" 29 | 30 | sha256sum "${MSI}" >"${MSI_SHASUM}" 31 | cat "${MSI_SHASUM}" 32 | 33 | rsync --archive \ 34 | --verbose \ 35 | --progress \ 36 | "${MSI}" "${MSI_SHASUM}" "${MSIDIR}/${VERSION}/" 37 | 38 | # Update the symlink to point to most recent MSI directory 39 | pushd "${MSIDIR}" 40 | rm -rf latest # This is a safety measure just in case something was left there previously 41 | ln -s "${VERSION}" latest 42 | popd 43 | } 44 | 45 | # The site need to be located in the binary directory 46 | function uploadSite() { 47 | rsync --archive \ 48 | --verbose \ 49 | --progress \ 50 | "${D}/" "${MSIDIR// /\\ }/" 51 | } 52 | 53 | function show() { 54 | echo "Parameters:" 55 | echo "MSI: $MSI" 56 | echo "MSIDIR: $MSIDIR" 57 | echo "---" 58 | } 59 | 60 | show 61 | init 62 | generateSite 63 | uploadPackage 64 | uploadSite 65 | -------------------------------------------------------------------------------- /molecule/servlet/Dockerfile.j2: -------------------------------------------------------------------------------- 1 | # Molecule managed 2 | 3 | {% if item.registry is defined %} 4 | FROM {{ item.registry.url }}/{{ item.image }} 5 | {% else %} 6 | FROM {{ item.image }} 7 | {% endif %} 8 | 9 | {% if item.env is defined %} 10 | {% for var, value in item.env.items() %} 11 | {% if value %} 12 | ENV {{ var }} {{ value }} 13 | {% endif %} 14 | {% endfor %} 15 | {% endif %} 16 | 17 | RUN if [ $(command -v apt-get) ]; then export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y python3 sudo bash ca-certificates iproute2 python3-apt python3-lxml python3-psutil aptitude rsync && apt-get clean && rm -rf /var/lib/apt/lists/*; \ 18 | elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install /usr/bin/python3 /usr/bin/python3-config /usr/bin/dnf-3 sudo bash iproute python3-psutil rsync && dnf clean all; \ 19 | elif [ $(command -v yum) ]; then yum makecache fast && yum install -y /usr/bin/python /usr/bin/python2-config sudo yum-plugin-ovl bash iproute python-psutil rsync && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ 20 | elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python3 python3-psutil sudo bash iproute2 rsync && zypper clean -a; \ 21 | elif [ $(command -v apk) ]; then apk update && apk add --no-cache python3 sudo bash ca-certificates rsync; \ 22 | elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python3 sudo bash ca-certificates iproute2 rsync && xbps-remove -O; fi 23 | -------------------------------------------------------------------------------- /msi/publish/publish.ps1: -------------------------------------------------------------------------------- 1 | function Export-Variables($file) { 2 | Get-Content $file | Select-String -Pattern "^export"| ForEach-Object { 3 | $array= $_[0].ToString().split("=") 4 | $array[0] = $array[0].Replace("export","").Trim() 5 | if($array[1].Contains('${')) { 6 | $array[1] = $ExecutionContext.InvokeCommand.ExpandString($array[1].Replace('${', '${env:')) 7 | } elseif($array[1] -match '\$\(([^)]*)\)(.*)') { 8 | $command = $Matches[1].Trim() 9 | $rest = $Matches[2] 10 | if($command.StartsWith('realpath')) { 11 | $command = Invoke-Expression -Command $command.Replace('realpath', 'Resolve-Path') 12 | } else { 13 | Write-Error "Unknown command to convert: $command" 14 | } 15 | $array[1] = '{0}{1}' -f $command,$rest 16 | $array[1] = $ExecutionContext.InvokeCommand.ExpandString($array[1]) 17 | } 18 | [System.Environment]::SetEnvironmentVariable($array[0], $array[1]) 19 | } 20 | } 21 | 22 | if(($null -ne $env:BRAND) -and (Test-Path $env:BRAND)) { 23 | Export-Variables .\$env:BRAND 24 | } 25 | 26 | Export-Variables .\$env:BUILDENV 27 | 28 | Write-Host "Copying binaries to ${env:MSIDIR}" 29 | 30 | if(!(Test-Path $env:MSIDIR)) { 31 | New-Item -ItemType Directory -Path $env:MSIDIR 32 | } 33 | 34 | Get-ChildItem -Path '.\msi\build\bin\Release\en-US\*' -File -Include *.msi,*.msi.sha256 | Copy-Item -Destination $env:MSIDIR 35 | 36 | Get-ChildItem -Path $env:MSIDIR 37 | -------------------------------------------------------------------------------- /templates/header.rpm.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block distribution_instruction %} 4 | 5 |

Red Hat and derivatives

6 | 7 |

8 | To install Jenkins on Red Hat Enterprise Linux, AlmaLinux, Rocky Linux, Oracle Linux, or another Red 9 | Hat based distribution, you can utilize the instructions provided in our Red Hat Enterprise Linux installation 11 | guide. 12 |

13 | 14 |

15 | To install Jenkins on Fedora, use the instructions provided in our 16 | Fedora installation guide. 17 |

18 | 19 |

openSUSE

20 | 21 | To use this repository with openSUSE, start by adding the requirements with the following command: 22 | 23 |
24 | 
25 |     zypper install dejavu-fonts fontconfig java-21-openjdk wget
26 |   
27 | 28 | Then add the repository with run the following command: 29 | 30 |
31 | 
32 |     wget -O /etc/zypp/repos.d/jenkins.repo \
33 |       {{web_url}}/jenkins.repo
34 |   
35 | 36 |

37 | With that set up, the {{ product_name }} package can be installed with: 38 | 39 |

40 | 
41 |     zypper install {{ artifactName }}
42 |   
43 |

44 | {% endblock %} 45 | 46 | {% block individual_package_instruction %} 47 | If you need *.rpm for a specific version, use these. 48 | {% endblock %} 49 | -------------------------------------------------------------------------------- /war/publish/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | : "${AGENT_WORKDIR:=/tmp}" 6 | : "${WAR:?Require Jenkins War file}" 7 | : "${WARDIR:? Require where to put binary files}" 8 | 9 | # $$ Contains current pid 10 | D="$AGENT_WORKDIR/$$" 11 | 12 | function clean() { 13 | rm -rf "$D" 14 | } 15 | 16 | # Generate and publish site content 17 | function generateSite() { 18 | "$BASE/bin/indexGenerator.py" \ 19 | --distribution war \ 20 | --targetDir "$D" 21 | } 22 | 23 | function init() { 24 | mkdir -p "$D" "${WARDIR}/${VERSION}/" 25 | } 26 | 27 | function uploadPackage() { 28 | sha256sum "${WAR}" | sed "s, .*, ${ARTIFACTNAME}.war," >"${WAR_SHASUM}" 29 | cat "${WAR_SHASUM}" 30 | 31 | rsync --archive \ 32 | --verbose \ 33 | --progress \ 34 | "${WAR}" "${WAR_SHASUM}" "${WARDIR}/${VERSION}/" 35 | 36 | # Update the symlink to point to most recent WAR directory 37 | pushd "${WARDIR}" 38 | rm -rf latest # This is a safety measure just in case something was left there previously 39 | ln -s "${VERSION}" latest 40 | popd 41 | } 42 | 43 | # Site html need to be located in the binary directory 44 | function uploadSite() { 45 | rsync --archive \ 46 | --verbose \ 47 | --progress \ 48 | --include "HEADER.html" \ 49 | --include "FOOTER.html" \ 50 | --exclude "*" \ 51 | "${D}/" "${WARDIR// /\\ }/" 52 | } 53 | 54 | function show() { 55 | echo "Parameters:" 56 | echo "WAR: $WAR" 57 | echo "WARDIR: $WARDIR" 58 | echo "---" 59 | } 60 | 61 | show 62 | init 63 | generateSite 64 | uploadPackage 65 | uploadSite 66 | clean 67 | -------------------------------------------------------------------------------- /molecule/default/Dockerfile.j2: -------------------------------------------------------------------------------- 1 | # Molecule managed 2 | 3 | {% if item.registry is defined %} 4 | FROM {{ item.registry.url }}/{{ item.image }} 5 | {% else %} 6 | FROM {{ item.image }} 7 | {% endif %} 8 | 9 | {% if item.env is defined %} 10 | {% for var, value in item.env.items() %} 11 | {% if value %} 12 | ENV {{ var }} {{ value }} 13 | {% endif %} 14 | {% endfor %} 15 | {% endif %} 16 | 17 | RUN if [ $(command -v apt-get) ]; then export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y python3 sudo bash ca-certificates iproute2 python3-apt python3-psutil aptitude rsync && apt-get clean && rm -rf /var/lib/apt/lists/*; \ 18 | elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install /usr/bin/python3 /usr/bin/python3-config /usr/bin/dnf-3 sudo bash iproute $(dnf info python3-libdnf5 &>/dev/null && echo python3-libdnf5) python3-psutil rsync && dnf clean all; \ 19 | elif [ $(command -v yum) ]; then yum makecache fast && yum install -y /usr/bin/python /usr/bin/python2-config sudo yum-plugin-ovl bash iproute python-psutil rsync && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ 20 | elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python311 python311-psutil sudo bash iproute2 rsync && zypper clean -a; \ 21 | elif [ $(command -v apk) ]; then apk update && apk add --no-cache python3 sudo bash ca-certificates rsync; \ 22 | elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python3 sudo bash ca-certificates iproute2 rsync && xbps-remove -O; fi 23 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | # docker exec -i -t packaging_packaging_1 gpg --import --batch credentials/sandbox.gpg 2 | version: '3' 3 | volumes: 4 | sshd: 5 | pkgserver: 6 | services: 7 | packaging: 8 | image: jenkinsciinfra/packaging:latest 9 | command: "sleep 99d" 10 | environment: 11 | - "BUILDENV=/srv/releases/jenkins/env/test.mk" 12 | - "BRANDING_DIR=/srv/releases/jenkins/branding" 13 | - "BRAND=/srv/releases/jenkins/branding/jenkins.mk" 14 | - "GPG_FILE=/srv/releases/jenkins/credentials/sandbox.gpg" 15 | - "GPG_KEYNAME=Bogus Test" 16 | - "GPG_PASSPHRASE=s3cr3t" 17 | - "GPG_PASSPHRASE_FILE=/srv/releases/jenkins/credentials/test.gpg.password.txt" 18 | - "WAR=/srv/releases/jenkins/jenkins.war" 19 | - "MSI=/srv/releases/jenkins/jenkins.msi" 20 | - "RELEASELINE=-experimental" 21 | volumes: 22 | - ".:/srv/releases/jenkins:z" 23 | - "./credentials/ssh:/home/jenkins/.ssh:z" 24 | working_dir: "/srv/releases/jenkins" 25 | 26 | remote: 27 | image: jenkinsciinfra/packaging:latest 28 | user: root # In order to start, sshd needs to be root 29 | command: "/usr/sbin/sshd -D" 30 | ports: 31 | - "2222:22" 32 | volumes: 33 | - "./credentials/ssh/id_rsa.pub:/home/jenkins/.ssh/authorized_keys:ro" 34 | - sshd:/run/sshd 35 | - "pkgserver:/srv/releases/jenkins" 36 | 37 | pkgserver: 38 | image: httpd 39 | ports: 40 | - "80:80" 41 | volumes: 42 | - "./pkgConfig/httpd.conf:/usr/local/apache2/conf/httpd.conf" 43 | - "./target:/usr/local/apache2/htdocs" 44 | -------------------------------------------------------------------------------- /molecule/servlet/verify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Verify 3 | hosts: all 4 | tasks: 5 | - pids: 6 | name: java 7 | register: service_pids 8 | - assert: 9 | that: 10 | - (service_pids.pids | length) == 0 11 | fail_msg: "{{ service_pids.pids | join(',') }}" 12 | - command: 13 | cmd: /usr/local/tomcat/bin/catalina.sh start 14 | when: ansible_hostname == 'tomcat-10' 15 | - uri: 16 | url: "http://127.0.0.1:8080/jenkins/login" 17 | return_content: true 18 | register: result 19 | until: result.status == 200 20 | retries: 20 21 | delay: 5 22 | - assert: 23 | that: 24 | - "'Sign in - Jenkins' in result.content" 25 | fail_msg: "{{ result.content }}" 26 | - pids: 27 | name: java 28 | register: service_pids 29 | - assert: 30 | that: 31 | - (service_pids.pids | length) == 1 32 | fail_msg: "{{ service_pids.pids | join(',') }}" 33 | - file: 34 | path: "/var/tmp/jenkins_home" 35 | register: jenkins_dir 36 | - assert: 37 | that: 38 | - "jenkins_dir.state == 'directory'" 39 | fail_msg: "{{ jenkins_dir.state }}" 40 | - command: 41 | cmd: /usr/local/tomcat/bin/catalina.sh stop 42 | when: ansible_hostname == 'tomcat-10' 43 | - pids: 44 | name: java 45 | register: service_pids 46 | - assert: 47 | that: 48 | - (service_pids.pids | length) == 0 49 | fail_msg: "{{ service_pids.pids | join(',') }}" 50 | -------------------------------------------------------------------------------- /deb/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | # build a debian package from a release build 4 | 5 | hostname 6 | dir=$(dirname "$0") 7 | 8 | # tmp dir 9 | D=$(mktemp -d) 10 | trap 'rm -rf "${D}"' EXIT 11 | 12 | # debian packaging needs to touch the file in the source tree, so do this in tmp dir 13 | # so that multiple builds can go on concurrently 14 | cp -R "${dir}"/* "${D}" 15 | cp "${BASE}/systemd/jenkins.service" "${D}/debian" 16 | cp "${BASE}/systemd/jenkins.sh" "${D}" 17 | cp "${BASE}/systemd/migrate.sh" "${D}" 18 | cp "${BASE}/systemd/jenkins.conf" "${D}/debian/jenkins.tmpfiles" 19 | 20 | # Create a description temp file 21 | sed -i.bak -e 's/^\s*$/./' -e 's/^/ /' "${DESCRIPTION_FILE}" 22 | 23 | # Expand variables in the definition 24 | "${BASE}/bin/branding.py" "${D}" 25 | 26 | # Rewrite the file 27 | mv "${DESCRIPTION_FILE}.bak" "${DESCRIPTION_FILE}" 28 | 29 | cat >"${D}/debian/changelog" < 2 | 3 | 4 | [ProductName] Setup 5 | Select Java home directory (JDK or JRE) 6 | Please select the path of a Java Development Kit or Java Runtime Environment. Only Java 17, 21 and 25 are supported by Jenkins. 7 | &Change... 8 | Invalid Java Directory 9 | Failed to find compatible Java version (17, 21 or 25) in [JAVA_HOME] 10 | 11 | 12 | Browse to the Java Home directory 13 | {\WixUI_Font_Title}Select Java folder 14 | 15 | 16 | Run service as LocalSystem (not recommended) 17 | Enables a firewall exception for the Java running Jenkins on port [PORTNUMBER] (not recommended). 18 | Starts the Jenkins service after install. 19 | 20 | -------------------------------------------------------------------------------- /templates/header.debian.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block distribution_instruction %} 4 | 5 |

6 | This is the Debian package repository of {{product_name}} to automate installation and upgrade. 7 | 8 | To use this repository, first add the key to your system (for the Weekly Release Line): 9 | 10 |

11 |     
12 |   sudo wget -O /etc/apt/keyrings/jenkins-keyring.asc \
13 |     {{web_url}}/{{gpg_public_key_filename}}
14 |   
15 | 16 | Then add a Jenkins apt repository entry: 17 | 18 |
19 |     
20 |   echo "deb [signed-by=/etc/apt/keyrings/jenkins-keyring.asc]" \
21 |     {{ web_url }} binary/ | sudo tee \
22 |     /etc/apt/sources.list.d/jenkins.list > /dev/null
23 |   
24 |

25 | 26 |

27 | Update your local package index, then finally install {{product_name}}: 28 | 29 |

30 |    
31 |   sudo apt-get update
32 |   sudo apt-get install fontconfig openjdk-21-jre
33 |   sudo apt-get install {{artifactName}}
34 |   
35 | (Install openjdk-17-jre on Debian 12 or earlier) 36 |

37 | 38 |

39 | The apt packages were signed using this key: 40 |

41 | 42 |
{{ pub_key_info|trim }}
43 | {% endblock %} 44 | 45 | {% block individual_package_instruction %} 46 | 47 |

48 | If you need *.deb for a specific version, use these. 49 |

50 | 51 | {% endblock %} 52 | -------------------------------------------------------------------------------- /credentials/test.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIERTCCAy2gAwIBAgIJALm//tP6yofwMA0GCSqGSIb3DQEBCwUAMIG4MQswCQYD 3 | VQQGEwJVUzEQMA4GA1UECAwHTm93aGVyZTEVMBMGA1UEBwwMTm93aGVyZSBDaXR5 4 | MR4wHAYDVQQKDBVCb2d1cyBUZXN0aW5nIENvbXBhbnkxHjAcBgNVBAsMFURvIE5v 5 | dCBVc2UgRGVwYXJ0bWVudDEZMBcGA1UEAwwQTXIuU2VsZmllIFNpZ25lcjElMCMG 6 | CSqGSIb3DQEJARYWbm9yZXBseUBqZW5raW5zLWNpLm9yZzAgFw0xNTA0MDUxNzI3 7 | NTlaGA8yMTE1MDMxMjE3Mjc1OVowgbgxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdO 8 | b3doZXJlMRUwEwYDVQQHDAxOb3doZXJlIENpdHkxHjAcBgNVBAoMFUJvZ3VzIFRl 9 | c3RpbmcgQ29tcGFueTEeMBwGA1UECwwVRG8gTm90IFVzZSBEZXBhcnRtZW50MRkw 10 | FwYDVQQDDBBNci5TZWxmaWUgU2lnbmVyMSUwIwYJKoZIhvcNAQkBFhZub3JlcGx5 11 | QGplbmtpbnMtY2kub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA 12 | vRHgamoEgcF1FqN0YusXKWZuZL7iAy1wLs9zeUj5HxwuHmF6MBKCvF44JU3A6BIx 13 | 7xOaLbb+G6qZj0MlpVzl2ra54PWn7KffGgOF8bxJ6CnYaBXpJfrBW+ORTfbV9tGS 14 | Nhqzc0Z1Gfe/+EgFuKuD6FmPJpUIzdMFrnfs9k0In1sP+VbdlUyFsvshlv6zTmYy 15 | gNKKroXODqYXYyEkS9RV3YvIzhIHx4PmTN9XIOo71ZwieRM1aVBv4lIxGqPF08f/ 16 | x/fP5Nm/aWkT7S1vQ9VGtd4J4TxVs2tlKndtUaB0wlGIEXRk0cxIQ2fFaPhnjqjo 17 | 0pJJbbqFAHF0qYm4PYtyMwIDAQABo04wTDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB 18 | /wQEAwIHgDAXBgNVHSUBAf8EDTALBgkqhkiG92NkBA0wEwYKKoZIhvdjZAYBDgEB 19 | /wQCBQAwDQYJKoZIhvcNAQELBQADggEBAE7p6Qg3QMuiiORtK/eA9P5rTpG7iARS 20 | uZRT+7VHt78gzIqen0oGJjBB1/1dM2lJuxiQNyTPbtz0TZh5RyHi52rQ9L0OHkqF 21 | JGZy3f7hgrWVJ0rlABA6MvsXUVUgq2aMcs0kjmbs5no9aaVQkBh7NveSjT+g6Kqj 22 | 5x8jowA2v46BI3zbvsZHvwYqdCk4r4o/HFOAYw5CuwABBUH8MG7HSXgMYzIm7UnV 23 | tjT6b0Tttdw8NLvxwRqmIESrabB+/TXHhzVp8Wm8V+brhK42qtR3Rqx5WurworUE 24 | 06agnSx5X1YRKReo6Iw0nUwxbrKL4VwYPBcuGDdPM7OI0UBWR+V3n1w= 25 | -----END CERTIFICATE----- 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # refers to the definition of a release target 2 | BRAND ?= ./branding/test.mk 3 | include ${BRAND} 4 | 5 | # refers to the definition of the release process execution environment 6 | BUILDENV ?=./env/test.mk 7 | include ${BUILDENV} 8 | 9 | # refers to whereabouts of code-signing keys 10 | # CREDENTIAL ?=./credentials/test.mk 11 | 12 | include ${CREDENTIAL} 13 | 14 | include ./setup.mk 15 | 16 | PACKAGE_BUILDER_VERSION:=0.1 17 | 18 | ####################################################### 19 | 20 | clean: 21 | rm -rf ${TARGET} 22 | 23 | setup: 24 | bash -ex -c 'for f in */setup.sh; do $$f; done' 25 | 26 | package: war deb rpm 27 | 28 | publish: war.publish deb.publish rpm.publish 29 | 30 | test: deb.test rpm.test 31 | 32 | war: ${WAR} 33 | war.publish: ${WAR} 34 | ./war/publish/publish.sh 35 | 36 | 37 | 38 | deb: ${DEB} 39 | ${DEB}: ${WAR} $(shell find deb/build -type f) 40 | ./deb/build/build.sh 41 | deb.publish: ${DEB} $(shell find deb/publish -type f) 42 | ./deb/publish/publish.sh 43 | 44 | 45 | 46 | rpm: ${RPM} 47 | ${RPM}: ${WAR} $(shell find rpm/build -type f) 48 | ./rpm/build/build.sh 49 | rpm.publish: ${RPM} $(shell find rpm/publish -type f) 50 | ./rpm/publish/publish.sh 51 | 52 | msi.publish: 53 | ./msi/publish/publish.sh 54 | 55 | ${CLI}: 56 | @mkdir ${TARGET} || true 57 | wget -O $@.tmp ${JENKINS_URL}jnlpJars/jenkins-cli.jar 58 | mv $@.tmp $@ 59 | 60 | 61 | 62 | test.local.setup: 63 | # start a test Apache server that acts as package server 64 | # we'll refer to this as 'test.pkg.jenkins.io' 65 | @mkdir -p ${TESTDIR} || true 66 | docker run --rm -t -i -p 9200:80 -v ${TESTDIR}:/var/www/html fedora/apache 67 | -------------------------------------------------------------------------------- /credentials/ssh/id_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAw6bQJN8ceL5T7FaNs2QdSEnGgLKy5zvpuORDJLd0Q/wTm5DV 3 | MVxqJzT8hCtL7a4D1NBPaBm6pAvlxCnKMhdZwSi+e2zuzRokOuivlAHyiV7le9Ln 4 | 1K/pKkDchAIz8P3YWLt1YZJERDUI8nXW9MC8ZOEt/IudmLTsZQcSr8lXOFIwNZe4 5 | b/NSr/9sxvSnYQqw5q6j1ZxdjW/KtXPQapU+PObZ/31jzTH9W966LpoF8XYo0xRA 6 | hJvy3f+NxbSVPhjH422wHCeeyfI/+B/xYlVNC3yYR4ONvXbAXsewB0aRhnOfh+sS 7 | kzotOCDMBZHOjKrg27MLs0dfrmjxGffF2Vq+JQIDAQABAoIBAELefZ9Mfg+qhUZu 8 | YqngWr29MVIFQW4UpRIjOeuPo/YkbpMp0iO3wTQ7QN7vaVkHs5mFxM4AlTDCPDpq 9 | SggKwQtqoIfQuGFzQNS9eFzuuXVH8Mj8UW343Ykqd/PKSPRh3hKdp0W81wY01iUA 10 | L4KhaQJVkAETur5Zf74bx8A64UuG+qWbDUGlRGCRk/pl9xGB1z0FQ7Api/6gQd2A 11 | Tnu6ASmQfoKeDsDDOBVy8sHv7HlkU9msowD9TdOj7Gxx9DoPryX6GlAhgi//+jyA 12 | qUCf03kdey5aCVKFVUIOkxpDxYRI0etW0ef0rww+DJDpL7pT0kWMf4sqxgmxPTly 13 | TaOnl+ECgYEA4GpfL7GTPTFvhatxi78TlaATTzjmzPYLrxOF8EHQM3Tz/nDbDknX 14 | x5YtQdq0cv2TNdR2uZ0AyuzZ06j6axyBCJWKgtErN+SO01+Qxa9rcv+Vw7NtdTGs 15 | GUrMa7CU/X4t8jt6UiObIgGRNbvu93ANeEzjIOFn9S9QKQ0vrtfW/W0CgYEA3zAV 16 | /z5rt/AThnajCRPv5c/o9c2TykKy3DFFUdgNTEwnHE04D+xoqH1eoTMNoNXdVbI0 17 | 1C5WTzCpYLuKmbl/aZEwvidi6ssTpYHcviAAz8iqN/TL9Ys5XmJ3iJViNK3IxxHB 18 | TRLMiBC057tS8ZZLRa756weEZ2TUYRydxFntaJkCgYAV/nbbvsSWb7zlVdsn/g8W 19 | T/z0e7grCEY232v2Ew0rrd+n5Tmi2dvbBL3kwWGED5QY53zHTjrgqHvkwZ/hVYbT 20 | 54wOrB9XOABDeQ9AQKQAPkpYRsKIhNjAFdOZDlJb0b0BC5E+cZznpU2s/YE7IPFB 21 | BBASjeTZY8ywaUluEltQtQKBgCi2idy000uLdNRbgeQfCez/Hzzvkl0cC6qVJlMG 22 | uW5Imf3UrDxjYLgTnpaDTKIhQS3nwzFNfpsVgmBN9buTFgX44U5euvGft+bCKLVZ 23 | +yvsK/jnI+mXyxBHoAx/S5nWdcCyoXNg0YSkn4uCJWBCjVqZz6crCOEfiIpqgPEX 24 | gnJJAoGBAKvDah87FijEJRBiaroef5buG1jr9pNCBoXIGbvZ1sFwkGWQGgrH6Y3s 25 | EBD083+BBCcIMvzy2leB692axxGhtdyCxfPRN7KiZgT/YC6cCDL1yzhSHtZ8kamb 26 | N8Qqs+wVE4YIdELB+VgKTho1v4gAyzZNuMJMhne6qH+oxNfGUgER 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /credentials/test.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEAvRHgamoEgcF1FqN0YusXKWZuZL7iAy1wLs9zeUj5HxwuHmF6 3 | MBKCvF44JU3A6BIx7xOaLbb+G6qZj0MlpVzl2ra54PWn7KffGgOF8bxJ6CnYaBXp 4 | JfrBW+ORTfbV9tGSNhqzc0Z1Gfe/+EgFuKuD6FmPJpUIzdMFrnfs9k0In1sP+Vbd 5 | lUyFsvshlv6zTmYygNKKroXODqYXYyEkS9RV3YvIzhIHx4PmTN9XIOo71ZwieRM1 6 | aVBv4lIxGqPF08f/x/fP5Nm/aWkT7S1vQ9VGtd4J4TxVs2tlKndtUaB0wlGIEXRk 7 | 0cxIQ2fFaPhnjqjo0pJJbbqFAHF0qYm4PYtyMwIDAQABAoIBAHAEI11oqnrlzyU2 8 | ekIQ3owcr9LodKdFSG2zYsq8vTv9SiWdwvKwRNytRb50LpJQFV1706C6BhsGHCyQ 9 | r8ElJNlL4Ryy7mZ7nuaep8DsuSzffeNM9/EUe3KhhPkYAPRWfbWoZCEr4T0dV5MV 10 | uK4Mj/4c8X7+VVT8bSVM0Aus4Crol5JfzTLfgWtjUF3v9BaGSKssU76QGtqV0Zlp 11 | OvMgu5xtH7ArjqvSVWMFEVFRjc40roRRqX9UMzpolAOOUrsk/n2XeMu3SPH2Y4KJ 12 | sc1SvpVabZXgfwoDinesCa1QUq9naLEMAByyK6Y9uZFVUDV0F9yKTGjlzoJ8HwXh 13 | g2X0IAECgYEA6Q84dKE9EVVroRtlg3/Bx3ea5AD421cSHJkTv6CmpAyFdADhbNJS 14 | EZjrxs2PYudayEWlUjZdoNqYI+OdSs7Bs6ld0qWGqD8/v3SmcrJpcm5+uhzoLPMN 15 | 8P5UG+0QE3iFtUUwNSd+/3j0Ame1Or+PnEc5ddkWHlvV4+SyPD99zjMCgYEAz64t 16 | f3wB0WOsl7V8AVJ2vvHD9gpvsQFCTVdJNEW5h/SSABw1H2fbS0QJKSqJjyry6kS6 17 | g7/mQ8qYmFSFXvnKqGgx4WByu7+le6eRew7fZSS8/pb0NY1RG7J2zhm7PFeFxt/b 18 | UhO5mEaG21po2fr7JXSttslzv0egYbuv1nRPzAECgYBZVJwvGB5wJm26suWWIcIE 19 | 0rNr8XNxn04x5/rJ2KoG90Wv0SaWr4cFd7fn26K6JjOF0Cwt9uisXx0xpG0F33of 20 | gyuTMh8LHjMxD2U9UWVZl0C71ZioogEV/mX+zj77N5cIhByWQy1KfvIIeffdLM++ 21 | 9w3vPeZcfJbfYyluLmfqQQKBgF5HLMJd0hlzDSvFqGiVPfDKofH0pOWOs8GWaVYA 22 | fQv5+7lvFLKQHB4b4ai9dbr3fVTaJG2g1PBbbVBhtjX6YYR34IT2mr8ebgondMSP 23 | aNxqhB1y+6O/5l0TdBl11ui6trEkeFTXPX6iLaAwd77Uz+QeBqoe45um8WjMojNR 24 | k9QBAoGAWbinFVDJR7jnan0QaXN3yxHYrKphohvDPmsz34dPGbEw24/Yd/GW1igg 25 | myoj2+cSC42Ri/SlkC6cDiwIzesWONK+DFsJogDrDdqbFBfXylW0bUw4F4Lf00Sk 26 | F+oa01qOfJ/Y2eTMFsRD5L8uzOtQv2iZ07GFd300LGdoRWehhOQ= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /molecule/default/verify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Verify 3 | hosts: all 4 | tasks: 5 | - file: 6 | path: /etc/systemd/system/jenkins.service.d 7 | state: directory 8 | when: ansible_service_mgr == 'systemd' 9 | - stat: 10 | path: /etc/systemd/system/jenkins.service.d/override.conf 11 | register: drop_in 12 | when: ansible_service_mgr == 'systemd' 13 | - assert: 14 | that: 15 | - not drop_in.stat.exists 16 | - copy: 17 | dest: /etc/systemd/system/jenkins.service.d/override.conf 18 | content: | 19 | [Service] 20 | Environment="JAVA_OPTS=-Djava.awt.headless=true -Xmx256m -Dhudson.model.DirectoryBrowserSupport.CSP=\"default-src 'self';\"" 21 | TimeoutStartSec=600 22 | when: ansible_service_mgr == 'systemd' 23 | - systemd: 24 | daemon_reload: true 25 | when: ansible_service_mgr == 'systemd' 26 | - pids: 27 | name: java 28 | register: service_pids 29 | - assert: 30 | that: 31 | - (service_pids.pids | length) == 0 32 | fail_msg: "{{ service_pids.pids|join(',') }}" 33 | - service: 34 | name: jenkins 35 | state: started 36 | - uri: 37 | url: "http://127.0.0.1:8080/login" 38 | return_content: true 39 | register: result 40 | until: result.status == 200 41 | retries: 20 42 | delay: 5 43 | - assert: 44 | that: 45 | - "'Sign in - Jenkins' in result.content" 46 | fail_msg: "{{ result.content }}" 47 | - pids: 48 | name: java 49 | register: service_pids 50 | - assert: 51 | that: 52 | - (service_pids.pids | length) == 1 53 | fail_msg: "{{ service_pids.pids | join(',') }}" 54 | - service: 55 | name: jenkins 56 | state: stopped 57 | - pids: 58 | name: java 59 | register: service_pids 60 | - assert: 61 | that: 62 | - (service_pids.pids | length) == 0 63 | fail_msg: "{{ service_pids.pids | join(',') }}" 64 | -------------------------------------------------------------------------------- /credentials/README.md: -------------------------------------------------------------------------------- 1 | # Code-signing credentials 2 | Different platforms want private keys and certificates in different formats. 3 | To correctly sign all the supported formats, you need your keys in the following format: 4 | 5 | * Code-signing key and certificate in PKCS12 format for Windows 6 | * OS X keychain file that contains a valid installer signing certificate issued from Apple. 7 | This requires you to be a member of the Mac Developer Program. Create a separate keychain, 8 | add your code signing key and certificate, and use this keychain file. 9 | * GPG secret/public keypair in separate GPG public keyring and GPG secret keyring. 10 | 11 | `test.mk` contains the variable definitions to point to those files. 12 | 13 | ## Creating your own GPG key 14 | 15 | Generate a new GPG key with `gpg --full-generate-key`: 16 | 17 | * When asked what kind of key you want, select "(1) RSA and RSA (default)". 18 | * When asked what key size you want, enter "4096" bits. 19 | * When asked how long the key should be valid, enter "0" (key does not expire). 20 | * When asked for your real name, enter "Bogus Test". 21 | * When asked for your email address, enter "noreply@jenkins-ci.org". 22 | * When asked for a comment, enter "This is test only key". 23 | * When asked for the secret password, enter the password from `test.gpg.password.txt`. 24 | 25 | Export your public key & private key 26 | 27 | gpg --export KEYID > test.gpg 28 | gpg --export --armor KEYID > test.ascii.key 29 | gpg --export-secret-keys KEYID > test.secret.gpg 30 | cat test.gpg >sandbox.gpg 31 | cat test.secret.gpg >>sandbox.gpg 32 | 33 | Verify the newly created keyring. Note that the keyring options must have some directory name parts in it, or else it's treated as they are in `~/.gnupg` 34 | 35 | gpg --no-default-keyring --keyring=./test.gpg --secret-keyring=./test.secret.gpg --list-keys 36 | gpg --no-default-keyring --keyring=./test.gpg --secret-keyring=./test.secret.gpg --list-secret-keys 37 | -------------------------------------------------------------------------------- /branding/README.md: -------------------------------------------------------------------------------- 1 | # Branding Definition 2 | Branding definition file has the following variables 3 | 4 | * `RELEASELINE`: used only for OSS Jenkins releases. This variable selects one of the 4 release lines that we 5 | maintain (empty for mainline releases, "-rc" for RCs, "-stable" for LTS, and "-stable-rc" for LTS RCs.) 6 | * `PRODUCTNAME`: Short human readable name of the product. Should be something like "Acme Foo Bar Zot". 7 | Used as the title of the product. 8 | * `SUMMARY`: One line human readable description of what the product does. 9 | * `ARTIFACTNAME`: Alpha-numeric lower-case (plus '-' and '_') only machine name of the product. Used as the stem of the file names. 10 | * `CAMELARTIFACTNAME`: Alpha-numeric machine name of the product, but in CamelCase (such as FooBarZot.) 11 | By convention this name should not have '-' or '_' 12 | * `VENDOR`: Short human readable name of the entity that generates the package. 13 | * `PORT`: TCP/IP port that Jenkins will bind to out of the box. 14 | * `MSI_PRODUCTCODE`: Windows installer uses UUID to identify which MSI files are of the same lineage. 15 | If two MSIs have the same UUID, one will overwrite another. So if you are to produce your own MSI, 16 | you need to use a different UUID. 17 | * `AUTHOR`: Author name & email for distributed package, i.e. Bob Smith 18 | * `LICENSE`: License(s) for this distribution, such as 'Apache 2.0' 19 | * `HOMEPAGE`: homepage URL for this distribution of Jenkins (where users should go for more information) 20 | * `CHANGELOG_PAGE`: URL that users should visit to see the changelog for this distribution of Jenkins 21 | 22 | # Branding Files 23 | Each of these is an (absolute) path to a file containing a larger blob of brand-specific information. 24 | The file is read to the environment variable, and then templated in as with the variables above 25 | 26 | * `DESCRIPTION_FILE`: path to file containing the RPM description section (see 'description-file' in branding for an example) 27 | 28 | # Special handling: 29 | 30 | License files are handled specially: 31 | * `LICENSE_FILE` is the path of a file containing the license/copyright text body 32 | 33 | This is transformed specially (by setup.mk) for use in branding each different package: 34 | 35 | * `LICENSE_TEXT` is the actual file contents 36 | * `LICENSE_TEXT_COMMENTED` is the license text, split to 80 character lines with #-style comment at the start of each line 37 | * `LICENSE_TEXT_DEB` is formatted for a Debian copyright file, with a . between each paragraph, and one whitespace before each line 38 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | def jobProperties = [ 2 | buildDiscarder(logRotator(numToKeepStr: '50', artifactNumToKeepStr: '5')), 3 | disableConcurrentBuilds(abortPrevious: true) 4 | ] 5 | 6 | if (env.BRANCH_IS_PRIMARY) { 7 | jobProperties << pipelineTriggers([cron('@weekly')]) // Run at least weekly on the primary branch to assure we test recent releases 8 | } 9 | 10 | properties(jobProperties) 11 | 12 | podTemplate( 13 | inheritFrom: 'jnlp-maven-21', 14 | workingDir: '/home/jenkins/agent', 15 | containers: [ 16 | containerTemplate(name: 'jnlp', image: 'jenkinsciinfra/packaging:latest') 17 | ], 18 | envVars: [ 19 | envVar(key: 'HOME', value: '/home/jenkins/agent/workspace'), 20 | ], 21 | ) { 22 | nodeWithTimeout(POD_LABEL) { 23 | withEnv([ 24 | "BUILDENV=${WORKSPACE}/env/test.mk", 25 | "BRANDING_DIR=${WORKSPACE}/branding", 26 | "BRAND=${WORKSPACE}/branding/jenkins.mk", 27 | "GPG_FILE=${WORKSPACE}/credentials/sandbox.gpg", 28 | "GPG_KEYNAME=Bogus Test", 29 | "GPG_PASSPHRASE=s3cr3t", 30 | "GPG_PASSPHRASE_FILE=${WORKSPACE}/credentials/test.gpg.password.txt", 31 | "HOME=/home/jenkins/agent/workspace", 32 | "WAR=${WORKSPACE}/jenkins.war", 33 | "MSI=${WORKSPACE}/jenkins.msi", 34 | "RELEASELINE=-experimental", 35 | ]) { 36 | stage('Preparation') { 37 | checkout scm 38 | sh './prep.sh' 39 | } 40 | 41 | stage('Build') { 42 | sh 'make package && python3 -m pytest bin --junitxml target/junit.xml' 43 | junit 'target/junit.xml' 44 | def results = '*.war, target/debian/*.deb, target/rpm/*.rpm' 45 | stash includes: results, name: 'results' 46 | archiveArtifacts results 47 | } 48 | } 49 | } 50 | } 51 | 52 | nodeWithTimeout('docker') { 53 | stage('Test') { 54 | checkout scm 55 | unstash 'results' 56 | infra.withDockerCredentials { 57 | ansiColor('xterm') { 58 | sh ''' 59 | cat /proc/cpuinfo 60 | cat /proc/meminfo 61 | python3 -m venv venv 62 | . venv/bin/activate 63 | pip install -U pip wheel 64 | pip install -r requirements.txt 65 | ANSIBLE_FORCE_COLOR=true molecule test 66 | ANSIBLE_FORCE_COLOR=true molecule test -s servlet 67 | deactivate 68 | '''.stripIndent() 69 | } 70 | } 71 | } 72 | } 73 | 74 | void nodeWithTimeout(String label, Closure body) { 75 | node(label) { 76 | timeout(time: 1, unit: 'HOURS') { 77 | body() 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /make.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [Parameter(Position=1)] 4 | [String] $target = "package" 5 | ) 6 | 7 | # # refers to the definition of a release target 8 | # BRAND:=./branding/test.mk 9 | # include ${BRAND} 10 | 11 | # # refers to the definition of the release process execution environment 12 | # BUILDENV:=./env/test.mk 13 | # include ${BUILDENV} 14 | 15 | # # refers to whereabouts of code-signing keys 16 | # CREDENTIAL:=./credentials/test.mk 17 | # include ${CREDENTIAL} 18 | 19 | # include ./setup.mk 20 | 21 | # PACKAGE_BUILDER_VERSION:=0.1 22 | 23 | # ####################################################### 24 | 25 | # clean: 26 | # rm -rf ${TARGET} 27 | 28 | $global:msiDone = $false 29 | $global:chocolateyDone = $false 30 | 31 | function Setup() { 32 | Get-ChildItem -Recurse -Include setup.ps1 -File | ForEach-Object { 33 | Push-Location (Split-Path -Parent $_) 34 | try { 35 | & $_ 36 | } finally { 37 | Pop-Location 38 | } 39 | } 40 | } 41 | 42 | function New-Msi() { 43 | if(-not $global:msiDone) { 44 | Push-Location ./msi/build 45 | try { 46 | & ./build.ps1 47 | $global:msiDone = $true 48 | } finally { 49 | Pop-Location 50 | } 51 | } 52 | } 53 | 54 | function Publish-Msi() { 55 | New-Msi 56 | Push-Location ./msi/publish 57 | try { 58 | & ./publish.ps1 59 | } finally { 60 | Pop-Location 61 | } 62 | } 63 | 64 | function New-Chocolatey() { 65 | New-Msi 66 | if(-not $global:chocolateyDone) { 67 | Push-Location ./chocolatey/build 68 | try { 69 | & ./build.ps1 70 | $global:chocolateyDone = $true 71 | } finally { 72 | Pop-Location 73 | } 74 | } 75 | } 76 | 77 | function Publish-Chocolatey() { 78 | New-Chocolatey 79 | Push-Location ./chocolatey/publish 80 | try { 81 | & ./publish.ps1 82 | } finally { 83 | Pop-Location 84 | } 85 | } 86 | 87 | function Publish() { 88 | @( 89 | (Get-Item function:Publish-Msi) 90 | ) | ForEach-Object { 91 | & $_ 92 | } 93 | } 94 | 95 | function New-Package() { 96 | @( 97 | (Get-Item function:New-Msi) 98 | ) | ForEach-Object { 99 | Write-Host $_.Name.Replace("New-", "") -BackgroundColor 'White' -ForegroundColor 'Black' 100 | & $_ 101 | Write-Host "`n`n" 102 | } 103 | } 104 | 105 | Setup 106 | switch -wildcard ($target) { 107 | # release targets 108 | "package" { New-Package } 109 | "msi" { New-Msi } 110 | "chocolatey" { New-Chocolatey } 111 | "clean" { Clean } 112 | 113 | default { Write-Error "No target '$target'" ; Exit -1 } 114 | } 115 | -------------------------------------------------------------------------------- /deb/build/debian/jenkins.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # postinst script for @@ARTIFACTNAME@@ 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | 8 | # summary of how this script can be called: 9 | # * `configure' 10 | # * `abort-upgrade' 11 | # * `abort-remove' `in-favour' 12 | # 13 | # * `abort-remove' 14 | # * `abort-deconfigure' `in-favour' 15 | # `removing' 16 | # 17 | # for details, see http://www.debian.org/doc/debian-policy/ or 18 | # the debian-policy package 19 | 20 | case "$1" in 21 | configure) 22 | if [ -d /run/systemd/system ]; then 23 | # TODO --value would eliminate the need for cut, but older versions of systemd do not support it 24 | JENKINS_USER=$(systemctl show @@ARTIFACTNAME@@ --property=User 2>/dev/null | cut -d= -f2-) 25 | JENKINS_GROUP=$(systemctl show @@ARTIFACTNAME@@ --property=Group 2>/dev/null | cut -d= -f2-) 26 | elif [ -r /etc/default/@@ARTIFACTNAME@@ ]; then 27 | . /etc/default/@@ARTIFACTNAME@@ 28 | fi 29 | : "${JENKINS_USER:=@@ARTIFACTNAME@@}" 30 | : "${JENKINS_GROUP:=@@ARTIFACTNAME@@}" 31 | 32 | # Create @@ARTIFACTNAME@@ group and user if they don't exist. 33 | # sometimes tools that users want Jenkins to run need a shell, 34 | # so use /bin/bash. See JENKINS-4830 35 | if ! getent group "$JENKINS_GROUP" >/dev/null; then 36 | addgroup --system --quiet "$JENKINS_GROUP" 37 | fi 38 | if ! id "$JENKINS_USER" >/dev/null 2>&1; then 39 | adduser --system --quiet --home /var/lib/@@ARTIFACTNAME@@ --no-create-home \ 40 | --ingroup "$JENKINS_GROUP" --disabled-password --shell /bin/bash \ 41 | --gecos '@@PRODUCTNAME@@' \ 42 | "$JENKINS_USER" 43 | fi 44 | 45 | # directories needed for jenkins 46 | # we don't do -R because it can take a long time on big installation 47 | chown "${JENKINS_USER}:${JENKINS_GROUP}" /var/lib/@@ARTIFACTNAME@@ /var/log/@@ARTIFACTNAME@@ 48 | # we don't do "chmod 750" so that the user can choose the pemission for g and o on their own 49 | chmod u+rwx /var/lib/@@ARTIFACTNAME@@ /var/log/@@ARTIFACTNAME@@ 50 | 51 | # make sure jenkins can delete everything in /var/cache/jenkins to 52 | # re-explode war. 53 | chown -R "${JENKINS_USER}:${JENKINS_GROUP}" /var/cache/@@ARTIFACTNAME@@ 54 | chmod -R 750 /var/cache/@@ARTIFACTNAME@@ 55 | 56 | # older installations may use /var/run/jenkins 57 | # so make sure that they can delete too. 58 | if [ -d "/var/run/@@ARTIFACTNAME@@" ]; then 59 | chown -R "${JENKINS_USER}:${JENKINS_GROUP}" /var/run/@@ARTIFACTNAME@@ 60 | chmod -R 750 /var/run/@@ARTIFACTNAME@@ 61 | fi 62 | 63 | /usr/share/@@ARTIFACTNAME@@/migrate /etc/default/@@ARTIFACTNAME@@ || true 64 | ;; 65 | 66 | abort-upgrade | abort-remove | abort-deconfigure) ;; 67 | 68 | \ 69 | *) 70 | echo "postinst called with unknown argument \`$1'" >&2 71 | exit 1 72 | ;; 73 | esac 74 | 75 | # dh_installdeb will replace this with shell code automatically 76 | # generated by other debhelper scripts. 77 | 78 | #DEBHELPER# 79 | 80 | exit 0 81 | -------------------------------------------------------------------------------- /deb/build/debian/jenkins.default: -------------------------------------------------------------------------------- 1 | # defaults for Jenkins automation server 2 | 3 | # pulled in from the init script; makes things easier. 4 | NAME=@@ARTIFACTNAME@@ 5 | 6 | # arguments to pass to java 7 | 8 | # Allow graphs etc. to work even when an X server is present 9 | JAVA_ARGS="-Djava.awt.headless=true" 10 | 11 | #JAVA_ARGS="-Xmx256m" 12 | 13 | # make jenkins listen on IPv4 address 14 | #JAVA_ARGS="-Djava.net.preferIPv4Stack=true" 15 | 16 | PIDFILE=/var/run/$NAME/$NAME.pid 17 | 18 | # user and group to be invoked as (default to jenkins) 19 | JENKINS_USER=$NAME 20 | JENKINS_GROUP=$NAME 21 | 22 | # location of the jenkins war file 23 | JENKINS_WAR=/usr/share/java/$NAME.war 24 | 25 | # jenkins home location 26 | JENKINS_HOME=/var/lib/$NAME 27 | 28 | # set this to false if you don't want Jenkins to run by itself 29 | # in this set up, you are expected to provide a servlet container 30 | # to host jenkins. 31 | RUN_STANDALONE=true 32 | 33 | # log location. this may be a syslog facility.priority 34 | JENKINS_LOG=/var/log/$NAME/$NAME.log 35 | #JENKINS_LOG=daemon.info 36 | 37 | # Whether to enable web access logging or not. 38 | # Set to "yes" to enable logging to /var/log/$NAME/access_log 39 | JENKINS_ENABLE_ACCESS_LOG="no" 40 | 41 | # OS LIMITS SETUP 42 | # comment this out to observe /etc/security/limits.conf 43 | # this is on by default because http://github.com/jenkinsci/jenkins/commit/2fb288474e980d0e7ff9c4a3b768874835a3e92e 44 | # reported that Ubuntu's PAM configuration doesn't include pam_limits.so, and as a result the # of file 45 | # descriptors are forced to 1024 regardless of /etc/security/limits.conf 46 | MAXOPENFILES=8192 47 | 48 | # set the umask to control permission bits of files that Jenkins creates. 49 | # 027 makes files read-only for group and inaccessible for others, which some security sensitive users 50 | # might consider benefitial, especially if Jenkins runs in a box that's used for multiple purposes. 51 | # Beware that 027 permission would interfere with sudo scripts that run on the master (JENKINS-25065.) 52 | # 53 | # Note also that the particularly sensitive part of $JENKINS_HOME (such as credentials) are always 54 | # written without 'others' access. So the umask values only affect job configuration, build records, 55 | # that sort of things. 56 | # 57 | # If commented out, the value from the OS is inherited, which is normally 022 (as of Ubuntu 12.04, 58 | # by default umask comes from pam_umask(8) and /etc/login.defs 59 | 60 | # UMASK=027 61 | 62 | # port for HTTP connector (default 8080; disable with -1) 63 | HTTP_PORT=@@PORT@@ 64 | 65 | 66 | # servlet context, important if you want to use apache proxying 67 | PREFIX=/$NAME 68 | 69 | # arguments to pass to jenkins. 70 | # full list available from java -jar jenkins.war --help 71 | # --javaHome=$JAVA_HOME 72 | # --httpListenAddress=$HTTP_HOST (default 0.0.0.0) 73 | # --httpPort=$HTTP_PORT (default 8080; disable with -1) 74 | # --httpsPort=$HTTP_PORT 75 | # --argumentsRealm.passwd.$ADMIN_USER=[password] 76 | # --argumentsRealm.roles.$ADMIN_USER=admin 77 | # --webroot=~/.jenkins/war 78 | # --prefix=$PREFIX 79 | 80 | JENKINS_ARGS="--webroot=/var/cache/$NAME/war --httpPort=$HTTP_PORT" 81 | -------------------------------------------------------------------------------- /rpm/build/SPECS/jenkins.spec: -------------------------------------------------------------------------------- 1 | # TODO: 2 | # - how to add to the trusted service of the firewall? 3 | 4 | %define workdir %{_var}/lib/@@ARTIFACTNAME@@ 5 | 6 | Name: @@ARTIFACTNAME@@ 7 | Version: %{ver} 8 | Release: 1 9 | Summary: @@SUMMARY@@ 10 | Source: jenkins.war 11 | Source1: jenkins.service 12 | Source2: jenkins.sh 13 | Source3: migrate.sh 14 | Source4: jenkins.conf 15 | URL: @@HOMEPAGE@@ 16 | License: @@LICENSE@@ 17 | BuildRoot: %{_tmppath}/build-%{name}-%{version} 18 | # Unfortunately the Oracle Java RPMs do not register as providing anything (including "java" or "jdk") 19 | # So either we make a hard requirement on the OpenJDK or none at all 20 | # Only workaround would be to use a java virtual package, see https://github.com/keystep/virtual-java-rpm 21 | # TODO: If re-enable, fix the matcher for Java 17 22 | # Requires: java >= 1:1.8.0 23 | Requires: procps 24 | Requires(pre): /usr/sbin/useradd, /usr/sbin/groupadd 25 | BuildArch: noarch 26 | %systemd_requires 27 | 28 | %description 29 | @@DESCRIPTION_FILE@@ 30 | 31 | Authors: 32 | -------- 33 | @@AUTHOR@@ 34 | 35 | %prep 36 | %setup -q -T -c 37 | 38 | %build 39 | 40 | %install 41 | rm -rf "%{buildroot}" 42 | %__install -D -m0644 "%{SOURCE0}" "%{buildroot}%{_javadir}/%{name}.war" 43 | %__install -D -m0644 "%{SOURCE1}" "%{buildroot}%{_unitdir}/%{name}.service" 44 | %__install -D -m0755 "%{SOURCE2}" "%{buildroot}%{_bindir}/%{name}" 45 | %__install -D -m0755 "%{SOURCE3}" "%{buildroot}%{_datadir}/%{name}/migrate" 46 | %__install -D -m0755 "%{SOURCE4}" "%{buildroot}%{_tmpfilesdir}/%{name}.conf" 47 | 48 | %pre 49 | /usr/bin/getent group %{name} &>/dev/null || /usr/sbin/groupadd -r %{name} &>/dev/null 50 | # SUSE version had -o here, but in Fedora -o isn't allowed without -u 51 | /usr/bin/getent passwd %{name} &>/dev/null || /usr/sbin/useradd -g %{name} -s /bin/false -r -c "@@SUMMARY@@" \ 52 | -d "%{workdir}" %{name} &>/dev/null 53 | 54 | %post 55 | if [ $1 -eq 1 ]; then 56 | %__install -d -m 0755 -o %{name} -g %{name} %{workdir} 57 | %__install -d -m 0750 -o %{name} -g %{name} %{_localstatedir}/cache/%{name} 58 | elif [ -f "%{_sysconfdir}/sysconfig/%{name}" ]; then 59 | %{_datadir}/%{name}/migrate "/etc/sysconfig/%{name}" || true 60 | fi 61 | %systemd_post %{name}.service 62 | 63 | %preun 64 | if [ $1 -eq 0 ]; then 65 | %__rm -rf %{_localstatedir}/cache/%{name}/war 66 | fi 67 | %systemd_preun %{name}.service 68 | 69 | %postun 70 | %systemd_postun_with_restart %{name}.service 71 | 72 | %files 73 | %{_javadir}/%{name}.war 74 | %ghost %{workdir} 75 | %ghost %{_localstatedir}/cache/%{name} 76 | %{_unitdir}/%{name}.service 77 | %{_bindir}/%{name} 78 | %dir %{_datadir}/%{name} 79 | %{_datadir}/%{name}/migrate 80 | %{_tmpfilesdir}/%{name}.conf 81 | 82 | %changelog 83 | * Mon Nov 06 2023 minfrin@sharp.fm 84 | - added unix domain socket support 85 | * Mon Jun 19 2023 projects@unixadm.org 86 | - removed sysv initscript for el>=7 87 | - removed logrotate config 88 | - avoid re-chowning workdir and cachedir on upgrades 89 | * Sat Apr 19 2014 mbarr@mbarr.net 90 | - Removed the jenkins.repo installation. Per https://issues.jenkins-ci.org/browse/JENKINS-22690 91 | * Wed Sep 28 2011 kk@kohsuke.org 92 | - See [@@CHANGELOG_PAGE@@] for complete details 93 | -------------------------------------------------------------------------------- /rpm/publish/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail 3 | 4 | : "${AGENT_WORKDIR:=/tmp}" 5 | : "${GPG_KEYNAME:?Require valid gpg keyname}" 6 | : "${RPMDIR:?Require where to put binary files}" 7 | : "${RPM_WEBDIR:?Require where to put index and other web contents}" 8 | : "${RPM_URL:?Require rpm repository url}" 9 | : "${RELEASELINE?Require rpm release line}" 10 | : "${BASE:?Require base directory}" 11 | : "${GPG_PUBLIC_KEY_FILENAME:="${ORGANIZATION}.key"}" 12 | 13 | # $$ Contains current pid 14 | D="$AGENT_WORKDIR/$$" 15 | 16 | function clean() { 17 | rm -rf "$D" 18 | } 19 | 20 | function generateSite() { 21 | local gpg_publickey_repomd="$D/repodata/repomd.xml.key" 22 | local gpg_publickey_file="$D/${GPG_PUBLIC_KEY_FILENAME}" 23 | local gpg_publickey_info_file="$D/${GPG_PUBLIC_KEY_FILENAME}.info" 24 | 25 | mkdir -p "$(dirname "${gpg_publickey_repomd}")" 26 | gpg --export -a --output "${gpg_publickey_repomd}" "${GPG_KEYNAME}" 27 | gpg --import-options show-only --import "${gpg_publickey_repomd}" > "${gpg_publickey_info_file}" 28 | cp "${gpg_publickey_repomd}" "${gpg_publickey_file}" # Duplicate between repository files and user facing website 29 | 30 | cat >"$D/${ARTIFACTNAME}.repo" < "$RPM_WEBDIR/repodata/repomd.xml.asc" 65 | } 66 | 67 | function init() { 68 | mkdir -p "$D/RPMS/noarch" "${RPMDIR}" "${RPM_WEBDIR}" 69 | } 70 | 71 | function uploadPackage() { 72 | rsync --archive \ 73 | --verbose \ 74 | --progress \ 75 | "$RPM" "$RPMDIR/" 76 | } 77 | 78 | function show() { 79 | echo "Parameters:" 80 | echo "RPM: $RPM" 81 | echo "RPMDIR: $RPMDIR" 82 | echo "RPM_WEBDIR: $RPM_WEBDIR" 83 | echo "GPG_KEYNAME: $GPG_KEYNAME" 84 | echo "GPG_PUBLIC_KEY_FILENAME: $GPG_PUBLIC_KEY_FILENAME" 85 | echo "---" 86 | } 87 | 88 | function uploadSite() { 89 | pushd "$D" 90 | rsync --archive \ 91 | --verbose \ 92 | --progress \ 93 | --exclude RPMS \ 94 | --exclude "HEADER.html" \ 95 | --exclude "FOOTER.html" \ 96 | . "${RPM_WEBDIR}/" 97 | 98 | # Following html need to be located inside the binary directory 99 | rsync --archive \ 100 | --verbose \ 101 | --progress \ 102 | --include "HEADER.html" \ 103 | --include "FOOTER.html" \ 104 | --exclude "*" \ 105 | . "${RPMDIR}/" 106 | popd 107 | } 108 | 109 | show 110 | init 111 | uploadPackage 112 | generateSite 113 | uploadSite 114 | clean 115 | -------------------------------------------------------------------------------- /credentials/test.ascii.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | mQINBGIgHG8BEAD1EcibFpYRfEakMtky2E2pVqbwbTNH+jUr9XjMuyltEmIvlnNW 4 | W1ZzAlKY9hIM1zOhXp3jO3LCschvb6Rff8CuV0i+3g4rPi35i8Ur3MVkr7yTelge 5 | sF8ywZrAL3zhJDkeUChbKgWHB5HKdL/ZkEBci7TbHzSolGlKPA0YcAmE0jROfXal 6 | VBT7jcwJ2xx7RGYoRn5UHpJ2N5eRj96+wpI2SbZcNXaLSGd+rZNd9Q/4Xozw2Mzs 7 | PXCGUlk1tDfPSv91PHbYj1h1bIiU4iOISTOQJay5MjTyVHEho6LJ4s8PVsiG0/hB 8 | bEo8r2Izw75GShD7A9ZYUxlj8IqtzMjvNLxakN3U6lwLbcOYSDf6l2uIYl5UOhaf 9 | X9JeGll//hXSRiDQOwnO2LxqXwZ/uRP/IvoygswdKCPqot0Sl4q5VkfTt3PWNmEa 10 | dVDl52pj2GW4/REL8ouqGmaHwusuxxRekbYYXxqWTKoicoyTamcxKLrEBJ3vTIsS 11 | 4CQDl2hO67Gk1wzbdnTY7vzt1+8FlexKeu1XB1bv6VQSoJRdKPtfx5ZMdM6416hN 12 | VAdTGfCNEqBZn2KP3kPkHtc4/+BGKfBZDJwbPSta2VdvgGWTSQqia8vgPRFn9waS 13 | +nJKVCR1btoVBOX1F3N8VWl939J9V2bnMAj6AlbFeuxIB8C/8BSIShma+QARAQAB 14 | tDtCb2d1cyBUZXN0IChUaGlzIGlzIHRlc3Qgb25seSBrZXkpIDxub3JlcGx5QGpl 15 | bmtpbnMtY2kub3JnPokCUgQTAQgAPBYhBNkdPgAgAQfkIZUk3UJxW1biEbBCBQJi 16 | IBxvAhsDBQsJCAcCAyICAQYVCgkICwIEFgIDAQIeBwIXgAAKCRBCcVtW4hGwQgLB 17 | D/4m17etiSMd6i/eWM8Z3EXiGC4+lZRq0eJ+n0HDDcVG4PEmUWwNCpe5x12iJXF4 18 | XApWOFxyC6ptTHMYPxiYr5VebJaSqzYlIb+gJY2GGoFGvvLr+A746SmmWannWkG8 19 | hfi37V7gBIhQ45kOAY91XR7Vxr12b2Xg1QeLaOTktAXeZV/b5UYLxuhm6FUGtQdw 20 | X13W+xtfjRjUkSSVkdaf9wXX3gW6i+ihrT1deL/PenfoPGJCIGV3/qNr5CkP7v0O 21 | BD7sUAmZyqwWo8HjK4fVSY4Sr0akG6QPQoE4WdaldZB8AJmJ/nwiIlFFnOrism5e 22 | rQlSq1XTCniEzIQPoLr9SY4vzC+ZuZArBqfedAEh8qut1Pl0unEvkBoe6bSxeF/W 23 | WOzL9J+LVwgoulUR2FjRZiCelCJFp5u6DpaV3P3ljsfvijhEips/4YPpYyuAQBWm 24 | x9RXf6Sx/vBx79bfts2jgJwIouCxLUsJf7lTgrZuurRkmdPu/rcOnDMWr3cAuFqa 25 | oWQOT2ktunQz53lLbXoIRzYOJCLmf2eVTyCSU5NGF5Del+wIJhnwAJi5u5m3RwUk 26 | lMNhCJ4vLWiq87ngSfxJG4s0BECdfDtUMzNwGNRNA825GPEIoliogA+lH0UkuDPo 27 | i8kdlmJlmUbZ2OR7EEjVDNMmOB5V4DdDaNhovjOvZB+cNLkCDQRiIBxvARAAyFyj 28 | RqO9/nV6/EmDk9TUYIBSSrCJJOIdKXMgpXup9ILxy9mXpZPOX7mAyvw/u3zRYjQt 29 | vB+jp+1OwZ5hgy9FBxs4JYFzT+PaNwOdeEK5woEqJMOUCWpiI9ljNFOIubqspLaa 30 | JGaUj6wr5ajWvwoC0wy22t77fIRf09fMmhtQ6D6aLS+gQ7bABVwcwNrObSjder0w 31 | Sb+deh+2tzSchby0w8Yn5RuVcnQhygfNiK2uqXrUROnkpY5r2JeWm853C4nog9rN 32 | MEAStAxdvjb6/GJSJ8UZdtlyIqsyWZEPYnRmYi4zvoP7yksC4Qr97yWBXv73lTsW 33 | KWlumRqk8KmJwh0oerR0AGmMIjoS/ihcY3QfnjHuDZ4y+Z9X8ATHa/eRcMexIZZe 34 | jAFQtbt6G5OfxJQ6cMV611MdjAgzjlLaODnCfhpT33gxoYmTG4ZNtnytHqugd3VK 35 | WYXRBOhnFpi/NswnbE9o/FKwzAwFfnznPa5XhyW9GTzEENhJLjajOnV8+VwaiYpB 36 | q0CY705wmnwRNbkerV/tX6j4oU2aoGy4ngW5XBDXcjGJuvdEeRP1QStKV2NnKcWY 37 | FsjyJ9MQSeKGZ1RkJwOUvOHd14GAQp+xJzd0JbfFMeq22WRsFlpdFV5RtUNe+3bo 38 | BJRWsBPIiou+iZUCJcruUdECNPK9dKgNqOo3ru0AEQEAAYkCNgQYAQgAIBYhBNkd 39 | PgAgAQfkIZUk3UJxW1biEbBCBQJiIBxvAhsMAAoJEEJxW1biEbBC1WoP/27gtSCD 40 | 99++rK4KS0N06kHi7b1zQH1N0em7764zc9OvIhcwQJW0QW7Fd8GBmeFApAaGkYPp 41 | D5FFxpaI8aGnfrkZxZ3CGj/kQhJQgRWoWyoQ+NdEM2QTEBiAGFq8HQiHDevC0rTF 42 | cxNIn/drDnJE+COvEmaCoKX++5sR3YXefIl7qdAHRa5yUCi4Dt62jD6Xvdnm+Bdc 43 | RxgDomtlzXby01WoS3wu6+YzoMGgVVpCsHaz3iSuboVVce90vTccsmpeEiEfAP3n 44 | zZ+Wtk96LUKdttm5fJq7FQXuF0a8gqwsDqnZksqrVcvSQAYR8Q9TaEsDIFZcfO/b 45 | otpdZkBmfRxLRK/tz6jGPvLf5q4vEWYARCizHaycmhaf3wDckl6s+2bsbf3ErpWI 46 | N5fG6AeE750RSO9tcVSmJFUzZ1wfIyifbDNCaKgrfv9r1Cg5zdbWP47ZoEZS3OZ+ 47 | 5BAGJZNZo7jbExG8gZwjjH7N3ctNpTlOBRbef3FYPaTxMfpDO295yyqmD6bvCm/T 48 | atoU8dHfKlnxp5kEPqTudGSgUnBeD4d7u8CSbGn8ZEMM1Ev0P0iK48rqzJLeqple 49 | 7wx2WUbMYEB/f7aIbyUSAOzuJp01AAOElGoynT0zeIqexQh0pRDyyPMUffm1gE4O 50 | cBMVenZ3qy5zyY5xyBxrvVLICEhag09VUcXj 51 | =wRQC 52 | -----END PGP PUBLIC KEY BLOCK----- 53 | -------------------------------------------------------------------------------- /bin/test_branding.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import branding 4 | import os 5 | import string 6 | import tempfile 7 | import unittest 8 | 9 | RAW_CONTENT = """ 10 | PRODUCTNAME 11 | ARTIFACTNAME 12 | 13 | SUMMARY 14 | PORT 15 | 16 | AUTHOR 17 | # Not here 18 | LICENSE 19 | HOMEPAGE 20 | CHANGELOG_PAGE 21 | ---------------------------------- 22 | 23 | # INVALID 24 | DEB_URL 25 | LICENSE_TEXT 26 | 27 | """ 28 | 29 | SHORT_VARS = """ 30 | TESTVAR 31 | """ 32 | 33 | # NOMATCH is a section that should *not* be treated as a variable for substitution to 34 | # Avoid issues with curly braces 35 | TEMPLATED_CONTENT = ( 36 | "My @@VAR@@ is @@FILECONTENT@@ and I have @@@@ESCAPES@@ and @@{NOMATCH}@@ stuff" 37 | ) 38 | TEMPLATE_VARS = {"VAR": "SPECIAL", "FILECONTENT": "gooooooober"} 39 | 40 | # Shows that substitutions were performed, and NOMATCH does not get handled as a substitution variable 41 | TEMPLATE_EXPECTED = ( 42 | "My SPECIAL is gooooooober and I have @@ESCAPES@@ and @@{NOMATCH}@@ stuff" 43 | ) 44 | 45 | 46 | class TestBranding(unittest.TestCase): 47 | def test_clean_lines(self): 48 | cleaned = set(branding.clean_text_lines(RAW_CONTENT)) 49 | expected = { 50 | "PRODUCTNAME", 51 | "ARTIFACTNAME", 52 | "SUMMARY", 53 | "PORT", 54 | "AUTHOR", 55 | "LICENSE", 56 | "HOMEPAGE", 57 | "CHANGELOG_PAGE", 58 | "DEB_URL", 59 | "LICENSE_TEXT", 60 | } 61 | invalid_results = cleaned ^ expected # Items in one set but not the other 62 | self.assertFalse(invalid_results) 63 | 64 | def test_read_env_list(self): 65 | temp = tempfile.NamedTemporaryFile() 66 | temp.write(SHORT_VARS.encode()) 67 | temp.seek(0) 68 | os.environ["TESTVAR"] = "testvalue" 69 | vals = branding.read_env_variable_list(temp.name) 70 | self.assertEqual(1, len(vals)) 71 | self.assertEqual("testvalue", vals["TESTVAR"]) 72 | 73 | def test_read_file_content(self): 74 | """Write file and then read, using path from env""" 75 | temp = tempfile.NamedTemporaryFile() 76 | temp.write(RAW_CONTENT.encode()) 77 | temp.seek(0) 78 | 79 | os.environ["FILEPATH"] = temp.name 80 | vals = branding.read_file_content({"FILEPATH": temp.name}) 81 | self.assertEqual(RAW_CONTENT, vals["FILEPATH"]) 82 | 83 | def test_templating(self): 84 | output = branding.apply_template(TEMPLATED_CONTENT, TEMPLATE_VARS) 85 | self.assertEqual(TEMPLATE_EXPECTED, output) 86 | 87 | def test_missing_variable(self): 88 | """Prove branding will fail if branding variable is undefined""" 89 | 90 | try: 91 | output = branding.apply_template( 92 | "My @@UNDEFINED_VALUE@@ is going to fail", {"going": "to fail"} 93 | ) 94 | self.fail("Should throw KeyError") 95 | except KeyError: 96 | pass 97 | 98 | def test_in_place_templating(self): 99 | temp = tempfile.NamedTemporaryFile() 100 | temp.write(TEMPLATED_CONTENT.encode()) 101 | temp.seek(0) 102 | branding.apply_templating_to_file(temp.name, TEMPLATE_VARS) 103 | temp.seek(0) 104 | self.assertEqual(TEMPLATE_EXPECTED, temp.read().decode()) 105 | 106 | 107 | if __name__ == "__main__": 108 | unittest.main() 109 | -------------------------------------------------------------------------------- /deb/publish/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | : "${AGENT_WORKDIR:=/tmp}" 6 | : "${GPG_KEYNAME:?Require valid gpg keyname}" 7 | : "${DEB:?Require Debian package}" 8 | : "${DEBDIR:? Require where to put binary files}" 9 | : "${DEB_WEBDIR:? Require where to put repository index and other web contents}" 10 | : "${DEB_URL:? Require Debian repository Url}" 11 | : "${GPG_PUBLIC_KEY_FILENAME:="${ORGANIZATION}.key"}" 12 | 13 | # $$ Contains current pid 14 | D="$AGENT_WORKDIR/$$" 15 | 16 | bin="$(dirname "$0")" 17 | 18 | function clean() { 19 | rm -rf "$D" 20 | } 21 | 22 | # Generate and publish site content 23 | function generateSite() { 24 | cp -R "$bin/contents/." "$D/contents" 25 | 26 | local gpg_publickey_file="$D/contents/${GPG_PUBLIC_KEY_FILENAME}" 27 | local gpg_publickey_info_file="$D/contents/${GPG_PUBLIC_KEY_FILENAME}.info" 28 | gpg --export -a --output "${gpg_publickey_file}" "${GPG_KEYNAME}" 29 | gpg --import-options show-only --import "${gpg_publickey_file}" > "${gpg_publickey_info_file}" 30 | 31 | "$BASE/bin/indexGenerator.py" \ 32 | --distribution debian \ 33 | --gpg-key-info-file "${gpg_publickey_info_file}" \ 34 | --targetDir "$D/html" 35 | 36 | "$BASE/bin/branding.py" "$D" 37 | 38 | # build package index 39 | # see http://wiki.debian.org/SecureApt for more details 40 | cp "${DEB}" "$D/binary/" 41 | 42 | pushd "$D" 43 | apt-ftparchive packages binary >binary/Packages 44 | apt-ftparchive contents binary >binary/Contents 45 | popd 46 | 47 | # Remote ftparchive-merge 48 | # https://github.com/kohsuke/apt-ftparchive-merge 49 | pushd "$D/binary" 50 | mvn -V org.kohsuke:apt-ftparchive-merge:1.6:merge -Durl="$DEB_URL/binary/" -Dout=../merged 51 | popd 52 | 53 | # Local ftparchive-merge 54 | 55 | cat "$D/merged/Packages" >"$D/binary/Packages" 56 | gzip -9c "$D/merged/Packages" >"$D/binary/Packages.gz" 57 | bzip2 -c "$D/merged/Packages" >"$D/binary/Packages.bz2" 58 | lzma -c "$D/merged/Packages" >"$D/binary/Packages.lzma" 59 | gzip -9c "$D/merged/Contents" >"$D/binary/Contents.gz" 60 | 61 | apt-ftparchive -c "$bin/release.conf" release "$D/binary" >"$D/binary/Release" 62 | } 63 | 64 | function init() { 65 | mkdir -p "$D/binary" "$D/contents" "$D/html" \ 66 | "$DEBDIR" `# where to put binary files` \ 67 | "$DEB_WEBDIR" `# where to put repository index and other web contents` 68 | } 69 | 70 | # Upload Debian Package 71 | function uploadPackage() { 72 | rsync --archive \ 73 | --verbose \ 74 | --progress \ 75 | "$DEB" "$DEBDIR/" 76 | } 77 | 78 | function uploadPackageSite() { 79 | cp \ 80 | "$D"/binary/Packages* \ 81 | "$D"/binary/Release \ 82 | "$D"/binary/Release.gpg \ 83 | "$D"/binary/Contents* \ 84 | "$D"/contents/binary 85 | 86 | rsync --archive \ 87 | --verbose \ 88 | --progress \ 89 | "$D/contents/" "$DEB_WEBDIR/" 90 | } 91 | 92 | function uploadHtmlSite() { 93 | rsync --archive \ 94 | --verbose \ 95 | --progress \ 96 | "$D/html/" "$DEB_WEBDIR/" 97 | } 98 | 99 | function show() { 100 | echo "Parameters:" 101 | echo "DEB: $DEB" 102 | echo "DEBDIR: $DEBDIR" 103 | echo "DEB_WEBDIR: $DEB_WEBDIR" 104 | echo "GPG_KEYNAME: $GPG_KEYNAME" 105 | echo "GPG_PUBLIC_KEY_FILENAME: $GPG_PUBLIC_KEY_FILENAME" 106 | echo "---" 107 | } 108 | 109 | function signSite() { 110 | # sign the release file 111 | if [ -f "$D/binary/Release.gpg" ]; then 112 | rm "$D/binary/Release.gpg" 113 | fi 114 | 115 | gpg \ 116 | --batch \ 117 | --pinentry-mode loopback \ 118 | --digest-algo=sha256 \ 119 | -u "$GPG_KEYNAME" \ 120 | --passphrase-file "$GPG_PASSPHRASE_FILE" \ 121 | -abs \ 122 | -o "$D/binary/Release.gpg" \ 123 | "$D/binary/Release" 124 | } 125 | 126 | show 127 | init 128 | generateSite 129 | signSite 130 | 131 | uploadPackage 132 | uploadPackageSite 133 | 134 | uploadHtmlSite 135 | clean 136 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | 7 | platforms: 8 | # deb 9 | - name: debian-11 # EOL 2026-06-30 10 | image: dokken/debian-11:latest 11 | override_command: false 12 | volumes: 13 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 14 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 15 | cgroupns_mode: host 16 | privileged: true 17 | - name: debian-12 # EOL 2028-06-10 18 | image: dokken/debian-12:latest 19 | override_command: false 20 | volumes: 21 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 22 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 23 | cgroupns_mode: host 24 | privileged: true 25 | - name: debian-13 # EOL 2030-06-30 (LTS) 26 | image: dokken/debian-13:latest 27 | override_command: false 28 | volumes: 29 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 30 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 31 | cgroupns_mode: host 32 | privileged: true 33 | - name: ubuntu-22-04 # EOL 2027-04-01 34 | image: dokken/ubuntu-22.04:latest 35 | override_command: false 36 | volumes: 37 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 38 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 39 | cgroupns_mode: host 40 | privileged: true 41 | - name: ubuntu-24-04 # EOL 2029-04-01 42 | image: dokken/ubuntu-24.04:latest 43 | override_command: false 44 | volumes: 45 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 46 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 47 | cgroupns_mode: host 48 | privileged: true 49 | # rpm 50 | - name: almalinux-9 # EOL 2027-05-31 51 | image: dokken/almalinux-9:latest 52 | override_command: false 53 | volumes: 54 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 55 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 56 | cgroupns_mode: host 57 | privileged: true 58 | - name: rockylinux-9 # 2032-05-31 59 | image: dokken/rockylinux-9:latest 60 | override_command: false 61 | volumes: 62 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 63 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 64 | cgroupns_mode: host 65 | privileged: true 66 | - name: amazonlinux-2023 # EOL 2029-06-30 67 | image: dokken/amazonlinux-2023:latest 68 | override_command: false 69 | volumes: 70 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 71 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 72 | cgroupns_mode: host 73 | privileged: true 74 | - name: centos-stream-9 # EOL 2027-05-31 75 | image: dokken/centos-stream-9:latest 76 | override_command: false 77 | volumes: 78 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 79 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 80 | cgroupns_mode: host 81 | privileged: true 82 | - name: centos-stream-10 # EOL 2030-01-01 83 | image: dokken/centos-stream-10:latest 84 | override_command: false 85 | volumes: 86 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 87 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 88 | cgroupns_mode: host 89 | privileged: true 90 | - name: fedora-41 # EOL 2025-11-19 91 | image: dokken/fedora-41:latest 92 | override_command: false 93 | volumes: 94 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 95 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 96 | cgroupns_mode: host 97 | privileged: true 98 | - name: oraclelinux-9 # EOL 2032-06-30 99 | image: dokken/oraclelinux-9:latest 100 | override_command: false 101 | volumes: 102 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 103 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 104 | cgroupns_mode: host 105 | privileged: true 106 | # suse 107 | - name: opensuse-leap-15.6 # EOL 2025-12-01 108 | image: dokken/opensuse-leap-15.6:latest 109 | override_command: false 110 | volumes: 111 | - ${MOLECULE_PROJECT_DIRECTORY}/target:/var/tmp/target 112 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 113 | cgroupns_mode: host 114 | privileged: true 115 | provisioner: 116 | name: ansible 117 | verifier: 118 | name: ansible 119 | -------------------------------------------------------------------------------- /bin/branding.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import re 5 | import string 6 | import sys 7 | 8 | # Applies branding to files/folders with simple templating 9 | # Usage is 'python branding.py {file or folder}' 10 | # Env variables to use are given in BRANDING_ENV_VARIABLE_LIST 11 | # Env variables giving *paths* to read content for templating are given in BRANDING_ENV_PATH_LIST 12 | # Author Sam Van Oort 13 | 14 | BRANDING_ENV_VARIABLE_LIST = "branding.list" 15 | BRANDING_ENV_PATH_LIST = "branding-files.list" 16 | 17 | 18 | class CustomTemplate(string.Template): 19 | delimiter = "@@" 20 | pattern = r""" %(delim)s(?: 21 | (?P) | # Nope, taken care of by the delimiter not being a valid id character 22 | (?P%(id)s) | # delimiter and a Python identifier 23 | (?P%(id)s) | # we don't support braced identifiers, since it's surrounded by delimiters 24 | (?P) # no matches 25 | )%(delim)s """ % dict( 26 | delim=re.escape("@@"), id=string.Template.idpattern 27 | ) 28 | 29 | 30 | def clean_text_lines(textcontent): 31 | """Splits file content by line boundaries, strips leading/trailing whitespace, 32 | and removes comments with # and -- prefixes and whitespace lines""" 33 | lines = map(lambda x: x.strip(), textcontent.splitlines()) 34 | lines = filter( 35 | lambda x: x and not x.startswith("#") and not x.startswith("--"), lines 36 | ) 37 | return lines 38 | 39 | 40 | def read_env_variable_list(path): 41 | """Read a list of environment variables from a file (one per line) and get a dict of var:value""" 42 | with open(path, "r") as env_file: 43 | lines = clean_text_lines(env_file.read()) 44 | return {x: os.environ.get(x) for x in lines} 45 | 46 | 47 | def read_file_content(value_path_dictionary): 48 | """For a {variable_name:file_path} dictionary, read each file and 49 | return a dictionary of {variable:file_content} 50 | 51 | If paths are null/empty, they are not read to result.""" 52 | output = {} 53 | filtered = filter(lambda x: x[1] and x[1].strip(), value_path_dictionary.items()) 54 | for variable, path in filtered: 55 | with open(path, "r") as f: 56 | output[variable] = f.read() 57 | return output 58 | 59 | 60 | def read_branding_variables(base_path, env_variables_list, file_variables_list): 61 | """Read branding variables from files/environment and return result""" 62 | 63 | raw_variables = read_env_variable_list(os.path.join(base_path, env_variables_list)) 64 | file_variables = read_env_variable_list( 65 | os.path.join(base_path, file_variables_list) 66 | ) 67 | raw_variables.update( 68 | read_file_content(file_variables) 69 | ) # Add file content variables 70 | return raw_variables 71 | 72 | 73 | def apply_template(input_string, branding_map): 74 | """Applies templating in a back-compatible fashion""" 75 | return CustomTemplate(input_string).substitute(branding_map) 76 | 77 | 78 | def apply_templating_to_file(path, branding_map): 79 | """Do IN-PLACE search and replace using string templating for a each file 80 | Throws Exceptions if I/O fails or substitution is missing vars (safety check) 81 | """ 82 | with open(path, "r+") as f: 83 | f_content = apply_template(f.read(), branding_map) 84 | f.seek(0) 85 | f.write(f_content) 86 | f.truncate() # This removes any original content beyond the end of templated content 87 | 88 | 89 | def apply_templating_to_folder(path, branding_map): 90 | """Walks through all contents of folder recursively, and applies templating""" 91 | for root, dirnames, filenames in os.walk(path): 92 | for filename in filenames: 93 | apply_templating_to_file(os.path.join(root, filename), branding_map) 94 | 95 | 96 | # Importable as a library without executing it 97 | if __name__ == "__main__": 98 | if len(sys.argv) != 2: 99 | raise Exception("Usage: branding.py [file or folder name]") 100 | path = sys.argv[1] 101 | 102 | mypath = os.path.dirname(os.path.realpath(__file__)) 103 | branding_values = read_branding_variables( 104 | mypath, BRANDING_ENV_VARIABLE_LIST, BRANDING_ENV_PATH_LIST 105 | ) 106 | 107 | # List of branding values that are allowed to be blank 108 | allowed_blank = ["RELEASELINE"] 109 | # Remove branding values with nothing set so we fail early if they are used in a template 110 | # except for values where blank is explicitly allows 111 | branding_values = { 112 | k: v for k, v in branding_values.items() if k in allowed_blank or v 113 | } 114 | 115 | # Apply templating to files or content of folder 116 | if os.path.isfile(path): 117 | apply_templating_to_file(path, branding_values) 118 | elif os.path.isdir(path): 119 | apply_templating_to_folder(path, branding_values) 120 | else: 121 | raise Exception("Supplied path must be file or directory") 122 | -------------------------------------------------------------------------------- /systemd/jenkins.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | die() { 4 | echo "$(basename "$0"): $*" >&2 5 | exit 1 6 | } 7 | 8 | check_env() { 9 | required=true 10 | for var in "$@"; do 11 | if [ "${var}" = '--' ]; then 12 | required=false 13 | continue 14 | fi 15 | 16 | val=$(eval echo "\$${var}") 17 | if $required && [ -z "${val}" ]; then 18 | die "check_env: ${var} must be non-empty" 19 | fi 20 | done 21 | } 22 | 23 | infer_java_cmd() { 24 | if [ -n "${JENKINS_JAVA_CMD}" ] && [ -x "${JENKINS_JAVA_CMD}" ]; then 25 | return 0 26 | fi 27 | 28 | if [ -n "${JAVA_HOME}" ] && [ -x "${JAVA_HOME}/bin/java" ]; then 29 | JENKINS_JAVA_CMD="${JAVA_HOME}/bin/java" 30 | return 0 31 | fi 32 | 33 | JENKINS_JAVA_CMD="$(command -v java)" || return "$?" 34 | } 35 | 36 | infer_jenkins_opts() { 37 | inferred_jenkins_opts="" 38 | 39 | if [ -n "${JENKINS_WEBROOT}" ]; then 40 | inferred_jenkins_opts="${inferred_jenkins_opts} --webroot='${JENKINS_WEBROOT}'" 41 | fi 42 | 43 | if [ -n "${JENKINS_LOG}" ]; then 44 | inferred_jenkins_opts="${inferred_jenkins_opts} --logfile='${JENKINS_LOG}'" 45 | fi 46 | 47 | if [ -n "${JENKINS_PORT}" ]; then 48 | inferred_jenkins_opts="${inferred_jenkins_opts} --httpPort=${JENKINS_PORT}" 49 | fi 50 | 51 | if [ -n "${JENKINS_LISTEN_ADDRESS}" ]; then 52 | inferred_jenkins_opts="${inferred_jenkins_opts} --httpListenAddress=${JENKINS_LISTEN_ADDRESS}" 53 | fi 54 | 55 | if [ -n "${JENKINS_UNIX_DOMAIN_PATH}" ]; then 56 | inferred_jenkins_opts="${inferred_jenkins_opts} --httpUnixDomainPath=${JENKINS_UNIX_DOMAIN_PATH}" 57 | fi 58 | 59 | if [ -n "${JENKINS_HTTPS_PORT}" ]; then 60 | inferred_jenkins_opts="${inferred_jenkins_opts} --httpsPort=${JENKINS_HTTPS_PORT}" 61 | fi 62 | 63 | if [ -n "${JENKINS_HTTPS_LISTEN_ADDRESS}" ]; then 64 | inferred_jenkins_opts="${inferred_jenkins_opts} --httpsListenAddress=${JENKINS_HTTPS_LISTEN_ADDRESS}" 65 | fi 66 | 67 | if [ -n "${JENKINS_HTTPS_KEYSTORE}" ]; then 68 | inferred_jenkins_opts="${inferred_jenkins_opts} --httpsKeyStore='${JENKINS_HTTPS_KEYSTORE}'" 69 | fi 70 | 71 | if [ -n "${JENKINS_HTTPS_KEYSTORE_PASSWORD}" ]; then 72 | inferred_jenkins_opts="${inferred_jenkins_opts} --httpsKeyStorePassword='${JENKINS_HTTPS_KEYSTORE_PASSWORD}'" 73 | fi 74 | 75 | if [ -n "${JENKINS_HTTP2_PORT}" ]; then 76 | inferred_jenkins_opts="${inferred_jenkins_opts} --http2Port=${JENKINS_HTTP2_PORT}" 77 | fi 78 | 79 | if [ -n "${JENKINS_HTTP2_LISTEN_ADDRESS}" ]; then 80 | inferred_jenkins_opts="${inferred_jenkins_opts} --http2ListenAddress=${JENKINS_HTTP2_LISTEN_ADDRESS}" 81 | fi 82 | 83 | if [ -n "${JENKINS_DEBUG_LEVEL}" ] && [ "${JENKINS_DEBUG_LEVEL}" -ne 5 ]; then 84 | inferred_jenkins_opts="${inferred_jenkins_opts} --debug=${JENKINS_DEBUG_LEVEL}" 85 | fi 86 | 87 | if [ -n "${JENKINS_PREFIX}" ]; then 88 | inferred_jenkins_opts="${inferred_jenkins_opts} --prefix='${JENKINS_PREFIX}'" 89 | fi 90 | 91 | if [ -n "${JENKINS_OPTS}" ]; then 92 | inferred_jenkins_opts="${inferred_jenkins_opts} ${JENKINS_OPTS}" 93 | fi 94 | 95 | if [ -n "${JENKINS_ENABLE_ACCESS_LOG}" ] && $JENKINS_ENABLE_ACCESS_LOG; then 96 | inferred_jenkins_opts="${inferred_jenkins_opts} --accessLoggerClassName=winstone.accesslog.SimpleAccessLogger" 97 | inferred_jenkins_opts="${inferred_jenkins_opts} --simpleAccessLogger.format=combined" 98 | inferred_jenkins_opts="${inferred_jenkins_opts} --simpleAccessLogger.file='/var/log/@@ARTIFACTNAME@@/access_log'" 99 | fi 100 | } 101 | 102 | main() { 103 | if [ -n "${JENKINS_HOME}" ]; then 104 | [ -d "${JENKINS_HOME}" ] || die "${JENKINS_HOME} is not a directory" 105 | fi 106 | [ -f "${JENKINS_WAR}" ] || die "${JENKINS_WAR} is not a file" 107 | 108 | infer_java_cmd || die 'failed to find a valid Java installation' 109 | 110 | infer_jenkins_opts 111 | 112 | java_opts_tmp="${JAVA_OPTS}" 113 | unset JAVA_OPTS 114 | unset JENKINS_DEBUG_LEVEL 115 | unset JENKINS_ENABLE_ACCESS_LOG 116 | unset JENKINS_HTTP2_LISTEN_ADDRESS 117 | unset JENKINS_HTTP2_PORT 118 | unset JENKINS_HTTPS_KEYSTORE 119 | unset JENKINS_HTTPS_KEYSTORE_PASSWORD 120 | unset JENKINS_HTTPS_LISTEN_ADDRESS 121 | unset JENKINS_HTTPS_PORT 122 | java_cmd="${JENKINS_JAVA_CMD}" 123 | unset JENKINS_JAVA_CMD 124 | unset JENKINS_UNIX_DOMAIN_PATH 125 | unset JENKINS_LISTEN_ADDRESS 126 | unset JENKINS_LOG 127 | unset JENKINS_OPTS 128 | unset JENKINS_PORT 129 | unset JENKINS_PREFIX 130 | jenkins_war_tmp="${JENKINS_WAR}" 131 | unset JENKINS_WAR 132 | unset JENKINS_WEBROOT 133 | eval exec \ 134 | "${java_cmd}" \ 135 | ${java_opts_tmp} \ 136 | -jar "${jenkins_war_tmp}" \ 137 | ${inferred_jenkins_opts} 138 | } 139 | 140 | if [ -z "${JENKINS_OPTS}" ]; then 141 | JENKINS_OPTS="$*" 142 | else 143 | JENKINS_OPTS="${JENKINS_OPTS} $*" 144 | fi 145 | 146 | if [ -z "${JENKINS_WAR}" ]; then 147 | JENKINS_WAR=/usr/share/java/@@ARTIFACTNAME@@.war 148 | fi 149 | 150 | check_env \ 151 | JENKINS_WAR \ 152 | -- \ 153 | JAVA_HOME \ 154 | JENKINS_DEBUG_LEVEL \ 155 | JENKINS_ENABLE_ACCESS_LOG \ 156 | JENKINS_HOME \ 157 | JENKINS_HTTP2_LISTEN_ADDRESS \ 158 | JENKINS_HTTP2_PORT \ 159 | JENKINS_HTTPS_KEYSTORE \ 160 | JENKINS_HTTPS_KEYSTORE_PASSWORD \ 161 | JENKINS_HTTPS_LISTEN_ADDRESS \ 162 | JAVA_OPTS \ 163 | JENKINS_HTTPS_PORT \ 164 | JENKINS_JAVA_CMD \ 165 | JENKINS_UNIX_DOMAIN_PATH \ 166 | JENKINS_LISTEN_ADDRESS \ 167 | JENKINS_LOG \ 168 | JENKINS_OPTS \ 169 | JENKINS_PORT \ 170 | JENKINS_PREFIX \ 171 | JENKINS_WEBROOT 172 | 173 | main 174 | 175 | exit 0 176 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% block head %} 10 | {{ os_family | capitalize}} {{product_name | capitalize }} Packages 11 | {% endblock %} 12 | 13 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 | 58 |
59 | 60 |
61 |
62 |
63 |
64 |

{% block title %}{{product_name | capitalize }} {{ os_family | capitalize}} Packages{% endblock %}

65 | 66 | {% block distribution_instruction %}{% endblock %} 67 | 68 | {% block java_instructions %} 69 |

70 | You will need to explicitly install a supported Java runtime environment (JRE), either from your distribution 71 | (as described above) or another Java vendor (e.g., Adoptium). 72 |

73 | 74 |

75 | Weekly Release Line 76 |

77 | 78 |

79 | Supported Java versions for the weekly release line are: 80 |

81 | 82 |
83 |
2.463 (June 2024) and newer
84 |
Java 17 or Java 21
85 | 86 |
2.419 (August 2023) and newer
87 |
Java 11, Java 17, or Java 21
88 | 89 |
2.357 (June 2022) and newer
90 |
Java 11 or Java 17
91 | 92 |
2.164 (February 2019) and newer
93 |
Java 8 or Java 11
94 | 95 |
2.54 (April 2017) and newer
96 |
Java 8
97 | 98 |
1.612 (May 2015) and newer
99 |
Java 7
100 |
101 | 102 |

103 | Long Term Support (LTS) Release Line 104 |

105 | 106 |

107 | Supported Java versions for the LTS release line are: 108 |

109 | 110 |
111 |
2.479.1 (October 2024) and newer
112 |
Java 17 or Java 21
113 | 114 |
2.426.1 (November 2023) and newer
115 |
Java 11, Java 17 or Java 21
116 | 117 |
2.361.1 (September 2022) and newer
118 |
Java 11 or Java 17
119 | 120 |
2.346.1 (June 2022) and newer
121 |
Java 8, Java 11, or Java 17
122 | 123 |
2.164.1 (March 2019) and newer
124 |
Java 8 or Java 11
125 | 126 |
2.60.1 (June 2017) and newer
127 |
Java 8
128 | 129 |
1.625.1 (October 2015) and newer
130 |
Java 7
131 |
132 | {% endblock %} 133 | 134 |

135 | See the installation guide for more information, including how {{ product_name }} is run and where the configuration is stored, etc. 136 |

137 |
138 |
139 |
140 |
141 | 146 |
147 |
148 |
149 |
150 | 151 | 152 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Native package script for Jenkins 2 | 3 | This repository contains scripts for packaging `jenkins.war` into various platform-specific native packages. 4 | The following platforms are currently supported: 5 | 6 | * Windows MSI: `msi/` 7 | * RedHat/CentOS/openSUSE RPM: `rpm/` 8 | * Debian/Ubuntu DEB: `deb/` 9 | 10 | # Pre-requisites 11 | Running the main package script requires a Linux environment (currently Ubuntu, see [JENKINS-27744](https://issues.jenkins-ci.org/browse/JENKINS-27744).) 12 | Run `make setup` to install (most of the) necessary tools. Alternatively you can manually install the following onto a base install of Ubuntu: 13 | * make 14 | * unzip 15 | * devscripts 16 | * debhelper 17 | * rpm 18 | * expect 19 | * createrepo-c 20 | * ruby 21 | * net-sftp (`gem install net-sftp`) 22 | * maven 23 | * java 24 | 25 | You also need a Jenkins instance with [dist-fork plugin](https://wiki.jenkins-ci.org/display/JENKINS/DistFork+Plugin) 26 | installed. URL of this Jenkins can be fed into `make` via the `JENKINS_URL` variable. 27 | This Jenkins needs to have a Windows build agent that has [WiX Toolset](http://wixtoolset.org/) (currently 3.5), msbuild, [cygwin](https://www.cygwin.com/) and .net 2.0. This build agent is used to build MSI packages, which 28 | can be only built on Windows. 29 | 30 | You'll also need a `jenkins.war` file that you are packaging, which comes from the release process. 31 | The location of this file is set via the `WAR` variable. 32 | 33 | Remark: 34 | 35 | A docker image is available to run following script 36 | 37 | [![logo](https://img.shields.io/docker/pulls/jenkinsciinfra/packaging?label=jenkinsciinfra%2Fpackaging&logo=docker&logoColor=white)](https://hub.docker.com/r/jenkinsciinfra/packaging) 38 | 39 | Run `docker-compose run --rm packaging bash` to get a shell in the official Docker image for this repository. 40 | 41 | # Generating packages 42 | Run `./prep.sh` to perform the preparatory actions of downloading the WAR and importing the GPG key. 43 | Run `make package` to build all the native packages. 44 | At minimum, you have to specify the `WAR` variable that points to the war file to be packaged and the `BRAND` variable that points to the branding file for licensing, artifact names, and package descriptions. 45 | If a branding file is not provided, the branding/test.mk file is used with the artifact names and package descriptions it provides. 46 | You will probably need to pass in the build environment and credentials. 47 | 48 | For example: 49 | ```shell 50 | make package BRAND=./branding/jenkins.mk BUILDENV=./env/test.mk CREDENTIAL=./credentials/test.mk 51 | ``` 52 | 53 | Packages will be placed into `target/` directory. 54 | See the definition of the `package` goal for how to build individual packages selectively. 55 | 56 | # Running functional tests 57 | 58 | The functional tests require Python 3 and Docker. 59 | Having built the packages as described above, run the functional tests with: 60 | 61 | ```shell 62 | python3 -m venv venv 63 | source venv/bin/activate 64 | pip install -r requirements.txt 65 | molecule test 66 | deactivate 67 | ``` 68 | 69 | # Publishing packages 70 | This repository contains scripts for copying packages over to a remote web server to publish them. 71 | Run `make publish` to publish all native packages. 72 | 73 | See the definition of the `publish` goal for individual package publishment. 74 | 75 | ## Running local tests 76 | These tests install packages from a web server where they are published. So if you want to 77 | run tests prior to publishing them, you need to create a temporary web server that you can mess up. 78 | 79 | The default branding & environment (`branding/test.mk` and `env/test.mk`) are designed to support 80 | this scenario. To make local testing work, you also need to have `/etc/hosts` entry that maps 81 | `test.pkg.jenkins.io` hostname to `127.0.0.1`, and your computer has to be running ssh that 82 | lets you login as you. 83 | 84 | Once you verified the above prerequisites, open another terminal and run `make test.local.setup` 85 | This will run a docker container that acts as your throw-away package web server. When done, Ctrl+C 86 | to kill it. 87 | 88 | # Branding 89 | `branding/` directory contains `*.mk` files that control the branding of the generated packages. 90 | It also include text files which are used for large, branded text blocks (license and descriptions). 91 | Specify the branding file via the `BRAND` variable. 92 | 93 | You can create your own branding definition to customize the package generation process. 94 | See [branding readme](branding/README.md) for more details. In the rest of the packaging script files, 95 | these branding parameters are referenced via `@@NAME@@` and get substituted by `bin/branding.py`. 96 | To escape a string normally like @@VALUE@@, add an additional two @@ symbols as a prefix: @@@@VALUE@@. 97 | 98 | # Environment 99 | `env/` directory contains `*.mk` files that control the environment into which 100 | you publish packages. Specify the environment file via the `BUILDENV` variable. 101 | 102 | You can create your own environment definition to customize the package generation process. 103 | See [environment readme](env/README.md) for more details. 104 | 105 | # Credentials 106 | `credentials/` directory contains `test.mk` file that controls the locations of code-signing keys, 107 | their passwords, and certificates. Specify the credentials file via the `CREDENTIAL` variable. 108 | 109 | For production use, you need to create your own credentials file. See [credentials readme](credentials/README.md) 110 | for more details. 111 | 112 | # TODO (mostly note to myself) 113 | * Split resource templates to enable customization 114 | -------------------------------------------------------------------------------- /msi/docs/build-msi-locally.md: -------------------------------------------------------------------------------- 1 | # How to build a Jenkins MSI on your Windows machine 2 | 3 | ## Pre-requisites 4 | 5 | ### Jenkins WAR file 6 | 7 | First of all, you should get the Jenkins war file that will be inside that MSI file. 8 | You can get it from the official Jenkins website or from [the Jenkins update center](https://updates.jenkins.io/). 9 | 10 | Check [Jenkins download page](https://www.jenkins.io/download/) and download the latest weekly version of Jenkins for example. 11 | 12 | ### Git 13 | 14 | There are quite a few ways to get Git on Windows, but the most straightforward is to see what the [official Git website recommends](https://git-scm.com/download/win). 15 | 16 | ### Install MSBuild 17 | 18 | You can install [MSBuild](https://aka.ms/vs/17/release/vs_BuildTools.exe) from Visual Studio or from the [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022). 19 | 20 | This command line tool is used to build the MSI file. 21 | 22 | ### Install .NET Framework 3.5 23 | 24 | You may already have it installed on your machine, but not activated. 25 | You can activate it from the Windows Features dialog box. 26 | 27 | To access this dialog box, press the keys ⊞ Win + R, then enter the command `appwiz.cpl` and push enter. 28 | Search for 29 | 30 | > Turn Windows features on or off. 31 | 32 | Tick the `.NET Framework 3.5` entry and install. 33 | 34 | Important: now run Windows Update to check for security updates. 35 | 36 | If it is not installed yet, you can install [.NET Framework 3.5](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net35-sp1) from the Windows Features. 37 | 38 | ### Check if you have PowerShell 39 | 40 | In recent versions of Windows, PowerShell is already installed and accessible through the [terminal](https://support.microsoft.com/en-us/topic/6453ce98-da91-476f-8651-5c14d5777c20#:~:text=In%20Windows%2011%2022H2%2C%20the,an%20instance%20of%20Windows%20Terminal) application. 41 | At the time of writing, the pre-installed version is `5.1.22621.963`. 42 | You can also install the latest version from the [Microsoft Store](https://www.microsoft.com/en-us/p/powershell/9mz1snwt0n5d?activetab=pivot:overviewtab) (7.3.2 at the time of writing). 43 | 44 | ## Build the MSI 45 | 46 | ### Clone the Jenkins packaging repository 47 | 48 | Choose your `git` tool and clone the [Jenkins packaging repository](https://github.com/jenkinsci/packaging.git) on your machine. 49 | 50 | ### Prepare the build 51 | 52 | Open a `terminal` and go to the folder where you cloned the repository. For example `C:\jenkinsci\packaging\`. 53 | You now have to declare where you downloaded the Jenkins war file so the build can find it. 54 | 55 | ```powershell 56 | $env:War = "$env:USERPROFILE\jenkins.war" 57 | ``` 58 | 59 | If you ever moved it into your repository clone folder, you can use this command instead: 60 | 61 | ```powershell 62 | $env:War = "C:\jenkinsci\packaging\msi\build\jenkins.war" 63 | ``` 64 | 65 | ### Build the MSI 66 | 67 | Enter the subfolder `msi\build` and run the following command: 68 | 69 | ```powershell 70 | .\build.ps1 71 | ``` 72 | 73 | You should get an output similar to: 74 | 75 | ```powershell 76 | Extracting components 77 | JenkinsVersion = 2.392 78 | Restoring packages before build 79 | All packages listed in packages.config are already installed. 80 | Building MSI 81 | MSBuild version 17.4.0+18d5aef85 for .NET Framework 82 | Build started 01/12/2022 20:53:30. 83 | Project "C:\jenkinsci\packaging\msi\build\jenkins.wixproj" on node 1 (default targets). 84 | SetConstants: 85 | EncodedVersion = 2.255.3920 86 | Compile: 87 | Skipping target "Compile" because all output files are up-to-date with respect to the input files. 88 | AssignCultures: 89 | Culture: en-US 90 | Link: 91 | C:\jenkinsci\packaging\msi\build\packages\WiX.3.11.1\build\..\tools\Light.exe -out C:\jenkinsci\packaging\msi\build\bi 92 | n\Release\en-US\jenkins-2.392.msi -pdbout C:\jenkinsci\packaging\msi\build\bin\Release\en-US\jenkins-2.392.wixpdb -sw1076 -cultures:en-US -ext C:\S 93 | upport\users\jenkinsci\packaging\packaging\msi\build\packages\WiX.3.11.1\build\..\tools\\WixUIExtension.dll -ext C:\jenkinsci\packaging\msi\bu 94 | ild\packages\WiX.3.11.1\build\..\tools\\WixNetFxExtension.dll -ext C:\jenkinsci\packaging\msi\build\packages\WiX.3.11.1\build\..\tools\\WixUtilExte 95 | nsion.dll -ext .\msiext-1.5\WixExtensions\WixCommonUIExtension.dll -ext C:\jenkinsci\packaging\msi\build\packages\WiX.3.11.1\build\..\tools\\WixFir 96 | ewallExtension.dll -fv -loc jenkins_en-US.wxl -spdb -contentsfile obj\Release\jenkins.wixproj.BindContentsFileListen-US.txt -outputsfile obj\Release\jenkins.wixproj.BindOutputs 97 | FileListen-US.txt -builtoutputsfile obj\Release\jenkins.wixproj.BindBuiltOutputsFileListen-US.txt -wixprojectfile C:\jenkinsci\packaging\msi\build\ 98 | jenkins.wixproj obj\Release\jenkins.wixobj 99 | Windows Installer XML Toolset Linker version 3.11.1.2318 100 | Copyright (c) .NET Foundation and contributors. All rights reserved. 101 | 102 | jenkins -> C:\jenkinsci\packaging\msi\build\bin\Release\en-US\jenkins-2.392.msi 103 | Done Building Project "C:\jenkinsci\packaging\msi\build\jenkins.wixproj" (default targets). 104 | 105 | 106 | Build succeeded. 107 | 0 Warning(s) 108 | 0 Error(s) 109 | 110 | Time Elapsed 00:00:08.26 111 | ``` 112 | 113 | ## Locate the generated MSI file 114 | 115 | The MSI file is located in the `.\bin\Release\en-US\` folder. 116 | You will find there the generated MSI file and its `sha256` file. 117 | 118 | ```powershell 119 | ls 120 | 121 | Directory: C:\jenkinsci\packaging\msi\build\bin\Release\en-US 122 | 123 | 124 | Mode LastWriteTime Length Name 125 | ---- ------------- ------ ---- 126 | -a---- 01/12/2022 20:53 105107456 jenkins-2.392.msi 127 | -a---- 01/12/2022 20:53 84 jenkins-2.392.msi.sha256 128 | ``` 129 | -------------------------------------------------------------------------------- /systemd/jenkins.service: -------------------------------------------------------------------------------- 1 | # 2 | # This file is managed by systemd(1). Do NOT edit this file manually! 3 | # To override these settings, run: 4 | # 5 | # systemctl edit @@ARTIFACTNAME@@ 6 | # 7 | # For more information about drop-in files, see: 8 | # 9 | # https://www.freedesktop.org/software/systemd/man/systemd.unit.html 10 | # 11 | 12 | [Unit] 13 | Description=Jenkins Continuous Integration Server 14 | Requires=network.target 15 | After=network.target 16 | StartLimitBurst=5 17 | StartLimitIntervalSec=5m 18 | 19 | [Service] 20 | Type=notify 21 | NotifyAccess=main 22 | ExecStart=/usr/bin/@@ARTIFACTNAME@@ 23 | Restart=on-failure 24 | SuccessExitStatus=143 25 | 26 | # Configures the time to wait for start-up. If Jenkins does not signal start-up 27 | # completion within the configured time, the service will be considered failed 28 | # and will be shut down again. Takes a unit-less value in seconds, or a time span 29 | # value such as "5min 20s". Pass "infinity" to disable the timeout logic. 30 | #TimeoutStartSec=90 31 | 32 | # Unix account that runs the Jenkins daemon 33 | # Be careful when you change this, as you need to update the permissions of 34 | # $JENKINS_HOME, $JENKINS_LOG, and (if you have already run Jenkins) 35 | # $JENKINS_WEBROOT. 36 | User=@@ARTIFACTNAME@@ 37 | Group=@@ARTIFACTNAME@@ 38 | 39 | # Directory where Jenkins stores its configuration and workspaces 40 | Environment="JENKINS_HOME=/var/lib/@@ARTIFACTNAME@@" 41 | WorkingDirectory=/var/lib/@@ARTIFACTNAME@@ 42 | 43 | # Location of the Jenkins WAR 44 | #Environment="JENKINS_WAR=/usr/share/java/@@ARTIFACTNAME@@.war" 45 | 46 | # Location of the exploded WAR 47 | Environment="JENKINS_WEBROOT=%C/@@ARTIFACTNAME@@/war" 48 | 49 | # Location of the Jenkins log. By default, systemd-journald(8) is used. 50 | #Environment="JENKINS_LOG=%L/@@ARTIFACTNAME@@/@@ARTIFACTNAME@@.log" 51 | 52 | # The Java home directory. When left empty, JENKINS_JAVA_CMD and PATH are consulted. 53 | #Environment="JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64" 54 | 55 | # The Java executable. When left empty, JAVA_HOME and PATH are consulted. 56 | #Environment="JENKINS_JAVA_CMD=/etc/alternatives/java" 57 | 58 | # Arguments for the Jenkins JVM 59 | Environment="JAVA_OPTS=-Djava.awt.headless=true" 60 | 61 | # Unix Domain Socket to listen on for local HTTP requests. Default is disabled. 62 | #Environment="JENKINS_UNIX_DOMAIN_PATH=/run/jenkins/jenkins.socket" 63 | 64 | # IP address to listen on for HTTP requests. 65 | # The default is to listen on all interfaces (0.0.0.0). 66 | #Environment="JENKINS_LISTEN_ADDRESS=" 67 | 68 | # Port to listen on for HTTP requests. Set to -1 to disable. 69 | # To be able to listen on privileged ports (port numbers less than 1024), 70 | # add the CAP_NET_BIND_SERVICE capability to the AmbientCapabilities 71 | # directive below. 72 | Environment="JENKINS_PORT=@@PORT@@" 73 | 74 | # IP address to listen on for HTTPS requests. Default is disabled. 75 | #Environment="JENKINS_HTTPS_LISTEN_ADDRESS=" 76 | 77 | # Port to listen on for HTTPS requests. Default is disabled. 78 | # To be able to listen on privileged ports (port numbers less than 1024), 79 | # add the CAP_NET_BIND_SERVICE capability to the AmbientCapabilities 80 | # directive below. 81 | #Environment="JENKINS_HTTPS_PORT=443" 82 | 83 | # Path to the keystore in JKS format (as created by the JDK's keytool). 84 | # Default is disabled. 85 | #Environment="JENKINS_HTTPS_KEYSTORE=/path/to/keystore.jks" 86 | 87 | # Password to access the keystore defined in JENKINS_HTTPS_KEYSTORE. 88 | # Default is disabled. 89 | #Environment="JENKINS_HTTPS_KEYSTORE_PASSWORD=s3cR3tPa55w0rD" 90 | 91 | # IP address to listen on for HTTP2 requests. Default is disabled. 92 | #Environment="JENKINS_HTTP2_LISTEN_ADDRESS=" 93 | 94 | # HTTP2 port to listen on. Default is disabled. 95 | # To be able to listen on privileged ports (port numbers less than 1024), 96 | # add the CAP_NET_BIND_SERVICE capability to the AmbientCapabilities 97 | # directive below. 98 | #Environment="JENKINS_HTTP2_PORT=" 99 | 100 | # Controls which capabilities to include in the ambient capability set for the 101 | # executed process. Takes a whitespace-separated list of capability names, e.g. 102 | # CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, CAP_SYS_PTRACE. Ambient capability sets are 103 | # useful if you want to execute a process as a non-privileged user but still 104 | # want to give it some capabilities. For example, add the CAP_NET_BIND_SERVICE 105 | # capability to be able to listen on privileged ports (port numbers less than 106 | # 1024). 107 | #AmbientCapabilities=CAP_NET_BIND_SERVICE 108 | 109 | # Debug level for logs. The higher the value, the more verbose. 5 is INFO. 110 | #Environment="JENKINS_DEBUG_LEVEL=5" 111 | 112 | # Set to true to enable logging to /var/log/@@ARTIFACTNAME@@/access_log. 113 | #Environment="JENKINS_ENABLE_ACCESS_LOG=false" 114 | 115 | # Servlet context (important if you want to use reverse proxying) 116 | #Environment="JENKINS_PREFIX=/@@ARTIFACTNAME@@" 117 | 118 | # Arbitrary additional arguments to pass to Jenkins. 119 | # Full option list: java -jar @@ARTIFACTNAME@@.war --help 120 | #Environment="JENKINS_OPTS=" 121 | 122 | # Maximum core file size. If unset, the value from the OS is inherited. 123 | #LimitCORE=infinity 124 | 125 | # Maximum file size. If unset, the value from the OS is inherited. 126 | #LimitFSIZE=infinity 127 | 128 | # File descriptor limit. If unset, the value from the OS is inherited. 129 | #LimitNOFILE=8192 130 | 131 | # Maximum number of processes. If unset, the value from the OS is inherited. 132 | #LimitNPROC=32768 133 | 134 | # Set the umask to control the permission bits of files that Jenkins creates. 135 | # 136 | # 0027 makes files read-only for group and inaccessible for others, which some 137 | # security sensitive users might consider beneficial, especially if Jenkins 138 | # is running on a server that is used for multiple purposes. Beware that 0027 139 | # permissions would interfere with sudo scripts that run on the controller 140 | # (see JENKINS-25065). 141 | # 142 | # Note also that the particularly sensitive parts of $JENKINS_HOME (such as 143 | # credentials) are always written without 'other' access. So the umask values 144 | # only affect job configuration, build records, etc. 145 | # 146 | # If unset, the value from the OS is inherited, which is normally 0022. 147 | # The default umask comes from pam_umask(8) and /etc/login.defs. 148 | #UMask=0022 149 | 150 | [Install] 151 | WantedBy=multi-user.target 152 | -------------------------------------------------------------------------------- /deb/build/debian/jenkins.init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env /lib/init/init-d-script 2 | # /etc/init.d/jenkins 3 | # debian-compatible jenkins startup script. 4 | # Amelia A Lewis 5 | # 6 | ### BEGIN INIT INFO 7 | # Provides: @@ARTIFACTNAME@@ 8 | # Required-Start: $remote_fs $syslog $network 9 | # Required-Stop: $remote_fs $syslog $network 10 | # Default-Start: 2 3 4 5 11 | # Default-Stop: 0 1 6 12 | # Short-Description: Start @@PRODUCTNAME@@ at boot time 13 | # Description: Controls @@SUMMARY@@ 14 | ### END INIT INFO 15 | 16 | DAEMON=none 17 | COMMAND_NAME=java 18 | NAME="@@ARTIFACTNAME@@" 19 | DESC="@@SUMMARY@@" 20 | 21 | check_arguments() { 22 | # Exit if not supposed to run standalone 23 | if [ "${RUN_STANDALONE}" = "false" ]; then 24 | echo "ERROR: Not configured to run standalone" >&2 25 | return 2 26 | fi 27 | 28 | # Make sure there exists a java executable, it may not be always the case 29 | JAVA=$(command -v "${COMMAND_NAME}") 30 | if [ -z "${JAVA}" ]; then 31 | echo "ERROR: No Java executable found in current PATH: ${PATH}" >&2 32 | echo "If you actually have Java installed on the system make sure the executable is in the aforementioned path and that 'command -v ${COMMAND_NAME}' returns the Java executable path" >&2 33 | return 2 34 | fi 35 | 36 | # Make sure we run as root, since setting the max open files through 37 | # ulimit requires root access 38 | if [ "$(id -u)" -gt 0 ]; then 39 | echo "The ${NAME} init script can only be run as root" >&2 40 | return 2 41 | fi 42 | } 43 | 44 | check_tcp_port() { 45 | service=$1 46 | assigned=$2 47 | default=$3 48 | assigned_address=$4 49 | default_address=$5 50 | 51 | if [ -n "${assigned}" ]; then 52 | port=${assigned} 53 | else 54 | port=${default} 55 | fi 56 | 57 | if [ -n "${assigned_address}" ]; then 58 | address=${assigned_address} 59 | else 60 | address=${default_address} 61 | fi 62 | 63 | count=$(netstat --listen --numeric-ports | grep "${address}:${port}[[:space:]]" | grep -c .) 64 | 65 | if [ "${count}" -gt 0 ]; then 66 | echo "The selected ${service} port (${port}) on address ${address} seems to be in use by another program " 67 | echo "Please select another address/port combination to use for ${NAME}" 68 | return 2 69 | fi 70 | } 71 | 72 | do_start_cmd_override() { 73 | check_arguments || return "$?" 74 | 75 | # load environments 76 | if [ -r /etc/default/locale ]; then 77 | . /etc/default/locale 78 | export LANG LANGUAGE 79 | elif [ -r /etc/environment ]; then 80 | . /etc/environment 81 | export LANG LANGUAGE 82 | fi 83 | export JENKINS_HOME 84 | 85 | # the default location is /var/run/jenkins/jenkins.pid but the parent directory needs to be created 86 | mkdir -p "$(dirname "${PIDFILE}")" || return 2 87 | chown "${JENKINS_USER}" "$(dirname "${PIDFILE}")" || return 2 88 | 89 | # Verify that the jenkins port is not already in use, winstone does not exit 90 | # even for BindException 91 | check_tcp_port "http" "${HTTP_PORT}" "@@PORT@@" "${HTTP_HOST}" "0.0.0.0" || return 2 92 | 93 | # If the var MAXOPENFILES is enabled in /etc/default/jenkins then set the max open files to the 94 | # proper value 95 | if [ -n "${MAXOPENFILES}" ]; then 96 | [ "${VERBOSE}" != no ] && echo "Setting up max open files limit to ${MAXOPENFILES}" 97 | ulimit -n "${MAXOPENFILES}" || return 2 98 | fi 99 | # notify of explicit umask 100 | if [ -n "${UMASK}" ]; then 101 | [ "${VERBOSE}" != no ] && echo "Setting umask to ${UMASK}" 102 | fi 103 | 104 | # enable access log 105 | if [ "${JENKINS_ENABLE_ACCESS_LOG}" = "yes" ]; then 106 | JENKINS_ARGS="${JENKINS_ARGS} --accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=/var/log/${NAME}/access_log" 107 | fi 108 | 109 | # start-stop-daemon --chuid/--group doesn't prepare environment variables 110 | # like HOME, USER, LOGNAME or USERNAME, so re-export these 111 | SHELL=$(awk -F: "\$1 == \"${JENKINS_USER}\" {print \$NF}" /etc/passwd) 112 | [ -n "${SHELL}" ] || SHELL=/bin/bash 113 | HOME="${JENKINS_HOME}" \ 114 | SHELL="${SHELL}" \ 115 | USER="${JENKINS_USER}" \ 116 | LOGNAME="${JENKINS_USER}" \ 117 | USERNAME="${JENKINS_USER}" \ 118 | PWD="${JENKINS_HOME}" \ 119 | eval \ 120 | start-stop-daemon \ 121 | --start \ 122 | --quiet \ 123 | --oknodo \ 124 | --background \ 125 | --no-close \ 126 | --make-pidfile \ 127 | --pidfile "${PIDFILE}" \ 128 | --chdir "${JENKINS_HOME}" \ 129 | --chuid "${JENKINS_USER}" \ 130 | --user "${JENKINS_USER}" \ 131 | --group "${JENKINS_GROUP}" \ 132 | --name "${COMMAND_NAME}" \ 133 | --exec "${JAVA}" \ 134 | ${UMASK:+--umask ${UMASK}} \ 135 | -- ${JAVA_ARGS} -jar "${JENKINS_WAR}" ${JENKINS_ARGS} >>"${JENKINS_LOG}" 2>&1 136 | RETVAL="$?" 137 | [ "${RETVAL}" = 2 ] && return 2 138 | # Verify the process did in fact start successfully and didn't just bomb out 139 | sleep 1 140 | ATTEMPT=1 141 | while [ ${ATTEMPT} -le 30 ]; do 142 | pidofproc -p "${PIDFILE}" "${JAVA}" >/dev/null && break 143 | [ "${ATTEMPT}" = 30 ] && return 2 144 | sleep 1 145 | ATTEMPT=$((ATTEMPT + 1)) 146 | done 147 | return "${RETVAL}" 148 | } 149 | 150 | do_stop_cmd_override() { 151 | check_arguments || return "$?" 152 | start-stop-daemon \ 153 | --stop \ 154 | --quiet \ 155 | --oknodo \ 156 | --pidfile "${PIDFILE}" \ 157 | --chdir "${JENKINS_HOME}" \ 158 | --chuid "${JENKINS_USER}" \ 159 | --user "${JENKINS_USER}" \ 160 | --group "${JENKINS_GROUP}" \ 161 | --name "${COMMAND_NAME}" \ 162 | --exec "${JAVA}" \ 163 | --retry=TERM/30/KILL/5 164 | RETVAL="$?" 165 | [ "${RETVAL}" = 2 ] && return 2 166 | # Wait for children to finish too if this is a daemon that forks 167 | # and if the daemon is only ever run from this initscript. 168 | # If the above conditions are not satisfied then add some other code 169 | # that waits for the process to drop all resources that could be 170 | # needed by services started subsequently. A last resort is to 171 | # sleep for some time. 172 | start-stop-daemon \ 173 | --stop \ 174 | --quiet \ 175 | --oknodo \ 176 | --pidfile "${PIDFILE}" \ 177 | --chdir "${JENKINS_HOME}" \ 178 | --chuid "${JENKINS_USER}" \ 179 | --user "${JENKINS_USER}" \ 180 | --group "${JENKINS_GROUP}" \ 181 | --name "${COMMAND_NAME}" \ 182 | --exec "${JAVA}" \ 183 | --retry=0/30/KILL/5 184 | [ "$?" = 2 ] && return 2 185 | # Many daemons don't delete their pidfiles when they exit. 186 | rm -f "${PIDFILE}" 187 | return "${RETVAL}" 188 | } 189 | 190 | do_status_override() { 191 | check_arguments || return "$?" 192 | status_of_proc "${JAVA}" "${NAME}" -p "${PIDFILE}" 193 | } 194 | -------------------------------------------------------------------------------- /msi/build/build.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [String] $War = $env:WAR, 4 | [string] $MSBuildPath = '', 5 | [bool] $UseTracing = $false, 6 | [String] $ProductName = $env:PRODUCTNAME, 7 | [String] $ProductSummary = $env:SUMMARY, 8 | [String] $ProductVendor = $env:VENDOR, 9 | [String] $ArtifactName = $env:ARTIFACTNAME, 10 | [String] $BannerBmp = '', 11 | [String] $DialogBmp = '', 12 | [String] $InstallerIco = '' 13 | ) 14 | 15 | function Set-CodeSigningSignature { 16 | param ( 17 | $Path, 18 | $JenkinsVersion 19 | ) 20 | 21 | if((-not ([System.String]::IsNullOrWhiteSpace($env:PKCS12_FILE)) -and (Test-Path $env:PKCS12_FILE)) -and (-not [System.String]::IsNullOrWhiteSpace($env:SIGN_STOREPASS))) { 22 | Write-Host "Signing $Path" 23 | # always disable tracing here 24 | Set-PSDebug -Trace 0 25 | $retries = 10 26 | $i = $retries 27 | # Create an array of timestamp servers that includes each of the known timestamp servers duplicated $retries times so that the list won't be exhausted during retry 28 | # Start with digicert because we purchased the code signing certificate from digicert 29 | $timestampservers = "http://timestamp.digicert.com", "http://rfc3161timestamp.globalsign.com/advanced", "http://timestamp.sectigo.com/", "http://timestamp.verisign.com/scripts/timstamp.dll" * $retries 30 | for(; $i -gt 0; $i--) { 31 | # Pop first entry from timestamp server array, use it as timestamp server for this attempt 32 | $timestamp, $timestampservers = $timestampservers 33 | # Submit SHA256 digest to RFC 3161 timestamp server 34 | $p = Start-Process -Wait -PassThru -NoNewWindow -FilePath "signtool.exe" -ArgumentList "sign /v /f `"${env:PKCS12_FILE}`" /p ${env:SIGN_STOREPASS} /tr $timestamp /td SHA256 /fd SHA256 /d `"Jenkins Automation Server ${JenkinsVersion}`" /du `"https://jenkins.io`" $Path" 35 | $p.WaitForExit() 36 | # we will retry up to $retries times until we get a good exit code 37 | if($p.ExitCode -eq 0) { 38 | break 39 | } else { 40 | Start-Sleep -Seconds 15 41 | } 42 | } 43 | 44 | if($i -le 0) { 45 | Write-Error "signtool did not complete successfully after $retries tries" 46 | exit -1 47 | } 48 | 49 | if($UseTracing) { Set-PSDebug -Trace 1 } 50 | 51 | Write-Host "Checking the signature" 52 | # It will print the entire certificate chain with details 53 | signtool verify /v /pa /all $Path 54 | } 55 | } 56 | 57 | if($UseTracing) { Set-PSDebug -Trace 1 } 58 | 59 | if([String]::IsNullOrWhiteSpace($War)) { 60 | Write-Error "Missing jenkins WAR path" 61 | exit 1 62 | } 63 | 64 | $ErrorActionPreference = "Stop" 65 | 66 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 67 | 68 | Add-Type -Assembly System.IO.Compression.FileSystem 69 | 70 | $tmpDir = Join-Path $PSScriptRoot "tmp" 71 | 72 | if(!(Test-Path $tmpDir)) { 73 | New-Item -ItemType Directory -Path $tmpDir -Force -Confirm:$false | Out-Null 74 | } else { 75 | Get-ChildItem tmp\* | Remove-Item -Force 76 | } 77 | 78 | if(!(Test-Path (Join-Path $PSScriptRoot 'msiext-1.5/WixExtensions/WixCommonUiExtension.dll'))) { 79 | Invoke-WebRequest -Uri "https://github.com/dblock/msiext/releases/download/1.5/msiext-1.5.zip" -OutFile (Join-Path $PSScriptRoot 'msiext-1.5.zip') -UseBasicParsing 80 | [IO.Compression.ZipFile]::ExtractToDirectory((Join-Path $PSScriptRoot 'msiext-1.5.zip'), $PSScriptRoot) 81 | } 82 | 83 | Write-Host "Extracting components" 84 | if($UseTracing) { Set-PSDebug -Trace 0 } 85 | # get the components we need from the war file 86 | 87 | $maniFestFile = Join-Path $tmpDir "MANIFEST.MF" 88 | $zip = [IO.Compression.ZipFile]::OpenRead($War) 89 | $zip.Entries | Where-Object {$_.Name -like 'MANIFEST.MF'} | ForEach-Object { [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $maniFestFile, $true)} 90 | 91 | $JenkinsVersion = $(Get-Content $maniFestFile | Select-String -Pattern "^Jenkins-Version:\s*(.*)" | ForEach-Object { $_.Matches } | ForEach-Object { $_.Groups[1].Value } | Select-Object -First 1) 92 | Write-Host "JenkinsVersion = $JenkinsVersion" 93 | 94 | $zip.Entries | Where-Object {$_.Name -like "jenkins-core-${JenkinsVersion}.jar"} | ForEach-Object {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, [System.IO.Path]::Combine($tmpDir, "core.jar"), $true)} 95 | $zip.Dispose() 96 | 97 | $zip = [IO.Compression.ZipFile]::OpenRead([System.IO.Path]::Combine($tmpDir, 'core.jar')) 98 | $zip.Entries | Where-Object {$_.Name -like 'jenkins.exe'} | ForEach-Object {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, [System.IO.Path]::Combine($tmpDir, "jenkins.exe"), $true)} 99 | $zip.Dispose() 100 | 101 | $zip = [IO.Compression.ZipFile]::OpenRead([System.IO.Path]::Combine($tmpDir, 'core.jar')) 102 | $zip.Entries | Where-Object {$_.Name -like 'jenkins.xml'} | ForEach-Object {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, [System.IO.Path]::Combine($tmpDir, "jenkins.xml"), $true)} 103 | $zip.Dispose() 104 | if($UseTracing) { Set-PSDebug -Trace 1 } 105 | 106 | $isLts = $JenkinsVersion.Split('.').Length -gt 2 107 | 108 | Write-Host "Restoring packages before build" 109 | # restore the Wix package 110 | & "./nuget.exe" restore -PackagesDirectory "packages" 111 | 112 | Write-Host "Building MSI" 113 | if($MSBuildPath -ne '') { 114 | if($MSBuildPath.ToLower().EndsWith('msbuild.exe')) { 115 | $MSBuildPath = [System.IO.Path]::GetDirectoryName($MSBuildPath) 116 | } 117 | $env:PATH = $env:PATH + ";" + $MSBuildPath 118 | } else { 119 | # try to find it with vswhere 120 | $MSBuildPath = & 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -products * -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe 121 | if(($MSBuildPath -ne '') -and $MSBuildPath.ToLower().EndsWith('msbuild.exe')) { 122 | $MSBuildPath = [System.IO.Path]::GetDirectoryName($MSBuildPath) 123 | } 124 | $env:PATH = $env:PATH + ";" + $MSBuildPath 125 | } 126 | 127 | # Sign the Update-JenkinsVersion.ps1 script if we have PKCS files 128 | Copy-Item -Force -Path .\Update-JenkinsVersion.ps1 -Destination tmp 129 | Set-CodeSigningSignature -Path .\tmp\Update-JenkinsVersion.ps1 -JenkinsVersion $JenkinsVersion 130 | 131 | msbuild "jenkins.wixproj" /p:Stable="${isLts}" /p:WAR="${War}" /p:Configuration=Release /p:DisplayVersion=$JenkinsVersion /p:ProductName="${ProductName}" /p:ProductSummary="${ProductSummary}" /p:ProductVendor="${ProductVendor}" /p:ArtifactName="${ArtifactName}" /p:BannerBmp="${BannerBmp}" /p:DialogBmp="${DialogBmp}" /p:InstallerIco="${InstallerIco}" 132 | 133 | Get-ChildItem .\bin\Release -Filter *.msi -Recurse | 134 | Foreach-Object { 135 | Set-CodeSigningSignature -Path $($_.FullName) -JenkinsVersion $JenkinsVersion 136 | 137 | $sha256 = (Get-FileHash -Algorithm SHA256 -Path $_.FullName).Hash.ToString().ToLower() 138 | Set-Content -Path "$($_.FullName).sha256" -Value "$sha256 $($_.Name)" -Force 139 | $env:MSI_SHA256 = $sha256 140 | } 141 | 142 | if ($UseTracing) { Set-PSDebug -Trace 0 } 143 | -------------------------------------------------------------------------------- /msi/build/jenkins.wixproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 3.5 8 | {49c7ae2b-d9d1-4b32-9d11-474f1be86658} 9 | 2.0 10 | False 11 | jenkins-$(DisplayVersion) 12 | jenkins-$(DisplayVersion)-stable 13 | Package 14 | true 15 | True 16 | false 17 | 1076 18 | en-US 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 1 && int.TryParse(items[1], out minor) && minor > 255) { 33 | EncodedVersion = string.Format("{0}.255.{1}", items[0], minor * 10); 34 | } else { 35 | EncodedVersion = string.Format("{0}.0", DisplayVersion); 36 | } 37 | } else { 38 | int minor = 0; 39 | if(int.TryParse(items[1], out minor) && minor > 255) { 40 | EncodedVersion = string.Format("{0}.255.{1}", items[0], (minor * 10) + int.Parse(items[2])); 41 | } else { 42 | EncodedVersion = string.Format("{0}.{1}.{2}", items[0], items[1], int.Parse(items[2])); 43 | } 44 | } 45 | ]]> 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | $(EncodedVersion) 64 | 65 | 66 | {415933D8-4104-47C3-AEE9-66B31DE07A57} 67 | 68 | 69 | $(DisplayVersion) 70 | 71 | 72 | tmp\jenkins.war 73 | 74 | 75 | $(WAR) 76 | 77 | 78 | 79 | Jenkins 80 | 81 | 82 | $(ProductName) 83 | 84 | 85 | 86 | Jenkins Automation Server 87 | 88 | 89 | $(ProductSummary) 90 | 91 | 92 | 93 | Jenkins Project 94 | 95 | 96 | $(ProductVendor) 97 | 98 | 99 | 100 | Jenkins 101 | 102 | 103 | $(ArtifactName) 104 | 105 | 106 | 107 | 108 | jenkins.ico 109 | 110 | 111 | $(InstallerIco) 112 | 113 | 114 | 115 | jenkins.bmp 116 | 117 | 118 | $(DialogBmp) 119 | 120 | 121 | 122 | banner.bmp 123 | 124 | 125 | $(BannerBmp) 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | bin\$(Configuration)\ 144 | obj\$(Configuration)\ 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | $(WixExtDir)\WixUIExtension.dll 158 | WixUIExtension 159 | 160 | 161 | $(WixExtDir)\WixNetFxExtension.dll 162 | WixNetFxExtension 163 | 164 | 165 | $(WixExtDir)\WixUtilExtension.dll 166 | WixUtilExtension 167 | 168 | 169 | .\msiext-1.5\WixExtensions\WixCommonUIExtension.dll 170 | WixCommonUIExtension 171 | 172 | 173 | $(WixExtDir)\WixFirewallExtension.dll 174 | WixCommonUIExtension 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /msi/build/Update-JenkinsVersion.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Upgrades the version information in the register from the current Jenkins war file. 4 | .Description 5 | The purpose of this script is to update the version of Jenkins in the registry 6 | when the user may have upgraded the war file in place. The script probes the 7 | registry for information about the Jenkins install (path to war, etc.) and 8 | then grabs the version information from the war to update the values in the 9 | registry so they match the version of the war file. 10 | 11 | This will help with security scanners that look in the registry for versions 12 | of software and flag things when they are too low. The information in the 13 | registry may be very old compared to what version of the war file is 14 | actually installed on the system. 15 | #> 16 | 17 | 18 | # Self-elevate the script if required 19 | if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) { 20 | # We may be running under powershell.exe or pwsh.exe, make sure we relaunch the same one. 21 | $Executable = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName 22 | if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) { 23 | # Launching with RunAs to get elevation 24 | $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments 25 | Start-Process -FilePath $Executable -Verb Runas -ArgumentList $CommandLine 26 | Exit 27 | } 28 | } 29 | 30 | function New-TemporaryDirectory { 31 | $Parent = [System.IO.Path]::GetTempPath() 32 | do { 33 | $Name = [System.IO.Path]::GetRandomFileName() 34 | $Item = New-Item -Path $Parent -Name $Name -ItemType "Directory" -ErrorAction SilentlyContinue 35 | } while (-not $Item) 36 | return $Item.FullName 37 | } 38 | 39 | function Exit-Script($Message, $Fatal = $False) { 40 | $ExitCode = 0 41 | if($Fatal) { 42 | Write-Error $Message 43 | } else { 44 | Write-Host $Message 45 | } 46 | Read-Host "Press ENTER to continue" 47 | Exit $ExitCode 48 | } 49 | 50 | # Let's find the location of the war file... 51 | $JenkinsDir = Get-ItemPropertyValue -Path HKLM:\Software\Jenkins\InstalledProducts\Jenkins -Name InstallLocation -ErrorAction SilentlyContinue 52 | 53 | if (($Null -eq $JenkinsDir) -or [String]::IsNullOrWhiteSpace($JenkinsDir)) { 54 | Exit-Script -Message "Jenkins does not seem to be installed. Please verify you have previously installed using the MSI installer" -Fatal $True 55 | } 56 | 57 | $WarPath = Join-Path $JenkinsDir "jenkins.war" 58 | if(-Not (Test-Path $WarPath)) { 59 | Exit-Script -Message "Could not find war file at location found in registry, please verify Jenkins installation" -Fatal $True 60 | } 61 | 62 | # Get the MANIFEST.MF file from the war file to get the version of Jenkins 63 | $TempWorkDir = New-TemporaryDirectory 64 | $ManifestFile = Join-Path $TempWorkDir "MANIFEST.MF" 65 | $Zip = [IO.Compression.ZipFile]::OpenRead($WarPath) 66 | $Zip.Entries | Where-Object { $_.Name -like "MANIFEST.MF" } | ForEach-Object { [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $ManiFestFile, $True) } 67 | $Zip.Dispose() 68 | 69 | $JenkinsVersion = $(Get-Content $ManiFestFile | Select-String -Pattern "^Jenkins-Version:\s*(.*)" | ForEach-Object { $_.Matches } | ForEach-Object { $_.Groups[1].Value } | Select-Object -First 1) 70 | Remove-Item -Path $ManifestFile 71 | 72 | # Convert the Jenkins version into what should be in the registry 73 | $VersionItems = $JenkinsVersion.Split(".") | ForEach-Object { [int]::Parse($_) } 74 | 75 | # Use the same encoding algorithm as the installer to encode the version into the correct format 76 | $RegistryEncodedVersion = 0 77 | $Major = $VersionItems[0] 78 | if ($VersionItems.Length -le 2) { 79 | $Minor = 0 80 | if (($VersionItems.Length -gt 1) -and ($VersionItems[1] -gt 255)) { 81 | $Minor = $VersionItems[1] 82 | $RegistryEncodedVersion = $RegistryEncodedVersion -bor ((($Major -band 0xff) -shl 24) -bor 0x00ff0000 -bor (($Minor * 10) -band 0x0000ffff)) 83 | } 84 | else { 85 | $RegistryEncodedVersion = $RegistryEncodedVersion -bor (($Major -band 0xff) -shl 24) 86 | } 87 | } 88 | else { 89 | $Minor = $VersionItems[1] 90 | if ($Minor -gt 255) { 91 | $RegistryEncodedVersion = $RegistryEncodedVersion -bor ((($Major -band 0xff) -shl 24) -bor 0x00ff0000 -bor ((($Minor * 10) + $VersionItems[2]) -band 0x0000ffff)) 92 | } 93 | else { 94 | $RegistryEncodedVersion = $RegistryEncodedVersion -bor ((($Major -band 0xff) -shl 24) -bor (($Minor -band 0xff) -shl 16) -bor ($VersionItems[2] -band 0x0000ffff)) 95 | } 96 | } 97 | 98 | $ProductName = "Jenkins $JenkinsVersion" 99 | 100 | # Find the registry key for Jenkins in the Installer\Products area and CurrentVersion\Uninstall 101 | $JenkinsProductsRegistryKey = Get-ChildItem -Path HKLM:\SOFTWARE\Classes\Installer\Products | Where-Object { $_.GetValue("ProductName", "").StartsWith("Jenkins") } 102 | 103 | $JenkinsUninstallRegistryKey = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | Where-Object { $_.GetValue("DisplayName", "").StartsWith("Jenkins") } 104 | 105 | if (($Null -eq $JenkinsProductsRegistryKey) -or ($Null -eq $JenkinsUninstallRegistryKey)) { 106 | Exit-Script -Message "Could not find the product information for Jenkins" -Fatal $True 107 | } 108 | 109 | # Update the Installer\Products area 110 | $RegistryPath = $JenkinsProductsRegistryKey.Name.Substring($JenkinsProductsRegistryKey.Name.IndexOf("\")) 111 | 112 | $OldProductName = $JenkinsProductsRegistryKey.GetValue("ProductName", "") 113 | if ($OldProductName -ne $ProductName) { 114 | Set-ItemProperty -Path HKLM:$RegistryPath -Name "ProductName" -Type String -Value $ProductName 115 | } 116 | 117 | $OldVersion = $JenkinsProductsRegistryKey.GetValue("Version", 0) 118 | if ($OldVersion -ne $RegistryEncodedVersion) { 119 | Set-ItemProperty -Path HKLM:$RegistryPath -Name "Version" -Type DWord -Value $RegistryEncodedVersion 120 | } 121 | 122 | # Update the Uninstall area 123 | $RegistryPath = $JenkinsUninstallRegistryKey.Name.Substring($JenkinsUninstallRegistryKey.Name.IndexOf("\")) 124 | $OldDisplayName = $JenkinsUninstallRegistryKey.GetValue("DisplayName", "") 125 | if ($OldDisplayName -ne $ProductName) { 126 | Set-ItemProperty -Path HKLM:$RegistryPath -Name "DisplayName" -Type String -Value $ProductName 127 | } 128 | 129 | $OldDisplayVersion = $JenkinsUninstallRegistryKey.GetValue("DisplayVersion", "") 130 | $DisplayVersion = "{0}.{1}.{2}" -f ($RegistryEncodedVersion -shr 24), (($RegistryEncodedVersion -shr 16) -band 0xff), ($RegistryEncodedVersion -band 0xffff) 131 | if ($OldDisplayVersion -ne $DisplayVersion) { 132 | Set-ItemProperty -Path HKLM:$RegistryPath -Name "DisplayVersion" -Type String -Value $DisplayVersion 133 | } 134 | 135 | $OldVersion = $JenkinsUninstallRegistryKey.GetValue("Version", 0) 136 | if ($OldVersion -ne $RegistryEncodedVersion) { 137 | Set-ItemProperty -Path HKLM:$RegistryPath -Name "Version" -Type DWord -Value $RegistryEncodedVersion 138 | } 139 | 140 | $OldVersionMajor = $JenkinsUninstallRegistryKey.GetValue("VersionMajor", 0) 141 | $VersionMajor = $RegistryEncodedVersion -shr 24 142 | if ($OldVersionMajor -ne $VersionMajor) { 143 | 144 | Set-ItemProperty -Path HKLM:$RegistryPath -Name "VersionMajor" -Type DWord -Value $VersionMajor 145 | } 146 | 147 | $OldVersionMinor = $JenkinsUninstallRegistryKey.GetValue("VersionMinor", 0) 148 | $VersionMinor = ($RegistryEncodedVersion -shr 16) -band 0xff 149 | if ($OldVersionMinor -ne $VersionMinor) { 150 | Set-ItemProperty -Path HKLM:$RegistryPath -Name "VersionMinor" -Type DWord -Value $VersionMinor 151 | } 152 | 153 | Read-Host "Press ENTER to continue" 154 | -------------------------------------------------------------------------------- /bin/indexGenerator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import getopt 4 | import jinja2 5 | import os 6 | import pathlib 7 | import sys 8 | 9 | 10 | def basename(path): 11 | return os.path.basename(path) 12 | 13 | 14 | class IndexGenerator: 15 | DISTRIBUTIONS = { 16 | "debian": { 17 | "extension": ".deb", 18 | "template": "header.debian.html", 19 | "web_url": os.getenv("DEB_URL"), 20 | }, 21 | "rpm": { 22 | "extension": ".rpm", 23 | "template": "header.rpm.html", 24 | "web_url": os.getenv("RPM_URL"), 25 | }, 26 | "war": {"extension": ".war", "template": "header.war.html", "web_url": "unset"}, 27 | "windows": { 28 | "extension": ".msi", 29 | "template": "header.msi.html", 30 | "web_url": "unset", 31 | }, 32 | } 33 | 34 | HELP_MESSAGE = """ 35 | Generate header.html for package distribution site 36 | It supports debian and rpm packages 37 | 38 | indexGenerator.py 39 | -d : Which package distribution to target 40 | -o : Where to create the HEADER.html 41 | 42 | ex: 43 | indexGenerator.py 44 | -d debian 45 | -o /packages/website/debian 46 | """ 47 | 48 | packages = [] 49 | targetFile = "" 50 | template_file = "" 51 | template_directory = "templates" 52 | repositories = [] 53 | 54 | def __init__(self, argv): 55 | 56 | self.artifact = os.getenv("ARTIFACTNAME", "jenkins") 57 | self.releaseline = os.getenv("RELEASELINE", "") 58 | self.download_url = os.getenv("URL", "null") 59 | self.organization = os.getenv("ORGANIZATION", "jenkins.io") 60 | self.product_name = os.getenv("PRODUCTNAME", "Jenkins") 61 | self.distribution = os.getenv("OS_FAMILY", "debian") 62 | self.gpg_pub_key_info_file = os.getenv("GPGPUBKEYINFO", ".") 63 | self.gpg_public_key_filename = os.getenv("GPG_PUBLIC_KEY_FILENAME", "jenkins.io.key") 64 | self.target_directory = "./target/" + self.distribution 65 | 66 | try: 67 | opts, args = getopt.getopt( 68 | argv, "hd:o:", ["targetDir=", "distribution=", "gpg-key-info-file="] 69 | ) 70 | except getopt.GetoptError: 71 | print(self.HELP_MESSAGE) 72 | sys.exit(2) 73 | for opt, arg in opts: 74 | if opt == "-h": 75 | print(self.HELP_MESSAGE) 76 | sys.exit() 77 | elif opt in ("-d", "--distribution"): 78 | self.distribution = arg 79 | self.target_directory = "./target/" + self.distribution 80 | os.makedirs(self.target_directory, exist_ok=True) 81 | elif opt in ("-g", "--gpg-key-info-file"): 82 | self.gpg_pub_key_info_file = arg 83 | elif opt in ("-o", "--targetDir"): 84 | self.target_directory = arg 85 | self.targetFile = self.target_directory + "/HEADER.html" 86 | 87 | self.targetFile = self.target_directory + "/HEADER.html" 88 | self.footer = self.target_directory + "/FOOTER.html" 89 | self.index = self.target_directory + "/index.html" 90 | self.template_file = self.DISTRIBUTIONS[self.distribution]["template"] 91 | self.root_dir = os.path.dirname(self.target_directory[0:-1]) 92 | self.root_header = self.root_dir + "/HEADER.html" 93 | self.root_footer = self.root_dir + "/FOOTER.html" 94 | self.web_url = self.DISTRIBUTIONS[self.distribution]["web_url"] 95 | 96 | def show_information(self): 97 | print("Product Name: " + self.product_name) 98 | print("Download URL: " + self.download_url) 99 | print("Organization: " + self.organization) 100 | print("Artifact Name: " + self.artifact) 101 | print("Distribution: " + self.distribution) 102 | print("Web URL: " + str(self.web_url)) 103 | print("Number of Packages found: " + str(len(self.packages))) 104 | print("Template file: " + self.template_file) 105 | print("Repository header generated: " + self.targetFile) 106 | print("Repository index generated: " + self.index) 107 | print("Repository footer generated: " + self.footer) 108 | print("Root header generated: " + self.root_header) 109 | print("Root footer generated: " + self.root_footer) 110 | print("GPG Key Info File: " + self.gpg_pub_key_info_file) 111 | print("GPG Public Key Filename: " + self.gpg_public_key_filename) 112 | 113 | def generate_root_header(self): 114 | 115 | contexts = { 116 | "product_name": self.product_name, 117 | "repositories": self.repositories, 118 | } 119 | 120 | env = jinja2.Environment( 121 | loader=jinja2.FileSystemLoader(self.template_directory) 122 | ) 123 | template = env.get_template("header.root.html") 124 | 125 | with open(self.root_header, "w") as f: 126 | f.write(template.render(contexts)) 127 | 128 | def generate_root_footer(self): 129 | 130 | contexts = {} 131 | 132 | env = jinja2.Environment( 133 | loader=jinja2.FileSystemLoader(self.template_directory) 134 | ) 135 | template = env.get_template("footer.html") 136 | 137 | with open(self.root_footer, "w") as f: 138 | f.write(template.render(contexts)) 139 | 140 | def generate_footer(self): 141 | 142 | contexts = {"product_name": self.product_name} 143 | 144 | env = jinja2.Environment( 145 | loader=jinja2.FileSystemLoader(self.template_directory) 146 | ) 147 | template = env.get_template("footer.html") 148 | 149 | with open(self.footer, "w") as f: 150 | f.write(template.render(contexts)) 151 | 152 | def fetch_pubkeyinfo(self): 153 | pub_key_info = "" 154 | 155 | if self.gpg_pub_key_info_file != ".": 156 | gpg_pub_key = pathlib.Path(self.gpg_pub_key_info_file) 157 | if gpg_pub_key.is_file(): 158 | with open(self.gpg_pub_key_info_file, "r") as gpg_pub_key: 159 | pub_key_info = gpg_pub_key.read() 160 | 161 | return pub_key_info 162 | 163 | def generate_repository_header(self): 164 | contexts = { 165 | "product_name": self.product_name, 166 | "url": self.download_url, 167 | "organization": self.organization, 168 | "artifactName": self.artifact, 169 | "os_family": self.distribution, 170 | "packages": self.packages, 171 | "releaseline": self.releaseline, 172 | "web_url": self.web_url, 173 | "pub_key_info": self.fetch_pubkeyinfo(), 174 | "gpg_public_key_filename": self.gpg_public_key_filename, 175 | } 176 | 177 | env = jinja2.Environment( 178 | loader=jinja2.FileSystemLoader(self.template_directory) 179 | ) 180 | env.filters["basename"] = basename 181 | template = env.get_template(self.template_file) 182 | 183 | with open(self.targetFile, "w") as f: 184 | f.write(template.render(contexts)) 185 | 186 | def generate_repository_index(self): 187 | contexts = { 188 | "header": self.template_file, 189 | "product_name": self.product_name, 190 | "url": self.download_url, 191 | "organization": self.organization, 192 | "artifactName": self.artifact, 193 | "os_family": self.distribution, 194 | "packages": self.packages, 195 | "releaseline": self.releaseline, 196 | "web_url": self.web_url, 197 | "pub_key_info": self.fetch_pubkeyinfo(), 198 | "gpg_public_key_filename": self.gpg_public_key_filename, 199 | } 200 | 201 | env = jinja2.Environment( 202 | loader=jinja2.FileSystemLoader(self.template_directory) 203 | ) 204 | env.filters["basename"] = basename 205 | templateIndex = env.get_template("index.html") 206 | 207 | with open(self.index, "w") as f: 208 | f.write(templateIndex.render(contexts)) 209 | 210 | 211 | if __name__ == "__main__": 212 | headerGenerator = IndexGenerator(sys.argv[1:]) 213 | headerGenerator.show_information() 214 | headerGenerator.generate_repository_header() 215 | headerGenerator.generate_footer() 216 | headerGenerator.generate_repository_index() 217 | headerGenerator.generate_root_header() 218 | headerGenerator.generate_root_footer() 219 | -------------------------------------------------------------------------------- /systemd/migrate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | die() { 6 | echo "$(basename "$0"): $*" >&2 7 | exit 1 8 | } 9 | 10 | usage() { 11 | echo "$(basename "$0"): $*" >&2 12 | echo "Usage: $(basename "$0") " 13 | exit 2 14 | } 15 | 16 | NEW_JAVA_OPTS_DEFAULT="-Djava.awt.headless=true" 17 | NEW_JENKINS_DEBUG_LEVEL_DEFAULT="5" 18 | NEW_JENKINS_GROUP_DEFAULT="@@ARTIFACTNAME@@" 19 | NEW_JENKINS_HOME_DEFAULT="/var/lib/@@ARTIFACTNAME@@" 20 | NEW_JENKINS_LOG_DEFAULT="/var/log/@@ARTIFACTNAME@@/@@ARTIFACTNAME@@.log" 21 | NEW_JENKINS_MAXOPENFILES_DEFAULT="8192" 22 | NEW_JENKINS_PORT_DEFAULT="@@PORT@@" 23 | NEW_JENKINS_USER_DEFAULT="@@ARTIFACTNAME@@" 24 | NEW_JENKINS_WAR_DEFAULT="/usr/share/java/@@ARTIFACTNAME@@.war" 25 | NEW_JENKINS_WEBROOT_DEFAULT="/var/cache/@@ARTIFACTNAME@@/war" 26 | 27 | NEW_JAVA_HOME="" 28 | NEW_JAVA_OPTS="${NEW_JAVA_OPTS_DEFAULT}" 29 | NEW_JENKINS_DEBUG_LEVEL="${NEW_JENKINS_DEBUG_LEVEL_DEFAULT}" 30 | NEW_JENKINS_ENABLE_ACCESS_LOG=false 31 | NEW_JENKINS_GROUP="${NEW_JENKINS_GROUP_DEFAULT}" 32 | NEW_JENKINS_HOME="${NEW_JENKINS_HOME_DEFAULT}" 33 | NEW_JENKINS_HTTP2_LISTEN_ADDRESS="" 34 | NEW_JENKINS_HTTP2_PORT="" 35 | NEW_JENKINS_HTTPS_KEYSTORE="" 36 | NEW_JENKINS_HTTPS_KEYSTORE_PASSWORD="" 37 | NEW_JENKINS_HTTPS_LISTEN_ADDRESS="" 38 | NEW_JENKINS_HTTPS_PORT="" 39 | NEW_JENKINS_JAVA_CMD="" 40 | NEW_JENKINS_LISTEN_ADDRESS="" 41 | NEW_JENKINS_LOG="${NEW_JENKINS_LOG_DEFAULT}" 42 | NEW_JENKINS_MAXOPENFILES="${NEW_JENKINS_MAXOPENFILES_DEFAULT}" 43 | NEW_JENKINS_OPTS="" 44 | NEW_JENKINS_PORT="${NEW_JENKINS_PORT_DEFAULT}" 45 | NEW_JENKINS_PREFIX="" 46 | NEW_JENKINS_UMASK="" 47 | NEW_JENKINS_USER="${NEW_JENKINS_USER_DEFAULT}" 48 | NEW_JENKINS_WAR="${NEW_JENKINS_WAR_DEFAULT}" 49 | NEW_JENKINS_WEBROOT="${NEW_JENKINS_WEBROOT_DEFAULT}" 50 | 51 | has_prefix=false 52 | 53 | read_old_options() { 54 | # This could only be the case for deb 55 | if [ -n "${HTTP_PORT}" ] && [ "${HTTP_PORT}" -gt 0 ]; then 56 | # Normalize to rpm convention 57 | JENKINS_PORT="${HTTP_PORT}" 58 | fi 59 | 60 | if [ -n "${JENKINS_ARGS}" ]; then 61 | if [ -n "${NAME}" ]; then 62 | # For deb, these are all the arguments, except for the JENKINS_ENABLE_ACCESS_LOG additions 63 | webroot_quoted=false 64 | TMP_JENKINS_WEBROOT="$(printf '%s' "${JENKINS_ARGS}" | sed -n "s/.*--webroot=[\"']\\([[:alnum:][:space:]+,-\\./:;@\\_]*\\)[\"'].*/\\1/p")" 65 | [ -n "${TMP_JENKINS_WEBROOT}" ] && webroot_quoted=true 66 | [ -z "${TMP_JENKINS_WEBROOT}" ] && TMP_JENKINS_WEBROOT="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--webroot=\([[:alnum:][:punct:]]*\).*/\1/p')" 67 | 68 | log_quoted=false 69 | TMP_JENKINS_LOG="$(printf '%s' "${JENKINS_ARGS}" | sed -n "s/.*--logfile=[\"']\\([[:alnum:][:space:]+,-\\./:;@\\_]*\\)[\"'].*/\\1/p")" 70 | [ -n "${TMP_JENKINS_LOG}" ] && log_quoted=true 71 | [ -z "${TMP_JENKINS_LOG}" ] && TMP_JENKINS_LOG="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--logfile=\([[:alnum:][:punct:]]*\).*/\1/p')" 72 | 73 | TMP_JENKINS_PORT="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--httpPort=\([[:alnum:][:punct:]]*\).*/\1/p')" 74 | 75 | TMP_JENKINS_LISTEN_ADDRESS="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--httpListenAddress=\([[:alnum:][:punct:]]*\).*/\1/p')" 76 | 77 | TMP_JENKINS_HTTPS_PORT="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--httpsPort=\([[:alnum:][:punct:]]*\).*/\1/p')" 78 | 79 | TMP_JENKINS_HTTPS_LISTEN_ADDRESS="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--httpsListenAddress=\([[:alnum:][:punct:]]*\).*/\1/p')" 80 | 81 | keystore_quoted=false 82 | TMP_JENKINS_HTTPS_KEYSTORE="$(printf '%s' "${JENKINS_ARGS}" | sed -n "s/.*--httpsKeyStore=[\"']\\([[:alnum:][:space:]+,-\\./:;@\\_]*\\)[\"'].*/\\1/p")" 83 | [ -n "${TMP_JENKINS_HTTPS_KEYSTORE}" ] && keystore_quoted=true 84 | [ -z "${TMP_JENKINS_HTTPS_KEYSTORE}" ] && TMP_JENKINS_HTTPS_KEYSTORE="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--httpsKeyStore=\([[:alnum:][:punct:]]*\).*/\1/p')" 85 | 86 | keystore_password_quoted=false 87 | TMP_JENKINS_HTTPS_KEYSTORE_PASSWORD="$(printf '%s' "${JENKINS_ARGS}" | sed -n "s/.*--httpsKeyStorePassword=[\"']\\([[:alnum:][:space:]+,-\\./:;@\\_]*\\)[\"'].*/\\1/p")" 88 | [ -n "${TMP_JENKINS_HTTPS_KEYSTORE_PASSWORD}" ] && keystore_password_quoted=true 89 | [ -z "${TMP_JENKINS_HTTPS_KEYSTORE_PASSWORD}" ] && TMP_JENKINS_HTTPS_KEYSTORE_PASSWORD="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--httpsKeyStorePassword=\([[:alnum:][:punct:]]*\).*/\1/p')" 90 | 91 | TMP_JENKINS_HTTP2_PORT="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--http2Port=\([[:alnum:][:punct:]]*\).*/\1/p')" 92 | 93 | TMP_JENKINS_HTTP2_LISTEN_ADDRESS="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--http2ListenAddress=\([[:alnum:][:punct:]]*\).*/\1/p')" 94 | 95 | TMP_JENKINS_DEBUG_LEVEL="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--debug=\([[:alnum:][:punct:]]*\).*/\1/p')" 96 | 97 | prefix_quoted=false 98 | TMP_PREFIX="$(printf '%s' "${JENKINS_ARGS}" | sed -n "s/.*--prefix=[\"']\\([[:alnum:][:space:]+,-\\./:;@\\_]*\\)[\"'].*/\\1/p")" 99 | [ -n "${TMP_PREFIX}" ] && prefix_quoted=true 100 | [ -z "${TMP_PREFIX}" ] && TMP_PREFIX="$(printf '%s' "${JENKINS_ARGS}" | sed -n 's/.*--prefix=\([[:alnum:][:punct:]]*\).*/\1/p')" 101 | 102 | [ -n "${TMP_JENKINS_WEBROOT}" ] && JENKINS_WEBROOT="${TMP_JENKINS_WEBROOT}" 103 | [ -n "${TMP_JENKINS_LOG}" ] && JENKINS_LOG="${TMP_JENKINS_LOG}" 104 | [ -n "${TMP_JENKINS_PORT}" ] && JENKINS_PORT="${TMP_JENKINS_PORT}" 105 | [ -n "${TMP_JENKINS_LISTEN_ADDRESS}" ] && JENKINS_LISTEN_ADDRESS="${TMP_JENKINS_LISTEN_ADDRESS}" 106 | [ -n "${TMP_JENKINS_HTTPS_PORT}" ] && JENKINS_HTTPS_PORT="${TMP_JENKINS_HTTPS_PORT}" 107 | [ -n "${TMP_JENKINS_HTTPS_LISTEN_ADDRESS}" ] && JENKINS_HTTPS_LISTEN_ADDRESS="${TMP_JENKINS_HTTPS_LISTEN_ADDRESS}" 108 | [ -n "${TMP_JENKINS_HTTPS_KEYSTORE}" ] && JENKINS_HTTPS_KEYSTORE="${TMP_JENKINS_HTTPS_KEYSTORE}" 109 | [ -n "${TMP_JENKINS_HTTPS_KEYSTORE_PASSWORD}" ] && JENKINS_HTTPS_KEYSTORE_PASSWORD="${TMP_JENKINS_HTTPS_KEYSTORE_PASSWORD}" 110 | [ -n "${TMP_JENKINS_HTTP2_PORT}" ] && JENKINS_HTTP2_PORT="${TMP_JENKINS_HTTP2_PORT}" 111 | [ -n "${TMP_JENKINS_HTTP2_LISTEN_ADDRESS}" ] && JENKINS_HTTP2_LISTEN_ADDRESS="${TMP_JENKINS_HTTP2_LISTEN_ADDRESS}" 112 | [ -n "${TMP_JENKINS_DEBUG_LEVEL}" ] && JENKINS_DEBUG_LEVEL="${TMP_JENKINS_DEBUG_LEVEL}" 113 | [ -n "${TMP_PREFIX}" ] && PREFIX="${TMP_PREFIX}" 114 | [ -n "${TMP_PREFIX}" ] && has_prefix=true 115 | 116 | if $webroot_quoted; then 117 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed "s/--webroot=[\"'][[:alnum:][:space:]+,-\\./:;@\\_]*[\"']//g")" 118 | else 119 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--webroot=[[:alnum:][:punct:]]*//g')" 120 | fi 121 | 122 | if $log_quoted; then 123 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed "s/--logfile=[\"'][[:alnum:][:space:]+,-\\./:;@\\_]*[\"']//g")" 124 | else 125 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--logfile=[[:alnum:][:punct:]]*//g')" 126 | fi 127 | 128 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--httpPort=[[:alnum:][:punct:]]*//g')" 129 | 130 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--httpListenAddress=[[:alnum:][:punct:]]*//g')" 131 | 132 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--httpsPort=[[:alnum:][:punct:]]*//g')" 133 | 134 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--httpsListenAddress=[[:alnum:][:punct:]]*//g')" 135 | 136 | if $keystore_quoted; then 137 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed "s/--httpsKeyStore=[\"'][[:alnum:][:space:]+,-\\./:;@\\_]*[\"']//g")" 138 | else 139 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--httpsKeyStore=[[:alnum:][:punct:]]*//g')" 140 | fi 141 | 142 | if $keystore_password_quoted; then 143 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed "s/--httpsKeyStorePassword=[\"'][[:alnum:][:space:]+,-\\./:;@\\_]*[\"']//g")" 144 | else 145 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--httpsKeyStorePassword=[[:alnum:][:punct:]]*//g')" 146 | fi 147 | 148 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--http2Port=[[:alnum:][:punct:]]*//g')" 149 | 150 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--http2ListenAddress=[[:alnum:][:punct:]]*//g')" 151 | 152 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--debug=[[:alnum:][:punct:]]*//g')" 153 | 154 | if $prefix_quoted; then 155 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed "s/--prefix=[\"'][[:alnum:][:space:]+,-\\./:;@\\_]*[\"']//g")" 156 | else 157 | JENKINS_ARGS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/--prefix=[[:alnum:][:punct:]]*//g')" 158 | fi 159 | 160 | # All that remains are the extra arguments 161 | NEW_JENKINS_OPTS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/^[[:space:]]*//g')" 162 | NEW_JENKINS_OPTS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/[[:space:]]*$//g')" 163 | else 164 | # For rpm and suse, these are extra arguments 165 | NEW_JENKINS_OPTS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/^[[:space:]]*//g')" 166 | NEW_JENKINS_OPTS="$(printf '%s' "${JENKINS_ARGS}" | sed 's/[[:space:]]*$//g')" 167 | fi 168 | fi 169 | 170 | if [ -n "${JENKINS_USER}" ]; then 171 | NEW_JENKINS_USER="${JENKINS_USER}" 172 | fi 173 | 174 | if [ -n "${JENKINS_GROUP}" ]; then 175 | NEW_JENKINS_GROUP="${JENKINS_GROUP}" 176 | fi 177 | 178 | if [ -n "${JENKINS_HOME}" ] && [ -d "${JENKINS_HOME}" ]; then 179 | NEW_JENKINS_HOME="${JENKINS_HOME}" 180 | fi 181 | 182 | if [ -n "${JENKINS_WAR}" ] && [ -f "${JENKINS_WAR}" ]; then 183 | NEW_JENKINS_WAR="${JENKINS_WAR}" 184 | fi 185 | if [ "${NEW_JENKINS_WAR}" = "/usr/share/@@ARTIFACTNAME@@/@@ARTIFACTNAME@@.war" ]; then 186 | # deb 187 | NEW_JENKINS_WAR="${NEW_JENKINS_WAR_DEFAULT}" 188 | elif [ "${NEW_JENKINS_WAR}" = "/usr/lib/@@ARTIFACTNAME@@/@@ARTIFACTNAME@@.war" ]; then 189 | # rpm 190 | NEW_JENKINS_WAR="${NEW_JENKINS_WAR_DEFAULT}" 191 | fi 192 | 193 | if [ -n "${JENKINS_WEBROOT}" ] && [ -d "${JENKINS_WEBROOT}" ]; then 194 | NEW_JENKINS_WEBROOT="${JENKINS_WEBROOT}" 195 | fi 196 | 197 | if [ -n "${JENKINS_LOG}" ]; then 198 | NEW_JENKINS_LOG="${JENKINS_LOG}" 199 | fi 200 | 201 | if [ -n "${JENKINS_JAVA_HOME}" ] && [ -d "${JENKINS_JAVA_HOME}" ]; then 202 | NEW_JAVA_HOME="${JENKINS_JAVA_HOME}" 203 | fi 204 | 205 | if [ -n "${JENKINS_JAVA_CMD}" ] && [ -x "${JENKINS_JAVA_CMD}" ]; then 206 | NEW_JENKINS_JAVA_CMD="${JENKINS_JAVA_CMD}" 207 | fi 208 | 209 | if [ -n "${JAVA_ARGS}" ]; then 210 | NEW_JAVA_OPTS="${JAVA_ARGS}" 211 | elif [ -n "${JENKINS_JAVA_OPTIONS}" ]; then 212 | NEW_JAVA_OPTS="${JENKINS_JAVA_OPTIONS}" 213 | fi 214 | 215 | if [ -n "${JENKINS_LISTEN_ADDRESS}" ]; then 216 | NEW_JENKINS_LISTEN_ADDRESS="${JENKINS_LISTEN_ADDRESS}" 217 | fi 218 | 219 | if [ -n "${JENKINS_PORT}" ] && [ "${JENKINS_PORT}" -gt 0 ]; then 220 | NEW_JENKINS_PORT="${JENKINS_PORT}" 221 | fi 222 | 223 | if [ -n "${JENKINS_HTTPS_LISTEN_ADDRESS}" ]; then 224 | NEW_JENKINS_HTTPS_LISTEN_ADDRESS="${JENKINS_HTTPS_LISTEN_ADDRESS}" 225 | fi 226 | 227 | if [ -n "${JENKINS_HTTPS_PORT}" ] && [ "${JENKINS_HTTPS_PORT}" -gt 0 ]; then 228 | NEW_JENKINS_HTTPS_PORT="${JENKINS_HTTPS_PORT}" 229 | fi 230 | 231 | if [ -n "${JENKINS_HTTPS_KEYSTORE}" ] && [ -f "${JENKINS_HTTPS_KEYSTORE}" ]; then 232 | NEW_JENKINS_HTTPS_KEYSTORE="${JENKINS_HTTPS_KEYSTORE}" 233 | fi 234 | 235 | if [ -n "${JENKINS_HTTPS_KEYSTORE_PASSWORD}" ]; then 236 | NEW_JENKINS_HTTPS_KEYSTORE_PASSWORD="${JENKINS_HTTPS_KEYSTORE_PASSWORD}" 237 | fi 238 | 239 | if [ -n "${JENKINS_HTTP2_LISTEN_ADDRESS}" ]; then 240 | NEW_JENKINS_HTTP2_LISTEN_ADDRESS="${JENKINS_HTTP2_LISTEN_ADDRESS}" 241 | fi 242 | 243 | if [ -n "${JENKINS_HTTP2_PORT}" ] && [ "${JENKINS_HTTP2_PORT}" -gt 0 ]; then 244 | NEW_JENKINS_HTTP2_PORT="${JENKINS_HTTP2_PORT}" 245 | fi 246 | 247 | if [ -n "${JENKINS_DEBUG_LEVEL}" ] && [ "${JENKINS_DEBUG_LEVEL}" -gt 0 ]; then 248 | NEW_JENKINS_DEBUG_LEVEL="${JENKINS_DEBUG_LEVEL}" 249 | fi 250 | 251 | if [ -n "${JENKINS_ENABLE_ACCESS_LOG}" ] && [ "${JENKINS_ENABLE_ACCESS_LOG}" = "yes" ]; then 252 | NEW_JENKINS_ENABLE_ACCESS_LOG=true 253 | fi 254 | 255 | if [ -n "${PREFIX}" ] && $has_prefix; then 256 | NEW_JENKINS_PREFIX="${PREFIX}" 257 | fi 258 | 259 | if [ -n "${MAXOPENFILES}" ] && [ "${MAXOPENFILES}" -gt 0 ]; then 260 | NEW_JENKINS_MAXOPENFILES="${MAXOPENFILES}" 261 | fi 262 | 263 | if [ -n "${UMASK}" ]; then 264 | NEW_JENKINS_UMASK="${UMASK}" 265 | fi 266 | } 267 | 268 | migrate_options() { 269 | if [ -f /etc/systemd/system/@@ARTIFACTNAME@@.service.d/override.conf ]; then 270 | if grep -q '\-\-handlerCount' /etc/systemd/system/@@ARTIFACTNAME@@.service.d/override.conf; then 271 | sed -ibak -r -e 's/--handlerCount[A-Za-z]+=[0-9]+//g' /etc/systemd/system/@@ARTIFACTNAME@@.service.d/override.conf 272 | fi 273 | return 274 | fi 275 | 276 | tmpfile=$(mktemp) 277 | edited=false 278 | 279 | echo '[Service]' >>"${tmpfile}" 280 | 281 | if [ "${NEW_JENKINS_USER}" != "${NEW_JENKINS_USER_DEFAULT}" ]; then 282 | NEW_JENKINS_USER="$(printf '%s' "${NEW_JENKINS_USER}" | sed -e 's/"/\\"/g')" 283 | echo "User=${NEW_JENKINS_USER}" >>"${tmpfile}" 284 | edited=true 285 | fi 286 | 287 | if [ "${NEW_JENKINS_GROUP}" != "${NEW_JENKINS_GROUP_DEFAULT}" ]; then 288 | NEW_JENKINS_GROUP="$(printf '%s' "${NEW_JENKINS_GROUP}" | sed -e 's/"/\\"/g')" 289 | echo "Group=${NEW_JENKINS_GROUP}" >>"${tmpfile}" 290 | edited=true 291 | fi 292 | 293 | if [ "${NEW_JENKINS_HOME}" != "${NEW_JENKINS_HOME_DEFAULT}" ]; then 294 | NEW_JENKINS_HOME="$(printf '%s' "${NEW_JENKINS_HOME}" | sed -e 's/"/\\"/g')" 295 | echo "Environment=\"JENKINS_HOME=${NEW_JENKINS_HOME}\"" >>"${tmpfile}" 296 | echo "WorkingDirectory=${NEW_JENKINS_HOME}" >>"${tmpfile}" 297 | edited=true 298 | fi 299 | 300 | if [ "${NEW_JENKINS_WAR}" != "${NEW_JENKINS_WAR_DEFAULT}" ]; then 301 | NEW_JENKINS_WAR="$(printf '%s' "${NEW_JENKINS_WAR}" | sed -e 's/"/\\"/g')" 302 | echo "Environment=\"JENKINS_WAR=${NEW_JENKINS_WAR}\"" >>"${tmpfile}" 303 | edited=true 304 | fi 305 | 306 | if [ "${NEW_JENKINS_WEBROOT}" != "${NEW_JENKINS_WEBROOT_DEFAULT}" ]; then 307 | NEW_JENKINS_WEBROOT="$(printf '%s' "${NEW_JENKINS_WEBROOT}" | sed -e 's/"/\\"/g')" 308 | echo "Environment=\"JENKINS_WEBROOT=${NEW_JENKINS_WEBROOT}\"" >>"${tmpfile}" 309 | edited=true 310 | fi 311 | 312 | if [ "${NEW_JENKINS_LOG}" != "${NEW_JENKINS_LOG_DEFAULT}" ]; then 313 | NEW_JENKINS_LOG="$(printf '%s' "${NEW_JENKINS_LOG}" | sed -e 's/"/\\"/g')" 314 | echo "Environment=\"JENKINS_LOG=${NEW_JENKINS_LOG}\"" >>"${tmpfile}" 315 | edited=true 316 | fi 317 | 318 | if [ -n "${NEW_JAVA_HOME}" ]; then 319 | NEW_JENKINS_HOME="$(printf '%s' "${NEW_JENKINS_HOME}" | sed -e 's/"/\\"/g')" 320 | echo "Environment=\"JAVA_HOME=${NEW_JAVA_HOME}\"" >>"${tmpfile}" 321 | edited=true 322 | fi 323 | 324 | if [ -n "${NEW_JENKINS_JAVA_CMD}" ]; then 325 | NEW_JENKINS_JAVA_CMD="$(printf '%s' "${NEW_JENKINS_JAVA_CMD}" | sed -e 's/"/\\"/g')" 326 | echo "Environment=\"JENKINS_JAVA_CMD=${NEW_JENKINS_JAVA_CMD}\"" >>"${tmpfile}" 327 | edited=true 328 | fi 329 | 330 | if [ "${NEW_JAVA_OPTS}" != "${NEW_JAVA_OPTS_DEFAULT}" ]; then 331 | NEW_JAVA_OPTS="$(printf '%s' "${NEW_JAVA_OPTS}" | sed -e 's/"/\\"/g')" 332 | echo "Environment=\"JAVA_OPTS=${NEW_JAVA_OPTS}\"" >>"${tmpfile}" 333 | edited=true 334 | fi 335 | 336 | if [ -n "${NEW_JENKINS_LISTEN_ADDRESS}" ]; then 337 | NEW_JENKINS_LISTEN_ADDRESS="$(printf '%s' "${NEW_JENKINS_LISTEN_ADDRESS}" | sed -e 's/"/\\"/g')" 338 | echo "Environment=\"JENKINS_LISTEN_ADDRESS=${NEW_JENKINS_LISTEN_ADDRESS}\"" >>"${tmpfile}" 339 | edited=true 340 | fi 341 | 342 | privileged_port=false 343 | 344 | if [ "${NEW_JENKINS_PORT}" != "${NEW_JENKINS_PORT_DEFAULT}" ]; then 345 | [ "${NEW_JENKINS_PORT}" -lt 1024 ] && privileged_port=true 346 | NEW_JENKINS_PORT="$(printf '%s' "${NEW_JENKINS_PORT}" | sed -e 's/"/\\"/g')" 347 | echo "Environment=\"JENKINS_PORT=${NEW_JENKINS_PORT}\"" >>"${tmpfile}" 348 | edited=true 349 | fi 350 | 351 | if [ -n "${NEW_JENKINS_HTTPS_LISTEN_ADDRESS}" ]; then 352 | NEW_JENKINS_HTTPS_LISTEN_ADDRESS="$(printf '%s' "${NEW_JENKINS_HTTPS_LISTEN_ADDRESS}" | sed -e 's/"/\\"/g')" 353 | echo "Environment=\"JENKINS_HTTPS_LISTEN_ADDRESS=${NEW_JENKINS_HTTPS_LISTEN_ADDRESS}\"" >>"${tmpfile}" 354 | edited=true 355 | fi 356 | 357 | if [ -n "${NEW_JENKINS_HTTPS_PORT}" ]; then 358 | [ "${NEW_JENKINS_HTTPS_PORT}" -lt 1024 ] && privileged_port=true 359 | NEW_JENKINS_HTTPS_PORT="$(printf '%s' "${NEW_JENKINS_HTTPS_PORT}" | sed -e 's/"/\\"/g')" 360 | echo "Environment=\"JENKINS_HTTPS_PORT=${NEW_JENKINS_HTTPS_PORT}\"" >>"${tmpfile}" 361 | edited=true 362 | fi 363 | 364 | if [ -n "${NEW_JENKINS_HTTPS_KEYSTORE}" ]; then 365 | NEW_JENKINS_HTTPS_KEYSTORE="$(printf '%s' "${NEW_JENKINS_HTTPS_KEYSTORE}" | sed -e 's/"/\\"/g')" 366 | echo "Environment=\"JENKINS_HTTPS_KEYSTORE=${NEW_JENKINS_HTTPS_KEYSTORE}\"" >>"${tmpfile}" 367 | edited=true 368 | fi 369 | 370 | if [ -n "${NEW_JENKINS_HTTPS_KEYSTORE_PASSWORD}" ]; then 371 | NEW_JENKINS_HTTPS_KEYSTORE_PASSWORD="$(printf '%s' "${NEW_JENKINS_HTTPS_KEYSTORE_PASSWORD}" | sed -e 's/"/\\"/g')" 372 | echo "Environment=\"JENKINS_HTTPS_KEYSTORE_PASSWORD=${NEW_JENKINS_HTTPS_KEYSTORE_PASSWORD}\"" >>"${tmpfile}" 373 | edited=true 374 | fi 375 | 376 | if [ -n "${NEW_JENKINS_HTTP2_LISTEN_ADDRESS}" ]; then 377 | NEW_JENKINS_HTTP2_LISTEN_ADDRESS="$(printf '%s' "${NEW_JENKINS_HTTP2_LISTEN_ADDRESS}" | sed -e 's/"/\\"/g')" 378 | echo "Environment=\"JENKINS_HTTP2_LISTEN_ADDRESS=${NEW_JENKINS_HTTP2_LISTEN_ADDRESS}\"" >>"${tmpfile}" 379 | edited=true 380 | fi 381 | 382 | if [ -n "${NEW_JENKINS_HTTP2_PORT}" ]; then 383 | [ "${NEW_JENKINS_HTTP2_PORT}" -lt 1024 ] && privileged_port=true 384 | NEW_JENKINS_HTTP2_PORT="$(printf '%s' "${NEW_JENKINS_HTTP2_PORT}" | sed -e 's/"/\\"/g')" 385 | echo "Environment=\"JENKINS_HTTP2_PORT=${NEW_JENKINS_HTTP2_PORT}\"" >>"${tmpfile}" 386 | edited=true 387 | fi 388 | 389 | if $privileged_port; then 390 | echo "AmbientCapabilities=CAP_NET_BIND_SERVICE" >>"${tmpfile}" 391 | edited=true 392 | fi 393 | 394 | if [ "${NEW_JENKINS_DEBUG_LEVEL}" != "${NEW_JENKINS_DEBUG_LEVEL_DEFAULT}" ]; then 395 | NEW_JENKINS_DEBUG_LEVEL="$(printf '%s' "${NEW_JENKINS_DEBUG_LEVEL}" | sed -e 's/"/\\"/g')" 396 | echo "Environment=\"JENKINS_DEBUG_LEVEL=${NEW_JENKINS_DEBUG_LEVEL}\"" >>"${tmpfile}" 397 | edited=true 398 | fi 399 | 400 | if $NEW_JENKINS_ENABLE_ACCESS_LOG; then 401 | echo "Environment=\"JENKINS_ENABLE_ACCESS_LOG=${NEW_JENKINS_ENABLE_ACCESS_LOG}\"" >>"${tmpfile}" 402 | edited=true 403 | fi 404 | 405 | if [ -n "${NEW_JENKINS_PREFIX}" ]; then 406 | NEW_JENKINS_PREFIX="$(printf '%s' "${NEW_JENKINS_PREFIX}" | sed -e 's/"/\\"/g')" 407 | echo "Environment=\"JENKINS_PREFIX=${NEW_JENKINS_PREFIX}\"" >>"${tmpfile}" 408 | edited=true 409 | fi 410 | 411 | if [ -n "${NEW_JENKINS_OPTS}" ]; then 412 | NEW_JENKINS_OPTS="$(printf '%s' "${NEW_JENKINS_OPTS}" | sed -e 's/"/\\"/g')" 413 | echo "Environment=\"JENKINS_OPTS=${NEW_JENKINS_OPTS}\"" >>"${tmpfile}" 414 | edited=true 415 | fi 416 | 417 | if [ "${NEW_JENKINS_MAXOPENFILES}" != "${NEW_JENKINS_MAXOPENFILES_DEFAULT}" ]; then 418 | NEW_JENKINS_MAXOPENFILES="$(printf '%s' "${NEW_JENKINS_MAXOPENFILES}" | sed -e 's/"/\\"/g')" 419 | echo "LimitNOFILE=${NEW_JENKINS_MAXOPENFILES}" >>"${tmpfile}" 420 | edited=true 421 | fi 422 | 423 | if [ -n "${NEW_JENKINS_UMASK}" ]; then 424 | NEW_JENKINS_UMASK="$(printf '%s' "${NEW_JENKINS_UMASK}" | sed -e 's/"/\\"/g')" 425 | echo "UMask=${NEW_JENKINS_UMASK}" >>"${tmpfile}" 426 | edited=true 427 | fi 428 | 429 | if $edited; then 430 | mkdir -p /etc/systemd/system/@@ARTIFACTNAME@@.service.d 431 | mv "${tmpfile}" /etc/systemd/system/@@ARTIFACTNAME@@.service.d/override.conf 432 | else 433 | rm -f "${tmpfile}" 434 | fi 435 | } 436 | 437 | main() { 438 | from=$1 439 | 440 | [ -f "${from}" ] || die "${from} does not exist" 441 | . "${from}" 442 | read_old_options 443 | migrate_options 444 | } 445 | 446 | [ $# -gt 1 ] && usage "too many arguments specified" 447 | [ $# -lt 1 ] && usage "too few arguments specified" 448 | main "$1" 449 | 450 | exit 0 451 | -------------------------------------------------------------------------------- /pkgConfig/httpd.conf: -------------------------------------------------------------------------------- 1 | ServerRoot "/usr/local/apache2" 2 | 3 | Listen 80 4 | 5 | # 6 | # Dynamic Shared Object (DSO) Support 7 | # 8 | # To be able to use the functionality of a module which was built as a DSO you 9 | # have to place corresponding `LoadModule' lines at this location so the 10 | # directives contained in it are actually available _before_ they are used. 11 | # Statically compiled modules (those listed by `httpd -l') do not need 12 | # to be loaded here. 13 | # 14 | # Example: 15 | # LoadModule foo_module modules/mod_foo.so 16 | # 17 | LoadModule mpm_event_module modules/mod_mpm_event.so 18 | #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so 19 | #LoadModule mpm_worker_module modules/mod_mpm_worker.so 20 | LoadModule authn_file_module modules/mod_authn_file.so 21 | #LoadModule authn_dbm_module modules/mod_authn_dbm.so 22 | #LoadModule authn_anon_module modules/mod_authn_anon.so 23 | #LoadModule authn_dbd_module modules/mod_authn_dbd.so 24 | #LoadModule authn_socache_module modules/mod_authn_socache.so 25 | LoadModule authn_core_module modules/mod_authn_core.so 26 | LoadModule authz_host_module modules/mod_authz_host.so 27 | LoadModule authz_groupfile_module modules/mod_authz_groupfile.so 28 | LoadModule authz_user_module modules/mod_authz_user.so 29 | #LoadModule authz_dbm_module modules/mod_authz_dbm.so 30 | #LoadModule authz_owner_module modules/mod_authz_owner.so 31 | #LoadModule authz_dbd_module modules/mod_authz_dbd.so 32 | LoadModule authz_core_module modules/mod_authz_core.so 33 | #LoadModule authnz_ldap_module modules/mod_authnz_ldap.so 34 | #LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so 35 | LoadModule access_compat_module modules/mod_access_compat.so 36 | LoadModule auth_basic_module modules/mod_auth_basic.so 37 | #LoadModule auth_form_module modules/mod_auth_form.so 38 | #LoadModule auth_digest_module modules/mod_auth_digest.so 39 | #LoadModule allowmethods_module modules/mod_allowmethods.so 40 | #LoadModule isapi_module modules/mod_isapi.so 41 | #LoadModule file_cache_module modules/mod_file_cache.so 42 | #LoadModule cache_module modules/mod_cache.so 43 | #LoadModule cache_disk_module modules/mod_cache_disk.so 44 | #LoadModule cache_socache_module modules/mod_cache_socache.so 45 | #LoadModule socache_shmcb_module modules/mod_socache_shmcb.so 46 | #LoadModule socache_dbm_module modules/mod_socache_dbm.so 47 | #LoadModule socache_memcache_module modules/mod_socache_memcache.so 48 | #LoadModule socache_redis_module modules/mod_socache_redis.so 49 | #LoadModule watchdog_module modules/mod_watchdog.so 50 | #LoadModule macro_module modules/mod_macro.so 51 | #LoadModule dbd_module modules/mod_dbd.so 52 | #LoadModule bucketeer_module modules/mod_bucketeer.so 53 | #LoadModule dumpio_module modules/mod_dumpio.so 54 | #LoadModule echo_module modules/mod_echo.so 55 | #LoadModule example_hooks_module modules/mod_example_hooks.so 56 | #LoadModule case_filter_module modules/mod_case_filter.so 57 | #LoadModule case_filter_in_module modules/mod_case_filter_in.so 58 | #LoadModule example_ipc_module modules/mod_example_ipc.so 59 | #LoadModule buffer_module modules/mod_buffer.so 60 | #LoadModule data_module modules/mod_data.so 61 | #LoadModule ratelimit_module modules/mod_ratelimit.so 62 | LoadModule reqtimeout_module modules/mod_reqtimeout.so 63 | #LoadModule ext_filter_module modules/mod_ext_filter.so 64 | #LoadModule request_module modules/mod_request.so 65 | #LoadModule include_module modules/mod_include.so 66 | LoadModule filter_module modules/mod_filter.so 67 | #LoadModule reflector_module modules/mod_reflector.so 68 | #LoadModule substitute_module modules/mod_substitute.so 69 | #LoadModule sed_module modules/mod_sed.so 70 | #LoadModule charset_lite_module modules/mod_charset_lite.so 71 | #LoadModule deflate_module modules/mod_deflate.so 72 | #LoadModule xml2enc_module modules/mod_xml2enc.so 73 | #LoadModule proxy_html_module modules/mod_proxy_html.so 74 | #LoadModule brotli_module modules/mod_brotli.so 75 | LoadModule mime_module modules/mod_mime.so 76 | #LoadModule ldap_module modules/mod_ldap.so 77 | LoadModule log_config_module modules/mod_log_config.so 78 | #LoadModule log_debug_module modules/mod_log_debug.so 79 | #LoadModule log_forensic_module modules/mod_log_forensic.so 80 | #LoadModule logio_module modules/mod_logio.so 81 | #LoadModule lua_module modules/mod_lua.so 82 | LoadModule env_module modules/mod_env.so 83 | #LoadModule mime_magic_module modules/mod_mime_magic.so 84 | #LoadModule cern_meta_module modules/mod_cern_meta.so 85 | #LoadModule expires_module modules/mod_expires.so 86 | LoadModule headers_module modules/mod_headers.so 87 | #LoadModule ident_module modules/mod_ident.so 88 | #LoadModule usertrack_module modules/mod_usertrack.so 89 | #LoadModule unique_id_module modules/mod_unique_id.so 90 | LoadModule setenvif_module modules/mod_setenvif.so 91 | LoadModule version_module modules/mod_version.so 92 | #LoadModule remoteip_module modules/mod_remoteip.so 93 | #LoadModule proxy_module modules/mod_proxy.so 94 | #LoadModule proxy_connect_module modules/mod_proxy_connect.so 95 | #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so 96 | #LoadModule proxy_http_module modules/mod_proxy_http.so 97 | #LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so 98 | #LoadModule proxy_scgi_module modules/mod_proxy_scgi.so 99 | #LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so 100 | #LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so 101 | #LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so 102 | #LoadModule proxy_ajp_module modules/mod_proxy_ajp.so 103 | #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so 104 | #LoadModule proxy_express_module modules/mod_proxy_express.so 105 | #LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so 106 | #LoadModule session_module modules/mod_session.so 107 | #LoadModule session_cookie_module modules/mod_session_cookie.so 108 | #LoadModule session_crypto_module modules/mod_session_crypto.so 109 | #LoadModule session_dbd_module modules/mod_session_dbd.so 110 | #LoadModule slotmem_shm_module modules/mod_slotmem_shm.so 111 | #LoadModule slotmem_plain_module modules/mod_slotmem_plain.so 112 | #LoadModule ssl_module modules/mod_ssl.so 113 | #LoadModule optional_hook_export_module modules/mod_optional_hook_export.so 114 | #LoadModule optional_hook_import_module modules/mod_optional_hook_import.so 115 | #LoadModule optional_fn_import_module modules/mod_optional_fn_import.so 116 | #LoadModule optional_fn_export_module modules/mod_optional_fn_export.so 117 | #LoadModule dialup_module modules/mod_dialup.so 118 | #LoadModule http2_module modules/mod_http2.so 119 | #LoadModule proxy_http2_module modules/mod_proxy_http2.so 120 | #LoadModule md_module modules/mod_md.so 121 | #LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so 122 | #LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so 123 | #LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so 124 | #LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so 125 | LoadModule unixd_module modules/mod_unixd.so 126 | #LoadModule heartbeat_module modules/mod_heartbeat.so 127 | #LoadModule heartmonitor_module modules/mod_heartmonitor.so 128 | #LoadModule dav_module modules/mod_dav.so 129 | LoadModule status_module modules/mod_status.so 130 | LoadModule autoindex_module modules/mod_autoindex.so 131 | #LoadModule asis_module modules/mod_asis.so 132 | #LoadModule info_module modules/mod_info.so 133 | #LoadModule suexec_module modules/mod_suexec.so 134 | 135 | #LoadModule cgid_module modules/mod_cgid.so 136 | 137 | 138 | #LoadModule cgi_module modules/mod_cgi.so 139 | 140 | #LoadModule dav_fs_module modules/mod_dav_fs.so 141 | #LoadModule dav_lock_module modules/mod_dav_lock.so 142 | #LoadModule vhost_alias_module modules/mod_vhost_alias.so 143 | #LoadModule negotiation_module modules/mod_negotiation.so 144 | LoadModule dir_module modules/mod_dir.so 145 | #LoadModule imagemap_module modules/mod_imagemap.so 146 | #LoadModule actions_module modules/mod_actions.so 147 | #LoadModule speling_module modules/mod_speling.so 148 | #LoadModule userdir_module modules/mod_userdir.so 149 | LoadModule alias_module modules/mod_alias.so 150 | #LoadModule rewrite_module modules/mod_rewrite.so 151 | 152 | 153 | # 154 | # If you wish httpd to run as a different user or group, you must run 155 | # httpd as root initially and it will switch. 156 | # 157 | # User/Group: The name (or #number) of the user/group to run httpd as. 158 | # It is usually good practice to create a dedicated user and group for 159 | # running httpd, as with most system services. 160 | # 161 | User daemon 162 | Group daemon 163 | 164 | 165 | 166 | # 'Main' server configuration 167 | # 168 | # The directives in this section set up the values used by the 'main' 169 | # server, which responds to any requests that aren't handled by a 170 | # definition. These values also provide defaults for 171 | # any containers you may define later in the file. 172 | # 173 | # All of these directives may appear inside containers, 174 | # in which case these default settings will be overridden for the 175 | # virtual host being defined. 176 | # 177 | 178 | # 179 | # ServerAdmin: Your address, where problems with the server should be 180 | # e-mailed. This address appears on some server-generated pages, such 181 | # as error documents. e.g. admin@your-domain.com 182 | # 183 | ServerAdmin me@olblak.com 184 | 185 | # 186 | # ServerName gives the name and port that the server uses to identify itself. 187 | # This can often be determined automatically, but we recommend you specify 188 | # it explicitly to prevent problems during startup. 189 | # 190 | # If your host doesn't have a registered DNS name, enter its IP address here. 191 | # 192 | #ServerName www.example.com:80 193 | 194 | # 195 | # Deny access to the entirety of your server's filesystem. You must 196 | # explicitly permit access to web content directories in other 197 | # blocks below. 198 | # 199 | 200 | AllowOverride none 201 | Require all denied 202 | 203 | 204 | # 205 | # Note that from this point forward you must specifically allow 206 | # particular features to be enabled - so if something's not working as 207 | # you might expect, make sure that you have specifically enabled it 208 | # below. 209 | # 210 | 211 | # 212 | # DocumentRoot: The directory out of which you will serve your 213 | # documents. By default, all requests are taken from this directory, but 214 | # symbolic links and aliases may be used to point to other locations. 215 | # 216 | DocumentRoot "/usr/local/apache2/htdocs" 217 | 218 | Options Indexes FollowSymLinks 219 | AllowOverride FileInfo 220 | Require all granted 221 | 222 | IndexOptions FancyIndexing VersionSort TrackModified FoldersFirst SuppressHTMLPreamble NameWidth=* SuppressRules SuppressIcon SuppressDescription 223 | 224 | HeaderName HEADER.html 225 | ReadmeName FOOTER.html 226 | 227 | IndexIgnore HEADER* FOOTER* index.html 228 | 229 | 230 | 231 | # 232 | # DirectoryIndex: sets the file that Apache will serve if a directory 233 | # is requested. 234 | # 235 | 236 | DirectoryIndex index.html 237 | 238 | 239 | # 240 | # The following lines prevent .htaccess and .htpasswd files from being 241 | # viewed by Web clients. 242 | # 243 | 244 | Require all denied 245 | 246 | 247 | # 248 | # ErrorLog: The location of the error log file. 249 | # If you do not specify an ErrorLog directive within a 250 | # container, error messages relating to that virtual host will be 251 | # logged here. If you *do* define an error logfile for a 252 | # container, that host's errors will be logged there and not here. 253 | # 254 | ErrorLog /proc/self/fd/2 255 | 256 | # 257 | # LogLevel: Control the number of messages logged to the error_log. 258 | # Possible values include: debug, info, notice, warn, error, crit, 259 | # alert, emerg. 260 | # 261 | LogLevel warn 262 | 263 | 264 | # 265 | # The following directives define some format nicknames for use with 266 | # a CustomLog directive (see below). 267 | # 268 | LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 269 | LogFormat "%h %l %u %t \"%r\" %>s %b" common 270 | 271 | 272 | # You need to enable mod_logio.c to use %I and %O 273 | LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio 274 | 275 | 276 | # 277 | # The location and format of the access logfile (Common Logfile Format). 278 | # If you do not define any access logfiles within a 279 | # container, they will be logged here. Contrariwise, if you *do* 280 | # define per- access logfiles, transactions will be 281 | # logged therein and *not* in this file. 282 | # 283 | CustomLog /proc/self/fd/1 common 284 | 285 | # 286 | # If you prefer a logfile with access, agent, and referer information 287 | # (Combined Logfile Format) you can use the following directive. 288 | # 289 | #CustomLog "logs/access_log" combined 290 | 291 | 292 | 293 | # 294 | # Redirect: Allows you to tell clients about documents that used to 295 | # exist in your server's namespace, but do not anymore. The client 296 | # will make a new request for the document at its new location. 297 | # Example: 298 | # Redirect permanent /foo http://www.example.com/bar 299 | 300 | # 301 | # Alias: Maps web paths into filesystem paths and is used to 302 | # access content that does not live under the DocumentRoot. 303 | # Example: 304 | # Alias /webpath /full/filesystem/path 305 | # 306 | # If you include a trailing / on /webpath then the server will 307 | # require it to be present in the URL. You will also likely 308 | # need to provide a section to allow access to 309 | # the filesystem path. 310 | 311 | # 312 | # ScriptAlias: This controls which directories contain server scripts. 313 | # ScriptAliases are essentially the same as Aliases, except that 314 | # documents in the target directory are treated as applications and 315 | # run by the server when requested rather than as documents sent to the 316 | # client. The same rules about trailing "/" apply to ScriptAlias 317 | # directives as to Alias. 318 | # 319 | ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" 320 | 321 | 322 | 323 | 324 | # 325 | # ScriptSock: On threaded servers, designate the path to the UNIX 326 | # socket used to communicate with the CGI daemon of mod_cgid. 327 | # 328 | #Scriptsock cgisock 329 | 330 | 331 | # 332 | # "/usr/local/apache2/cgi-bin" should be changed to whatever your ScriptAliased 333 | # CGI directory exists, if you have that configured. 334 | # 335 | 336 | AllowOverride None 337 | Options None 338 | Require all granted 339 | 340 | 341 | 342 | # 343 | # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied 344 | # backend servers which have lingering "httpoxy" defects. 345 | # 'Proxy' request header is undefined by the IETF, not listed by IANA 346 | # 347 | RequestHeader unset Proxy early 348 | 349 | 350 | 351 | # 352 | # TypesConfig points to the file containing the list of mappings from 353 | # filename extension to MIME-type. 354 | # 355 | TypesConfig conf/mime.types 356 | 357 | # 358 | # AddType allows you to add to or override the MIME configuration 359 | # file specified in TypesConfig for specific file types. 360 | # 361 | #AddType application/x-gzip .tgz 362 | # 363 | # AddEncoding allows you to have certain browsers uncompress 364 | # information on the fly. Note: Not all browsers support this. 365 | # 366 | #AddEncoding x-compress .Z 367 | #AddEncoding x-gzip .gz .tgz 368 | # 369 | # If the AddEncoding directives above are commented-out, then you 370 | # probably should define those extensions to indicate media types: 371 | # 372 | AddType application/x-compress .Z 373 | AddType application/x-gzip .gz .tgz 374 | 375 | # 376 | # AddHandler allows you to map certain file extensions to "handlers": 377 | # actions unrelated to filetype. These can be either built into the server 378 | # or added with the Action directive (see below) 379 | # 380 | # To use CGI scripts outside of ScriptAliased directories: 381 | # (You will also need to add "ExecCGI" to the "Options" directive.) 382 | # 383 | #AddHandler cgi-script .cgi 384 | 385 | # For type maps (negotiated resources): 386 | #AddHandler type-map var 387 | 388 | # 389 | # Filters allow you to process content before it is sent to the client. 390 | # 391 | # To parse .shtml files for server-side includes (SSI): 392 | # (You will also need to add "Includes" to the "Options" directive.) 393 | # 394 | #AddType text/html .shtml 395 | #AddOutputFilter INCLUDES .shtml 396 | 397 | 398 | # 399 | # The mod_mime_magic module allows the server to use various hints from the 400 | # contents of the file itself to determine its type. The MIMEMagicFile 401 | # directive tells the module where the hint definitions are located. 402 | # 403 | #MIMEMagicFile conf/magic 404 | 405 | # 406 | # Customizable error responses come in three flavors: 407 | # 1) plain text 2) local redirects 3) external redirects 408 | # 409 | # Some examples: 410 | #ErrorDocument 500 "The server made a boo boo." 411 | #ErrorDocument 404 /missing.html 412 | #ErrorDocument 404 "/cgi-bin/missing_handler.pl" 413 | #ErrorDocument 402 http://www.example.com/subscription_info.html 414 | # 415 | 416 | # 417 | # MaxRanges: Maximum number of Ranges in a request before 418 | # returning the entire resource, or one of the special 419 | # values 'default', 'none' or 'unlimited'. 420 | # Default setting is to accept 200 Ranges. 421 | #MaxRanges unlimited 422 | 423 | # 424 | # EnableMMAP and EnableSendfile: On systems that support it, 425 | # memory-mapping or the sendfile syscall may be used to deliver 426 | # files. This usually improves server performance, but must 427 | # be turned off when serving from networked-mounted 428 | # filesystems or if support for these functions is otherwise 429 | # broken on your system. 430 | # Defaults: EnableMMAP On, EnableSendfile Off 431 | # 432 | EnableMMAP off 433 | #EnableSendfile on 434 | 435 | # Supplemental configuration 436 | # 437 | # The configuration files in the conf/extra/ directory can be 438 | # included to add extra features or to modify the default configuration of 439 | # the server, or you may simply copy their contents here and change as 440 | # necessary. 441 | 442 | # Server-pool management (MPM specific) 443 | #Include conf/extra/httpd-mpm.conf 444 | 445 | # Multi-language error messages 446 | #Include conf/extra/httpd-multilang-errordoc.conf 447 | 448 | # Fancy directory listings 449 | #Include conf/extra/httpd-autoindex.conf 450 | 451 | # Language settings 452 | #Include conf/extra/httpd-languages.conf 453 | 454 | # User home directories 455 | #Include conf/extra/httpd-userdir.conf 456 | 457 | # Real-time info on requests and configuration 458 | #Include conf/extra/httpd-info.conf 459 | 460 | # Virtual hosts 461 | #Include conf/extra/httpd-vhosts.conf 462 | 463 | # Local access to the Apache HTTP Server Manual 464 | #Include conf/extra/httpd-manual.conf 465 | 466 | # Distributed authoring and versioning (WebDAV) 467 | #Include conf/extra/httpd-dav.conf 468 | 469 | # Various default settings 470 | #Include conf/extra/httpd-default.conf 471 | 472 | # Configure mod_proxy_html to understand HTML4/XHTML1 473 | 474 | Include conf/extra/proxy-html.conf 475 | 476 | 477 | # Secure (SSL/TLS) connections 478 | #Include conf/extra/httpd-ssl.conf 479 | # 480 | # Note: The following must must be present to support 481 | # starting without SSL on platforms with no /dev/random equivalent 482 | # but a statically compiled-in mod_ssl. 483 | # 484 | 485 | SSLRandomSeed startup builtin 486 | SSLRandomSeed connect builtin 487 | 488 | --------------------------------------------------------------------------------