Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

[WIP] Add Application plugin and Event repeater #474

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

YujiOshima
Copy link
Contributor

This PR add concept of application plugin. ( Related #435 )
Infrakit 'app' is an application that can talk to the infrakit plugins using the plugin api but itself listens on a port and offers a REST api for operations.
An example of App is Event repeater.
It is subscribe event plugin and publish the messages to other protocol brocker(e.g. mqtt).

** Get Start

*** Prepare
Start event plugin and mqtt broker

$ ./build/infrakit-event-time
$ docker run -it --rm -p 1883:1883 eclipse-mosquitto

*** Run event repeater

$ ./build/infrakit-application-repeater -h
Event Repeater Application plugin

Usage:
  ./build/infrakit-application-repeater [flags]

Flags:
      --allowall              Allow all event from source and repeat the event to sink as same topic name. default: false
      --log int               Logging level. 0 is least verbose. Max is 5 (default 4)
      --name string           Application name to advertise for discovery (default "app-event-repeater")
      --sink string           Event sink address. default: localhost:1883 (default "localhost:1883")
      --sinkprotocol string   Event sink protocol. Now only mqtt and stderr is implemented. (default "mqtt")
      --source string         Event sourve address. (default "event-plugin")

$ ./build/infrakit-application-repeater --source ~/.infrakit/plugins/event-time --sink tcp://localhost:1883

Now your app connected to event plugin and mqtt broker.
If you set —-allowall, your app subscribe ‘.’ Topic from event and publish all events to broker with original topic.
You can specify repeat topics with infrakit command like below.

$ ./build/infrakit application update -h


___  ________   ________ ________  ________  ___  __    ___  _________
|\  \|\   ___  \|\  _____\\   __  \|\   __  \|\  \|\  \ |\  \|\___   ___\
\ \  \ \  \\ \  \ \  \__/\ \  \|\  \ \  \|\  \ \  \/  /|\ \  \|___ \  \_|
 \ \  \ \  \\ \  \ \   __\\ \   _  _\ \   __  \ \   ___  \ \  \   \ \  \
  \ \  \ \  \\ \  \ \  \_| \ \  \\  \\ \  \ \  \ \  \\ \  \ \  \   \ \  \
   \ \__\ \__\\ \__\ \__\   \ \__\\ _\\ \__\ \__\ \__\\ \__\ \__\   \ \__\
    \|__|\|__| \|__|\|__|    \|__|\|__|\|__|\|__|\|__| \|__|\|__|    \|__|


Update application's resouce

Usage:
  ./build/infrakit application update [flags]

Flags:
      --op int            update operation 1: Add, 2: Delete, 3: Update, 4: Read(default) (default 3)
      --resource string   target resource
      --value string      update value

Global Flags:
  -H, --host stringSlice        host list. Default is local sockets
      --httptest.serve string   if non-empty, httptest.NewServer serves on this address and blocks
      --log int                 log level (default 4)
      --log-caller              include caller function (default true)
      --log-format string       log format: logfmt|term|json (default "term")
      --log-stack               include caller stack
      --log-stdout              log to stdout
      --name string             Name of plugin
$ ./build/infrakit application update --name app-event-repeater --op 1 --resource event --value '[{"sourcetopic":"timer/sec/1","sinktopic":"/time/1s"},{"sourcetopic":"timer/msec/500","sinktopic":"/time/500m"}]'

Events are described json style.
Then you can delete registerd event.

./build/infrakit application update --name app-event-repeater --op 2 --resource event --value '[{"sourcetopic":"timer/sec/1”}]’

@YujiOshima
Copy link
Contributor Author

YujiOshima commented Apr 11, 2017

@chungers I want to show you my image with a working code. Of cource I will add tests and documents!

@codecov
Copy link

codecov bot commented Apr 11, 2017

Codecov Report

Merging #474 into master will increase coverage by 0.78%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #474      +/-   ##
==========================================
+ Coverage   56.56%   57.35%   +0.78%     
==========================================
  Files          57       57              
  Lines        3928     3782     -146     
==========================================
- Hits         2222     2169      -53     
+ Misses       1420     1334      -86     
+ Partials      286      279       -7
Impacted Files Coverage Δ
pkg/template/template.go 70.55% <0%> (-2.18%) ⬇️
pkg/cli/remote/remote.go 60% <0%> (-0.98%) ⬇️
examples/instance/terraform/plugin.go 61.83% <0%> (-0.54%) ⬇️
pkg/rpc/mux/reverse_proxy.go 39.43% <0%> (+0.97%) ⬆️
pkg/template/funcs.go 64.41% <0%> (+3.09%) ⬆️
pkg/plugin/instance/libvirt/instance.go 58.82% <0%> (+10.15%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2218fc7...91c6fe8. Read the comment docs.

@chungers
Copy link
Contributor

@YujiOshima - nice work!

Can you add some docs on the use of MQTT? Also let's add some tests...

There's a infrakit util subcommand that is used to start some useful daemons like the mux proxy (for remote client) and a fileserver (for serving config files/templates during development). Maybe we should just add a subcommand under util for this? Like infrakit util event-repeater and infrakit util event-repeater update?

UPDATE
// GET resources
GET
)
Copy link
Contributor

@chungers chungers Apr 11, 2017

Choose a reason for hiding this comment

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

A few comments:

  1. This SPI is pretty generic... are you intending for this to be a way to do generic CRUD operations on objects? This makes me think about TPR in k8s: https://kubernetes.io/docs/concepts/ecosystem/thirdpartyresource/

  2. What are objects that we are doing CRUD operations on? Do you mean something like a group Spec or an instance Spec or something that maps to our plugin objects? For example, if I wanted to let a developer write an application that can control its own node scaling, can we expose the Group spec as an object and let the user call this API to update the Group spec (e.g. changing the number of nodes)?

  3. I think this should be a RESTful API listening on a port and not another JSON-RPC plugin interface. This is so that this becomes a general API (and not an SPI) which can be easily consumed by any application. So you could deploy a web application that will automatically scale up and down the number of nodes and do rolling update when the application itself detects a new version is available. Make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

are you intending for this to be a way to do generic CRUD operations on objects?

Yes. Since application has not been defined for a specific purpose, we think that it needs a general interface.

What are objects that we are doing CRUD operations on?

Although it is sufficient to think of handling Group specs, it is not clear what kinds of objects to handle at the moment. Because the purpose of application is not specific.
If it is limited to Group spec, instance Spec, implementation of event repeater becomes complicated
For that reason, we are currently setting it as a simple json object, of course GroupSpec could also be passed as a json object.

I think this should be a RESTful API listening on a port
So you could deploy a web application …

As you say, I think the Restful interface is useful.
In my understanding, Is the infrakit application to connect deployed app (not infrakit app, app on docker cluster) and Infrakit flavor and instance plugin for autoscale and rolling update?
If so it is quite consistent with my opinion.
I'd like to implement it as the next Infarakit application.

Copy link
Contributor

Choose a reason for hiding this comment

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

A non-trivial example of an infrakit 'application' that I have in mind is a small daemon that listens on a tcp port, offers a RESTful api that makes it easy for infrakit to implement this:
https://github.com/kubernetes/contrib/blob/master/cluster-autoscaler/cloudprovider/cloud_provider.go#L40

So if you look at it this way, we need to have a way to give an imperative API to infrakit's inherently declarative based api (via only a verb commit). We don't really need to add more plugin spi / JSON RPC implementations... instead the 'application' can surface our internal plugin SPI in a meaningful way to other systems.

So let's chat at DockerCon more in detail about this idea. We need to take time to get this right.

@chungers
Copy link
Contributor

@YujiOshima - thank you for taking the lead on this.

Let's leave this PR / branch open and refine it. I think you're onto something very cool. My initial thinking when we talked about this was not very refined, but seeing your POC has gotten me thinking about a general API. Can you have a look at my questions and lets discuss more. Thank you!

@chungers chungers changed the title Add Application plugin and Event repeater [WIP] Add Application plugin and Event repeater Apr 12, 2017
@YujiOshima
Copy link
Contributor Author

YujiOshima commented Apr 13, 2017

@chungers Thankyou for your comments!
I'm willing to discuss and refine it.
First, We need util command and general rest API (of course tests and docs :) )

Signed-off-by: Yuji Oshima <[email protected]>
Signed-off-by: Yuji Oshima <[email protected]>
Signed-off-by: Yuji Oshima <[email protected]>
Signed-off-by: Yuji Oshima <[email protected]>
Signed-off-by: Yuji Oshima <[email protected]>
Signed-off-by: Yuji Oshima <[email protected]>
@YujiOshima
Copy link
Contributor Author

Hi @chungers ! I added tests and moved commands to under util.
And I've made the application publish the REST API instead of rpc.
You can use both of unix socket and tcp port.
I also modified the commands and APIs associated with it.
I updated documents: https://github.com/YujiOshima/infrakit/blob/749e1f2a285fba712105c5b643446442b51668c5/pkg/application/eventrepeater/README.md.
Please take a look. Thanks!

@chungers
Copy link
Contributor

chungers commented May 1, 2017

@YujiOshima - can you sync and update this PR? Sorry the cmd/cli directory has been renamed to cmd/infrakit plus a few fixes. I will take a look at your README. Thank you!

@YujiOshima
Copy link
Contributor Author

@chungers Thanks! This PR is now up to date !

@chungers
Copy link
Contributor

chungers commented May 2, 2017

@YujiOshima

I get the event repeater but I am little confused by the usage of the infrakit util application tool. I understand how it is used to add / change/ update topics in the event repeater, but how do you envision this work with the rest of the plugin system? In particular, you have this path that can map to resource/resourceID -- do these relate to the plugins?

If the infrakit util application is more closely coupled to the event repeater, then maybe we can structure the commands to be infrakit util event-repeater run and infrakit util event-repeater manage ...?

@YujiOshima
Copy link
Contributor Author

@chungers Thank you for review. I understand you said and I agree that is more reasonable about event-repeater.
But in that case, we will not have any schema for the application.
I think it's ok now, but we need discuss about the schema when other application will add.

@YujiOshima
Copy link
Contributor Author

YujiOshima commented May 2, 2017

@chungers I integrated two commands to event-repater command.
I remained path option for I want to enable to manage with path.
For example, `infrakit util manage post --path /events/EVENTNAME/ --value ...
What do you think?

@GordonTheTurtle
Copy link

Please sign your commits following these rules:
https://github.com/moby/moby/blob/master/CONTRIBUTING.md#sign-your-work
The easiest way to do this is to amend the last commit:

$ git clone -b "evrepeater" [email protected]:YujiOshima/infrakit.git somewhere
$ cd somewhere
$ git rebase -i HEAD~842354568776
editor opens
change each 'pick' to 'edit'
save the file and quit
$ git commit --amend -s --no-edit
$ git rebase --continue # and repeat the amend for each commit
$ git push -f

Amending updates the existing PR. You DO NOT need to open a new one.

chungers pushed a commit to chungers/infrakit that referenced this pull request Sep 30, 2017
* Updated the Docker for AWS docs, to include new parameters, and remove private beta stuff

* Change the crontab for prune job to once per day instead of once per hour

Signed-off-by: Ken Cochrane <[email protected]>

* cleaned up comments from friism

Signed-off-by: Ken Cochrane <[email protected]>
chungers pushed a commit to chungers/infrakit that referenced this pull request Oct 1, 2017
* Updated the Docker for AWS docs, to include new parameters, and remove private beta stuff

* Change the crontab for prune job to once per day instead of once per hour

Signed-off-by: Ken Cochrane <[email protected]>

* cleaned up comments from friism

Signed-off-by: Ken Cochrane <[email protected]>
@chungers
Copy link
Contributor

Hi @YujiOshima - Let's discuss this PR. I think now that we have some useful patterns in terms of controllers vs. plugins, we should revisit this.

I am thinking of the recent example of an enrollment controller that tracks group membership with an instance plugin (e.g. for NFS volume authorization -- see #678 ) could have a nice application here. We can have a controller that maintains a list of topics to register. When the user updates the specification either by add/change/and delete entries, we can synchronize this in MQTT via this controller -- perhaps via calls to "Provision" or "Destroy" an MQTT topic... This would have the nice property of allowing us declaratively specify the MQTT topics from a cluster -- instead of a lot of command line calls that only bash_history remembers... What do you think? Let's talk in person if you are at the Moby Summit in Copenhagen.

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

Successfully merging this pull request may close these issues.

3 participants