Beispiel #1
0
        private static List <ConfigPair> ParseBackupOrRestoreArgs(List <string> args, bool isBackup, Dictionary <string, Type> pipelineComponents, Dictionary <string, Type> databaseComponents, Dictionary <string, Type> storageComponents, out ConfigPair databaseConfig, out ConfigPair storageConfig)
        {
            if (args.Count < 2)
            {
                throw new ArgumentException("Please provide both the database and storage plugins after the backup subcommand.");
            }


            string databaseArg;
            string storageArg;

            if (isBackup)
            {
                databaseArg = args[0];
                storageArg  = args[args.Count - 1];
            }
            else
            {
                databaseArg = args[args.Count - 1];
                storageArg  = args[0];
            }


            if (databaseArg.Contains("://"))
            {
                throw new ArgumentException("The first sub argument must be the name of the database.");
            }

            if (databaseArg[0] == '[' && databaseArg[databaseArg.Length - 1] == ']')
            {
                databaseArg = string.Format("db(database={0})", databaseArg.Substring(1, databaseArg.Length - 2).Replace(";", ";;"));
            }

            databaseConfig = ConfigUtil.ParseComponentConfig(databaseComponents, databaseArg);



            if (storageArg[0] == '[' && storageArg[databaseArg.Length - 1] == ']')
            {
                throw new ArgumentException("The last sub argument must be a storage plugin.");
            }

            if (storageArg.StartsWith("file://"))
            {
                Uri uri = new Uri(storageArg);
                storageArg = string.Format("local(path={0})", uri.LocalPath.Replace(";", ";;"));
            }


            storageConfig = ConfigUtil.ParseComponentConfig(storageComponents, storageArg);



            List <string> pipelineArgs = new List <string>();

            for (int i = 1; i < args.Count - 1; i++)
            {
                pipelineArgs.Add(args[i]);
            }


            List <ConfigPair> pipeline = BuildPipelineFromString(pipelineArgs, pipelineComponents);


            return(pipeline);
        }
Beispiel #2
0
        static int Main(string[] args)
        {
            //TODO: add pause on complete switch to command line
            //TODO: restore on top of an existing database? no error message
            //TODO: package version number does not match assembly's version number.
            //TODO: cntl-c kills the app, but we can handle the event: http://www.codeneverwritten.com/2006/10/ctrl-c-and-net-console-application.html
            //TODO: Do escaped cmd line args work?
            //TODO: error on overwrite?
            //TODO: Verify SQL Server version compatibility preferred 2000 throught 2014+
            //TODO: better device timeout, longer execution timeout (db might be locked)
            //TODO: check file extensions
            try
            {
                //everything here is modular and is passed from pipeline to pipeline these are the
                //three main pipelines, pipeline componnets are for compression, encryption and filters
                //anything that would be considered a filter
                //database components are the VDI commands and data stream from the backup or restore operation
                //storage components are the last stage and consists of just disk targets at the moment.
                var pipelineComponents = BackupPipeSystem.LoadTransformComponents();
                var databaseComponents = BackupPipeSystem.LoadDatabaseComponents();
                var storageComponents  = BackupPipeSystem.LoadStorageComponents();

                if (args.Length == 0)
                {
                    Console.WriteLine("For help, type \'msbp.exe help\'");
                    return(0);
                }
                switch (args[0].ToLowerInvariant())
                {
                case "help":
                    if (args.Length == 1)
                    {
                        PrintHelp.PrintUsage();
                    }
                    else
                    {
                        switch (args[1].ToLowerInvariant())
                        {
                        case "backup":
                            PrintHelp.PrintBackupUsage();
                            break;

                        case "restore":
                            PrintHelp.PrintRestoreUsage();
                            break;

                        case "restoreverifyonly":
                            PrintHelp.PrintVerifyOnlyUsage();
                            break;

                        case "restoreheaderonly":
                            PrintHelp.PrintRestoreHeaderOnlyUsage();
                            break;

                        case "restorefilelistonly":
                            PrintHelp.PrintRestoreFilelistOnlyUsage();
                            break;

                        case "listplugins":
                            Console.WriteLine("Lists the plugins available.  Go on, try it.");
                            break;

                        case "helpplugin":
                            Console.WriteLine("Displays a plugin's help text. For example:");
                            Console.WriteLine("\tmsbp.exe helpplugin gzip");
                            break;

                        case "version":
                            Console.WriteLine("Displays the version number.");
                            break;

                        default:
                            Console.WriteLine("Command doesn't exist: {0}", args[1]);
                            PrintHelp.PrintUsage();
                            return(-1);
                        }
                    }
                    return(0);

                //start of backup command
                case "backup":
                {
                    try
                    {
                        ConfigPair storageConfig;
                        ConfigPair databaseConfig;
                        const int  commandType = 1;

                        var pipelineConfig = ParseBackupOrRestoreArgs(CopySubArgs(args), commandType, pipelineComponents, databaseComponents, storageComponents, out databaseConfig, out storageConfig);
                        //async notifier for percent complete report
                        var notifier = new CommandLineNotifier(true);

                        var startTime = DateTime.UtcNow;
                        //configure and start backup command
                        List <string> devicenames;
                        BackupPipeSystem.Backup(databaseConfig, pipelineConfig, storageConfig, notifier, out devicenames);
                        Console.WriteLine("Completed Successfully. {0}", string.Format("{0:dd\\:hh\\:mm\\:ss\\.ff}", DateTime.UtcNow - startTime));

                        //this is so we can do a restore filelistonly and restore headeronly
                        HeaderFileList.WriteHeaderFilelist(databaseConfig, storageConfig, devicenames);

#if DEBUG
                        Console.WriteLine();
                        Console.WriteLine("Hit Any Key To Continue:");
                        Console.ReadKey();
#endif
                        return(0);
                    }
                    catch (ParallelExecutionException ee)
                    {
                        HandleExecutionExceptions(ee, true);
                        return(-1);
                    }
                    catch (Exception e)
                    {
                        HandleException(e, true);
                        return(-1);
                    }
                }

                //start of restore command
                case "restore":
                {
                    try
                    {
                        ConfigPair storageConfig;
                        ConfigPair databaseConfig;

                        const int commandType = 2;

                        var pipelineConfig = ParseBackupOrRestoreArgs(CopySubArgs(args), commandType, pipelineComponents, databaseComponents, storageComponents, out databaseConfig, out storageConfig);
                        //async notifier for percent complete report
                        var notifier = new CommandLineNotifier(false);

                        var startTime = DateTime.UtcNow;
                        //configure and start restore command
                        BackupPipeSystem.Restore(storageConfig, pipelineConfig, databaseConfig, notifier);
                        Console.WriteLine("Completed Successfully. {0}", string.Format("{0:dd\\:hh\\:mm\\:ss\\.ff}", DateTime.UtcNow - startTime));
                        return(0);
                    }
                    catch (ParallelExecutionException ee)
                    {
                        HandleExecutionExceptions(ee, false);
                        return(-1);
                    }
                    catch (Exception e)
                    {
                        HandleException(e, false);
                        return(-1);
                    }
                }

                case "restorefilelistonly":
                {
                    var startTime = DateTime.UtcNow;
                    var bFormat   = new BinaryFormatter();
                    //var hargs = CopySubArgs(args);
                    var        storageArg = args[1];
                    ConfigPair storageConfig;
                    try
                    {
                        if (storageArg.StartsWith("file://"))
                        {
                            var uri = new Uri(storageArg);
                            storageArg = string.Format("local(path={0})", uri.LocalPath.Replace(";", ";;"));
                        }
                    }
                    catch (Exception e)
                    {
                        HandleException(e, false);
                        return(-1);
                    }
                    try
                    {
                        storageConfig = ConfigUtil.ParseComponentConfig(storageComponents, storageArg);
                    }
                    catch (Exception e)
                    {
                        HandleException(e, false);
                        return(-1);
                    }
                    var metaDataPath = storageConfig.Parameters["path"][0];
                    if (!File.Exists(metaDataPath))
                    {
                        metaDataPath = storageConfig.Parameters["path"][0] + ".hfl";
                    }

                    try
                    {
                        using (var fs = new FileStream(metaDataPath, FileMode.Open))
                        {
                            using (var headerOnlyData = (DataSet)bFormat.Deserialize(fs))
                            {
                                using (var table = headerOnlyData.Tables[1])
                                {
                                    var sb = new StringBuilder();
                                    foreach (DataColumn column in table.Columns)
                                    {
                                        sb.Append(column);
                                        sb.Append(",");
                                    }
                                    sb.Length -= 1;
                                    sb.AppendLine();
                                    foreach (DataRow row in table.Rows)     // Loop over the rows.
                                    {
                                        foreach (var value in row.ItemArray)
                                        {
                                            sb.Append(value);
                                            sb.Append(",");
                                        }
                                        sb.Length -= 1;
                                        sb.AppendLine();
                                    }
                                    Console.WriteLine(sb.ToString());
                                }
                            }
                            Console.WriteLine("Completed Successfully. {0}", string.Format("{0:dd\\:hh\\:mm\\:ss\\.ff}", DateTime.UtcNow - startTime));
                        }
                        return(0);
                    }
                    catch (Exception e)
                    {
                        HandleException(e, false);
                        return(-1);
                    }
                }

                case "restoreheaderonly":
                {
                    var        startTime  = DateTime.UtcNow;
                    var        bFormat    = new BinaryFormatter();
                    var        storageArg = args[1];
                    ConfigPair storageConfig;
                    try
                    {
                        if (storageArg.StartsWith("file://"))
                        {
                            var uri = new Uri(storageArg);
                            storageArg = string.Format("local(path={0})", uri.LocalPath.Replace(";", ";;"));
                        }
                    }
                    catch (Exception e)
                    {
                        HandleException(e, false);
                        return(-1);
                    }
                    try
                    {
                        storageConfig = ConfigUtil.ParseComponentConfig(storageComponents, storageArg);
                    }
                    catch (Exception e)
                    {
                        HandleException(e, false);
                        return(-1);
                    }

                    var metaDataPath = storageConfig.Parameters["path"][0];
                    if (!File.Exists(metaDataPath))
                    {
                        metaDataPath = storageConfig.Parameters["path"][0] + ".hfl";
                    }

                    try
                    {
                        using (var fs = new FileStream(metaDataPath, FileMode.Open))
                        {
                            using (var headerOnlyData = (DataSet)bFormat.Deserialize(fs))
                            {
                                using (var table = headerOnlyData.Tables[0])
                                {
                                    var sb = new StringBuilder();
                                    foreach (DataColumn column in table.Columns)
                                    {
                                        sb.Append(column);
                                        sb.Append(",");
                                    }
                                    sb.Length -= 1;
                                    sb.AppendLine();
                                    foreach (DataRow row in table.Rows)     // Loop over the rows.
                                    {
                                        foreach (var value in row.ItemArray)
                                        {
                                            sb.Append(value);
                                            sb.Append(",");
                                        }
                                        sb.Length -= 1;
                                        sb.AppendLine();
                                    }
                                    Console.WriteLine(sb.ToString());
                                }
                                Console.WriteLine("Completed Successfully. {0}", string.Format("{0:dd\\:hh\\:mm\\:ss\\.ff}", DateTime.UtcNow - startTime));
                            }
                        }
                        return(0);
                    }
                    catch (Exception e)
                    {
                        HandleException(e, false);
                        return(-1);
                    }
                }

                case "restoreverifyonly":
                {
                    try
                    {
                        ConfigPair storageConfig;
                        ConfigPair databaseConfig;

                        const int commandType = 3;

                        var pipelineConfig = ParseBackupOrRestoreArgs(CopySubArgs(args), commandType, pipelineComponents, databaseComponents, storageComponents, out databaseConfig, out storageConfig);
                        //async notifier for percent complete report
                        var notifier = new CommandLineNotifier(false);

                        var startTime = DateTime.UtcNow;
                        //configure and start restore command
                        BackupPipeSystem.Verify(storageConfig, pipelineConfig, databaseConfig, notifier);
                        Console.WriteLine("Completed Successfully. {0}", string.Format("{0:dd\\:hh\\:mm\\:ss\\.ff}", DateTime.UtcNow - startTime));
                        return(0);
                    }
                    catch (ParallelExecutionException ee)
                    {
                        HandleExecutionExceptions(ee, false);
                        return(-1);
                    }
                    catch (Exception e)
                    {
                        HandleException(e, false);
                        return(-1);
                    }
                }

                case "listplugins":
                    PrintHelp.PrintPlugins(pipelineComponents, databaseComponents, storageComponents);
                    return(0);

                case "helpplugin":
                    if (args.Length < 2)
                    {
                        Console.WriteLine("Please give a plugin name, like msbp.exe helpplugin <plugin>");
                        return(-1);
                    }
                    return(PrintHelp.PrintPluginHelp(args[1], pipelineComponents, databaseComponents, storageComponents));

                case "version":
                    var version = Assembly.GetEntryAssembly().GetName().Version;
                    //ProcessorArchitecture arch = typeof(VirtualDeviceSet).Assembly.GetName().ProcessorArchitecture;
                    Console.WriteLine("v{0} 32+64 ({1:yyyy MMM dd})", version, (new DateTime(2000, 1, 1)).AddDays(version.Build));
                    return(0);

                default:
                    Console.WriteLine("Unknown command: {0}", args[0]);

                    PrintHelp.PrintUsage();
                    return(-1);
                }
            }

            catch (Exception e)
            {
                Util.WriteError(e);
                //TODO: cut down on verbosity of error messages in release mode

                var ie = e;
                while (ie.InnerException != null)
                {
                    ie = ie.InnerException;
                }
                if (!ie.Equals(e))
                {
                    Console.WriteLine(ie.Message);
                }
                PrintHelp.PrintUsage();
                return(-1);
            }
        }