diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 769442ad3..246d414f2 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -36,7 +36,6 @@ import ( operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1" "github.com/operator-framework/operator-controller/internal/controllers" - "github.com/operator-framework/operator-controller/internal/resolution/entitysources" "github.com/operator-framework/operator-controller/pkg/features" ) @@ -103,7 +102,6 @@ func main() { Client: mgr.GetClient(), Scheme: mgr.GetScheme(), Resolver: solver.NewDeppySolver( - entitysources.NewCatalogdEntitySource(mgr.GetClient()), controllers.NewVariableSource(mgr.GetClient()), ), }).SetupWithManager(mgr); err != nil { diff --git a/go.mod b/go.mod index 445daa2e3..85ed3a8b6 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onsi/gomega v1.27.10 github.com/operator-framework/api v0.17.4-0.20230223191600-0131a6301e42 github.com/operator-framework/catalogd v0.5.0 - github.com/operator-framework/deppy v0.0.0-20230629133131-bb7b6ae7b266 + github.com/operator-framework/deppy v0.0.1 github.com/operator-framework/operator-registry v1.28.0 github.com/operator-framework/rukpak v0.13.0 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 25b504b25..91d13b96e 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,7 @@ github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSY github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -71,6 +72,7 @@ github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfy github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -263,6 +265,7 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= @@ -305,6 +308,7 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -454,6 +458,7 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/cel-go v0.12.6 h1:kjeKudqV0OygrAqA9fX6J55S8gj+Jre2tckIm5RoG4M= github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= @@ -511,6 +516,7 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -521,6 +527,7 @@ github.com/h2non/filetype v1.1.1 h1:xvOwnXKAckvtLWsN398qS9QhlxlnVXBjXBydK2/UFB4= github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c h1:fEE5/5VNnYUoBOj2I9TP8Jc+a7lge3QWn9DKE7NCwfc= github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8RYb1Y7fYivughjxojTmIu5iAIjSrSLCLeqE= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= @@ -553,6 +560,7 @@ github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52Cu github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d h1:A2/B900ip/Z20TzkLeGRNy1s6J2HmH9AmGt+dHyqb4I= github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d/go.mod h1:7HQupe4vyNxMKXmM5DFuwXHsqwMyglcYmZBtlDPIcZ8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -568,6 +576,7 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -623,6 +632,7 @@ github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI= @@ -647,6 +657,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -661,6 +672,7 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -705,6 +717,8 @@ github.com/operator-framework/catalogd v0.5.0 h1:azU5KCofUXVoakXCPRGjAjYyDtZzNSS github.com/operator-framework/catalogd v0.5.0/go.mod h1:1xksKKGHglY0i92h3/KDZURMSEhf3xtKRj2vCfJ57fk= github.com/operator-framework/deppy v0.0.0-20230629133131-bb7b6ae7b266 h1:SQEUaAoRWNhr2poLH6z/RsEWZG7PppDWHsr5vAvJkJc= github.com/operator-framework/deppy v0.0.0-20230629133131-bb7b6ae7b266/go.mod h1:6kgHMeS5vQt3gqWGgJIig1yT5uflBUsCc1orP+I3nbk= +github.com/operator-framework/deppy v0.0.1 h1:PLTtaFGwktPhKuKZkfUruTimrWpyaO3tghbsjs0uMjc= +github.com/operator-framework/deppy v0.0.1/go.mod h1:EV6vnxRodSFRn2TFztfxFhMPGh5QufOhn3tpIP1Z8cc= github.com/operator-framework/operator-registry v1.28.0 h1:vtmd2WgJxkx7vuuOxW4k5Le/oo0SfonSeJVMU3rKIfk= github.com/operator-framework/operator-registry v1.28.0/go.mod h1:UYw3uaZyHwHgnczLRYmUqMpgRgP2EfkqOsaR+LI+nK8= github.com/operator-framework/rukpak v0.13.0 h1:QP0P9ybwtkFpfVOMY9z5v4+vRyBdoqAotv8RP/SZ0hw= @@ -793,6 +807,7 @@ github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -836,6 +851,7 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -849,6 +865,7 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= @@ -866,6 +883,7 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPS github.com/yvasiyarov/gorelic v0.0.7 h1:4DTF1WOM2ZZS/xMOkTFBOcb6XiHu/PKn3rVo6dbewQE= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20160601141957-9c099fbc30e9 h1:AsFN8kXcCVkUFHyuzp1FtYbzp1nCO/H6+1uPSGEyPzM= +gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= @@ -950,6 +968,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= diff --git a/internal/controllers/operator_controller.go b/internal/controllers/operator_controller.go index 03ec6f20b..1bf1fa9b5 100644 --- a/internal/controllers/operator_controller.go +++ b/internal/controllers/operator_controller.go @@ -45,7 +45,7 @@ import ( operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1" "github.com/operator-framework/operator-controller/internal/controllers/validators" - "github.com/operator-framework/operator-controller/internal/resolution/entities" + "github.com/operator-framework/operator-controller/internal/resolution/variables" olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" ) @@ -157,7 +157,7 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha // lookup the bundle entity in the solution that corresponds to the // Operator's desired package name. - bundleEntity, err := r.getBundleEntityFromSolution(solution, op.Spec.PackageName) + bundleVariable, err := r.getBundleEntityFromSolution(solution, op.Spec.PackageName) if err != nil { op.Status.InstalledBundleResource = "" setInstalledStatusConditionUnknown(&op.Status.Conditions, "installation has not been attempted as resolution failed", op.GetGeneration()) @@ -167,7 +167,7 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha } // Get the bundle image reference for the bundle - bundleImage, err := bundleEntity.BundlePath() + bundleImage, err := bundleVariable.BundlePath() if err != nil { op.Status.InstalledBundleResource = "" setInstalledStatusConditionUnknown(&op.Status.Conditions, "installation has not been attempted as resolution failed", op.GetGeneration()) @@ -181,7 +181,7 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha op.Status.ResolvedBundleResource = bundleImage setResolvedStatusConditionSuccess(&op.Status.Conditions, fmt.Sprintf("resolved to %q", bundleImage), op.GetGeneration()) - mediaType, err := bundleEntity.MediaType() + mediaType, err := bundleVariable.MediaType() if err != nil { setInstalledStatusConditionFailed(&op.Status.Conditions, err.Error(), op.GetGeneration()) return ctrl.Result{}, err @@ -263,16 +263,16 @@ func mapBDStatusToInstalledCondition(existingTypedBundleDeployment *rukpakv1alph } } -func (r *OperatorReconciler) getBundleEntityFromSolution(solution *solver.Solution, packageName string) (*entities.BundleEntity, error) { +func (r *OperatorReconciler) getBundleEntityFromSolution(solution *solver.Solution, packageName string) (*variables.BundleVariable, error) { for _, variable := range solution.SelectedVariables() { switch v := variable.(type) { case *olmvariables.BundleVariable: - entityPkgName, err := v.BundleEntity().PackageName() + entityPkgName, err := v.PackageName() if err != nil { return nil, err } if packageName == entityPkgName { - return v.BundleEntity(), nil + return v, nil } } } @@ -377,13 +377,13 @@ func (r *OperatorReconciler) existingBundleDeploymentUnstructured(ctx context.Co // rukpak bundle provisioner class name that is capable of unpacking the bundle type func mapBundleMediaTypeToBundleProvisioner(mediaType string) (string, error) { switch mediaType { - case entities.MediaTypePlain: + case olmvariables.MediaTypePlain: return "core-rukpak-io-plain", nil // To ensure compatibility with bundles created with OLMv0 where the // olm.bundle.mediatype property doesn't exist, we assume that if the // property is empty (i.e doesn't exist) that the bundle is one created // with OLMv0 and therefore should use the registry provisioner - case entities.MediaTypeRegistry, "": + case olmvariables.MediaTypeRegistry, "": return "core-rukpak-io-registry", nil default: return "", fmt.Errorf("unknown bundle mediatype: %s", mediaType) diff --git a/internal/controllers/variable_source.go b/internal/controllers/variable_source.go index 21fa0b219..bf5dd0e1e 100644 --- a/internal/controllers/variable_source.go +++ b/internal/controllers/variable_source.go @@ -38,5 +38,8 @@ func NewVariableSource(cl client.Client) variablesources.NestedVariableSource { func(inputVariableSource input.VariableSource) (input.VariableSource, error) { return variablesources.NewCRDUniquenessConstraintsVariableSource(inputVariableSource), nil }, + func(inputVariableSource input.VariableSource) (input.VariableSource, error) { + return variablesources.NewCatalogdVariableSource(cl), nil + }, } } diff --git a/internal/resolution/entities/bundle_entity.go b/internal/resolution/entities/bundle_entity.go deleted file mode 100644 index b9ccf4cce..000000000 --- a/internal/resolution/entities/bundle_entity.go +++ /dev/null @@ -1,285 +0,0 @@ -package entities - -import ( - "encoding/json" - "fmt" - "sync" - - bsemver "github.com/blang/semver/v4" - "github.com/operator-framework/deppy/pkg/deppy/input" - "github.com/operator-framework/operator-registry/alpha/property" -) - -const PropertyBundlePath = "olm.bundle.path" -const PropertyBundleChannelEntry = "olm.bundle.channelEntry" -const PropertyBundleMediaType = "olm.bundle.mediatype" - -type MediaType string - -const ( - MediaTypePlain = "plain+v0" - MediaTypeRegistry = "registry+v1" -) - -// ---- - -type propertyRequirement bool - -const ( - required propertyRequirement = true - optional propertyRequirement = false -) - -type PackageRequired struct { - property.PackageRequired - SemverRange *bsemver.Range `json:"-"` -} - -type GVK property.GVK - -type ChannelEntry struct { - Name string `json:"name"` - Replaces string `json:"replaces"` - // Skips and skipRange will probably go here as well -} - -func (g GVK) String() string { - return fmt.Sprintf(`group:"%s" version:"%s" kind:"%s"`, g.Group, g.Version, g.Kind) -} - -type GVKRequired property.GVKRequired - -func (g GVKRequired) String() string { - return fmt.Sprintf(`group:"%s" version:"%s" kind:"%s"`, g.Group, g.Version, g.Kind) -} - -func (g GVKRequired) AsGVK() GVK { - return GVK(g) -} - -type BundleEntity struct { - *input.Entity - - // these properties are lazy loaded as they are requested - bundlePackage *property.Package - providedGVKs []GVK - requiredGVKs []GVKRequired - requiredPackages []PackageRequired - channel *property.Channel - channelEntry *ChannelEntry - semVersion *bsemver.Version - bundlePath string - mediaType string - mu sync.RWMutex -} - -func NewBundleEntity(entity *input.Entity) *BundleEntity { - return &BundleEntity{ - Entity: entity, - mu: sync.RWMutex{}, - } -} - -func (b *BundleEntity) PackageName() (string, error) { - if err := b.loadPackage(); err != nil { - return "", err - } - return b.bundlePackage.PackageName, nil -} - -func (b *BundleEntity) Version() (*bsemver.Version, error) { - if err := b.loadPackage(); err != nil { - return nil, err - } - return b.semVersion, nil -} - -func (b *BundleEntity) ProvidedGVKs() ([]GVK, error) { - if err := b.loadProvidedGVKs(); err != nil { - return nil, err - } - return b.providedGVKs, nil -} - -func (b *BundleEntity) RequiredGVKs() ([]GVKRequired, error) { - if err := b.loadRequiredGVKs(); err != nil { - return nil, err - } - return b.requiredGVKs, nil -} - -func (b *BundleEntity) RequiredPackages() ([]PackageRequired, error) { - if err := b.loadRequiredPackages(); err != nil { - return nil, err - } - return b.requiredPackages, nil -} - -func (b *BundleEntity) ChannelName() (string, error) { - if err := b.loadChannelProperties(); err != nil { - return "", err - } - return b.channel.ChannelName, nil -} - -func (b *BundleEntity) Channel() (*property.Channel, error) { - if err := b.loadChannelProperties(); err != nil { - return nil, err - } - return b.channel, nil -} - -func (b *BundleEntity) BundleChannelEntry() (*ChannelEntry, error) { - if err := b.loadBundleChannelEntry(); err != nil { - return nil, err - } - return b.channelEntry, nil -} - -func (b *BundleEntity) loadBundleChannelEntry() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.channelEntry == nil { - channelEntry, err := loadFromEntity[*ChannelEntry](b.Entity, PropertyBundleChannelEntry, optional) - if err != nil || channelEntry == nil { - return fmt.Errorf("error determining replaces for entity '%s': %w", b.ID, err) - } - b.channelEntry = channelEntry - } - return nil -} - -func (b *BundleEntity) BundlePath() (string, error) { - if err := b.loadBundlePath(); err != nil { - return "", err - } - return b.bundlePath, nil -} - -func (b *BundleEntity) MediaType() (string, error) { - if err := b.loadMediaType(); err != nil { - return "", err - } - - return b.mediaType, nil -} - -func (b *BundleEntity) loadMediaType() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.mediaType == "" { - mediaType, err := loadFromEntity[string](b.Entity, PropertyBundleMediaType, optional) - if err != nil { - return fmt.Errorf("error determining bundle mediatype for entity '%s': %w", b.ID, err) - } - b.mediaType = mediaType - } - return nil -} - -func (b *BundleEntity) loadPackage() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.bundlePackage == nil { - bundlePackage, err := loadFromEntity[property.Package](b.Entity, property.TypePackage, required) - if err != nil { - return fmt.Errorf("error determining package for entity '%s': %w", b.ID, err) - } - b.bundlePackage = &bundlePackage - if b.semVersion == nil { - semVer, err := bsemver.Parse(b.bundlePackage.Version) - if err != nil { - return fmt.Errorf("could not parse semver (%s) for entity '%s': %w", b.bundlePackage.Version, b.ID, err) - } - b.semVersion = &semVer - } - } - return nil -} - -func (b *BundleEntity) loadProvidedGVKs() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.providedGVKs == nil { - providedGVKs, err := loadFromEntity[[]GVK](b.Entity, property.TypeGVK, optional) - if err != nil { - return fmt.Errorf("error determining bundle provided gvks for entity '%s': %w", b.ID, err) - } - b.providedGVKs = providedGVKs - } - return nil -} - -func (b *BundleEntity) loadRequiredGVKs() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.requiredGVKs == nil { - requiredGVKs, err := loadFromEntity[[]GVKRequired](b.Entity, property.TypeGVKRequired, optional) - if err != nil { - return fmt.Errorf("error determining bundle required gvks for entity '%s': %w", b.ID, err) - } - b.requiredGVKs = requiredGVKs - } - return nil -} - -func (b *BundleEntity) loadRequiredPackages() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.requiredPackages == nil { - requiredPackages, err := loadFromEntity[[]PackageRequired](b.Entity, property.TypePackageRequired, optional) - if err != nil { - return fmt.Errorf("error determining bundle required packages for entity '%s': %w", b.ID, err) - } - for _, requiredPackage := range requiredPackages { - semverRange, err := bsemver.ParseRange(requiredPackage.VersionRange) - if err != nil { - return fmt.Errorf("error determining bundle required package semver range for entity '%s': '%w'", b.ID, err) - } - requiredPackage.SemverRange = &semverRange - } - b.requiredPackages = requiredPackages - } - return nil -} - -func (b *BundleEntity) loadChannelProperties() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.channel == nil { - channel, err := loadFromEntity[property.Channel](b.Entity, property.TypeChannel, required) - if err != nil { - return fmt.Errorf("error determining bundle channel properties for entity '%s': %w", b.ID, err) - } - b.channel = &channel - } - return nil -} - -func (b *BundleEntity) loadBundlePath() error { - b.mu.Lock() - defer b.mu.Unlock() - if b.bundlePath == "" { - bundlePath, err := loadFromEntity[string](b.Entity, PropertyBundlePath, required) - if err != nil { - return fmt.Errorf("error determining bundle path for entity '%s': %w", b.ID, err) - } - b.bundlePath = bundlePath - } - return nil -} - -func loadFromEntity[T interface{}](entity *input.Entity, propertyName string, required propertyRequirement) (T, error) { - deserializedProperty := *new(T) - propertyValue, ok := entity.Properties[propertyName] - if ok { - // TODO: In order to avoid invalid properties we should use a decoder that only allows the properties we expect. - // ie. decoder.DisallowUnknownFields() - if err := json.Unmarshal([]byte(propertyValue), &deserializedProperty); err != nil { - return deserializedProperty, fmt.Errorf("property '%s' ('%s') could not be parsed: %w", propertyName, propertyValue, err) - } - } else if required { - return deserializedProperty, fmt.Errorf("required property '%s' not found", propertyName) - } - return deserializedProperty, nil -} diff --git a/internal/resolution/entities/bundle_entity_test.go b/internal/resolution/entities/bundle_entity_test.go deleted file mode 100644 index 087575970..000000000 --- a/internal/resolution/entities/bundle_entity_test.go +++ /dev/null @@ -1,358 +0,0 @@ -package entities_test - -import ( - "fmt" - "testing" - - bsemver "github.com/blang/semver/v4" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "github.com/operator-framework/deppy/pkg/deppy/input" - "github.com/operator-framework/operator-registry/alpha/property" - - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" -) - -func TestBundleEntity(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "BundleEntity Suite") -} - -var _ = Describe("BundleEntity", func() { - Describe("PackageName", func() { - It("should return the package name if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.14.0\"}", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - packageName, err := bundleEntity.PackageName() - Expect(err).ToNot(HaveOccurred()) - Expect(packageName).To(Equal("prometheus")) - }) - It("should return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - packageName, err := bundleEntity.PackageName() - Expect(packageName).To(Equal("")) - Expect(err.Error()).To(Equal("error determining package for entity 'operatorhub/prometheus/0.14.0': required property 'olm.package' not found")) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.package": "badPackageNameStructure", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - packageName, err := bundleEntity.PackageName() - Expect(packageName).To(Equal("")) - Expect(err.Error()).To(Equal("error determining package for entity 'operatorhub/prometheus/0.14.0': property 'olm.package' ('badPackageNameStructure') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - }) - - Describe("Version", func() { - It("should return the bundle version if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.14.0\"}", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - version, err := bundleEntity.Version() - Expect(err).ToNot(HaveOccurred()) - Expect(*version).To(Equal(bsemver.MustParse("0.14.0"))) - }) - It("should return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - version, err := bundleEntity.Version() - Expect(version).To(BeNil()) - Expect(err.Error()).To(Equal("error determining package for entity 'operatorhub/prometheus/0.14.0': required property 'olm.package' not found")) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.package": "badPackageStructure", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - version, err := bundleEntity.Version() - Expect(version).To(BeNil()) - Expect(err.Error()).To(Equal("error determining package for entity 'operatorhub/prometheus/0.14.0': property 'olm.package' ('badPackageStructure') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - It("should return error if the version is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.package": "{\"packageName\":\"prometheus\",\"version\":\"badversion\"}", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - version, err := bundleEntity.Version() - Expect(version).To(BeNil()) - Expect(err.Error()).To(Equal("could not parse semver (badversion) for entity 'operatorhub/prometheus/0.14.0': No Major.Minor.Patch elements found")) - }) - }) - - Describe("ProvidedGVKs", func() { - It("should return the bundle provided gvks if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.gvk": "[{\"group\":\"foo.io\",\"kind\":\"Foo\",\"version\":\"v1\"},{\"group\":\"bar.io\",\"kind\":\"Bar\",\"version\":\"v1alpha1\"}]", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - providedGvks, err := bundleEntity.ProvidedGVKs() - Expect(err).ToNot(HaveOccurred()) - Expect(providedGvks).To(Equal([]olmentity.GVK{ - {Group: "foo.io", Kind: "Foo", Version: "v1"}, - {Group: "bar.io", Kind: "Bar", Version: "v1alpha1"}, - })) - }) - It("should return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - providedGvks, err := bundleEntity.ProvidedGVKs() - Expect(providedGvks).To(BeNil()) - Expect(err).ToNot(HaveOccurred()) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.gvk": "badGvkStructure", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - providedGvks, err := bundleEntity.ProvidedGVKs() - Expect(providedGvks).To(BeNil()) - Expect(err.Error()).To(Equal("error determining bundle provided gvks for entity 'operatorhub/prometheus/0.14.0': property 'olm.gvk' ('badGvkStructure') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - }) - - Describe("RequiredGVKs", func() { - It("should return the bundle required gvks if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.gvk.required": "[{\"group\":\"foo.io\",\"kind\":\"Foo\",\"version\":\"v1\"},{\"group\":\"bar.io\",\"kind\":\"Bar\",\"version\":\"v1alpha1\"}]", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - requiredGvks, err := bundleEntity.RequiredGVKs() - Expect(err).ToNot(HaveOccurred()) - Expect(requiredGvks).To(Equal([]olmentity.GVKRequired{ - {Group: "foo.io", Kind: "Foo", Version: "v1"}, - {Group: "bar.io", Kind: "Bar", Version: "v1alpha1"}, - })) - }) - It("should return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - requiredGvks, err := bundleEntity.RequiredGVKs() - Expect(requiredGvks).To(BeNil()) - Expect(err).ToNot(HaveOccurred()) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.gvk.required": "badGvkStructure", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - requiredGvks, err := bundleEntity.RequiredGVKs() - Expect(requiredGvks).To(BeNil()) - Expect(err.Error()).To(Equal("error determining bundle required gvks for entity 'operatorhub/prometheus/0.14.0': property 'olm.gvk.required' ('badGvkStructure') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - }) - - Describe("RequiredPackages", func() { - It("should return the bundle required packages if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.package.required": `[{"packageName": "packageA", "versionRange": ">1.0.0"}, {"packageName": "packageB", "versionRange": ">0.5.0 <0.8.6"}]`, - }) - bundleEntity := olmentity.NewBundleEntity(entity) - requiredPackages, err := bundleEntity.RequiredPackages() - Expect(err).ToNot(HaveOccurred()) - Expect(requiredPackages).To(Equal([]olmentity.PackageRequired{ - {PackageRequired: property.PackageRequired{PackageName: "packageA", VersionRange: ">1.0.0"}}, - {PackageRequired: property.PackageRequired{PackageName: "packageB", VersionRange: ">0.5.0 <0.8.6"}}, - })) - }) - It("should return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - requiredPackages, err := bundleEntity.RequiredPackages() - Expect(requiredPackages).To(BeNil()) - Expect(err).ToNot(HaveOccurred()) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.package.required": "badRequiredPackageStructure", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - requiredPackages, err := bundleEntity.RequiredPackages() - Expect(requiredPackages).To(BeNil()) - Expect(err.Error()).To(Equal("error determining bundle required packages for entity 'operatorhub/prometheus/0.14.0': property 'olm.package.required' ('badRequiredPackageStructure') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - }) - - Describe("ChannelName", func() { - It("should return the bundle channel name if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.channel": "{\"channelName\":\"beta\",\"priority\":0}", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - channelName, err := bundleEntity.ChannelName() - Expect(err).ToNot(HaveOccurred()) - Expect(channelName).To(Equal("beta")) - }) - It("should return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - channelName, err := bundleEntity.ChannelName() - Expect(channelName).To(BeEmpty()) - Expect(err.Error()).To(Equal("error determining bundle channel properties for entity 'operatorhub/prometheus/0.14.0': required property 'olm.channel' not found")) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.channel": "badChannelPropertiesStructure", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - channelName, err := bundleEntity.ChannelName() - Expect(channelName).To(BeEmpty()) - Expect(err.Error()).To(Equal("error determining bundle channel properties for entity 'operatorhub/prometheus/0.14.0': property 'olm.channel' ('badChannelPropertiesStructure') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - }) - - Describe("Channel", func() { - It("should return the bundle channel properties if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.channel": `{"channelName":"beta","priority":0, "replaces": "bundle.v1.0.0", "skips": ["bundle.v0.9.0", "bundle.v0.9.6"], "skipRange": ">=0.9.0 <=0.9.6"}`, - }) - bundleEntity := olmentity.NewBundleEntity(entity) - channelProperties, err := bundleEntity.Channel() - Expect(err).ToNot(HaveOccurred()) - Expect(*channelProperties).To(Equal(property.Channel{ - ChannelName: "beta", - Priority: 0, - }, - )) - }) - It("should return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - channelProperties, err := bundleEntity.Channel() - Expect(channelProperties).To(BeNil()) - Expect(err.Error()).To(Equal("error determining bundle channel properties for entity 'operatorhub/prometheus/0.14.0': required property 'olm.channel' not found")) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.channel": "badChannelPropertiesStructure", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - channelProperties, err := bundleEntity.Channel() - Expect(channelProperties).To(BeNil()) - Expect(err.Error()).To(Equal("error determining bundle channel properties for entity 'operatorhub/prometheus/0.14.0': property 'olm.channel' ('badChannelPropertiesStructure') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - }) - - Describe("BundlePath", func() { - It("should return the bundle channel properties if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.bundle.path": `"bundle.io/path/to/bundle"`, - }) - bundleEntity := olmentity.NewBundleEntity(entity) - bundlePath, err := bundleEntity.BundlePath() - Expect(err).ToNot(HaveOccurred()) - Expect(bundlePath).To(Equal("bundle.io/path/to/bundle")) - }) - It("should return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - bundlePath, err := bundleEntity.BundlePath() - Expect(bundlePath).To(BeEmpty()) - Expect(err.Error()).To(Equal("error determining bundle path for entity 'operatorhub/prometheus/0.14.0': required property 'olm.bundle.path' not found")) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - "olm.bundle.path": "badBundlePath", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - bundlePath, err := bundleEntity.BundlePath() - Expect(bundlePath).To(BeEmpty()) - Expect(err.Error()).To(Equal("error determining bundle path for entity 'operatorhub/prometheus/0.14.0': property 'olm.bundle.path' ('badBundlePath') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - }) - - Describe("ChannelEntry", func() { - It("should return the channel entry property if present", func() { - entity := input.NewEntity("test", map[string]string{ - "olm.bundle.channelEntry": `{"name":"test.v0.3.0","replaces": "test.v0.2.0"}`, - }) - bundleEntity := olmentity.NewBundleEntity(entity) - channelEntry, err := bundleEntity.BundleChannelEntry() - Expect(err).ToNot(HaveOccurred()) - Expect(channelEntry).To(Equal(&olmentity.ChannelEntry{Name: "test.v0.3.0", Replaces: "test.v0.2.0"})) - }) - It("should not return an error if the property is not found", func() { - entity := input.NewEntity("test", map[string]string{ - "olm.thingy": `{"whatever":"this"}`, - }) - bundleEntity := olmentity.NewBundleEntity(entity) - channelEntry, err := bundleEntity.BundleChannelEntry() - Expect(channelEntry).To(BeNil()) - Expect(err).To(HaveOccurred()) - }) - }) - - Describe("MediaType", func() { - It("should return the bundle mediatype property if present", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - olmentity.PropertyBundleMediaType: fmt.Sprintf(`"%s"`, olmentity.MediaTypePlain), - }) - bundleEntity := olmentity.NewBundleEntity(entity) - mediaType, err := bundleEntity.MediaType() - Expect(err).ToNot(HaveOccurred()) - Expect(mediaType).To(Equal(olmentity.MediaTypePlain)) - }) - It("should not return an error if the property is not found", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{}) - bundleEntity := olmentity.NewBundleEntity(entity) - mediaType, err := bundleEntity.MediaType() - Expect(mediaType).To(BeEmpty()) - Expect(err).ToNot(HaveOccurred()) - }) - It("should return error if the property is malformed", func() { - entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{ - olmentity.PropertyBundleMediaType: "badtype", - }) - bundleEntity := olmentity.NewBundleEntity(entity) - mediaType, err := bundleEntity.MediaType() - Expect(mediaType).To(BeEmpty()) - Expect(err.Error()).To(Equal("error determining bundle mediatype for entity 'operatorhub/prometheus/0.14.0': property 'olm.bundle.mediatype' ('badtype') could not be parsed: invalid character 'b' looking for beginning of value")) - }) - }) - - // Increase test coverage - Describe("GVKRequired properties", func() { - It("should return the GVKRequired properties", func() { - gvk := olmentity.GVKRequired{ - Group: "foo.io", - Kind: "Foo", - Version: "v1", - } - Expect(gvk.AsGVK().Version).To(Equal("v1")) - Expect(gvk.AsGVK().Group).To(Equal("foo.io")) - Expect(gvk.AsGVK().Kind).To(Equal("Foo")) - }) - It("should return the GVKRequired properties as a string", func() { - gvk := olmentity.GVKRequired{ - Group: "foo.io", - Kind: "Foo", - Version: "v1", - } - Expect(gvk.String()).To(Equal(`group:"foo.io" version:"v1" kind:"Foo"`)) - }) - }) - Describe("GVK properties", func() { - It("should return the gvk properties", func() { - gvk := olmentity.GVK{ - Group: "foo.io", - Kind: "Foo", - Version: "v1", - } - Expect(gvk.Version).To(Equal("v1")) - Expect(gvk.Group).To(Equal("foo.io")) - Expect(gvk.Kind).To(Equal("Foo")) - }) - It("should return the gvk properties as a string", func() { - gvk := olmentity.GVK{ - Group: "foo.io", - Kind: "Foo", - Version: "v1", - } - Expect(gvk.String()).To(Equal(`group:"foo.io" version:"v1" kind:"Foo"`)) - }) - }) -}) diff --git a/internal/resolution/util/predicates/predicates.go b/internal/resolution/util/predicates/predicates.go index aa351b9e8..2cfa3ce48 100644 --- a/internal/resolution/util/predicates/predicates.go +++ b/internal/resolution/util/predicates/predicates.go @@ -2,15 +2,16 @@ package predicates import ( bsemver "github.com/blang/semver/v4" - "github.com/operator-framework/deppy/pkg/deppy/input" - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" + olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" ) -func WithPackageName(packageName string) input.Predicate { - return func(entity *input.Entity) bool { - bundleEntity := olmentity.NewBundleEntity(entity) - name, err := bundleEntity.PackageName() +type Predicate func(variable *olmvariables.BundleVariable) bool + +func WithPackageName(packageName string) Predicate { + return func(variable *olmvariables.BundleVariable) bool { + bundleVariable := olmvariables.NewBundleVariable(variable, make([]*olmvariables.BundleVariable, 0), variable.Properties) + name, err := bundleVariable.PackageName() if err != nil { return false } @@ -18,10 +19,10 @@ func WithPackageName(packageName string) input.Predicate { } } -func InSemverRange(semverRange bsemver.Range) input.Predicate { - return func(entity *input.Entity) bool { - bundleEntity := olmentity.NewBundleEntity(entity) - bundleVersion, err := bundleEntity.Version() +func InSemverRange(semverRange bsemver.Range) Predicate { + return func(variable *olmvariables.BundleVariable) bool { + bundleVariable := olmvariables.NewBundleVariable(variable, make([]*olmvariables.BundleVariable, 0), variable.Properties) + bundleVersion, err := bundleVariable.Version() if err != nil { return false } @@ -29,10 +30,10 @@ func InSemverRange(semverRange bsemver.Range) input.Predicate { } } -func InChannel(channelName string) input.Predicate { - return func(entity *input.Entity) bool { - bundleEntity := olmentity.NewBundleEntity(entity) - bundleChannel, err := bundleEntity.ChannelName() +func InChannel(channelName string) Predicate { + return func(variable *olmvariables.BundleVariable) bool { + bundleVariable := olmvariables.NewBundleVariable(variable, make([]*olmvariables.BundleVariable, 0), variable.Properties) + bundleChannel, err := bundleVariable.ChannelName() if err != nil { return false } @@ -40,10 +41,10 @@ func InChannel(channelName string) input.Predicate { } } -func ProvidesGVK(gvk *olmentity.GVK) input.Predicate { - return func(entity *input.Entity) bool { - bundleEntity := olmentity.NewBundleEntity(entity) - providedGVKs, err := bundleEntity.ProvidedGVKs() +func ProvidesGVK(gvk *olmvariables.GVK) Predicate { + return func(variable *olmvariables.BundleVariable) bool { + bundleVariable := olmvariables.NewBundleVariable(variable, make([]*olmvariables.BundleVariable, 0), variable.Properties) + providedGVKs, err := bundleVariable.ProvidedGVKs() if err != nil { return false } @@ -57,10 +58,10 @@ func ProvidesGVK(gvk *olmentity.GVK) input.Predicate { } } -func WithBundleImage(bundleImage string) input.Predicate { - return func(entity *input.Entity) bool { - bundleEntity := olmentity.NewBundleEntity(entity) - bundlePath, err := bundleEntity.BundlePath() +func WithBundleImage(bundleImage string) Predicate { + return func(variable *olmvariables.BundleVariable) bool { + bundleVariable := olmvariables.NewBundleVariable(variable, make([]*olmvariables.BundleVariable, 0), variable.Properties) + bundlePath, err := bundleVariable.BundlePath() if err != nil { return false } @@ -68,10 +69,10 @@ func WithBundleImage(bundleImage string) input.Predicate { } } -func Replaces(bundleID string) input.Predicate { - return func(entity *input.Entity) bool { - bundleEntity := olmentity.NewBundleEntity(entity) - replaces, err := bundleEntity.BundleChannelEntry() +func Replaces(bundleID string) Predicate { + return func(variable *olmvariables.BundleVariable) bool { + bundleVariable := olmvariables.NewBundleVariable(variable, make([]*olmvariables.BundleVariable, 0), variable.Properties) + replaces, err := bundleVariable.BundleChannelEntry() if err != nil { return false } diff --git a/internal/resolution/util/sort/sort.go b/internal/resolution/util/sort/sort.go index d013b982f..c5f0cf559 100644 --- a/internal/resolution/util/sort/sort.go +++ b/internal/resolution/util/sort/sort.go @@ -3,33 +3,28 @@ package sort import ( "strings" - "github.com/operator-framework/deppy/pkg/deppy/input" - - "github.com/operator-framework/operator-controller/internal/resolution/entities" + "github.com/operator-framework/operator-controller/internal/resolution/variables" ) // ByChannelAndVersion is an entity sort function that orders the entities in // package, channel (default channel at the head), and inverse version (higher versions on top) // if a property does not exist for one of the entities, the one missing the property is pushed down // if both entities are missing the same property they are ordered by id -func ByChannelAndVersion(entity1 *input.Entity, entity2 *input.Entity) bool { - e1 := entities.NewBundleEntity(entity1) - e2 := entities.NewBundleEntity(entity2) - +func ByChannelAndVersion(variable1 *variables.BundleVariable, variable2 *variables.BundleVariable) bool { // first sort package lexical order - pkgOrder := packageOrder(e1, e2) + pkgOrder := packageOrder(variable1, variable2) if pkgOrder != 0 { return pkgOrder < 0 } // todo(perdasilva): handle default channel in ordering once it is being exposed by the entity - channelOrder := channelOrder(e1, e2) + channelOrder := channelOrder(variable1, variable2) if channelOrder != 0 { return channelOrder < 0 } // order version from highest to lowest (favor the latest release) - versionOrder := versionOrder(e1, e2) + versionOrder := versionOrder(variable1, variable2) return versionOrder > 0 } @@ -44,9 +39,9 @@ func compareErrors(err1 error, err2 error) int { return 0 } -func packageOrder(e1, e2 *entities.BundleEntity) int { - name1, err1 := e1.PackageName() - name2, err2 := e2.PackageName() +func packageOrder(var1, var2 *variables.BundleVariable) int { + name1, err1 := var1.PackageName() + name2, err2 := var2.PackageName() errComp := compareErrors(err1, err2) if errComp != 0 { return errComp @@ -54,9 +49,9 @@ func packageOrder(e1, e2 *entities.BundleEntity) int { return strings.Compare(name1, name2) } -func channelOrder(e1, e2 *entities.BundleEntity) int { - channelProperties1, err1 := e1.Channel() - channelProperties2, err2 := e2.Channel() +func channelOrder(var1, var2 *variables.BundleVariable) int { + channelProperties1, err1 := var1.Channel() + channelProperties2, err2 := var2.Channel() errComp := compareErrors(err1, err2) if errComp != 0 { return errComp @@ -67,9 +62,9 @@ func channelOrder(e1, e2 *entities.BundleEntity) int { return strings.Compare(channelProperties1.ChannelName, channelProperties2.ChannelName) } -func versionOrder(e1, e2 *entities.BundleEntity) int { - ver1, err1 := e1.Version() - ver2, err2 := e2.Version() +func versionOrder(var1, var2 *variables.BundleVariable) int { + ver1, err1 := var1.Version() + ver2, err2 := var2.Version() errComp := compareErrors(err1, err2) if errComp != 0 { // the sign gets inverted because version is sorted diff --git a/internal/resolution/variables/bundle.go b/internal/resolution/variables/bundle.go index dce8bed50..4a2e13800 100644 --- a/internal/resolution/variables/bundle.go +++ b/internal/resolution/variables/bundle.go @@ -1,32 +1,96 @@ package variables import ( + "encoding/json" + "fmt" + "sync" + "github.com/operator-framework/deppy/pkg/deppy" "github.com/operator-framework/deppy/pkg/deppy/constraint" "github.com/operator-framework/deppy/pkg/deppy/input" + "github.com/operator-framework/operator-registry/alpha/property" + + bsemver "github.com/blang/semver/v4" +) - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" +const PropertyBundlePath = "olm.bundle.path" +const PropertyBundleChannelEntry = "olm.bundle.channelEntry" +const PropertyBundleMediaType = "olm.bundle.mediatype" + +type MediaType string + +const ( + MediaTypePlain = "plain+v0" + MediaTypeRegistry = "registry+v1" ) +// ---- + +type propertyRequirement bool + +const ( + required propertyRequirement = true + optional propertyRequirement = false +) + +type PackageRequired struct { + property.PackageRequired + SemverRange *bsemver.Range `json:"-"` +} + +type GVK property.GVK + +type ChannelEntry struct { + Name string `json:"name"` + Replaces string `json:"replaces"` + // Skips and skipRange will probably go here as well +} + +func (g GVK) String() string { + return fmt.Sprintf(`group:"%s" version:"%s" kind:"%s"`, g.Group, g.Version, g.Kind) +} + +type GVKRequired property.GVKRequired + +func (g GVKRequired) String() string { + return fmt.Sprintf(`group:"%s" version:"%s" kind:"%s"`, g.Group, g.Version, g.Kind) +} + +func (g GVKRequired) AsGVK() GVK { + return GVK(g) +} + var _ deppy.Variable = &BundleVariable{} type BundleVariable struct { *input.SimpleVariable - bundleEntity *olmentity.BundleEntity - dependencies []*olmentity.BundleEntity -} + ID deppy.Identifier + Properties map[string]string + dependencies []*BundleVariable -func (b *BundleVariable) BundleEntity() *olmentity.BundleEntity { - return b.bundleEntity + // these properties are lazy loaded as they are requested + bundlePackage *property.Package + providedGVKs []GVK + requiredGVKs []GVKRequired + requiredPackages []PackageRequired + channel *property.Channel + channelEntry *ChannelEntry + semVersion *bsemver.Version + bundlePath string + mediaType string + mu sync.RWMutex } -func (b *BundleVariable) Dependencies() []*olmentity.BundleEntity { +type BundleList []BundleVariable +type BundleListMap map[string]BundleList + +func (b *BundleVariable) Dependencies() []*BundleVariable { return b.dependencies } -func NewBundleVariable(bundleEntity *olmentity.BundleEntity, dependencyBundleEntities []*olmentity.BundleEntity) *BundleVariable { - dependencyIDs := make([]deppy.Identifier, 0, len(dependencyBundleEntities)) - for _, bundle := range dependencyBundleEntities { +func NewBundleVariable(variable deppy.Variable, dependencyBundleVariables []*BundleVariable, properties map[string]string) *BundleVariable { + dependencyIDs := make([]deppy.Identifier, 0, len(dependencyBundleVariables)) + for _, bundle := range dependencyBundleVariables { dependencyIDs = append(dependencyIDs, bundle.ID) } var constraints []deppy.Constraint @@ -34,9 +98,10 @@ func NewBundleVariable(bundleEntity *olmentity.BundleEntity, dependencyBundleEnt constraints = append(constraints, constraint.Dependency(dependencyIDs...)) } return &BundleVariable{ - SimpleVariable: input.NewSimpleVariable(bundleEntity.ID, constraints...), - bundleEntity: bundleEntity, - dependencies: dependencyBundleEntities, + SimpleVariable: input.NewSimpleVariable(variable.Identifier(), constraints...), + dependencies: dependencyBundleVariables, + mu: sync.RWMutex{}, + Properties: properties, } } @@ -56,3 +121,207 @@ func NewBundleUniquenessVariable(id deppy.Identifier, atMostIDs ...deppy.Identif SimpleVariable: input.NewSimpleVariable(id, constraint.AtMost(1, atMostIDs...)), } } + +func (b *BundleVariable) PackageName() (string, error) { + if err := b.loadPackage(); err != nil { + return "", err + } + return b.bundlePackage.PackageName, nil +} + +func (b *BundleVariable) Version() (*bsemver.Version, error) { + if err := b.loadPackage(); err != nil { + return nil, err + } + return b.semVersion, nil +} + +func (b *BundleVariable) ProvidedGVKs() ([]GVK, error) { + if err := b.loadProvidedGVKs(); err != nil { + return nil, err + } + return b.providedGVKs, nil +} + +func (b *BundleVariable) RequiredGVKs() ([]GVKRequired, error) { + if err := b.loadRequiredGVKs(); err != nil { + return nil, err + } + return b.requiredGVKs, nil +} + +func (b *BundleVariable) RequiredPackages() ([]PackageRequired, error) { + if err := b.loadRequiredPackages(); err != nil { + return nil, err + } + return b.requiredPackages, nil +} + +func (b *BundleVariable) ChannelName() (string, error) { + if err := b.loadChannelProperties(); err != nil { + return "", err + } + return b.channel.ChannelName, nil +} + +func (b *BundleVariable) Channel() (*property.Channel, error) { + if err := b.loadChannelProperties(); err != nil { + return nil, err + } + return b.channel, nil +} + +func (b *BundleVariable) BundleChannelEntry() (*ChannelEntry, error) { + if err := b.loadBundleChannelEntry(); err != nil { + return nil, err + } + return b.channelEntry, nil +} + +func (b *BundleVariable) loadBundleChannelEntry() error { + b.mu.Lock() + defer b.mu.Unlock() + if b.channelEntry == nil { + channelEntry, err := loadFromVariable[*ChannelEntry](b, PropertyBundleChannelEntry, optional) + if err != nil || channelEntry == nil { + return fmt.Errorf("error determining replaces for variable '%s': %w", b.ID, err) + } + b.channelEntry = channelEntry + } + return nil +} + +func (b *BundleVariable) BundlePath() (string, error) { + if err := b.loadBundlePath(); err != nil { + return "", err + } + return b.bundlePath, nil +} + +func (b *BundleVariable) MediaType() (string, error) { + if err := b.loadMediaType(); err != nil { + return "", err + } + + return b.mediaType, nil +} + +func (b *BundleVariable) loadMediaType() error { + b.mu.Lock() + defer b.mu.Unlock() + if b.mediaType == "" { + mediaType, err := loadFromVariable[string](b, PropertyBundleMediaType, optional) + if err != nil { + return fmt.Errorf("error determining bundle mediatype for entity '%s': %w", b.ID, err) + } + b.mediaType = mediaType + } + return nil +} + +func (b *BundleVariable) loadPackage() error { + b.mu.Lock() + defer b.mu.Unlock() + if b.bundlePackage == nil { + bundlePackage, err := loadFromVariable[property.Package](b, property.TypePackage, required) + if err != nil { + return fmt.Errorf("error determining package for entity '%s': %w", b.ID, err) + } + b.bundlePackage = &bundlePackage + if b.semVersion == nil { + semVer, err := bsemver.Parse(b.bundlePackage.Version) + if err != nil { + return fmt.Errorf("could not parse semver (%s) for entity '%s': %w", b.bundlePackage.Version, b.ID, err) + } + b.semVersion = &semVer + } + } + return nil +} + +func (b *BundleVariable) loadProvidedGVKs() error { + b.mu.Lock() + defer b.mu.Unlock() + if b.providedGVKs == nil { + providedGVKs, err := loadFromVariable[[]GVK](b, property.TypeGVK, optional) + if err != nil { + return fmt.Errorf("error determining bundle provided gvks for entity '%s': %w", b.ID, err) + } + b.providedGVKs = providedGVKs + } + return nil +} + +func (b *BundleVariable) loadRequiredGVKs() error { + b.mu.Lock() + defer b.mu.Unlock() + if b.requiredGVKs == nil { + requiredGVKs, err := loadFromVariable[[]GVKRequired](b, property.TypeGVKRequired, optional) + if err != nil { + return fmt.Errorf("error determining bundle required gvks for entity '%s': %w", b.ID, err) + } + b.requiredGVKs = requiredGVKs + } + return nil +} + +func (b *BundleVariable) loadRequiredPackages() error { + b.mu.Lock() + defer b.mu.Unlock() + if b.requiredPackages == nil { + requiredPackages, err := loadFromVariable[[]PackageRequired](b, property.TypePackageRequired, optional) + if err != nil { + return fmt.Errorf("error determining bundle required packages for entity '%s': %w", b.ID, err) + } + for _, requiredPackage := range requiredPackages { + semverRange, err := bsemver.ParseRange(requiredPackage.VersionRange) + if err != nil { + return fmt.Errorf("error determining bundle required package semver range for entity '%s': '%w'", b.ID, err) + } + requiredPackage.SemverRange = &semverRange + } + b.requiredPackages = requiredPackages + } + return nil +} + +func (b *BundleVariable) loadChannelProperties() error { + b.mu.Lock() + defer b.mu.Unlock() + if b.channel == nil { + channel, err := loadFromVariable[property.Channel](b, property.TypeChannel, required) + if err != nil { + return fmt.Errorf("error determining bundle channel properties for entity '%s': %w", b.ID, err) + } + b.channel = &channel + } + return nil +} + +func (b *BundleVariable) loadBundlePath() error { + b.mu.Lock() + defer b.mu.Unlock() + if b.bundlePath == "" { + bundlePath, err := loadFromVariable[string](b, PropertyBundlePath, required) + if err != nil { + return fmt.Errorf("error determining bundle path for entity '%s': %w", b.ID, err) + } + b.bundlePath = bundlePath + } + return nil +} + +func loadFromVariable[T interface{}](variable *BundleVariable, propertyName string, required propertyRequirement) (T, error) { + deserializedProperty := *new(T) + propertyValue, ok := variable.Properties[propertyName] + if ok { + // TODO: In order to avoid invalid properties we should use a decoder that only allows the properties we expect. + // ie. decoder.DisallowUnknownFields() + if err := json.Unmarshal([]byte(propertyValue), &deserializedProperty); err != nil { + return deserializedProperty, fmt.Errorf("property '%s' ('%s') could not be parsed: %w", propertyName, propertyValue, err) + } + } else if required { + return deserializedProperty, fmt.Errorf("required property '%s' not found", propertyName) + } + return deserializedProperty, nil +} diff --git a/internal/resolution/variables/catalogd.go b/internal/resolution/variables/catalogd.go new file mode 100644 index 000000000..33968ad25 --- /dev/null +++ b/internal/resolution/variables/catalogd.go @@ -0,0 +1,13 @@ +package variables + +import ( + "github.com/operator-framework/deppy/pkg/deppy" + "github.com/operator-framework/deppy/pkg/deppy/input" +) + +var _ deppy.Variable = &CatalogdVariable{} + +type CatalogdVariable struct { + *input.SimpleVariable + dependencies []*BundleVariable +} diff --git a/internal/resolution/variables/installed_package.go b/internal/resolution/variables/installed_package.go index 0d176b81a..4885575ac 100644 --- a/internal/resolution/variables/installed_package.go +++ b/internal/resolution/variables/installed_package.go @@ -6,29 +6,27 @@ import ( "github.com/operator-framework/deppy/pkg/deppy" "github.com/operator-framework/deppy/pkg/deppy/constraint" "github.com/operator-framework/deppy/pkg/deppy/input" - - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" ) var _ deppy.Variable = &InstalledPackageVariable{} type InstalledPackageVariable struct { *input.SimpleVariable - bundleEntities []*olmentity.BundleEntity + bundleVariables []*BundleVariable } -func (r *InstalledPackageVariable) BundleEntities() []*olmentity.BundleEntity { - return r.bundleEntities +func (r *InstalledPackageVariable) BundleVariables() []*BundleVariable { + return r.bundleVariables } -func NewInstalledPackageVariable(packageName string, bundleEntities []*olmentity.BundleEntity) *InstalledPackageVariable { +func NewInstalledPackageVariable(packageName string, bundleVariables []*BundleVariable) *InstalledPackageVariable { id := deppy.IdentifierFromString(fmt.Sprintf("installed package %s", packageName)) - entityIDs := make([]deppy.Identifier, 0, len(bundleEntities)) - for _, bundle := range bundleEntities { - entityIDs = append(entityIDs, bundle.ID) + variableIDs := make([]deppy.Identifier, 0, len(bundleVariables)) + for _, bundle := range bundleVariables { + variableIDs = append(variableIDs, bundle.ID) } return &InstalledPackageVariable{ - SimpleVariable: input.NewSimpleVariable(id, constraint.Mandatory(), constraint.Dependency(entityIDs...)), - bundleEntities: bundleEntities, + SimpleVariable: input.NewSimpleVariable(id, constraint.Mandatory(), constraint.Dependency(variableIDs...)), + bundleVariables: bundleVariables, } } diff --git a/internal/resolution/variables/required_package.go b/internal/resolution/variables/required_package.go index d2916f5f3..c3456ac6a 100644 --- a/internal/resolution/variables/required_package.go +++ b/internal/resolution/variables/required_package.go @@ -6,29 +6,27 @@ import ( "github.com/operator-framework/deppy/pkg/deppy" "github.com/operator-framework/deppy/pkg/deppy/constraint" "github.com/operator-framework/deppy/pkg/deppy/input" - - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" ) var _ deppy.Variable = &RequiredPackageVariable{} type RequiredPackageVariable struct { *input.SimpleVariable - bundleEntities []*olmentity.BundleEntity + bundleVariables []*BundleVariable } -func (r *RequiredPackageVariable) BundleEntities() []*olmentity.BundleEntity { - return r.bundleEntities +func (r *RequiredPackageVariable) BundleVariables() []*BundleVariable { + return r.bundleVariables } -func NewRequiredPackageVariable(packageName string, bundleEntities []*olmentity.BundleEntity) *RequiredPackageVariable { +func NewRequiredPackageVariable(packageName string, bundleVariables []*BundleVariable) *RequiredPackageVariable { id := deppy.IdentifierFromString(fmt.Sprintf("required package %s", packageName)) - entityIDs := make([]deppy.Identifier, 0, len(bundleEntities)) - for _, bundle := range bundleEntities { - entityIDs = append(entityIDs, bundle.ID) + variableIDs := make([]deppy.Identifier, 0, len(bundleVariables)) + for _, bundle := range bundleVariables { + variableIDs = append(variableIDs, bundle.ID) } return &RequiredPackageVariable{ - SimpleVariable: input.NewSimpleVariable(id, constraint.Mandatory(), constraint.Dependency(entityIDs...)), - bundleEntities: bundleEntities, + SimpleVariable: input.NewSimpleVariable(id, constraint.Mandatory(), constraint.Dependency(variableIDs...)), + bundleVariables: bundleVariables, } } diff --git a/internal/resolution/variablesources/bundle_deployment.go b/internal/resolution/variablesources/bundle_deployment.go index 4363d6bc2..2f68db98c 100644 --- a/internal/resolution/variablesources/bundle_deployment.go +++ b/internal/resolution/variablesources/bundle_deployment.go @@ -23,7 +23,7 @@ func NewBundleDeploymentVariableSource(cl client.Client, inputVariableSource inp } } -func (o *BundleDeploymentVariableSource) GetVariables(ctx context.Context, entitySource input.EntitySource) ([]deppy.Variable, error) { +func (o *BundleDeploymentVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { variableSources := SliceVariableSource{} if o.inputVariableSource != nil { variableSources = append(variableSources, o.inputVariableSource) @@ -50,5 +50,5 @@ func (o *BundleDeploymentVariableSource) GetVariables(ctx context.Context, entit } } - return variableSources.GetVariables(ctx, entitySource) + return variableSources.GetVariables(ctx) } diff --git a/internal/resolution/variablesources/bundles_and_dependencies.go b/internal/resolution/variablesources/bundles_and_dependencies.go index 0301487e4..733508a40 100644 --- a/internal/resolution/variablesources/bundles_and_dependencies.go +++ b/internal/resolution/variablesources/bundles_and_dependencies.go @@ -9,9 +9,8 @@ import ( "github.com/operator-framework/deppy/pkg/deppy" "github.com/operator-framework/deppy/pkg/deppy/input" - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" "github.com/operator-framework/operator-controller/internal/resolution/util/predicates" - entitysort "github.com/operator-framework/operator-controller/internal/resolution/util/sort" + variablesort "github.com/operator-framework/operator-controller/internal/resolution/util/sort" olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" ) @@ -27,12 +26,12 @@ func NewBundlesAndDepsVariableSource(inputVariableSources ...input.VariableSourc } } -func (b *BundlesAndDepsVariableSource) GetVariables(ctx context.Context, entitySource input.EntitySource) ([]deppy.Variable, error) { +func (b *BundlesAndDepsVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { var variables []deppy.Variable // extract required package variables for _, variableSource := range b.variableSources { - inputVariables, err := variableSource.GetVariables(ctx, entitySource) + inputVariables, err := variableSource.GetVariables(ctx) if err != nil { return nil, err } @@ -40,22 +39,22 @@ func (b *BundlesAndDepsVariableSource) GetVariables(ctx context.Context, entityS } // create bundle queue for dependency resolution - var bundleEntityQueue []*olmentity.BundleEntity + var bundleVariableQueue []*olmvariables.BundleVariable for _, variable := range variables { switch v := variable.(type) { case *olmvariables.RequiredPackageVariable: - bundleEntityQueue = append(bundleEntityQueue, v.BundleEntities()...) + bundleVariableQueue = append(bundleVariableQueue, v.BundleVariables()...) case *olmvariables.InstalledPackageVariable: - bundleEntityQueue = append(bundleEntityQueue, v.BundleEntities()...) + bundleVariableQueue = append(bundleVariableQueue, v.BundleVariables()...) } } // build bundle and dependency variables visited := map[deppy.Identifier]struct{}{} - for len(bundleEntityQueue) > 0 { + for len(bundleVariableQueue) > 0 { // pop head of queue - var head *olmentity.BundleEntity - head, bundleEntityQueue = bundleEntityQueue[0], bundleEntityQueue[1:] + var head *olmvariables.BundleVariable + head, bundleVariableQueue = bundleVariableQueue[0], bundleVariableQueue[1:] // ignore bundles that have already been processed if _, ok := visited[head.ID]; ok { @@ -64,28 +63,28 @@ func (b *BundlesAndDepsVariableSource) GetVariables(ctx context.Context, entityS visited[head.ID] = struct{}{} // get bundle dependencies - dependencyEntityBundles, err := b.getEntityDependencies(ctx, head, entitySource) + dependencyBundleVariables, err := b.getVariableDependencies(ctx, head) if err != nil { - return nil, fmt.Errorf("could not determine dependencies for entity with id '%s': %w", head.ID, err) + return nil, fmt.Errorf("could not determine dependencies for variable with id '%s': %w", head.ID, err) } // add bundle dependencies to queue for processing - bundleEntityQueue = append(bundleEntityQueue, dependencyEntityBundles...) + bundleVariableQueue = append(bundleVariableQueue, dependencyBundleVariables...) // create variable - variables = append(variables, olmvariables.NewBundleVariable(head, dependencyEntityBundles)) + variables = append(variables, olmvariables.NewBundleVariable(head, dependencyBundleVariables, head.Properties)) } return variables, nil } -func (b *BundlesAndDepsVariableSource) getEntityDependencies(ctx context.Context, bundleEntity *olmentity.BundleEntity, entitySource input.EntitySource) ([]*olmentity.BundleEntity, error) { - var dependencies []*olmentity.BundleEntity +func (b *BundlesAndDepsVariableSource) getVariableDependencies(ctx context.Context, bundleVariable *olmvariables.BundleVariable) ([]*olmvariables.BundleVariable, error) { + var dependencies []*olmvariables.BundleVariable added := map[deppy.Identifier]struct{}{} // gather required package dependencies // todo(perdasilva): disambiguate between not found and actual errors - requiredPackages, _ := bundleEntity.RequiredPackages() + requiredPackages, _ := bundleVariable.RequiredPackages() for _, requiredPackage := range requiredPackages { semverRange, err := bsemver.ParseRange(requiredPackage.VersionRange) if err != nil { @@ -96,20 +95,20 @@ func (b *BundlesAndDepsVariableSource) getEntityDependencies(ctx context.Context return nil, err } if len(packageDependencyBundles) == 0 { - return nil, fmt.Errorf("could not find package dependencies for bundle '%s'", bundleEntity.ID) + return nil, fmt.Errorf("could not find package dependencies for bundle '%s'", bundleVariable.ID) } for i := 0; i < len(packageDependencyBundles); i++ { - entity := packageDependencyBundles[i] - if _, ok := added[entity.ID]; !ok { - dependencies = append(dependencies, olmentity.NewBundleEntity(&entity)) - added[entity.ID] = struct{}{} + variable := packageDependencyBundles[i] + if _, ok := added[variable.ID]; !ok { + dependencies = append(dependencies, olmvariables.NewBundleVariable(&variable, make([]*olmvariables.BundleVariable, 0), variable.Properties)) + added[variable.ID] = struct{}{} } } } // gather required gvk dependencies // todo(perdasilva): disambiguate between not found and actual errors - gvkDependencies, _ := bundleEntity.RequiredGVKs() + gvkDependencies, _ := bundleVariable.RequiredGVKs() for i := 0; i < len(gvkDependencies); i++ { providedGvk := gvkDependencies[i].AsGVK() gvkDependencyBundles, err := entitySource.Filter(ctx, predicates.ProvidesGVK(&providedGvk)) @@ -117,20 +116,20 @@ func (b *BundlesAndDepsVariableSource) getEntityDependencies(ctx context.Context return nil, err } if len(gvkDependencyBundles) == 0 { - return nil, fmt.Errorf("could not find gvk dependencies for bundle '%s'", bundleEntity.ID) + return nil, fmt.Errorf("could not find gvk dependencies for bundle '%s'", bundleVariable.ID) } for i := 0; i < len(gvkDependencyBundles); i++ { - entity := gvkDependencyBundles[i] - if _, ok := added[entity.ID]; !ok { - dependencies = append(dependencies, olmentity.NewBundleEntity(&entity)) - added[entity.ID] = struct{}{} + variable := gvkDependencyBundles[i] + if _, ok := added[variable.ID]; !ok { + dependencies = append(dependencies, olmvariables.NewBundleVariable(&variable, make([]*olmvariables.BundleVariable, 0), variable.Properties)) + added[variable.ID] = struct{}{} } } } // sort bundles in version order sort.SliceStable(dependencies, func(i, j int) bool { - return entitysort.ByChannelAndVersion(dependencies[i].Entity, dependencies[j].Entity) + return variablesort.ByChannelAndVersion(dependencies[i], dependencies[j]) }) return dependencies, nil diff --git a/internal/resolution/entitysources/catalogdsource.go b/internal/resolution/variablesources/catalogdsource.go similarity index 62% rename from internal/resolution/entitysources/catalogdsource.go rename to internal/resolution/variablesources/catalogdsource.go index 106f893f8..5e263b696 100644 --- a/internal/resolution/entitysources/catalogdsource.go +++ b/internal/resolution/variablesources/catalogdsource.go @@ -1,4 +1,4 @@ -package entitysources +package variablesources import ( "context" @@ -12,26 +12,46 @@ import ( "github.com/operator-framework/operator-registry/alpha/property" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/operator-framework/operator-controller/internal/resolution/entities" + olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" ) -// CatalogdEntitySource is a source for(/collection of) deppy defined input.Entity, built from content +// TODO update comment +// CatalogdVariableSource is a source for(/collection of) deppy defined input.Entity, built from content // made accessible on-cluster by https://github.com/operator-framework/catalogd. // It is an implementation of deppy defined input.EntitySource -type CatalogdEntitySource struct { +type CatalogdVariableSource struct { client client.Client } -func NewCatalogdEntitySource(client client.Client) *CatalogdEntitySource { - return &CatalogdEntitySource{client: client} +func NewCatalogdVariableSource(client client.Client) *CatalogdVariableSource { + return &CatalogdVariableSource{client: client} } -func (es *CatalogdEntitySource) Get(_ context.Context, _ deppy.Identifier) (*input.Entity, error) { - panic("not implemented") +func (vs *CatalogdVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { + var variables []deppy.Variable + var catalogList catalogd.CatalogList + if err := vs.client.List(ctx, &catalogList); err != nil { + return nil, err + } + for _, catalog := range catalogList.Items { + channels, bundles, err := fetchCatalogMetadata(ctx, vs.client, catalog.Name) + if err != nil { + return nil, err + } + + catalogVariablesList, err := MetadataToVariables(catalog.Name, channels, bundles) + if err != nil { + return nil, err + } + + variables = append(variables, catalogVariablesList...) + } + + return variables, nil } -func (es *CatalogdEntitySource) Filter(ctx context.Context, filter input.Predicate) (input.EntityList, error) { - resultSet := input.EntityList{} +func (es *CatalogdVariableSource) Filter(ctx context.Context, filter input.Predicate) ([]deppy.Variable, error) { + resultSet := make([]deppy.Variable, 0) entities, err := getEntities(ctx, es.client) if err != nil { return nil, err @@ -44,12 +64,12 @@ func (es *CatalogdEntitySource) Filter(ctx context.Context, filter input.Predica return resultSet, nil } -func (es *CatalogdEntitySource) GroupBy(ctx context.Context, fn input.GroupByFunction) (input.EntityListMap, error) { +func (es *CatalogdVariableSource) GroupBy(ctx context.Context, fn input.GroupByFunction) (map[string][]deppy.Variable, error) { entities, err := getEntities(ctx, es.client) if err != nil { return nil, err } - resultSet := input.EntityListMap{} + resultSet := map[string][]deppy.Variable{} for i := range entities { keys := fn(&entities[i]) for _, key := range keys { @@ -59,7 +79,7 @@ func (es *CatalogdEntitySource) GroupBy(ctx context.Context, fn input.GroupByFun return resultSet, nil } -func (es *CatalogdEntitySource) Iterate(ctx context.Context, fn input.IteratorFunction) error { +func (es *CatalogdVariableSource) Iterate(ctx context.Context, fn input.IteratorFunction) error { entities, err := getEntities(ctx, es.client) if err != nil { return err @@ -72,8 +92,8 @@ func (es *CatalogdEntitySource) Iterate(ctx context.Context, fn input.IteratorFu return nil } -func getEntities(ctx context.Context, cl client.Client) (input.EntityList, error) { - allEntitiesList := input.EntityList{} +func getEntities(ctx context.Context, cl client.Client) ([]deppy.Variable, error) { + allEntitiesList := make([]deppy.Variable, 0) var catalogList catalogd.CatalogList if err := cl.List(ctx, &catalogList); err != nil { @@ -85,7 +105,7 @@ func getEntities(ctx context.Context, cl client.Client) (input.EntityList, error return nil, err } - catalogEntitiesList, err := MetadataToEntities(catalog.Name, channels, bundles) + catalogEntitiesList, err := MetadataToVariables(catalog.Name, channels, bundles) if err != nil { return nil, err } @@ -96,8 +116,8 @@ func getEntities(ctx context.Context, cl client.Client) (input.EntityList, error return allEntitiesList, nil } -func MetadataToEntities(catalogName string, channels []declcfg.Channel, bundles []declcfg.Bundle) (input.EntityList, error) { - entityList := input.EntityList{} +func MetadataToVariables(catalogName string, channels []declcfg.Channel, bundles []declcfg.Bundle) ([]deppy.Variable, error) { + var variables []deppy.Variable bundlesMap := map[string]*declcfg.Bundle{} for i := range bundles { @@ -121,8 +141,8 @@ func MetadataToEntities(catalogName string, channels []declcfg.Channel, bundles // this is already a json marshalled object, so it doesn't need to be marshalled // like the other ones props[property.TypePackage] = string(prop.Value) - case entities.PropertyBundleMediaType: - props[entities.PropertyBundleMediaType] = string(prop.Value) + case olmvariables.PropertyBundleMediaType: + props[olmvariables.PropertyBundleMediaType] = string(prop.Value) } } @@ -130,26 +150,26 @@ func MetadataToEntities(catalogName string, channels []declcfg.Channel, bundles if err != nil { return nil, err } - props[entities.PropertyBundlePath] = string(imgValue) + props[olmvariables.PropertyBundlePath] = string(imgValue) channelValue, _ := json.Marshal(property.Channel{ChannelName: ch.Name, Priority: 0}) props[property.TypeChannel] = string(channelValue) - replacesValue, _ := json.Marshal(entities.ChannelEntry{ + replacesValue, _ := json.Marshal(olmvariables.ChannelEntry{ Name: bundle.Name, Replaces: chEntry.Replaces, }) - props[entities.PropertyBundleChannelEntry] = string(replacesValue) + props[olmvariables.PropertyBundleChannelEntry] = string(replacesValue) catalogScopedEntryName := fmt.Sprintf("%s-%s", catalogName, bundle.Name) - entity := input.Entity{ - ID: deppy.IdentifierFromString(fmt.Sprintf("%s%s%s", catalogScopedEntryName, bundle.Package, ch.Name)), - Properties: props, - } - entityList = append(entityList, entity) + variable := olmvariables.NewBundleVariable( + input.NewSimpleVariable(deppy.IdentifierFromString(fmt.Sprintf("%s%s%s", catalogScopedEntryName, bundle.Package, ch.Name))), + make([]*olmvariables.BundleVariable, 0), + props) + variables = append(variables, variable) } } - return entityList, nil + return variables, nil } func fetchCatalogMetadata(ctx context.Context, cl client.Client, catalogName string) ([]declcfg.Channel, []declcfg.Bundle, error) { diff --git a/internal/resolution/variablesources/composite.go b/internal/resolution/variablesources/composite.go index b66bf75ef..d0e3a20b9 100644 --- a/internal/resolution/variablesources/composite.go +++ b/internal/resolution/variablesources/composite.go @@ -29,7 +29,7 @@ var _ input.VariableSource = &NestedVariableSource{} type NestedVariableSource []func(inputVariableSource input.VariableSource) (input.VariableSource, error) -func (s NestedVariableSource) GetVariables(ctx context.Context, entitySource input.EntitySource) ([]deppy.Variable, error) { +func (s NestedVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { if len(s) == 0 { return nil, errors.New("empty nested variable sources") } @@ -43,15 +43,15 @@ func (s NestedVariableSource) GetVariables(ctx context.Context, entitySource inp } } - return variableSource.GetVariables(ctx, entitySource) + return variableSource.GetVariables(ctx) } type SliceVariableSource []input.VariableSource -func (s SliceVariableSource) GetVariables(ctx context.Context, entitySource input.EntitySource) ([]deppy.Variable, error) { +func (s SliceVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { var variables []deppy.Variable for _, variableSource := range s { - inputVariables, err := variableSource.GetVariables(ctx, entitySource) + inputVariables, err := variableSource.GetVariables(ctx) if err != nil { return nil, err } diff --git a/internal/resolution/variablesources/crd_constraints.go b/internal/resolution/variablesources/crd_constraints.go index 798fca211..193f2098a 100644 --- a/internal/resolution/variablesources/crd_constraints.go +++ b/internal/resolution/variablesources/crd_constraints.go @@ -7,7 +7,6 @@ import ( "github.com/operator-framework/deppy/pkg/deppy" "github.com/operator-framework/deppy/pkg/deppy/input" - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" ) @@ -34,8 +33,8 @@ func NewCRDUniquenessConstraintsVariableSource(inputVariableSource input.Variabl } } -func (g *CRDUniquenessConstraintsVariableSource) GetVariables(ctx context.Context, entitySource input.EntitySource) ([]deppy.Variable, error) { - variables, err := g.inputVariableSource.GetVariables(ctx, entitySource) +func (g *CRDUniquenessConstraintsVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { + variables, err := g.inputVariableSource.GetVariables(ctx) if err != nil { return nil, err } @@ -48,9 +47,9 @@ func (g *CRDUniquenessConstraintsVariableSource) GetVariables(ctx context.Contex for _, variable := range variables { switch v := variable.(type) { case *olmvariables.BundleVariable: - bundleEntities := []*olmentity.BundleEntity{v.BundleEntity()} - bundleEntities = append(bundleEntities, v.Dependencies()...) - for _, bundleEntity := range bundleEntities { + bundleVariables := []*olmvariables.BundleVariable{v} + bundleVariables = append(bundleVariables, v.Dependencies()...) + for _, bundleEntity := range bundleVariables { // get bundleID package and update map packageName, err := bundleEntity.PackageName() if err != nil { diff --git a/internal/resolution/variablesources/installed_package.go b/internal/resolution/variablesources/installed_package.go index a36256f1d..cdc449f3f 100644 --- a/internal/resolution/variablesources/installed_package.go +++ b/internal/resolution/variablesources/installed_package.go @@ -7,10 +7,10 @@ import ( "github.com/operator-framework/deppy/pkg/deppy" "github.com/operator-framework/deppy/pkg/deppy/input" - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" "github.com/operator-framework/operator-controller/internal/resolution/util/predicates" "github.com/operator-framework/operator-controller/internal/resolution/util/sort" "github.com/operator-framework/operator-controller/internal/resolution/variables" + olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" ) var _ input.VariableSource = &InstalledPackageVariableSource{} @@ -19,7 +19,7 @@ type InstalledPackageVariableSource struct { bundleImage string } -func (r *InstalledPackageVariableSource) GetVariables(ctx context.Context, entitySource input.EntitySource) ([]deppy.Variable, error) { +func (r *InstalledPackageVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { // find corresponding bundle entity for the installed content resultSet, err := entitySource.Filter(ctx, predicates.WithBundleImage(r.bundleImage)) if err != nil { @@ -41,7 +41,7 @@ func (r *InstalledPackageVariableSource) GetVariables(ctx context.Context, entit // if so, we should take the value from spec of the operator CR in the owner ref of the bundle deployment. // If that channel is set, we need to update the filter above to filter by channel as well. resultSet = resultSet.Sort(sort.ByChannelAndVersion) - installedBundle := olmentity.NewBundleEntity(&resultSet[0]) + installedBundle := olmvariables.NewBundleVariable(&resultSet[0], make([]*olmvariables.BundleVariable, 0), resultSet[0].Properties) // now find the bundles that replace the installed bundle // TODO: this algorithm does not yet consider skips and skipRange @@ -61,9 +61,9 @@ func (r *InstalledPackageVariableSource) GetVariables(ctx context.Context, entit return nil, err } resultSet = resultSet.Sort(sort.ByChannelAndVersion) - upgradeEdges := make([]*olmentity.BundleEntity, 0, len(resultSet)) + upgradeEdges := make([]*olmvariables.BundleVariable, 0, len(resultSet)) for i := range resultSet { - upgradeEdges = append(upgradeEdges, olmentity.NewBundleEntity(&resultSet[i])) + upgradeEdges = append(upgradeEdges, olmvariables.NewBundleVariable(&resultSet[i], make([]*olmvariables.BundleVariable, 0), resultSet[i].Properties)) } // you can always upgrade to yourself, i.e. not upgrade diff --git a/internal/resolution/variablesources/operator.go b/internal/resolution/variablesources/operator.go index a827cd273..618c5cea5 100644 --- a/internal/resolution/variablesources/operator.go +++ b/internal/resolution/variablesources/operator.go @@ -24,7 +24,7 @@ func NewOperatorVariableSource(cl client.Client, inputVariableSource input.Varia } } -func (o *OperatorVariableSource) GetVariables(ctx context.Context, entitySource input.EntitySource) ([]deppy.Variable, error) { +func (o *OperatorVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { variableSources := SliceVariableSource{} if o.inputVariableSource != nil { variableSources = append(variableSources, o.inputVariableSource) @@ -48,5 +48,5 @@ func (o *OperatorVariableSource) GetVariables(ctx context.Context, entitySource variableSources = append(variableSources, rps) } - return variableSources.GetVariables(ctx, entitySource) + return variableSources.GetVariables(ctx) } diff --git a/internal/resolution/variablesources/required_package.go b/internal/resolution/variablesources/required_package.go index 229e34c7e..12c5b64fb 100644 --- a/internal/resolution/variablesources/required_package.go +++ b/internal/resolution/variablesources/required_package.go @@ -8,7 +8,6 @@ import ( "github.com/operator-framework/deppy/pkg/deppy" "github.com/operator-framework/deppy/pkg/deppy/input" - olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities" "github.com/operator-framework/operator-controller/internal/resolution/util/predicates" "github.com/operator-framework/operator-controller/internal/resolution/util/sort" olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" @@ -67,7 +66,7 @@ func NewRequiredPackageVariableSource(packageName string, options ...RequiredPac return r, nil } -func (r *RequiredPackageVariableSource) GetVariables(ctx context.Context, entitySource input.EntitySource) ([]deppy.Variable, error) { +func (r *RequiredPackageVariableSource) GetVariables(ctx context.Context) ([]deppy.Variable, error) { resultSet, err := entitySource.Filter(ctx, input.And(r.predicates...)) if err != nil { return nil, err @@ -76,9 +75,9 @@ func (r *RequiredPackageVariableSource) GetVariables(ctx context.Context, entity return nil, r.notFoundError() } resultSet = resultSet.Sort(sort.ByChannelAndVersion) - var bundleEntities []*olmentity.BundleEntity + var bundleEntities []*olmvariables.BundleVariable for i := 0; i < len(resultSet); i++ { - bundleEntities = append(bundleEntities, olmentity.NewBundleEntity(&resultSet[i])) + bundleEntities = append(bundleEntities, olmvariables.NewBundleVariable(&resultSet[i], make([]*olmvariables.BundleVariable, 0), resultSet[i].Properties)) } return []deppy.Variable{ olmvariables.NewRequiredPackageVariable(r.packageName, bundleEntities),