Compare commits

...
5 Commits
Author SHA1 Message Date
Lauri Ojansivu cd0cd64849 v7.99 2025-10-11 06:13:27 +03:00
Lauri Ojansivu aab671398c Improve automatic Snap upgrades.
Thanks to xet7 !
2025-10-11 05:52:41 +03:00
Lauri Ojansivu d64aeb25d5 Updated ChangeLog. 2025-10-11 04:57:24 +03:00
Lauri Ojansivu aa4fa83127 Updated ChangeLog. 2025-10-11 04:50:23 +03:00
Lauri Ojansivu 81c3dc1d95 Security Fix JVN#15385465: CWE-79 XSS, that affected WeKan 7.94.
Thanks to Sho Sugiyama and xet7 !
2025-10-11 04:47:17 +03:00
17 changed files with 751 additions and 86 deletions

No files matched your search

+15 -2
View File
@@ -19,6 +19,15 @@ Fixing other platforms In Progress.
[Upgrade WeKan](https://wekan.fi/upgrade/)
# v7.99 2025-10-11 WeKan ® release
This release fixed the following bugs:
- [Improve automatic Snap upgrades](https://github.com/wekan/wekan/commit/aab671398c7ee3d7ea4934c6c9c977ad630fa74f).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.98 2025-10-11 WeKan ® release
This release adds the following CRITICAL SECURITY FIXES:
@@ -29,14 +38,18 @@ This release adds the following CRITICAL SECURITY FIXES:
Thanks to Anynymous Security Researcher and xet7.
- [Security Fix FG-VD-22-078: Prevent SVG Billion Laughs Attack](https://github.com/wekan/wekan/commit/30c1597b658b0ef50fd2efc56786e8b0f08ac72c).
Thanks to Nguyen Thanh Nguyen of Fortinet's FortiGuard Labs and xet7.
- [Security Fix usd-2022-0041: CWE-284 Improper Access Control](https://github.com/wekan/wekan/commit/f6591d7820e01075cba93612a5fdbf692fbe49dc).
Thanks to Christian Pöschl of usd AG and xet7.
- [Security Fix JVN#14269684: Broken access control](https://github.com/wekan/wekan/commit/9720e703fd9432bf0e1bfea2358f8c7ea078f1b1).
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7.
- [Security Fix JVN#74210258: Stored XSS](https://github.com/wekan/wekan/commit/e1fa607f87d821accb846f2deef1f388003848d1).
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7.
- [Security Fix JVN#86586539: Stored XSS](https://github.com/wekan/wekan/commit/ee79cab7b27f73fab62a00ec49add73fd6f7bcaa).
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7.
- [Security Fix usd-2022-0041: CWE-284 Improper Access Control](https://github.com/wekan/wekan/commit/f6591d7820e01075cba93612a5fdbf692fbe49dc).
Thanks to Christian Pöschl of usd AG and xet7.
- [Security Fix JVN#15385465: CWE-79 XSS, that affected WeKan 7.94](https://github.com/wekan/wekan/commit/81c3dc1d956cd7040655940f6569653d7b98fa9a).
Thanks to Sho Sugiyama and xet7.
- Security Fix JVN#80785288: CWE-79 XSS, that affected WeKan 3.94 and v3.95. This was already previously fixed.
Thanks to xet7.
and adds the following new features:
+3 -3
View File
@@ -249,9 +249,9 @@ cd /home/wekan/app
# Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc.
#rm -rf /home/wekan/app_build/bundle/programs/web.browser.legacy
#mv /home/wekan/app_build/bundle /build
wget "https://github.com/wekan/wekan/releases/download/v7.98/wekan-7.98-amd64.zip"
unzip wekan-7.98-amd64.zip
rm wekan-7.98-amd64.zip
wget "https://github.com/wekan/wekan/releases/download/v7.99/wekan-7.99-amd64.zip"
unzip wekan-7.99-amd64.zip
rm wekan-7.99-amd64.zip
mv /home/wekan/app/bundle /build
# Put back the original tar
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v7.98.0"
appVersion: "v7.99.0"
files:
userUploads:
- README.md
+2 -2
View File
@@ -10,7 +10,7 @@ This is without container (without Docker or Snap).
Right click and download files 1-4:
1. [wekan-7.98-amd64-windows.zip](https://github.com/wekan/wekan/releases/download/v7.98/wekan-7.98-amd64-windows.zip)
1. [wekan-7.99-amd64-windows.zip](https://github.com/wekan/wekan/releases/download/v7.99/wekan-7.99-amd64-windows.zip)
2. [node.exe](https://nodejs.org/dist/latest-v14.x/win-x64/node.exe)
@@ -22,7 +22,7 @@ Right click and download files 1-4:
6. Double click `mongodb-windows-x86_64-7.0.25-signed.msi` . In installer, uncheck downloading MongoDB compass.
7. Unzip `wekan-7.98-amd64-windows.zip` , inside it is directory `bundle`, to it copy other files:
7. Unzip `wekan-7.99-amd64-windows.zip` , inside it is directory `bundle`, to it copy other files:
```
bundle (directory)
+28 -5
View File
@@ -51,14 +51,37 @@ export function getSecureDOMPurifyConfig() {
return false;
}
// Block img tags with SVG data URIs
// Block img tags with SVG data URIs that could contain malicious JavaScript
if (node.tagName && node.tagName.toLowerCase() === 'img') {
const src = node.getAttribute('src');
if (src && (src.startsWith('data:image/svg') || src.endsWith('.svg'))) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked potentially malicious SVG image:', src);
if (src) {
// Block all SVG data URIs to prevent XSS via embedded JavaScript
if (src.startsWith('data:image/svg') || src.endsWith('.svg')) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked potentially malicious SVG image:', src);
}
return false;
}
// Additional check for base64 encoded SVG with script tags
if (src.startsWith('data:image/svg+xml;base64,')) {
try {
const base64Content = src.split(',')[1];
const decodedContent = atob(base64Content);
if (decodedContent.includes('<script') || decodedContent.includes('javascript:')) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked SVG with embedded JavaScript:', src.substring(0, 100) + '...');
}
return false;
}
} catch (e) {
// If decoding fails, block it as a safety measure
if (process.env.DEBUG === 'true') {
console.warn('Blocked malformed SVG data URI:', src);
}
return false;
}
}
return false;
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v7.98.0",
"version": "v7.99.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v7.98.0",
"version": "v7.99.0",
"description": "Open-Source kanban",
"private": true,
"repository": {
+28 -5
View File
@@ -51,14 +51,37 @@ export function getSecureDOMPurifyConfig() {
return false;
}
// Block img tags with SVG data URIs
// Block img tags with SVG data URIs that could contain malicious JavaScript
if (node.tagName && node.tagName.toLowerCase() === 'img') {
const src = node.getAttribute('src');
if (src && (src.startsWith('data:image/svg') || src.endsWith('.svg'))) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked potentially malicious SVG image:', src);
if (src) {
// Block all SVG data URIs to prevent XSS via embedded JavaScript
if (src.startsWith('data:image/svg') || src.endsWith('.svg')) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked potentially malicious SVG image:', src);
}
return false;
}
// Additional check for base64 encoded SVG with script tags
if (src.startsWith('data:image/svg+xml;base64,')) {
try {
const base64Content = src.split(',')[1];
const decodedContent = atob(base64Content);
if (decodedContent.includes('<script') || decodedContent.includes('javascript:')) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked SVG with embedded JavaScript:', src.substring(0, 100) + '...');
}
return false;
}
} catch (e) {
// If decoding fails, block it as a safety measure
if (process.env.DEBUG === 'true') {
console.warn('Blocked malformed SVG data URI:', src);
}
return false;
}
}
return false;
}
}
+78 -49
View File
@@ -103,58 +103,87 @@ Markdown.use(function(md) {
}
}
// Check for HTML tokens that might contain SVG
// Check for HTML tokens that might contain SVG or malicious content
if (token.type === 'html_block' || token.type === 'html_inline') {
const content = token.content;
if (content && (
content.includes('<svg') ||
content.includes('data:image/svg') ||
content.includes('xlink:href') ||
content.includes('<use') ||
content.includes('<defs>')
)) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked potentially malicious SVG content in HTML:', content.substring(0, 100) + '...');
if (content) {
// Check for SVG content
const hasSVG = content.includes('<svg') ||
content.includes('data:image/svg') ||
content.includes('xlink:href') ||
content.includes('<use') ||
content.includes('<defs>');
// Check for malicious img tags with SVG data URIs
const hasMaliciousImg = content.includes('<img') &&
(content.includes('data:image/svg') ||
content.includes('src="data:image/svg'));
// Check for base64 encoded SVG with script tags
const hasBase64SVG = content.includes('data:image/svg+xml;base64,');
if (hasSVG || hasMaliciousImg || hasBase64SVG) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked potentially malicious SVG content in HTML:', content.substring(0, 100) + '...');
}
// Additional check for base64 encoded SVG with script tags
if (hasBase64SVG) {
try {
const base64Match = content.match(/data:image\/svg\+xml;base64,([^"'\s]+)/);
if (base64Match) {
const decodedContent = atob(base64Match[1]);
if (decodedContent.includes('<script') || decodedContent.includes('javascript:')) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked SVG with embedded JavaScript in markdown');
}
}
}
} catch (e) {
// If decoding fails, continue with blocking
}
}
// Replace with warning
token.type = 'paragraph_open';
token.tag = 'p';
token.nesting = 1;
token.attrSet('style', 'color: red; background: #ffe6e6; padding: 8px; border: 1px solid #ff9999;');
token.attrSet('title', 'Blocked potentially malicious SVG content');
// Add warning text
const warningToken = {
type: 'text',
content: '⚠️ Blocked potentially malicious SVG content for security reasons',
level: token.level,
markup: '',
info: '',
meta: null,
block: true,
hidden: false
};
// Insert warning token after the paragraph open
tokens.splice(i + 1, 0, warningToken);
// Add paragraph close token
const closeToken = {
type: 'paragraph_close',
tag: 'p',
nesting: -1,
level: token.level,
markup: '',
info: '',
meta: null,
block: true,
hidden: false
};
tokens.splice(i + 2, 0, closeToken);
// Remove the original HTML token
tokens.splice(i, 1);
i--; // Adjust index since we removed a token
}
// Replace with warning
token.type = 'paragraph_open';
token.tag = 'p';
token.nesting = 1;
token.attrSet('style', 'color: red; background: #ffe6e6; padding: 8px; border: 1px solid #ff9999;');
token.attrSet('title', 'Blocked potentially malicious SVG content');
// Add warning text
const warningToken = {
type: 'text',
content: '⚠️ Blocked potentially malicious SVG content for security reasons',
level: token.level,
markup: '',
info: '',
meta: null,
block: true,
hidden: false
};
// Insert warning token after the paragraph open
tokens.splice(i + 1, 0, warningToken);
// Add paragraph close token
const closeToken = {
type: 'paragraph_close',
tag: 'p',
nesting: -1,
level: token.level,
markup: '',
info: '',
meta: null,
block: true,
hidden: false
};
tokens.splice(i + 2, 0, closeToken);
// Remove the original HTML token
tokens.splice(i, 1);
i--; // Adjust index since we removed a token
}
}
}
+2 -2
View File
@@ -1524,7 +1524,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<ul class="toc-list-h1">
<li>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v7.98">Wekan REST API v7.98</a>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v7.99">Wekan REST API v7.99</a>
</li>
@@ -2053,7 +2053,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<div class="page-wrapper">
<div class="dark-box"></div>
<div class="content">
<h1 id="wekan-rest-api">Wekan REST API v7.98</h1>
<h1 id="wekan-rest-api">Wekan REST API v7.99</h1>
<blockquote>
<p>Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.</p>
</blockquote>
+1 -1
View File
@@ -1,7 +1,7 @@
swagger: '2.0'
info:
title: Wekan REST API
version: v7.98
version: v7.99
description: |
The REST API allows you to control and extend Wekan with ease.
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
# Release script for wekan versions.
# 1) Check that there is only 2 parameters
# of Wekan version number:
if [ $# -ne 2 ]
then
echo "Syntax with Wekan current-version release-new-version:"
echo " ./release.sh 7.20 7.21"
exit 1
fi
sed -i 's|$1|$2|g' snapcraft.yaml docs/Platforms/Propietary/Windows/Offline.md Dockerfile Stackerfile.yml sandstorm-pkgdef.capnp
+2 -2
View File
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user.
appVersion = 798,
appVersion = 799,
# Increment this for every release.
appMarketingVersion = (defaultText = "7.98.0~2025-10-11"),
appMarketingVersion = (defaultText = "7.99.0~2025-10-11"),
# Human-readable presentation of the app version.
minUpgradableAppVersion = 0,
+188
View File
@@ -0,0 +1,188 @@
#!/bin/bash
# MongoDB Log Rotation Script for Wekan Snap
# This script handles log rotation for MongoDB logs in the Wekan snap environment
set -e
# Source settings if available, otherwise use defaults
if [ -f "$SNAP/bin/wekan-read-settings" ]; then
source $SNAP/bin/wekan-read-settings
else
# Default values when wekan-read-settings is not available
SNAP_COMMON="/var/snap/wekan/common"
SNAP_NAME="wekan"
fi
# Configuration
MONGODB_LOG="${SNAP_COMMON}/mongodb.log"
MAX_SIZE_MB=100
KEEP_COPIES=10
COMPRESS_LOGS=true
# Logging functions
log_message() {
local message="$1"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] $message"
}
log_error() {
local message="$1"
log_message "ERROR: $message"
}
log_success() {
local message="$1"
log_message "SUCCESS: $message"
}
log_warning() {
local message="$1"
log_message "WARNING: $message"
}
# Check if log file exists and is large enough to rotate
check_rotation_needed() {
if [ ! -f "$MONGODB_LOG" ]; then
log_message "MongoDB log file not found: $MONGODB_LOG"
return 1
fi
# Get log file size in MB
local log_size_mb=$(du -m "$MONGODB_LOG" | cut -f1)
if [ "$log_size_mb" -lt "$MAX_SIZE_MB" ]; then
log_message "MongoDB log size (${log_size_mb}MB) is below rotation threshold (${MAX_SIZE_MB}MB)"
return 1
fi
log_message "MongoDB log size (${log_size_mb}MB) exceeds rotation threshold (${MAX_SIZE_MB}MB)"
return 0
}
# Rotate MongoDB log file
rotate_log() {
local mongodb_log="$1"
local max_size_mb="$2"
local keep_copies="$3"
local compress="$4"
log_message "Starting MongoDB log rotation"
# Create rotated log file with timestamp
local timestamp=$(date +%Y%m%d-%H%M%S)
local rotated_log="${mongodb_log}.${timestamp}"
# Copy current log to rotated file
if cp "$mongodb_log" "$rotated_log"; then
log_message "Created rotated log file: $rotated_log"
# Truncate original log file
if > "$mongodb_log"; then
log_message "Truncated original log file"
else
log_error "Failed to truncate original log file"
return 1
fi
# Compress rotated log file if requested
if [ "$compress" = "true" ]; then
if gzip "$rotated_log"; then
log_message "Compressed rotated log file: ${rotated_log}.gz"
else
log_warning "Failed to compress rotated log file"
fi
fi
# Clean up old rotated logs (keep only specified number)
local old_logs=$(ls -t "${mongodb_log}".* 2>/dev/null | tail -n +$((keep_copies + 1)))
if [ -n "$old_logs" ]; then
echo "$old_logs" | xargs rm -f
log_message "Cleaned up old rotated log files"
fi
log_success "MongoDB log rotation completed successfully"
return 0
else
log_error "Failed to create rotated log file"
return 1
fi
}
# Show log file statistics
show_log_stats() {
if [ ! -f "$MONGODB_LOG" ]; then
log_message "MongoDB log file not found: $MONGODB_LOG"
return 1
fi
local log_size_mb=$(du -m "$MONGODB_LOG" | cut -f1)
local log_lines=$(wc -l < "$MONGODB_LOG" 2>/dev/null || echo "0")
local rotated_count=$(ls -1 "${MONGODB_LOG}".* 2>/dev/null | wc -l)
log_message "MongoDB Log Statistics:"
log_message " Current log size: ${log_size_mb}MB"
log_message " Current log lines: ${log_lines}"
log_message " Rotated log files: ${rotated_count}"
log_message " Rotation threshold: ${MAX_SIZE_MB}MB"
log_message " Keep copies: ${KEEP_COPIES}"
}
# Force rotation regardless of size
force_rotation() {
log_message "Force rotating MongoDB log file"
if [ ! -f "$MONGODB_LOG" ]; then
log_error "MongoDB log file not found: $MONGODB_LOG"
return 1
fi
rotate_log "$MONGODB_LOG" "$MAX_SIZE_MB" "$KEEP_COPIES" "$COMPRESS_LOGS"
}
# Main function
main() {
local action="${1:-check}"
case "$action" in
"check")
log_message "Checking if MongoDB log rotation is needed"
if check_rotation_needed; then
log_message "Log rotation is needed"
rotate_log "$MONGODB_LOG" "$MAX_SIZE_MB" "$KEEP_COPIES" "$COMPRESS_LOGS"
else
log_message "Log rotation is not needed"
fi
;;
"force")
force_rotation
;;
"stats")
show_log_stats
;;
"help"|"-h"|"--help")
echo "Usage: $0 [check|force|stats|help]"
echo ""
echo "Commands:"
echo " check - Check if rotation is needed and rotate if so (default)"
echo " force - Force rotation regardless of log size"
echo " stats - Show log file statistics"
echo " help - Show this help message"
echo ""
echo "Configuration:"
echo " Log file: $MONGODB_LOG"
echo " Max size: ${MAX_SIZE_MB}MB"
echo " Keep copies: $KEEP_COPIES"
echo " Compress: $COMPRESS_LOGS"
;;
*)
log_error "Unknown action: $action"
echo "Use '$0 help' for usage information"
exit 1
;;
esac
}
# Run main function
main "$@"
+175
View File
@@ -0,0 +1,175 @@
#!/bin/bash
# Wekan Log Rotation Setup Script
# This script sets up log rotation for Wekan snap installation
set -e
# Configuration
SNAP_NAME="wekan"
SNAP_COMMON="/var/snap/${SNAP_NAME}/common"
LOGROTATE_DIR="/etc/logrotate.d"
WEKAN_LOGROTATE_CONF="${LOGROTATE_DIR}/${SNAP_NAME}"
# Log file paths
MONGODB_LOG="${SNAP_COMMON}/mongodb.log"
WEKAN_APP_LOG="${SNAP_COMMON}/wekan-app.log"
WEKAN_ERROR_LOG="${SNAP_COMMON}/wekan-error.log"
# Log rotation configuration
ROTATE_SIZE="100M"
KEEP_DAYS="30"
KEEP_COPIES="10"
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
log_error() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >&2
}
# Check if running as root
if [ "$EUID" -ne 0 ]; then
log_error "This script must be run as root"
exit 1
fi
# Check if snap is installed
if ! snap list | grep -q "^${SNAP_NAME} "; then
log_error "Snap ${SNAP_NAME} is not installed"
exit 1
fi
log_message "Setting up log rotation for Wekan snap..."
# Create logrotate configuration
cat > "${WEKAN_LOGROTATE_CONF}" << EOF
# Wekan Snap Log Rotation Configuration
# Generated by wekan logrotate-setup script
# MongoDB logs
${MONGODB_LOG} {
daily
missingok
rotate ${KEEP_COPIES}
compress
delaycompress
notifempty
create 644 root root
postrotate
# Send SIGUSR1 to MongoDB to reopen log file
if [ -f "${SNAP_COMMON}/mongodb.pid" ]; then
kill -USR1 \$(cat "${SNAP_COMMON}/mongodb.pid") 2>/dev/null || true
fi
# Alternative: restart MongoDB service if PID file doesn't exist
if [ ! -f "${SNAP_COMMON}/mongodb.pid" ]; then
snap restart ${SNAP_NAME}.mongodb 2>/dev/null || true
fi
endscript
}
# Wekan application logs
${WEKAN_APP_LOG} {
daily
missingok
rotate ${KEEP_COPIES}
compress
delaycompress
notifempty
create 644 root root
postrotate
# Send SIGUSR1 to Wekan application to reopen log file
if [ -f "${SNAP_COMMON}/wekan.pid" ]; then
kill -USR1 \$(cat "${SNAP_COMMON}/wekan.pid") 2>/dev/null || true
fi
# Alternative: restart Wekan service if PID file doesn't exist
if [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
fi
endscript
}
# Wekan error logs
${WEKAN_ERROR_LOG} {
daily
missingok
rotate ${KEEP_COPIES}
compress
delaycompress
notifempty
create 644 root root
postrotate
# Send SIGUSR1 to Wekan application to reopen log file
if [ -f "${SNAP_COMMON}/wekan.pid" ]; then
kill -USR1 \$(cat "${SNAP_COMMON}/wekan.pid") 2>/dev/null || true
fi
# Alternative: restart Wekan service if PID file doesn't exist
if [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
fi
endscript
}
# Size-based rotation for large log files
${SNAP_COMMON}/*.log {
size ${ROTATE_SIZE}
missingok
rotate ${KEEP_COPIES}
compress
delaycompress
notifempty
create 644 root root
sharedscripts
postrotate
# Generic postrotate for all log files
# Try to signal processes to reopen log files
for pidfile in "${SNAP_COMMON}"/*.pid; do
if [ -f "\$pidfile" ]; then
kill -USR1 \$(cat "\$pidfile") 2>/dev/null || true
fi
done
# Restart services if no PID files found
if [ ! -f "${SNAP_COMMON}/mongodb.pid" ] && [ ! -f "${SNAP_COMMON}/wekan.pid" ]; then
snap restart ${SNAP_NAME}.mongodb 2>/dev/null || true
snap restart ${SNAP_NAME}.wekan 2>/dev/null || true
fi
endscript
}
EOF
log_message "Created logrotate configuration: ${WEKAN_LOGROTATE_CONF}"
# Test logrotate configuration
if logrotate -d "${WEKAN_LOGROTATE_CONF}" >/dev/null 2>&1; then
log_message "Logrotate configuration test passed"
else
log_error "Logrotate configuration test failed"
exit 1
fi
# Create log directory if it doesn't exist
mkdir -p "${SNAP_COMMON}"
# Set proper permissions
chown root:root "${WEKAN_LOGROTATE_CONF}"
chmod 644 "${WEKAN_LOGROTATE_CONF}"
# Create initial log files if they don't exist
touch "${MONGODB_LOG}" "${WEKAN_APP_LOG}" "${WEKAN_ERROR_LOG}"
chown root:root "${SNAP_COMMON}"/*.log
chmod 644 "${SNAP_COMMON}"/*.log
log_message "Log rotation setup completed successfully"
log_message "Configuration file: ${WEKAN_LOGROTATE_CONF}"
log_message "Log files will be rotated daily and when they exceed ${ROTATE_SIZE}"
log_message "Log files will be kept for ${KEEP_DAYS} days (${KEEP_COPIES} copies)"
log_message "To test log rotation manually: sudo logrotate -f ${WEKAN_LOGROTATE_CONF}"
log_message "To view logrotate status: sudo logrotate -d ${WEKAN_LOGROTATE_CONF}"
echo ""
echo "Next steps:"
echo "1. Configure MongoDB to log to file: sudo snap set ${SNAP_NAME} mongo-log-destination=snapcommon"
echo "2. Configure Wekan to log to file (if not already done)"
echo "3. Test log rotation: sudo logrotate -f ${WEKAN_LOGROTATE_CONF}"
echo "4. Monitor log files: ls -la ${SNAP_COMMON}/*.log*"
+207 -8
View File
@@ -77,6 +77,11 @@ log_success() {
log_message "SUCCESS: $message"
}
log_warning() {
local message="$1"
log_message "WARNING: $message"
}
# Disk space checking functions
check_disk_space() {
local required_space_gb="$1"
@@ -222,6 +227,28 @@ check_migration_needed() {
return 1
}
# Display MongoDB log content for debugging
display_mongodb_log_content() {
local mongodb_log="${SNAP_COMMON}/mongodb.log"
if [ ! -f "$mongodb_log" ]; then
log_message "MongoDB log file not found: $mongodb_log"
return 1
fi
log_message "MongoDB log file content (last 50 lines):"
if [ -r "$mongodb_log" ]; then
tail -50 "$mongodb_log" | while read -r line; do
log_message "LOG: $line"
done
else
log_message "MongoDB log file not readable, trying with sudo"
sudo tail -50 "$mongodb_log" 2>/dev/null | while read -r line; do
log_message "LOG: $line"
done
fi
}
# Detect if MongoDB upgrade is needed by checking log file
detect_mongodb_upgrade_needed() {
local mongodb_log="${SNAP_COMMON}/mongodb.log"
@@ -232,20 +259,168 @@ detect_mongodb_upgrade_needed() {
return 1
fi
# Check for the specific error message indicating upgrade is needed
if grep -q "This version of MongoDB is too recent to start up on the existing data files. Try MongoDB 4.2 or earlier." "$mongodb_log"; then
log_message "MongoDB upgrade needed detected in log file"
# Display log content for debugging
display_mongodb_log_content
# Check file permissions and try to read with appropriate method
if [ ! -r "$mongodb_log" ]; then
log_message "MongoDB log file not readable, trying with sudo"
# Try to read with sudo if not readable
if ! sudo grep -q "too recent to start up on the existing data files" "$mongodb_log" 2>/dev/null; then
log_message "No MongoDB upgrade needed detected in log file (via sudo)"
return 1
fi
else
# Check for various error messages that indicate upgrade is needed
# The exact message may vary between MongoDB versions
local upgrade_patterns=(
"This version of MongoDB is too recent to start up on the existing data files"
"too recent to start up on the existing data files"
"Try MongoDB 4.2 or earlier"
"unsupported format version"
"data files are incompatible"
"database files are incompatible"
"version too new"
"version too recent"
)
local found_upgrade_needed=false
for pattern in "${upgrade_patterns[@]}"; do
if grep -q "$pattern" "$mongodb_log" 2>/dev/null; then
log_message "Found upgrade pattern in log: '$pattern'"
found_upgrade_needed=true
break
fi
done
if [ "$found_upgrade_needed" = false ]; then
log_message "No MongoDB upgrade needed detected in log file"
return 1
fi
fi
log_message "MongoDB upgrade needed detected in log file"
return 0
}
# Log rotation function for MongoDB logs
rotate_mongodb_logs() {
local mongodb_log="${SNAP_COMMON}/mongodb.log"
local max_size_mb=100
local keep_copies=10
# Check if log file exists and is large enough to rotate
if [ ! -f "$mongodb_log" ]; then
log_message "MongoDB log file not found, skipping rotation"
return 0
fi
# Also check for similar error messages that might indicate upgrade issues
if grep -q "too recent to start up on the existing data files" "$mongodb_log"; then
log_message "MongoDB upgrade needed detected in log file (alternative message)"
# Get log file size in MB
local log_size_mb=$(du -m "$mongodb_log" | cut -f1)
if [ "$log_size_mb" -lt "$max_size_mb" ]; then
log_message "MongoDB log size (${log_size_mb}MB) is below rotation threshold (${max_size_mb}MB)"
return 0
fi
log_message "No MongoDB upgrade needed detected in log file"
return 1
log_message "Rotating MongoDB log file (size: ${log_size_mb}MB)"
# Create rotated log file with timestamp
local timestamp=$(date +%Y%m%d-%H%M%S)
local rotated_log="${mongodb_log}.${timestamp}"
# Copy current log to rotated file
if cp "$mongodb_log" "$rotated_log"; then
log_message "Created rotated log file: $rotated_log"
# Truncate original log file
if > "$mongodb_log"; then
log_message "Truncated original log file"
else
log_error "Failed to truncate original log file"
return 1
fi
# Compress rotated log file
if gzip "$rotated_log"; then
log_message "Compressed rotated log file: ${rotated_log}.gz"
else
log_warning "Failed to compress rotated log file"
fi
# Clean up old rotated logs (keep only specified number)
local old_logs=$(ls -t "${mongodb_log}".* 2>/dev/null | tail -n +$((keep_copies + 1)))
if [ -n "$old_logs" ]; then
echo "$old_logs" | xargs rm -f
log_message "Cleaned up old rotated log files"
fi
log_success "MongoDB log rotation completed successfully"
return 0
else
log_error "Failed to create rotated log file"
return 1
fi
}
# Enhanced log rotation function for migration logs
rotate_migration_logs() {
local migration_log="${SNAP_COMMON}/mongodb-migration-log.txt"
local max_size_mb=50
local keep_copies=5
# Check if migration log file exists and is large enough to rotate
if [ ! -f "$migration_log" ]; then
log_message "Migration log file not found, skipping rotation"
return 0
fi
# Get log file size in MB
local log_size_mb=$(du -m "$migration_log" | cut -f1)
if [ "$log_size_mb" -lt "$max_size_mb" ]; then
log_message "Migration log size (${log_size_mb}MB) is below rotation threshold (${max_size_mb}MB)"
return 0
fi
log_message "Rotating migration log file (size: ${log_size_mb}MB)"
# Create rotated log file with timestamp
local timestamp=$(date +%Y%m%d-%H%M%S)
local rotated_log="${migration_log}.${timestamp}"
# Copy current log to rotated file
if cp "$migration_log" "$rotated_log"; then
log_message "Created rotated migration log file: $rotated_log"
# Truncate original log file
if > "$migration_log"; then
log_message "Truncated original migration log file"
else
log_error "Failed to truncate original migration log file"
return 1
fi
# Compress rotated log file
if gzip "$rotated_log"; then
log_message "Compressed rotated migration log file: ${rotated_log}.gz"
else
log_warning "Failed to compress rotated migration log file"
fi
# Clean up old rotated logs (keep only specified number)
local old_logs=$(ls -t "${migration_log}".* 2>/dev/null | tail -n +$((keep_copies + 1)))
if [ -n "$old_logs" ]; then
echo "$old_logs" | xargs rm -f
log_message "Cleaned up old rotated migration log files"
fi
log_success "Migration log rotation completed successfully"
return 0
else
log_error "Failed to create rotated migration log file"
return 1
fi
}
# Reset MONGO_LOG_DESTINATION to devnull after successful migration
@@ -493,6 +668,18 @@ perform_migration() {
log_message "Starting MongoDB migration from version 3 to 7"
# Rotate MongoDB logs before migration if needed
log_message "Checking if MongoDB log rotation is needed"
if ! rotate_mongodb_logs; then
log_warning "MongoDB log rotation failed, continuing with migration"
fi
# Rotate migration logs before migration if needed
log_message "Checking if migration log rotation is needed"
if ! rotate_migration_logs; then
log_warning "Migration log rotation failed, continuing with migration"
fi
# Create backup before migration
log_message "Creating backup before migration"
if ! create_backup; then
@@ -572,6 +759,18 @@ EOF
log_success "MongoDB migration completed successfully"
# Rotate MongoDB logs after successful migration
log_message "Rotating MongoDB logs after successful migration"
if ! rotate_mongodb_logs; then
log_warning "MongoDB log rotation after migration failed"
fi
# Rotate migration logs after successful migration
log_message "Rotating migration logs after successful migration"
if ! rotate_migration_logs; then
log_warning "Migration log rotation after migration failed"
fi
# Reset MONGO_LOG_DESTINATION to devnull after successful migration
reset_mongo_log_destination
+4 -4
View File
@@ -1,5 +1,5 @@
name: wekan
version: '7.98'
version: '7.99'
base: core24
summary: Open Source kanban
description: |
@@ -203,9 +203,9 @@ parts:
# Cleanup
mkdir .build
cd .build
wget https://github.com/wekan/wekan/releases/download/v7.98/wekan-7.98-amd64.zip
unzip wekan-7.98-amd64.zip
rm wekan-7.98-amd64.zip
wget https://github.com/wekan/wekan/releases/download/v7.99/wekan-7.99-amd64.zip
unzip wekan-7.99-amd64.zip
rm wekan-7.99-amd64.zip
cd ..
##cd .build/bundle
##find . -type d -name '*-garbage*' | xargs rm -rf