internal override void Execute(SkytapClient client, SkytapConfiguration configuration) { var runstate = client.GetConfigurationRunstate(configuration.Id); if (runstate == "stopped") { this.LogInformation("Environment {0} is already stopped.", configuration.Name); return; } if (runstate == "suspended" && this.Runstate == StopConfigurationMode.Suspend) { this.LogInformation("Environment {0} is already suspended.", configuration.Name); return; } this.LogInformation( "{0} environment...", InedoLib.Util.Switch <StopConfigurationMode, string>(this.Runstate) .Case(StopConfigurationMode.Suspend, "Suspending") .Case(StopConfigurationMode.ShutDown, "Shutting down") .Case(StopConfigurationMode.PowerOff, "Powering off") .End() ); var targetRunstate = InedoLib.Util.Switch <StopConfigurationMode, string>(this.Runstate) .Case(StopConfigurationMode.Suspend, "suspended") .Case(StopConfigurationMode.ShutDown, "stopped") .Case(StopConfigurationMode.PowerOff, "halted") .End(); client.SetConfigurationRunstate(configuration.Id, targetRunstate); if (this.WaitForStop) { this.LogInformation("Stop command issued; waiting for environment to enter {0} state...", this.Runstate == StopConfigurationMode.Suspend ? "suspended" : "stopped"); do { this.Context.CancellationToken.WaitHandle.WaitOne(5000); this.ThrowIfCanceledOrTimeoutExpired(); runstate = client.GetConfigurationRunstate(configuration.Id); }while (runstate == "busy"); if (runstate == "stopped" || runstate == "suspended") { this.LogInformation("Environment is {0}.", runstate); } else { this.LogError("Environment is {0}.", runstate); } } else { this.LogInformation("Stop command issued."); } }
internal sealed override void Execute(SkytapClient client) { if (string.IsNullOrWhiteSpace(this.ConfigurationId) && string.IsNullOrWhiteSpace(this.ConfigurationName)) { this.LogError("Environment ID or environment name must be specified."); return; } this.LogDebug("Using best match for environment Id={0}, environment name={1}", this.ConfigurationId, this.ConfigurationName); var notFoundLogLevel = this.allowConfigNotFound ? MessageLevel.Debug : MessageLevel.Error; this.LogDebug("Looking up environment on Skytap..."); SkytapConfiguration configuration = null; if (!string.IsNullOrWhiteSpace(this.ConfigurationId)) { configuration = client.GetConfiguration(this.ConfigurationId); if (configuration == null) { if (string.IsNullOrWhiteSpace(this.ConfigurationName)) { var message = "Could not find environment with ID=" + this.ConfigurationId; this.Log(notFoundLogLevel, message); if (this.allowConfigNotFound) { this.Execute(client, null); } return; } else { this.LogDebug("Could not find environment with ID=" + this.ConfigurationId + "; looking up environment with name=" + this.ConfigurationName); } } } if (configuration == null && !string.IsNullOrWhiteSpace(this.ConfigurationName)) { configuration = client.GetConfigurationFromName(this.ConfigurationName); if (configuration == null) { var message = "Could not find environment with name=" + this.ConfigurationName; this.Log(notFoundLogLevel, message); if (this.allowConfigNotFound) { this.Execute(client, null); } return; } } this.LogDebug("Found environment ID={0}, name={1}", configuration.Id, configuration.Name); this.Execute(client, configuration); }
internal override void Execute(SkytapClient client, SkytapConfiguration configuration) { if (configuration == null) { this.LogWarning("Environment {0} not found.", this.ConfigurationName); return; } this.LogInformation("Deleting {0} environment...", configuration.Name); try { client.DeleteConfiguration(configuration.Id); this.LogInformation("Environment deleted."); } catch (Exception ex) { this.LogError("The environment could not be deleted: " + ex.Message); } }
internal override void Execute(SkytapClient client, SkytapConfiguration configuration) { if (string.IsNullOrWhiteSpace(this.NewConfigurationName)) { this.LogInformation("Creating environment from {1} environment...", configuration.Name); } else { this.LogInformation("Creating {0} environment from {1} template...", this.NewConfigurationName, configuration.Name); } string configurationId; try { configurationId = client.CopyConfiguration(configuration.Id); } catch (WebException ex) { this.LogError("The environment could not be copied: " + ex.Message); return; } this.LogDebug("Environment copied (ID={0})", configurationId); if (!string.IsNullOrWhiteSpace(this.NewConfigurationName)) { this.LogDebug("Setting environment name to {0}...", this.NewConfigurationName); client.RenameConfiguration(configurationId, this.NewConfigurationName); this.LogDebug("Environment renamed."); } if (this.ExportVariables) { this.SetSkytapVariableValue("EnvironmentId", configurationId); } this.LogInformation("Environment copied."); }
internal override void Execute(SkytapClient client, SkytapConfiguration configuration) { var runstate = client.GetConfigurationRunstate(configuration.Id); if (runstate == "running") { this.LogInformation("Environment {0} is already running.", configuration.Name); return; } this.LogInformation("Starting environment..."); client.SetConfigurationRunstate(configuration.Id, "running"); if (this.WaitForStart) { this.LogInformation("Start command issued; waiting for environment to enter running state..."); do { this.Context.CancellationToken.WaitHandle.WaitOne(5000); this.ThrowIfCanceledOrTimeoutExpired(); runstate = client.GetConfigurationRunstate(configuration.Id); }while (runstate == "busy"); if (runstate == "running") { this.LogInformation("Environment is running."); } else { this.LogError("Environment is {0}.", runstate); } } else { this.LogInformation("Start command issued."); } }
internal override void Execute(SkytapClient client, SkytapConfiguration configuration) { var serverIds = this.CreateServers(configuration); if (serverIds.Count == 0) { this.LogWarning("There were no BuildMaster servers created for this environment."); return; } this.RunUpdater(); this.LogInformation("Waiting for servers to enter ready state..."); do { var statuses = StoredProcs .Environments_GetServers(Domains.YN.No) .Execute() .Where(s => serverIds.Contains(s.Server_Id)); foreach (var server in statuses) { if (server.ServerStatus_Code == Domains.ServerStatus.Ready) { this.LogDebug("Server {0} is ready.", server.Server_Name); serverIds.Remove(server.Server_Id); } } this.Context.CancellationToken.WaitHandle.WaitOne(5000); this.ThrowIfCanceledOrTimeoutExpired(); }while (serverIds.Count > 0); this.LogInformation("Servers are ready."); }
private HashSet <int> CreateServers(SkytapConfiguration configuration) { var buildMasterServers = StoredProcs .Environments_GetServers(Domains.YN.Yes) .Execute() .ToDictionary(s => s.Server_Name, StringComparer.OrdinalIgnoreCase); var serverIds = new HashSet <int>(); foreach (var vm in configuration.VirtualMachines) { var publishedService = vm .NetworkInterfaces .SelectMany(n => n.Services) .Where(s => s.InternalPort == 6468 || s.InternalPort == 6864 || s.InternalPort == 22) .FirstOrDefault(); if (publishedService == null) { this.LogInformation("Virtual machine {0} does not have any published services with known BuildMaster agent ports or SSH ports.", vm.Name); continue; } this.LogDebug("Waiting for {0}:{1} to start accepting connections...", publishedService.ExternalIPAddress, publishedService.ExternalPort); using (var tcpClient = new TcpClient()) { bool connected = false; do { using (var connectTask = Task.Factory.FromAsync(tcpClient.BeginConnect, tcpClient.EndConnect, publishedService.ExternalIPAddress, publishedService.ExternalPort, null)) { while (!connectTask.IsCompleted) { try { connected = connectTask.Wait(100); } catch (AggregateException) { Thread.Sleep(1000); } this.ThrowIfCanceledOrTimeoutExpired(); } } }while (!connected); } var bmServer = buildMasterServers.GetValueOrDefault("Skytap-" + vm.Id); var agent = this.CreateAgent(publishedService, vm.Credentials); if (agent != null) { int serverId; if (bmServer == null) { this.LogInformation("Creating server Skytap-{0} for virtual machine {1}...", vm.Id, vm.Name); serverId = (int)StoredProcs.Environments_CreateOrUpdateServer( Server_Id: null, Server_Name: "Skytap-" + vm.Id, ServerType_Code: Domains.ServerTypeCodes.Server, Agent_Configuration: Util.Persistence.SerializeToPersistedObjectXml(agent), Active_Indicator: Domains.YN.Yes ).Execute(); } else { serverId = bmServer.Server_Id; var agentConfigString = Util.Persistence.SerializeToPersistedObjectXml(agent); if (agentConfigString != bmServer.Agent_Configuration || !(YNIndicator)bmServer.Active_Indicator) { this.LogInformation("Updating server configuration for server Skytap-{0} (virtual machine {1})...", vm.Id, vm.Name); StoredProcs.Environments_CreateOrUpdateServer( Server_Id: bmServer.Server_Id, Server_Name: bmServer.Server_Name, ServerType_Code: bmServer.ServerType_Code, Agent_Configuration: agentConfigString, Active_Indicator: Domains.YN.Yes ).Execute(); } else { this.LogInformation("Server Skytap-{0} already created for virtual machine {1}.", vm.Id, vm.Name); } } serverIds.Add(serverId); this.SetSkytapVariableValue("VM-" + vm.Name, "Skytap-" + vm.Id); } } return(serverIds); }
internal abstract void Execute(SkytapClient client, SkytapConfiguration configuration);
private static void CleanupConnections(Credentials credentials, SkytapConfiguration config) { // FUTURE: may need to account for more than one connection, but that change should be // relatively straightforward. Add an array to the persisted values and simply loop // over all of them to clean-up. if (!string.IsNullOrEmpty(config.IcnrId)) { SkytapApi.DeleteIcnrConnection(credentials, config.IcnrId); } if (!string.IsNullOrEmpty(config.VpnId)) { SkytapApi.DisconnectVpn(credentials, config.ConfigurationUrl, config.ConfigurationNetworkId, config.VpnId); SkytapApi.DetachVpn(credentials, config.ConfigurationUrl, config.ConfigurationNetworkId, config.VpnId); } }
internal override void Execute(SkytapClient client, SkytapConfiguration configuration) { if (string.IsNullOrWhiteSpace(this.DefaultAccess) && (this.VirtualMachines == null || this.VirtualMachines.Length == 0)) { this.LogError("Virtual machine access level is not specified."); return; } this.LogInformation("Getting list of virtual machines for {0} environment...", configuration.Name); var configVms = client.ListVms(configuration.Id).ToList(); this.LogDebug("Received {0} virtual machines.", configVms.Count); var publishedVmRefs = new List <SkytapPublishedVmRef>(); if (this.VirtualMachines != null && this.VirtualMachines.Length > 0) { var vms = this.VirtualMachines .GroupJoin( configVms, p => p.Name, v => v.Name, (p, v) => new { p.Name, p.Access, Matches = v.ToList() }, StringComparer.OrdinalIgnoreCase); bool errors = false; foreach (var vm in vms) { if (vm.Matches.Count == 1) { this.LogDebug("{0} with {1} access", vm.Name, vm.Access); publishedVmRefs.Add(new SkytapPublishedVmRef(vm.Matches[0].Id, vm.Access)); } else if (vm.Matches.Count == 0) { this.LogError("Could not resolve virtual machine named {0} in {1} environment.", vm.Name, configuration.Name); errors = true; } else { this.LogError("Ambiguous virtual machine names ({0}) in {1} environment.", vm.Name, configuration.Name); errors = true; } } if (errors) { return; } } else { foreach (var vm in configVms) { this.LogDebug("{0} with {1} access", vm.Name, this.DefaultAccess); publishedVmRefs.Add(new SkytapPublishedVmRef(vm.Id, this.DefaultAccess)); } } TimeSpan?runtimeLimit = null; if (!string.IsNullOrEmpty(this.RuntimeLimitHours)) { runtimeLimit = TimeSpan.FromHours(double.Parse(this.RuntimeLimitHours)); this.LogDebug("Runtime limit: " + runtimeLimit); } DateTime?expirationDate = null; if (!string.IsNullOrEmpty(this.ExpirationHours)) { var timeUntilExipiration = TimeSpan.FromHours(double.Parse(this.ExpirationHours)); expirationDate = DateTime.UtcNow + timeUntilExipiration; this.LogDebug("Expiration date: {0} (UTC)", expirationDate); } TimeSpan?dailyStart = null; TimeSpan?dailyEnd = null; if (!string.IsNullOrEmpty(this.DailyAccessStart) && !string.IsNullOrEmpty(this.DailyAccessEnd)) { var utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); var start = TimeSpan.Parse(this.DailyAccessStart) - utcOffset; var end = TimeSpan.Parse(this.DailyAccessEnd) - utcOffset; if (start < TimeSpan.Zero) { start += new TimeSpan(24, 0, 0); } else if (start >= new TimeSpan(24, 0, 0)) { start -= new TimeSpan(24, 0, 0); } if (end < TimeSpan.Zero) { end += new TimeSpan(24, 0, 0); } else if (end >= new TimeSpan(24, 0, 0)) { end -= new TimeSpan(24, 0, 0); } dailyStart = start; dailyEnd = end; this.LogDebug("Daily access window: {0} to {1} (UTC)", start, end); } this.LogInformation("Creating publish set..."); var publishedSet = client.CreatePublishSet( configuration.Id, this.PublishedSetName, this.OneUrlPerVm, dailyStart, dailyEnd, this.Password, publishedVmRefs, runtimeLimit, expirationDate ); this.LogInformation("Publish set created."); if (this.ExportVariables) { string desktopsUrl; if (this.OneUrlPerVm && publishedSet.Vms.Count > 1) { desktopsUrl = string.Join( Environment.NewLine, publishedSet.Vms .Join( configVms, p => p.Id, v => v.Id, (p, v) => new { v.Name, p.DesktopUrl }) .Select(v => v.Name + ": " + v.DesktopUrl) ); } else { desktopsUrl = publishedSet.DesktopsUrl; } this.SetSkytapVariableValue("DesktopsUrl", desktopsUrl); } }