Thanks for the review and for sanity-checking me :)
On 4 June 2014 15:19, Gavin Panella <email address hidden> wrote:
> Looks good, but I have several comments.
>
> Also, there probably ought to be a test to demonstrate that DeployForm has fields that reflect the current state of the system, rather than that as import time.
Good point. I'll work on that.
> Rapheël mentioned using callables for parts of Django's form machinery. Did you investigate that?
Yeah, doesn't work (there's an open ticket for it in the Django Trac).
Well, it does for `initial` values, but not for `choices`. Because,
why would you want something that useful.
> Diff comments:
>
>> === modified file 'src/maasserver/forms.py'
>> --- src/maasserver/forms.py 2014-05-29 18:20:58 +0000
>> +++ src/maasserver/forms.py 2014-06-04 09:49:20 +0000
>> @@ -230,7 +230,10 @@
>> for nodegroup in NodeGroup.objects.all():
>> osystems = osystems.union(
>> BootImage.objects.get_usable_osystems(nodegroup))
>> - osystems = [OperatingSystemRegistry[osystem] for osystem in osystems]
>> + osystems = [
>> + OperatingSystemRegistry[osystem] for osystem in osystems
>> + if osystem in OperatingSystemRegistry
>
> I suspect this needs to be changed to query the cluster. All information on what OS/release combos could be supported are in the simplestream that describes boot images. The information on what OS/release combos that *can be supported right now* is in the list of boot resources downloaded. Both of those originate in the cluster, though the latter is also cached in BootImage.
>
> This doesn't need to be changed in this branch, but there ought to be a plan to address it.
Right. I'll file a bug once this is landed.
>> + ]
>> return sorted(osystems, key=lambda osystem: osystem.title)
>>
>>
>> @@ -1023,9 +1026,33 @@
>>
>> class DeployForm(ConfigForm):
>> """Settings page, Deploy section."""
>> +
>> default_osystem = get_config_field('default_osystem')
>> default_distro_series = get_config_field('default_distro_series')
>>
>> + def __init__(self, *args, **kwargs):
>> + super(DeployForm, self).__init__(*args, **kwargs)
>> + # There's a race condition of some descrption that causes an
>> + # error when walking the BootImage table at import time (as
>> + # get_usable{os|release}_choices ultimately do). Setting the
>> + # choices here is less expensive than trying to find the
>> + # underlying race, which might be a Django thing.
>> + usable_oses = list_all_usable_osystems()
>> + os_choices = list_osystem_choices(usable_oses)
>> + self.fields['default_osystem'].choices = os_choices
>> + self.fields['default_osystem'].error_messages = {
>> + 'invalid_choice': compose_invalid_choice_text(
>> + 'osystem', os_choices)
>> + }
>> +
>> + release_choices = list_release_choices(
>> + list_all_usable_releases(usable_oses))
>> + self.fields['default_distro_series'].choices = release_choices
>> + self.fields['default_distro_series'].error_messages = {
>> + 'invalid_choice': compose_invalid_choice_text(
>> + 'osystem', release_choices)
>
> s/osystem/release/ or something like that.
Yup, ta.
>> === modified file 'src/maasserver/testing/factory.py'
>> --- src/maasserver/testing/factory.py 2014-06-03 08:24:52 +0000
>> +++ src/maasserver/testing/factory.py 2014-06-04 09:49:20 +0000
>> @@ -64,7 +64,7 @@
>> # XXX 2014-05-13 blake-rouse bug=1319143
>> # Need to not import directly, use RPC to info from cluster.
>> from provisioningserver.driver import OperatingSystemRegistry
>> -from provisioningserver.driver.os_ubuntu import UbuntuOS
>> +from provisioningserver.driver.os_ubuntu import UbuntuOS, DISTRO_SERIES_CHOICES
>
> Format imports.
Gaah. I'll do a lint check too.
>>
>> # We have a limited number of public keys:
>> # src/maasserver/tests/data/test_rsa{0, 1, 2, 3, 4}.pub
>> @@ -148,6 +148,10 @@
>>
>> def getRandomOS(self):
>> """Pick a random operating system from the registry."""
>> + # Make sure there's a boot image for each of the existing Ubuntu
>> + # OS / release combinations.
>
> Could you fabricate a random new OS here?
Sure.
>> + for series in DISTRO_SERIES_CHOICES.keys():
>
> No need for .keys().
Thanks for the review and for sanity-checking me :)
On 4 June 2014 15:19, Gavin Panella <email address hidden> wrote:
> Looks good, but I have several comments.
>
> Also, there probably ought to be a test to demonstrate that DeployForm has fields that reflect the current state of the system, rather than that as import time.
Good point. I'll work on that.
> Rapheël mentioned using callables for parts of Django's form machinery. Did you investigate that?
Yeah, doesn't work (there's an open ticket for it in the Django Trac).
Well, it does for `initial` values, but not for `choices`. Because,
why would you want something that useful.
> Diff comments: /forms. py' forms.py 2014-05-29 18:20:58 +0000 forms.py 2014-06-04 09:49:20 +0000 objects. all(): objects. get_usable_ osystems( nodegroup) ) mRegistry[ osystem] for osystem in osystems] Registry[ osystem] for osystem in osystems Registry
>
>> === modified file 'src/maasserver
>> --- src/maasserver/
>> +++ src/maasserver/
>> @@ -230,7 +230,10 @@
>> for nodegroup in NodeGroup.
>> osystems = osystems.union(
>> BootImage.
>> - osystems = [OperatingSyste
>> + osystems = [
>> + OperatingSystem
>> + if osystem in OperatingSystem
>
> I suspect this needs to be changed to query the cluster. All information on what OS/release combos could be supported are in the simplestream that describes boot images. The information on what OS/release combos that *can be supported right now* is in the list of boot resources downloaded. Both of those originate in the cluster, though the latter is also cached in BootImage.
>
> This doesn't need to be changed in this branch, but there ought to be a plan to address it.
Right. I'll file a bug once this is landed.
>> + ] ConfigForm) : field(' default_ osystem' ) distro_ series = get_config_ field(' default_ distro_ series' ) _init__ (*args, **kwargs) os|release} _choices ultimately do). Setting the usable_ osystems( ) choices( usable_ oses) 'default_ osystem' ].choices = os_choices 'default_ osystem' ].error_ messages = { invalid_ choice_ text( choices( usable_ releases( usable_ oses)) 'default_ distro_ series' ].choices = release_choices 'default_ distro_ series' ].error_ messages = { invalid_ choice_ text(
>> return sorted(osystems, key=lambda osystem: osystem.title)
>>
>>
>> @@ -1023,9 +1026,33 @@
>>
>> class DeployForm(
>> """Settings page, Deploy section."""
>> +
>> default_osystem = get_config_
>> default_
>>
>> + def __init__(self, *args, **kwargs):
>> + super(DeployForm, self)._
>> + # There's a race condition of some descrption that causes an
>> + # error when walking the BootImage table at import time (as
>> + # get_usable{
>> + # choices here is less expensive than trying to find the
>> + # underlying race, which might be a Django thing.
>> + usable_oses = list_all_
>> + os_choices = list_osystem_
>> + self.fields[
>> + self.fields[
>> + 'invalid_choice': compose_
>> + 'osystem', os_choices)
>> + }
>> +
>> + release_choices = list_release_
>> + list_all_
>> + self.fields[
>> + self.fields[
>> + 'invalid_choice': compose_
>> + 'osystem', release_choices)
>
> s/osystem/release/ or something like that.
Yup, ta.
>> === modified file 'src/maasserver /testing/ factory. py' testing/ factory. py 2014-06-03 08:24:52 +0000 testing/ factory. py 2014-06-04 09:49:20 +0000 ver.driver import OperatingSystem Registry ver.driver. os_ubuntu import UbuntuOS ver.driver. os_ubuntu import UbuntuOS, DISTRO_ SERIES_ CHOICES
>> --- src/maasserver/
>> +++ src/maasserver/
>> @@ -64,7 +64,7 @@
>> # XXX 2014-05-13 blake-rouse bug=1319143
>> # Need to not import directly, use RPC to info from cluster.
>> from provisioningser
>> -from provisioningser
>> +from provisioningser
>
> Format imports.
Gaah. I'll do a lint check too.
>> tests/data/ test_rsa{ 0, 1, 2, 3, 4}.pub
>> # We have a limited number of public keys:
>> # src/maasserver/
>> @@ -148,6 +148,10 @@
>>
>> def getRandomOS(self):
>> """Pick a random operating system from the registry."""
>> + # Make sure there's a boot image for each of the existing Ubuntu
>> + # OS / release combinations.
>
> Could you fabricate a random new OS here?
Sure.
>> + for series in DISTRO_ SERIES_ CHOICES. keys():
>
> No need for .keys().
K.
>> + self.make_ boot_image( release= series, osystem="ubuntu") Registry] choice( osystems) /tests/ test_forms. py' tests/test_ forms.py 2014-05-30 07:10:20 +0000 tests/test_ forms.py 2014-06-04 09:49:20 +0000 usable_ osystems( )) all_usable_ osystems_ omits_oses_ without_ boot_images( self): make_name( 'os') make_name( 'os') usable_ boot_images( osystem= usable_ os_name) osystem( self, usable_os_name) osystem( self, unusable_os_name) usable_ osystems( ) usable_ os, usable_os_list) n(unusable_ os, usable_os_list) all_usable_ osystems_ omits_oses_ not_supported( self): make_name( 'os') make_name( 'os') usable_ boot_images( osystem= usable_ os_name) usable_ boot_images( osystem= unusable_ os_name) osystem( self, usable_os_name) usable_ osystems( ) usable_ os, usable_os_list) n(unusable_ os_name, [os.name for os in usable_os_list]) all_usable_ releases_ combines_ nodegroups( self): /code.launchpad .net/~gmb/ maas/fix- commissioning- page-distro- list-bug- 1312844/ +merge/ 222010
>> osystems = [obj for _, obj in OperatingSystem
>> return random.
>>
>>
>> === modified file 'src/maasserver
>> --- src/maasserver/
>> +++ src/maasserver/
>> @@ -238,6 +238,28 @@
>> self.assertEqual(
>> [osystem], list_all_
>>
>> + def test_list_
>> + usable_os_name = factory.
>> + unusable_os_name = factory.
>> + self.make_
>> + usable_os = make_usable_
>> + unusable_os = make_usable_
>> +
>> + usable_os_list = list_all_
>> + self.assertIn(
>> + self.assertNotI
>> +
>> + def test_list_
>> + usable_os_name = factory.
>> + unusable_os_name = factory.
>> + self.make_
>> + self.make_
>> + usable_os = make_usable_
>> +
>> + usable_os_list = list_all_
>> + self.assertIn(
>> + self.assertNotI
>> +
>> def test_list_
>> expected = {}
>> osystems = []
>>
>
>
> --
> https:/
> You are the owner of lp:~gmb/maas/fix-commissioning-page-distro-list-bug-1312844.