Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lobs communication spike #947

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docker/kubernetes-tentacle/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ ARG TARGETOS
ARG TARGETVARIANT

EXPOSE 10933
EXPOSE 5001
EXPOSE 5002

COPY docker/kubernetes-tentacle/scripts/* /scripts/
COPY --from=bootstrapRunnerBuilder bootstrapRunner/bin/bootstrapRunner /bootstrapRunner
Expand Down
2 changes: 1 addition & 1 deletion installer/Octopus.Tentacle.Installer/Product.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
- Product/Version : Change this every major build
- Product/UpgradeCode : Never change this
-->
<Product Id="*" Name="Octopus Deploy Tentacle" Language="1033" Version="8.1.1518" Manufacturer="Octopus Deploy Pty. Ltd." UpgradeCode="1B32E04F-49C2-4907-8879-A556986F7F16">
<Product Id="*" Name="Octopus Deploy Tentacle" Language="1033" Version="8.1.1693" Manufacturer="Octopus Deploy Pty. Ltd." UpgradeCode="1B32E04F-49C2-4907-8879-A556986F7F16">
<Package InstallerVersion="200" Compressed="yes" Description="Octopus Deploy Tentacle" Platform="$(var.Platform)" InstallScope="perMachine" />
<Media Id="1" Cabinet="Files.cab" EmbedCab="yes" />
<Property Id="MSIFASTINSTALL" Value="3" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
<Resource Include="Resources\Images\warning.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.6.2" />
<PackageReference Include="Autofac" Version="6.2.0" />
<PackageReference Include="FluentValidation" Version="7.2.1" />
<PackageReference Include="MaterialDesignColors" Version="2.1.4" />
<PackageReference Include="MaterialDesignThemes" Version="4.9.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using Autofac;
using NSubstitute;
using NUnit.Framework;
using Octopus.Diagnostics;
Expand Down Expand Up @@ -60,7 +61,8 @@ public override void SetUp()
Substitute.For<IWindowsLocalAdminRightsChecker>(),
new AppVersion(GetType().Assembly),
Substitute.For<ILogFileOnlyLogger>(),
backgroundTasks.Select(bt => new Lazy<IBackgroundTask>(() => bt)).ToList());
backgroundTasks.Select(bt => new Lazy<IBackgroundTask>(() => bt)).ToList(),
new ContainerBuilder().Build());

selector.Current.Returns(new ApplicationInstanceConfiguration("MyTentacle", null, null, null));
}
Expand Down
104 changes: 102 additions & 2 deletions source/Octopus.Tentacle/Commands/RunAgentCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,20 @@
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using Autofac;
using Autofac.Extensions.DependencyInjection;
#if !NETFRAMEWORK
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Octopus.Tentacle.Communications.gRPC;
#endif
using Octopus.Diagnostics;
using Octopus.Tentacle.Background;
using Octopus.Tentacle.Communications;
Expand Down Expand Up @@ -41,6 +54,11 @@ public class RunAgentCommand : AbstractStandardCommand

public override bool CanRunAsService => true;

readonly ILifetimeScope container;

#if !NETFRAMEWORK
private IHost host;
#endif
public RunAgentCommand(
Lazy<IHalibutInitializer> halibut,
Lazy<IWritableTentacleConfiguration> configuration,
Expand All @@ -53,7 +71,7 @@ public RunAgentCommand(
IWindowsLocalAdminRightsChecker windowsLocalAdminRightsChecker,
AppVersion appVersion,
ILogFileOnlyLogger logFileOnlyLogger,
IEnumerable<Lazy<IBackgroundTask>> backgroundTasks) : base(selector, log, logFileOnlyLogger)
IEnumerable<Lazy<IBackgroundTask>> backgroundTasks, ILifetimeScope container) : base(selector, log, logFileOnlyLogger)
{
this.halibut = halibut;
this.configuration = configuration;
Expand All @@ -66,6 +84,11 @@ public RunAgentCommand(
this.windowsLocalAdminRightsChecker = windowsLocalAdminRightsChecker;
this.appVersion = appVersion;
this.backgroundTasks = backgroundTasks;
this.container = container;

#if !NETFRAMEWORK
host = CreateHostBuilder().Build();
#endif

Options.Add("wait=", "Delay (ms) before starting", arg => wait = int.Parse(arg));
Options.Add("console", "Don't attempt to run as a service, even if the user is non-interactive", v =>
Expand All @@ -74,6 +97,74 @@ public RunAgentCommand(
// This option is added to show help
});
}
#if !NETFRAMEWORK
private IHostBuilder CreateHostBuilder() =>
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel(options =>
{
// options.ConfigureHttpsDefaults(httpsOptions =>
// {
// httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
// httpsOptions.ClientCertificateValidation = (certificate, _, __) =>
// {
// using var cert = new X509Certificate2(certificate.Export(X509ContentType.Cert));
// return configuration.Value.TrustedOctopusServers.Any(serverConfiguration => serverConfiguration.Thumbprint == cert.Thumbprint);
// };
// });
options.Limits.MaxRequestBodySize = null;

options.ListenAnyIP(5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1;
// listenOptions.UseHttps(configuration.Value.TentacleCertificate!);
});
options.ListenAnyIP(5002, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
// listenOptions.UseHttps(configuration.Value.TentacleCertificate!);
});
Comment on lines +118 to +127
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

});
webBuilder.UseStartup<Startup>();
}).UseServiceProviderFactory(new AutofacChildLifetimeScopeServiceProviderFactory(container));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to update Autofac so I could easily get the existing container services into the Kestrel's container to allow for DI in the gRPC service


class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpcReflection();
services.AddGrpc(options =>
{
options.MaxReceiveMessageSize = null;
options.MaxSendMessageSize = null;
});
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// if (env.IsDevelopment())
// {
app.UseDeveloperExceptionPage();
// }

app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcReflectionService();
endpoints.MapGrpcService<GreeterService>();
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync(
"Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
});
});
}
}
#endif

protected override void Start()
{
Expand Down Expand Up @@ -128,6 +219,9 @@ protected override void Start()

halibut.Value.Start();
halibutHasStarted = true;
#if !NETFRAMEWORK
host.Start();
#endif

foreach (var backgroundTaskLazy in backgroundTasks)
{
Expand Down Expand Up @@ -156,10 +250,16 @@ protected override void Stop()
halibut.Value.Stop();
}

#if !NETFRAMEWORK
Console.WriteLine("Stopping host");
host.StopAsync().GetAwaiter().GetResult();
host.Dispose();
#endif

foreach (var backgroundTaskLazy in backgroundTasks.Where(bt => bt.IsValueCreated))
{
backgroundTaskLazy.Value.Stop();
}
}
}
}
}
14 changes: 11 additions & 3 deletions source/Octopus.Tentacle/Communications/HalibutInitializer.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Halibut;
using Halibut.Diagnostics;
using NuGet.Packaging;
using Octopus.Client.Model;
using Octopus.Client.Model.Endpoints;
using Octopus.Diagnostics;
Expand All @@ -20,6 +23,7 @@ public class HalibutInitializer : IHalibutInitializer
readonly HalibutRuntime halibut;
readonly IProxyConfigParser proxyConfigParser;
readonly ISystemLog log;
public static readonly IList<ServiceEndPoint> ServiceEndPoints = new List<ServiceEndPoint>();

public HalibutInitializer(IWritableTentacleConfiguration configuration, HalibutRuntime halibut, IProxyConfigParser proxyConfigParser, ISystemLog log)
{
Expand All @@ -35,8 +39,10 @@ public void Start()

TrustOctopusServers();

AddPollingEndpoints();
ServiceEndPoints.AddRange(AddPollingEndpoints());

// KeepPingingServersForNoReason(endpoints);

if (configuration.NoListen)
{
log.Info("Agent will not listen on any TCP ports");
Expand Down Expand Up @@ -85,7 +91,7 @@ void TrustOctopusServers()



void AddPollingEndpoints()
IEnumerable<ServiceEndPoint> AddPollingEndpoints()
{
foreach (var pollingEndPoint in GetOctopusServersToPoll())
{
Expand All @@ -110,6 +116,8 @@ void AddPollingEndpoints()
for (var i = 0; i < connectionCount; i++)
{
halibut.Poll(new Uri(pollingEndPoint.SubscriptionId), serviceEndPoint, CancellationToken.None);
yield return serviceEndPoint;
//yield return new ServiceEndPoint(new Uri(pollingEndPoint.SubscriptionId), pollingEndPoint.Thumbprint, halibutTimeoutsAndLimits);
}
}
}
Expand Down Expand Up @@ -174,4 +182,4 @@ public void Stop()
{
}
}
}
}
20 changes: 20 additions & 0 deletions source/Octopus.Tentacle/Communications/IEchoService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Threading;
using System.Threading.Tasks;

namespace Octopus.Tentacle.Communications
{
public interface IMyEchoService
{
string SayHello(string name);
}

public interface IAsyncClientMyEchoService
{
Task<string> SayHelloAsync(string name);
}

public interface IAsyncMyEchoService
{
Task<string> SayHelloAsync(string name, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protected override void Load(ContainerBuilder builder)
base.Load(builder);

builder.RegisterType<ProxyConfigParser>().As<IProxyConfigParser>();
builder.RegisterType<HalibutInitializer>().As<IHalibutInitializer>();
builder.RegisterType<HalibutInitializer>().As<IHalibutInitializer>().SingleInstance();
builder.RegisterType<AutofacServiceFactory>().AsImplementedInterfaces().SingleInstance();

builder.Register(c =>
Expand Down
37 changes: 37 additions & 0 deletions source/Octopus.Tentacle/Communications/gRPC/GreeterService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#if !NETFRAMEWORK
using System;
using System.Linq;
using System.Threading.Tasks;
using Grpc.Core;
using Halibut;

namespace Octopus.Tentacle.Communications.gRPC
{
public class GreeterService: Greeter.GreeterBase
{
readonly HalibutRuntime halibut;

public GreeterService(HalibutRuntime halibut)
{
this.halibut = halibut;
}


public override Task<HelloReply> SayHello(
HelloRequest request, ServerCallContext context)
{
var client = halibut.CreateAsyncClient<IMyEchoService, IAsyncClientMyEchoService>(HalibutInitializer.ServiceEndPoints.First());

Task.Run(async () =>
{
await client.SayHelloAsync("Hello from: " + request.Name);
});

return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ protected override void Load(ContainerBuilder builder)
.As<IApplicationInstanceManager>()
.SingleInstance();

#pragma warning disable CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint.
builder.Register(c =>
{
var selector = c.Resolve<IApplicationInstanceSelector>();
Expand All @@ -82,6 +83,7 @@ protected override void Load(ContainerBuilder builder)
})
.As<IWritableKeyValueStore>()
.SingleInstance();
#pragma warning restore CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint.

builder.RegisterType<HomeConfiguration>()
.As<IHomeConfiguration>()
Expand Down
20 changes: 19 additions & 1 deletion source/Octopus.Tentacle/Octopus.Tentacle.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,21 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0' Or '$(TargetFramework)' == 'net6.0-windows'">
<PackageReference Include="KubernetesClient" Version="13.0.26" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Google.Protobuf" Version="3.27.0" />
<PackageReference Include="Grpc.AspNetCore" Version="2.62.0"/>
<PackageReference Include="Grpc.AspNetCore.Server.Reflection" Version="2.62.0" />
<PackageReference Include="Grpc.Tools" Version="2.64.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Octopus.Client" Version="14.3.1389" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.6.2" />
<PackageReference Include="Autofac" Version="6.2.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="NuGet.Common" Version="3.6.0-octopus-58692" />
<PackageReference Include="NuGet.Frameworks" Version="3.6.0-octopus-58692" />
<PackageReference Include="NuGet.Packaging" Version="3.6.0-octopus-58692" />
Expand Down Expand Up @@ -127,4 +136,13 @@
<EmbeddedResource Include="Startup\PathsToDeleteOnStartup.netfx.txt" />
<None Remove="Kubernetes\bootstrapRunner.sh" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Extensions.Hosting.Abstractions" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server"/>
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions source/Octopus.Tentacle/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ public override IContainer BuildContainer(StartUpInstanceRequest startUpInstance
builder.RegisterCommand<ListInstancesCommand>("list-instances", "Lists all installed Tentacle instances");
builder.RegisterCommand<VersionCommand>("version", "Show the Tentacle version information");
builder.RegisterCommand<ShowConfigurationCommand>("show-configuration", "Outputs the Tentacle configuration");

builder.RegisterModule(new CommandModule());

return builder.Build();
}
Expand Down
Loading