def test_removes_old_bootresourcefiles(self): # Regression test for LP:1660418 os = factory.make_name('os') series = factory.make_name('series') OperatingSystemRegistry.register_item(os, CustomOS()) self.addCleanup(OperatingSystemRegistry.unregister_item, os) name = '%s/%s' % (os, series) architecture = make_usable_architecture(self) resource = factory.make_usable_boot_resource( rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=name, architecture=architecture) upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode('utf-8') upload_name = factory.make_name('filename') uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { 'name': name, 'architecture': architecture, 'filetype': upload_type, } form = BootResourceForm(data=data, files={'content': uploaded_file}) self.assertTrue(form.is_valid(), form._errors) form.save() self.assertEqual( 1, BootResourceFile.objects.filter( resource_set__resource=resource).count())
def test_creates_boot_resource(self): name = factory.make_name('name') title = factory.make_name('title') architecture = make_usable_architecture(self) subarch = architecture.split('/')[1] upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode('utf-8') upload_name = factory.make_name('filename') uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { 'name': 'custom/' + name, 'title': title, 'architecture': architecture, 'filetype': upload_type, } form = BootResourceForm(data=data, files={'content': uploaded_file}) self.assertTrue(form.is_valid(), form._errors) form.save() resource = BootResource.objects.get(rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=name, architecture=architecture) resource_set = resource.sets.first() rfile = resource_set.files.first() self.assertEqual(title, resource.extra['title']) self.assertEqual(subarch, resource.extra['subarches']) self.assertTrue(filetype, rfile.filetype) self.assertTrue(filetype, rfile.filename) self.assertTrue(size, rfile.largefile.total_size) with rfile.largefile.content.open('rb') as stream: written_content = stream.read() self.assertEqual(content, written_content)
def test_adds_boot_resource_set_to_existing_uploaded_boot_resource(self): os = factory.make_name('os') series = factory.make_name('series') OperatingSystemRegistry.register_item(os, CustomOS()) self.addCleanup(OperatingSystemRegistry.unregister_item, os) name = '%s/%s' % (os, series) architecture = make_usable_architecture(self) resource = factory.make_usable_boot_resource( rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=name, architecture=architecture) upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode('utf-8') upload_name = factory.make_name('filename') uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { 'name': name, 'architecture': architecture, 'filetype': upload_type, 'keep_old': True, } form = BootResourceForm(data=data, files={'content': uploaded_file}) self.assertTrue(form.is_valid(), form._errors) form.save() resource = reload_object(resource) resource_set = resource.sets.order_by('id').last() rfile = resource_set.files.first() self.assertTrue(filetype, rfile.filetype) self.assertTrue(filetype, rfile.filename) self.assertTrue(size, rfile.largefile.total_size) with rfile.largefile.content.open('rb') as stream: written_content = stream.read() self.assertEqual(content, written_content) self.assertEqual(resource.rtype, BOOT_RESOURCE_TYPE.UPLOADED)
def test_creates_boot_resource(self): name = factory.make_name("name") title = factory.make_name("title") architecture = make_usable_architecture(self) subarch = architecture.split("/")[1] upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode("utf-8") upload_name = factory.make_name("filename") uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { "name": "custom/" + name, "title": title, "architecture": architecture, "filetype": upload_type, } form = BootResourceForm(data=data, files={"content": uploaded_file}) self.assertTrue(form.is_valid(), form._errors) form.save() resource = BootResource.objects.get( rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=name, architecture=architecture, ) resource_set = resource.sets.first() rfile = resource_set.files.first() self.assertEqual(title, resource.extra["title"]) self.assertEqual(subarch, resource.extra["subarches"]) self.assertTrue(filetype, rfile.filetype) self.assertTrue(filetype, rfile.filename) self.assertTrue(size, rfile.largefile.total_size) with rfile.largefile.content.open("rb") as stream: written_content = stream.read() self.assertEqual(content, written_content)
def test_creates_boot_resoures_with_uploaded_rtype(self): os = factory.make_name("os") series = factory.make_name("series") OperatingSystemRegistry.register_item(os, CustomOS()) self.addCleanup(OperatingSystemRegistry.unregister_item, os) name = "%s/%s" % (os, series) architecture = make_usable_architecture(self) upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode("utf-8") upload_name = factory.make_name("filename") uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { "name": name, "architecture": architecture, "filetype": upload_type, } form = BootResourceForm(data=data, files={"content": uploaded_file}) self.assertTrue(form.is_valid(), form._errors) form.save() resource = BootResource.objects.get( rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=name, architecture=architecture, ) resource_set = resource.sets.first() rfile = resource_set.files.first() self.assertTrue(filetype, rfile.filetype) self.assertTrue(filetype, rfile.filename) self.assertTrue(size, rfile.largefile.total_size) with rfile.largefile.content.open("rb") as stream: written_content = stream.read() self.assertEqual(content, written_content)
def test_adds_boot_resource_set_to_existing_boot_resource(self): name = factory.make_name("name") architecture = make_usable_architecture(self) resource = factory.make_usable_boot_resource( rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=name, architecture=architecture, ) upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode("utf-8") upload_name = factory.make_name("filename") uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { "name": name, "architecture": architecture, "filetype": upload_type, "keep_old": True, } form = BootResourceForm(data=data, files={"content": uploaded_file}) self.assertTrue(form.is_valid(), form._errors) form.save() resource = reload_object(resource) resource_set = resource.sets.order_by("id").last() rfile = resource_set.files.first() self.assertTrue(filetype, rfile.filetype) self.assertTrue(filetype, rfile.filename) self.assertTrue(size, rfile.largefile.total_size) with rfile.largefile.content.open("rb") as stream: written_content = stream.read() self.assertEqual(content, written_content)
def test_requires_fields(self): form = BootResourceForm(data={}) self.assertFalse(form.is_valid(), form.errors) self.assertItemsEqual( ["name", "architecture", "filetype", "content"], form.errors.keys(), )
def test_requires_fields(self): form = BootResourceForm(data={}) self.assertFalse(form.is_valid(), form.errors) self.assertItemsEqual([ 'name', 'architecture', 'filetype', 'content', ], form.errors.keys())
def test_prevents_reserved_name(self): bsc = factory.make_BootSourceCache() upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode('utf-8') upload_name = factory.make_name('filename') uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { 'name': '%s/%s' % (bsc.os, bsc.release), 'title': factory.make_name('title'), 'architecture': make_usable_architecture(self), 'filetype': upload_type, } form = BootResourceForm(data=data, files={'content': uploaded_file}) self.assertFalse(form.is_valid())
def test_prevents_reserved_centos_names(self): reserved_name = 'centos%d' % random.randint(0, 99) upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode('utf-8') upload_name = factory.make_name('filename') uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { 'name': reserved_name, 'title': factory.make_name('title'), 'architecture': make_usable_architecture(self), 'filetype': upload_type, } form = BootResourceForm(data=data, files={'content': uploaded_file}) self.assertFalse(form.is_valid())
def test_prevents_reserved_name(self): bsc = factory.make_BootSourceCache() upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode("utf-8") upload_name = factory.make_name("filename") uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { "name": "%s/%s" % (bsc.os, bsc.release), "title": factory.make_name("title"), "architecture": make_usable_architecture(self), "filetype": upload_type, } form = BootResourceForm(data=data, files={"content": uploaded_file}) self.assertFalse(form.is_valid())
def test_prevents_reserved_centos_names(self): reserved_name = "centos%d" % random.randint(0, 99) upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode("utf-8") upload_name = factory.make_name("filename") uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { "name": reserved_name, "title": factory.make_name("title"), "architecture": make_usable_architecture(self), "filetype": upload_type, } form = BootResourceForm(data=data, files={"content": uploaded_file}) self.assertFalse(form.is_valid())
def test_prevents_reversed_osystem_from_driver(self): reserved_name = factory.make_name('name') OperatingSystemRegistry.register_item(reserved_name, CustomOS()) upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode('utf-8') upload_name = factory.make_name('filename') uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { 'name': reserved_name, 'title': factory.make_name('title'), 'architecture': make_usable_architecture(self), 'filetype': upload_type, } form = BootResourceForm(data=data, files={'content': uploaded_file}) self.assertFalse(form.is_valid())
def test_invalidates_nonexistent_custom_image_base_os(self): name = "custom/%s" % factory.make_name("name") upload_type, filetype = self.pick_filetype() size = random.randint(1024, 2048) content = factory.make_string(size).encode("utf-8") upload_name = factory.make_name("filename") uploaded_file = SimpleUploadedFile(content=content, name=upload_name) data = { "name": name, "title": factory.make_name("title"), "architecture": make_usable_architecture(self), "filetype": upload_type, "base_image": factory.make_name("invalid"), } form = BootResourceForm(data=data, files={"content": uploaded_file}) self.assertFalse(form.is_valid())
def create(self, request): """@description-title Upload a new boot resource @description Uploads a new boot resource. @param (string) "name" [required=true] Name of the boot resource. @param (string) "architecture" [required=true] Architecture the boot resource supports. @param (string) "sha256" [required=true] The ``sha256`` hash of the resource. @param (string) "size" [required=true] The size of the resource in bytes. @param (string) "title" [required=false] Title for the boot resource. @param (string) "filetype" [required=false] Filetype for uploaded content. (Default: ``tgz``. Supported: ``tgz``, ``tbz``, ``txz``, ``ddtgz``, ``ddtbz``, ``ddtxz``, ``ddtar``, ``ddbz2``, ``ddgz``, ``ddxz``, ``ddraw``) @param (string) "content" [required=false] Image content. Note: this is not a normal parameter, but an ``application/octet-stream`` file upload. @success (http-status-code) "server-success" 201 @success (json) "success-json" A JSON object containing information about the uploaded resource. @success-example "success-json" [exkey=boot-res-create] placeholder text """ # If the user provides no parameters to the create command, then # django will treat the form as valid, and so it won't actually # validate any of the data. data = request.data.copy() if data is None: data = {} if "filetype" not in data: data["filetype"] = "tgz" file_content = get_content_parameter(request) if file_content is not None: content = SimpleUploadedFile( content=file_content, name="file", content_type="application/octet-stream", ) form = BootResourceForm(data=data, files={"content": content}) else: form = BootResourceNoContentForm(data=data) if not form.is_valid(): raise MAASAPIValidationError(form.errors) resource = form.save() # If an upload contained the full file, then we can have the clusters # sync a new resource. if file_content is not None: # Avoid circular import. from maasserver.clusterrpc.boot_images import ( RackControllersImporter, ) post_commit_do(RackControllersImporter.schedule) stream = json_object(boot_resource_to_dict(resource, with_sets=True), request) return HttpResponse( stream, content_type="application/json; charset=utf-8", status=int(http.client.CREATED), )