-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Catalog upload feature2 #98
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good but needs more commentary. I think the biggest requirement is to explain the upload protocol in an accessible way as it's not a simple process and not everyone will have it in their heads when working on this code.
Test cases are great. Thanks taking the care to put them in.
govcd/catalog.go
Outdated
@@ -125,7 +128,7 @@ type Envelope struct { | |||
} `xml:"References>File"` | |||
} | |||
|
|||
// If catalogitem is a valid CatalogItem and the call succeds, | |||
// If catalog item is a valid CatalogItem and the call succeeds, | |||
// then the function returns a CatalogItem. If the item does not | |||
// exist, then it returns an empty CatalogItem. If The call fails |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: 'If The call' should be 'If the call'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
govcd/catalog.go
Outdated
@@ -163,37 +166,47 @@ func (cat *Catalog) FindCatalogItem(catalogitem string) (CatalogItem, error) { | |||
|
|||
// uploads an ova file to a catalog. This method only uploads bits to vCD spool area. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leading sentence should be capitalized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
govcd/catalog.go
Outdated
@@ -163,37 +166,47 @@ func (cat *Catalog) FindCatalogItem(catalogitem string) (CatalogItem, error) { | |||
|
|||
// uploads an ova file to a catalog. This method only uploads bits to vCD spool area. | |||
// Returns errors if any occur during upload from vCD or upload process. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a catalog upload fails does the client program have to do any cleanup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expanded comment.
govcd/catalog.go
Outdated
|
||
for _, catalogItemName := range getExistingCatalogItems(cat) { | ||
if catalogItemName == itemName { | ||
return UploadTask{}, fmt.Errorf("catalog item by name: '%s' already exist. Upload with different name", itemName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Message is not fully grammatical. Suggestion: "Catalog item'%s' already exists. Upload with different name."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
govcd/catalog.go
Outdated
uploadProgress = (float64(bytesUploaded) / float64(totalSize)) * 100 | ||
} | ||
|
||
go uploadFiles(cat.client, vappTemplate, &ovfFileDesc, tempPath, filesAbsPaths, uploadPieceSize, callBack, tmpDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment to explain the concurrent processing you are doing here? IT's not easy to read out of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
govcd/catalog_test.go
Outdated
catalog, org := findCatalog(vcd, check, catalogName) | ||
AddToCleanupList(itemName, "catalogItem", vcd.org.Org.Name, "Test_UploadOvf") | ||
|
||
//execute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary comment. (Same applies to verify below.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
@@ -0,0 +1,33 @@ | |||
package govcd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a proper Apache 2 header. Please copy from another file. Also any file you touch should have the copyright date 2018 added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added and updated year on files I touched everywhere.
*Task | ||
} | ||
|
||
func NewUploadTask(task *Task, uploadProgress *float64) *UploadTask { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment to document public APIs in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
util/tar.go
Outdated
func Unpack(tarFile string) ([]string, error) { | ||
const TmpDirPrefix = "govcd" | ||
|
||
//extract files to system tmp dir with name govcd+random number. Created folder with files isn't deleted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the output of this function? Also 'extract' should be capitalized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
"testing" | ||
) | ||
|
||
func TestSanitizedName(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please a comment describing what this test is checking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests should conform to the general structure of the other tests.
As for the binaries in the code directory, I'd move them in a separate repository, but I'll let the team decide what's the best place for them.
govcd/catalog_test.go
Outdated
|
||
const ( | ||
OvaPath = "/test_vapp_template.ova" | ||
OvaChunkedPath = "/template_with_custom_chunk_size.ova" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see two problems with these two files:
- binary artifacts should not be in the code directory. Our repo will end up in someone else's vendor directory, and many would object to having non-text files mixed up with code.
- test components should be referred to in the configuration file. These two items should be added to the config structure in api_vcd_test.go and used accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
I would agree with https://medium.com/@matryer/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742 and move all test to different package - in that away we can avoid more clutter in future and separate stuff. And solve issue mentioned by you as binary files would be in different package. Otherwise we create issue that test exist but they fail for others if they won't checkout special folder with binary files.
-
Yes, I can move constants to api_vcd_test.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have already tests that depend on user defined artifacts. This test should be no different. It may pass with the artifacts that we recommend, but we must see how it behaves with user defined items.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move binaries to test-resources. Ova paths are configured if empty, tests are skipped.
govcd/catalog_test.go
Outdated
@@ -84,3 +96,179 @@ func (vcd *TestVCD) Test_DeleteCatalog(check *C) { | |||
check.Assert(catalog, Equals, Catalog{}) | |||
|
|||
} | |||
|
|||
func (vcd *TestVCD) Test_UploadOvf(check *C) { | |||
checkUploadOvf(vcd, check, getCurrentPath()+OvaPath, TestCreateCatalog, "item1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every item created by the tests should have a name that refers to the function that creates it. See the constants in api_vcd_test.go for some examples.
Thus, "item1" should become "TestUploadOvf", and TestCreateCatalog should not be used. If you need to create a new catalog for this function, it should have a function related name.
Is there a reason not to use the catalog indicated in the test configuration file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I missed this - will correct it.
govcd/catalog_test.go
Outdated
|
||
func (vcd *TestVCD) Test_UploadOvf_progress_works(check *C) { | ||
catalogName := TestCreateCatalog + "3" | ||
itemName := "item3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the above comments for the name of the items.
Moreover, the upload tests are creating four catalogs. Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's test independence question. Test can't depend on other tests result (e.g. what id did with catalog in previous test).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If more catalogs are needed, we should name them according to their purposes.
In general, we should make tests that work with the material provided by users (i.e the catalog defined in the configuration file).
We should create new catalogs only when testing something relating to catalog creation or if we run an operation that requires two catalogs. Otherwise, we should always use the catalog given by users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
govcd/catalog_test.go
Outdated
setupCatalog(vcd, check, catalogName) | ||
|
||
catalog, org := findCatalog(vcd, check, catalogName) | ||
AddToCleanupList(itemName, "catalogItem", vcd.org.Org.Name, "Test_UploadOvf") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cleanup procedure in api_vcd_test.go does not recognize "catalogItem" yet. It should be updated to handle this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked and think we can avoid it as catalog cleanup allows to delete catalog with items. So removing AddToCleanupList should be sufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. All the tests are removing their artifacts. The cleanup list is the safety net to remove things when the test fails and aborts prematurely.
We should keep it and update the cleanup function accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CatalogItem cleanup added.
govcd/catalog_test.go
Outdated
org := getOrg(vcd, check) | ||
|
||
// creating catalog | ||
adminCatalog, err := org.CreateCatalog(testCreateCatalog, TestCreateCatalogDesc, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this test is using an AdminCatalog, it should check whether skipAdminTests
is set, and skip the test if it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will add.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this isn't needed cause tests rung fine with org user or admin.
govcd/catalog_test.go
Outdated
return org | ||
} | ||
|
||
func skipThenOvaPathMissing(vcd *TestVCD, check *C) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be called skipWhenOvaPathMissing
govcd/catalog_test.go
Outdated
//setupCatalog(vcd, check, testCreateCatalog) | ||
|
||
catalog, org := findCatalog(vcd, check, vcd.config.VCD.Catalog.Name) | ||
AddToCleanupList(itemName, "catalogItem", vcd.org.Org.Name+"|"+vcd.config.VCD.Catalog.Name, "Test_UploadOvf") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The call to AddToCleanupList
should only happen after the successful creation of an item.
govcd/catalog.go
Outdated
@@ -202,58 +223,94 @@ func (cat *Catalog) UploadOvf(ovaFileName, itemName, description string, chunkSi | |||
for _, filePath := range filesAbsPaths { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are assuming here that the extracted file contains a .ovf.
If this is not true, the procedure hangs. This check needs to happen before the item is created.
govcd/api_vcd_test.go
Outdated
} | ||
} | ||
} | ||
vcd.infoCleanup(removedMsg, entity.EntityType, entity.Name, entity.CreatedBy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something is missing in this procedure. When I use a non existing OVA in the test, it still prints Removed catalogItem '<ITEM_NAME>' created by Test_UploadOvf
.
govcd/catalog.go
Outdated
} | ||
|
||
filesAbsPaths, err := util.Unpack(ovaFileName) | ||
filesAbsPaths, tmpDir, err := util.Unpack(ovaFileName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unpack should happen before we create the item. If the unpack fails, the item will stay unused and waiting for an upload that won't come.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please merge after implementing Giuseppe's feedback.
// Upload files for vCD created upload links. Different approach then vmdk file are | ||
// chunked (e.g. test.vmdk.000000000, test.vmdk.000000001 or test.vmdk). vmdk files are chunked if | ||
// in description file attribute ChunkSize is not zero. | ||
func uploadFiles(client *Client, vappTemplate *types.VAppTemplate, ovfFileDesc *Envelope, tempPath string, filesAbsPaths []string, uploadPieceSize int64, callBack func(bytesUpload, totalSize int64)) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function has too many positional arguments.
Please add documentation about the meaning of every argument. Consider doing the same for every function that has more than three args.
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
…t with callback when we add it. Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
…ou can check progress and wait for task completion. Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
…00 without explanation. Signed-off-by: Vaidotas Bauzys <[email protected]>
…errors, like: storage quota exceeded Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
… remove api function and test. Moved binaries to test-resources folder. Signed-off-by: Vaidotas Bauzys <[email protected]>
…valid. Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
… catalog item created on various fails anymore. Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
…happend. Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Signed-off-by: Vaidotas Bauzys <[email protected]>
Second part of missing functionality Related issue: (#50)
Enhanced upload functionality for catalog item. Returns special upload task which allows monitor upload if required and later can wait until vCD import task finishes. Upload happens in background. Other improvements:
Added Missing tests
Code improvements
Removed lock to xml first element
Better error handling
Verified and improved that "sanitizedName" func is enough to cover security issue -> See vmware-archive/pyvcloud#268.
Use new logging system
Error handling return within xml of response
Checked and parse errors when vCD fails after ovf file upload.
Multiupload verified.
Report percentage progress.
Check against nil catalog
Files unarchived to temp folder and cleaned
Checked files: from the tarball header with the size we have extracted
Make upload chunking working as function parameter
Specific check to avoid cryptic error then item already exist.
Note: Exist one question how to handle between AdminCatalog and Catalog object if needed. Current implementation allows working from Catalog object perspective.