Subversion Repositories configs

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 - 1
#!/bin/sh
2
#
3
# netcf-transaction: save/restore current network interface configuration
4
#
5
# chkconfig:   - 09 91
6
# description: This script can save the current state of network config, \
7
#              and later revert to that config, or commit the new config \
8
#              (by deleting the snapshot). At boot time, if there are \
9
#              uncommitted changes to the network config, they are \
10
#              reverted (and the discarded changes are archived in \
11
#              /var/lib/netcf/network-rollback-*).
12
 
13
### BEGIN INIT INFO
14
# Provides: netcf-transaction
15
# Required-Start: $local_fs
16
# Short-Description: save/restore network configuration files
17
# Description: This script can save the current state of network config,
18
#              and later revert to that config, or commit the new config
19
#              (by deleting the snapshot). At boot time, if there are
20
#              uncommitted changes to the network config, they are
21
#              reverted (and the discarded changes are archived in
22
#              /var/lib/netcf/network-rollback-*).
23
#
24
### END INIT INFO
25
 
26
# special exit code that means a command was issued that is invalid for the
27
# current state (e.g. change-begin when there is already an open transaction)
28
EINVALID_IN_THIS_STATE=199
29
 
30
sysconfdir="/etc"
31
localstatedir="/var"
32
 
33
netconfdir="$sysconfdir"/sysconfig/network-scripts
34
snapshotdir="$localstatedir"/lib/netcf/network-snapshot
35
rollbackdirbase="$localstatedir"/lib/netcf/network-rollback
36
 
37
# Source function library.
38
test ! -r "$sysconfdir"/rc.d/init.d/functions ||
39
    . "$sysconfdir"/rc.d/init.d/functions
40
 
41
# take a snapshot of current network configuration scripts
42
change_begin ()
43
{
44
    if test -e "$snapshotdir"
45
    then
46
        echo "There is already an open transaction ($snapshotdir exists)"
47
        return $EINVALID_IN_THIS_STATE
48
    fi
49
    if ! mkdir -p "$snapshotdir"
50
    then
51
        echo "failed to create snapshot directory $snapshotdir"
52
        return 1
53
    fi
54
    for f in "$netconfdir"/ifcfg-* "$netconfdir"/route-* \
55
             "$netconfdir"/rule-*
56
    do
57
        test ! -f "$f" && continue
58
        if ! cp -p "$f" "$snapshotdir"
59
        then
60
            echo "failed to copy $f to $snapshotdir"
61
            return 1
62
        fi
63
    done
64
    date >"$snapshotdir"/date
65
}
66
 
67
change_commit ()
68
{
69
    if test ! -d "$snapshotdir"
70
    then
71
        echo "No pending transaction to commit"
72
        return $EINVALID_IN_THIS_STATE
73
    fi
74
    if ! rm -rf "$snapshotdir"
75
    then
76
        echo "Failed to remove obsolete snapshot directory $snapshotdir"
77
    fi
78
}
79
 
80
# rollback network configuration to last snapshot (if one exists)
81
change_rollback ()
82
{
83
    if test ! -d "$snapshotdir"
84
    then
85
        echo "No pending transaction to rollback"
86
        return $EINVALID_IN_THIS_STATE
87
    fi
88
 
89
    rollback_ret=0
90
 
91
    # eliminate all but the last 20 rollback saves
92
    LC_ALL=C ls -d "$rollbackdirbase"-* 2>/dev/null | head -n -20 |\
93
    while read r
94
    do
95
        if ! rm -rf "$r"
96
        then
97
            # indicate an error, but continue
98
            echo "Failed to remove obsolete rollback directory $r"
99
            rollback_ret=1
100
        fi
101
    done
102
 
103
    # save a copy of the current config before rollback "just in case"
104
    rollbackdir=$rollbackdirbase-$(date +%Y.%m.%d-%H:%M:%S)
105
    if ! mkdir -p "$rollbackdir"
106
    then
107
        echo "failed to create rollback directory $rollbackdir"
108
        return 1
109
    fi
110
    for f in "$netconfdir"/ifcfg-* "$netconfdir"/route-* \
111
             "$netconfdir"/rule-*
112
    do
113
        test ! -f "$f" && continue
114
        if ! cp -p "$f" "$rollbackdir"
115
        then
116
            echo "failed to copy $f to $rollbackdir"
117
            return 1
118
        fi
119
    done
120
 
121
    # There are 4 classes of files, each handled slightly differently to
122
    # minimize disruption in services:
123
    # 1) file in both, unmodified - just erase the snapshot copy
124
    # 2) file in both, modified   - copy the snapshot version over
125
    #                               the current & erase copy
126
    # 3) file in current only     - remove the file
127
    # 4) file in snapshot only    - copy the snapshot file to current
128
    #
129
    # We handle the 1st three cases in one loop going through all
130
    # current config files, and what is left over in snapshotdir is,
131
    # by definition, case 4.
132
    #
133
    # (NB: we can't mv the files, because then the selinux labels
134
    # don't get reset properly.)
135
 
136
    for f in "$netconfdir"/ifcfg-* "$netconfdir"/route-* \
137
             "$netconfdir"/rule-*
138
    do
139
        test ! -f "$f" && continue
140
 
141
        snapshotf=$snapshotdir/${f##*/}
142
        if test -f "$snapshotf"
143
        then
144
            # Case (1) & (2) (only copies if they're different)
145
            if ! cmp -s "$snapshotf" "$f"
146
            then
147
                if ! cp -pf "$snapshotf" "$f"
148
                then
149
                    echo "failed to restore $snapshotf to $f"
150
                    return 1
151
                fi
152
            fi
153
            if ! rm -f "$snapshotf"
154
            then
155
                # indicate an error, but continue
156
                echo "Failed to remove obsolete snapshot file $snapshotf"
157
                rollback_ret=1
158
            fi
159
        else
160
            # Case (3)
161
            if ! rm -f "$f"
162
            then
163
                # indicate an error, but continue
164
                echo "Failed to remove unwanted config file $f"
165
                rollback_ret=1
166
            fi
167
        fi
168
    done
169
 
170
    # Case (4)
171
    for f in "$snapshotdir"/ifcfg-* "$snapshotdir"/route-* \
172
             "$snapshotdir"/rule-*
173
    do
174
        test ! -f "$f" && continue
175
        if ! cp -pf "$f" "$netconfdir"
176
        then
177
            echo "failed to restore $f to $netconfdir"
178
            return 1
179
        fi
180
    done
181
 
182
    test -f "$snapshotdir"/date \
183
     && echo Rolled back to network config state of $(cat "$snapshotdir"/date)
184
 
185
    if ! rm -rf "$snapshotdir"
186
    then
187
        # indicate an error, but continue
188
        echo "Failed to remove obsolete snapshot directory $snapshotdir"
189
        rollback_ret=1
190
    fi
191
 
192
    return $rollback_ret
193
}
194
 
195
# usage [val]
196
# Display usage string, then exit with VAL (defaults to 2).
197
usage() {
198
    echo $"Usage: $0 {change-begin|change-commit|change-rollback|snapshot-dir|start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
199
    exit ${1-2}
200
}
201
 
202
# See how we were called.
203
if test $# != 1; then
204
    usage
205
fi
206
 
207
retval=0
208
case "$1" in
209
    # commands required in all Fedora initscripts
210
    start|restart|reload|force-reload|condrestart|try-restart)
211
        echo -n $"Running $prog $1: "
212
        change_rollback
213
        # ignore the "no pending transaction" error
214
        test "$retval" != "$EINVALID_IN_THIS_STATE" && retval=$?
215
        echo
216
        ;;
217
    stop|status)
218
        if test -d "$snapshotdir"
219
        then
220
            echo $"There is an open transaction"
221
        else
222
            echo $"No open transaction"
223
        fi
224
        ;;
225
 
226
    --help)
227
        usage 0
228
        ;;
229
    # specific to netcf-transaction
230
    change-begin)
231
        change_begin
232
        retval=$?
233
        ;;
234
    change-commit)
235
        change_commit
236
        retval=$?
237
        ;;
238
    change-rollback)
239
        change_rollback
240
        retval=$?
241
        ;;
242
    snapshot-dir)
243
        echo $snapshotdir
244
        ;;
245
    *)
246
        usage
247
        ;;
248
esac
249
 
250
exit $retval