Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

Add support for loading plugin and creating task from remote locations #1201

Open
andrzej-k opened this issue Sep 13, 2016 · 10 comments
Open

Comments

@andrzej-k
Copy link
Contributor

andrzej-k commented Sep 13, 2016

Currently both snapctl plugin load and snapctl task create require passing file path to either a plugin or a task. Sometimes it may not be feasible (or is cumbersome) and having possibility to call plugin load and task create like this may be useful:

  • snapctl plugin load http://snap.ci.snap-telemetry.io/plugins/snap-plugin-publisher-file/master/latest/linux/x86_64/snap-plugin-publisher-file
  • snapctl task create -u http://snap.ci.snap-telemetry.io/tasks/some-example-task.json (-u standing for url).

REST API should also support this.

@brharrington
Copy link

Being able to reference a common url for the task seems like it would be convenient.

The plugin loading would make me a bit nervous and I would want a way to disable it. Pulling in executables from an arbitrary url, in particular via the REST API, means we would need to be much more careful about what can interact with and access the REST endpoint. At the very least, I think #286 becomes critical if you support this.

In general for our setup we would typically want the consumption use-cases like creating tasks to be fairly open so developers can get the data they need with minimal hassle. However, we would likely restrict some of the management use-cases. Even if you ignore security concerns like an attacker, pulling in and running arbitrary binary on the instance seems like an easy way for a developer to accidentally break the app or cluster and cause an outage.

@IRCody
Copy link
Contributor

IRCody commented Sep 14, 2016

Currently both snapctl plugin load and snapctl task create require passing file path to either a plugin or a task. Sometimes it may not be feasible (or is cumbersome) and having possibility to call plugin load and task create like this may be useful:

snapctl plugin load http://snap.ci.snap-telemetry.io/plugins/snap-plugin-publisher-file/master/latest/linux/x86_64/snap-plugin-publisher-file
snapctl task create -u http://snap.ci.snap-telemetry.io/tasks/some-example-task.json (-u standing for url).

I'm not sure I agree that requiring someone using snapctl/api to have a plugin/task file locally is cumbersome or infeasible. Can you give some reasons/examples of why/when that would be the case?

REST API should also support this.

This seems like a larger and separate issue.

@edhenry
Copy link

edhenry commented Sep 14, 2016

@IRCody In highly heterogeneous environments this can prove to be cumbersome depending on the deployment tooling one uses. I'll give an example on some of the early work I was using SNAP for.

Nested deployment for dev/test/prod environment can make things a bit challenging. See image below.

image

I was automating the entire process using Ansible. This required me to have a copy of the task definition local to the playbook directory, which then had to be copied to VM that was being provisioned, and subsequently copied to the container that the SNAP daemon would run in.

It would be useful to be able to have a repository of task files that I could point the SNAP daemon at.

Thoughts?

@IRCody
Copy link
Contributor

IRCody commented Sep 15, 2016

@edhenry: Thank you for taking the time to respond with an example.

I was automating the entire process using Ansible. This required me to have a copy of the task definition local to the playbook directory, which then had to be copied to VM that was being provisioned, and subsequently copied to the container that the SNAP daemon would run in.

The task/plugin only needs to be local to the snapctl instance, not the daemon. snapctl can connect to remote daemons via the -u flag. It will send files/tasks via the API to the daemon. Is doing snapctl calls to the appropriate daemon as cumbersome as calling copy multiple layers down?

It would be useful to be able to have a repository of task files that I could point the SNAP daemon at.

This seems like a different ask than what is above. Can you explain what you mean by "a repository of task files"?

@edhenry
Copy link

edhenry commented Sep 15, 2016

The task/plugin only needs to be local to the snapctl instance, not the daemon. snapctl can connect to remote daemons via the -u flag. It will send files/tasks via the API to the daemon. Is doing snapctl calls to the appropriate daemon as cumbersome as calling copy multiple layers down?

Cool, that was my misunderstanding of the functionality between the snap daemon and snapctl. From the use case I'd presented above, that does address the copying of the file multiple levels deep.

This seems like a different ask than what is above. Can you explain what you mean by "a repository of task files"?

Sorry for the lack of clarity. I was speaking more from an implementation perspective, I think.

I was thinking in the same vein of how something like a schema registry works in the world of Kafka/Avro. Being able to centrally store the schema definitions, or in the snap case task definitions / plugins, it might be useful if snapctl were able to call these objects from a remote repository. Rather than having the task / plugin files littered throughout whatever orchestration system you may be dealing with (Puppet, Chef, Ansible, Salt, etc.)

Does this make sense?

@andrzej-k
Copy link
Contributor Author

andrzej-k commented Sep 15, 2016

@IRCody my use case looks like this: I have a snap running as a pod in Kubernetes. Both snapd and snapctl are inside the container.

Now, for example, in order to load a new plugin I must first download it (and depending on cluster type I must first find a partition to which I can write):
curl -O http://snap.ci.snap-telemetry.io/plugins/snap-plugin-publisher-file/master/latest/linux/x86_64/snap-plugin-publisher-file

then I must copy plugin binary inside a container, like this (bit hacky): kubectl exec -i snap-e6rtb --namespace=kube-system -- /bin/bash -c 'cat > /tmp/snap-plugin-publisher-file' < snap-plugin-publisher-file

and then I can load a plugin like this: kubectl exec snap-e6rtb /usr/local/bin/snapctl plugin load /tmp/snap-plugin-publisher-file --namespace=kube-system

Alternatively I could attach to docker container with snapd and snapctl, then download and load plugin there, but this also seems too complicated.

If instead of all those steps I could use kubectl exec snap-e6rtb /usr/local/bin/snapctl plugin load http://snap.ci.snap-telemetry.io/plugins/snap-plugin-publisher-file/master/latest/linux/x86_64/snap-plugin-publisher-file then it would be great simplification.

@IRCody
Copy link
Contributor

IRCody commented Sep 15, 2016

I was thinking in the same vein of how something like a schema registry works in the world of Kafka/Avro. Being able to centrally store the schema definitions, or in the snap case task definitions / plugins, it might be useful if snapctl were able to call these objects from a remote repository. Rather than having the task / plugin files littered throughout whatever orchestration system you may be dealing with (Puppet, Chef, Ansible, Salt, etc.)

Does this make sense?

@edhenry: I'm not familiar with kafka/avro but it seems like adding the ability to point snapctl to remote url's as a convenience might make sense, especially if a lot of people think it would be helpful.

This is a little different than having a central registry that can be listed/etc. Is the registry more what you were thinking would be good?

@IRCody my use case looks like this: I have a snap running as a pod in Kubernetes. Both snapd and snapctl are inside the container.

Now, for example, in order to load a new plugin I must first download it (and depending on cluster type I must first find a partition to which I can write):
curl -O http://snap.ci.snap-telemetry.io/plugins/snap-plugin-publisher-file/master/latest/linux/x86_64/snap-plugin-publisher-file

This part I understand, but the change being asked for basically amounts to snapctl doing the curl call (or equivalent) before sending that file to snapd? I guess it would hold the plugin in memory instead of writing to disk?

then I must copy plugin binary inside a container, like this (bit hacky): kubectl exec -i snap-e6rtb --namespace=kube-system -- /bin/bash -c 'cat > /tmp/snap-plugin-publisher-file' < snap-plugin-publisher-file

If you can access snapd http-api then this step is not required since snapctl can specify a remote snapd instance.

and then I can load a plugin like this: kubectl exec snap-e6rtb /usr/local/bin/snapctl plugin load /tmp/snap-plugin-publisher-file --namespace=kube-system

Alternatively I could attach to docker container with snapd and snapctl, then download and load plugin there, but this also seems too complicated.

If instead of all those steps I could use kubectl exec snap-e6rtb /usr/local/bin/snapctl plugin load http://snap.ci.snap-telemetry.io/plugins/snap-plugin-publisher-file/master/latest/linux/x86_64/snap-plugin-publisher-file then it would be great simplification.

@andrzej-k: You can see my reply to @edhenry above about adding url option to snapctl.

It also seems to me that all of these requested changes are limited to snapctl changes but in the original issue you mentioned supporting it in the rest api also. Can you expand on that?

@andrzej-k
Copy link
Contributor Author

@IRCody Regarding REST API - according to the documentation (https://github.com/intelsdi-x/snap/blob/master/docs/REST_API.md#plugin-apis-and-examples) loading plugin is done like this:

POST /v1/plugins: Load a plugin

Example Request

curl -X POST -F plugin=@build/plugin/snap-collector-mock http://localhost:8181/v1/plugins

So, if anyone would like to use REST API instead of snapctl then REST API should also support this feature.

@IRCody
Copy link
Contributor

IRCody commented Sep 16, 2016

It seems like if someone is already scripting the API calls they should be able to deal with getting the binary to the API. Do we really want to complicate the API implementation when you can use curl already to do this?

curl http://snap.ci.snap-telemetry.io/plugins/snap-plugin-publisher-file/master/latest/darwin/x86_64/snap-plugin-publisher-file | curl -X POST -F "plugin=@-;filename=snap-plugin-publisher-file" http://localhost:8181/v1/plugins

@andrzej-k
Copy link
Contributor Author

@IRCody I don't mind complicating implementation to simplify the (user) interface ;)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants