[Cloud-init-dev] [Merge] ~raharper/cloud-init:snapuser-create into cloud-init:master

2016-10-19 Thread Ryan Harper
The proposal to merge ~raharper/cloud-init:snapuser-create into 
cloud-init:master has been updated.

Description changed to:

Add support for snap create-user on Ubuntu Core images

Ubuntu Core images use the `snap create-user` to add users to a Ubuntu
Core system.  Add support for creating snap users by added a key to
the users dictionary:

users:
  - name: bob
snapuser: b...@bobcom.io

Or via the 'snappy' dictionary:

snappy:
  email: b...@bobcom.io
  
These methods will contact the Ubuntu SSO infrastructure to request
user information (including public ssh keys if present) for creating
the user.

Users may also create a snap user without contacting the SSO by
providing a 'system-user' assertion by importing them into snapd.

snappy:
  email: b...@bobcom.io
  known: true
  assertions:
  - |


Additionally, Ubuntu Core systems have a read-only /etc/passwd such that
the normal useradd/groupadd commands do not function without an additional
flag, '--extrausers', which redirects the pwd to /var/lib/extrausers.

Move the system_is_snappy() check from cc_snappy module to util for
re-use and then update the Distro class to append '--extrausers' if
the system is Ubuntu Core.





For more details, see:
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/304700
-- 
Your team cloud init development team is requested to review the proposed merge 
of ~raharper/cloud-init:snapuser-create into cloud-init:master.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


Re: [Cloud-init-dev] [Merge] ~raharper/cloud-init:snapuser-create into cloud-init:master

2016-10-19 Thread Ryan Harper
On Wed, Oct 19, 2016 at 8:52 AM, Ryan Harper 
wrote:

>
>
> On Wed, Oct 19, 2016 at 8:04 AM, Scott Moser  wrote:
>
>> over all, looks good.
>> you dont have to clean up the handle, but if you see easy way to do that
>> that'd be nice.
>>
>> is the snappy path now valid on non-snappy system ? (ubuntu server with
>> 'snap' support).
>>
>
> It is, and util.is_system_snappy() I think passes where it works; I'll
> confirm.
>


is_system_snappy is looking for 'all-snap' style images;  so snaps on
classic don't
respond.  We'd need to design something for validating that it works on
snaps on classic
setups.

One key difference is that all-snap systems have non-writable /etc ; where
as snapd on classic doesn't.  If we added classic systems to the
is_system_snappy check, then users would get added
to /var/lib/extrausers instead of /etc;  I think that's non-optimal and
introduces changes to existing
behavior.

Ryan

-- 
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/304700
Your team cloud init development team is requested to review the proposed merge 
of ~raharper/cloud-init:snapuser-create into cloud-init:master.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


Re: [Cloud-init-dev] [Merge] ~raharper/cloud-init:snapuser-create into cloud-init:master

2016-10-13 Thread Ryan Harper
Thanks for looking at the code!

Diff comments:

> diff --git a/cloudinit/config/cc_snap_config.py 
> b/cloudinit/config/cc_snap_config.py
> new file mode 100644
> index 000..667b9c6
> --- /dev/null
> +++ b/cloudinit/config/cc_snap_config.py
> @@ -0,0 +1,177 @@
> +# vi: ts=4 expandtab
> +#
> +#Copyright (C) 2016 Canonical Ltd.
> +#
> +#Author: Ryan Harper 
> +#
> +#This program is free software: you can redistribute it and/or modify
> +#it under the terms of the GNU General Public License version 3, as
> +#published by the Free Software Foundation.
> +#
> +#This program is distributed in the hope that it will be useful,
> +#but WITHOUT ANY WARRANTY; without even the implied warranty of
> +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +#GNU General Public License for more details.
> +#
> +#You should have received a copy of the GNU General Public License
> +#along with this program.  If not, see .
> +
> +"""
> +Snappy
> +--
> +**Summary:** snap_config modules allows configuration of snapd.
> +
> +This module uses the same ``snappy`` namespace for configuration but
> +acts only only a subset of the configuration.
> +
> +If ``assertions`` is set and the user has included a list of assertions
> +then cloud-init will collect the assertions into a single assertion file
> +and invoke ``snap ack `` which will attempt
> +to load the provided assertions into the snapd assertion database.
> +
> +If ``email`` is set, this value is used to create an authorized user for
> +contacting and installing snaps from the Ubuntu Store.  This is done by
> +calling ``snap create-user`` command.
> +
> +If ``known`` is set to True, then it is expected the user also included
> +an assertion of type ``system-user``.  When ``snap create-user`` is called
> +cloud-init will append '--known' flag which instructs snapd to look for
> +a system-user assertion with the details.  If ``known`` is not set, then
> +``snap create-user`` will contact the Ubuntu SSO for validating and importing
> +a system-user for the instance.
> +
> +.. note::
> +If the system is already managed, then cloud-init will not attempt to
> +create a system-user.
> +
> +**Internal name:** ``cc_snap_config``
> +
> +**Module frequency:** per instance
> +
> +**Supported distros:** ubuntu
> +
> +**Config keys**::
> +
> +#cloud-config
> +snappy:
> +assertions:
> +- |
> +
> +- |
> +
> +email: u...@user.org
> +known: true
> +
> +"""
> +
> +from cloudinit import log as logging
> +from cloudinit.settings import PER_INSTANCE
> +from cloudinit import util
> +
> +LOG = logging.getLogger(__name__)

AIUI, modules should all change to the above;  note we're importing logging 
from cloudinit.log; which is a nice wrapper for initializing logging 
specifically for cloud-init and the __name__ allows proper naming of the output.

> +
> +frequency = PER_INSTANCE
> +SNAPPY_CMD = "snap"
> +ASSERTIONS_FILE = "/var/lib/cloud/instance/snapd.assertions"
> +
> +distros = ['ubuntu']
> +
> +
> +def set_snappy_command():
> +global SNAPPY_CMD
> +if util.which("snappy-go"):
> +SNAPPY_CMD = "snappy-go"
> +elif util.which("snappy"):
> +SNAPPY_CMD = "snappy"
> +else:
> +SNAPPY_CMD = "snap"
> +LOG.debug("snappy command is '%s'", SNAPPY_CMD)
> +
> +
> +"""
> +snappy:
> +  assertions:
> +  - |
> +  
> +  - |
> +  
> +  email: f...@foo.io
> +  known: true
> +"""
> +
> +
> +def add_assertions(assertions):
> +""" Import list of assertions by concatenating each
> +assertion into a string separated by a '\n'.
> +Write this string to a instance file and
> +then invoke `snap ack /path/to/file`
> +and check for errors.
> +
> +If snap exits 0, then all assertions are imported.
> +"""
> +if not assertions:

On one hand, I'd like to avoid exploding cloudinit.util with what are proper 
utility functions, but until another module needs to use the add_assertions I'd 
leave it here.  I think it's reasonable to include the checks here in-case of 
re-use.  I'll defer to Scott or Josh on this one.

> +assertions = []
> +
> +if not isinstance(assertions, list):
> +raise ValueError('assertion parameter was not a list: %s', 
> assertions)
> +
> +snap_cmd = [SNAPPY_CMD, 'ack']
> +combined = "\n".join(assertions)
> +if len(combined) == 0:
> +raise ValueError("Assertion list is empty")
> +
> +for asrt in assertions:
> +LOG.debug('Acking: %s', asrt.split('\n')[0:2])
> +
> +util.write_file(ASSERTIONS_FILE, combined.encode('utf-8'))

write_file already will bubble up a ProcessExecutionError message; and there's 
nothing more for us to do AFAIK.
Same with snap ack;  there's no recovery.

> +util.subp(snap_cmd + [ASSERTIONS_FILE], capture=True)
> +
> +
> +def handle(name, cfg, cloud,