Merge lp:~gz/maas/1.2_add_db_kernel_params into lp:maas/1.2
- 1.2_add_db_kernel_params
- Merge into 1.2
Status: | Merged |
---|---|
Approved by: | Martin Packman |
Approved revision: | no longer in the source branch. |
Merged at revision: | 1285 |
Proposed branch: | lp:~gz/maas/1.2_add_db_kernel_params |
Merge into: | lp:maas/1.2 |
Prerequisite: | lp:~gz/maas/1.2_fix_duplicated_039_migration |
Diff against target: |
271 lines (+220/-3) 4 files modified
src/maasserver/migrations/0043_add_tag_kernel_opts.py (+203/-0) src/maasserver/models/tag.py (+3/-0) src/maasserver/testing/factory.py (+4/-3) src/maasserver/tests/test_tag.py (+10/-0) |
To merge this branch: | bzr merge lp:~gz/maas/1.2_add_db_kernel_params |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
John A Meinel (community) | Approve | ||
Review via email: mp+133044@code.launchpad.net |
Commit message
Add kernel_opts field to Tag to allow for customisation of kernel command line
Description of the change
Adds a field to Tag for holding custom kernel parameters, which is a step towards resolving bug 1044503.
The plan is to store the global options as a specially named field in Config, which will not require a migration. The values there are json, but it's fine to just use a string instead of an object. The per-tag customisation could also be done there by packing the tag name into the key, but having a string field on tag is simple enough.
The added field allows null in the hope that we may be able to distinguish "use global" from "use no params" simply.
Martin Packman (gz) wrote : | # |
Have added to the class docstring, and integrated a little with the testing environment. Real testing can wait for when there's some actual logic I think.
Martin Packman (gz) wrote : | # |
As suggested by John on call, have renamed kernel_params field to kernel_opts which is closer to the existing usage in provisioningserver.
Preview Diff
1 | === added file 'src/maasserver/migrations/0043_add_tag_kernel_opts.py' | |||
2 | --- src/maasserver/migrations/0043_add_tag_kernel_opts.py 1970-01-01 00:00:00 +0000 | |||
3 | +++ src/maasserver/migrations/0043_add_tag_kernel_opts.py 2012-11-07 10:40:26 +0000 | |||
4 | @@ -0,0 +1,203 @@ | |||
5 | 1 | # -*- coding: utf-8 -*- | ||
6 | 2 | import datetime | ||
7 | 3 | from south.db import db | ||
8 | 4 | from south.v2 import SchemaMigration | ||
9 | 5 | from django.db import models | ||
10 | 6 | |||
11 | 7 | |||
12 | 8 | class Migration(SchemaMigration): | ||
13 | 9 | |||
14 | 10 | def forwards(self, orm): | ||
15 | 11 | # Adding field 'Tag.kernel_opts' | ||
16 | 12 | db.add_column(u'maasserver_tag', 'kernel_opts', | ||
17 | 13 | self.gf('django.db.models.fields.TextField')(null=True, blank=True), | ||
18 | 14 | keep_default=False) | ||
19 | 15 | |||
20 | 16 | |||
21 | 17 | def backwards(self, orm): | ||
22 | 18 | # Deleting field 'Tag.kernel_opts' | ||
23 | 19 | db.delete_column(u'maasserver_tag', 'kernel_opts') | ||
24 | 20 | |||
25 | 21 | |||
26 | 22 | models = { | ||
27 | 23 | 'auth.group': { | ||
28 | 24 | 'Meta': {'object_name': 'Group'}, | ||
29 | 25 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
30 | 26 | 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | ||
31 | 27 | 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | ||
32 | 28 | }, | ||
33 | 29 | 'auth.permission': { | ||
34 | 30 | 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, | ||
35 | 31 | 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
36 | 32 | 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), | ||
37 | 33 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
38 | 34 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | ||
39 | 35 | }, | ||
40 | 36 | 'auth.user': { | ||
41 | 37 | 'Meta': {'object_name': 'User'}, | ||
42 | 38 | 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
43 | 39 | 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | ||
44 | 40 | 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
45 | 41 | 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), | ||
46 | 42 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
47 | 43 | 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | ||
48 | 44 | 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
49 | 45 | 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
50 | 46 | 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
51 | 47 | 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
52 | 48 | 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | ||
53 | 49 | 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), | ||
54 | 50 | 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) | ||
55 | 51 | }, | ||
56 | 52 | 'contenttypes.contenttype': { | ||
57 | 53 | 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | ||
58 | 54 | 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
59 | 55 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
60 | 56 | 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
61 | 57 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
62 | 58 | }, | ||
63 | 59 | u'maasserver.bootimage': { | ||
64 | 60 | 'Meta': {'unique_together': "((u'nodegroup', u'architecture', u'subarchitecture', u'release', u'purpose'),)", 'object_name': 'BootImage'}, | ||
65 | 61 | 'architecture': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||
66 | 62 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
67 | 63 | 'nodegroup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['maasserver.NodeGroup']"}), | ||
68 | 64 | 'purpose': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||
69 | 65 | 'release': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||
70 | 66 | 'subarchitecture': ('django.db.models.fields.CharField', [], {'max_length': '255'}) | ||
71 | 67 | }, | ||
72 | 68 | u'maasserver.componenterror': { | ||
73 | 69 | 'Meta': {'object_name': 'ComponentError'}, | ||
74 | 70 | 'component': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}), | ||
75 | 71 | 'created': ('django.db.models.fields.DateTimeField', [], {}), | ||
76 | 72 | 'error': ('django.db.models.fields.CharField', [], {'max_length': '1000'}), | ||
77 | 73 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
78 | 74 | 'updated': ('django.db.models.fields.DateTimeField', [], {}) | ||
79 | 75 | }, | ||
80 | 76 | u'maasserver.config': { | ||
81 | 77 | 'Meta': {'object_name': 'Config'}, | ||
82 | 78 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
83 | 79 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||
84 | 80 | 'value': ('maasserver.fields.JSONObjectField', [], {'null': 'True'}) | ||
85 | 81 | }, | ||
86 | 82 | u'maasserver.dhcplease': { | ||
87 | 83 | 'Meta': {'object_name': 'DHCPLease'}, | ||
88 | 84 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
89 | 85 | 'ip': ('django.db.models.fields.IPAddressField', [], {'unique': 'True', 'max_length': '15'}), | ||
90 | 86 | 'mac': ('maasserver.fields.MACAddressField', [], {}), | ||
91 | 87 | 'nodegroup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['maasserver.NodeGroup']"}) | ||
92 | 88 | }, | ||
93 | 89 | u'maasserver.filestorage': { | ||
94 | 90 | 'Meta': {'object_name': 'FileStorage'}, | ||
95 | 91 | 'content': ('metadataserver.fields.BinaryField', [], {}), | ||
96 | 92 | 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), | ||
97 | 93 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) | ||
98 | 94 | }, | ||
99 | 95 | u'maasserver.macaddress': { | ||
100 | 96 | 'Meta': {'object_name': 'MACAddress'}, | ||
101 | 97 | 'created': ('django.db.models.fields.DateTimeField', [], {}), | ||
102 | 98 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
103 | 99 | 'mac_address': ('maasserver.fields.MACAddressField', [], {'unique': 'True'}), | ||
104 | 100 | 'node': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['maasserver.Node']"}), | ||
105 | 101 | 'updated': ('django.db.models.fields.DateTimeField', [], {}) | ||
106 | 102 | }, | ||
107 | 103 | u'maasserver.node': { | ||
108 | 104 | 'Meta': {'object_name': 'Node'}, | ||
109 | 105 | 'after_commissioning_action': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
110 | 106 | 'architecture': ('django.db.models.fields.CharField', [], {'default': "u'i386/generic'", 'max_length': '31'}), | ||
111 | 107 | 'cpu_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
112 | 108 | 'created': ('django.db.models.fields.DateTimeField', [], {}), | ||
113 | 109 | 'distro_series': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '10', 'null': 'True', 'blank': 'True'}), | ||
114 | 110 | 'error': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'blank': 'True'}), | ||
115 | 111 | 'hardware_details': ('maasserver.fields.XMLField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}), | ||
116 | 112 | 'hostname': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'blank': 'True'}), | ||
117 | 113 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
118 | 114 | 'memory': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
119 | 115 | 'netboot': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | ||
120 | 116 | 'nodegroup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['maasserver.NodeGroup']", 'null': 'True'}), | ||
121 | 117 | 'owner': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}), | ||
122 | 118 | 'power_parameters': ('maasserver.fields.JSONObjectField', [], {'default': "u''", 'blank': 'True'}), | ||
123 | 119 | 'power_type': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '10', 'blank': 'True'}), | ||
124 | 120 | 'status': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '10'}), | ||
125 | 121 | 'system_id': ('django.db.models.fields.CharField', [], {'default': "u'node-8b729164-2805-11e2-bc60-fa163e384ad1'", 'unique': 'True', 'max_length': '41'}), | ||
126 | 122 | 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['maasserver.Tag']", 'symmetrical': 'False'}), | ||
127 | 123 | 'token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['piston.Token']", 'null': 'True'}), | ||
128 | 124 | 'updated': ('django.db.models.fields.DateTimeField', [], {}) | ||
129 | 125 | }, | ||
130 | 126 | u'maasserver.nodegroup': { | ||
131 | 127 | 'Meta': {'object_name': 'NodeGroup'}, | ||
132 | 128 | 'api_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '18'}), | ||
133 | 129 | 'api_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['piston.Token']", 'unique': 'True'}), | ||
134 | 130 | 'cluster_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100', 'blank': 'True'}), | ||
135 | 131 | 'created': ('django.db.models.fields.DateTimeField', [], {}), | ||
136 | 132 | 'dhcp_key': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'blank': 'True'}), | ||
137 | 133 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
138 | 134 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}), | ||
139 | 135 | 'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
140 | 136 | 'updated': ('django.db.models.fields.DateTimeField', [], {}), | ||
141 | 137 | 'uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}) | ||
142 | 138 | }, | ||
143 | 139 | u'maasserver.nodegroupinterface': { | ||
144 | 140 | 'Meta': {'unique_together': "((u'nodegroup', u'interface'),)", 'object_name': 'NodeGroupInterface'}, | ||
145 | 141 | 'broadcast_ip': ('django.db.models.fields.GenericIPAddressField', [], {'default': 'None', 'max_length': '39', 'null': 'True', 'blank': 'True'}), | ||
146 | 142 | 'created': ('django.db.models.fields.DateTimeField', [], {}), | ||
147 | 143 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
148 | 144 | 'interface': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'blank': 'True'}), | ||
149 | 145 | 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | ||
150 | 146 | 'ip_range_high': ('django.db.models.fields.GenericIPAddressField', [], {'default': 'None', 'max_length': '39', 'null': 'True', 'blank': 'True'}), | ||
151 | 147 | 'ip_range_low': ('django.db.models.fields.GenericIPAddressField', [], {'default': 'None', 'max_length': '39', 'null': 'True', 'blank': 'True'}), | ||
152 | 148 | 'management': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
153 | 149 | 'nodegroup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['maasserver.NodeGroup']"}), | ||
154 | 150 | 'router_ip': ('django.db.models.fields.GenericIPAddressField', [], {'default': 'None', 'max_length': '39', 'null': 'True', 'blank': 'True'}), | ||
155 | 151 | 'subnet_mask': ('django.db.models.fields.GenericIPAddressField', [], {'default': 'None', 'max_length': '39', 'null': 'True', 'blank': 'True'}), | ||
156 | 152 | 'updated': ('django.db.models.fields.DateTimeField', [], {}) | ||
157 | 153 | }, | ||
158 | 154 | u'maasserver.sshkey': { | ||
159 | 155 | 'Meta': {'unique_together': "((u'user', u'key'),)", 'object_name': 'SSHKey'}, | ||
160 | 156 | 'created': ('django.db.models.fields.DateTimeField', [], {}), | ||
161 | 157 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
162 | 158 | 'key': ('django.db.models.fields.TextField', [], {}), | ||
163 | 159 | 'updated': ('django.db.models.fields.DateTimeField', [], {}), | ||
164 | 160 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) | ||
165 | 161 | }, | ||
166 | 162 | u'maasserver.tag': { | ||
167 | 163 | 'Meta': {'object_name': 'Tag'}, | ||
168 | 164 | 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
169 | 165 | 'created': ('django.db.models.fields.DateTimeField', [], {}), | ||
170 | 166 | 'definition': ('django.db.models.fields.TextField', [], {}), | ||
171 | 167 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
172 | 168 | 'kernel_opts': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), | ||
173 | 169 | 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}), | ||
174 | 170 | 'updated': ('django.db.models.fields.DateTimeField', [], {}) | ||
175 | 171 | }, | ||
176 | 172 | u'maasserver.userprofile': { | ||
177 | 173 | 'Meta': {'object_name': 'UserProfile'}, | ||
178 | 174 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
179 | 175 | 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}) | ||
180 | 176 | }, | ||
181 | 177 | 'piston.consumer': { | ||
182 | 178 | 'Meta': {'object_name': 'Consumer'}, | ||
183 | 179 | 'description': ('django.db.models.fields.TextField', [], {}), | ||
184 | 180 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
185 | 181 | 'key': ('django.db.models.fields.CharField', [], {'max_length': '18'}), | ||
186 | 182 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||
187 | 183 | 'secret': ('django.db.models.fields.CharField', [], {'max_length': '32'}), | ||
188 | 184 | 'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '16'}), | ||
189 | 185 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'consumers'", 'null': 'True', 'to': "orm['auth.User']"}) | ||
190 | 186 | }, | ||
191 | 187 | 'piston.token': { | ||
192 | 188 | 'Meta': {'object_name': 'Token'}, | ||
193 | 189 | 'callback': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), | ||
194 | 190 | 'callback_confirmed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
195 | 191 | 'consumer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['piston.Consumer']"}), | ||
196 | 192 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
197 | 193 | 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
198 | 194 | 'key': ('django.db.models.fields.CharField', [], {'max_length': '18'}), | ||
199 | 195 | 'secret': ('django.db.models.fields.CharField', [], {'max_length': '32'}), | ||
200 | 196 | 'timestamp': ('django.db.models.fields.IntegerField', [], {'default': '1352201505L'}), | ||
201 | 197 | 'token_type': ('django.db.models.fields.IntegerField', [], {}), | ||
202 | 198 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tokens'", 'null': 'True', 'to': "orm['auth.User']"}), | ||
203 | 199 | 'verifier': ('django.db.models.fields.CharField', [], {'max_length': '10'}) | ||
204 | 200 | } | ||
205 | 201 | } | ||
206 | 202 | |||
207 | 203 | complete_apps = ['maasserver'] | ||
208 | 0 | 204 | ||
209 | === modified file 'src/maasserver/models/tag.py' | |||
210 | --- src/maasserver/models/tag.py 2012-10-10 10:25:28 +0000 | |||
211 | +++ src/maasserver/models/tag.py 2012-11-07 10:40:26 +0000 | |||
212 | @@ -89,6 +89,8 @@ | |||
213 | 89 | tag. | 89 | tag. |
214 | 90 | :ivar comment: A long-form description for humans about what this tag is | 90 | :ivar comment: A long-form description for humans about what this tag is |
215 | 91 | trying to accomplish. | 91 | trying to accomplish. |
216 | 92 | :ivar kernel_opts: Optional kernel command-line parameters string to be | ||
217 | 93 | used in the PXE config for nodes with this tags. | ||
218 | 92 | :ivar objects: The :class:`TagManager`. | 94 | :ivar objects: The :class:`TagManager`. |
219 | 93 | """ | 95 | """ |
220 | 94 | 96 | ||
221 | @@ -101,6 +103,7 @@ | |||
222 | 101 | validators=[RegexValidator(_tag_name_regex)]) | 103 | validators=[RegexValidator(_tag_name_regex)]) |
223 | 102 | definition = TextField() | 104 | definition = TextField() |
224 | 103 | comment = TextField(blank=True) | 105 | comment = TextField(blank=True) |
225 | 106 | kernel_opts = TextField(blank=True, null=True) | ||
226 | 104 | 107 | ||
227 | 105 | objects = TagManager() | 108 | objects = TagManager() |
228 | 106 | 109 | ||
229 | 107 | 110 | ||
230 | === modified file 'src/maasserver/testing/factory.py' | |||
231 | --- src/maasserver/testing/factory.py 2012-10-30 10:25:24 +0000 | |||
232 | +++ src/maasserver/testing/factory.py 2012-11-07 10:40:26 +0000 | |||
233 | @@ -251,14 +251,15 @@ | |||
234 | 251 | key.save() | 251 | key.save() |
235 | 252 | return key | 252 | return key |
236 | 253 | 253 | ||
239 | 254 | def make_tag(self, name=None, definition=None, comment='', created=None, | 254 | def make_tag(self, name=None, definition=None, comment='', |
240 | 255 | updated=None): | 255 | kernel_opts=None, created=None, updated=None): |
241 | 256 | if name is None: | 256 | if name is None: |
242 | 257 | name = self.make_name('tag') | 257 | name = self.make_name('tag') |
243 | 258 | if definition is None: | 258 | if definition is None: |
244 | 259 | # Is there a 'node' in this xml? | 259 | # Is there a 'node' in this xml? |
245 | 260 | definition = '//node' | 260 | definition = '//node' |
247 | 261 | tag = Tag(name=name, definition=definition, comment=comment) | 261 | tag = Tag(name=name, definition=definition, comment=comment, |
248 | 262 | kernel_opts=kernel_opts) | ||
249 | 262 | self._save_node_unchecked(tag) | 263 | self._save_node_unchecked(tag) |
250 | 263 | # Update the 'updated'/'created' fields with a call to 'update' | 264 | # Update the 'updated'/'created' fields with a call to 'update' |
251 | 264 | # preventing a call to save() from overriding the values. | 265 | # preventing a call to save() from overriding the values. |
252 | 265 | 266 | ||
253 | === modified file 'src/maasserver/tests/test_tag.py' | |||
254 | --- src/maasserver/tests/test_tag.py 2012-10-10 09:41:48 +0000 | |||
255 | +++ src/maasserver/tests/test_tag.py 2012-11-07 10:40:26 +0000 | |||
256 | @@ -29,6 +29,16 @@ | |||
257 | 29 | self.assertEqual('tag-name', tag.name) | 29 | self.assertEqual('tag-name', tag.name) |
258 | 30 | self.assertEqual('//node[@id=display]', tag.definition) | 30 | self.assertEqual('//node[@id=display]', tag.definition) |
259 | 31 | self.assertEqual('', tag.comment) | 31 | self.assertEqual('', tag.comment) |
260 | 32 | self.assertIs(None, tag.kernel_opts) | ||
261 | 33 | self.assertIsNot(None, tag.updated) | ||
262 | 34 | self.assertIsNot(None, tag.created) | ||
263 | 35 | |||
264 | 36 | def test_factory_make_tag_with_hardware_details(self): | ||
265 | 37 | tag = factory.make_tag('a-tag', 'true', kernel_opts="console=ttyS0") | ||
266 | 38 | self.assertEqual('a-tag', tag.name) | ||
267 | 39 | self.assertEqual('true', tag.definition) | ||
268 | 40 | self.assertEqual('', tag.comment) | ||
269 | 41 | self.assertEqual('console=ttyS0', tag.kernel_opts) | ||
270 | 32 | self.assertIsNot(None, tag.updated) | 42 | self.assertIsNot(None, tag.updated) |
271 | 33 | self.assertIsNot(None, tag.created) | 43 | self.assertIsNot(None, tag.created) |
272 | 34 | 44 |
The actual change seems good. But I'm thinking there should be a docstring somewhere that needs updating as well. And maybe some sort of test about setting & getting the value?