Exemplo n.º 1
0
        public void ExecuteTask(IDuplicityTask task)
        {
            Dictionary<string, string> options = new Dictionary<string,string>();

            //Set the log level to be that of the GUI
            options["log-level"] = Duplicati.Library.Logging.Log.LogLevel.ToString();

            string destination = task.GetConfiguration(options);

            string results = "";
            string parsedMessage = "";
            m_isAborted = false;

            try
            {
                //TODO: Its a bit dirty to set the options after creating the instance
                using (Interface i = new Interface(destination, options))
                {
                    lock (m_lock)
                    {
                        m_stopReason = System.Windows.Forms.CloseReason.None;
                        m_currentBackupControlInterface = i;
                    }

                    SetupControlInterface();

                    i.OperationProgress += new OperationProgressEvent(Duplicati_OperationProgress);

                    switch (task.TaskType)
                    {
                        case DuplicityTaskType.FullBackup:
                        case DuplicityTaskType.IncrementalBackup:
                            {
                                //Activate auto-cleanup
                                options["auto-cleanup"] = "";
                                options["force"] = "";
                                if (task.Schedule.Task.KeepFull > 0)
                                    m_extraOperations++;
                                if (!string.IsNullOrEmpty(task.Schedule.Task.KeepTime))
                                    m_extraOperations++;

                                Library.Utility.TempFolder tf = null;
                                try
                                {
                                    if (ProgressEvent != null)
                                        ProgressEvent(DuplicatiOperation.Backup, RunnerState.Started, task.Schedule.Name, "", 0, -1);

                                    if (task.Task.IncludeSetup)
                                    {
                                        //Make a copy of the current database
                                        tf = new Duplicati.Library.Utility.TempFolder();
                                        string filename = System.IO.Path.Combine(tf, System.IO.Path.GetFileName(Program.DatabasePath));

                                        System.IO.File.Copy(Program.DatabasePath, filename, true);
                                        using (System.Data.IDbConnection con = (System.Data.IDbConnection)Activator.CreateInstance(SQLiteLoader.SQLiteConnectionType))
                                        {
                                            con.ConnectionString = "Data Source=" + filename;

                                            //Open the database, handle any encryption issues automatically
                                            Program.OpenDatabase(con);

                                            using (System.Data.IDbCommand cmd = con.CreateCommand())
                                            {
                                                //Remove all log data to minimize the size of the database
                                                cmd.CommandText = "DELETE FROM CommandQueue;";
                                                cmd.ExecuteNonQuery();
                                                cmd.CommandText = "DELETE FROM Log;";
                                                cmd.ExecuteNonQuery();
                                                cmd.CommandText = "DELETE FROM LogBlob;";
                                                cmd.ExecuteNonQuery();

                                                //Free up unused space
                                                cmd.CommandText = "VACUUM;";
                                                cmd.ExecuteNonQuery();
                                            }
                                        }

                                        options["signature-control-files"] = filename;
                                    }

                                    options["full-if-sourcefolder-changed"] = "";

                                    List<KeyValuePair<bool, string>> filters = new List<KeyValuePair<bool, string>>();
                                    string[] sourceFolders = DynamicSetupHelper.GetSourceFolders(task.Task, new ApplicationSettings(task.Task.DataParent), filters);

                                    if (options.ContainsKey("filter"))
                                        filters.AddRange(Library.Utility.FilenameFilter.DecodeFilter(options["filter"]));

                                    options["filter"] = Library.Utility.FilenameFilter.EncodeAsFilter(filters);

                                    //At this point we register the backup as being in progress
                                    ((FullOrIncrementalTask)task).WriteBackupInProgress(Strings.DuplicatiRunner.ShutdownWhileBackupInprogress);

                                    results = i.Backup(sourceFolders);
                                }
                                finally
                                {
                                    if (tf != null)
                                        tf.Dispose();

                                    if (ProgressEvent != null)
                                        ProgressEvent(DuplicatiOperation.Backup, RunnerState.Stopped, task.Schedule.Name, "", 100, -1);
                                }
                                break;
                            }
                        case DuplicityTaskType.ListBackups:

                            List<string> res = new List<string>();
                            foreach (ManifestEntry be in i.GetBackupSets())
                            {
                                res.Add(be.Time.ToString());
                                foreach (ManifestEntry bei in be.Incrementals)
                                    res.Add(bei.Time.ToString());
                            }

                            (task as ListBackupsTask).Backups = res.ToArray();
                            break;
                        case DuplicityTaskType.ListBackupEntries:
                            (task as ListBackupEntriesTask).Backups = i.GetBackupSets();
                            break;
                        case DuplicityTaskType.ListFiles:
                            (task as ListFilesTask).Files = i.ListCurrentFiles();
                            break;
                        case DuplicityTaskType.ListSourceFolders:
                            (task as ListSourceFoldersTask).Files = new List<string>(i.ListSourceFolders() ?? new string[0]);
                            break;
                        case DuplicityTaskType.ListActualFiles:
                            (task as ListActualFilesTask).Files = i.ListActualSignatureFiles();
                            break;
                        case DuplicityTaskType.RemoveAllButNFull:
                            results = i.DeleteAllButNFull();
                            break;
                        case DuplicityTaskType.RemoveOlderThan:
                            results = i.DeleteOlderThan();
                            break;
                        case DuplicityTaskType.Restore:
                            options["file-to-restore"] = ((RestoreTask)task).SourceFiles;
                            if (options.ContainsKey("filter"))
                                options.Remove("filter");

                            try
                            {
                                if (ProgressEvent != null)
                                    ProgressEvent(DuplicatiOperation.Restore, RunnerState.Started, task.Schedule.Name, "", 0, -1);
                                results = i.Restore(task.LocalPath.Split(System.IO.Path.PathSeparator));
                            }
                            finally
                            {
                                if (ProgressEvent != null)
                                    ProgressEvent(DuplicatiOperation.Restore, RunnerState.Stopped, task.Schedule.Name, "", 100, -1);
                            }
                            break;

                        case DuplicityTaskType.RestoreSetup:
                            i.RestoreControlFiles(task.LocalPath);
                            break;
                        default:
                            return;
                    }
                }
            }
            catch (Exception ex)
            {
                while (ex is System.Reflection.TargetInvocationException && ex.InnerException != null)
                    ex = ex.InnerException;

                if (ex is System.Threading.ThreadAbortException)
                {
                    m_isAborted = true;
                    System.Threading.Thread.ResetAbort();
                }
                else if (ex is Library.Main.LiveControl.ExecutionStoppedException)
                    m_isAborted = true;

                if (m_isAborted && m_stopReason != System.Windows.Forms.CloseReason.None)
                {
                    //If the user has stopped the backup for some reason, write a nicer message
                    switch (m_stopReason)
                    {
                        case System.Windows.Forms.CloseReason.ApplicationExitCall:
                            parsedMessage = Strings.DuplicatiRunner.ApplicationExitLogMesssage;
                            break;
                        case System.Windows.Forms.CloseReason.TaskManagerClosing:
                            parsedMessage = Strings.DuplicatiRunner.TaskManagerCloseMessage;
                            break;
                        case System.Windows.Forms.CloseReason.UserClosing:
                            parsedMessage = Strings.DuplicatiRunner.UserClosingMessage;
                            break;
                        case System.Windows.Forms.CloseReason.WindowsShutDown:
                            parsedMessage = Strings.DuplicatiRunner.WindowsShutdownMessage;
                            break;
                        default:
                            parsedMessage = string.Format(Strings.DuplicatiRunner.OtherAbortMessage, m_stopReason);
                            break;
                    }

                    if (task.Schedule != null)
                    {
                        //If the application is going down, the backup should resume on next launch
                        switch (m_stopReason)
                        {
                            case System.Windows.Forms.CloseReason.ApplicationExitCall:
                            case System.Windows.Forms.CloseReason.TaskManagerClosing:
                            case System.Windows.Forms.CloseReason.WindowsShutDown:
                                task.Schedule.ScheduledRunFailed();
                                break;
                        }
                    }
                }
                else
                    parsedMessage = string.Format(Strings.DuplicatiRunner.ErrorMessage, ex.Message);

                results = "Error: " + ex.ToString(); //Don't localize

                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                    results += Environment.NewLine + "InnerError: " + ex.ToString(); //Don't localize
                }

            }
            finally
            {
                lock (m_lock)
                    m_currentBackupControlInterface = null;
            }

            try
            {
                if (!m_isAborted && (task.TaskType == DuplicityTaskType.FullBackup || task.TaskType == DuplicityTaskType.IncrementalBackup))
                {
                    if (task.Schedule.Task.KeepFull > 0)
                    {
                        m_lastPGProgress = 100;
                        m_lastPGmessage = Strings.DuplicatiRunner.CleaningUpMessage;
                        m_lastPGSubmessage = "";
                        m_lastPGSubprogress = -1;

                        ReinvokeLastProgressEvent();
                        m_extraOperations--;

                        RemoveAllButNFullTask tmpTask = new RemoveAllButNFullTask(task.Schedule, (int)task.Schedule.Task.KeepFull);
                        ExecuteTask(tmpTask);
                        results += Environment.NewLine + Strings.DuplicatiRunner.CleanupLogdataHeader + Environment.NewLine + tmpTask.Result;
                    }

                    if (!string.IsNullOrEmpty(task.Schedule.Task.KeepTime))
                    {
                        m_lastPGProgress = 100;
                        m_lastPGmessage = Strings.DuplicatiRunner.CleaningUpMessage;
                        m_lastPGSubmessage = "";
                        m_lastPGSubprogress = -1;

                        ReinvokeLastProgressEvent();
                        m_extraOperations--;

                        RemoveOlderThanTask tmpTask = new RemoveOlderThanTask(task.Schedule, task.Schedule.Task.KeepTime);
                        ExecuteTask(tmpTask);
                        results += Environment.NewLine + Strings.DuplicatiRunner.CleanupLogdataHeader + Environment.NewLine + tmpTask.Result;
                    }

                    if (task.Schedule.Task.KeepFull > 0 || !string.IsNullOrEmpty(task.Schedule.Task.KeepTime))
                        ReinvokeLastProgressEvent();

                    if (ProgressEvent != null)
                        ProgressEvent(DuplicatiOperation.Backup, RunnerState.Stopped, task.Schedule.Name, "", 100, -1);
                }
            }
            catch (Exception ex)
            {
                results += Environment.NewLine + string.Format(Strings.DuplicatiRunner.CleanupError, ex.Message);
            }

            task.IsAborted = m_isAborted;
            task.Result = results;
            task.RaiseTaskCompleted(results, parsedMessage);

            if (ResultEvent != null && task is FullBackupTask || task is IncrementalBackupTask)
            {
                Log[] logs = Program.DataConnection.GetObjects<Log>("TaskID = ? AND SubAction LIKE ? ORDER BY EndTime DESC", task.Task.ID, "Primary");
                if (logs != null && logs.Length > 0)
                {
                    Datamodel.Log l = logs[0];
                    RunnerResult r = RunnerResult.Error;
                    if (l.ParsedStatus == DuplicatiOutputParser.ErrorStatus)
                        r = RunnerResult.Error;
                    else if (l.ParsedStatus == DuplicatiOutputParser.OKStatus || l.ParsedStatus == DuplicatiOutputParser.NoChangedFiles)
                        r = RunnerResult.OK;
                    else if (l.ParsedStatus == DuplicatiOutputParser.PartialStatus)
                        r = RunnerResult.Partial;
                    else if (l.ParsedStatus == DuplicatiOutputParser.WarningStatus)
                        r = RunnerResult.Warning;

                    ResultEvent(r, parsedMessage, results);
                }
            }

            if (task.Schedule != null && !m_isAborted)
                task.Schedule.ScheduledRunCompleted(); //Register as completed if not aborted
        }
Exemplo n.º 2
0
        public void ExecuteTask(IDuplicityTask task)
        {
            Dictionary <string, string> options = new Dictionary <string, string>();

            //Set the log level to be that of the GUI
            options["log-level"] = Duplicati.Library.Logging.Log.LogLevel.ToString();

            string destination = task.GetConfiguration(options);

            string results       = "";
            string parsedMessage = "";

            m_isAborted = false;

            try
            {
                //TODO: Its a bit dirty to set the options after creating the instance
                using (Interface i = new Interface(destination, options))
                {
                    lock (m_lock)
                    {
                        m_stopReason = System.Windows.Forms.CloseReason.None;
                        m_currentBackupControlInterface = i;
                    }

                    SetupControlInterface();

                    i.OperationProgress += new OperationProgressEvent(Duplicati_OperationProgress);

                    switch (task.TaskType)
                    {
                    case DuplicityTaskType.FullBackup:
                    case DuplicityTaskType.IncrementalBackup:
                    {
                        //Activate auto-cleanup
                        options["auto-cleanup"] = "";
                        options["force"]        = "";
                        if (task.Schedule.Task.KeepFull > 0)
                        {
                            m_extraOperations++;
                        }
                        if (!string.IsNullOrEmpty(task.Schedule.Task.KeepTime))
                        {
                            m_extraOperations++;
                        }

                        Library.Utility.TempFolder tf = null;
                        try
                        {
                            if (ProgressEvent != null)
                            {
                                ProgressEvent(DuplicatiOperation.Backup, RunnerState.Started, task.Schedule.Name, "", 0, -1);
                            }

                            if (task.Task.IncludeSetup)
                            {
                                //Make a copy of the current database
                                tf = new Duplicati.Library.Utility.TempFolder();
                                string filename = System.IO.Path.Combine(tf, System.IO.Path.GetFileName(Program.DatabasePath));

                                System.IO.File.Copy(Program.DatabasePath, filename, true);
                                using (System.Data.IDbConnection con = (System.Data.IDbConnection)Activator.CreateInstance(SQLiteLoader.SQLiteConnectionType))
                                {
                                    con.ConnectionString = "Data Source=" + filename;

                                    //Open the database, handle any encryption issues automatically
                                    Program.OpenDatabase(con);

                                    using (System.Data.IDbCommand cmd = con.CreateCommand())
                                    {
                                        //Remove all log data to minimize the size of the database
                                        cmd.CommandText = "DELETE FROM CommandQueue;";
                                        cmd.ExecuteNonQuery();
                                        cmd.CommandText = "DELETE FROM Log;";
                                        cmd.ExecuteNonQuery();
                                        cmd.CommandText = "DELETE FROM LogBlob;";
                                        cmd.ExecuteNonQuery();

                                        //Free up unused space
                                        cmd.CommandText = "VACUUM;";
                                        cmd.ExecuteNonQuery();
                                    }
                                }

                                options["signature-control-files"] = filename;
                            }

                            options["full-if-sourcefolder-changed"] = "";

                            List <KeyValuePair <bool, string> > filters = new List <KeyValuePair <bool, string> >();
                            string[] sourceFolders = DynamicSetupHelper.GetSourceFolders(task.Task, new ApplicationSettings(task.Task.DataParent), filters);

                            if (options.ContainsKey("filter"))
                            {
                                filters.AddRange(Library.Utility.FilenameFilter.DecodeFilter(options["filter"]));
                            }

                            options["filter"] = Library.Utility.FilenameFilter.EncodeAsFilter(filters);

                            //At this point we register the backup as being in progress
                            ((FullOrIncrementalTask)task).WriteBackupInProgress(Strings.DuplicatiRunner.ShutdownWhileBackupInprogress);

                            results = i.Backup(sourceFolders);
                        }
                        finally
                        {
                            if (tf != null)
                            {
                                tf.Dispose();
                            }

                            if (ProgressEvent != null)
                            {
                                ProgressEvent(DuplicatiOperation.Backup, RunnerState.Stopped, task.Schedule.Name, "", 100, -1);
                            }
                        }
                        break;
                    }

                    case DuplicityTaskType.ListBackups:

                        List <string> res = new List <string>();
                        foreach (ManifestEntry be in i.GetBackupSets())
                        {
                            res.Add(be.Time.ToString());
                            foreach (ManifestEntry bei in be.Incrementals)
                            {
                                res.Add(bei.Time.ToString());
                            }
                        }

                        (task as ListBackupsTask).Backups = res.ToArray();
                        break;

                    case DuplicityTaskType.ListBackupEntries:
                        (task as ListBackupEntriesTask).Backups = i.GetBackupSets();
                        break;

                    case DuplicityTaskType.ListFiles:
                        (task as ListFilesTask).Files = i.ListCurrentFiles();
                        break;

                    case DuplicityTaskType.ListSourceFolders:
                        (task as ListSourceFoldersTask).Files = new List <string>(i.ListSourceFolders() ?? new string[0]);
                        break;

                    case DuplicityTaskType.ListActualFiles:
                        (task as ListActualFilesTask).Files = i.ListActualSignatureFiles();
                        break;

                    case DuplicityTaskType.RemoveAllButNFull:
                        results = i.DeleteAllButNFull();
                        break;

                    case DuplicityTaskType.RemoveOlderThan:
                        results = i.DeleteOlderThan();
                        break;

                    case DuplicityTaskType.Restore:
                        options["file-to-restore"] = ((RestoreTask)task).SourceFiles;
                        if (options.ContainsKey("filter"))
                        {
                            options.Remove("filter");
                        }

                        try
                        {
                            if (ProgressEvent != null)
                            {
                                ProgressEvent(DuplicatiOperation.Restore, RunnerState.Started, task.Schedule.Name, "", 0, -1);
                            }
                            results = i.Restore(task.LocalPath.Split(System.IO.Path.PathSeparator));
                        }
                        finally
                        {
                            if (ProgressEvent != null)
                            {
                                ProgressEvent(DuplicatiOperation.Restore, RunnerState.Stopped, task.Schedule.Name, "", 100, -1);
                            }
                        }
                        break;

                    case DuplicityTaskType.RestoreSetup:
                        i.RestoreControlFiles(task.LocalPath);
                        break;

                    default:
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                while (ex is System.Reflection.TargetInvocationException && ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                if (ex is System.Threading.ThreadAbortException)
                {
                    m_isAborted = true;
                    System.Threading.Thread.ResetAbort();
                }
                else if (ex is Library.Main.LiveControl.ExecutionStoppedException)
                {
                    m_isAborted = true;
                }

                if (m_isAborted && m_stopReason != System.Windows.Forms.CloseReason.None)
                {
                    //If the user has stopped the backup for some reason, write a nicer message
                    switch (m_stopReason)
                    {
                    case System.Windows.Forms.CloseReason.ApplicationExitCall:
                        parsedMessage = Strings.DuplicatiRunner.ApplicationExitLogMesssage;
                        break;

                    case System.Windows.Forms.CloseReason.TaskManagerClosing:
                        parsedMessage = Strings.DuplicatiRunner.TaskManagerCloseMessage;
                        break;

                    case System.Windows.Forms.CloseReason.UserClosing:
                        parsedMessage = Strings.DuplicatiRunner.UserClosingMessage;
                        break;

                    case System.Windows.Forms.CloseReason.WindowsShutDown:
                        parsedMessage = Strings.DuplicatiRunner.WindowsShutdownMessage;
                        break;

                    default:
                        parsedMessage = string.Format(Strings.DuplicatiRunner.OtherAbortMessage, m_stopReason);
                        break;
                    }

                    if (task.Schedule != null)
                    {
                        //If the application is going down, the backup should resume on next launch
                        switch (m_stopReason)
                        {
                        case System.Windows.Forms.CloseReason.ApplicationExitCall:
                        case System.Windows.Forms.CloseReason.TaskManagerClosing:
                        case System.Windows.Forms.CloseReason.WindowsShutDown:
                            task.Schedule.ScheduledRunFailed();
                            break;
                        }
                    }
                }
                else
                {
                    parsedMessage = string.Format(Strings.DuplicatiRunner.ErrorMessage, ex.Message);
                }

                results = "Error: " + ex.ToString(); //Don't localize

                while (ex.InnerException != null)
                {
                    ex       = ex.InnerException;
                    results += Environment.NewLine + "InnerError: " + ex.ToString(); //Don't localize
                }
            }
            finally
            {
                lock (m_lock)
                    m_currentBackupControlInterface = null;
            }

            try
            {
                if (!m_isAborted && (task.TaskType == DuplicityTaskType.FullBackup || task.TaskType == DuplicityTaskType.IncrementalBackup))
                {
                    if (task.Schedule.Task.KeepFull > 0)
                    {
                        m_lastPGProgress    = 100;
                        m_lastPGmessage     = Strings.DuplicatiRunner.CleaningUpMessage;
                        m_lastPGSubmessage  = "";
                        m_lastPGSubprogress = -1;

                        ReinvokeLastProgressEvent();
                        m_extraOperations--;

                        RemoveAllButNFullTask tmpTask = new RemoveAllButNFullTask(task.Schedule, (int)task.Schedule.Task.KeepFull);
                        ExecuteTask(tmpTask);
                        results += Environment.NewLine + Strings.DuplicatiRunner.CleanupLogdataHeader + Environment.NewLine + tmpTask.Result;
                    }

                    if (!string.IsNullOrEmpty(task.Schedule.Task.KeepTime))
                    {
                        m_lastPGProgress    = 100;
                        m_lastPGmessage     = Strings.DuplicatiRunner.CleaningUpMessage;
                        m_lastPGSubmessage  = "";
                        m_lastPGSubprogress = -1;

                        ReinvokeLastProgressEvent();
                        m_extraOperations--;

                        RemoveOlderThanTask tmpTask = new RemoveOlderThanTask(task.Schedule, task.Schedule.Task.KeepTime);
                        ExecuteTask(tmpTask);
                        results += Environment.NewLine + Strings.DuplicatiRunner.CleanupLogdataHeader + Environment.NewLine + tmpTask.Result;
                    }

                    if (task.Schedule.Task.KeepFull > 0 || !string.IsNullOrEmpty(task.Schedule.Task.KeepTime))
                    {
                        ReinvokeLastProgressEvent();
                    }

                    if (ProgressEvent != null)
                    {
                        ProgressEvent(DuplicatiOperation.Backup, RunnerState.Stopped, task.Schedule.Name, "", 100, -1);
                    }
                }
            }
            catch (Exception ex)
            {
                results += Environment.NewLine + string.Format(Strings.DuplicatiRunner.CleanupError, ex.Message);
            }

            task.IsAborted = m_isAborted;
            task.Result    = results;
            task.RaiseTaskCompleted(results, parsedMessage);

            if (ResultEvent != null && task is FullBackupTask || task is IncrementalBackupTask)
            {
                Log[] logs = Program.DataConnection.GetObjects <Log>("TaskID = ? AND SubAction LIKE ? ORDER BY EndTime DESC", task.Task.ID, "Primary");
                if (logs != null && logs.Length > 0)
                {
                    Datamodel.Log l = logs[0];
                    RunnerResult  r = RunnerResult.Error;
                    if (l.ParsedStatus == DuplicatiOutputParser.ErrorStatus)
                    {
                        r = RunnerResult.Error;
                    }
                    else if (l.ParsedStatus == DuplicatiOutputParser.OKStatus || l.ParsedStatus == DuplicatiOutputParser.NoChangedFiles)
                    {
                        r = RunnerResult.OK;
                    }
                    else if (l.ParsedStatus == DuplicatiOutputParser.PartialStatus)
                    {
                        r = RunnerResult.Partial;
                    }
                    else if (l.ParsedStatus == DuplicatiOutputParser.WarningStatus)
                    {
                        r = RunnerResult.Warning;
                    }

                    ResultEvent(r, parsedMessage, results);
                }
            }

            if (task.Schedule != null && !m_isAborted)
            {
                task.Schedule.ScheduledRunCompleted(); //Register as completed if not aborted
            }
        }