From 0e46e763d5d75b0c65c5890c03b369aaa25c95c3 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Fri, 13 Nov 2020 18:25:44 +0100 Subject: [PATCH] Move bus implementation to a separate repo, hook to events in luet --- cmd/root.go | 17 ++++++ go.mod | 10 ++-- go.sum | 37 ++++++++++++- pkg/bus/events.go | 46 +++++++++++++++++ pkg/compiler/artifact.go | 4 ++ pkg/compiler/compiler.go | 35 +++++++++++++ pkg/installer/installer.go | 4 ++ pkg/installer/repository.go | 17 ++++++ pkg/plugin/bus.go | 70 ------------------------- pkg/plugin/events.go | 53 ------------------- pkg/plugin/manager.go | 29 ----------- pkg/plugin/plugin.go | 49 ------------------ pkg/plugin/plugin_suite_test.go | 32 ------------ pkg/plugin/plugin_test.go | 92 --------------------------------- tests/fixtures/plugin/test-foo | 3 ++ tests/integration/20_plugin.sh | 83 +++++++++++++++++++++++++++++ 16 files changed, 248 insertions(+), 333 deletions(-) create mode 100644 pkg/bus/events.go delete mode 100644 pkg/plugin/bus.go delete mode 100644 pkg/plugin/events.go delete mode 100644 pkg/plugin/manager.go delete mode 100644 pkg/plugin/plugin.go delete mode 100644 pkg/plugin/plugin_suite_test.go delete mode 100644 pkg/plugin/plugin_test.go create mode 100755 tests/fixtures/plugin/test-foo create mode 100755 tests/integration/20_plugin.sh diff --git a/cmd/root.go b/cmd/root.go index 3f4644e3..0f8db51c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,6 +24,8 @@ import ( "strings" "github.com/marcsauter/single" + bus "github.com/mudler/luet/pkg/bus" + extensions "github.com/mudler/cobra-extensions" config "github.com/mudler/luet/pkg/config" helpers "github.com/mudler/luet/pkg/helpers" @@ -68,6 +70,18 @@ var RootCmd = &cobra.Command{ if err != nil { Fatal("failed on init tmp basedir:", err.Error()) } + + viper.BindPFlag("plugin", cmd.Flags().Lookup("plugin")) + + plugin := viper.GetStringSlice("plugin") + + bus.Manager.Load(plugin...).Register() + if len(bus.Manager.Plugins) != 0 { + Info(":lollipop:Enabled plugins:") + for _, p := range bus.Manager.Plugins { + Info("\t:arrow_right:", p.Name) + } + } }, PersistentPostRun: func(cmd *cobra.Command, args []string) { // Cleanup all tmp directories used by luet @@ -156,6 +170,7 @@ func init() { "Disable config protect analysis.") pflags.StringP("logfile", "l", config.LuetCfg.GetLogging().Path, "Logfile path. Empty value disable log to file.") + pflags.StringSlice("plugin", []string{}, "A list of runtime plugins to load") // os/user doesn't work in from scratch environments. // Check if i can retrieve user informations. @@ -175,6 +190,8 @@ func init() { config.LuetCfg.Viper.BindPFlag("general.debug", pflags.Lookup("debug")) config.LuetCfg.Viper.BindPFlag("general.fatal_warnings", pflags.Lookup("fatal")) config.LuetCfg.Viper.BindPFlag("general.same_owner", pflags.Lookup("same-owner")) + config.LuetCfg.Viper.BindPFlag("plugin", pflags.Lookup("plugin")) + // Currently I maintain this only from cli. config.LuetCfg.Viper.BindPFlag("no_spinner", pflags.Lookup("no-spinner")) config.LuetCfg.Viper.BindPFlag("config_protect_skip", pflags.Lookup("skip-config-protect")) diff --git a/go.mod b/go.mod index 7ace5d6a..9d4fc385 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,6 @@ require ( github.com/asdine/storm v0.0.0-20190418133842-e0f77eada154 github.com/briandowns/spinner v1.7.0 github.com/cavaliercoder/grab v2.0.0+incompatible - github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 - github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 github.com/crillab/gophersat v1.3.2-0.20201023142334-3fc2ac466765 github.com/docker/docker v17.12.0-ce-rc1.0.20200417035958-130b0bc6032c+incompatible github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect @@ -27,9 +25,10 @@ require ( github.com/moby/sys/mount v0.1.1-0.20200320164225-6154f11e6840 // indirect github.com/mudler/cobra-extensions v0.0.0-20200612154940-31a47105fe3d github.com/mudler/docker-companion v0.4.6-0.20200418093252-41846f112d87 + github.com/mudler/go-pluggable v0.0.0-20201113172133-2b1db55e5ff0 github.com/mudler/topsort v0.0.0-20201103161459-db5c7901c290 - github.com/onsi/ginkgo v1.12.1 - github.com/onsi/gomega v1.10.0 + github.com/onsi/ginkgo v1.14.2 + github.com/onsi/gomega v1.10.3 github.com/otiai10/copy v1.2.1-0.20200916181228-26f84a0b1578 github.com/pelletier/go-toml v1.6.0 // indirect github.com/philopon/go-toposort v0.0.0-20170620085441-9be86dbd762f @@ -41,8 +40,7 @@ require ( go.uber.org/multierr v1.4.0 // indirect go.uber.org/zap v1.13.0 golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect - golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect - gopkg.in/yaml.v2 v2.2.8 + gopkg.in/yaml.v2 v2.3.0 gotest.tools/v3 v3.0.2 // indirect helm.sh/helm/v3 v3.3.4 mvdan.cc/sh/v3 v3.0.0-beta1 diff --git a/go.sum b/go.sum index 97875fdb..09c6cb69 100644 --- a/go.sum +++ b/go.sum @@ -205,6 +205,8 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/go-dockerclient v1.6.4 h1:B+L+1lz1LUrNgEUUh8PSG76s70EYC49ssv2xvTefTMM= github.com/fsouza/go-dockerclient v1.6.4/go.mod h1:GOdftxWLWIbIWKbIMDroKFJzPdg6Iw7r+jX1DDZdVsA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= @@ -298,6 +300,13 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= @@ -508,6 +517,8 @@ github.com/mudler/cobra-extensions v0.0.0-20200612154940-31a47105fe3d h1:fKh+rvw github.com/mudler/cobra-extensions v0.0.0-20200612154940-31a47105fe3d/go.mod h1:puRUWSwyecW2V355tKncwPVPRAjQBduPsFjG0mrV/Nw= github.com/mudler/docker-companion v0.4.6-0.20200418093252-41846f112d87 h1:mGz7T8KvmHH0gLWPI5tQne8xl2cO3T8wrrb6Aa16Jxo= github.com/mudler/docker-companion v0.4.6-0.20200418093252-41846f112d87/go.mod h1:1w4zI1LYXDeiUXqedPcrT5eQJnmKR6dbg5iJMgSIP/Y= +github.com/mudler/go-pluggable v0.0.0-20201113172133-2b1db55e5ff0 h1:UR5db9V1ppo6GTbxwPXaf3N7wJhiENW1vxpcm18TzBg= +github.com/mudler/go-pluggable v0.0.0-20201113172133-2b1db55e5ff0/go.mod h1:4P/ULate+2QxoAQtojaRjyO5VGMhV0KLnSdAS8nuBbo= github.com/mudler/topsort v0.0.0-20201103161459-db5c7901c290 h1:426hFyXMpXeqIeGJn2cGAW9ogvM2Jf+Jv23gtVPvBLM= github.com/mudler/topsort v0.0.0-20201103161459-db5c7901c290/go.mod h1:uP5BBgFxq2wNWo7n1vnY5SSbgL0WDshVJrOO12tZ/lA= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -538,6 +549,8 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -546,6 +559,9 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.0 h1:Gwkk+PTu/nfOwNMtUB/mRUv0X7ewW5dO4AERT1ThVKo= github.com/onsi/gomega v1.10.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/openSUSE/umoci v0.1.1-0.20191030112807-c0dd46ae078f h1:G9hyzNrFbTgp9KEoGRcNYxAT41lo7hDy9oxXT1Y7WHI= github.com/openSUSE/umoci v0.1.1-0.20191030112807-c0dd46ae078f/go.mod h1:3p4KA5nwyY65lVmQZxv7tm0YEylJ+t1fY91ORsVXv58= @@ -842,8 +858,9 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2 h1:4dVFTC832rPn4pomLSz1vA+are2+dU19w1H8OngV7nc= golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= @@ -882,6 +899,7 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190913121621-c3b328c6e5a7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -890,11 +908,17 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -963,6 +987,13 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -995,6 +1026,8 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= diff --git a/pkg/bus/events.go b/pkg/bus/events.go new file mode 100644 index 00000000..dffcaeb0 --- /dev/null +++ b/pkg/bus/events.go @@ -0,0 +1,46 @@ +package bus + +import ( + "github.com/mudler/go-pluggable" +) + +var ( + // Package events + + // EventPackageInstall is the event fired when a new package is being installed + EventPackageInstall pluggable.EventType = "package.install" + // EventPackageUnInstall is the event fired when a new package is being uninstalled + EventPackageUnInstall pluggable.EventType = "package.uninstall" + + // Package build + + // EventPackagePreBuild is the event fired before a package is being built + EventPackagePreBuild pluggable.EventType = "package.pre.build" + // EventPackagePreBuildArtifact is the event fired before a package artifact is being built + EventPackagePreBuildArtifact pluggable.EventType = "package.pre.build_artifact" + // EventPackagePostBuildArtifact is the event fired after a package artifact was built + EventPackagePostBuildArtifact pluggable.EventType = "package.post.build_artifact" + // EventPackagePostBuild is the event fired after a package was built + EventPackagePostBuild pluggable.EventType = "package.post.build" + + // Repository events + + // EventRepositoryPreBuild is the event fired before a repository is being built + EventRepositoryPreBuild pluggable.EventType = "repository.pre.build" + // EventRepositoryPostBuild is the event fired after a repository was built + EventRepositoryPostBuild pluggable.EventType = "repository.post.build" +) + +// Manager is the bus instance manager, which subscribes plugins to events emitted by Luet +var Manager *pluggable.Manager = pluggable.NewManager( + []pluggable.EventType{ + EventPackageInstall, + EventPackageUnInstall, + EventPackagePreBuild, + EventPackagePreBuildArtifact, + EventPackagePostBuildArtifact, + EventPackagePostBuild, + EventRepositoryPreBuild, + EventRepositoryPostBuild, + }, +) diff --git a/pkg/compiler/artifact.go b/pkg/compiler/artifact.go index 42b09eb8..81eed3e3 100644 --- a/pkg/compiler/artifact.go +++ b/pkg/compiler/artifact.go @@ -34,6 +34,7 @@ import ( "strings" "sync" + bus "github.com/mudler/luet/pkg/bus" . "github.com/mudler/luet/pkg/config" "github.com/mudler/luet/pkg/helpers" . "github.com/mudler/luet/pkg/logger" @@ -170,6 +171,8 @@ func (a *PackageArtifact) WriteYaml(dst string) error { return errors.Wrap(err, "While marshalling for PackageArtifact YAML") } + bus.Manager.Publish(bus.EventPackagePreBuildArtifact, a) + mangle, err := NewPackageArtifactFromYaml(data) if err != nil { return errors.Wrap(err, "Generated invalid artifact") @@ -191,6 +194,7 @@ func (a *PackageArtifact) WriteYaml(dst string) error { return errors.Wrap(err, "While writing PackageArtifact YAML") } //a.CompileSpec.GetPackage().SetPath(p) + bus.Manager.Publish(bus.EventPackagePostBuildArtifact, a) return nil } diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 1c24a338..09f38ce1 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -26,6 +26,8 @@ import ( "sync" "time" + bus "github.com/mudler/luet/pkg/bus" + "github.com/mudler/luet/pkg/helpers" . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" @@ -596,6 +598,14 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila targetAssertion := p.GetSourceAssertion().Search(p.GetPackage().GetFingerPrint()) targetPackageHash := cs.ImageRepository + ":" + targetAssertion.Hash.PackageHash + bus.Manager.Publish(bus.EventPackagePreBuild, struct { + CompileSpec CompilationSpec + Assert solver.PackageAssert + }{ + CompileSpec: p, + Assert: *targetAssertion, + }) + // - If image is set we just generate a plain dockerfile // Treat last case (easier) first. The image is provided and we just compute a plain dockerfile with the images listed as above if p.GetImage() != "" { @@ -636,6 +646,14 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila Debug(pkgTag, " :arrow_right_hook: :whale: Builder image from", buildImageHash) Debug(pkgTag, " :arrow_right_hook: :whale: Package image name", currentPackageImageHash) + bus.Manager.Publish(bus.EventPackagePreBuild, struct { + CompileSpec CompilationSpec + Assert solver.PackageAssert + }{ + CompileSpec: compileSpec, + Assert: assertion, + }) + lastHash = currentPackageImageHash if compileSpec.GetImage() != "" { Debug(pkgTag, " :wrench: Compiling "+compileSpec.GetPackage().HumanReadableString()+" from image") @@ -655,6 +673,15 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila // deperrs = append(deperrs, err) // break // stop at first error } + + bus.Manager.Publish(bus.EventPackagePostBuild, struct { + CompileSpec CompilationSpec + Artifact Artifact + }{ + CompileSpec: compileSpec, + Artifact: artifact, + }) + departifacts = append(departifacts, artifact) Info(pkgTag, ":white_check_mark: Done") } @@ -673,6 +700,14 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila artifact.SetDependencies(departifacts) artifact.SetSourceAssertion(p.GetSourceAssertion()) + bus.Manager.Publish(bus.EventPackagePostBuild, struct { + CompileSpec CompilationSpec + Artifact Artifact + }{ + CompileSpec: p, + Artifact: artifact, + }) + return artifact, err } else { return departifacts[len(departifacts)-1], nil diff --git a/pkg/installer/installer.go b/pkg/installer/installer.go index f8056cec..f7f25b9f 100644 --- a/pkg/installer/installer.go +++ b/pkg/installer/installer.go @@ -24,6 +24,7 @@ import ( "strings" "sync" + "github.com/mudler/luet/pkg/bus" compiler "github.com/mudler/luet/pkg/compiler" "github.com/mudler/luet/pkg/config" "github.com/mudler/luet/pkg/helpers" @@ -451,6 +452,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *Sy if err != nil && !l.Options.Force { return errors.Wrap(err, "Failed creating package") } + bus.Manager.Publish(bus.EventPackageInstall, c) } var toFinalize []pkg.Package if !l.Options.NoDeps { @@ -655,6 +657,8 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error { return errors.Wrap(err, "Failed removing package from database") } + bus.Manager.Publish(bus.EventPackageUnInstall, p) + Info(":recycle:", p.GetFingerPrint(), "Removed :heavy_check_mark:") return nil } diff --git a/pkg/installer/repository.go b/pkg/installer/repository.go index 7e40a8e9..392a03c9 100644 --- a/pkg/installer/repository.go +++ b/pkg/installer/repository.go @@ -26,6 +26,7 @@ import ( "strings" "time" + "github.com/mudler/luet/pkg/bus" "github.com/mudler/luet/pkg/compiler" "github.com/mudler/luet/pkg/config" "github.com/mudler/luet/pkg/helpers" @@ -426,6 +427,14 @@ func (r *LuetSystemRepository) Write(dst string, resetRevision bool) error { r.Name, r.Revision, r.LastUpdate, )) + bus.Manager.Publish(bus.EventRepositoryPreBuild, struct { + Repo LuetSystemRepository + Path string + }{ + Repo: *r, + Path: dst, + }) + // Create tree and repository file archive, err := config.LuetCfg.GetSystem().TempDir("archive") if err != nil { @@ -506,6 +515,14 @@ func (r *LuetSystemRepository) Write(dst string, resetRevision bool) error { return err } + bus.Manager.Publish(bus.EventRepositoryPostBuild, struct { + Repo LuetSystemRepository + Path string + }{ + Repo: *r, + Path: dst, + }) + return nil } diff --git a/pkg/plugin/bus.go b/pkg/plugin/bus.go deleted file mode 100644 index 27e6934a..00000000 --- a/pkg/plugin/bus.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright © 2020 Ettore Di Giacinto -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// 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 . - -package plugin - -import ( - "github.com/chuckpreslar/emission" - "github.com/codegangsta/inject" -) - -type Bus struct { - inject.Injector - emission.Emitter -} - -func NewBus() *Bus { - return &Bus{ - Injector: inject.New(), - Emitter: *emission.NewEmitter(), - } -} - -// On Binds a callback to an event, mapping the arguments on a global level -func (a *Bus) Listen(event EventType, listener interface{}) *Bus { - a.On(string(event), func() { a.Invoke(listener) }) - return a -} - -// Emit Emits an event, it does accept only the event as argument, since -// the callback will have access to the service mapped by the injector -func (a *Bus) Publish(t EventType, e *Event) *Bus { - a.Map(e) - a.Emit(string(t)) - return a -} - -// Once Binds a callback to an event, mapping the arguments on a global level -// It is fired only once. -func (a *Bus) OnlyOnce(event EventType, listener interface{}) *Bus { - a.Once(string(event), func() { a.Invoke(listener) }) - return a -} - -// EmitSync Emits an event in a syncronized manner, -// it does accept only the event as argument, since -// the callback will have access to the service mapped by the injector -func (a *Bus) EmitSync(event interface{}) *Bus { - a.EmitSync(event) - return a -} - -func (b *Bus) PropagateEvent(p Plugin) func(e *Event) { - return func(e *Event) { - resp, _ := p.Run(*e) - b.Map(&resp) - b.Emit(p.Name) - } -} diff --git a/pkg/plugin/events.go b/pkg/plugin/events.go deleted file mode 100644 index 1953e11c..00000000 --- a/pkg/plugin/events.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright © 2020 Ettore Di Giacinto -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// 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 . - -package plugin - -import "encoding/json" - -var ( - PackageInstalled EventType = "package.install" -) - -type EventType string - -type Event struct { - Name EventType `json:"name"` - Data string `json:"data"` -} - -type EventResponse struct { - State string `json:"state"` - Data string `json:"data"` - Error string `json:"error"` -} - -func (e Event) JSON() (string, error) { - dat, err := json.Marshal(e) - return string(dat), err -} - -func (r EventResponse) Unmarshal(i interface{}) error { - return json.Unmarshal([]byte(r.Data), i) -} - -func (r EventResponse) Errored() bool { - return len(r.Error) != 0 -} - -func NewEvent(name EventType, obj interface{}) (*Event, error) { - dat, err := json.Marshal(obj) - return &Event{Name: name, Data: string(dat)}, err -} diff --git a/pkg/plugin/manager.go b/pkg/plugin/manager.go deleted file mode 100644 index a0ed4dd8..00000000 --- a/pkg/plugin/manager.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © 2020 Ettore Di Giacinto -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// 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 . - -package plugin - -type Manager struct { - Plugins []Plugin - Events []EventType -} - -func (m Manager) Subscribe(b *Bus) { - for _, p := range m.Plugins { - for _, e := range m.Events { - b.Listen(e, b.PropagateEvent(p)) - } - } -} diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go deleted file mode 100644 index b6d3a934..00000000 --- a/pkg/plugin/plugin.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright © 2020 Ettore Di Giacinto -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// 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 . - -package plugin - -import ( - "encoding/json" - "os/exec" - - "github.com/pkg/errors" -) - -// External binaries to be hooked on events, with common js input, and common js output -type Plugin struct { - Name string - Executable string -} - -func (p Plugin) Run(e Event) (EventResponse, error) { - r := EventResponse{} - k, err := e.JSON() - if err != nil { - return r, errors.Wrap(err, "while marshalling evet") - } - cmd := exec.Command(p.Executable, string(e.Name), k) - out, err := cmd.Output() - if err != nil { - r.Error = err.Error() - return r, errors.Wrap(err, "while executing plugin") - } - - if err := json.Unmarshal(out, &r); err != nil { - r.Error = err.Error() - return r, errors.Wrap(err, "while unmarshalling response") - } - return r, nil -} diff --git a/pkg/plugin/plugin_suite_test.go b/pkg/plugin/plugin_suite_test.go deleted file mode 100644 index d719b77f..00000000 --- a/pkg/plugin/plugin_suite_test.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright © 2020 Ettore Di Giacinto -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// 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 . - -package plugin_test - -import ( - "testing" - - . "github.com/mudler/luet/cmd" - config "github.com/mudler/luet/pkg/config" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestPlugin(t *testing.T) { - RegisterFailHandler(Fail) - LoadConfig(config.LuetCfg) - RunSpecs(t, "Plugin Suite") -} diff --git a/pkg/plugin/plugin_test.go b/pkg/plugin/plugin_test.go deleted file mode 100644 index 53c3773e..00000000 --- a/pkg/plugin/plugin_test.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright © 2020 Ettore Di Giacinto -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// 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 . - -package plugin_test - -import ( - "io/ioutil" - "os" - - . "github.com/mudler/luet/pkg/plugin" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Plugin", func() { - Context("event subscription", func() { - var pluginFile *os.File - var err error - var b *Bus - var m *Manager - - BeforeEach(func() { - pluginFile, err = ioutil.TempFile(os.TempDir(), "tests") - Expect(err).Should(BeNil()) - defer os.Remove(pluginFile.Name()) // clean up - b = NewBus() - m = &Manager{} - }) - - It("gets the json event name", func() { - d1 := []byte("#!/bin/bash\necho \"{ \\\"state\\\": \\\"$1\\\" }\"\n") - err := ioutil.WriteFile(pluginFile.Name(), d1, 0550) - Expect(err).Should(BeNil()) - - m.Plugins = []Plugin{{Name: "test", Executable: pluginFile.Name()}} - m.Events = []EventType{PackageInstalled} - m.Subscribe(b) - - ev, err := NewEvent(PackageInstalled, map[string]string{"foo": "bar"}) - Expect(err).Should(BeNil()) - - var received map[string]string - var resp *EventResponse - b.Listen("test", func(r *EventResponse) { - resp = r - r.Unmarshal(&received) - }) - - b.Publish(PackageInstalled, ev) - Expect(resp.Errored()).ToNot(BeTrue()) - Expect(resp.State).Should(Equal(string(PackageInstalled))) - }) - - It("gets the json event payload", func() { - d1 := []byte("#!/bin/bash\necho $2\n") - err := ioutil.WriteFile(pluginFile.Name(), d1, 0550) - Expect(err).Should(BeNil()) - - m.Plugins = []Plugin{{Name: "test", Executable: pluginFile.Name()}} - m.Events = []EventType{PackageInstalled} - m.Subscribe(b) - - foo := map[string]string{"foo": "bar"} - ev, err := NewEvent(PackageInstalled, foo) - Expect(err).Should(BeNil()) - - var received map[string]string - var resp *EventResponse - b.Listen("test", func(r *EventResponse) { - resp = r - r.Unmarshal(&received) - }) - - b.Publish(PackageInstalled, ev) - Expect(resp.Errored()).ToNot(BeTrue()) - Expect(received).Should(Equal(foo)) - }) - }) -}) diff --git a/tests/fixtures/plugin/test-foo b/tests/fixtures/plugin/test-foo new file mode 100755 index 00000000..7073bea4 --- /dev/null +++ b/tests/fixtures/plugin/test-foo @@ -0,0 +1,3 @@ +#!/bin/bash +echo "$1" >> $EVENT_FILE +echo "$2" >> $PAYLOAD_FILE \ No newline at end of file diff --git a/tests/integration/20_plugin.sh b/tests/integration/20_plugin.sh new file mode 100755 index 00000000..9cd0c0fb --- /dev/null +++ b/tests/integration/20_plugin.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +export LUET_NOLOCK=true +export PATH=$PATH:$ROOT_DIR/tests/fixtures/plugin + + +oneTimeSetUp() { +export tmpdir="$(mktemp -d)" +export EVENT_FILE=$tmpdir/events.txt +export PAYLOAD_FILE=$tmpdir/payloads.txt +} + +oneTimeTearDown() { + rm -rf "$tmpdir" +} + +testBuild() { + mkdir $tmpdir/testbuild + luet build --plugin test-foo --tree "$ROOT_DIR/tests/fixtures/templatedfinalizers" --destination $tmpdir/testbuild --compression gzip --all + buildst=$? + assertEquals 'builds successfully' "$buildst" "0" + assertContains 'event file contains corresponding event' "$(cat $EVENT_FILE)" 'package.pre.build' + assertContains 'event file contains corresponding event' "$(cat $PAYLOAD_FILE)" 'alpine' +} + +testRepo() { + assertTrue 'no repository' "[ ! -e '$tmpdir/testbuild/repository.yaml' ]" + luet --plugin test-foo create-repo --tree "$ROOT_DIR/tests/fixtures/templatedfinalizers" \ + --output $tmpdir/testbuild \ + --packages $tmpdir/testbuild \ + --name "test" \ + --descr "Test Repo" \ + --urls $tmpdir/testrootfs \ + --type disk > /dev/null + + createst=$? + assertEquals 'create repo successfully' "$createst" "0" + assertContains 'event file contains corresponding event' "$(cat $EVENT_FILE)" 'repository.pre.build' +} + +testConfig() { + mkdir $tmpdir/testrootfs + cat < $tmpdir/luet.yaml +general: + debug: true +system: + rootfs: $tmpdir/testrootfs + database_path: "/" + database_engine: "boltdb" +config_from_host: true +repositories: + - name: "main" + type: "disk" + enable: true + urls: + - "$tmpdir/testbuild" +EOF + luet config --config $tmpdir/luet.yaml + res=$? + assertEquals 'config test successfully' "$res" "0" +} + +testInstall() { + luet --plugin test-foo install --config $tmpdir/luet.yaml seed/alpine + #luet install --config $tmpdir/luet.yaml test/c-1.0 > /dev/null + installst=$? + assertEquals 'install test successfully' "$installst" "0" + assertTrue 'package installed' "[ -e '$tmpdir/testrootfs/bin/busybox' ]" + assertTrue 'finalizer runs' "[ -e '$tmpdir/testrootfs/tmp/foo' ]" + assertEquals 'finalizer printed used shell' "$(cat $tmpdir/testrootfs/tmp/foo)" 'alpine' + assertContains 'event file contains corresponding event' "$(cat $EVENT_FILE)" 'package.install' + +} + + +testCleanup() { + luet cleanup --config $tmpdir/luet.yaml + installst=$? + assertEquals 'install test successfully' "$installst" "0" +} + +# Load shUnit2. +. "$ROOT_DIR/tests/integration/shunit2"/shunit2