Skip to content

Commit

Permalink
Updated the agent and updater to use IPC communications rather than T…
Browse files Browse the repository at this point in the history
…CP. Altered the updater update command to make it more resilient and updated the version number for a new build.
  • Loading branch information
chri4799 committed Oct 24, 2013
1 parent 4f42947 commit ef16f88
Show file tree
Hide file tree
Showing 33 changed files with 521 additions and 114 deletions.
2 changes: 1 addition & 1 deletion Properties.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
COMPANY = "Rackspace Cloud"
DESCRIPTION = "C#.NET Agent for Windows Virtual Machines"
CLR_VERSION = 'v3.5'
RELEASE_BUILD_NUMBER = "1.2.5.0"
RELEASE_BUILD_NUMBER = "1.2.6.0"

#Paths
SLN_FILE = File.join(ABSOLUTE_PATH,'src','WindowsConfigurationAgent.sln')
Expand Down
4 changes: 3 additions & 1 deletion README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ C#.NET Agent for Windows Virtual Machines
Gems needed to run rake:

rake (version 0.8.6+)
albacore (version 0.2.2)
albacore (version 0.2.2)
fileutils
rubyzip (version 0.9.8)
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
[assembly: AssemblyCompany("Rackspace Cloud")]
[assembly: AssemblyProduct("Rackspace Cloud Server Agent")]
[assembly: AssemblyCopyright("Copyright (c) 2009 2010 2011, Rackspace Cloud. All Rights Reserved")]
[assembly: AssemblyVersion("1.2.5.0")]
[assembly: AssemblyVersion("1.2.6.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
[assembly: AssemblyCompany("Rackspace Cloud")]
[assembly: AssemblyProduct("Rackspace Cloud Server Agent")]
[assembly: AssemblyCopyright("Copyright (c) 2009 2010 2011, Rackspace Cloud. All Rights Reserved")]
[assembly: AssemblyVersion("1.2.5.0")]
[assembly: AssemblyVersion("1.2.6.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
Expand All @@ -52,6 +53,7 @@
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="StructureMap, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
Expand Down
42 changes: 37 additions & 5 deletions src/Rackspace.Cloud.Server.Agent.Service/ServerClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
// under the License.

using System;
using System.Reflection;
using System.Timers;
using System.Reflection;
using System.Text;
using System.Timers;
using Rackspace.Cloud.Server.Agent.Commands;
using Rackspace.Cloud.Server.Agent.Interfaces;
using Rackspace.Cloud.Server.Common.Logging;
using StructureMap;
Expand All @@ -38,11 +40,15 @@ public class ServerClass {

_timer = new ProdTimer { Interval = TIMER_INTERVAL_IS_SIX_SECONDS };
_timer.Elapsed(TimerElapsed);
_timer.Enabled = true;


StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;
StructureMapConfiguration.BuildInstancesOf<ITimer>().TheDefaultIs(Registry.Object(_timer));
IoC.Register();
IoC.Register();

CheckAgentUpdater();

_timer.Enabled = true;
}

public void Onstop() {
Expand All @@ -57,6 +63,32 @@ public class ServerClass {
} catch (Exception ex) {
_logger.Log("Exception was : " + ex.Message + "\nStackTrace Was: " + ex.StackTrace);
}
}
}

private void CheckAgentUpdater()
{
try
{
var minAgentUpdater = new CommandFactory().CreateCommand(Utilities.Commands.ensureminagentupdater.ToString());
var result = minAgentUpdater.Execute(string.Empty);
if (result.ExitCode == "1")
{
var sb = new StringBuilder();
if (result.Error != null)
{
foreach (var error in result.Error)
{
sb.AppendLine(error);
}
}

throw new Exception(sb.ToString());
}
}
catch (Exception ex)
{
_logger.Log(string.Format("Error checking the min version of the updater and updating: {0}", ex));
}
}
}
}
2 changes: 2 additions & 0 deletions src/Rackspace.Cloud.Server.Agent.Service/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
<add key="RemotingUri" value="AgentUpdater"/>
<add key="RemotingPort" value="1984"/>
<add key="AgentVersionUpdatesPath" value="C:\Program Files\Rackspace\Cloud Servers\Updates\"/>
<add key="IpcUriHost" value="RackspaceAgentUpdaterService"/>
<add key="IpcUriName" value="RackspaceAgentUpdater"/>
<!-- | separated values -->
<add key="FirewallRoleNames" value="rax_managed|rack_connect"/>
</appSettings>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
[assembly: AssemblyCompany("Rackspace Cloud")]
[assembly: AssemblyProduct("Rackspace Cloud Server Agent")]
[assembly: AssemblyCopyright("Copyright (c) 2009 2010 2011, Rackspace Cloud. All Rights Reserved")]
[assembly: AssemblyVersion("1.2.5.0")]
[assembly: AssemblyVersion("1.2.6.0")]
39 changes: 28 additions & 11 deletions src/Rackspace.Cloud.Server.Agent.Specs/UpdaterUpdateSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Rackspace.Cloud.Server.Agent.Actions;
using Rackspace.Cloud.Server.Agent.Commands;
using Rackspace.Cloud.Server.Agent.Configuration;
using Rackspace.Cloud.Server.Common.Configuration;
using Rackspace.Cloud.Server.Common.Logging;
using Rhino.Mocks;

Expand All @@ -25,6 +26,7 @@ public class UpdaterUpdateSpec
private IServiceStopper _serviceStopper;
private IServiceStarter _serviceStarter;
private ILogger _logger;
private IBackupUpdater _backupUpdater;

[SetUp]
public void Setup()
Expand All @@ -41,11 +43,12 @@ public void Setup()
_logger = MockRepository.GenerateMock<ILogger>();
_serviceStopper = MockRepository.GenerateMock<IServiceStopper>();
_serviceStarter = MockRepository.GenerateMock<IServiceStarter>();
_backupUpdater = MockRepository.GenerateMock<IBackupUpdater>();
_agentUpdateMessageHandler = new AgentUpdateMessageHandler();

_logger.Stub(x => x.Log(Arg<string>.Is.Anything));

_updaterUpdate = new UpdaterUpdate(_sleeper, _downloader, _checksumValidator, _unzipper, _fileCopier, _finalizer, _serviceStopper, _serviceStarter, _connectionChecker, _agentUpdateMessageHandler, _logger);
_updaterUpdate = new UpdaterUpdate(_sleeper, _downloader, _checksumValidator, _unzipper, _fileCopier, _finalizer, _serviceStopper, _serviceStarter, _connectionChecker, _agentUpdateMessageHandler, _logger, _backupUpdater);

}

Expand All @@ -70,15 +73,29 @@ public void should_update_xentools()
_updaterUpdate.Execute(_agentUpdateInfo);
}

[Test]
public void should_throw_UnsuccessfulCommandExecutionException_if_connection_to_updater_service_fails()
{
_sleeper.Expect(x => x.Sleep(Arg<int>.Is.Anything));
_connectionChecker.Stub(x => x.Check())
.Throw(new UnsuccessfulCommandExecutionException("error message", new ExecutableResult { ExitCode = "1" }));
var result = _updaterUpdate.Execute(_agentUpdateInfo);
Assert.That(result.ExitCode, Is.EqualTo("1"));
Assert.That(result.Error[0], Is.EqualTo("Update failed"));
}
//[Test]
//public void should_throw_UnsuccessfulCommandExecutionException_if_connection_to_updater_service_fails()
//{
// _sleeper.Expect(x => x.Sleep(Arg<int>.Is.Anything));
// _connectionChecker.Stub(x => x.Check())
// .Throw(new UnsuccessfulCommandExecutionException("error message", new ExecutableResult { ExitCode = "1" }));
// var result = _updaterUpdate.Execute(_agentUpdateInfo);
// Assert.That(result.ExitCode, Is.EqualTo("1"));
// Assert.That(result.Error[0], Is.EqualTo("Update failed"));
//}

//[Test]
//public void GetChecksum()
//{
// ChecksumValidator val = new ChecksumValidator(_logger);
// val.Validate("", @"C:\Agent Services\Single Deploy 1.2.6.0\AgentService.zip");
//}

//[Test]
//public void ExtractFile()
//{
// new ExtractEmbededResource().Extract(@"C:\Agent Services\Testing\", Constants.UpdaterEmbeddedReleasePackagePath, Constants.UpdaterReleasePackageName);
// new Unzipper(_logger).Unzip( @"C:\Agent Services\Testing\" + Constants.UpdaterReleasePackageName, @"C:\Agent Services\Testing\updater", "");
//}
}
}
20 changes: 10 additions & 10 deletions src/Rackspace.Cloud.Server.Agent.Specs/XentoolsUpdateSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ public void should_not_restart_vss_provider_if_service_does_not_exist()
_mockRepo.VerifyAll();
}

[Test]
public void should_throw_UnsuccessfulCommandExecutionException_if_connection_to_updater_service_fails()
{
_sleeper.Expect(x => x.Sleep(Arg<int>.Is.Anything));
_connectionChecker.Stub(x => x.Check())
.Throw(new UnsuccessfulCommandExecutionException("error message", new ExecutableResult { ExitCode = "1" }));
var result = _xentoolsUpdate.Execute(_agentUpdateInfo);
Assert.That(result.ExitCode, Is.EqualTo("1"));
Assert.That(result.Error[0], Is.EqualTo("Update failed"));
}
//[Test]
//public void should_throw_UnsuccessfulCommandExecutionException_if_connection_to_updater_service_fails()
//{
// _sleeper.Expect(x => x.Sleep(Arg<int>.Is.Anything));
// _connectionChecker.Stub(x => x.Check())
// .Throw(new UnsuccessfulCommandExecutionException("error message", new ExecutableResult { ExitCode = "1" }));
// var result = _xentoolsUpdate.Execute(_agentUpdateInfo);
// Assert.That(result.ExitCode, Is.EqualTo("1"));
// Assert.That(result.Error[0], Is.EqualTo("Update failed"));
//}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class AgentUpdater : MarshalByRefObject, IAgentUpdater {
_agentUpdateInfo = agentUpdateInfo;
_logger.Log(String.Format("Received from Agent the following data:\r\nURL:{0}\r\nCHECKSUM:{1}, will resume in a minute", _agentUpdateInfo.url, _agentUpdateInfo.signature));

new Timer(TimerElapsed,null,60000,0);
new Timer(TimerElapsed,null,10000,0);
}

private void TimerElapsed(object sender) {
Expand Down
2 changes: 2 additions & 0 deletions src/Rackspace.Cloud.Server.Agent.UpdaterService/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<add key="AgentVersionUpdatesPath" value="C:\Program Files\Rackspace\Cloud Servers\Updates\"/>
<add key="RemotingPort" value="1984"/>
<add key="RemotingUri" value="AgentUpdater"/>
<add key="IpcUriHost" value="RackspaceAgentUpdaterService"/>
<add key="IpcUriName" value="RackspaceAgentUpdater"/>
</appSettings>
<log4net>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
Expand Down
28 changes: 22 additions & 6 deletions src/Rackspace.Cloud.Server.Agent.UpdaterService/HostUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
// License for the specific language governing permissions and limitations
// under the License.

using System.Collections;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Runtime.Remoting.Channels.Tcp;
using System.Security.Principal;
using Rackspace.Cloud.Server.Common.Configuration;
using Rackspace.Cloud.Server.Common.Logging;
using StructureMap;
Expand All @@ -40,17 +43,30 @@ public class HostUpdater {
}

private void ConfigureRemotingHost() {
SetTcpChannel();
SetIpcChannel();
SetRemotingType();
}

private void SetTcpChannel() {
ChannelServices.RegisterChannel(new TcpChannel(SvcConfiguration.RemotingPort), false);
private void SetIpcChannel() {
// Get SID code for the Built in Administrators group
SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
// Get the NT account related to the SID
NTAccount account = sid.Translate(typeof(NTAccount)) as NTAccount;

IDictionary sProperties = new Hashtable();
sProperties["portName"] = SvcConfiguration.IpcUriHost;
sProperties["authorizedGroup"] = account.Value;

BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();

IpcServerChannel channel = new IpcServerChannel(sProperties, serverProvider);
ChannelServices.RegisterChannel(channel, true);

}

private void SetRemotingType() {
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(AgentUpdater), SvcConfiguration.RemotingUri, WellKnownObjectMode.SingleCall);
typeof(AgentUpdater), SvcConfiguration.IpcUriName, WellKnownObjectMode.SingleCall);
}

public void OnStop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
[assembly: AssemblyCompany("Rackspace Cloud")]
[assembly: AssemblyProduct("Rackspace Cloud Server Agent")]
[assembly: AssemblyCopyright("Copyright (c) 2009 2010 2011, Rackspace Cloud. All Rights Reserved")]
[assembly: AssemblyVersion("1.2.5.0")]
[assembly: AssemblyVersion("1.2.6.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
Expand All @@ -52,6 +53,7 @@
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.85.5.452, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
Expand Down
60 changes: 60 additions & 0 deletions src/Rackspace.Cloud.Server.Agent/Actions/BackupUpdater.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2011 OpenStack LLC.
// All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Rackspace.Cloud.Server.Common.AgentUpdate;
using Rackspace.Cloud.Server.Common.Configuration;
using Rackspace.Cloud.Server.Common.Logging;

namespace Rackspace.Cloud.Server.Agent.Actions
{
public interface IBackupUpdater
{
void Backup(string sourcePath, string backupPath);
void Restore(string targetPath, string backupPath);
}

public class BackupUpdater : IBackupUpdater
{
private readonly ILogger _logger;
private readonly IFileCopier _fileCopier;

public BackupUpdater(ILogger logger, IFileCopier fileCopier)
{
_logger = logger;
_fileCopier = fileCopier;
}

public void Backup(string sourcePath, string backupPath)
{
if (Directory.Exists(backupPath))
{
Directory.Delete(backupPath, true);
}
Directory.CreateDirectory(backupPath);

_fileCopier.CopyFiles(sourcePath, backupPath, _logger);
}

public void Restore(string targetPath, string backupPath)
{
_fileCopier.CopyFiles(backupPath, targetPath, _logger);
}
}
}
Loading

0 comments on commit ef16f88

Please sign in to comment.