Skip to content

Feature: Provisioning (ix-iocage-plugin) #426

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

Merged
merged 28 commits into from
Jul 28, 2018
Merged

Conversation

gronke
Copy link
Member

@gronke gronke commented Jul 7, 2018

closes #1

  • introduces nested jail config properties
  • embeds provisioning methods:
    • ix for ix-iocage-plugins
    • ansible as runner for ansible playbooks stored in a remote git repository will be implemented in another PR

ix-iocage-plugin install stages

When a jail is configured with provisioning.method=ix, the following will happen when running the provisioning command with provisioning.source=jenkins:

  1. Download https://github.com/freenas/iocage-ix-plugins/blob/master/jenkins.json
  2. Read artifacts from jenkins.json
  3. Clone artifacts repo URL to a child dataset of the jail
  4. Start jail with artifacts mounted
  5. Install list of pkgs in jenkinsk.json within the jail
  6. Run post_install.sh from the artifacts folder if it exists

CLI Syntax

ioc create plextemplate \
    provisioning.method=ix \
    provisioning.source=plexmediaserver \
    template=yes

# run provisioner
ioc provision plextemplate

# create jail from the provisioned template
ioc create -t plextemplate plexjail

# configure network and run plexjail
# ...

Update: Providing a temporary network connecting is no longer required. The ix-iocage-plugin now installs packages via iocage.lib.Pkg which does not require internet connections within a jail.

@gronke gronke force-pushed the feature/provisioning branch 13 times, most recently from dfe52be to 60d2e1a Compare July 11, 2018 18:13
@gronke gronke requested a review from skarekrow July 11, 2018 18:15
@gronke
Copy link
Member Author

gronke commented Jul 11, 2018

The ioc provision option can be set multiple times and allows to temporary override jail configuration properties. When provisioning a template this can be used to leave the configuration untouched while installing packages.

libiocage does not automatically configure the network when provisioning jails or templates because they are potentially untrusted.

yield event

try:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do a try: finally block when any of the try's above the finally statement would end execution. I think you can drop a whole nested level here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would, but instead each nested try block would require the same fallback. This top-level try/finally makes sure that the code in finally is executed independently of the success of its internal steps.

yield packageInstallEvent.begin()
try:
stdout, stderr, returncode = self.jail.exec(
["pkg", "install", "-yield"] + pkg_packages,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pkg install -yield?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hahahaha, damn you auto-correct. 😆(Have no other explanation)
Of course this must be just -y.

zfs.delete_dataset_recursive(dataset)
except libzfs.ZFSException:
except libzfs.ZFSException as e:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You aren't using e, you can drop that

@@ -375,6 +374,7 @@ def provisioner(self) -> 'iocage.lib.Provisioning.prototype.Provisioner':
except AttributeError:
pass

import iocage.lib.Provisioning
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you remove the top level import? Recursion issues?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes Python does not like circular dependencies when loading them at import time. And In long term I'd like to reduce the memory footprint and startup time by lazy-loading specific features. There is a relatively small penalty for re-importing dependencies, but this would only happen once per jail if the provisioner is used.

yield event
if isinstance(event, iocage.lib.events.JailCommandExecution):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an additional line with \ as there isn't anything else to be done if the if statement below isn't True

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get it. Could you please further explain or leave a code snippet?

@gronke gronke force-pushed the feature/provisioning branch 2 times, most recently from 1a9271e to c20d993 Compare July 14, 2018 09:33
@gronke
Copy link
Member Author

gronke commented Jul 14, 2018

@william-gr we've talked about ix-iocage-plugin support at BSDCan. Finally here is the implementation to install the plugins using the provision command (or Jail method).

@skarekrow you have pointed out some plugin features that were not implemented in this branch. In my opinion another application layer than libiocage should implement UI specific features such as printing administration URLs. My recommendation here is to use custom jail config properties to store the desired port and applying it (or the plugins default) during jail start. At jail start you have such properties stored in the environment variables.

Can you spot any missing install steps besides the UI part, that seems FreeNAS specific to me.

@gronke gronke changed the title Feature: Provisioning Feature: Provisioning (ix-iocage-plugin) Jul 14, 2018
@gronke gronke force-pushed the feature/provisioning branch from c20d993 to b406f6b Compare July 14, 2018 11:20
@gronke gronke force-pushed the feature/provisioning branch from b406f6b to 001ac8e Compare July 15, 2018 23:00
@gronke
Copy link
Member Author

gronke commented Jul 19, 2018

This feature can be enhanced after #435 is merged, so that no network is required in jails for package installation. Most of the ix-iocage-plugins will then not require network to get provisioning.

Copy link
Collaborator

@igalic igalic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments / output strings are wrong here…

and then there's a few bits that i don't quite understand!

__rootcmd__ = True


@click.command(name="start", help="Trigger provisionong of jails.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: provisioning

"--option", "-o",
"temporary_config_override",
multiple=True,
help="Temporary override jail config options"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temporarily

jails: typing.Tuple[str, ...],
temporary_config_override: typing.Tuple[str, ...]
) -> None:
"""Start one or many jails."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong documentation

failed_jails.append(jail)
continue

changed_jails.append(jail)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we really tell here if a jail was changed (again)? or if an idempotent operation did, in fact, nothing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, at the current time plugins do not signal whether they applied changes or not. We only know that the provisioner ran and did not error.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

puppet returns 1 on success, 0 on idempotent success, and 2 on failure

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we can listen for the return code in the puppet provisioner. The ix-plugins do not differentiate, so that there is no need yet to respond here now.

"--option", "-o",
"temporary_config_override",
multiple=True,
help="Temporary override jail config options"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"temporarily", or else, make it "for jail config options"

key: str,
data: typing.Dict[str, typing.Any]
) -> None:
if "." in key:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mumbles something about nested json

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is about CLI interaction. The internal storage occurs as nested JSON - just the property may be accessed via dot notation.

try:
if os.path.isfile(f"{plugin_dataset.mountpoint}/post_install.sh"):
stdout, stderr, returncode = self.jail.exec(
["/.ix-plugin/post_install.sh"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this file guaranteed to be executable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was created by ourselves. Yes, we can assume that this file is existing and executable.

@@ -441,6 +441,7 @@ class HardenedBSD(Updater):

@property
def _update_command(self) -> typing.List[str]:
return ["sleep", "2000"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😮 Good question. Will be removed!

@gronke gronke force-pushed the feature/provisioning branch 2 times, most recently from c8f133d to a630e5c Compare July 22, 2018 06:08
gronke added 26 commits July 27, 2018 22:51
fixes an issue deleting properties from jails
instead of returning provisioning that points to a dict structure provisioning.source and its siblings are returned
@gronke gronke force-pushed the feature/provisioning branch from 40bb603 to 0fa7c34 Compare July 27, 2018 20:51
@gronke
Copy link
Member Author

gronke commented Jul 28, 2018

This basic implementation of ix-iocage-plugins also lays the groundwork for libiocage provisioning.

As discussed offline with @skarekrow there are changes to the ix-iocage-plugin standard planned aiming for:

  • Compatibility with different OS versions
  • Idempotence

Now is the right time to start an open discussion around this topic, so that we end up with a solution that shares interfaces with Ansible and Puppet provisioning.

With support for provisioning of current ix-iocage-plugins and the base implementation for generalised provisioning in this branch is ready to get merged at this point.

@gronke gronke merged commit 8e5e924 into master Jul 28, 2018
@gronke gronke deleted the feature/provisioning branch July 28, 2018 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature: Plugins
3 participants