in src/ccf/virtual-ccf-provider/docker/DockerRecoveryServiceInstanceProvider.cs [166:276]
private async Task<RecoveryServiceEndpoint> CreateRecoveryServiceContainer(
string instanceName,
string serviceName,
string akvEndpoint,
string maaEndpoint,
NetworkJoinPolicy networkJoinPolicy,
JsonObject? providerConfig,
string skrEndpoint,
CredentialsProxyEndpoint credsProxyEndpoint,
EnvoyEndpoint envoyEndpoint)
{
string containerName = "recovery-service-" + instanceName;
var imageParams = new ImagesCreateParameters
{
FromImage = ImageUtils.CcfRecoveryServiceImage(),
Tag = ImageUtils.CcfRecoveryServiceTag(),
};
await this.client.Images.CreateImageAsync(
imageParams,
authConfig: null,
new Progress<JSONMessage>(m => this.logger.LogInformation(m.ToProgressMessage())));
string hostServiceCertDir = DockerClientEx.GetHostServiceCertDirectory("rs", instanceName);
string hostInsecureVirtualDir =
DockerClientEx.GetHostInsecureVirtualDirectory("rs", instanceName);
string insecureVirtualDir =
DockerClientEx.GetInsecureVirtualDirectory("rs", instanceName);
Directory.CreateDirectory(insecureVirtualDir);
// Copy out the test keys/report into the host directory so that it can be mounted into
// the container.
WorkspaceDirectories.CopyDirectory(
Directory.GetCurrentDirectory() + "/insecure-virtual/recovery-service",
insecureVirtualDir,
recursive: true);
string base64EncodedPolicy =
Convert.ToBase64String(
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(networkJoinPolicy)));
var createParams = new CreateContainerParameters
{
Labels = new Dictionary<string, string>
{
{
DockerConstants.CcfRecoveryServiceNameTag,
serviceName
},
{
DockerConstants.CcfRecoveryServiceTypeTag,
"recovery-service"
},
{
DockerConstants.CcfRecoveryServiceResourceNameTag,
instanceName
}
},
Name = containerName,
Image = $"{imageParams.FromImage}:{imageParams.Tag}",
Env = new List<string>
{
$"ASPNETCORE_URLS=http://+:{Ports.RecoveryServicePort}",
$"IDENTITY_ENDPOINT={credsProxyEndpoint.IdentityEndpoint}",
$"IMDS_ENDPOINT={credsProxyEndpoint.ImdsEndpoint}",
$"AKV_ENDPOINT={akvEndpoint}",
$"MAA_ENDPOINT={maaEndpoint}",
$"SKR_ENDPOINT={skrEndpoint}",
$"CCF_NETWORK_INITIAL_JOIN_POLICY={base64EncodedPolicy}",
$"SERVICE_CERT_LOCATION={DockerConstants.ServiceCertPemFilePath}",
$"INSECURE_VIRTUAL_ENVIRONMENT=true"
},
ExposedPorts = new Dictionary<string, EmptyStruct>
{
{
$"{Ports.RecoveryServicePort}/tcp", new EmptyStruct()
}
},
HostConfig = new HostConfig
{
Binds = new List<string>
{
$"{hostServiceCertDir}:{DockerConstants.ServiceFolderMountPath}:ro",
$"{hostInsecureVirtualDir}:/app/insecure-virtual:ro"
},
NetworkMode = serviceName,
// Although traffic will be routed via envoy exposing the HTTP port for easier
// debugging.
PortBindings = new Dictionary<string, IList<PortBinding>>
{
{
$"{Ports.RecoveryServicePort}/tcp", new List<PortBinding>
{
new()
{
// Dynamic assignment.
HostPort = null
}
}
}
}
}
};
var container = await this.client.CreateOrGetContainer(createParams);
await this.client.Containers.StartContainerAsync(
container.ID,
new ContainerStartParameters());
return this.ToServiceEndpoint(envoyEndpoint);
}