aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Application/OpenSim.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs81
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs91
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs25
5 files changed, 167 insertions, 47 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 39004d4..8add2af 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -267,12 +267,13 @@ namespace OpenSim
267 267
268 m_console.Commands.AddCommand("region", false, "save oar", 268 m_console.Commands.AddCommand("region", false, "save oar",
269 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", 269 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
270 "save oar [-p|--profile=<url>] [<OAR path>]", 270 "save oar [-p|--profile=<url>] [--noassets] [<OAR path>]",
271 "Save a region's data to an OAR archive.", 271 "Save a region's data to an OAR archive.",
272// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine 272// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
273 "-p|--profile=<url> adds the url of the profile service to the saved user information" + Environment.NewLine 273 "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
274 + "The OAR path must be a filesystem path." 274 + " The OAR path must be a filesystem path."
275 + " If this is not given then the oar is saved to region.oar in the current directory.", 275 + " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine
276 + "--noassets stops assets being saved to the OAR.",
276 SaveOar); 277 SaveOar);
277 278
278 m_console.Commands.AddCommand("region", false, "edit scale", 279 m_console.Commands.AddCommand("region", false, "edit scale",
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index 597b780..6a86dfe 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -58,7 +58,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
58 /// <summary> 58 /// <summary>
59 /// The maximum major version of OAR that we can write. 59 /// The maximum major version of OAR that we can write.
60 /// </summary> 60 /// </summary>
61 public static int MAX_MAJOR_VERSION = 0; 61 public static int MAX_MAJOR_VERSION = 0;
62
63 /// <summary>
64 /// Determine whether this oar will save assets. Default is true.
65 /// </summary>
66 public bool SaveAssets { get; set; }
62 67
63 protected Scene m_scene; 68 protected Scene m_scene;
64 protected Stream m_saveStream; 69 protected Stream m_saveStream;
@@ -73,10 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
73 /// <exception cref="System.IO.IOException"> 78 /// <exception cref="System.IO.IOException">
74 /// If there was a problem opening a stream for the file specified by the savePath 79 /// If there was a problem opening a stream for the file specified by the savePath
75 /// </exception> 80 /// </exception>
76 public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) 81 public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId)
77 { 82 {
78 m_scene = scene;
79
80 try 83 try
81 { 84 {
82 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress); 85 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress);
@@ -86,10 +89,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
86 m_log.ErrorFormat( 89 m_log.ErrorFormat(
87 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream." 90 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
88 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?"); 91 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
89 m_log.Error(e); 92 m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
90 } 93 }
91
92 m_requestId = requestId;
93 } 94 }
94 95
95 /// <summary> 96 /// <summary>
@@ -98,11 +99,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
98 /// <param name="scene"></param> 99 /// <param name="scene"></param>
99 /// <param name="saveStream">The stream to which to save data.</param> 100 /// <param name="saveStream">The stream to which to save data.</param>
100 /// <param name="requestId">The id associated with this request</param> 101 /// <param name="requestId">The id associated with this request</param>
101 public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) 102 public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId)
102 { 103 {
103 m_scene = scene;
104 m_saveStream = saveStream; 104 m_saveStream = saveStream;
105 }
106
107 protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId)
108 {
109 m_scene = scene;
105 m_requestId = requestId; 110 m_requestId = requestId;
111
112 SaveAssets = true;
106 } 113 }
107 114
108 /// <summary> 115 /// <summary>
@@ -111,22 +118,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
111 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> 118 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
112 public void ArchiveRegion(Dictionary<string, object> options) 119 public void ArchiveRegion(Dictionary<string, object> options)
113 { 120 {
121 if (options.ContainsKey("noassets") && (bool)options["noassets"])
122 SaveAssets = false;
123
114 try 124 try
115 { 125 {
116 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); 126 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
117 127
118 EntityBase[] entities = m_scene.GetEntities(); 128 EntityBase[] entities = m_scene.GetEntities();
119 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 129 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
120
121 /*
122 foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
123 {
124 if (name == lo.LandData.Name)
125 {
126 // This is the parcel we want
127 }
128 }
129 */
130 130
131 // Filter entities so that we only have scene objects. 131 // Filter entities so that we only have scene objects.
132 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods 132 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
@@ -141,17 +141,24 @@ namespace OpenSim.Region.CoreModules.World.Archiver
141 sceneObjects.Add((SceneObjectGroup)entity); 141 sceneObjects.Add((SceneObjectGroup)entity);
142 } 142 }
143 } 143 }
144 144
145 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); 145 if (SaveAssets)
146
147 foreach (SceneObjectGroup sceneObject in sceneObjects)
148 { 146 {
149 assetGatherer.GatherAssetUuids(sceneObject, assetUuids); 147 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
148
149 foreach (SceneObjectGroup sceneObject in sceneObjects)
150 {
151 assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
152 }
153
154 m_log.DebugFormat(
155 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
156 sceneObjects.Count, assetUuids.Count);
157 }
158 else
159 {
160 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
150 } 161 }
151
152 m_log.DebugFormat(
153 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
154 sceneObjects.Count, assetUuids.Count);
155 162
156 // Make sure that we also request terrain texture assets 163 // Make sure that we also request terrain texture assets
157 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; 164 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
@@ -187,11 +194,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
187 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this 194 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
188 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); 195 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
189 m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); 196 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
190 197
191 new AssetsRequest( 198 if (SaveAssets)
192 new AssetsArchiver(archiveWriter), assetUuids, 199 new AssetsRequest(
193 m_scene.AssetService, m_scene.UserAccountService, 200 new AssetsArchiver(archiveWriter), assetUuids,
194 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute(); 201 m_scene.AssetService, m_scene.UserAccountService,
202 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
203 else
204 awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
195 } 205 }
196 catch (Exception) 206 catch (Exception)
197 { 207 {
@@ -204,7 +214,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
204 /// Create the control file for the most up to date archive 214 /// Create the control file for the most up to date archive
205 /// </summary> 215 /// </summary>
206 /// <returns></returns> 216 /// <returns></returns>
207 public static string CreateControlFile(Dictionary<string, object> options) 217 public string CreateControlFile(Dictionary<string, object> options)
208 { 218 {
209 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 6; 219 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 6;
210// 220//
@@ -258,6 +268,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
258 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); 268 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
259 xtw.WriteElementString("id", UUID.Random().ToString()); 269 xtw.WriteElementString("id", UUID.Random().ToString());
260 xtw.WriteEndElement(); 270 xtw.WriteEndElement();
271
272 xtw.WriteElementString("assets_included", SaveAssets.ToString());
273
261 xtw.WriteEndElement(); 274 xtw.WriteEndElement();
262 275
263 xtw.Flush(); 276 xtw.Flush();
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index 9277c59..08eb80c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -127,6 +127,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
127 OptionSet ops = new OptionSet(); 127 OptionSet ops = new OptionSet();
128// ops.Add("v|version=", delegate(string v) { options["version"] = v; }); 128// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
129 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); 129 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
130 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
130 131
131 List<string> mainParams = ops.Parse(cmdparams); 132 List<string> mainParams = ops.Parse(cmdparams);
132 133
@@ -160,7 +161,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
160 161
161 public void ArchiveRegion(Stream saveStream, Guid requestId) 162 public void ArchiveRegion(Stream saveStream, Guid requestId)
162 { 163 {
163 new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(new Dictionary<string, object>()); 164 ArchiveRegion(saveStream, requestId, new Dictionary<string, object>());
165 }
166
167 public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options)
168 {
169 new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options);
164 } 170 }
165 171
166 public void DearchiveRegion(string loadPath) 172 public void DearchiveRegion(string loadPath)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 2eb2861..34e2e23 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -212,6 +212,89 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
212 } 212 }
213 213
214 /// <summary> 214 /// <summary>
215 /// Test saving an OpenSim Region Archive with the no assets option
216 /// </summary>
217 [Test]
218 public void TestSaveOarNoAssets()
219 {
220 TestHelper.InMethod();
221// log4net.Config.XmlConfigurator.Configure();
222
223 SceneObjectPart part1 = CreateSceneObjectPart1();
224 SceneObjectGroup sog1 = new SceneObjectGroup(part1);
225 m_scene.AddNewSceneObject(sog1, false);
226
227 SceneObjectPart part2 = CreateSceneObjectPart2();
228
229 AssetNotecard nc = new AssetNotecard();
230 nc.BodyText = "Hello World!";
231 nc.Encode();
232 UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
233 UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
234 AssetBase ncAsset
235 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
236 m_scene.AssetService.Store(ncAsset);
237 SceneObjectGroup sog2 = new SceneObjectGroup(part2);
238 TaskInventoryItem ncItem
239 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
240 part2.Inventory.AddInventoryItem(ncItem, true);
241
242 m_scene.AddNewSceneObject(sog2, false);
243
244 MemoryStream archiveWriteStream = new MemoryStream();
245
246 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
247
248 Dictionary<string, Object> options = new Dictionary<string, Object>();
249 options.Add("noassets", true);
250 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
251 //AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
252 //while (assetServer.HasWaitingRequests())
253 // assetServer.ProcessNextRequest();
254
255 // Don't wait for completion - with --noassets save oar happens synchronously
256// Monitor.Wait(this, 60000);
257
258 Assert.That(m_lastRequestId, Is.EqualTo(requestId));
259
260 byte[] archive = archiveWriteStream.ToArray();
261 MemoryStream archiveReadStream = new MemoryStream(archive);
262 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
263
264 List<string> foundPaths = new List<string>();
265 List<string> expectedPaths = new List<string>();
266 expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog1));
267 expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2));
268
269 string filePath;
270 TarArchiveReader.TarEntryType tarEntryType;
271
272 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
273 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
274
275 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
276 arr.LoadControlFile(filePath, data);
277
278 Assert.That(arr.ControlFileLoaded, Is.True);
279
280 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
281 {
282 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
283 {
284 Assert.Fail("Asset was found in saved oar of TestSaveOarNoAssets()");
285 }
286 else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
287 {
288 foundPaths.Add(filePath);
289 }
290 }
291
292 Assert.That(foundPaths, Is.EquivalentTo(expectedPaths));
293
294 // TODO: Test presence of more files and contents of files.
295 }
296
297 /// <summary>
215 /// Test loading an OpenSim Region Archive. 298 /// Test loading an OpenSim Region Archive.
216 /// </summary> 299 /// </summary>
217 [Test] 300 [Test]
@@ -230,7 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
230 // upset load 313 // upset load
231 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 314 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
232 315
233 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>())); 316 tar.WriteFile(
317 ArchiveConstants.CONTROL_FILE_PATH,
318 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
234 319
235 SceneObjectPart part1 = CreateSceneObjectPart1(); 320 SceneObjectPart part1 = CreateSceneObjectPart1();
236 SceneObjectGroup object1 = new SceneObjectGroup(part1); 321 SceneObjectGroup object1 = new SceneObjectGroup(part1);
@@ -331,7 +416,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
331 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); 416 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
332 417
333 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 418 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
334 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>())); 419 tar.WriteFile(
420 ArchiveConstants.CONTROL_FILE_PATH,
421 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
335 422
336 RegionSettings rs = new RegionSettings(); 423 RegionSettings rs = new RegionSettings();
337 rs.AgentLimit = 17; 424 rs.AgentLimit = 17;
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
index d8229de..3fafc47 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
@@ -52,31 +52,44 @@ namespace OpenSim.Region.Framework.Interfaces
52 /// <summary> 52 /// <summary>
53 /// Archive the region to the given path 53 /// Archive the region to the given path
54 /// </summary> 54 /// </summary>
55 /// 55 /// <remarks>
56 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to 56 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
57 /// the EventManager.OnOarFileSaved event. 57 /// the EventManager.OnOarFileSaved event.
58 /// 58 /// </remarks>
59 /// <param name="savePath"></param> 59 /// <param name="savePath"></param>
60 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param> 60 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
61 /// <param name="options">Options for the save</param>
61 void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options); 62 void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options);
62 63
63 /// <summary> 64 /// <summary>
64 /// Archive the region to a stream. 65 /// Archive the region to a stream.
65 /// </summary> 66 /// </summary>
66 /// 67 /// <remarks>
67 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to 68 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
68 /// the EventManager.OnOarFileSaved event. 69 /// the EventManager.OnOarFileSaved event.
69 /// 70 /// </remarks>
70 /// <param name="saveStream"></param> 71 /// <param name="saveStream"></param>
71 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param> 72 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
72 void ArchiveRegion(Stream saveStream, Guid requestId); 73 void ArchiveRegion(Stream saveStream, Guid requestId);
73 74
74 /// <summary> 75 /// <summary>
76 /// Archive the region to a stream.
77 /// </summary>
78 /// <remarks>
79 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
80 /// the EventManager.OnOarFileSaved event.
81 /// </remarks>
82 /// <param name="saveStream"></param>
83 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
84 /// <param name="options">Options for the save</param>
85 void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options);
86
87 /// <summary>
75 /// Dearchive the given region archive. This replaces the existing scene. 88 /// Dearchive the given region archive. This replaces the existing scene.
76 /// </summary> 89 /// </summary>
77 /// 90 /// <remarks>
78 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event. 91 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
79 /// 92 /// </remarks>
80 /// <param name="loadPath"></param> 93 /// <param name="loadPath"></param>
81 void DearchiveRegion(string loadPath); 94 void DearchiveRegion(string loadPath);
82 95