Exemplo n.º 1
0
        public async Task WatcherIntegrationTest()
        {
            var kubernetesConfig = KubernetesClientConfiguration.BuildConfigFromConfigFile(kubeconfigPath: @"C:\Users\frede\Source\Repos\cloud\minikube.config");
            var kubernetes       = new Kubernetes(kubernetesConfig);

            var job = await kubernetes.CreateNamespacedJobAsync(
                new V1Job()
            {
                ApiVersion = "batch/v1",
                Kind       = V1Job.KubeKind,
                Metadata   = new V1ObjectMeta()
                {
                    Name = nameof(WatcherIntegrationTest).ToLowerInvariant()
                },
                Spec = new V1JobSpec()
                {
                    Template = new V1PodTemplateSpec()
                    {
                        Spec = new V1PodSpec()
                        {
                            Containers = new List <V1Container>()
                            {
                                new V1Container()
                                {
                                    Image   = "ubuntu/xenial",
                                    Name    = "runner",
                                    Command = new List <string>()
                                    {
                                        "/bin/bash",
                                        "-c",
                                        "--"
                                    },
                                    Args = new List <string>()
                                    {
                                        "trap : TERM INT; sleep infinity & wait"
                                    }
                                }
                            },
                            RestartPolicy = "Never"
                        },
                    }
                }
            },
                "default");

            Collection <Tuple <WatchEventType, V1Job> > events = new Collection <Tuple <WatchEventType, V1Job> >();

            AsyncManualResetEvent started          = new AsyncManualResetEvent();
            AsyncManualResetEvent connectionClosed = new AsyncManualResetEvent();

            var watcher = await kubernetes.WatchNamespacedJobAsync(
                job.Metadata.Name,
                job.Metadata.NamespaceProperty,
                resourceVersion : job.Metadata.ResourceVersion,
                timeoutSeconds : 30,
                onEvent :
                (type, source) =>
            {
                Debug.WriteLine($"Watcher 1: {type}, {source}");
                events.Add(new Tuple <WatchEventType, V1Job>(type, source));
                job = source;
                started.Set();
            },
                onClosed : connectionClosed.Set).ConfigureAwait(false);

            await started.WaitAsync();

            await Task.WhenAny(connectionClosed.WaitAsync(), Task.Delay(TimeSpan.FromMinutes(3)));

            Assert.True(connectionClosed.IsSet);

            await kubernetes.DeleteNamespacedJobAsync(
                job.Metadata.Name,
                job.Metadata.NamespaceProperty,
                new V1DeleteOptions());
        }
Exemplo n.º 2
0
        public async Task <Job> SubmitJob(Job job)
        {
            var resources = new V1ResourceRequirements
            {
                Requests = new Dictionary <string, ResourceQuantity>()
                {
                    { "cpu", new ResourceQuantity("1") },
                    { "memory", new ResourceQuantity($"1Gi") }
                }
            };

            var podSpec = new V1PodSpec
            {
                Containers = new[]
                {
                    new V1Container
                    {
                        Name    = job.Id,
                        Image   = _config["Pi:Docker:Image"],
                        Command = new []
                        {
                            "/app/Pi.Runtime.NetFx",
                            "-dp",
                            job.DecimalPlaces.ToString()
                        },
                        Resources = resources
                    }
                },
                RestartPolicy = "Never"
            };

            //for running in AKS with ACI integration:
            if (_config.GetValue <bool>("Pi:Processors:Kubernetes:UseAci"))
            {
                AddAciConfiguration(podSpec);
            }

            var jobSpec = new V1JobSpec()
            {
                Template = new V1PodTemplateSpec(spec: podSpec)
            };

            var jobMetadata = new V1ObjectMeta(name: job.Id)
            {
                Labels = new Dictionary <string, string>()
                {
                    { "com.pi", "1" }
                }
            };

            var k8sJob = new V1Job(metadata: jobMetadata, spec: jobSpec);

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("*** Generated YAML: ***");
                var yaml = Yaml.SaveToString(k8sJob);
                _logger.LogDebug(yaml);
                _logger.LogDebug("---");
            }

            await _kubernetes.CreateNamespacedJobAsync(k8sJob, _namespace);

            job.ProcessingId = k8sJob.Metadata.Name;
            return(job);
        }
Exemplo n.º 3
0
        async Task StartJobFor(IPerformerLog log, Context context, Read.Configuration.Build build)
        {
            var @namespace = "dolittle";

            var metadata = new V1ObjectMeta
            {
                Name = Guid.NewGuid().ToString() //,
                       //Labels = { { "type", "build" } }
            };

            log.Information($"---");
            log.Information($"Type : {build.Type}");
            log.Information($"BasePath : {build.BasePath}");
            log.Information($"Package : {build.Package}");
            log.Information($"Publish : {build.Publish}");
            log.Information($"Folder with project to publish : {build.FolderWithProjectToPublish}");
            log.Information($"---");

            var job = new V1Job
            {
                Metadata = metadata,
                Spec     = new V1JobSpec
                {
                    Completions = 1,

                    Template = new V1PodTemplateSpec
                    {
                        Metadata = metadata,
                        Spec     = new V1PodSpec
                        {
                            Containers = new [] {
                                new V1Container {
                                    Name            = "build",
                                    Image           = $"dolittlebuild/{build.Type}",
                                    ImagePullPolicy = "Always",
                                    Env             = new [] {
                                        new V1EnvVar("REPOSITORY", context.Project.Repository.ToString()),
                                        new V1EnvVar("COMMIT", context.SourceControl.Commit),
                                        new V1EnvVar("PULL_REQUEST", context.IsPullRequest.ToString()),
                                        new V1EnvVar("VERSION", context.Version),
                                        new V1EnvVar("BASE_PATH", build.BasePath),
                                        new V1EnvVar("PACKAGE", build.Package.ToString()),
                                        new V1EnvVar("PUBLISH", build.Publish.ToString()),
                                        new V1EnvVar("FOLDER_WITH_PROJECT_TO_PUBLISH", build.FolderWithProjectToPublish),
                                        new V1EnvVar("CALLBACK", $"http://continuousimprovement/buildJobDone?jobName={metadata.Name}")
                                    },
                                    VolumeMounts = new[] {
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/repository",
                                            SubPath   = context.Volumes.SourcePath
                                        },
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/packages",
                                            SubPath   = context.Volumes.PackagePath
                                        },
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/output",
                                            SubPath   = context.Volumes.OutputPath
                                        },
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/publish",
                                            SubPath   = context.Volumes.PublishPath
                                        },
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/testresults",
                                            SubPath   = context.Volumes.TestResultsPath
                                        }
                                    }
                                }
                            },
                            Volumes = new[] {
                                new V1Volume {
                                    Name      = "azure",
                                    AzureFile = new V1AzureFileVolumeSource {
                                        SecretName       = "azure-storage-secret",
                                        ShareName        = "continuousimprovement",
                                        ReadOnlyProperty = false
                                    }
                                }
                            },
                            RestartPolicy = "Never",
                        }
                    }
                }
            };

            await _kubernetes.CreateNamespacedJobAsync(job, @namespace);
        }
        private async Task <bool> CreateJobAsync(WebPingerArchive archive)
        {
            // check a pinger exists to archive:
            var services = await _kubernetes.ListNamespacedServiceAsync(
                Program.NamespaceName,
                labelSelector : $"app=web-ping,target={archive.Spec.Target}");

            if (!services.Items.Any())
            {
                Console.WriteLine($"** No WebPinger Service exists for target: {archive.Spec.Target}, in namespace: {Program.NamespaceName}");
                return(false);
            }

            var pingerServiceName = services.Items.First().Metadata.Name;
            var name = $"wpa-{archive.Metadata.Name}-{archive.Metadata.CreationTimestamp:yyMMdd-HHmm}";
            var jobs = await _kubernetes.ListNamespacedJobAsync(
                Program.NamespaceName,
                fieldSelector : $"metadata.name={name}");

            if (!jobs.Items.Any())
            {
                var job = new V1Job
                {
                    Metadata = new V1ObjectMeta
                    {
                        Name   = name,
                        Labels = new Dictionary <string, string>()
                        {
                            { "kiamol", "ch20" },
                        }
                    },
                    Spec = new V1JobSpec
                    {
                        Completions = 1,
                        Template    = new V1PodTemplateSpec
                        {
                            Metadata = new V1ObjectMeta
                            {
                                Labels = new Dictionary <string, string>()
                                {
                                    { "app", "web-ping-archive" },
                                    { "target", archive.Spec.Target }
                                }
                            },
                            Spec = new V1PodSpec
                            {
                                AutomountServiceAccountToken = false,
                                RestartPolicy = "Never",
                                Containers    = new List <V1Container>
                                {
                                    new V1Container
                                    {
                                        Name  = "archiver",
                                        Image = "kiamol/ch20-web-ping-archiver",
                                        Env   = new List <V1EnvVar>
                                        {
                                            new V1EnvVar
                                            {
                                                Name  = "WEB_PING_URL",
                                                Value = $"http://{pingerServiceName}:8080/archive"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                };

                await _kubernetes.CreateNamespacedJobAsync(job, Program.NamespaceName);

                Console.WriteLine($"** Created Job: {name}, in namespace: {Program.NamespaceName}");
                return(true);
            }
            else
            {
                Console.WriteLine($"** Job exists: {name}, in namespace: {Program.NamespaceName}");
                return(false);
            }
        }