diff --git a/go.mod b/go.mod index 31514ad..7d2a75d 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,15 @@ go 1.20 require ( github.com/Masterminds/semver/v3 v3.2.1 - github.com/avast/retry-go v3.0.0+incompatible github.com/cavaliergopher/grab/v3 v3.0.1 github.com/distribution/distribution v2.8.2+incompatible github.com/erikgeiser/promptkit v0.8.0 github.com/google/go-containerregistry v0.15.2 github.com/google/go-github/v40 v40.0.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/itchyny/gojq v0.12.13 github.com/jaypipes/ghw v0.10.0 github.com/joho/godotenv v1.5.1 - github.com/kairos-io/kairos-sdk v0.0.7 + github.com/kairos-io/kairos-sdk v0.0.8 github.com/labstack/echo/v4 v4.10.2 github.com/mitchellh/mapstructure v1.4.2 github.com/mudler/go-nodepair v0.0.0-20221223092639-ba399a66fdfb @@ -52,6 +50,7 @@ require ( github.com/StackExchange/wmi v1.2.1 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect github.com/atotto/clipboard v0.1.4 // indirect + github.com/avast/retry-go v2.7.0+incompatible // indirect github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect github.com/aymanbagabas/go-osc52 v1.2.1 // indirect github.com/cavaliergopher/grab v2.0.0+incompatible // indirect @@ -99,6 +98,7 @@ require ( github.com/huandu/xstrings v1.3.3 // indirect github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/itchyny/gojq v0.12.12 // indirect github.com/itchyny/timefmt-go v0.1.5 // indirect github.com/jaypipes/pcidb v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect diff --git a/go.sum b/go.sum index 33b182c..2b8bd20 100644 --- a/go.sum +++ b/go.sum @@ -93,6 +93,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/avast/retry-go v2.7.0+incompatible h1:XaGnzl7gESAideSjr+I8Hki/JBi+Yb9baHlMRPeSC84= +github.com/avast/retry-go v2.7.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= @@ -102,6 +104,7 @@ github.com/aymanbagabas/go-osc52 v1.2.1 h1:q2sWUyDcozPLcLabEMd+a+7Ea2DitxZVN9hTx github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/bool64/dev v0.2.27 h1:mFT+B74mFVgUeUmm/EbfM6ELPA55lEXBjQ/AOHCwCOc= @@ -130,6 +133,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= @@ -138,8 +142,11 @@ github.com/containerd/containerd v1.7.1 h1:k8DbDkSOwt5rgxQ3uCI4WMKIJxIndSCBUaGm5 github.com/containerd/containerd v1.7.1/go.mod h1:gA+nJUADRBm98QS5j5RPROnt0POQSMK+r7P7EGMC/Qc= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= +github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -176,6 +183,8 @@ github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryef github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/eliukblau/pixterm v1.3.1 h1:XeouQViH+lmzCa7sMUoK2cd7qlgHYGLIjwRKaOdJbKA= @@ -253,6 +262,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -369,6 +379,8 @@ github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+h github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/itchyny/gojq v0.12.12 h1:x+xGI9BXqKoJQZkr95ibpe3cdrTbY8D9lonrK433rcA= +github.com/itchyny/gojq v0.12.12/go.mod h1:j+3sVkjxwd7A7Z5jrbKibgOLn0ZfLWkV+Awxr/pyzJE= github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU= github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4= github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= @@ -391,8 +403,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kairos-io/kairos-sdk v0.0.7 h1:C1lK5QpmBy+ZZB2QIgtemaJ76aw4l5ZGxzb+mh24+Nc= -github.com/kairos-io/kairos-sdk v0.0.7/go.mod h1:kPT8LJVmUjwIslJl4LW471D4l91tBOmbGiGoO+NC+7E= +github.com/kairos-io/kairos-sdk v0.0.8 h1:3yfxdmUuJoN7ePg+ogpH1PJvuMsLmLcxEXuWoiGdIrg= +github.com/kairos-io/kairos-sdk v0.0.8/go.mod h1:Z+1CLqMZq97bzwX2XSIArr8EoniMth3mMYkOOb8L3QY= github.com/kbinani/screenshot v0.0.0-20210720154843-7d3a670d8329 h1:qq2nCpSrXrmvDGRxW0ruW9BVEV1CN2a9YDOExdt+U0o= github.com/kbinani/screenshot v0.0.0-20210720154843-7d3a670d8329/go.mod h1:2VPVQDR4wO7KXHwP+DAypEy67rXf+okUx2zjgpCxZw4= github.com/kendru/darwin/go/depgraph v0.0.0-20221105232959-877d6a81060c h1:eKb4PqwAMhlqwXw0W3atpKaYaPGlXE/Fwh+xpCEYaPk= @@ -425,6 +437,7 @@ github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= @@ -458,6 +471,7 @@ github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWV github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -476,6 +490,7 @@ github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/moby v23.0.2+incompatible h1:W9l+1HGV+mZ4a6RW9ZAHzSYPpqAZ96/ft5gFJAaeh9c= github.com/moby/moby v23.0.2+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= @@ -484,9 +499,11 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5 github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mudler/entities v0.0.0-20220905203055-68348bae0f49 h1:P1QgHLh0hX935j6m9K6rlSxc0mkD1UuIAOQEu+1VCW4= github.com/mudler/entities v0.0.0-20220905203055-68348bae0f49/go.mod h1:qquFT9tYp+/NO7tTotto4BT9zSRYSMDxo2PGZwujpFA= github.com/mudler/go-nodepair v0.0.0-20221223092639-ba399a66fdfb h1:F6TP0DW7C0U9sgm9g4uAs0Vp2JSkhn2umlyrNlxUKXw= @@ -545,6 +562,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee h1:P6U24L02WMfj9ymZTxl7CxS73JC99x3ukk+DBkgQGQs= github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee/go.mod h1:3uODdxMgOaPYeWU7RzZLxVtJHZ/x1f/iHkBZuKJDzuY= github.com/pierrec/lz4 v2.3.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -649,6 +667,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -672,6 +691,7 @@ github.com/swaggest/jsonschema-go v0.3.51 h1:Cl0hFQ/jtBIP8NlHNuwW6ka3J7zzW5r2jxb github.com/swaggest/jsonschema-go v0.3.51/go.mod h1:QfUB5HaZ8y5TiFtCPhM7QwvPNKxTsYxDJaLHTLq6jgU= github.com/swaggest/refl v1.1.0 h1:a+9a75Kv6ciMozPjVbOfcVTEQe81t2R3emvaD9oGQGc= github.com/swaggest/refl v1.1.0/go.mod h1:g3Qa6ki0A/L2yxiuUpT+cuBURuRaltF5SDQpg1kMZSY= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tredoe/osutil/v2 v2.0.0-rc.16 h1:5A2SKvyB2c3lhPYUIHyFtu6jbaXlaA3Hu5gWIam8Pik= github.com/tredoe/osutil/v2 v2.0.0-rc.16/go.mod h1:uLRVx/3pb7Y4RQhG8cQFbPE9ha5r81e6MXpBsxbTAYc= @@ -705,6 +725,7 @@ github.com/willdonnelly/passwd v0.0.0-20141013001024-7935dab3074c/go.mod h1:xcvf github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xanzy/ssh-agent v0.3.1 h1:AmzO1SSWxw73zxFZPRwaMN1MohDw8UyHnmuxyceTEGo= github.com/xanzy/ssh-agent v0.3.1/go.mod h1:QIE4lCeL7nkC25x+yA3LBIYfwCc1TFziCtG7cBAac6w= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= @@ -728,6 +749,7 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -739,6 +761,7 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -1177,11 +1200,13 @@ gopkg.in/djherbis/times.v1 v1.3.0 h1:uxMS4iMtH6Pwsxog094W0FYldiNnfY/xba00vq6C2+o gopkg.in/djherbis/times.v1 v1.3.0/go.mod h1:AQlg6unIsrsCEdQYhTzERy542dz6SFdQFZFv6mUY0P8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= @@ -1202,6 +1227,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/agent/agent.go b/internal/agent/agent.go index 3f262b3..68e04d3 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -6,12 +6,12 @@ import ( "path/filepath" events "github.com/kairos-io/kairos-sdk/bus" + "github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos-sdk/machine" "github.com/kairos-io/kairos-sdk/utils" hook "github.com/kairos-io/kairos/v2/internal/agent/hooks" "github.com/kairos-io/kairos/v2/internal/bus" config "github.com/kairos-io/kairos/v2/pkg/config" - "github.com/kairos-io/kairos/v2/pkg/config/collector" "github.com/nxadm/tail" ) diff --git a/internal/agent/install.go b/internal/agent/install.go index 613c61e..5196c4e 100644 --- a/internal/agent/install.go +++ b/internal/agent/install.go @@ -15,6 +15,7 @@ import ( "github.com/sirupsen/logrus" events "github.com/kairos-io/kairos-sdk/bus" + "github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos-sdk/machine" "github.com/kairos-io/kairos-sdk/utils" hook "github.com/kairos-io/kairos/v2/internal/agent/hooks" @@ -22,7 +23,6 @@ import ( "github.com/kairos-io/kairos/v2/internal/cmd" "github.com/kairos-io/kairos/v2/pkg/action" "github.com/kairos-io/kairos/v2/pkg/config" - "github.com/kairos-io/kairos/v2/pkg/config/collector" "github.com/kairos-io/kairos/v2/pkg/elementalConfig" v1 "github.com/kairos-io/kairos/v2/pkg/types/v1" elementalUtils "github.com/kairos-io/kairos/v2/pkg/utils" diff --git a/internal/agent/interactive_install.go b/internal/agent/interactive_install.go index 55daf5b..343f060 100644 --- a/internal/agent/interactive_install.go +++ b/internal/agent/interactive_install.go @@ -7,7 +7,7 @@ import ( "github.com/kairos-io/kairos/v2/internal/bus" "github.com/kairos-io/kairos/v2/internal/cmd" - config "github.com/kairos-io/kairos/v2/pkg/config" + "github.com/kairos-io/kairos/v2/pkg/config" "github.com/kairos-io/kairos/v2/pkg/elementalConfig" events "github.com/kairos-io/kairos-sdk/bus" diff --git a/internal/agent/notify.go b/internal/agent/notify.go index 15728d0..1edc4d6 100644 --- a/internal/agent/notify.go +++ b/internal/agent/notify.go @@ -4,9 +4,9 @@ import ( "fmt" events "github.com/kairos-io/kairos-sdk/bus" + "github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos/v2/internal/bus" "github.com/kairos-io/kairos/v2/pkg/config" - "github.com/kairos-io/kairos/v2/pkg/config/collector" "github.com/mudler/go-pluggable" ) diff --git a/internal/agent/reset.go b/internal/agent/reset.go index 6dccbd2..fc5f5cd 100644 --- a/internal/agent/reset.go +++ b/internal/agent/reset.go @@ -10,6 +10,7 @@ import ( "time" sdk "github.com/kairos-io/kairos-sdk/bus" + "github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos-sdk/machine" "github.com/kairos-io/kairos-sdk/utils" hook "github.com/kairos-io/kairos/v2/internal/agent/hooks" @@ -17,7 +18,6 @@ import ( "github.com/kairos-io/kairos/v2/internal/cmd" "github.com/kairos-io/kairos/v2/pkg/action" "github.com/kairos-io/kairos/v2/pkg/config" - "github.com/kairos-io/kairos/v2/pkg/config/collector" "github.com/kairos-io/kairos/v2/pkg/elementalConfig" "github.com/mudler/go-pluggable" diff --git a/internal/agent/upgrade.go b/internal/agent/upgrade.go index 181264d..2d7beb4 100644 --- a/internal/agent/upgrade.go +++ b/internal/agent/upgrade.go @@ -6,11 +6,11 @@ import ( "fmt" "github.com/Masterminds/semver/v3" events "github.com/kairos-io/kairos-sdk/bus" + "github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos-sdk/utils" "github.com/kairos-io/kairos/v2/internal/bus" "github.com/kairos-io/kairos/v2/pkg/action" "github.com/kairos-io/kairos/v2/pkg/config" - "github.com/kairos-io/kairos/v2/pkg/config/collector" "github.com/kairos-io/kairos/v2/pkg/elementalConfig" "github.com/kairos-io/kairos/v2/pkg/github" v1 "github.com/kairos-io/kairos/v2/pkg/types/v1" diff --git a/main.go b/main.go index 945102c..51e3452 100644 --- a/main.go +++ b/main.go @@ -4,29 +4,26 @@ import ( "context" "encoding/json" "fmt" + "os" "path/filepath" + "regexp" "runtime" + "strings" + "github.com/kairos-io/kairos-sdk/bundles" + "github.com/kairos-io/kairos-sdk/collector" + "github.com/kairos-io/kairos-sdk/machine" + "github.com/kairos-io/kairos-sdk/schema" + "github.com/kairos-io/kairos-sdk/state" + "github.com/kairos-io/kairos/v2/internal/agent" + "github.com/kairos-io/kairos/v2/internal/bus" + "github.com/kairos-io/kairos/v2/internal/common" + "github.com/kairos-io/kairos/v2/internal/webui" + "github.com/kairos-io/kairos/v2/pkg/config" "github.com/kairos-io/kairos/v2/pkg/elementalConfig" v1 "github.com/kairos-io/kairos/v2/pkg/types/v1" "github.com/kairos-io/kairos/v2/pkg/utils" "github.com/sirupsen/logrus" - "regexp" - - "os" - "strings" - - "github.com/kairos-io/kairos/v2/internal/agent" - "github.com/kairos-io/kairos/v2/internal/bus" - "github.com/kairos-io/kairos/v2/internal/webui" - - "github.com/kairos-io/kairos-sdk/bundles" - "github.com/kairos-io/kairos-sdk/machine" - "github.com/kairos-io/kairos-sdk/schema" - "github.com/kairos-io/kairos-sdk/state" - "github.com/kairos-io/kairos/v2/internal/common" - "github.com/kairos-io/kairos/v2/pkg/config" - "github.com/kairos-io/kairos/v2/pkg/config/collector" "github.com/Masterminds/semver/v3" "github.com/urfave/cli/v2" diff --git a/pkg/config/collector/collector.go b/pkg/config/collector/collector.go deleted file mode 100644 index 7a3911f..0000000 --- a/pkg/config/collector/collector.go +++ /dev/null @@ -1,483 +0,0 @@ -// Package configcollector can be used to merge configuration from different -// sources into one YAML. -package collector - -import ( - "encoding/json" - "fmt" - "io" - "net/http" - "os" - "path/filepath" - "reflect" - "strings" - "time" - "unicode" - - "github.com/kairos-io/kairos-sdk/machine" - - "github.com/avast/retry-go" - "github.com/itchyny/gojq" - "gopkg.in/yaml.v3" -) - -const DefaultHeader = "#cloud-config" - -var ValidFileHeaders = []string{ - "#cloud-config", - "#kairos-config", - "#node-config", -} - -type Configs []*Config - -// We don't allow yamls that are plain arrays because is has no use in Kairos -// and there is no way to merge an array yaml with a "map" yaml. -type Config map[string]interface{} - -// MergeConfigURL looks for the "config_url" key and if it's found -// it downloads the remote config and merges it with the current one. -// If the remote config also has config_url defined, it is also fetched -// recursively until a remote config no longer defines a config_url. -// NOTE: The "config_url" value of the final result is the value of the last -// config file in the chain because we replace values when we merge. -func (c *Config) MergeConfigURL() error { - // If there is no config_url, just return (do nothing) - configURL := c.ConfigURL() - if configURL == "" { - return nil - } - - // fetch the remote config - remoteConfig, err := fetchRemoteConfig(configURL) - if err != nil { - return err - } - - // recursively fetch remote configs - if err := remoteConfig.MergeConfigURL(); err != nil { - return err - } - - // merge remoteConfig back to "c" - return c.MergeConfig(remoteConfig) -} - -func (c *Config) toMap() (map[string]interface{}, error) { - var result map[string]interface{} - data, err := yaml.Marshal(c) - if err != nil { - return result, err - } - - err = yaml.Unmarshal(data, &result) - return result, err -} - -func (c *Config) applyMap(i interface{}) error { - data, err := yaml.Marshal(i) - if err != nil { - return err - } - - err = yaml.Unmarshal(data, c) - return err -} - -// MergeConfig merges the config passed as parameter back to the receiver Config. -func (c *Config) MergeConfig(newConfig *Config) error { - var err error - - // convert the two configs into maps - aMap, err := c.toMap() - if err != nil { - return err - } - bMap, err := newConfig.toMap() - if err != nil { - return err - } - - // deep merge the two maps - cMap, err := DeepMerge(aMap, bMap) - if err != nil { - return err - } - - // apply the result of the deepmerge into the base config - return c.applyMap(cMap) -} - -func deepMergeSlices(sliceA, sliceB []interface{}) ([]interface{}, error) { - // We use the first item in the slice to determine if there are maps present. - // Do we need to do the same for other types? - firstItem := sliceA[0] - if reflect.ValueOf(firstItem).Kind() == reflect.Map { - temp := make(map[string]interface{}) - - // first we put in temp all the keys present in a, and assign them their existing values - for _, item := range sliceA { - for k, v := range item.(map[string]interface{}) { - temp[k] = v - } - } - - // then we go through b to merge each of its keys - for _, item := range sliceB { - for k, v := range item.(map[string]interface{}) { - current, ok := temp[k] - if ok { - // if the key exists, we deep merge it - dm, err := DeepMerge(current, v) - if err != nil { - return []interface{}{}, fmt.Errorf("cannot merge %s with %s", current, v) - } - temp[k] = dm - } else { - // otherwise we just set it - temp[k] = v - } - } - } - - return []interface{}{temp}, nil - } - - // This implementation is needed because Go 1.19 does not implement compare for {}interface. Once - // FIPS can be upgraded to 1.20, we should be able to use this other code: - // // for simple slices - // for _, v := range sliceB { - // i := slices.Index(sliceA, v) - // if i < 0 { - // sliceA = append(sliceA, v) - // } - // } - for _, vB := range sliceB { - found := false - for _, vA := range sliceA { - if vA == vB { - found = true - } - } - - if !found { - sliceA = append(sliceA, vB) - } - } - - return sliceA, nil -} - -func deepMergeMaps(a, b map[string]interface{}) (map[string]interface{}, error) { - // go through all items in b and merge them to a - for k, v := range b { - current, ok := a[k] - if ok { - // when the key is already set, we don't know what type it has, so we deep merge them in case they are maps - // or slices - res, err := DeepMerge(current, v) - if err != nil { - return a, err - } - a[k] = res - } else { - a[k] = v - } - } - - return a, nil -} - -// DeepMerge takes two data structures and merges them together deeply. The results can vary depending on how the -// arguments are passed since structure B will always overwrite what's on A. -func DeepMerge(a, b interface{}) (interface{}, error) { - if a == nil && b != nil { - return b, nil - } - - typeA := reflect.TypeOf(a) - typeB := reflect.TypeOf(b) - - // We don't support merging different data structures - if typeA.Kind() != typeB.Kind() { - return map[string]interface{}{}, fmt.Errorf("cannot merge %s with %s", typeA.String(), typeB.String()) - } - - if typeA.Kind() == reflect.Slice { - return deepMergeSlices(a.([]interface{}), b.([]interface{})) - } - - if typeA.Kind() == reflect.Map { - return deepMergeMaps(a.(map[string]interface{}), b.(map[string]interface{})) - } - - // for any other type, b should take precedence - return b, nil -} - -// String returns a string which is a Yaml representation of the Config. -func (c *Config) String() (string, error) { - data, err := yaml.Marshal(c) - if err != nil { - return "", err - } - - return fmt.Sprintf("%s\n\n%s", DefaultHeader, string(data)), nil -} - -func (cs Configs) Merge() (*Config, error) { - result := &Config{} - - for _, c := range cs { - if err := c.MergeConfigURL(); err != nil { - return result, err - } - - if err := result.MergeConfig(c); err != nil { - return result, err - } - } - - return result, nil -} - -func Scan(o *Options, filter func(d []byte) ([]byte, error)) (*Config, error) { - configs := Configs{} - - configs = append(configs, parseFiles(o.ScanDir, o.NoLogs)...) - - if o.MergeBootCMDLine { - cConfig, err := ParseCmdLine(o.BootCMDLineFile, filter) - o.SoftErr("parsing cmdline", err) - if err == nil { // best-effort - configs = append(configs, cConfig) - } - } - - return configs.Merge() -} - -func allFiles(dir []string) []string { - files := []string{} - for _, d := range dir { - if f, err := listFiles(d); err == nil { - files = append(files, f...) - } - } - return files -} - -// parseFiles returns a list of Configs parsed from files. -func parseFiles(dir []string, nologs bool) Configs { - result := Configs{} - files := allFiles(dir) - for _, f := range files { - if fileSize(f) > 1.0 { - if !nologs { - fmt.Printf("warning: skipping %s. too big (>1MB)\n", f) - } - continue - } - if strings.Contains(f, "userdata") || filepath.Ext(f) == ".yml" || filepath.Ext(f) == ".yaml" { - b, err := os.ReadFile(f) - if err != nil { - if !nologs { - fmt.Printf("warning: skipping %s. %s\n", f, err.Error()) - } - continue - } - - if !HasValidHeader(string(b)) { - if !nologs { - fmt.Printf("warning: skipping %s because it has no valid header\n", f) - } - continue - } - - var newConfig Config - err = yaml.Unmarshal(b, &newConfig) - if err != nil && !nologs { - fmt.Printf("warning: failed to parse config:\n%s\n", err.Error()) - } - result = append(result, &newConfig) - } else { - if !nologs { - fmt.Printf("warning: skipping %s (extension).\n", f) - } - } - } - - return result -} - -func fileSize(f string) float64 { - file, err := os.Open(f) - if err != nil { - return 0 - } - defer file.Close() - - stat, err := file.Stat() - if err != nil { - return 0 - } - - bytes := stat.Size() - kilobytes := (bytes / 1024) - megabytes := (float64)(kilobytes / 1024) // cast to type float64 - - return megabytes -} - -func listFiles(dir string) ([]string, error) { - content := []string{} - - err := filepath.Walk(dir, - func(path string, info os.FileInfo, err error) error { - if err != nil { - return nil - } - if !info.IsDir() { - content = append(content, path) - } - - return nil - }) - - return content, err -} - -// ParseCmdLine reads options from the kernel cmdline and returns the equivalent -// Config. -func ParseCmdLine(file string, filter func(d []byte) ([]byte, error)) (*Config, error) { - result := Config{} - dotToYAML, err := machine.DotToYAML(file) - if err != nil { - return &result, err - } - - filteredYAML, err := filter(dotToYAML) - if err != nil { - return &result, err - } - - err = yaml.Unmarshal(filteredYAML, &result) - if err != nil { - return &result, err - } - - return &result, nil -} - -// ConfigURL returns the value of config_url if set or empty string otherwise. -func (c Config) ConfigURL() string { - if val, hasKey := c["config_url"]; hasKey { - if s, isString := val.(string); isString { - return s - } - } - - return "" -} - -func fetchRemoteConfig(url string) (*Config, error) { - var body []byte - result := &Config{} - - err := retry.Do( - func() error { - resp, err := http.Get(url) - if err != nil { - return err - } - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("unexpected status: %d", resp.StatusCode) - } - defer resp.Body.Close() - - body, err = io.ReadAll(resp.Body) - if err != nil { - return err - } - - return nil - }, retry.Delay(time.Second), retry.Attempts(3), - ) - - if err != nil { - // TODO: improve logging - fmt.Printf("WARNING: Couldn't fetch config_url: %s", err) - return result, nil - } - - if !HasValidHeader(string(body)) { - // TODO: Print a warning when we implement proper logging - fmt.Println("No valid header in remote config: %w", err) - return result, nil - } - - if err := yaml.Unmarshal(body, result); err != nil { - return result, fmt.Errorf("could not unmarshal remote config to an object: %w", err) - } - - return result, nil -} - -func HasValidHeader(data string) bool { - header := strings.SplitN(data, "\n", 2)[0] - - // Trim trailing whitespaces - header = strings.TrimRightFunc(header, unicode.IsSpace) - - // NOTE: we also allow "legacy" headers. Should only allow #cloud-config at - // some point. - return (header == DefaultHeader) || (header == "#kairos-config") || (header == "#node-config") -} - -func (c Config) Query(s string) (res string, err error) { - s = fmt.Sprintf(".%s", s) - - var dat map[string]interface{} - var dat1 map[string]interface{} - - yamlStr, err := c.String() - if err != nil { - panic(err) - } - // Marshall it so it removes the first line which cannot be parsed - err = yaml.Unmarshal([]byte(yamlStr), &dat1) - if err != nil { - panic(err) - } - // Transform it to json so its parsed correctly by gojq - b, err := json.Marshal(dat1) - if err != nil { - panic(err) - } - if err := json.Unmarshal(b, &dat); err != nil { - panic(err) - } - - query, err := gojq.Parse(s) - if err != nil { - return res, err - } - - iter := query.Run(dat) // or query.RunWithContext - for { - v, ok := iter.Next() - if !ok { - break - } - if err, ok := v.(error); ok { - return res, fmt.Errorf("failed parsing, error: %w", err) - } - - dat, err := yaml.Marshal(v) - if err != nil { - break - } - res += string(dat) - } - return -} diff --git a/pkg/config/collector/collector_test.go b/pkg/config/collector/collector_test.go deleted file mode 100644 index 17264f7..0000000 --- a/pkg/config/collector/collector_test.go +++ /dev/null @@ -1,754 +0,0 @@ -package collector_test - -import ( - "fmt" - "os" - "path" - "path/filepath" - - "github.com/kairos-io/kairos/v2/pkg/config" - . "github.com/kairos-io/kairos/v2/pkg/config/collector" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "gopkg.in/yaml.v1" -) - -var _ = Describe("Config Collector", func() { - Describe("Options", func() { - var options *Options - - BeforeEach(func() { - options = &Options{ - NoLogs: false, - } - }) - - It("applies a defined option function", func() { - option := func(o *Options) error { - o.NoLogs = true - return nil - } - - Expect(options.NoLogs).To(BeFalse()) - Expect(options.Apply(option)).NotTo(HaveOccurred()) - Expect(options.NoLogs).To(BeTrue()) - }) - }) - - Describe("MergeConfig", func() { - var originalConfig, newConfig *Config - BeforeEach(func() { - originalConfig = &Config{} - newConfig = &Config{} - }) - - Context("different keys", func() { - BeforeEach(func() { - err := yaml.Unmarshal([]byte(`#cloud-config -name: Mario`), originalConfig) - Expect(err).ToNot(HaveOccurred()) - err = yaml.Unmarshal([]byte(`#cloud-config -surname: Bros`), newConfig) - Expect(err).ToNot(HaveOccurred()) - }) - - It("gets merged together", func() { - Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred()) - surname, isString := (*originalConfig)["surname"].(string) - Expect(isString).To(BeTrue()) - Expect(surname).To(Equal("Bros")) - }) - }) - - Context("same keys", func() { - Context("when the key is a map", func() { - BeforeEach(func() { - err := yaml.Unmarshal([]byte(`#cloud-config -info: - name: Mario -`), originalConfig) - Expect(err).ToNot(HaveOccurred()) - err = yaml.Unmarshal([]byte(`#cloud-config -info: - surname: Bros -`), newConfig) - Expect(err).ToNot(HaveOccurred()) - }) - It("merges the keys", func() { - Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred()) - info, isMap := (*originalConfig)["info"].(Config) - Expect(isMap).To(BeTrue()) - Expect(info["name"]).To(Equal("Mario")) - Expect(info["surname"]).To(Equal("Bros")) - Expect(*originalConfig).To(HaveLen(1)) - Expect(info).To(HaveLen(2)) - }) - }) - - Context("when the key is a string", func() { - BeforeEach(func() { - err := yaml.Unmarshal([]byte("#cloud-config\nname: Mario"), originalConfig) - Expect(err).ToNot(HaveOccurred()) - err = yaml.Unmarshal([]byte("#cloud-config\nname: Luigi"), newConfig) - Expect(err).ToNot(HaveOccurred()) - }) - - It("overwrites", func() { - Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred()) - name, isString := (*originalConfig)["name"].(string) - Expect(isString).To(BeTrue()) - Expect(name).To(Equal("Luigi")) - Expect(*originalConfig).To(HaveLen(1)) - }) - }) - }) - }) - - Describe("MergeConfigURL", func() { - var originalConfig *Config - BeforeEach(func() { - originalConfig = &Config{} - }) - - Context("when there is no config_url defined", func() { - BeforeEach(func() { - err := yaml.Unmarshal([]byte("#cloud-config\nname: Mario"), originalConfig) - Expect(err).ToNot(HaveOccurred()) - }) - - It("does nothing", func() { - Expect(originalConfig.MergeConfigURL()).ToNot(HaveOccurred()) - Expect(*originalConfig).To(HaveLen(1)) - }) - }) - - Context("when there is a chain of config_url defined", func() { - var closeFunc ServerCloseFunc - var port int - var err error - var tmpDir string - var originalConfig *Config - - BeforeEach(func() { - tmpDir, err = os.MkdirTemp("", "config_url_chain") - Expect(err).ToNot(HaveOccurred()) - - closeFunc, port, err = startAssetServer(tmpDir) - Expect(err).ToNot(HaveOccurred()) - - originalConfig = &Config{} - err = yaml.Unmarshal([]byte(fmt.Sprintf(`#cloud-config -config_url: http://127.0.0.1:%d/config1.yaml -name: Mario -surname: Bros -info: - job: plumber -`, port)), originalConfig) - Expect(err).ToNot(HaveOccurred()) - - err := os.WriteFile(path.Join(tmpDir, "config1.yaml"), []byte(fmt.Sprintf(`#cloud-config - -config_url: http://127.0.0.1:%d/config2.yaml -surname: Bras -`, port)), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - err = os.WriteFile(path.Join(tmpDir, "config2.yaml"), []byte(`#cloud-config - -info: - girlfriend: princess -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - }) - - AfterEach(func() { - closeFunc() - err := os.RemoveAll(tmpDir) - Expect(err).ToNot(HaveOccurred()) - }) - - It("merges them all together", func() { - err := originalConfig.MergeConfigURL() - Expect(err).ToNot(HaveOccurred()) - - name, ok := (*originalConfig)["name"].(string) - Expect(ok).To(BeTrue()) - Expect(name).To(Equal("Mario")) - - surname, ok := (*originalConfig)["surname"].(string) - Expect(ok).To(BeTrue()) - Expect(surname).To(Equal("Bras")) - - info, ok := (*originalConfig)["info"].(Config) - Expect(ok).To(BeTrue()) - Expect(info["job"]).To(Equal("plumber")) - Expect(info["girlfriend"]).To(Equal("princess")) - - Expect(*originalConfig).To(HaveLen(4)) - }) - }) - }) - - Describe("deepMerge", func() { - Context("different types", func() { - a := map[string]interface{}{} - b := []string{} - - It("merges", func() { - _, err := DeepMerge(a, b) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("cannot merge map[string]interface {} with []string")) - - _, err = DeepMerge(b, a) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("cannot merge []string with map[string]interface {}")) - }) - }) - - Context("simple slices", func() { - a := []interface{}{"one", "three"} - b := []interface{}{"two", 4} - - It("merges", func() { - c, err := DeepMerge(a, b) - Expect(err).ToNot(HaveOccurred()) - Expect(c).To(Equal([]interface{}{"one", "three", "two", 4})) - }) - }) - - Context("slices containing maps", func() { - a := []interface{}{ - map[string]interface{}{ - "users": []interface{}{ - map[string]interface{}{ - "kairos": map[string]interface{}{ - "passwd": "kairos", - }, - }, - }, - }, - } - b := []interface{}{ - map[string]interface{}{ - "users": []interface{}{ - map[string]interface{}{ - "foo": map[string]interface{}{ - "passwd": "bar", - }, - }, - }, - }, - } - - It("merges", func() { - c, err := DeepMerge(a, b) - Expect(err).ToNot(HaveOccurred()) - users := c.([]interface{})[0].(map[string]interface{})["users"] - Expect(users).To(HaveLen(1)) - Expect(users).To(Equal([]interface{}{ - map[string]interface{}{ - "kairos": map[string]interface{}{ - "passwd": "kairos", - }, - "foo": map[string]interface{}{ - "passwd": "bar", - }, - }, - })) - }) - }) - - Context("empty map", func() { - a := map[string]interface{}{} - b := map[string]interface{}{ - "foo": "bar", - } - - It("merges", func() { - c, err := DeepMerge(a, b) - Expect(err).ToNot(HaveOccurred()) - Expect(c).To(Equal(map[string]interface{}{ - "foo": "bar", - })) - }) - }) - - Context("simple map", func() { - a := map[string]interface{}{ - "es": "uno", - "nl": "een", - "#": 0, - } - b := map[string]interface{}{ - "en": "one", - "nl": "één", - "de": "Eins", - "#": 1, - } - - It("merges", func() { - c, err := DeepMerge(a, b) - Expect(err).ToNot(HaveOccurred()) - Expect(c).To(Equal(map[string]interface{}{ - "#": 1, - "de": "Eins", - "en": "one", - "es": "uno", - "nl": "één", - })) - }) - }) - }) - - Describe("Scan", func() { - Context("duplicated configs", func() { - var cmdLinePath, tmpDir1 string - var err error - - BeforeEach(func() { - tmpDir1, err = os.MkdirTemp("", "config1") - Expect(err).ToNot(HaveOccurred()) - err := os.WriteFile(path.Join(tmpDir1, "local_config_1.yaml"), []byte(`#cloud-config - -stages: - initramfs: - - name: "Set user and password" - users: - kairos: - passwd: "kairos" - hostname: kairos-{{ trunc 4 .Random }} - -install: - auto: true - reboot: true - device: auto - grub_options: - extra_cmdline: foobarzz - bundles: - - rootfs_path: /usr/local/lib/extensions/kubo - targets: - - container://ttl.sh/97d4530c-df80-4eb4-9ae7-39f8f90c26e5:8h -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - err = os.WriteFile(path.Join(tmpDir1, "local_config_2.yaml"), []byte(`#cloud-config - -stages: - initramfs: - - name: "Set user and password" - users: - kairos: - passwd: "kairos" - hostname: kairos-{{ trunc 4 .Random }} - -install: - auto: true - reboot: true - device: auto - grub_options: - extra_cmdline: foobarzz - bundles: - - rootfs_path: /usr/local/lib/extensions/kubo - targets: - - container://ttl.sh/97d4530c-df80-4eb4-9ae7-39f8f90c26e5:8h -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - }) - - AfterEach(func() { - err = os.RemoveAll(tmpDir1) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should be the same as just one of them", func() { - o := &Options{} - err := o.Apply( - MergeBootLine, - WithBootCMDLineFile(cmdLinePath), - Directories(tmpDir1), - ) - Expect(err).ToNot(HaveOccurred()) - - c, err := Scan(o, config.FilterKeys) - Expect(err).ToNot(HaveOccurred()) - - fmt.Println(c.String()) - Expect(c.String()).To(Equal(`#cloud-config - -install: - auto: true - bundles: - - rootfs_path: /usr/local/lib/extensions/kubo - targets: - - container://ttl.sh/97d4530c-df80-4eb4-9ae7-39f8f90c26e5:8h - device: auto - grub_options: - extra_cmdline: foobarzz - reboot: true -stages: - initramfs: - - hostname: kairos-{{ trunc 4 .Random }} - name: Set user and password - users: - kairos: - passwd: kairos -`)) - }) - }) - Context("Deep merge maps within arrays", func() { - var cmdLinePath, tmpDir1 string - var err error - - BeforeEach(func() { - tmpDir1, err = os.MkdirTemp("", "config1") - Expect(err).ToNot(HaveOccurred()) - err := os.WriteFile(path.Join(tmpDir1, "local_config_1.yaml"), []byte(`#cloud-config -install: - auto: true - reboot: false - poweroff: false - grub_options: - extra_cmdline: "console=tty0" -options: - device: /dev/sda -stages: - initramfs: - - users: - kairos: - groups: - - sudo - passwd: kairos -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - err = os.WriteFile(path.Join(tmpDir1, "local_config_2.yaml"), []byte(`#cloud-config -stages: - initramfs: - - users: - foo: - groups: - - sudo - passwd: bar -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - }) - - AfterEach(func() { - err = os.RemoveAll(tmpDir1) - Expect(err).ToNot(HaveOccurred()) - }) - - It("merges all the sources accordingly", func() { - o := &Options{} - err := o.Apply( - MergeBootLine, - WithBootCMDLineFile(cmdLinePath), - Directories(tmpDir1), - ) - Expect(err).ToNot(HaveOccurred()) - - c, err := Scan(o, config.FilterKeys) - Expect(err).ToNot(HaveOccurred()) - - Expect(c.String()).To(Equal(`#cloud-config - -install: - auto: true - grub_options: - extra_cmdline: console=tty0 - poweroff: false - reboot: false -options: - device: /dev/sda -stages: - initramfs: - - users: - foo: - groups: - - sudo - passwd: bar - kairos: - groups: - - sudo - passwd: kairos -`)) - }) - }) - - Context("multiple sources are defined", func() { - var cmdLinePath, serverDir, tmpDir, tmpDir1, tmpDir2 string - var err error - var closeFunc ServerCloseFunc - var port int - - BeforeEach(func() { - // Prepare the cmdline config_url chain - serverDir, err = os.MkdirTemp("", "config_url_chain") - Expect(err).ToNot(HaveOccurred()) - closeFunc, port, err = startAssetServer(serverDir) - Expect(err).ToNot(HaveOccurred()) - cmdLinePath = createRemoteConfigs(serverDir, port) - - tmpDir1, err = os.MkdirTemp("", "config1") - Expect(err).ToNot(HaveOccurred()) - err := os.WriteFile(path.Join(tmpDir1, "local_config_1.yaml"), []byte(fmt.Sprintf(`#cloud-config - -config_url: http://127.0.0.1:%d/remote_config_3.yaml -local_key_1: local_value_1 -`, port)), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - err = os.WriteFile(path.Join(serverDir, "remote_config_3.yaml"), []byte(fmt.Sprintf(`#cloud-config - -config_url: http://127.0.0.1:%d/remote_config_4.yaml -remote_key_3: remote_value_3 -`, port)), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - err = os.WriteFile(path.Join(serverDir, "remote_config_4.yaml"), []byte(`#cloud-config - -options: - remote_option_1: remote_option_value_1 -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - tmpDir2, err = os.MkdirTemp("", "config2") - Expect(err).ToNot(HaveOccurred()) - err = os.WriteFile(path.Join(tmpDir2, "local_config_2.yaml"), []byte(fmt.Sprintf(`#cloud-config - -config_url: http://127.0.0.1:%d/remote_config_5.yaml -local_key_2: local_value_2 -`, port)), os.ModePerm) - err = os.WriteFile(path.Join(tmpDir2, "local_config_3.yaml"), []byte(`#cloud-config -local_key_3: local_value_3 -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - err = os.WriteFile(path.Join(serverDir, "remote_config_5.yaml"), []byte(fmt.Sprintf(`#cloud-config - -config_url: http://127.0.0.1:%d/remote_config_6.yaml -remote_key_4: remote_value_4 -`, port)), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - err = os.WriteFile(path.Join(serverDir, "remote_config_6.yaml"), []byte(`#cloud-config - -options: - remote_option_2: remote_option_value_2 -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - }) - - AfterEach(func() { - err = os.RemoveAll(serverDir) - Expect(err).ToNot(HaveOccurred()) - err = os.RemoveAll(tmpDir) - Expect(err).ToNot(HaveOccurred()) - err = os.RemoveAll(tmpDir1) - Expect(err).ToNot(HaveOccurred()) - err = os.RemoveAll(tmpDir2) - Expect(err).ToNot(HaveOccurred()) - - closeFunc() - }) - - It("merges all the sources accordingly", func() { - o := &Options{} - err := o.Apply( - MergeBootLine, - WithBootCMDLineFile(cmdLinePath), - Directories(tmpDir1, tmpDir2), - ) - Expect(err).ToNot(HaveOccurred()) - - c, err := Scan(o, config.FilterKeys) - Expect(err).ToNot(HaveOccurred()) - - configURL, ok := (*c)["config_url"].(string) - Expect(ok).To(BeTrue()) - Expect(configURL).To(MatchRegexp("remote_config_2.yaml")) - - k := (*c)["local_key_1"].(string) - Expect(k).To(Equal("local_value_1")) - k = (*c)["local_key_2"].(string) - Expect(k).To(Equal("local_value_2")) - k = (*c)["local_key_3"].(string) - Expect(k).To(Equal("local_value_3")) - k = (*c)["remote_key_1"].(string) - Expect(k).To(Equal("remote_value_1")) - k = (*c)["remote_key_2"].(string) - Expect(k).To(Equal("remote_value_2")) - k = (*c)["remote_key_3"].(string) - Expect(k).To(Equal("remote_value_3")) - k = (*c)["remote_key_4"].(string) - Expect(k).To(Equal("remote_value_4")) - - options := (*c)["options"].(Config) - Expect(options["foo"]).To(Equal("bar")) - Expect(options["remote_option_1"]).To(Equal("remote_option_value_1")) - Expect(options["remote_option_2"]).To(Equal("remote_option_value_2")) - - player := (*c)["player"].(Config) - Expect(player["name"]).NotTo(Equal("Toad")) - Expect(player["surname"]).To(Equal("Bros")) - }) - }) - - Context("when files have invalid or missing headers", func() { - var serverDir, tmpDir string - var err error - var closeFunc ServerCloseFunc - var port int - - BeforeEach(func() { - // Prepare the cmdline config_url chain - serverDir, err = os.MkdirTemp("", "config_url_chain") - Expect(err).ToNot(HaveOccurred()) - closeFunc, port, err = startAssetServer(serverDir) - Expect(err).ToNot(HaveOccurred()) - - tmpDir, err = os.MkdirTemp("", "config") - Expect(err).ToNot(HaveOccurred()) - - // Local configs - err = os.WriteFile(path.Join(tmpDir, "local_config.yaml"), []byte(fmt.Sprintf(`#cloud-config -config_url: http://127.0.0.1:%d/remote_config_1.yaml -local_key_1: local_value_1 -`, port)), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - // missing header - err = os.WriteFile(path.Join(tmpDir, "local_config_2.yaml"), - []byte("local_key_2: local_value_2"), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - // Remote config with valid header - err := os.WriteFile(path.Join(serverDir, "remote_config_1.yaml"), []byte(fmt.Sprintf(`#cloud-config -config_url: http://127.0.0.1:%d/remote_config_2.yaml -remote_key_1: remote_value_1`, port)), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - // Remote config with invalid header - err = os.WriteFile(path.Join(serverDir, "remote_config_2.yaml"), []byte(`#invalid-header -remote_key_2: remote_value_2`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - }) - - AfterEach(func() { - closeFunc() - err = os.RemoveAll(serverDir) - Expect(err).ToNot(HaveOccurred()) - err = os.RemoveAll(tmpDir) - }) - - It("ignores them", func() { - o := &Options{} - err := o.Apply(Directories(tmpDir), NoLogs) - Expect(err).ToNot(HaveOccurred()) - - c, err := Scan(o, config.FilterKeys) - Expect(err).ToNot(HaveOccurred()) - - Expect((*c)["local_key_2"]).To(BeNil()) - Expect((*c)["remote_key_2"]).To(BeNil()) - - // sanity check, the rest should be there - v, ok := (*c)["config_url"].(string) - Expect(ok).To(BeTrue()) - Expect(v).To(MatchRegexp("remote_config_2.yaml")) - - v, ok = (*c)["local_key_1"].(string) - Expect(ok).To(BeTrue()) - Expect(v).To(Equal("local_value_1")) - - v, ok = (*c)["remote_key_1"].(string) - Expect(ok).To(BeTrue()) - Expect(v).To(Equal("remote_value_1")) - }) - }) - }) - - Describe("String", func() { - var conf *Config - BeforeEach(func() { - conf = &Config{} - err := yaml.Unmarshal([]byte("name: Mario"), conf) - Expect(err).ToNot(HaveOccurred()) - }) - - It("returns the YAML string representation of the Config", func() { - s, err := conf.String() - Expect(err).ToNot(HaveOccurred()) - Expect(s).To(Equal(`#cloud-config - -name: Mario -`), s) - }) - }) - - Describe("Query", func() { - var tmpDir string - var err error - - BeforeEach(func() { - tmpDir, err = os.MkdirTemp("", "config") - Expect(err).ToNot(HaveOccurred()) - - err = os.WriteFile(filepath.Join(tmpDir, "b"), []byte(`zz.foo="baa" options.foo=bar`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - err = os.WriteFile(path.Join(tmpDir, "local_config.yaml"), []byte(`#cloud-config -local_key_1: local_value_1 -some: - other: - key: 3 -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - }) - - It("can query for keys", func() { - o := &Options{} - - err = o.Apply(MergeBootLine, Directories(tmpDir), - WithBootCMDLineFile(filepath.Join(tmpDir, "b")), - ) - Expect(err).ToNot(HaveOccurred()) - - c, err := Scan(o, config.FilterKeys) - Expect(err).ToNot(HaveOccurred()) - - v, err := c.Query("local_key_1") - Expect(err).ToNot(HaveOccurred()) - Expect(v).To(Equal("local_value_1\n")) - v, err = c.Query("some") - Expect(err).ToNot(HaveOccurred()) - Expect(v).To(Equal("other:\n key: 3\n")) - v, err = c.Query("some.other") - Expect(v).To(Equal("key: 3\n")) - v, err = c.Query("some.other.key") - Expect(v).To(Equal("3\n")) - Expect(c.Query("options")).To(Equal("foo: bar\n")) - }) - }) -}) - -func createRemoteConfigs(serverDir string, port int) string { - err := os.WriteFile(path.Join(serverDir, "remote_config_1.yaml"), []byte(fmt.Sprintf(`#cloud-config - -config_url: http://127.0.0.1:%d/remote_config_2.yaml -player: -remote_key_1: remote_value_1 -`, port)), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - err = os.WriteFile(path.Join(serverDir, "remote_config_2.yaml"), []byte(`#cloud-config - -player: - surname: Bros -remote_key_2: remote_value_2 -`), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - cmdLinePath := filepath.Join(serverDir, "cmdline") - // We put the cmdline in the same dir, it doesn't matter. - cmdLine := fmt.Sprintf(`config_url="http://127.0.0.1:%d/remote_config_1.yaml" player.name="Toad" options.foo=bar`, port) - err = os.WriteFile(cmdLinePath, []byte(cmdLine), os.ModePerm) - Expect(err).ToNot(HaveOccurred()) - - return cmdLinePath -} diff --git a/pkg/config/collector/options.go b/pkg/config/collector/options.go deleted file mode 100644 index 48026dd..0000000 --- a/pkg/config/collector/options.go +++ /dev/null @@ -1,63 +0,0 @@ -package collector - -import "fmt" - -type Options struct { - ScanDir []string - BootCMDLineFile string - MergeBootCMDLine bool - NoLogs bool - StrictValidation bool -} - -type Option func(o *Options) error - -var NoLogs Option = func(o *Options) error { - o.NoLogs = true - return nil -} - -// SoftErr prints a warning if err is no nil and NoLogs is not true. -// It's use to wrap the same handling happening in multiple places. -// -// TODO: Switch to a standard logging library (e.g. verbose, silent mode etc). -func (o *Options) SoftErr(message string, err error) { - if !o.NoLogs && err != nil { - fmt.Printf("WARNING: %s, %s\n", message, err.Error()) - } -} - -func (o *Options) Apply(opts ...Option) error { - for _, oo := range opts { - if err := oo(o); err != nil { - return err - } - } - return nil -} - -var MergeBootLine = func(o *Options) error { - o.MergeBootCMDLine = true - return nil -} - -func WithBootCMDLineFile(s string) Option { - return func(o *Options) error { - o.BootCMDLineFile = s - return nil - } -} - -func StrictValidation(v bool) Option { - return func(o *Options) error { - o.StrictValidation = v - return nil - } -} - -func Directories(d ...string) Option { - return func(o *Options) error { - o.ScanDir = d - return nil - } -} diff --git a/pkg/config/collector/suite_test.go b/pkg/config/collector/suite_test.go deleted file mode 100644 index 3e0f578..0000000 --- a/pkg/config/collector/suite_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package collector_test - -import ( - "context" - "net" - "net/http" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -func TestConfig(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Config Collector Suite") -} - -type ServerCloseFunc func() - -func startAssetServer(path string) (ServerCloseFunc, int, error) { - listener, err := net.Listen("tcp", ":0") - if err != nil { - return nil, 0, err - } - port := listener.Addr().(*net.TCPAddr).Port - - ctx, cancelFunc := context.WithCancel(context.Background()) - go func() { - defer GinkgoRecover() - err := http.Serve(listener, http.FileServer(http.Dir(path))) - select { - case <-ctx.Done(): // We closed it with the CancelFunc, ignore the error - return - default: // We didnt' close it, return the error - Expect(err).ToNot(HaveOccurred()) - } - }() - - stopFunc := func() { - cancelFunc() - listener.Close() - } - - return stopFunc, port, nil -} diff --git a/pkg/config/config.go b/pkg/config/config.go index faaefc2..f39ad6c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -8,8 +8,8 @@ import ( "unicode" "github.com/kairos-io/kairos-sdk/bundles" + "github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos-sdk/schema" - "github.com/kairos-io/kairos/v2/pkg/config/collector" yip "github.com/mudler/yip/pkg/schema" "gopkg.in/yaml.v3"