aboutsummaryrefslogtreecommitdiffstats
path: root/squashfu
blob: 7b42d46097e54f731f3ecd7abf068d28942806e5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/bin/bash

# Declare base options, overwrite with user specs as necessary
# MAKE SURE TO CHANGE THIS BEFORE PUSHING PUBLIC
CONFIG=/home/haruko/dev/git/squashfu/etc/squashfu
source $CONFIG
if [[ $? -gt 0 ]]; then
    echo "FATAL: Error in config file. Please check your syntax"
    exit 1
fi

# Informational output w/ happy colors
debug () {
    echo -e '\033[1;33m??\033[1;m ' $*
}

die () {
    echo -e '\033[1;31m!!\033[1;m ' $*
    exit 1
}
mount_aufs_by_num () {
    # Check for the union already being mounted
    grep "${BKUP_ROOT}/rw" /proc/mounts >/dev/null && umount "$BKUP_ROOT/rw"

    # build branch string
    branches="br="
    for i in `seq $1 -1 1`; do
        branches="${branches}${BKUP_ROOT}/bins/${i}:"
    done
    branches="${branches}${BKUP_ROOT}/ro"

    # build and execute mount command
    mount -t aufs none $BKUP_ROOT/rw -o udba=reval,$branches
}

create_new_seed () {
    # For our very first seed, we're writing directly to disk, so
    # Delete the data after the squashed seed has been created
    [[ "$1" == "--initial" ]] && run_rsync

    # Create a new squashfs based on the contents of the union
    mksquashfs "${BKUP_ROOT}/rw" "$SEED" -b 65536

    # Delete the rsync source since its now squashed
    [[ "$1" == "--initial" ]] && rm -rf "${BKUP_ROOT}/rw/*"
}

move_old_tree () {
    storage="${BKUP_ROOT}/bkup-$(date +%Y-%m-%d)"
    mkdir "$storage"
    cd "$BKUP_ROOT" && mv {$SEED,bins/} "$storage"
}

mount_seed () {
    debug "Mounting seed"
    # Mount the squashed seed, failing if we can't
    mount -o loop,ro "${SEED}" "${BKUP_ROOT}/ro" || {
        echo FATAL: Error mounting $SEED;
        exit 1;
    }
}

mount_aufs_by_day() {
    # convert DoW to a number
    mount_aufs_by_num `date --date=$1 +%u`
}

run_rsync() {
    # Gather includes and excludes from config file
    # No error checking here -- user better not have
    # effed up the config
    INCLUDES=($(grep ^#+ $CONFIG | cut -d+ -f2-))
    EXCLUDES=($(grep ^#- $CONFIG | cut -d- -f2-))

    # rsync source to $BKUP_ROOT/rw
    echo Rsync executing with:
    echo    Options: ${RSYNC_OPTS[@]}
    echo   Includes: ${INCLUDES[@]}
    echo   Excludes: ${EXCLUDES[@]}
    rsync ${RSYNC_OPTS[@]} ${INCLUDES[@]} ${EXCLUDES[@]} ${BKUP_ROOT}/rw || return 1
}

# Unmount union and squash
unmount_all () {
    #Union must be unmounted first, or bad things happen
    umount "${BKUP_ROOT}/rw"
    umount "$SEED"
}

# Sanity checks
#  - Are we root?
[[ $UID -eq 0 ]] || { echo "Must be root!"; exit 1; }

#  - is our BKUP_ROOT valid? (FAIL)
[[ -w "${BKUP_ROOT}" ]] ||
    { echo "FATAL: Backup root '$BKUP_ROOT' is not a valid location!";
      echo "Please check the setting in /etc/squashfu"; exit 1; }

# Blindly unmount all just in case
unmount_all

# - do we have a proper (expected) directory structure in place?
# Use cd to BKUP_ROOT to avoid issues with brace expansion in a quoted path
cd "$BKUP_ROOT" && mkdir -p {rw,ro,bins/{1,2,3,4,5,6,7}}

# Prep work
#  - does seed exist? (if not, our backup is creating the seed)
[[ -f "$SEED" ]] || { 
    echo "No seed found -- creating a new one...";
    create_new_seed "--initial";
}
#  mount seed if it exists and is not already mounted
grep "${BKUP_ROOT}/ro" /proc/mounts >/dev/null || mount_seed

# Prepare union mount with proper bins
mount_aufs_by_num $(( $(date +%u) + $MODIFIER ))

# Ready for backup!
run_rsync

# 5) Cleanup 
#   - Is this resquash day? If so, we need a new squash
#   - If new squash creation fails, we're in trouble. (by default, keep previous week)
[[ $(date +%u) -eq $RESQUASH_DAY ]] && {
    create_new_seed
    # Set aside last week's tree if user opted to, else delete it all
    if [[ $KEEP_LAST_WEEK -eq 1 ]]; then
        move_old_tree
    else
        find "${BKUP_ROOT}/bins/" -type f -delete
        rm $SEED
    fi
}

unmount_all

# 6) Optional behavior
#   --seed-initial      Create new seed
#   --rollback $1 $2    Rollback to the day specified by $1, mounting at $2
#   --resquash          Create a new seed
#