diff options
author | Justin Clark-Casey (justincc) | 2011-05-26 02:22:52 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2011-05-26 02:22:52 +0100 |
commit | 3270f4353e0a2bded9361a72526ba673e6266cc1 (patch) | |
tree | 6de02c29ee9e2008f286c815ebdba94f135233a7 /OpenSim/Region/CoreModules/Avatar/Inventory | |
parent | Bump OAR file format version up to 0.7 for this development cycle. (diff) | |
download | opensim-SC_OLD-3270f4353e0a2bded9361a72526ba673e6266cc1.zip opensim-SC_OLD-3270f4353e0a2bded9361a72526ba673e6266cc1.tar.gz opensim-SC_OLD-3270f4353e0a2bded9361a72526ba673e6266cc1.tar.bz2 opensim-SC_OLD-3270f4353e0a2bded9361a72526ba673e6266cc1.tar.xz |
Add --noassets option for "save iar"
Like "save oar", this saves an iar without assets
This can be useful for backup when you know the required assets will still be present (e.g. you're backing up the assets db separately).
This also bumps the iar format version to 0.3 and 1.2 respectively.
0.3 is backward compatible with previous opensim versions
1.2 is used if the --profile switch is specified. It is only compatible with 0.7.1 presently.
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Inventory')
3 files changed, 145 insertions, 18 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index c039b5a..b5272ad 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -46,6 +46,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | /// <summary> | ||
50 | /// Determine whether this archive will save assets. Default is true. | ||
51 | /// </summary> | ||
52 | public bool SaveAssets { get; set; } | ||
53 | |||
49 | /// <value> | 54 | /// <value> |
50 | /// Used to select all inventory nodes in a folder but not the folder itself | 55 | /// Used to select all inventory nodes in a folder but not the folder itself |
51 | /// </value> | 56 | /// </value> |
@@ -112,6 +117,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
112 | m_invPath = invPath; | 117 | m_invPath = invPath; |
113 | m_saveStream = saveStream; | 118 | m_saveStream = saveStream; |
114 | m_assetGatherer = new UuidGatherer(m_scene.AssetService); | 119 | m_assetGatherer = new UuidGatherer(m_scene.AssetService); |
120 | |||
121 | SaveAssets = true; | ||
115 | } | 122 | } |
116 | 123 | ||
117 | protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) | 124 | protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) |
@@ -150,7 +157,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
150 | string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); | 157 | string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); |
151 | m_archiveWriter.WriteFile(filename, serialization); | 158 | m_archiveWriter.WriteFile(filename, serialization); |
152 | 159 | ||
153 | m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); | 160 | if (SaveAssets) |
161 | m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); | ||
154 | } | 162 | } |
155 | 163 | ||
156 | /// <summary> | 164 | /// <summary> |
@@ -195,6 +203,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
195 | /// </summary> | 203 | /// </summary> |
196 | public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) | 204 | public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) |
197 | { | 205 | { |
206 | if (options.ContainsKey("noassets") && (bool)options["noassets"]) | ||
207 | SaveAssets = false; | ||
208 | |||
198 | try | 209 | try |
199 | { | 210 | { |
200 | InventoryFolderBase inventoryFolder = null; | 211 | InventoryFolderBase inventoryFolder = null; |
@@ -285,12 +296,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
285 | 296 | ||
286 | // Don't put all this profile information into the archive right now. | 297 | // Don't put all this profile information into the archive right now. |
287 | //SaveUsers(); | 298 | //SaveUsers(); |
288 | 299 | ||
289 | new AssetsRequest( | 300 | if (SaveAssets) |
290 | new AssetsArchiver(m_archiveWriter), | 301 | { |
291 | m_assetUuids, m_scene.AssetService, | 302 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count); |
292 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, | 303 | |
293 | options, ReceivedAllAssets).Execute(); | 304 | new AssetsRequest( |
305 | new AssetsArchiver(m_archiveWriter), | ||
306 | m_assetUuids, m_scene.AssetService, | ||
307 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, | ||
308 | options, ReceivedAllAssets).Execute(); | ||
309 | } | ||
310 | else | ||
311 | { | ||
312 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified"); | ||
313 | |||
314 | ReceivedAllAssets(new List<UUID>(), new List<UUID>()); | ||
315 | } | ||
294 | } | 316 | } |
295 | catch (Exception) | 317 | catch (Exception) |
296 | { | 318 | { |
@@ -387,19 +409,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
387 | /// </summary> | 409 | /// </summary> |
388 | /// <param name="options"></param> | 410 | /// <param name="options"></param> |
389 | /// <returns></returns> | 411 | /// <returns></returns> |
390 | public static string CreateControlFile(Dictionary<string, object> options) | 412 | public string CreateControlFile(Dictionary<string, object> options) |
391 | { | 413 | { |
392 | int majorVersion, minorVersion; | 414 | int majorVersion, minorVersion; |
393 | 415 | ||
394 | if (options.ContainsKey("profile")) | 416 | if (options.ContainsKey("profile")) |
395 | { | 417 | { |
396 | majorVersion = 1; | 418 | majorVersion = 1; |
397 | minorVersion = 1; | 419 | minorVersion = 2; |
398 | } | 420 | } |
399 | else | 421 | else |
400 | { | 422 | { |
401 | majorVersion = 0; | 423 | majorVersion = 0; |
402 | minorVersion = 2; | 424 | minorVersion = 3; |
403 | } | 425 | } |
404 | 426 | ||
405 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); | 427 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); |
@@ -411,6 +433,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
411 | xtw.WriteStartElement("archive"); | 433 | xtw.WriteStartElement("archive"); |
412 | xtw.WriteAttributeString("major_version", majorVersion.ToString()); | 434 | xtw.WriteAttributeString("major_version", majorVersion.ToString()); |
413 | xtw.WriteAttributeString("minor_version", minorVersion.ToString()); | 435 | xtw.WriteAttributeString("minor_version", minorVersion.ToString()); |
436 | |||
437 | xtw.WriteElementString("assets_included", SaveAssets.ToString()); | ||
438 | |||
414 | xtw.WriteEndElement(); | 439 | xtw.WriteEndElement(); |
415 | 440 | ||
416 | xtw.Flush(); | 441 | xtw.Flush(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 576a154..e0b02aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -122,7 +122,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
122 | 122 | ||
123 | scene.AddCommand( | 123 | scene.AddCommand( |
124 | this, "save iar", | 124 | this, "save iar", |
125 | "save iar [--p|-profile=<url>] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]", | 125 | "save iar [--p|-profile=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]", |
126 | "Save user inventory archive (IAR).", | 126 | "Save user inventory archive (IAR).", |
127 | "<first> is the user's first name." + Environment.NewLine | 127 | "<first> is the user's first name." + Environment.NewLine |
128 | + "<last> is the user's last name." + Environment.NewLine | 128 | + "<last> is the user's last name." + Environment.NewLine |
@@ -130,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
130 | + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine | 130 | + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine |
131 | + "-c|--creators preserves information about foreign creators." + Environment.NewLine | 131 | + "-c|--creators preserves information about foreign creators." + Environment.NewLine |
132 | + "-v|--verbose extra debug messages." + Environment.NewLine | 132 | + "-v|--verbose extra debug messages." + Environment.NewLine |
133 | + "--noassets stops assets being saved to the IAR." | ||
133 | + "<IAR path> is the filesystem path at which to save the IAR." | 134 | + "<IAR path> is the filesystem path at which to save the IAR." |
134 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), | 135 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), |
135 | HandleSaveInvConsoleCommand); | 136 | HandleSaveInvConsoleCommand); |
@@ -398,6 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
398 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); | 399 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); |
399 | ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); | 400 | ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); |
400 | ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); | 401 | ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); |
402 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | ||
401 | 403 | ||
402 | List<string> mainParams = ops.Parse(cmdparams); | 404 | List<string> mainParams = ops.Parse(cmdparams); |
403 | 405 | ||
@@ -406,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
406 | if (mainParams.Count < 6) | 408 | if (mainParams.Count < 6) |
407 | { | 409 | { |
408 | m_log.Error( | 410 | m_log.Error( |
409 | "[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] <first name> <last name> <inventory path> <user password> [<save file path>]"); | 411 | "[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>]"); |
410 | return; | 412 | return; |
411 | } | 413 | } |
412 | 414 | ||
@@ -423,16 +425,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
423 | m_log.InfoFormat( | 425 | m_log.InfoFormat( |
424 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", | 426 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", |
425 | savePath, invPath, firstName, lastName); | 427 | savePath, invPath, firstName, lastName); |
426 | 428 | ||
429 | lock (m_pendingConsoleSaves) | ||
430 | m_pendingConsoleSaves.Add(id); | ||
431 | |||
427 | ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); | 432 | ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); |
428 | } | 433 | } |
429 | catch (InventoryArchiverException e) | 434 | catch (InventoryArchiverException e) |
430 | { | 435 | { |
431 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); | 436 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); |
432 | } | 437 | } |
433 | |||
434 | lock (m_pendingConsoleSaves) | ||
435 | m_pendingConsoleSaves.Add(id); | ||
436 | } | 438 | } |
437 | 439 | ||
438 | private void SaveInvConsoleCommandCompleted( | 440 | private void SaveInvConsoleCommandCompleted( |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index d97311a..ae3ab21 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs | |||
@@ -123,11 +123,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
123 | } | 123 | } |
124 | 124 | ||
125 | /// <summary> | 125 | /// <summary> |
126 | /// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive | 126 | /// Test saving a single inventory item to an IAR |
127 | /// (subject to change since there is no fixed format yet). | 127 | /// (subject to change since there is no fixed format yet). |
128 | /// </summary> | 128 | /// </summary> |
129 | [Test] | 129 | [Test] |
130 | public void TestSaveItemToIarV0_1() | 130 | public void TestSaveItemToIar() |
131 | { | 131 | { |
132 | TestHelper.InMethod(); | 132 | TestHelper.InMethod(); |
133 | // log4net.Config.XmlConfigurator.Configure(); | 133 | // log4net.Config.XmlConfigurator.Configure(); |
@@ -217,6 +217,106 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
217 | 217 | ||
218 | // TODO: Test presence of more files and contents of files. | 218 | // TODO: Test presence of more files and contents of files. |
219 | } | 219 | } |
220 | |||
221 | /// <summary> | ||
222 | /// Test saving a single inventory item to an IAR without its asset | ||
223 | /// </summary> | ||
224 | [Test] | ||
225 | public void TestSaveItemToIarNoAssets() | ||
226 | { | ||
227 | TestHelper.InMethod(); | ||
228 | // log4net.Config.XmlConfigurator.Configure(); | ||
229 | |||
230 | // Create user | ||
231 | string userFirstName = "Jock"; | ||
232 | string userLastName = "Stirrup"; | ||
233 | string userPassword = "troll"; | ||
234 | UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); | ||
235 | UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); | ||
236 | |||
237 | // Create asset | ||
238 | UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); | ||
239 | SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); | ||
240 | |||
241 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); | ||
242 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); | ||
243 | m_scene.AssetService.Store(asset1); | ||
244 | |||
245 | // Create item | ||
246 | UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); | ||
247 | string item1Name = "My Little Dog"; | ||
248 | InventoryItemBase item1 = new InventoryItemBase(); | ||
249 | item1.Name = item1Name; | ||
250 | item1.AssetID = asset1.FullID; | ||
251 | item1.ID = item1Id; | ||
252 | InventoryFolderBase objsFolder | ||
253 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; | ||
254 | item1.Folder = objsFolder.ID; | ||
255 | m_scene.AddInventoryItem(item1); | ||
256 | |||
257 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
258 | |||
259 | Dictionary<string, Object> options = new Dictionary<string, Object>(); | ||
260 | options.Add("noassets", true); | ||
261 | |||
262 | // When we're not saving assets, archiving is being done synchronously. | ||
263 | m_archiverModule.ArchiveInventory( | ||
264 | Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options); | ||
265 | |||
266 | byte[] archive = archiveWriteStream.ToArray(); | ||
267 | MemoryStream archiveReadStream = new MemoryStream(archive); | ||
268 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | ||
269 | |||
270 | //bool gotControlFile = false; | ||
271 | bool gotObject1File = false; | ||
272 | //bool gotObject2File = false; | ||
273 | string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1); | ||
274 | string expectedObject1FilePath = string.Format( | ||
275 | "{0}{1}", | ||
276 | ArchiveConstants.INVENTORY_PATH, | ||
277 | expectedObject1FileName); | ||
278 | |||
279 | string filePath; | ||
280 | TarArchiveReader.TarEntryType tarEntryType; | ||
281 | |||
282 | // Console.WriteLine("Reading archive"); | ||
283 | |||
284 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) | ||
285 | { | ||
286 | Console.WriteLine("Got {0}", filePath); | ||
287 | |||
288 | // if (ArchiveConstants.CONTROL_FILE_PATH == filePath) | ||
289 | // { | ||
290 | // gotControlFile = true; | ||
291 | // } | ||
292 | |||
293 | if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml")) | ||
294 | { | ||
295 | // string fileName = filePath.Remove(0, "Objects/".Length); | ||
296 | // | ||
297 | // if (fileName.StartsWith(part1.Name)) | ||
298 | // { | ||
299 | Assert.That(expectedObject1FilePath, Is.EqualTo(filePath)); | ||
300 | gotObject1File = true; | ||
301 | // } | ||
302 | // else if (fileName.StartsWith(part2.Name)) | ||
303 | // { | ||
304 | // Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); | ||
305 | // gotObject2File = true; | ||
306 | // } | ||
307 | } | ||
308 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) | ||
309 | { | ||
310 | Assert.Fail("Found asset path in TestSaveItemToIarNoAssets()"); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | // Assert.That(gotControlFile, Is.True, "No control file in archive"); | ||
315 | Assert.That(gotObject1File, Is.True, "No item1 file in archive"); | ||
316 | // Assert.That(gotObject2File, Is.True, "No object2 file in archive"); | ||
317 | |||
318 | // TODO: Test presence of more files and contents of files. | ||
319 | } | ||
220 | 320 | ||
221 | /// <summary> | 321 | /// <summary> |
222 | /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized | 322 | /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized |