Example #1
0
        public override snapshot createSnapshot(string dataset, string snapshotName)
        {
            snapshot newVal = uncachedNAS.createSnapshot(dataset, snapshotName);

            snapshots.TryAdd(newVal.id, newVal);
            return(newVal);
        }
Example #2
0
 public override void rollbackSnapshot(snapshot shotToRestore)
 {
     lock (events)
     {
         events.Add(new mockedCall("rollbackSnapshot", "shotToRestore: '" + shotToRestore));
     }
 }
Example #3
0
        public override void deleteSnapshot(snapshot toDelete)
        {
            uncachedNAS.deleteSnapshot(toDelete);
            snapshot foo;

            snapshots.TryRemove(toDelete.id, out foo);
        }
        private static snapshot getSnapshot(NASAccess nas, string snapshotFullName)
        {
            snapshot shotToRestore = nas.getSnapshots().SingleOrDefault(
                x => x.fullname.ToLower().Contains("/" + snapshotFullName.ToLower() + "@") || x.id == snapshotFullName);

            return(shotToRestore);
        }
Example #5
0
        public override void deleteSnapshot(snapshot toDelete)
        {
            string name = Uri.EscapeDataString(toDelete.fullname);
            string url  = "http://" + _serverIp + "/api/v1.0/storage/snapshot/" + name;

            doReq(url, "DELETE", HttpStatusCode.NoContent);
        }
Example #6
0
        public override void rollbackSnapshot(snapshot shotToRestore) //, volume parentVolume, volume clone)
        {
            lock (nonAPIReqLock)
            {
                // Oh no, FreeNAS doesn't export the 'rollback' command via the API! :( We need to log into the web UI and faff with
                // that in order to rollback instead.
                //
                // First, do an initial GET to / so we can get a CSRF token and some cookies.
                DoNonAPIReq("", HttpStatusCode.OK);
                //doInitialReq();

                // Now we can perform the login.
                string url        = "account/login/";
                string payloadStr = string.Format("username={0}&password={1}", _username, _password);
                DoNonAPIReq(url, HttpStatusCode.OK, payloadStr);

                // Now we can do the request to rollback the snapshot.
                string resp = DoNonAPIReq("storage/snapshot/rollback/" + shotToRestore.fullname + "/", HttpStatusCode.OK,
                                          "");

                if (resp.Contains("\"error\": true") || !resp.Contains("Rollback successful."))
                {
                    throw new nasAccessException("Rollback failed: " + resp);
                }
            }
        }
Example #7
0
 public override void cloneSnapshot(snapshot toClone, string fullCloneName)
 {
     lock (events)
     {
         events.Add(new mockedCall("cloneSnapshot", "toClone: '" + toClone + "' fullCloneName: " + fullCloneName));
     }
 }
        private static snapshotObjects getSnapshotObjectsFromNAS(NASAccess nas, string snapshotFullName)
        {
            snapshot shotToRestore = getSnapshot(nas, snapshotFullName);

            if (shotToRestore == null)
            {
                nas.invalidateSnapshots();
                shotToRestore = getSnapshot(nas, snapshotFullName);
                if (shotToRestore == null)
                {
                    throw new Exception("Cannot find snapshot " + snapshotFullName);
                }
            }

            // Now find the extent. We'll need to delete it before we can rollback the snapshot.
            iscsiExtent extent = getExtent(nas, snapshotFullName);

            if (extent == null)
            {
                nas.invalidateExtents();
                extent = getExtent(nas, snapshotFullName);
                if (extent == null)
                {
                    throw new Exception("Cannot find extent " + snapshotFullName);
                }
            }

            // Find the 'target to extent' mapping, since this will need to be deleted before we can delete the extent.
            iscsiTargetToExtentMapping tgtToExtent = getTgtToExtent(nas, extent);

            if (tgtToExtent == null)
            {
                nas.invalidateTargetToExtents();
                tgtToExtent = getTgtToExtent(nas, extent);
                if (tgtToExtent == null)
                {
                    throw new Exception("Cannot find target-to-extent mapping with ID " + extent.id + " for snapshot " + shotToRestore.name);
                }
            }

            // We find the target, as well, just to be sure that our cache is correct.
            if (nas.getISCSITargets().Count(x => x.id == tgtToExtent.iscsi_target) == 0)
            {
                nas.invalidateTargets();
                if (nas.getISCSITargets().Count(x => x.id == tgtToExtent.iscsi_target) == 0)
                {
                    throw new Exception("Cannot find target for snapshot " + snapshotFullName);
                }
            }
            return(new snapshotObjects()
            {
                extent = extent,
                shotToRestore = shotToRestore,
                tgtToExtent = tgtToExtent
            });
        }
Example #9
0
        public override void cloneSnapshot(snapshot snapshot, string path)
        {
            string url     = String.Format("http://{0}/api/v1.0/storage/snapshot/{1}/clone/", _serverIp, snapshot.fullname);
            string payload = String.Format("{{\"name\": \"{0}\" }}", path);

            doReq(url, "POST", HttpStatusCode.Accepted, payload);
            // This API function returns a HTTP status of Accepted (202), which should indicate that the operation has been started
            // and will continue async. However, after studying the FreeNAS code ("FreeNAS-9.10.1 (d989edd)"), there appears to be
            // a shell out to 'zfs clone', which is sync. AFAICT, the call can never return before the clone is complete.
        }
Example #10
0
        public override void deleteSnapshot(snapshot toDelete)
        {
            lock (events)
            {
                events.Add(new mockedCall("deleteSnapshot", "toDelete: " + toDelete));
            }

            lock (snapshots)
            {
                snapshots.Remove(toDelete.id);
            }
        }
Example #11
0
        public void addSnapshot(snapshot baseSnapshot)
        {
            lock (events)
            {
                events.Add(new mockedCall("addSnapshot", "baseSnapshot: '" + baseSnapshot + "'"));
            }

            lock (snapshots)
            {
                snapshots.Add(baseSnapshot.id, baseSnapshot);
            }
        }
Example #12
0
 public override void rollbackSnapshot(snapshot shotToRestore)
 {
     snapshotsLock.EnterWriteLock();
     try
     {
         uncachedNAS.getSnapshots().Clear();
         uncachedNAS.getSnapshots().ForEach(x => snapshots.TryAdd(x.id, x));
     }
     catch (Exception)
     {
         snapshots.Clear();
         throw;
     }
     finally
     {
         snapshotsLock.ExitWriteLock();
     }
 }
Example #13
0
        public override snapshot createSnapshot(string dataset, string snapshotName)
        {
            lock (events)
            {
                events.Add(new mockedCall("createSnapshot", "dataset: '" + dataset + "' snapshotName: " + snapshotName));
            }

            lock (snapshots)
            {
                string   newID   = idGen.Next().ToString();
                snapshot newShot = new snapshot()
                {
                    fullname   = "/dev/foo/bar/" + snapshotName,
                    id         = newID,
                    name       = snapshotName,
                    filesystem = dataset
                };
                snapshots.Add(newID, newShot);
                return(snapshots[newID]);
            }
        }
Example #14
0
 public override void cloneSnapshot(snapshot toClone, string fullCloneName)
 {
     uncachedNAS.cloneSnapshot(toClone, fullCloneName);
 }
Example #15
0
 public abstract void rollbackSnapshot(snapshot shotToRestore);
Example #16
0
 public abstract void cloneSnapshot(snapshot toClone, string fullCloneName);
Example #17
0
 public abstract void deleteSnapshot(snapshot toDelete);