ctdb-scripts: Add support for backing up persistent TDBs
[samba4-gss.git] / ctdb / doc / examples / config_migrate.sh
blob874e96c880ffb5aac0cbdbb0c926d7e727d4354d
1 #!/bin/sh
3 # config_migrate.sh - migrate old ctdbd.conf file to new configuration files
5 # Input files are old-style CTDB configuration files, including:
7 # /etc/ctdb/ctdbd.conf
8 # /usr/local/etc/ctdb/ctdbd.conf
9 # /etc/sysconfig/ctdb
10 # /etc/defaults/ctdb
12 # These files are sourced by this script. They used to be sourced by
13 # ctdbd_wrapper, so this should not be too surprising.
15 # By default, the output directory is the given configuration
16 # directory. An alternate output directory can be specified if this
17 # isn't desired.
19 # The output directory will contain the following if non-empty:
21 # * ctdb.conf (may be empty)
22 # * script.options
23 # * ctdb.tunables
24 # * ctdb.sysconfig - consider installing as /etc/sysconfig/ctdb,
25 # /etc/default/ctdb, or similar
26 # * commands.sh - consider running commands in this files
27 # * README.warn - warnings about removed/invalid configuration options
29 usage ()
31 cat <<EOF
32 usage: config_migrate.sh [-f] [-d <ctdb-config-dir>] [-o <out-dir>] <file> ...
33 EOF
34 exit 1
37 config_dir=""
38 out_dir=""
39 force=false
41 while getopts "d:fho:?" opt ; do
42 case "$opt" in
43 d) config_dir="$OPTARG" ;;
44 f) force=true ;;
45 o) out_dir="$OPTARG" ;;
46 \?|h) usage ;;
47 esac
48 done
49 shift $((OPTIND - 1))
51 if [ $# -lt 1 ] ; then
52 usage
55 if [ -z "$config_dir" ] ; then
56 echo "Assuming \"/etc/ctdb\" as ctdb configuration directory"
57 echo "If that's not correct, please specify config dir with -d"
58 echo
59 config_dir="/etc/ctdb"
60 else
61 echo "Using \"$config_dir\" as ctdb configuration directory"
62 echo
65 if [ -z "$out_dir" ] ; then
66 echo "No output directory specified, using \"$config_dir\""
67 echo
68 out_dir="$config_dir"
71 ############################################################
74 # Output file handling
77 out_file_check_and_create ()
79 _out_file="$1"
81 if [ -f "$_out_file" ] ; then
82 if ! $force ; then
83 echo "Not overwriting existing file: ${_out_file}" >&2
84 return 1
86 mv -v "$_out_file" "${_out_file}.convertsave"
89 touch "$_out_file"
91 return 0
94 out_file_remove_if_empty ()
96 _out_file="$1"
98 if [ ! -s "$_out_file" ] ; then
99 rm "$_out_file"
103 ############################################################
106 # Option/tunable/service conversion and validity checking
108 # This is basically the data that drives most of the rest of the
109 # script
112 # Convert a ctdbd.conf opt+val into a ctdb.conf section+opt+val
114 # If opt is matched and val is empty then output is printed, allowing
115 # this function to be reused to check if opt is valid.
117 # Note that for boolean options, the expected value and the new value
118 # form part of the data.
119 get_ctdb_conf_option ()
121 _opt="$1"
122 _val="$2"
124 awk -v opt="${_opt}" -v val="${_val}" \
125 '$3 == opt {
126 if (!$4 || !val || val == $4) {
127 if ($5) {
128 print $1, $2, $5
129 } else {
130 print $1, $2, val
133 }' <<EOF
134 cluster node-address CTDB_NODE_ADDRESS
135 cluster cluster-lock CTDB_RECOVERY_LOCK
136 cluster transport CTDB_TRANSPORT
137 cluster leader-capability CTDB_CAPABILITY_RECMASTER no false
138 database lock-debug-script CTDB_DEBUG_LOCKS
139 database persistent-database-directory CTDB_DBDIR_PERSISTENT
140 database state-database-directory CTDB_DBDIR_STATE
141 database volatile-database-directory CTDB_DBDIR
142 event debug-script CTDB_DEBUG_HUNG_SCRIPT
143 legacy lmaster-capability CTDB_CAPABILITY_LMASTER no false
144 legacy realtime-scheduling CTDB_NOSETSCHED yes false
145 legacy script-log-level CTDB_SCRIPT_LOG_LEVEL
146 legacy start-as-disabled CTDB_START_AS_DISABLED yes true
147 legacy start-as-stopped CTDB_START_AS_STOPPED yes true
148 logging location CTDB_LOGGING
149 logging log-level CTDB_DEBUGLEVEL
154 # Check if an option will convert to a ctdb.conf option
155 check_ctdb_conf_option ()
157 _opt="$1"
159 _out=$(get_ctdb_conf_option "$_opt" "")
160 [ -n "$_out" ]
163 # Convert a ctdbd.conf tunable option into a ctdb.conf section+opt
165 # The difference between this and get_ctdb_conf_option() is that only
166 # the tunable part of the option is passed as opt and it is matched
167 # case-insensitively.
168 get_ctdb_conf_tunable_option ()
170 _opt="$1"
171 _val="$2"
173 awk -v opt="${_opt}" -v val="${_val}" \
174 'tolower($3) == tolower(opt) {
175 if (!$4 || !val || (val == 0 ? 0 : 1) == $4) {
176 if ($5) {
177 print $1, $2, $5
178 } else {
179 print $1, $2, val
182 }' <<EOF
183 database tdb-mutexes TDBMutexEnabled 0 false
184 failover disabled DisableIPFailover 1 true
189 # Check if a tunable will convert to a ctdb.conf option
190 check_ctdb_conf_tunable_option ()
192 _opt="$1"
194 _out=$(get_ctdb_conf_tunable_option "$_opt" "")
195 [ -n "$_out" ]
198 # Check if an option has been removed
199 check_removed_option ()
201 _option="$1"
203 grep -Fqx "$_option" <<EOF
204 CTDB_BASE
205 CTDB_PIDFILE
206 CTDB_SOCKET
207 CTDB_EVENT_SCRIPT_DIR
208 CTDB_NOTIFY_SCRIPT
209 CTDB_PUBLIC_INTERFACE
210 CTDB_MAX_PERSISTENT_CHECK_ERRORS
211 CTDB_SHUTDOWN_TIMEOUT
212 CTDB_MONITOR_SWAP_USAGE
216 # Check if an option is a valid script option
217 check_valid_script_option ()
219 _option="$1"
221 grep -Fqx "$_option" <<EOF
222 # 10.interface
223 CTDB_PARTIALLY_ONLINE_INTERFACES
224 # 11.natgw
225 CTDB_NATGW_DEFAULT_GATEWAY
226 CTDB_NATGW_NODES
227 CTDB_NATGW_PRIVATE_NETWORK
228 CTDB_NATGW_PUBLIC_IFACE
229 CTDB_NATGW_PUBLIC_IP
230 CTDB_NATGW_STATIC_ROUTES
231 # 13.per_ip_routing
232 CTDB_PER_IP_ROUTING_CONF
233 CTDB_PER_IP_ROUTING_RULE_PREF
234 CTDB_PER_IP_ROUTING_TABLE_ID_LOW
235 CTDB_PER_IP_ROUTING_TABLE_ID_HIGH
236 # 90.lvs
237 CTDB_LVS_NODES
238 CTDB_LVS_PUBLIC_IFACE
239 CTDB_LVS_PUBLIC_IP
240 # 20.multipathd
241 CTDB_MONITOR_MPDEVICES
242 # 31.clamd
243 CTDB_CLAMD_SOCKET
244 # 48.netbios
245 CTDB_SERVICE_NMB
246 # 49.winbind
247 CTDB_SERVICE_WINBIND
248 # 50.samba
249 CTDB_SAMBA_CHECK_PORTS
250 CTDB_SAMBA_SKIP_SHARE_CHECK
251 CTDB_SERVICE_SMB
252 # 60.nfs
253 CTDB_NFS_CALLOUT
254 CTDB_NFS_CHECKS_DIR
255 CTDB_NFS_SKIP_SHARE_CHECK
256 CTDB_RPCINFO_LOCALHOST
257 CTDB_RPCINFO_LOCALHOST6
258 CTDB_NFS_STATE_FS_TYPE
259 CTDB_NFS_STATE_MNT
260 # 70.iscsi
261 CTDB_START_ISCSI_SCRIPTS
262 # 00.ctdb
263 CTDB_MAX_CORRUPT_DB_BACKUPS
264 # 05.system
265 CTDB_MONITOR_FILESYSTEM_USAGE
266 CTDB_MONITOR_MEMORY_USAGE
267 # debug_hung_scripts.sh
268 CTDB_DEBUG_HUNG_SCRIPT_STACKPAT
272 # Check if a tunable is valid
273 check_valid_tunable ()
275 _tunable="$1"
277 grep -Fiqx "$_tunable" <<EOF
278 AllowClientDBAttach
279 AllowMixedVersions
280 AllowUnhealthyDBRead
281 ControlTimeout
282 DBRecordCountWarn
283 DBRecordSizeWarn
284 DBSizeWarn
285 DatabaseHashSize
286 DatabaseMaxDead
287 DeferredAttachTO
288 DisableIPFailover
289 ElectionTimeout
290 EnableBans
291 EventScriptTimeout
292 FetchCollapse
293 HopcountMakeSticky
294 IPAllocAlgorithm
295 KeepaliveInterval
296 KeepaliveLimit
297 LockProcessesPerDB
298 LogLatencyMs
299 MaxQueueDropMsg
300 MonitorInterval
301 MonitorTimeoutCount
302 NoIPFailback
303 NoIPTakeover
304 PullDBPreallocation
305 QueueBufferSize
306 RecBufferSizeLimit
307 RecLockLatencyMs
308 RecdFailCount
309 RecdPingTimeout
310 RecoverInterval
311 RecoverTimeout
312 RecoveryBanPeriod
313 RecoveryDropAllIPs
314 RecoveryGracePeriod
315 RepackLimit
316 RerecoveryTimeout
317 SeqnumInterval
318 StatHistoryInterval
319 StickyDuration
320 StickyPindown
321 TDBMutexEnabled
322 TakeoverTimeout
323 TickleUpdateInterval
324 TraverseTimeout
325 VacuumFastPathCount
326 VacuumInterval
327 VacuumMaxRunTime
328 VerboseMemoryNames
332 # Check if a tunable has been removed
333 check_removed_tunable ()
335 _tunable="$1"
337 grep -Fiqx "$_tunable" <<EOF
338 NoIPHostOnAllDisabled
339 VacuumLimit
343 # Print a command to enable an event script for the given service
344 print_event_script_enable_command ()
346 _service="$1"
348 _component=""
349 _script=""
350 case "$_service" in
351 samba) _component="legacy" ; _script="50.samba" ;;
352 winbind) _component="legacy" ; _script="49.winbind" ;;
353 apache2|httpd) _component="legacy" ; _script="41.httpd" ;;
354 clamd) _component="legacy" ; _script="31.clamd" ;;
355 iscsi) _component="legacy" ; _script="70.iscsi" ;;
356 nfs) _component="legacy" ; _script="60.nfs" ;;
357 vsftpd) _component="legacy" ; _script="40.vsftpd" ;;
358 esac
360 if [ -z "$_script" ] ; then
361 return 1
364 cat <<EOF
365 # Enable the ${_service} service
366 ctdb event script enable ${_component} ${_script}
371 # Check if the given service is valid
372 check_valid_service ()
374 _service="$1"
376 print_event_script_enable_command "$_service" >/dev/null
379 ############################################################
382 # Utilities
385 # List all options starting with "CTDB_" set in given configuration files
386 list_options ()
388 set |
389 sed -n 's|^\(CTDB_[^=]*\)=\(.*\)|\1 \2|p' |
390 while read -r _var _val ; do
391 # Strip quotes from value
392 _val=$(echo "$_val" | sed -e "s|^'||" -e "s|'\$||")
394 echo "${_var} ${_val}"
395 done
398 # List all tunables set in the given configuration files
399 list_tunables ()
401 list_options |
402 while read -r _opt _val ; do
403 case "$_opt" in
404 CTDB_SET_*) echo "${_opt#CTDB_SET_} ${_val}" ;;
405 esac
406 done
409 # List all managed services according to the given configuration files
410 list_managed_services ()
413 # CTDB_MANAGES_<service>="yes"
415 list_options |
416 while read -r _opt _val ; do
417 case "$_opt" in
418 CTDB_MANAGES_*) : ;;
419 *) continue ;;
420 esac
422 if [ "$_val" != "yes" ] ; then
423 continue
426 # Trim and downcase
427 echo "${_opt#CTDB_MANAGES_}" | tr '[:upper:]' '[:lower:]'
428 done
431 # CTDB_MANAGED_SERVICES
433 for _service in $CTDB_MANAGED_SERVICES ; do
434 echo "$_service"
435 done
438 ############################################################
441 # Print warnings for removed and unknown options
445 # Print a warning as a bullet list item
447 # Arguments after the 1st are printed as a subsequent paragraph.
448 warn ()
450 bullet="$1" ; shift
452 printf '* %s\n\n' "$bullet"
454 if [ $# -gt 0 ] ; then
455 printf ' %s\n\n' "$*"
459 warn_about_CTDB_DBDIR_tmpfs_yes ()
461 if $ctdb_dbdir_tmpfs_magic ; then
462 warn "Option \"CTDB_DBDIR=tmpfs\" is no longer available:" \
463 "Permanently mount a tmpfs filesystem on the volatile" \
464 "database directory"
468 warn_about_unknown_managed_services ()
470 list_managed_services |
471 while read -r _s ; do
472 if check_valid_service "$_s" ; then
473 continue
475 warn "Unknown service \"${_s}\" marked as managed" \
476 "If this is a 3rd party service, please enable it manually"
477 done
480 warn_about_removed_and_unknown_options ()
482 list_options |
483 while read -r _opt _val ; do
484 if check_ctdb_conf_option "$_opt" ; then
485 continue
488 if check_valid_script_option "$_opt" ; then
489 continue
492 case "$_opt" in
493 CTDB_MANAGED_SERVICES|\
494 CTDB_MANAGES_*|\
495 CTDB_SET_*|\
496 CTDB_NODES|\
497 CTDB_PUBLIC_ADDRESSES|\
498 CTDB_MAX_OPEN_FILES|\
499 CTDB_SUPPRESS_COREFILE)
500 # Handled elsewhere
501 continue
503 esac
505 if check_removed_option "$_opt" ; then
506 warn "Option \"${_opt}\" is no longer available" \
507 "Please see the WHATSNEW.txt"
508 continue
511 warn "Option \"${_opt}\" is unknown"
512 done
515 warn_about_removed_and_unknown_tunables ()
517 list_tunables |
518 while read -r _var _val ; do
519 if check_valid_tunable "$_var" ; then
520 continue
523 if check_removed_tunable "$_var" ; then
524 warn "Tunable \"${_var}\" is no longer available" \
525 "Please see the WHATSNEW.txt"
526 continue
529 warn "Tunable \"${_var}\" is unknown"
530 done
533 ############################################################
536 # Top-level file builders
539 build_ctdb_conf ()
541 _out_file="$1"
543 out_file_check_and_create "$_out_file" || return
545 list_options |
546 while read -r _opt _val ; do
547 case "$_opt" in
548 CTDB_SET_*)
549 _opt="${_opt#CTDB_SET_}"
550 _out=$(get_ctdb_conf_tunable_option "$_opt" "$_val")
553 _out=$(get_ctdb_conf_option "$_opt" "$_val")
554 esac
555 if [ -z "$_out" ] ; then
556 continue
559 # $_out is section and key, replace dashes with spaces
560 # Intentional word splitting
561 # shellcheck disable=SC2086
562 set -- $_out
563 _section=$(echo "$1" | sed -e 's|-| |g')
564 _key=$(echo "$2" | sed -e 's|-| |g')
565 _newval="$3"
567 if ! grep -Fqx "[${_section}]" "$_out_file" ; then
568 # Add blank line if file is not empty
569 if [ -s "$_out_file" ] ; then
570 echo >>"$_out_file"
572 # Create section at end of file
573 echo "[${_section}]" >>"$_out_file"
576 # Must escape leading TAB or sed eats it
577 sed -i -e "/\\[${_section}\\]/a\
578 \\ ${_key} = ${_newval}
579 " "$_out_file"
581 done
585 build_script_options ()
587 _out_file="$1"
589 out_file_check_and_create "$_out_file" || return
591 list_options |
592 while read -r _var _val ; do
593 if check_valid_script_option "$_var" ; then
594 echo "${_var}=${_val}"
596 done >>"$_out_file"
598 out_file_remove_if_empty "$_out_file"
601 build_ctdb_tunables ()
603 _out_file="$1"
605 out_file_check_and_create "$_out_file" || return
607 list_tunables |
608 while read -r _var _val ; do
609 if check_ctdb_conf_tunable_option "$_var" ; then
610 continue
612 if ! check_valid_tunable "$_var" ; then
613 continue
615 echo "${_var}=${_val}"
616 done >>"$_out_file"
618 out_file_remove_if_empty "$_out_file"
621 build_ctdb_sysconfig ()
623 _out_file="$1"
625 out_file_check_and_create "$_out_file" || return
627 if [ -n "$CTDB_SUPPRESS_COREFILE" ] ; then
628 if [ "$CTDB_SUPPRESS_COREFILE" = "yes" ] ; then
629 echo "ulimit -c 0"
630 else
631 echo "ulimit -c unlimited"
632 fi >>"$_out_file"
635 if [ -n "$CTDB_MAX_OPEN_FILES" ] ; then
636 echo "ulimit -n ${CTDB_MAX_OPEN_FILES}" >>"$_out_file"
639 out_file_remove_if_empty "$_out_file"
642 build_commands_sh ()
644 _out_file="$1"
646 out_file_check_and_create "$_out_file" || return
649 # Enable script for managed services
651 list_managed_services |
652 while read -r _service ; do
653 print_event_script_enable_command "$_service"
654 done >>"$_out_file"
657 # CTDB_NODES no longer available
659 if [ -n "$CTDB_NODES" ] ; then
660 if [ "$CTDB_NODES" = "${config_dir}/nodes" ] ; then
661 cat <<EOF
662 # CTDB_NODES=${CTDB_NODES}
663 # Looks like the standard location. Nothing to do.
666 else
667 cat <<EOF
668 # CTDB_NODES=${CTDB_NODES}
669 # Looks like a non-standard location. Use the default location
670 # in the configuration directory or create a symlink.
671 ln -s "$CTDB_NODES" "${config_dir}/nodes"
674 fi >>"$_out_file"
678 # CTDB_PUBLIC_ADDRESSES no longer available
680 if [ -n "$CTDB_PUBLIC_ADDRESSES" ] ; then
681 _pa="public_addresses"
682 if [ "$CTDB_PUBLIC_ADDRESSES" = "${config_dir}/${_pa}" ] ; then
683 cat <<EOF
684 # CTDB_PUBLIC_ADDRESSES=${CTDB_PUBLIC_ADDRESSES}
685 # Looks like the standard location. Nothing to do.
688 else
689 cat <<EOF
690 # CTDB_PUBLIC_ADDRESSES=${CTDB_PUBLIC_ADDRESSES}
691 # Looks like a non-standard location. Use the default location
692 # in the configuration directory or create a symlink.
693 ln -s "$CTDB_PUBLIC_ADDRESSES" "${config_dir}/${_pa}"
696 fi >>"$_out_file"
699 out_file_remove_if_empty "$_out_file"
702 build_README_warn ()
704 _out_file="$1"
706 out_file_check_and_create "$_out_file" || return
709 warn_about_CTDB_DBDIR_tmpfs_yes
710 warn_about_unknown_managed_services
711 warn_about_removed_and_unknown_options
712 warn_about_removed_and_unknown_tunables
713 } >>"$_out_file"
715 out_file_remove_if_empty "$_out_file"
718 ############################################################
720 mkdir -p "$out_dir" || exit 1
722 # Source the input files
723 for i ; do
724 # Unknown non-constant source
725 # shellcheck disable=SC1090
726 . "$i"
727 done
729 # Special case
730 ctdb_dbdir_tmpfs_magic=false
731 if [ "$CTDB_DBDIR" = "tmpfs" ] ; then
732 ctdb_dbdir_tmpfs_magic=true
733 unset CTDB_DBDIR
736 build_ctdb_conf "${out_dir}/ctdb.conf"
737 build_script_options "${out_dir}/script.options"
738 build_ctdb_tunables "${out_dir}/ctdb.tunables"
739 build_ctdb_sysconfig "${out_dir}/ctdb.sysconfig"
740 build_commands_sh "${out_dir}/commands.sh"
741 build_README_warn "${out_dir}/README.warn"