Skip to content

Commit

Permalink
Merge pull request #217 from lbr38/devel
Browse files Browse the repository at this point in the history
4.14.2
  • Loading branch information
lbr38 authored Dec 12, 2024
2 parents 4ca96a6 + 3a14057 commit 3927a0c
Show file tree
Hide file tree
Showing 27 changed files with 604 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/phpcs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
image: lbr38/repomanager:latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Print PHP version
run: php --version
Expand Down Expand Up @@ -83,7 +83,7 @@ jobs:
image: lbr38/repomanager:latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Print PHP version
run: php --version
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/test-ansible-role.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Test ansible role

on:
push:
branches: [ devel ]
pull_request:
push:
branches: [ stable ]
jobs:
ansible:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install requirements
run: |
sudo apt update
sudo apt install nginx ansible -y
- name: Generate self-signed SSL certificate
run: |
sudo mkdir -p /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/private.key -out /etc/nginx/ssl/certificate.crt -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=repomanager.example.com"
- name: Start nginx
run: sudo systemctl start nginx

- name: Execute ansible playbook
run: sudo ansible-playbook --connection=local --inventory 127.0.0.1, $GITHUB_WORKSPACE/ansible/repomanager-playbook.yml

- name: Print docker containers
run: sudo docker ps
135 changes: 135 additions & 0 deletions .github/workflows/test-database-update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
name: Database update tests

on:
push:
branches: [ devel ]
pull_request:
push:
branches: [ stable ]
jobs:
test-database-update:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install docker-compose
run: |
sudo apt-get update
sudo apt-get install -y docker-compose
# Get all releases
# Format them to a key-value array
# Start from release index which is 4.0.0
# Pull images starting from release 4.0.0
# Then pull the next image of the index, etc..
- name: Test all releases update from lbr38/repomanager
run: |
RELEASES=$(curl -s https://api.github.com/repos/lbr38/repomanager/releases?per_page=10000 | jq -r '.[].name' | tac)
index="0"
declare -A RELEASES_ARRAY
for release in $RELEASES; do
RELEASES_ARRAY["$index"]="$release"
index=$((index+1))
done
for i in "${!RELEASES_ARRAY[@]}"; do
if [[ "${RELEASES_ARRAY[$i]}" == "4.0.0" ]]; then
start_index="$i"
break
fi
done
for ((i=start_index; i<${#RELEASES_ARRAY[@]}; i++)); do
release="${RELEASES_ARRAY[$i]}"
docker rm -f repomanager
docker system prune -a -f
echo -e "\nPulling image for release $release\n"
docker run -d --restart always --name repomanager \
-e FQDN=repomanager.test.com \
-e MAX_UPLOAD_SIZE=32M \
-p 8080:8080 \
-v /etc/localtime:/etc/localtime:ro \
-v /var/lib/docker/volumes/repomanager-data:/var/lib/repomanager \
-v /var/lib/docker/volumes/repomanager-repo:/home/repo \
lbr38/repomanager:$release
if [ $? -ne 0 ]; then
echo "Failed to pull image for release $release"
exit 1
fi
# Retrieve and check errors in container logs
while true; do
OUTPUT=$(docker logs repomanager -n10000)
# Check if the logs contains failed message
if echo "$OUTPUT" | grep -q -i "failed"; then
echo "Database update seems to have failed: $OUTPUT"
exit 1
fi
if echo "$OUTPUT" | grep -q -i "error"; then
echo "Database update seems to have failed: $OUTPUT"
exit 1
fi
# Quit the loop if the maintenance page is disabled (meaning the update is done)
if echo "$OUTPUT" | grep -q "Disabling maintenance page"; then
break
fi
sleep 2
done
done
# Finally, test the devel image
- name: Test devel image from lbr38/repomanager
run: |
docker rm -f repomanager
docker system prune -a -f
echo -e "\Build devel image\n"
cd ${GITHUB_WORKSPACE}/docker
sed -i 's/env:.*/env: devel/g' docker-compose.yml
sed -i 's/fqdn:.*/fqdn: repomanager.test.com/g' docker-compose.yml
docker-compose -f docker-compose.yml up -d
if [ $? -ne 0 ]; then
echo "Failed to build devel image"
exit 1
fi
# Retrieve and check errors in container logs
while true; do
OUTPUT=$(docker logs repomanager -n10000)
# Check if the logs contains failed message
if echo "$OUTPUT" | grep -q -i "failed"; then
echo "Database update seems to have failed: $OUTPUT"
exit 1
fi
# Check if the logs contains error message
if echo "$OUTPUT" | grep -q -i "error"; then
echo "Database update seems to have failed: $OUTPUT"
exit 1
fi
# Quit the loop if the maintenance page is disabled (meaning the update is done)
if echo "$OUTPUT" | grep -q "Disabling maintenance page"; then
break
fi
sleep 2
done
# Print final container logs output
echo "$OUTPUT"
11 changes: 11 additions & 0 deletions ansible/repomanager-playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
- name: Install or update Repomanager
hosts: all
order: sorted
become: true
become_user: root

tasks:
- name: Execute repomanager role
ansible.builtin.include_role:
name: repomanager
5 changes: 5 additions & 0 deletions ansible/roles/repomanager/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: Reload nginx
ansible.builtin.systemd:
name: nginx
state: reloaded
38 changes: 38 additions & 0 deletions ansible/roles/repomanager/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
# Requirements:
# - docker installed and service running
# - nginx installed and service running
# - variables in vars/repomanager.yml must be set

# Include the variables
- name: Include repomanager variables
ansible.builtin.include_vars: repomanager.yml

# Pull the latest docker image and start the container
# This also works in a case of a new version, the image will be pulled and the container will be restarted
- name: Pull latest docker image
community.docker.docker_container:
name: repomanager
image: lbr38/repomanager:latest
env:
FQDN: "{{ repomanager_fqdn }}"
MAX_UPLOAD_SIZE: "{{ repomanager_vhost_max_upload_size | default('32') }}M"
ports:
- "{{ repomanager_listen_port | default('8080') }}:8080"
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/lib/docker/volumes/repomanager-data:/var/lib/repomanager
- /var/lib/docker/volumes/repomanager-repo:/home/repo
restart_policy: unless-stopped
pull: true
state: started

# Deploy the reverse-proxy vhost
- name: Deploy reverse-proxy
ansible.builtin.template:
src: repomanager-reverse-proxy.j2
dest: /etc/nginx/conf.d/repomanager-reverse-proxy.conf
owner: root
group: root
mode: "0600"
notify: Reload nginx
60 changes: 60 additions & 0 deletions ansible/roles/repomanager/templates/repomanager-reverse-proxy.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
upstream repomanager_docker {
server 127.0.0.1:{{ repomanager_listen_port }};
}

# Disable some logging
map $request_uri $loggable {
/ajax/controller.php 0;
default 1;
}

server {
listen {{ ansible_default_ipv4.address }}:80;
server_name {{ repomanager_fqdn }};

access_log /var/log/nginx/{{ repomanager_fqdn }}_access.log combined if=$loggable;
error_log /var/log/nginx/{{ repomanager_fqdn }}_error.log;

return 301 https://$server_name$request_uri;
}

server {
listen {{ ansible_default_ipv4.address }}:443 ssl;
server_name {{ repomanager_fqdn }};

# Path to SSL certificate/key files
ssl_certificate {{ repomanager_vhost_certificate_path }};
ssl_certificate_key {{ repomanager_vhost_private_key_path }};

# Path to log files
access_log /var/log/nginx/{{ repomanager_fqdn }}_ssl_access.log combined if=$loggable;
error_log /var/log/nginx/{{ repomanager_fqdn }}_ssl_error.log;

# Max upload size
client_max_body_size {{ repomanager_vhost_max_upload_size | default('32') }}M;

# Security headers
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;

# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;

location / {
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
proxy_pass http://repomanager_docker;
}
}
15 changes: 15 additions & 0 deletions ansible/roles/repomanager/vars/repomanager.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
# The FQDN of Repomanager
repomanager_fqdn: repomanager.example.com

# The port the container listens on (default: 8080)
repomanager_listen_port: 8080

# The maximum upload size in MB (default: 32M)
repomanager_vhost_max_upload_size: 32

# Path to the SSL certificate
repomanager_vhost_certificate_path: /etc/nginx/ssl/certificate.crt

# Path to the SSL private key
repomanager_vhost_private_key_path: /etc/nginx/ssl/private.key
7 changes: 6 additions & 1 deletion docker/init
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,14 @@ fi
/usr/sbin/service postfix start

# Initialize and update database (if needed)
/bin/su -s /bin/bash -c "/usr/bin/php $WWW_DIR/tools/database/initialize.php" www-data
/bin/su -s /bin/bash -c "/usr/bin/php $WWW_DIR/tools/database/initialize.php" www-data &&
/bin/su -s /bin/bash -c "/usr/bin/php $WWW_DIR/tools/database/update.php" www-data

if [ $? -ne 0 ];then
echo "Database initialization failed"
exit 1
fi

# Start shell service in background
/bin/bash "$WWW_DIR/bin/service" &

Expand Down
2 changes: 1 addition & 1 deletion www/controllers/App/Config/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static function get()
$message = '<span>A new release is available: ';
}

$message .= '<a href="https://github.com/lbr38/repomanager/releases/latest" target="_blank" rel="noopener noreferrer" title="See changelog"><code>' . GIT_VERSION . '</code> <img src="/assets/icons/external-link.svg" class="icon" /></a>';
$message .= '<a href="' . PROJECT_GIT_REPO . '/releases/latest" target="_blank" rel="noopener noreferrer" title="See changelog"><code>' . GIT_VERSION . '</code> <img src="/assets/icons/external-link.svg" class="icon" /></a>';
$message .= '<br><br><span>Please update your docker image by following the steps documented <b><a href="' . PROJECT_UPDATE_DOC_URL . '" target="_blank" rel="noopener noreferrer"><code>here</code></b> <img src="/assets/icons/external-link.svg" class="icon" /></a></span>';

$NOTIFICATION_MESSAGES[] = array('Title' => 'Update available', 'Message' => $message);
Expand Down
26 changes: 14 additions & 12 deletions www/controllers/Repo/Mirror/Deb.php
Original file line number Diff line number Diff line change
Expand Up @@ -723,18 +723,20 @@ private function downloadDebPackages($url)

/**
* Rename package if arch is not correctly specified in its name
*/
$debPackageName = preg_replace('/-amd64.deb$/', '_amd64.deb', $debPackageName);
$debPackageName = preg_replace('/-arm64.deb$/', '_arm64.deb', $debPackageName);
$debPackageName = preg_replace('/-armel.deb$/', '_armel.deb', $debPackageName);
$debPackageName = preg_replace('/-armhf.deb$/', '_armhf.deb', $debPackageName);
$debPackageName = preg_replace('/-i386.deb$/', '_i386.deb', $debPackageName);
$debPackageName = preg_replace('/-mips.deb$/', '_mips.deb', $debPackageName);
$debPackageName = preg_replace('/-mips64el.deb$/', '_mips64el.deb', $debPackageName);
$debPackageName = preg_replace('/-mipsel.deb$/', '_mipsel.deb', $debPackageName);
$debPackageName = preg_replace('/-ppc64el.deb$/', '_ppc64el.deb', $debPackageName);
$debPackageName = preg_replace('/-s390x.deb$/', '_s390x.deb', $debPackageName);
$debPackageName = preg_replace('/-all.deb$/', '_all.deb', $debPackageName);
* e.g. filebeat-8.0.0-amd64.deb -> filebeat-8.0.0_amd64.deb
* e.g. filebeat-8.0.0.amd64.deb -> filebeat-8.0.0_amd64.deb
*/
$debPackageName = preg_replace('/[-.]amd64.deb$/', '_amd64.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]arm64.deb$/', '_arm64.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]armel.deb$/', '_armel.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]armhf.deb$/', '_armhf.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]i386.deb$/', '_i386.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]mips.deb$/', '_mips.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]mips64el.deb$/', '_mips64el.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]mipsel.deb$/', '_mipsel.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]ppc64el.deb$/', '_ppc64el.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]s390x.deb$/', '_s390x.deb', $debPackageName);
$debPackageName = preg_replace('/[-.]all.deb$/', '_all.deb', $debPackageName);

/**
* Check if file does not already exists before downloading it (e.g. copied from a previously snapshot)
Expand Down
Loading

0 comments on commit 3927a0c

Please sign in to comment.