private static ulong GetNewContainerInstanceIdAtomic( ContainerDescription containerDesc) { #if DotNetCoreClrLinux // There is a file called containerid in // /log/application/partitionid/servicepackageactivationid/codepackagename/ // This file contains the number corresponding to the latest folder for logs // /mnt/log/application/partitionid/servicepackageactivationid/codepackagename/number/application.log // // For the first instance of thecontainer, create a new file and start at 0, // For every container afterwards, check the file exists, read from the file // and add 1 to the value in the file in order to get the new current instance id // and save the value to the file. var applicationNamePart = containerDesc.ApplicationName; var applicationNameExtraPart = string.Format("{0}/", RootNamingUriString); if (applicationNamePart.StartsWith(applicationNameExtraPart)) { applicationNamePart = applicationNamePart.Substring(applicationNameExtraPart.Length); } applicationNamePart = applicationNamePart.Replace('/', '_'); var digestedApplicationName = applicationNamePart + DigestedApplicationNameDockerSuffix; var logRoots = "/mnt/logs"; var logPath = Path.Combine(logRoots, digestedApplicationName, containerDesc.PartitionId, containerDesc.ServicePackageActivationId, containerDesc.CodePackageName); if (!FabricDirectory.Exists(logPath)) { FabricDirectory.CreateDirectory(logPath); } ulong containerId = 0; var containerInstanceIdFilePath = Path.Combine(logPath, CodePackageInstanceIdFileName); if (!FabricFile.Exists(containerInstanceIdFilePath)) { using (var containerIdFile = FabricFile.Create(containerInstanceIdFilePath)) { containerId = 0; } } else { containerId = ReadContainerIdFromFile(containerInstanceIdFilePath) + 1; } WriteContainerIdToFile(containerInstanceIdFilePath, containerId); return(containerId); #else return(0); #endif }
public static ContainerConfig GetContainerConfig( ProcessDescription processDesc, ContainerDescription containerDesc, string dockerVersion) { var containerConfig = new ContainerConfig { Image = processDesc.ExePath, Hostname = containerDesc.HostName, Labels = new Dictionary <string, string>(), Env = new List <string>(), ExposedPorts = new Dictionary <string, EmptyStruct>(), Tty = containerDesc.RunInteractive, OpenStdin = containerDesc.RunInteractive, HostConfig = new HostConfig() { Binds = new List <string>(), PortBindings = new Dictionary <string, IList <PortBinding> >(), DNSSearch = new List <string>(), SecurityOpt = containerDesc.SecurityOptions, AutoRemove = containerDesc.AutoRemove, LogConfig = new LogConfig() } }; #if !DotNetCoreClrLinux containerConfig.HostConfig.Isolation = containerDesc.IsolationMode.ToString().ToLower(); #endif PopulateLabels(containerConfig, processDesc, containerDesc); PopulateProcessEnvironment(containerConfig, processDesc, containerDesc); if (!containerDesc.RemoveServiceFabricRuntimeAccess) { PopulateFabricRuntimeEnvironment(containerConfig, processDesc, containerDesc); } PopulateVolumes(containerConfig, containerDesc); PopulateDebugParameters(containerConfig, processDesc, containerDesc); PopulateNetworkSettings(containerConfig, containerDesc); PopulateResourceGovernanceSettings(containerConfig, processDesc, dockerVersion); PopulateLogConfig(containerConfig, containerDesc); AddContainerLogMount(containerConfig, containerDesc); return(containerConfig); }
private static void PopulateLogConfig( ContainerConfig containerConfig, ContainerDescription containerDesc) { if (!string.IsNullOrEmpty(containerDesc.LogConfig.Driver)) { containerConfig.HostConfig.LogConfig = new LogConfig { Type = containerDesc.LogConfig.Driver, Config = ParseDriverOptions(containerDesc.LogConfig.DriverOpts) }; } }
// // Fabric Runtime environment is not made visible inside the container if RemoveServiceFabricRuntimeAccess is specified. // private static void PopulateFabricRuntimeEnvironment( ContainerConfig containerConfig, ProcessDescription processDesc, ContainerDescription containerDesc) { var packageFilePath = string.Empty; if (processDesc.EnvVars.ContainsKey(FabricPackageFileNameEnvironment)) { packageFilePath = processDesc.EnvVars[FabricPackageFileNameEnvironment]; } var fabricContainerLogRoot = Path.Combine(Utility.FabricLogRoot, "Containers"); var fabricContainerRoot = Path.Combine(fabricContainerLogRoot, containerDesc.ContainerName); FabricDirectory.CreateDirectory(fabricContainerRoot); var fabricContainerTraceRoot = Path.Combine(fabricContainerRoot, "Traces"); FabricDirectory.CreateDirectory(fabricContainerTraceRoot); var fabricContainerQueryTraceRoot = Path.Combine(fabricContainerRoot, "QueryTraces"); FabricDirectory.CreateDirectory(fabricContainerQueryTraceRoot); var fabricContainerOperationalTraceRoot = Path.Combine(fabricContainerRoot, "OperationalTraces"); FabricDirectory.CreateDirectory(fabricContainerOperationalTraceRoot); // Set path to UT file // TODO: Bug#9728016 - Disable the bind until windows supports mounting file onto container #if DotNetCoreClrLinux PopulateFabricRuntimeEnvironmentForLinux( containerConfig, containerDesc, processDesc, packageFilePath, fabricContainerRoot); #else PopulateFabricRuntimeEnvironmentForWindows( containerConfig, containerDesc, processDesc, packageFilePath, fabricContainerRoot); #endif }
private static void AddContainerLogMount( ContainerConfig containerConfig, ContainerDescription containerDesc) { // Create mounting Path // Pattern is Root/ApplicationName/PartitionId/ServicePackageActivationId/CodePackageName, // we will mount up to Root/ApplicationName/PartitionId/ServicePackageActivationId // ApplicationName might come as fabric:/MyAppName. User really only cares about the MyAppName portion. // The / character in the app name will be converted to _ for the directory // so we can keep only one directory instead of multiple (1 for each / in the name) // If the name is fabric:/MyAppName/AnotherPartOfTheName, we will convert it to MyAppName_AnotherPartOfTheName // On linux the mount root is /mnt/logs/ #if DotNetCoreClrLinux var applicationNamePart = containerDesc.ApplicationName; var applicationNameExtraPart = string.Format("{0}/", RootNamingUriString); if (applicationNamePart.StartsWith(applicationNameExtraPart)) { applicationNamePart = applicationNamePart.Substring(applicationNameExtraPart.Length); } applicationNamePart = applicationNamePart.Replace('/', '_'); containerConfig.Labels.Add(SimpleApplicationNameLabelKeyName, applicationNamePart); var digestedApplicationName = applicationNamePart + DigestedApplicationNameDockerSuffix; containerConfig.Labels.Add(DigestedApplicationNameLabelKeyName, digestedApplicationName); var logRoots = "/mnt/logs"; var logPath = Path.Combine(logRoots, digestedApplicationName, containerDesc.PartitionId, containerDesc.ServicePackageActivationId); if (Path.GetFullPath(logPath).Equals(Path.GetFullPath(logRoots))) { // We do no want to mount the root path to a container return; } // Create path FabricDirectory.CreateDirectory(logPath); // Add to environment label containerConfig.Env.Add(string.Format("{0}={1}", UserLogsDirectoryEnvVarName, logPath)); // Add to mount options containerConfig.HostConfig.Binds.Add(string.Format("{0}:{0}", logPath)); #endif }
private static void PopulateFabricRuntimeEnvironmentForWindows( ContainerConfig containerConfig, ContainerDescription containerDesc, ProcessDescription processDesc, string packageFilePath, string fabricContainerRoot) { containerConfig.Env.Add(string.Format("FabricCodePath={0}", HostingConfig.Config.ContainerFabricBinRootFolder)); containerConfig.Env.Add(string.Format("FabricLogRoot={0}", HostingConfig.Config.ContainerFabricLogRootFolder)); var appDir = Path.Combine(HostingConfig.Config.ContainerAppDeploymentRootFolder, containerDesc.ApplicationId); containerConfig.HostConfig.Binds.Add( string.Format("{0}:{1}", Path.GetFullPath(processDesc.AppDirectory), appDir)); if (!string.IsNullOrWhiteSpace(packageFilePath)) { var configDir = Path.GetDirectoryName(packageFilePath); containerConfig.HostConfig.Binds.Add( string.Format( "{0}:{1}:ro", Path.GetFullPath(configDir), HostingConfig.Config.ContainerPackageRootFolder)); } if (!string.IsNullOrWhiteSpace(Utility.FabricCodePath)) { containerConfig.HostConfig.Binds.Add( string.Format( "{0}:{1}:ro", Path.GetFullPath(Utility.FabricCodePath), HostingConfig.Config.ContainerFabricBinRootFolder)); } if (!string.IsNullOrWhiteSpace(fabricContainerRoot)) { containerConfig.HostConfig.Binds.Add( string.Format( "{0}:{1}", // Log folder should be writable. Path.GetFullPath(fabricContainerRoot), HostingConfig.Config.ContainerFabricLogRootFolder)); } // Mount the UT settings file // TODO: Bug#9728016 - Disable the bind until windows supports mounting file onto container }
private static void PopulateFabricRuntimeEnvironmentForLinux( ContainerConfig containerConfig, ContainerDescription containerDesc, ProcessDescription processDesc, string packageFilePath, string fabricContainerRoot) { containerConfig.Env.Add(string.Format("FabricCodePath={0}", Path.GetFullPath(Utility.FabricCodePath))); containerConfig.Env.Add(string.Format("FabricLogRoot={0}", fabricContainerRoot)); containerConfig.Env.Add(string.Format("FabricDataRoot={0}", Path.GetFullPath(Utility.FabricDataRoot))); containerConfig.HostConfig.Binds.Add( string.Format("{0}:{1}", processDesc.AppDirectory, processDesc.AppDirectory)); if (!string.IsNullOrWhiteSpace(packageFilePath)) { var configDir = Path.GetDirectoryName(packageFilePath); containerConfig.HostConfig.Binds.Add(string.Format("{0}:{1}:ro", configDir, configDir)); } if (!string.IsNullOrWhiteSpace(Utility.FabricCodePath)) { containerConfig.HostConfig.Binds.Add( string.Format( "{0}:{1}:ro", Utility.FabricCodePath, Utility.FabricCodePath)); } if (!string.IsNullOrWhiteSpace(fabricContainerRoot)) { containerConfig.HostConfig.Binds.Add( string.Format("{0}:{1}", fabricContainerRoot, fabricContainerRoot)); } if (processDesc.EnvVars.ContainsKey(RuntimeSslConnectionCertFilePath)) { var certDir = Path.GetDirectoryName(processDesc.EnvVars[RuntimeSslConnectionCertFilePath]); containerConfig.HostConfig.Binds.Add( string.Format("{0}:{1}:ro", certDir, certDir)); } // Mount the UT settings file // TODO: Bug#9728016 - Disable the bind until windows supports mounting file onto container }
private static void PopulateDebugParameters( ContainerConfig containerConfig, ProcessDescription processDesc, ContainerDescription containerDesc) { var debugParams = processDesc.DebugParameters; containerConfig.HostConfig.Binds.AddRange(debugParams.ContainerMountedVolumes); containerConfig.Env.AddRange(debugParams.ContainerEnvironmentBlock); if (debugParams.ContainerEntryPoints != null && debugParams.ContainerEntryPoints.Count > 0) { containerConfig.Entrypoint = debugParams.ContainerEntryPoints; } else if (!string.IsNullOrEmpty(containerDesc.EntryPoint)) { containerConfig.Entrypoint = containerDesc.EntryPoint.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); } }
public static void ReplaceWellKnownParameters(VolumeConfig volumeConfig, ContainerDescription containerDesc) { // Replace the PartitionId token in Docker Volume Driver options List <string> keysforPartition = new List <string>(); foreach (var key in volumeConfig.DriverOpts.Keys) { if (volumeConfig.DriverOpts[key] == PartitionIdToken) { keysforPartition.Add(key); } } foreach (var key in keysforPartition) { volumeConfig.DriverOpts[key] = containerDesc.PartitionId; } // Replace the PartitionId token in Source, if specified. if (volumeConfig.Name.Contains(PartitionIdToken)) { volumeConfig.Name = volumeConfig.Name.Replace(PartitionIdToken, containerDesc.PartitionId); } }
/// <inheritdoc/> public string ToDelimitedString() { CultureInfo culture = CultureInfo.CurrentCulture; return(string.Format( culture, StringHelper.StringFormatSequence(0, 15, Configuration.FieldSeparator), Id, SequenceNumberTestObservationMasterFile.HasValue ? SequenceNumberTestObservationMasterFile.Value.ToString(Consts.NumericFormat, culture) : null, DerivedSpecimen, ContainerDescription?.ToDelimitedString(), ContainerVolume.HasValue ? ContainerVolume.Value.ToString(Consts.NumericFormat, culture) : null, ContainerUnits?.ToDelimitedString(), Specimen?.ToDelimitedString(), Additive?.ToDelimitedString(), Preparation?.ToDelimitedString(), SpecialHandlingRequirements?.ToDelimitedString(), NormalCollectionVolume?.ToDelimitedString(), MinimumCollectionVolume?.ToDelimitedString(), SpecimenRequirements?.ToDelimitedString(), SpecimenPriorities != null ? string.Join(Configuration.FieldRepeatSeparator, SpecimenPriorities) : null, SpecimenRetentionTime?.ToDelimitedString() ).TrimEnd(Configuration.FieldSeparator.ToCharArray())); }
private static void PopulateProcessEnvironment( ContainerConfig containerConfig, ProcessDescription processDesc, ContainerDescription containerDesc) { foreach (var kvPair in processDesc.EnvVars) { var envVarName = kvPair.Key; var envVarValue = kvPair.Value; #if !DotNetCoreClrLinux if (envVarName.Equals(FabricPackageFileNameEnvironment, StringComparison.OrdinalIgnoreCase)) { var packageFilePath = kvPair.Value; var packageFileName = Path.GetFileName(packageFilePath); var containerPackageFilePath = Path.Combine(HostingConfig.Config.ContainerPackageRootFolder, packageFileName); envVarValue = containerPackageFilePath; } #endif containerConfig.Env.Add(string.Format("{0}={1}", envVarName, envVarValue)); } foreach (var setting in processDesc.EncryptedEnvironmentVariables) { var value = setting.Value; string decryptedValue = Utility.GetDecryptedValue(value); containerConfig.Env.Add(string.Format("{0}={1}", setting.Key, decryptedValue)); } containerConfig.Env.Add( string.Format("{0}={1}", ContainerNameEnvironmentVariable, containerDesc.ContainerName)); containerConfig.Cmd = processDesc.Arguments.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); }
private static void PopulateNetworkSettings( ContainerConfig containerConfig, ContainerDescription containerDesc) { var networkType = string.IsNullOrEmpty(containerDesc.AssignedIp) ? "Other" : "Open"; containerConfig.Env.Add(string.Format("{0}={1}", ContainerNetworkingModeEnvironmentVariable, networkType)); containerConfig.HostConfig.NetworkMode = HostingConfig.Config.ContainerDefaultNetwork; #if DotNetCoreClrLinux if (containerDesc.PortBindings.Count != 0) { containerConfig.HostConfig.NetworkMode = HostingConfig.Config.DefaultNatNetwork; } #endif var namespaceId = GetContainerNamespace(containerDesc.GroupContainerName); if (!string.IsNullOrEmpty(namespaceId)) { containerConfig.HostConfig.IpcMode = namespaceId; containerConfig.HostConfig.UsernsMode = namespaceId; containerConfig.HostConfig.PidMode = namespaceId; containerConfig.HostConfig.UTSMode = namespaceId; } bool sharingNetworkNamespace = false; if (!string.IsNullOrEmpty(namespaceId) && !string.IsNullOrEmpty(containerDesc.AssignedIp)) { sharingNetworkNamespace = true; containerConfig.HostConfig.NetworkMode = namespaceId; containerConfig.HostConfig.PublishAllPorts = false; } else if (containerDesc.PortBindings.Count > 0) { foreach (var portBinding in containerDesc.PortBindings) { containerConfig.HostConfig.PortBindings.Add( portBinding.Key, new List <PortBinding> { new PortBinding() { HostPort = portBinding.Value } }); containerConfig.ExposedPorts.Add(portBinding.Key, new EmptyStruct()); } containerConfig.HostConfig.PublishAllPorts = false; } else if (!string.IsNullOrEmpty(containerDesc.AssignedIp)) { var endPointSettings = new EndpointSettings() { IPAMConfig = new EndpointIPAMConfig() { IPv4Address = containerDesc.AssignedIp } }; containerConfig.NetworkingConfig = new NetworkingConfig { EndpointsConfig = new Dictionary <string, EndpointSettings>() { { "servicefabric_network", endPointSettings } } }; containerConfig.HostConfig.NetworkMode = "servicefabric_network"; containerConfig.HostConfig.PublishAllPorts = false; } else { containerConfig.HostConfig.PublishAllPorts = true; } if (sharingNetworkNamespace == false) { containerConfig.HostConfig.DNS = containerDesc.DnsServers; // On Linux, we explicitly pass the ndots value to 1. This is needed to override the default docker behavior. // Docker by default, sets the value to 0 for the cases when custom network is used for the container. // Value 0 means domains listed in the search list won't be tried. // In SF Mesh environment, we rely on DNS suffixes to uniquely identify a service in a given domain. #if DotNetCoreClrLinux containerConfig.HostConfig.DNSOptions = new List <string>(); containerConfig.HostConfig.DNSOptions.Add("ndots:1"); #endif var searchOptions = GetDnsSearchOptions(containerDesc.ApplicationName); if (!string.IsNullOrEmpty(searchOptions)) { containerConfig.HostConfig.DNSSearch.Add(searchOptions); } } }