Skip to content

Instantly share code, notes, and snippets.

@blankoworld
Forked from jthoenes/upgrade_dokuwiki.rb
Created April 12, 2014 11:21
Show Gist options
  • Save blankoworld/10530850 to your computer and use it in GitHub Desktop.
Save blankoworld/10530850 to your computer and use it in GitHub Desktop.
#! /usr/bin/env ruby
=begin
This script backups and updates all dokuwiki installations on this server
Copyright (c) 2010 by Johannes Thönes <johannes.thoenes@googlemail.com>
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
Found here: https://gist.github.com/jthoenes/285219
Modified by Olivier Dossmann <olivier+multidokuwiki@dossmann.net>
=end
# Library Requirements (need to install rubygems, ruby-dev and gem install libarchive on Debian)
require 'net/http' # for download of the files
require 'open-uri' # for download of the files
require 'fileutils' # for file operation
include FileUtils
require 'tmpdir' # for Dir.tmpdir
require 'date' # for time
require 'rubygems' # Rubygems for the following libs
require 'libarchive_ruby' # for archive extraction
require 'pathname' # for some path in archive to be created
# Permissions to give to installations
DIR_OWNER = 'www-data'
DIR_GROUP = 'www-data'
# Definition of existing installation (dokuwiki should be installed in a directory named 'dokuwiki'). For an example /srv/site1/dokuwiki.
INSTALLATIONS = [
'/srv/toile/dossmann/olivier/wiki',
'/srv/toile/depotoire/lerna/wiki'
].freeze
# Files to remove Gist
OLD_FILES_URL = 'https://github.com/splitbrain/dokuwiki/raw/stable/data/deleted.files'
# Helper Function (change here, if you want to customize something)
def backup_folder_base
@backup_folder_base ||= "#{Dir.tmpdir}/dokuwiki_backup_#{DateTime.now.strftime('%Y%m%d-%H%M%S')}"
end
def download_location uri
"#{Dir.tmpdir}/#{release_package_name(uri)}"
end
def release_package_name uri
uri.path.split('/').last
end
def release_name uri
release_package_name(uri).split('.').first
end
def walk_archive location
Archive.read_open_filename(location) do |archive|
while entry = archive.next_header
location = entry.pathname.split('/').reject{|dirname| dirname =~ /dokuwiki-\S{32}/dokuwiki/}
data = archive.read_data
yield(location, entry, data)
end
end
end
def apply_to_installation_path rel_path
INSTALLATIONS.each do |inst|
yield("#{inst}/#{rel_path}")
end
end
def create_data_folder_if_not_exists rel_path
apply_to_installation_path(rel_path) do |path|
unless File.directory?(path)
raise "'#{path}' exists but is not a directory" if File.exists?(path)
mkdir path
chown_R 'www-data', 'www-data', path
chmod_R 664, path
end
end
end
def create_folder_if_not_exists rel_path, entry
apply_to_installation_path(rel_path) do |path|
unless File.directory?(path)
raise "'#{path}' exists but is not a directory" if File.exists?(path)
mkdir path
chmod entry.mode, path
end
end
end
def create_destination_folder_if_not_exists rel_path
apply_to_installation_path(rel_path) do |path|
unless File.directory?(path)
raise "'#{path}' exists but is not a directory" if File.exists?(path)
mkdir path
end
end
end
def copy_file rel_path, entry, data
apply_to_installation_path(rel_path) do |path|
File.open(path, 'w', entry.mode) {|f| f.write(data)}
end
end
def delete_file_if_exists rel_path
apply_to_installation_path(rel_path) do |path|
rm(path) if File.exists?(path)
end
end
# Parameter extraction
raise "You need to supply the current dokuwiki release download. See here: http://download.dokuwiki.org/" if ARGV.first.nil?
package_uri = URI.parse(ARGV.first)
# Backup existing locations to a folder in tempdir
raise "Backup Folder '#{backup_folder_base}' already exists" if File.exists?(backup_folder_base)
mkdir backup_folder_base
INSTALLATIONS.each do |installation|
cp_r installation, backup_folder_base
end
# Downloading the newest dokuwiki package
archive_loc = download_location(package_uri)
Net::HTTP.start(package_uri.host) do |http|
response = http.get(package_uri.path)
File.open(download_location(package_uri), 'w') {|f| f.write(response.body)}
end
# Copy the new package (except the /data folder) into the the directories
walk_archive(archive_loc) do |location, entry, data|
if (location.first == 'data')
create_data_folder_if_not_exists(location.join('/')) if entry.directory?
else
# fetch entry pathname to see if directory in which entry is exists in the destination
current_path = Pathname.new(entry.pathname)
dir = current_path.dirname
create_destination_folder_if_not_exists(dir) if not dir.exist?
create_folder_if_not_exists(location.join('/'), entry) if entry.directory?
copy_file(location.join('/'), entry, data) unless entry.directory?
end
end
# Delete old files
open(OLD_FILES_URL) do |f|
f.each_line do |rel_path|
if rel_path !~ /^#/ and rel_path.strip.length != 0
delete_file_if_exists(rel_path)
end
end
end
# Set permissions on the whole directories
INSTALLATIONS.each do |path|
chown_R DIR_OWNER, DIR_GROUP, path
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment