Example #1
0
        private void SaveTagInfoToImageInfoFile(DateTime createdDate, ImageArtifactDetails imageArtifactDetails)
        {
            _loggerService.WriteSubheading("SETTING TAG INFO");

            IEnumerable <ImageData> images = imageArtifactDetails.Repos
                                             .SelectMany(repo => repo.Images)
                                             .Where(image => image.Manifest != null);

            Parallel.ForEach(images, image =>
            {
                image.Manifest.Created = createdDate;

                TagInfo sharedTag     = image.ManifestImage.SharedTags.First();
                image.Manifest.Digest = DockerHelper.GetDigestString(
                    image.ManifestRepo.FullModelName,
                    _manifestToolService.GetManifestDigestSha(
                        ManifestMediaType.ManifestList, sharedTag.FullyQualifiedName, Options.IsDryRun));
            });

            string imageInfoString = JsonHelper.SerializeObject(imageArtifactDetails);

            File.WriteAllText(Options.ImageInfoPath, imageInfoString);
        }
        private IEnumerable <string> GenerateManifests(RepoInfo repo, ImageInfo image)
        {
            yield return(GenerateManifest(repo, image, image.SharedTags.Select(tag => tag.Name),
                                          tag => DockerHelper.GetImageName(Manifest.Registry, Options.RepoPrefix + repo.Name, tag),
                                          platform => platform.Tags.First()));

            IEnumerable <IGrouping <string, TagInfo> > syndicatedTagGroups = image.SharedTags
                                                                             .Where(tag => tag.SyndicatedRepo != null)
                                                                             .GroupBy(tag => tag.SyndicatedRepo);

            foreach (IGrouping <string, TagInfo> syndicatedTags in syndicatedTagGroups)
            {
                string syndicatedRepo = syndicatedTags.Key;
                IEnumerable <string> destinationTags = syndicatedTags.SelectMany(tag => tag.SyndicatedDestinationTags);

                // There won't always be a platform tag that's syndicated. So if a manifest tag is syndicated, we need to account
                // for the possibility that a given platform for that manifest will not have a matching syndicated repo.

                yield return(GenerateManifest(repo, image, destinationTags,
                                              tag => DockerHelper.GetImageName(Manifest.Registry, Options.RepoPrefix + syndicatedRepo, tag),
                                              platform => platform.Tags.FirstOrDefault(tag => tag.SyndicatedRepo == syndicatedRepo)));
            }
        }
        private void EnsureArchitectureMatches(PlatformInfo platform, IEnumerable <string> allTags)
        {
            if (platform.Model.Architecture == _dockerService.Architecture)
            {
                return;
            }

            string primaryTag = allTags.First();
            IEnumerable <string> secondaryTags = allTags.Except(new[] { primaryTag });

            // Get the architecture from the built image's metadata
            string actualArchitecture   = DockerHelper.GetImageArch(primaryTag, Options.IsDryRun);
            string expectedArchitecture = platform.Model.Architecture.GetDockerName();

            // If the architecture of the built image is what we expect, then exit the method; otherwise, continue
            // with updating the architecture metadata.
            if (string.Equals(actualArchitecture, expectedArchitecture))
            {
                return;
            }

            // Save the Docker image to a tar file
            string tempImageTar = "image.tar.gz";

            DockerHelper.SaveImage(primaryTag, tempImageTar, Options.IsDryRun);
            try
            {
                string tarContentsDirectory = "tar_contents";
                Directory.CreateDirectory(tarContentsDirectory);

                try
                {
                    // Extract the tar file to a separate directory
                    ExecuteHelper.Execute("tar", $"-xf {tempImageTar} -C {tarContentsDirectory}", Options.IsDryRun);

                    // Open the manifest to find the name of the Config json file
                    string manifestContents = File.ReadAllText(Path.Combine(tarContentsDirectory, "manifest.json"));
                    JArray manifestDoc      = JArray.Parse(manifestContents);

                    if (manifestDoc.Count != 1)
                    {
                        throw new InvalidOperationException(
                                  $"Only expected one element in tar archive's manifest:{Environment.NewLine}{manifestContents}");
                    }

                    // Open the Config json file and set the architecture value
                    string  configPath     = Path.Combine(tarContentsDirectory, manifestDoc[0]["Config"].Value <string>());
                    string  configContents = File.ReadAllText(configPath);
                    JObject config         = JObject.Parse(configContents);
                    config["architecture"] = expectedArchitecture;

                    // Overwrite the Config json file with the updated architecture value
                    configContents = JsonConvert.SerializeObject(config);
                    File.WriteAllText(configPath, configContents);

                    // Repackage the directory into an updated tar file
                    ExecuteHelper.Execute("tar", $"-cf {tempImageTar} -C {tarContentsDirectory} .", Options.IsDryRun);
                }
                finally
                {
                    Directory.Delete(tarContentsDirectory, recursive: true);
                }

                // Load the updated tar file back into Docker
                DockerHelper.LoadImage(tempImageTar, Options.IsDryRun);
            }
            finally
            {
                File.Delete(tempImageTar);
            }

            // Recreate the other tags so that they get the updated architecture value.
            Parallel.ForEach(secondaryTags, tag =>
            {
                _dockerService.CreateTag(primaryTag, tag, Options.IsDryRun);
            });
        }
        private void SetPlatformDataDigest(PlatformData platform, string tag)
        {
            // The digest of an image that is pushed to ACR is guaranteed to be the same when transferred to MCR.
            string digest = _imageDigestCache.GetImageDigest(tag, Options.IsDryRun);

            if (digest != null)
            {
                digest = DockerHelper.GetDigestString(platform.PlatformInfo.FullRepoModelName, DockerHelper.GetDigestSha(digest));
            }

            if (platform.Digest != null && platform.Digest != digest)
            {
                // Pushing the same image with different tags should result in the same digest being output
                throw new InvalidOperationException(
                          $"Tag '{tag}' was pushed with a resulting digest value that differs from the corresponding image's digest value." +
                          Environment.NewLine +
                          $"\tDigest value from image info: {platform.Digest}{Environment.NewLine}" +
                          $"\tDigest value retrieved from query: {digest}");
            }

            platform.Digest = digest;
        }
        private void RefreshContainersListInternal()
        {
            int totalContainers = 0;

            try
            {
                IContainerViewModel selectedContainer = SelectedContainerInstance;
                SelectedContainerInstance = null;

                IEnumerable <DockerContainerInstance> containers;

                if (SelectedConnection is LocalConnectionViewModel)
                {
                    containers = DockerHelper.GetLocalDockerContainers(Hostname, out totalContainers);
                }
                else
                {
                    ContainersFoundText = UIResources.SSHConnectingStatusText;
                    var connection = SelectedConnection.Connection;
                    if (connection == null)
                    {
                        UpdateStatusMessage(UIResources.SSHConnectionFailedStatusText, isError: true);
                        return;
                    }
                    containers = DockerHelper.GetRemoteDockerContainers(connection, Hostname, out totalContainers);
                }

                if (containers.Count() > 0)
                {
                    string serverOS;

                    if (DockerHelper.TryGetServerOS(Hostname, out serverOS))
                    {
                        bool     lcow;
                        bool     getLCOW  = DockerHelper.TryGetLCOW(Hostname, out lcow);
                        TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
                        serverOS = textInfo.ToTitleCase(serverOS);

                        /* Note: LCOW is the abbreviation for Linux Containers on Windows
                         *
                         * In LCOW, both Linux and Windows containers can run simultaneously in a Docker (Windows) Engine.
                         * Thus, the container platform must be queried directly.
                         * Otherwise, the container platform must match that of the server engine.
                         */
                        if (lcow && serverOS.Contains("Windows"))
                        {
                            foreach (DockerContainerInstance container in containers)
                            {
                                string containerPlatform = string.Empty;
                                if (DockerHelper.TryGetContainerPlatform(Hostname, container.Name, out containerPlatform))
                                {
                                    container.Platform = textInfo.ToTitleCase(containerPlatform);
                                }
                                else
                                {
                                    container.Platform = unknownOS;
                                }
                            }
                        }
                        else
                        {
                            foreach (DockerContainerInstance container in containers)
                            {
                                container.Platform = serverOS;
                            }
                        }
                    }
                    else
                    {
                        foreach (DockerContainerInstance container in containers)
                        {
                            container.Platform = unknownOS;
                        }
                    }
                }

                ContainerInstances = new ObservableCollection <IContainerViewModel>(containers.Select(item => new DockerContainerViewModel(item)).ToList());
                OnPropertyChanged(nameof(ContainerInstances));

                if (ContainerInstances.Count() > 0)
                {
                    if (selectedContainer != null)
                    {
                        var found = ContainerInstances.FirstOrDefault(c => selectedContainer.Equals(c));
                        if (found != null)
                        {
                            SelectedContainerInstance = found;
                            return;
                        }
                    }
                    SelectedContainerInstance = ContainerInstances[0];
                }
            }
            catch (Exception ex)
            {
                UpdateStatusMessage(UIResources.ErrorStatusTextFormat.FormatCurrentCultureWithArgs(ex.Message), isError: true);
                return;
            }
            finally
            {
                if (ContainerInstances.Count() > 0)
                {
                    if (ContainerInstances.Count() < totalContainers)
                    {
                        UpdateStatusMessage(UIResources.ContainersNotAllParsedStatusText.FormatCurrentCultureWithArgs(totalContainers - ContainerInstances.Count()), isError: false);
                        ContainersFoundText = UIResources.ContainersNotAllParsedText.FormatCurrentCultureWithArgs(ContainerInstances.Count(), totalContainers);
                    }
                    else
                    {
                        ContainersFoundText = UIResources.ContainersFoundStatusText.FormatCurrentCultureWithArgs(ContainerInstances.Count());
                    }
                }
                else
                {
                    ContainersFoundText = UIResources.NoContainersFound;
                }
                IsRefreshEnabled = true;
            }
        }
Example #6
0
        private List <string> GetPathsToRebuild(
            IEnumerable <PlatformInfo> allPlatforms, PlatformInfo platform, RepoData repoData)
        {
            bool foundImageInfo = false;

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

            void processPlatformWithMissingImageInfo(PlatformInfo platform)
            {
                _loggerService.WriteMessage(
                    $"WARNING: Image info not found for '{platform.DockerfilePath}'. Adding path to build to be queued anyway.");
                IEnumerable <PlatformInfo> dependentPlatforms = platform.GetDependencyGraph(allPlatforms);

                pathsToRebuild.AddRange(dependentPlatforms.Select(p => p.Model.Dockerfile));
            }

            if (repoData == null || repoData.Images == null)
            {
                processPlatformWithMissingImageInfo(platform);
                return(pathsToRebuild);
            }

            foreach (ImageData imageData in repoData.Images)
            {
                PlatformData platformData = imageData.Platforms
                                            .FirstOrDefault(platformData => platformData.PlatformInfo == platform);
                if (platformData != null)
                {
                    foundImageInfo = true;
                    string fromImage = platform.FinalStageFromImage;
                    string currentDigest;

                    currentDigest = LockHelper.DoubleCheckedLockLookup(_imageDigestsLock, _imageDigests, fromImage,
                                                                       () =>
                    {
                        string digest = _manifestToolService.GetManifestDigestSha(ManifestMediaType.Any, fromImage, Options.IsDryRun);
                        return(DockerHelper.GetDigestString(DockerHelper.GetRepo(fromImage), digest));
                    });

                    bool rebuildImage = platformData.BaseImageDigest != currentDigest;

                    _loggerService.WriteMessage(
                        $"Checking base image '{fromImage}' from '{platform.DockerfilePath}'{Environment.NewLine}"
                        + $"\tLast build digest:    {platformData.BaseImageDigest}{Environment.NewLine}"
                        + $"\tCurrent digest:       {currentDigest}{Environment.NewLine}"
                        + $"\tImage is up-to-date:  {!rebuildImage}{Environment.NewLine}");

                    if (rebuildImage)
                    {
                        IEnumerable <PlatformInfo> dependentPlatforms = platform.GetDependencyGraph(allPlatforms);
                        pathsToRebuild.AddRange(dependentPlatforms.Select(p => p.Model.Dockerfile));
                    }

                    break;
                }
            }

            if (!foundImageInfo)
            {
                processPlatformWithMissingImageInfo(platform);
            }

            return(pathsToRebuild);
        }
Example #7
0
 protected void ExecuteWithUser(Action action)
 {
     DockerHelper.ExecuteWithUser(action, Options.Username, Options.Password, Manifest.Registry, Options.IsDryRun);
 }
        internal void RefreshContainersList()
        {
            IsRefreshEnabled = false;

            try
            {
                IContainerViewModel selectedContainer = SelectedContainerInstance;
                SelectedContainerInstance = null;

                ContainersFoundText = UIResources.SearchingStatusText;

                // Clear everything
                ContainerInstances?.Clear();
                UpdateStatusMessage(string.Empty, false);

                IEnumerable <DockerContainerInstance> containers;

                if (SelectedConnection is LocalConnectionViewModel)
                {
                    containers = DockerHelper.GetLocalDockerContainers(Hostname);
                }
                else
                {
                    ContainersFoundText = UIResources.SSHConnectingStatusText;
                    var connection = SelectedConnection.Connection;
                    if (connection == null)
                    {
                        UpdateStatusMessage(UIResources.SSHConnectionFailedStatusText, isError: true);
                        return;
                    }
                    containers = DockerHelper.GetRemoteDockerContainers(connection, Hostname);
                }

                ContainerInstances = new ObservableCollection <IContainerViewModel>(containers.Select(item => new DockerContainerViewModel(item)).ToList());
                OnPropertyChanged(nameof(ContainerInstances));

                if (ContainerInstances.Count() > 0)
                {
                    if (selectedContainer != null)
                    {
                        var found = ContainerInstances.FirstOrDefault(c => selectedContainer.Equals(c));
                        if (found != null)
                        {
                            SelectedContainerInstance = found;
                            return;
                        }
                    }
                    SelectedContainerInstance = ContainerInstances[0];
                }
            }
            catch (Exception ex)
            {
                UpdateStatusMessage(UIResources.ErrorStatusTextFormat.FormatCurrentCultureWithArgs(ex.Message), isError: true);
                return;
            }
            finally
            {
                if (ContainerInstances.Count() > 0)
                {
                    ContainersFoundText = UIResources.ContainersFoundStatusText.FormatCurrentCultureWithArgs(ContainerInstances.Count());
                }
                else
                {
                    ContainersFoundText = UIResources.NoContainersFound;
                }
                IsRefreshEnabled = true;
            }
        }
        private string GenerateManifest(RepoInfo repo, ImageInfo image, IEnumerable <string> tags, Func <string, string> getImageName,
                                        Func <PlatformInfo, TagInfo?> getTagRepresentative)
        {
            string        imageName   = getImageName(tags.First());
            StringBuilder manifestYml = new();

            manifestYml.AppendLine($"image: {imageName}");
            _publishedManifestTags.Add(imageName);

            string repoName = DockerHelper.GetRepo(imageName);

            IEnumerable <string> additionalTags = tags.Skip(1);

            if (additionalTags.Any())
            {
                manifestYml.AppendLine($"tags: [{string.Join(",", additionalTags)}]");
            }

            _publishedManifestTags.AddRange(additionalTags.Select(tag => $"{repoName}:{tag}"));

            manifestYml.AppendLine("manifests:");
            foreach (PlatformInfo platform in image.AllPlatforms)
            {
                TagInfo?imageTag;
                if (platform.Tags.Any())
                {
                    imageTag = getTagRepresentative(platform);
                }
                else
                {
                    (ImageInfo Image, PlatformInfo Platform)matchingImagePlatform = repo.AllImages
                                                                                    .SelectMany(image =>
                                                                                                image.AllPlatforms
                                                                                                .Select(p => (Image: image, Platform: p))
                                                                                                .Where(imagePlatform => platform != imagePlatform.Platform &&
                                                                                                       PlatformInfo.AreMatchingPlatforms(image, platform, imagePlatform.Image, imagePlatform.Platform) &&
                                                                                                       imagePlatform.Platform.Tags.Any()))
                                                                                    .FirstOrDefault();

                    if (matchingImagePlatform.Platform is null)
                    {
                        throw new InvalidOperationException(
                                  $"Could not find a platform with concrete tags for '{platform.DockerfilePathRelativeToManifest}'.");
                    }

                    imageTag = getTagRepresentative(matchingImagePlatform.Platform);
                }

                if (imageTag is not null)
                {
                    manifestYml.AppendLine($"- image: {getImageName(imageTag.Name)}");
                    manifestYml.AppendLine($"  platform:");
                    manifestYml.AppendLine($"    architecture: {platform.Model.Architecture.GetDockerName()}");
                    manifestYml.AppendLine($"    os: {platform.Model.OS.GetDockerName()}");
                    if (platform.Model.Variant != null)
                    {
                        manifestYml.AppendLine($"    variant: {platform.Model.Variant}");
                    }
                }
            }

            return(manifestYml.ToString());
        }
Example #10
0
 public MosquittoVerifier(CLIContext context)
 {
     Docker  = new DockerHelper(context);
     Context = context;
 }
        private string GenerateTagsListing(RepoInfo repo, string tagsMetadata)
        {
            Logger.WriteSubheading("GENERATING TAGS LISTING");

            string tagsDoc;

            string tempDir = $"{Options.GetCommandName()}-{DateTime.Now.ToFileTime()}";

            Directory.CreateDirectory(tempDir);

            try
            {
                string tagsMetadataFileName = Path.GetFileName(repo.Model.McrTagsMetadataTemplate);
                File.WriteAllText(
                    Path.Combine(tempDir, tagsMetadataFileName),
                    tagsMetadata);

                string dockerfilePath = Path.Combine(tempDir, "Dockerfile");
                File.WriteAllText(
                    dockerfilePath,
                    $"FROM {McrTagsRenderingToolTag}{Environment.NewLine}COPY {tagsMetadataFileName} /tableapp/files/ ");

                string renderingToolId = $"renderingtool-{DateTime.Now.ToFileTime()}";
                DockerHelper.PullImage(McrTagsRenderingToolTag, Options.IsDryRun);
                ExecuteHelper.Execute(
                    "docker",
                    $"build -t {renderingToolId} -f {dockerfilePath} {tempDir}",
                    Options.IsDryRun);

                try
                {
                    ExecuteHelper.Execute(
                        "docker",
                        $"run --name {renderingToolId} {renderingToolId} {tagsMetadataFileName}",
                        Options.IsDryRun);

                    try
                    {
                        string outputPath = Path.Combine(tempDir, "output.md");
                        ExecuteHelper.Execute(
                            "docker",
                            $"cp {renderingToolId}:/tableapp/files/{repo.Name.Replace('/', '-')}.md {outputPath}",
                            Options.IsDryRun
                            );

                        tagsDoc = File.ReadAllText(outputPath);
                    }
                    finally
                    {
                        ExecuteHelper.Execute("docker", $"container rm -f {renderingToolId}", Options.IsDryRun);
                    }
                }
                finally
                {
                    ExecuteHelper.Execute("docker", $"image rm -f {renderingToolId}", Options.IsDryRun);
                }
            }
            finally
            {
                Directory.Delete(tempDir, true);
            }

            if (Options.IsVerbose)
            {
                Logger.WriteSubheading($"Tags Documentation:");
                Logger.WriteMessage(tagsDoc);
            }

            return(tagsDoc);
        }
Example #12
0
        public static int Main(string[] args)
        {
            var app = new CommandLineApplication
            {
                Name        = "EOSCPPManager",
                Description = "A EOS Smart Contract helper tool",
            };

            app.ThrowOnUnexpectedArgument = false;
            app.HelpOption(inherited: true);

            app.Command("util", configCmd =>
            {
                configCmd.OnExecute(() =>
                {
                    //Console.WriteLine("Specify a subcommand");
                    configCmd.ShowHelp();
                    return(1);
                });


                configCmd.Command("cleanDocker", setCmd =>
                {
                    setCmd.Description = "Remove unused Docker containers that have been used to compile";

                    setCmd.OnExecute(() =>
                    {
                        logger.Info($"Start cleanup");

                        try
                        {
                            var x = DockerHelper.dockerCleanup().Result;
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex.Message);
                        }
                    });
                });
            });

            app.Command("init", configCmd =>
            {
                configCmd.OnExecute(() =>
                {
                    //Console.WriteLine("Specify a subcommand");
                    configCmd.ShowHelp();
                    return(1);
                });


                configCmd.Command("docker", setCmd =>
                {
                    setCmd.Description = "Check that the required docker images exist on the machine and download any missing";

                    setCmd.OnExecute(() =>
                    {
                        IConfiguration config = new ConfigurationBuilder()
                                                .AddJsonFile("appsettings.json", true, true)
                                                .Build();
                        var eosiocppDockerImage = config["eosiocppDockerImage"];

                        logger.Info("Check connection to local docker instance and confirm that image \"{0}\" exists", eosiocppDockerImage);
                        logger.Info("If this step hange/freezes for an extended period of time please confirm the following:");
                        logger.Info("\t 1. That your docker settings have \"expose daemon\" enabled. On windows this is tcp://localhost:2375 by default.");
                        logger.Info("\t 2. That your Antivirus is not blocking access to tcp://localhost:2375");

                        var exists = DockerHelper.CheckImageExistsAsync(eosiocppDockerImage).Result;
                        if (!exists)
                        {
                            var y = DockerHelper.getImageAsync(eosiocppDockerImage).Result;
                        }
                        else
                        {
                            logger.Info("Connection = good. Image exists. You're good to go.");
                        }
                        //logger.Info(list);
                    });
                });

                configCmd.Command("windows", setCmd =>
                {
                    setCmd.Description = "Initialize windows PATH variable - Must be run as Administartor";

                    setCmd.OnExecute(() =>
                    {
                        logger.Info($"Start Initialize windows env");
                        //if(DirectoryExistsAttribute.e)
                        var lib = new EOSCPPManagerCore();
                        try
                        {
                            lib.initializeWindowEnv();
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex.Message);
                        }
                    });
                });

                configCmd.Command("include", setCmd =>
                {
                    setCmd.Description = "Copy header files and other include files.";

                    setCmd.OnExecute(() =>
                    {
                        logger.Info($"Start Initialize include");
                        //if(DirectoryExistsAttribute.e)
                        var lib = new EOSCPPManagerCore();
                        try
                        {
                            lib.initializeInclude();
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex.Message);
                        }
                    });
                });
            });

            app.Command("template", configCmd =>
            {
                configCmd.OnExecute(() =>
                {
                    //Console.WriteLine("Specify a subcommand");
                    configCmd.ShowHelp();
                    return(1);
                });

                configCmd.Command("new", setCmd =>
                {
                    setCmd.Description  = "Create a new smart contract template";
                    var pathOption      = setCmd.Option("-p|--path <PATH>", "The path to the parent folder, which will contain the new template", CommandOptionType.SingleValue).IsRequired();
                    var nameOption      = setCmd.Option("-n|--name <NAME>", "The path to the parent folder, which will contain the new template", CommandOptionType.SingleValue).IsRequired();
                    var overwriteOption = setCmd.Option("-o|--overwrite", "If a project exists, delete and create new", CommandOptionType.NoValue);

                    setCmd.OnExecute(() =>
                    {
                        String path    = pathOption.Value();
                        String name    = nameOption.Value();
                        bool overwrite = false;
                        if (overwriteOption.Values.Count > 0)
                        {
                            overwrite = true;
                        }

                        //Console.WriteLine($"Create new project in {path}");
                        logger.Info($"Begin create of new smart contract {name} in parent folder {path}");
                        //if(DirectoryExistsAttribute.e)
                        var lib = new EOSCPPManagerCore();
                        try
                        {
                            lib.createNewSmartContract(path, name, overwrite);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex.Message);
                        }
                    });
                });
            });

            app.Command("build", configCmd =>
            {
                var eosiocppDockerImage = config["eosiocppDockerImage"];

                var pathOption        = configCmd.Option("-p|--path <PATH>", "The path to the parent folder, which will contain the new template (*Required)", CommandOptionType.SingleValue).IsRequired();
                var dockerImageOption = configCmd.Option("-d|--dockerImage <ImageName>", string.Format("The name of the docker image to use (Default: {0})", eosiocppDockerImage), CommandOptionType.SingleValue);
                var watchOption       = configCmd.Option("-w|--watch", "Continue watching this folder for changes (*Currently Required)", CommandOptionType.NoValue);


                configCmd.OnExecute(() =>
                {
                    var path = pathOption.Value();
                    //var dockerImage = "binaryfocus/eosio_wasm_1.2.6";
                    var dockerImage = eosiocppDockerImage;
                    var watch       = false;
                    if (dockerImageOption.Values.Count > 0)
                    {
                        dockerImage = dockerImageOption.Value();
                    }
                    if (watchOption.Values.Count > 0)
                    {
                        watch = true;
                    }

                    if (watch)
                    {
                        Console.WriteLine("Begin watching {0}. Build using docker image {1}.", path, dockerImage, watch);
                    }
                    else
                    {
                        Console.WriteLine("Compile {0} using docker image {1}. Continue watching = {2}", path, dockerImage, watch);
                    }


                    //logger.Info("Begin watching '{0}'", parsedWatchArgs.Path);

                    Watcher.start(path, dockerImage);
                    //It doesn't matter what file name we push onto the list, as long as it's a cpp or hpp it'll trigger a build.
                    DockerHelper.init(path, dockerImage, watch);
                    Watcher.addToQueue("test.cpp");


                    if (watch)
                    {
                        while (1 < 2)
                        {
                            Thread.Sleep(500);
                            // Every 500ms we chech the build queue and trigger a build in the Docker container.
                            // The purpose of the queue is to make sure that we don't end up with multiple builds in parallel.
                            Watcher.checkQueue();
                        }
                    }
                    else
                    {
                        //logger.Info("We're still experiencing some problems with the one off build command and docker. Please use the --watch option to watch the folder instead.");
                        Watcher.checkQueue();
                    }

                    //configCmd.ShowHelp();
                    return(1);
                });
            });

            app.OnExecute(() =>
            {
                Console.WriteLine("Specify a subcommand");
                app.ShowHelp();
                return(1);
            });

            int result = -1;

            try
            {
                result = app.Execute(args);
            }
            catch (Exception ex)
            {
                app.ShowHelp();
            }

            return(result);
        }
 protected Task ExecuteWithUserAsync(Func <Task> action)
 {
     Options.CredentialsOptions.Credentials.TryGetValue(Manifest.Registry ?? "", out RegistryCredentials? credentials);
     return(DockerHelper.ExecuteWithUserAsync(action, credentials?.Username, credentials?.Password, Manifest.Registry, Options.IsDryRun));
 }
 protected void ExecuteWithUser(Action action)
 {
     DockerHelper.ExecuteWithUser(action, Options.Username, Options.Password, Options.Server, Options.IsDryRun);
 }