-
Notifications
You must be signed in to change notification settings - Fork 148
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
autoinstall! #625
autoinstall! #625
Conversation
To test this, try something like:
|
6dd86d1
to
8bb18a1
Compare
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 don't see anything that would affect existing interactive installs. I've left some review comments for the autoinstall bits.
from curtin.config import merge_config | ||
|
||
|
||
def merge_autoinstall_configs(source_paths, target_path): |
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 order of the source_paths controls what the final config will look like due to how merge_config works with dictionaries and lists. I suggest documenting that behavior. Additionally it's important to retain the order of the configs, or the order of the expected precedence of autoinstall file locations. For example, would you expect the initrd-autoinstall.yaml to override other paths?
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.
Yes, we need to make some decisions and document how all this works. I'm going to post to discource, probably tomorrow, about this.
for path in source_paths: | ||
with open(path) as fp: | ||
c = yaml.safe_load(fp) | ||
merge_config(config, 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.
I would include a comment or a value in the merged config indicating the source yamls and the order of their merging so that when debugging a resulting autoinstall we can sort out how a value was modified after merging.
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.
Good idea.
self.load_autoinstall_data( | ||
app.autoinstall_config.get( | ||
self.autoinstall_key, | ||
self.autoinstall_default)) |
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.
Pre-populating the autoinstall_config dictionary with keys which may be None (due to the default value being set) means that checking for presence of a key w.r.t to whether subiquity uses a default value or the user provided can be difficult.
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.
Yes, there are a few different ways of looking at this. This API seems reasonably ok. load_install_data has access to self.app.autoinstall_config if it needs it...
self.cmds = data | ||
|
||
async def run(self): | ||
for i, cmd in enumerate(self.cmds): |
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 seems to expect that self.cmds will return a list like object; if an autoinstall config does not have any early commands, wont the load_autoinstall_data from the base controller set this to a None which would fail to enumerate?
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.
"autoinstall_default = []" handles this
class CmdListController(NoUIController): | ||
|
||
autoinstall_default = [] | ||
cmds = () |
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.
Should this be a list instead of tuple?
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.
perhaps autoinstall_default should be ()? I don't think it matters a great deal although having them different is indeed odd.
subiquity/controllers/mirror.py
Outdated
if data is None: | ||
return | ||
self.ai_data = data | ||
if 'mirror' in data: |
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 check fails if users don't provide 'mirror' info in the autoinstall, as the loader sets data['mirror'] = None.
Either the loader shouldn't set default value to None so you can do key checks like this, or this needs to be
if data['mirror'] is not None:
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 don't understand your comment but I don't think it is correct.
This all needs to change anyway because I want to redo how mirrors are described, see #626 and https://wiki.ubuntu.com/FoundationsTeam/AutomatedServerInstalls/ConfigReference?action=diff&rev2=40&rev1=38
self.active = self.interactive() | ||
|
||
def load_autoinstall_data(self, data): | ||
if data is not None and data.get('refresh'): |
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.
data.get('refresh-installer') or 'refresh' ?
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.
'refresh'. The format of the yaml is:
refresh-installer:
refresh: yes
self.model.authorized_keys = self.autoinstall_data.get( | ||
'authorized-keys', []) | ||
self.model.pwauth = self.autoinstall_data.get( | ||
'allow-pw', not self.model.authorized_keys) |
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.
Policy decision? Is this documented that one cannot set password and import ssh keys?
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.
Uh, the idea is only that the default of allow-pw is False iff a key is supplied. And I think that's what this code does but I've been thinking about udev too much to be sure.
@@ -25,7 +25,11 @@ | |||
|
|||
class WelcomeController(SubiquityController): | |||
|
|||
model_name = "locale" | |||
autoinstall_key = model_name = "locale" | |||
autoinstall_default = 'en_US.UTF-8' |
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.
C.UTF-8 is the default in cloud-images;
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.
Hmm. subiquity is more targeted towards humans, but maybe not for autoinstall cases. Easy to change later in any case.
realname: '' | ||
username: ubuntu | ||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' | ||
hostname: ubuntu |
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.
Does this example include all possible keys? We might want to expand this with comments or examples of other accepted autoinstall keys.
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 it certainly does not, and yes providing a more complete example would make sense.
Thanks for the review. I don't plan to make many changes to this branch in response to them, but I'll keep them in mind for later. I'll probably make some tweaks and merge this tomorrow. |
8bb18a1
to
b9c56c7
Compare
b9c56c7
to
db9762b
Compare
The branch implements the first cut of autoinstall for subiquity. What is there:
What is not there:
But I have plans for all of these things :)