in src/library/Connect/KubernetesRemoteEnvironmentManager.cs [424:521]
private V1Pod _GetClonedPodSpec(V1Pod pod, string containerName, string agentImage, bool isRoutingSession, ILocalProcessConfig localProcessConfig)
{
var newPodName = isRoutingSession ? $"{RemoteEnvironmentUtilities.SanitizedUserName()}-{pod.Metadata.Name}" : pod.Metadata.Name;
if (newPodName.Length > 253)
{
newPodName = newPodName.Substring(0, 253);
}
// New pod spec
V1Pod podSpec = new V1Pod()
{
ApiVersion = "v1",
Kind = "Pod",
Metadata = new V1ObjectMeta
{
Name = newPodName,
NamespaceProperty = pod.Metadata.NamespaceProperty,
// Copy pod identity label.
// Do not copy auto generated labels like pod-metadata-hash or label selectors that might be used by a service object
Labels = pod.Metadata.Labels?.Where(
label => label.Key.Equals(KubernetesConstants.Labels.AadPodBinding)).ToDictionary(kv => kv.Key, kv => kv.Value)
},
Spec = pod.Spec
};
// Making sure that we don't copy the nodeName field, as scheduling the remote agent on the same node may not be possible if it is low on resources.
podSpec.Spec.NodeName = null;
podSpec.Spec.TerminationGracePeriodSeconds = 0;
podSpec.Spec.ShareProcessNamespace = false;
podSpec.Spec.NodeSelector = new Dictionary<string, string>() { { KubernetesConstants.Labels.OS, KubernetesConstants.Labels.Values.Linux } };
// Add annotation to be used by Routing manager to keep track of the CorrelationIds of the pods currently being routed.
// This is used to track client sessions from the RoutingManagers logs.
if (podSpec.Metadata.Annotations == null)
{
podSpec.Metadata.Annotations = new Dictionary<string, string>();
}
podSpec.Metadata.Annotations[Annotations.CorrelationId] = _operationContext.CorrelationId;
// Replace the container's image with devhostagent image
foreach (var c in podSpec.Spec.Containers)
{
if (StringComparer.OrdinalIgnoreCase.Equals(c.Name, containerName))
{
c.ImagePullPolicy = "IfNotPresent";
c.Image = agentImage;
c.Command = new List<string>();
c.Args = new List<string>();
// When creating new env variables, the previous env variables are not retained to ensure only one is present.
var newEnv = new List<V1EnvVar>();
newEnv.Add(new V1EnvVar(EnvironmentVariables.Names.CollectTelemetry, _environmentVariables.CollectTelemetry.ToString()));
newEnv.Add(new V1EnvVar(EnvironmentVariables.Names.ConsoleVerbosity, LoggingVerbosity.Verbose.ToString()));
newEnv.Add(new V1EnvVar(EnvironmentVariables.Names.CorrelationId, _operationContext.CorrelationId));
c.Env = newEnv;
// If probes option is not enabled or not set, remove any probe in the new pod.
if (localProcessConfig?.IsProbesEnabled != true)
{
c.LivenessProbe = null;
c.ReadinessProbe = null;
c.StartupProbe = null;
}
// If lifecycle hooks option is not enabled or not set, remove any lifecycle hooks in the new pod.
if (localProcessConfig?.IsLifecycleHooksEnabled != true)
{
c.Lifecycle = null;
}
}
else
{
c.LivenessProbe = null;
c.ReadinessProbe = null;
c.StartupProbe = null;
}
}
// Filter out the following that could cause Pod creation to fail.
// - init container: devspaces-proxy-init
// - container devspaces-proxy
// - any volume that references aks-sp and default-token*
if (podSpec.Spec.InitContainers != null && podSpec.Spec.InitContainers.Count > 0)
{
podSpec.Spec.InitContainers = podSpec.Spec.InitContainers.Where(c => c.Name != "devspaces-proxy-init" && !c.Name.Contains("istio")).ToList();
}
if (podSpec.Spec.Containers != null && podSpec.Spec.Containers.Count > 0)
{
podSpec.Spec.Containers = podSpec.Spec.Containers.Where(c => c.Name != "devspaces-proxy" && c.Name != "istio-proxy").ToList();
}
if (podSpec.Spec.Volumes != null && podSpec.Spec.Volumes.Count > 0)
{
podSpec.Spec.Volumes = podSpec.Spec.Volumes.Where(v => !v.Name.Contains("istio")).ToList();
}
return podSpec;
}