Part 1: Setting up the servers
yum install ntp
ntpdate time.nist.gov
service ntpd start
/etc/ntp.conf
file to use the following servers:server 0.pool.ntp.org server 1.pool.ntp.org server 2.pool.ntp.org server 3.pool.ntp.org
service ntpd restart
chkconfig ntpd on
RedHat Cluster must be set up before the GFS2 File systems can be created and mounted.
yum install openais cman rgmanager lvm2-cluster gfs2-utils ccs
/etc/cluster/cluster.conf
REMEMBER: Always increment the “config_version” parameter in the cluster
tag!
<?xml version=“1.0”?> <cluster config_version=“24” name=“web-production”> <cman expected_votes=“1” two_node=“1”/> <fence_daemon clean_start=“1” post_fail_delay=“6” post_join_delay=“3”/> <totem rrp_mode=“none” secauth=“off”/> <clusternodes> <clusternode name=“bill” nodeid="1"> <fence> <method name="ipmi"> <device action=“reboot” name=“ipmi_bill”/> </method> </fence> </clusternode> <clusternode name=“ted” nodeid="2"> <fence> <method name="ipmi"> <device action=“reboot” name=“ipmi_ted”/> </method> </fence> </clusternode> </clusternodes> <fencedevices> <fencedevice agent=“fence_ipmilan” ipaddr=“billsp” login=“root” name=“ipmi_bill” passwd=“PASSWORD-HERE”/> <fencedevice agent=“fence_ipmilan” ipaddr=“tedsp” login=“root” name=“ipmi_ted” passwd=“PASSWORD-HERE”/> </fencedevices> <rm log_level="5"> <resources> <clusterfs device=“/dev/mapper/StorageTek2530-sites” fstype=“gfs2” mountpoint=“/sites” name=“sites”/> <clusterfs device=“/dev/mapper/StorageTek2530-databases” fstype=“gfs2” mountpoint=“/databases” name=“databases”/> <clusterfs device=“/dev/mapper/StorageTek2530-logs” fstype=“gfs2” mountpoint=“/logs” name=“logs”/> </resources> <failoverdomains> <failoverdomain name=“bill-only” nofailback=“1” ordered=“0” restricted="1"> <failoverdomainnode name=“bill”/> </failoverdomain> <failoverdomain name=“ted-only” nofailback=“1” ordered=“0” restricted="1"> <failoverdomainnode name=“ted”/> </failoverdomain> </failoverdomains> </rm> </cluster>
ccs_config_validate
passwd ricci
service ricci start
chkconfig ricci on
service modclusterd start
chkconfig modclusterd on
ccs -f /etc/cluster/cluster.conf -h ted --setconf
service cman start
chkconfig cman on
Create a partition on the new scsi device /dev/mapper/mpatha using parted. NOTE: This part only needs to be done once on one server
parted /dev/mapper/mpatha
mklabel gpt
mkpart primary 1 -1
set 1 lvm on
quit
parted -l
Edit the /etc/lvm/lvm.conf file
and set the value for locking_type = 3
to allow for cluster locking.
In order to enable the LVM volumes you are creating in a cluster, the cluster infrastructure must be running and the cluster must be quorate.
service clvmd start
chkconfig clvmd on
chkconfig gfs2 on
Create LVM partitions on the raw drive available from the StorageTek. NOTE: This part only needs to be done once on one server.
pvcreate /dev/mapper/mpatha1
vgcreate -c y StorageTek2530 /dev/mapper/mpatha1
Now create the different partitions for the system: sites, databases, logs, home, root
lvcreate --name sites --size 350GB StorageTek2530
lvcreate --name databases --size 100GB StorageTek2530
lvcreate --name logs --size 50GB StorageTek2530
lvcreate --name root --size 50GB StorageTek2530
Make a temporary directory /root-b
and copy everything from root’s home directory to there, because it will be erased when we make the GFS2 file system.
Copy /root/.ssh/known_hosts to /etc/ssh/root_known_hosts so the file is different for both servers.
Before doing the home directory, we have to remove it from the local LVM.
unmount /home
lvremove bill_local/home
and on ted lvremove ted_local/home
/etc/fstab
referring to the /home directory on the local LVMlvcreate --name home --size 50GB StorageTek2530
Create GFS2 files systems on the LVM partitions created on the StorageTek. Make sure they are unmounted, first. NOTE: This part only needs to be done once on one server.
mkfs.gfs2 -p lock_dlm -j 2 -t web-production:sites /dev/mapper/StorageTek2530-sites
mkfs.gfs2 -p lock_dlm -j 2 -t web-production:databases /dev/mapper/StorageTek2530-databases
mkfs.gfs2 -p lock_dlm -j 2 -t web-production:logs /dev/mapper/StorageTek2530-logs
mkfs.gfs2 -p lock_dlm -j 2 -t web-production:root /dev/mapper/StorageTek2530-root
mkfs.gfs2 -p lock_dlm -j 2 -t web-production:home /dev/mapper/StorageTek2530-home
Mount the GFS2 partitions
Make the appropriate folders on each node (/home is already there).
mkdir /sites /logs /databases
Make sure the appropriate lines are in /etc/fstab
#GFS2 partitions shared in the cluster /dev/mapper/StorageTek2530-root /root gfs2 defaults,acl 0 0 /dev/mapper/StorageTek2530-home /home gfs2 defaults,acl 0 0 /dev/mapper/StorageTek2530-databases /databases gfs2 defaults,acl 0 0 /dev/mapper/StorageTek2530-logs /logs gfs2 defaults,acl 0 0 /dev/mapper/StorageTek2530-sites /sites gfs2 defaults,acl 0 0
Once the GFS2 partitions are set up and in /etc/fstab
, rgmanager can be started. This will mount the GFS2 partions.
service rgmanager start
chkconfig rgmanager on
To start the cluster software on a node, type the following commands in this order:
service cman start
service clvmd start
service gfs2 start
service rgmanager start
To stop the cluster software on a node, type the following commands in this order:
service ossec-hids stop
service rgmanager stop
service gfs2 stop
umount -at gfs2
service clvmd stop
service cman stop
If a service shows as ‘failed’ when checking on services with clustat
clusvcadm -d service-name
clusvcadm -e service-name
Have Shorewall start sooner in the boot process.
/etc/init.d/shorewall
and change the line near the top from # chkconfig: - 28 90
to
# chkconfig: - 18 90
chkconfig shorewall off
chkconfig shorewall on
The only problem I face with this set up, though, is that I have multiple production servers out there. So this only works if this backup server could be a slave for multiple machines.
This is not possible, though, because, of course, no slave can serve two masters. Fortunately, a server can have multiple instances of MySQL running on it! So, in a sense, we have a server with multiple MySQL instances, to which a master can replicate. More about that set up in an upcoming post.
A how to on this blog, shows how this can be done. I’ll replicate the process below.
We’ll be working with CentOS 5.8, but this could really apply for any OS. First we’ll need to install MySQL like normal.
yum install mysql mysql-server
There are plenty of good tutorials out there on how to install the specific version of MySQL you want on the specific OS you’re running.
You’ll need to have a different folder for each of the MySQL instances, say /dbases/master-a/
, /dbases/master-b/
, and /dbases/master-c/
.
mkdir -p /dbases/{master-a,master-b,master-c}
This is the default MySQL config file, it may be named differently on other OSes.
cp /etc/my.cnf /etc/master-a.cnf; cp /etc/my.cnf /etc/master-b.cnf; cp /etc/my.cnf /etc/master-c.cnf
For each new config file, you’ll need to specify some unique variables.
[mysqld] port=3307 datadir=/dbases/master-a socket=/dbases/master-a/mysql.sock user=mysql server_id=3307 log-bin=/dbases/master/mysql-bin.log # Disabling symbolic-links is recommended to prevent assorted security risks; # to do so, uncomment this line: symbolic-links=0 [mysqld_safe] log-error=/dbases/master-a/mysqld.log pid-file=/dbases/master-a/mysqld.pid
The port
option sets this MySQL instance on a different port than the default 3306. The datadir
, socket
, log-bin
, log-error
, and pid-file
options make sure the necessary files are not using the default files.
The init script allows the server to start and stop the service at boot time, and allows for easy start up and shutdown (on CentOS/RedHat, at least – with an easy service mysqld start
).
cp /etc/init.d/mysqld /etc/init.d/mysqld-master-a
Just do one for now. We’ll copy the new one to create the others, then just do a quick search and replace in those files to change the master-a to master-b and master-c.
#!/bin/bash # # mysqld This shell script takes care of starting and stopping # the MySQL subsystem (mysqld). # # chkconfig: - 64 36 # description: MySQL database server. # processname: mysqld # config: /etc/master-a.cnf # pidfile: /dbases/master-a/mysqld.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network prog="MySQL" # extract value of a MySQL option from config files # Usage: get_mysql_option SECTION VARNAME DEFAULT # result is returned in $result # We use my_print_defaults which prints all options from multiple files, # with the more specific ones later; hence take the last match. get_mysql_option(){ result=/usr/bin/my_print_defaults "$1" | sed -n "s/^--$2=//p" | tail -n 1
if [ -z "$result" ]; then # not found, use default result="$3" fi } get_mysql_option mysqld datadir "/dbases/master-a" datadir="/dbases/master-a" get_mysql_option mysqld socket "/dbases/master-a/mysql.sock" socketfile="/dbases/master-a/mysql.sock" get_mysql_option mysqld_safe log-error "/dbases/master-a/mysqld.log" errlogfile="/dbases/master-a/mysqld.log" get_mysql_option mysqld_safe pid-file "/dbases/master-a/mysqld.pid" mypidfile="/dbases/master-a/mysqld.pid" defaultfile="/etc/master-a.cnf" start(){ touch "$errlogfile" chown mysql:mysql "$errlogfile" chmod 0640 "$errlogfile" [ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile" if [ ! -d "$datadir/mysql" ] ; then action $"Initializing MySQL database: " /usr/bin/mysql_install_db --datadir="$datadir" --user=mysql ret=$? chown -R mysql:mysql "$datadir" if [ $ret -ne 0 ] ; then return $ret fi fi chown mysql:mysql "$datadir" chmod 0755 "$datadir" # Pass all the options determined above, to ensure consistent behavior. # In many cases mysqld_safe would arrive at the same conclusions anyway # but we need to be sure. /usr/bin/mysqld_safe --defaults-file="$defaultfile" --datadir="$datadir" --socket="$socketfile" \ --log-error="$errlogfile" --pid-file="$mypidfile" \ --user=mysql >/dev/null 2>&1 & ret=$? # Spin for a maximum of N seconds waiting for the server to come up. # Rather than assuming we know a valid username, accept an "access # denied" response as meaning the server is functioning. if [ $ret -eq 0 ]; then STARTTIMEOUT=30 while [ $STARTTIMEOUT -gt 0 ]; do RESPONSE=/usr/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1
&& break echo "$RESPONSE" | grep -q "Access denied for user" && break sleep 1 let STARTTIMEOUT=${STARTTIMEOUT}-1 done if [ $STARTTIMEOUT -eq 0 ]; then echo "Timeout error occurred trying to start MySQL Daemon." action $"Starting $prog: " /bin/false ret=1 else action $"Starting $prog: " /bin/true fi else action $"Starting $prog: " /bin/false fi [ $ret -eq 0 ] && touch /dbases/master-a/mysqld return $ret } stop(){ MYSQLPID=cat "$mypidfile" 2>/dev/null
if [ -n "$MYSQLPID" ]; then /bin/kill "$MYSQLPID" >/dev/null 2>&1 ret=$? if [ $ret -eq 0 ]; then STOPTIMEOUT=60 while [ $STOPTIMEOUT -gt 0 ]; do /bin/kill -0 "$MYSQLPID" >/dev/null 2>&1 || break sleep 1 let STOPTIMEOUT=${STOPTIMEOUT}-1 done if [ $STOPTIMEOUT -eq 0 ]; then echo "Timeout error occurred trying to stop MySQL Daemon." ret=1 action $"Stopping $prog: " /bin/false else rm -f /dbases/master-a/mysqld rm -f "$socketfile" action $"Stopping $prog: " /bin/true fi else action $"Stopping $prog: " /bin/false fi else ret=1 action $"Stopping $prog: " /bin/false fi return $ret } restart(){ stop start } condrestart(){ [ -e /dbases/master-a/mysqld ] && restart || : } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status mysqld ;; restart) restart ;; condrestart) condrestart ;; *) echo $"Usage: $0 {start|stop|status|condrestart|restart}" exit 1 esac exit $?
Now you can start each instance with the handy service
command.
service mysqld-master-a start
Now, to connect to each MySQL instance, you’ll need to specify the port and/or socket file.
mysql -P3307 --socket="/dbases/mysql-master-a/mysql.sock"]]>
One of the most frustrating parts of this set up was getting the storage array talking to the servers. I finally got it figured out. I’m using a StorageTek 2530 to connect to two SunFire X2100 M2’s via SAS (Serial Attached SCSI) cables. I put in a dual port SAS HBA (Host Bus Adapter) in the X2100 M2’s, but for real redundancy, I should have used two single port HBA’s. The Sun/Oracle documentation is pretty good about how to physically set up the servers and storage array, but are pretty lacking from there on.
Replace the parts in squares brackets below with whatever you want.
yum install ksh bc /lib/ld-linux.so.2 libgcc.i686 libstdc++.i686 libzip.i686 gettext
rpm -Uvh jdk-6u20-linux-i586.rpm
./RunMe.bin -c
/opt/sun/cam/bin
folder to path
setenv PATH ${PATH}:/opt/sun/cam/bin
source .tcshrc
/etc/sysconfig/network-scripts/ifcfg-eth1:1
file and put this in there
rpm -ivh SMruntime.xx.xx.xx.xx-xxxx.rpm
rpm -ivh SMagent-LINUX-xx.xx.xx.xx-xxxx.rpm
sscs register -d storage-system
sscs modify -T [Array-Name] array ARRAY1
sscs create -a knox pool [Pool-Name]
sscs create -a knox -p [Pool-Name] -n 11 vdisk [Vdisk-Name]
sscs create -a knox -p [Pool-Name] -s max -v [Vdisk-Name] volume [Volume-Name]
sscs create -a knox hostgroup [ApacheHosts]
sscs create -a knox -g [ApacheHosts] host [Host-Name]
and repeat for other hosts.sscs map -a knox -g ApacheHosts volume Volume-Name
It took me a while to grasp the meaning for the different terms: pool, volume, volume groups, disks, etc. I drew up a chart with the appropriate commands to create the different aspects.
To utilize both cables connecting the server to the storage array, the OS needs to use multi-pathing. I had lots of troubles trying to set this up after the OS was installed, so I just let it be done by the installer. Here’s what should happen if you find the OS already installed and need to set up multi-paths.
/dev/mapper/mpatha
. This will be the device to partition, format, and throw LVM on.yum install device-mapper-multipath
mpathconf --enable
to create a default /etc/multipath.conf
file or create one using the following:
chkconfig multipathd on
service multipathd start
First of all, I’ll cover what set up I would like to achieve and why.
I’m using two Sun SunFire X2100 M2 connected to a StorageTek 2530 with 4.5TB of drive space. The servers attach to the storage array via SCSI cables for quick data transfer speeds. The array also has the ability to handle iSCSI connections. This will give me a decent base set up, with room to grow.
I’ll put the two servers in a cluster and make the services available over the cluster. They will share the storage using GFS2. In the future, I’ll add a couple of load balancer/proxy machines to farm out the Web traffic, and add a couple more SunFire X2100 M2’s to take that load. One of the main reasons to set up a new configuration with new servers is to provide a clean environment for the many WordPress and Omeka installations we host. We’ve had to hang on to some legacy services to support some older projects, so this will allow us to keep up to date. It will also allow me to set up Apache and PHP to run as a server user, locked down to it’s own directory. That way each of the 100+ sites won’t be able to access any other site’s content. I picked CentOS as the OS because it has cluster and GFS2 options of RedHat, but without the cost.
/boot
, the File System Type as ‘ext4’ and the Size (MB) as 500, then click ‘OK’One of the most important things to have with servers is some form of remote management. That way you don’t need to trek down to the data center each time the server hangs while testing (and it happens a lot). For Sun systems, that means setting up the ELOM (Embedded Lights Out Manager).
IPMI Config Set LAN Config Set PEF Config PEF Support ........ [Enabled] PEF Action Global All of them ..... [Enabled] Alert Startup Discover ..... [Disabled] Startup Delay .............. [Disabled] Event Message For PEF ...... [Disabled] BMC Watch Dog Timer Action ... [Disabled] External Com Port ............ [BMC] Remote Access Remote Access ................ [Serial] Serial Port Number ........... [Com2] Serial Port Mode ............. [115200 8,n,1] Flow Control ................. [Hardware] Post-Boot Support ............ [Always] Terminal Type ................ [VT100] VT-UTF8 Combo Key ............ [Enabled]
RedHat in EL 6, and thereby CentOS, moved to Upstart instead of Sysv, so we create a new serial-ttyS1.conf file instead of editing the /etc/inittab file.
# This service maintains a getty on /dev/ttyS1. stop on runlevel [016] respawn instance $TTY exec /sbin/mingetty $TTY
# grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/Logical/root # initrd /initrd-version.img #boot=/dev/sda default=0 timeout=5 #splashimage=(hd0,0)/grub/splash.xpm.gz #hiddenmenu serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 terminal --timeout=10 serial console title CentOS Linux (2.6.32-71.29.1.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-71.el6.x86_64 ro root=/dev/mapper/Local-root \ rd_LVM_LV=Local/root rd_LVM_LV=Local/swap rd_NO_LUKS rd_NO_MD rd_NO_DM \ console=tty1 console=ttyS1,115200n8 initrd /initramfs-2.6.32-71.29.1.el6.x86_64.img
console vc/1 vc/2 vc/3 vc/4 vc/5 vc/6 vc/7 vc/8 vc/9 vc/10 vc/11 tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8 tty9 tty10 tty11 ttyS1
Connect to the ELOM by ssh into the IP address.
ssh [email protected]
set /SP/SystemInfo/CtrlInfo PowerCtrl=on
set /SP/SystemInfo/CtrlInfo PowerCtrl=gracefuloff
set /SP/SystemInfo/CtrlInfo PowerCtrl=forceoff
set /SP/SystemInfo/CtrlInfo PowerCtrl=reset
set /SP/SystemInfo/CtrlInfo BootCtrl=BIOSSetup
set /SP/AgentInfo IpAddress=xxx.xxx.xxx.xxx
root
, and the default password is changeme
.
set /SP/User/[username] Password=[password]
start /SP/AgentInfo/console
Esc-Shift-9
keys.stop /SP/AgentInfo/console
Next we secure the new servers with some software updates and a firewall.
/etc/resolve.conf
options single-request-reopen
takes care of slow SSH logins. See here https://stomp.colorado.edu/blog/blog/2011/06/29/on-rhel-6-ssh-dns-firewalls-and-slow-logins/ and here http://www.linuxquestions.org/questions/showthread.php?p=4399340#post4399340 for more info.yum install openssh-clients tcsh ksh bc rpm-build gcc gcc-c++ redhat-rpm-config acl gcc gnupg make vim-enhanced man wget which mlocate bzip2-devel libxml2-devel screen sudo parted gd-devel pam_passwdqc.x86_64 rsync zip xorg-x11-server-utils gettext
/etc/sysconfig/selinux
file and set SELINUX=disabled
.
/etc/vimrc
file:
tcsh
/etc/passwd
file to have root use tcshroot:x:0:0:root:/root:/bin/tcsh
.tcshrc
file in root’s home.
setenv PATH ${PATH}:/opt/sun/cam/bin
# Make command completion (TAB key) cycle through all possible choices
# (The default is to simply display a list of all choices when more than one
# match is available.)
bindkey “^I” complete-word-fwd
/etc/hosts
. Add a line with IP and domain name.
# Internal Services
192.168.1.100 http.localdomain httpd.localdomain
192.168.1.101 mysql.localdomain
192.168.1.102 memcached.localdomain
updatedb
to set up the locate
database./etc/pam.d/system-auth
file. Change the linepassword requisite pam_cracklib.so try_first_pass retry=3
to thispassword requisite pam_passwdqc.so min=disabled,disabled,16,12,8
yum update
, and then ayum install firefox xorg-x11-xauth xorg-x11-fonts-Type1
There will be more you’ll need too.
process 702: D-Bus library appears to be incorrectly set up; failed to read machine uuid: Failed to open "/var/lib/dbus/machine-id": No such file or directory
. Then run the following command as root.
dbus-uuidgen > /var/lib/dbus/machine-id
ssh-keygen
cat id_rsa.pub >> ~/.ssh/authorized_keys
authorized_keys
and id_rsa
both set to rw-------
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
on the machine./etc/yum.repos.d/epel.repo
file and set the first “enabled” line to equal 0. That disables yum from using the EPEL repo by default.yum --enablerepo=epel install shorewall
/etc/shorewall/shorewall.conf
file. Change the STARTUP_ENABLED=NO
toSTARTUP_ENABLED=Yes
/etc/shorewall/zones
file:
/etc/shorewall/interfaces
file:
/etc/shorewall/policy
file:
/etc/shorewall/rules
file:
#LAST LINE — ADD YOUR ENTRIES BEFORE THIS ONE — DO NOT REMOVE
/etc/shorewall/routestopped
file:
chkconfig shorewall on
service shorewall start
The next part will be connecting the servers to the storage array.
]]>I was updating one server to use CentOS 6, and ran into this issue of setting up the iDRAC for remote console use. In previous versions, I would add a line to the /etc/inittab file. This is now unused. RedHat is favoring the “Upstart” system developed by and for Ubuntu. It starts services on request, rather than all at once.
So here is how I set up my Dell PowerEdge R510 with CentOS 6 to use the iDRAC6.
Info was taken from the RedHat manual, the Dell iDRAC manual, and probably a bunch of other sites that I googled for.
These steps are by no means comprehensive or detailed. I barely even know what’s going on myself, but it seems to work. It’s kind of cool to see a system boot up in your terminal. It’s like your terminal turns into a monitor connected to the server.
F2
to enter the BIOS setup utility during POST.<Enter>
.serial communication....On with serial redirection via com2
serial port address....Serial device1 = com1, serial device2 = com2
external serial connector....Serial device 1
failsafe baud rate....57600
remote terminal type....vt100/vt220
redirection after boot....Enabled
<Ctrl><E>
when prompted during POST. If your operating system begins to load before you press <Ctrl><E>
, allow the system to finish booting, and then restart your system and try again.<Enter>
. NIC Selection is displayed.<Enter>
.<Esc>
.<Esc>
./boot/grub/grub.conf
file as follows:cp /boot/grub/grub.conf /boot/grub/grub.conf.orig
/boot/grub/grub.conf
file as follows:serial --unit=0 --speed=57600
terminal --timeout=10 serial console
kernel ............. console=ttyS1,57600 console=tty1
/boot/grub/grub.conf
/etc/init/serial-ttyS1.conf
file.Sample File: /etc/inittab
/etc/securetty
/etc/securetty
file as follows:cp /etc/securetty /etc/securetty.orig
/etc/securetty
as follows:Add a new line with the name of the serial tty for COM2:ttyS1
Sample File: /etc/securetty
To connect to the managed system text console, open an iDRAC6 command prompt (displayed through an SSH session):
and type:
console com2
Only one console com2
client is supported at a time. The console -h com2
command displays the contents of the serial history buffer before waiting for input from the keyboard or new characters from the serial port.
To exit the console type these three keys: <Ctrl ><Shift >\
The default (and maximum) size of the history buffer is 8192 characters. You can set this number to a smaller value using the command:
racadm config -g cfgSerial -o cfgSerialHistorySize < number >
The first thing to do is update to the latest version. This ensures that if you need to turn this back into a dynamic site, it should hopefully be compatible with whatever the latest version is at that time.
Next, we’ll need to make it public to guests, so that wget has access to the pages.
Go to the Admin->Features and Options page and check the “Allow guests to browse the forum” box, then click save. Now we have to change the permissions on each board separately. Or with a bit of MySQL magic, we can change them all at once using the CONCAT operator. Open of phpMyAdmin, or something else of your choice. Before we mess with the data, make a copy of the table, just in case we totally hose it.
Browse to the ‘boards’ table, and then to the SQL tab. We’re going to enter an SQL command that will pre-pend (that’s append but onto the front rather than the end) some data.
UPDATE boards SET member_groups=CONCAT('-1,', member_groups) WHERE 1
This will add a -1, to the beginning of each field, which makes the board viewable by guests. No need to log in, which means wget can scrape the pages and turn them into HTML.
Now we get to play around with the theme files to get rid of forum specific items that we won’t need, like links to member info, the login, help, and search links, and anything else that we don’t want.
Here are some items to delete or alter, and the files I found them in for our home-made theme based off of an old default theme.
As it stands, SMF has some pretty ugly URLs. There are a couple of mods that I could never get to work. But editing a file and adding an .htaccess file seems to do the trick.
Open the Sources/QueryString.php file and look for the line like this:
$scripturl = $boardurl . '/index.php';
and get rid of the /index.php
Now create a .htaccess file in the root of the forum (in the same folder as the Settings.php file). It should look similar to this:
RewriteEngine On RewriteBase /7tah/forum/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /7tah/forum/index.php [L]
Now we run wget on the command line to grab the pages.
wget --mirror -P static-forum -nH -np -p -k -E --cut-dirs=2 http://domain.com/path/forum/
All of the static HTML files will now be located in a directory called static-forum.
Some filenames will be a bit broken. Specifically the style.css has an extra “?fin11” in the html files where the file is called. Also, it get’s name that way. So fix that by changing the name of the file to just style.css (it’s in your Theme directory). Then run this one-line command to search and replace throughout all of the static html files (run the command when you are in the static-forum directory.
find . -name '*.html' -type f -exec perl -pi -e 's/style.css%3Ffin11/style.css/g' {} \;
This will look for all of the references to the style.css%3Ffin11 file and change them to style.css. Then the pretty colors and formatting will work. Just for clarification, the %3F is code for a question mark. It shows up as such in the HTML source when viewing from a browser, but is displayed as such in the actual code.
Don’t forget to change the the actual name of the css file to style.css.
Depending on your needs, you may want to password protect your new static forum with an htaccess account. The good peoples at Dynamic Drive have an helpful tool for making the two files necessary to make this happen. Just plug in your desired user name, password, and location of the htpasswd file, and then it’s copy and paste into those files on the server.
I change the last line of the htaccess file to require user username
so that it works only with the given user, not any valid. But since it only pulls from the specified htpasswd file, it’s kind of pointless.
It’s a good idea to make a backup of the database and site files before getting rid of them. I just make a mysqldump of the database, throw it in the forum folder, and then make a tar or zip file of that and put the file in the new static forum folder for safe keeping.
Sit back and relax. Your forum is interactive no longer.
]]>