aboutsummaryrefslogtreecommitdiff
path: root/lib/hydra/backup
blob: de5f3ac7d8c42747c49d6bafdf23b69ea75f05f4 (plain)
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/bin/bash

# Setup environment for the backups website
function hydra_backup_environment_local_website {
  NODE="$1"
  SITE="$2"
  BACKUPDIR="/var/sites/backups/site/$SITE/$NODE"

  if [ -z "$SITE" ] || [ -z "$NODE" ]; then
    hydra_action_usage
    exit 1
  fi

  if [ ! -z "$DATE" ]; then
    RESTOREDIR="$BACKUPDIR/$DATE"
  else
    RESTOREDIR="$BACKUPDIR/`date +%Y%m%d`"
  fi

  # Try to get the newest if there's no backup for the current date
  if [ ! -e "$RESTOREDIR/$SITE.tar.bz2" ]; then
    RESTOREDIR="$(find $BACKUPDIR -name "$SITE.tar.bz2" -exec dirname {} \; | sort -n | tail -n 1)"

    if [ -z "$RESTOREDIR" ]; then
      echo "Backup not found for $DATE."
      exit 1
    fi
  fi

  DB_DUMP_BASE="$RESTOREDIR"
  mkdir -p $RESTOREDIR  
}

# Setup environment for backup restored from localhost
function hydra_backup_environment_local {
  BACKUPDIR="/var/backups/duplicity"

  if [ ! -z "$DATE" ]; then
    RESTOREDIR="/var/backups/restore/$DATE"
  else
    RESTOREDIR="/var/backups/restore/`date +%Y%m%d`"
  fi

  DB_DUMP_BASE="$RESTOREDIR/var/backups/mysql/sqldump/"
  mkdir -p $RESTOREDIR    
}

# Setup environment for backup restored from remote source
function hydra_backup_environment_remote {
  NODE="$1"
  METHOD="$2"
  BACKUP_ROOT="/var/backups/remote"
  DOMAIN="`facter domain`"
  BACKUPDIR="$BACKUP_ROOT/$NODE.$DOMAIN"

  if [ ! -z "$DATE" ]; then
    RESTOREDIR="$BACKUPDIR/restore/$DATE"
  else
    RESTOREDIR="$BACKUPDIR/restore/`date +%Y%m%d`"
  fi
  
  if [ -z "$NODE" ]; then
    hydra_action_usage
    exit 1
  fi
  
  if [ ! -d "$BACKUPDIR" ]; then
    echo "No backup found at $BACKUPDIR"
    exit 1
  fi
  
  if [ -z "$METHOD" ]; then
    if [ -d "$BACKUPDIR/rsync" ]; then
      echo "Assuming rsync backup method"
      BACKUPDIR="$BACKUPDIR/rsync/var/backups/duplicity/daily.1"
    elif [ -d "$BACKUPDIR/rdiff" ]; then
      echo "Assuming rdiff backup method"
      BACKUPDIR="$BACKUPDIR/rdiff/var/backups/duplicity"
    else
      echo "Missing backup action"
      exit 1 
    fi
  elif [ "$METHOD" == "rsync" ]; then
    BACKUPDIR="$BACKUPDIR/rsync/var/backups/duplicity/daily.1"
  elif [ "$METHOD" == "rdiff" ]; then
    BACKUPDIR="$BACKUPDIR/rdiff/var/backups/duplicity"
  else
    if [ -d "$BACKUPDIR/$METHOD" ]; then
      BACKUPDIR="$BACKUPDIR/$METHOD"
    else
      echo "Backup folder for $METHOD not found at $BACKUPDIR"
      exit 1 
    fi
  fi
  
  if [ -d "$RESTOREDIR" ] && [ "$METHOD" != "restore" ]; then
    echo "Restoration folder $RESTOREDIR already exists"
    exit 1
  fi
  
  DB_DUMP_BASE="$RESTOREDIR/var/backups/mysql/sqldump/"
  mkdir -p $RESTOREDIR
}

# Setup environment for the backups for a service
function hydra_backup_environment_service {
  # Check restore strategy.
  if [ "$HOST" == "localhost" ] || [ "$HOST" == "`facter hostname`" ]; then
    hydra_backup_environment_local
  else
    hydra_backup_environment_remote $HOST restore
  fi
  
  # Check if folder exist on the backup.
  if [ ! -d "$RESTOREDIR/$SERVICE_DIR" ]; then
    echo "Service folder does not exist: $RESTOREDIR/$SERVICE_DIR"
    exit 1
  fi
  
  # Set user.
  if hydra_check_user $SERVICE_USER; then
    SERVICE_USER="$SERVICE_USER"
  else
    SERVICE_USER="root"
  fi
  
  # Set group.
  if hydra_check_group $SERVICE_GROUP; then
    SERVICE_GROUP="$SERVICE_GROUP"
  else
    SERVICE_GROUP="root"
  fi
  
  # TODO: Backup it?
  #hydractl backup-$SERVICE
}

# Restore a database
function hydra_backup_restore_database {
  DATABASE="$1"

  if [ -z "$DATABASE" ]; then
    return
  fi

  # Check if there are database dumps
  if [ -f "$DB_DUMP_BASE/$DATABASE.sql.gz" ]; then
    DB_DUMP_EXT=".gz"
    DB_DUMP_EXTRACT="gunzip"
  elif [ -f "$DB_DUMP_BASE/$DATABASE.sql.bz2" ]; then
    DB_DUMP_EXT=".bz2"
    DB_DUMP_EXTRACT="bunzip2"
  elif [ -f "$DB_DUMP_BASE/$DATABASE.sql" ]; then
    DB_DUMP_EXT=""
    DB_DUMP_EXTRACT="true"
  fi
  
  # Restore database
  if [ ! -z "$DB_DUMP_EXTRACT" ]; then
    echo "Restoring database $DATABASE..."
    hydra_set_tmpfile $DATABASE -d
    cp $DB_DUMP_BASE/$DATABASE.sql$DB_DUMP_EXT $TMPWORK
    ( cd $TMPWORK && $DB_DUMP_EXTRACT $DATABASE.sql$DB_DUMP_EXT )
    hydra_truncate_database $DATABASE
    mysql $DATABASE < $TMPWORK/$DATABASE.sql
    hydra_unset_tmpfile $TMPWORK
  else
    echo "Database should be manually restored"
  fi
}

# Return a normalized database name
function hydra_database_name {
  # MySQL 16 chars limit
  echo $1 | sed -e 's/^\(................\).*/\1/'
}