Drop collector package and use sdk for it (#59)

This commit is contained in:
Itxaka 2023-06-14 14:44:22 +02:00 committed by GitHub
parent d3f9f169da
commit ed372395d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 51 additions and 1373 deletions

6
go.mod
View File

@ -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

30
go.sum
View File

@ -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=

View File

@ -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"
)

View File

@ -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"

View File

@ -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"

View File

@ -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"
)

View File

@ -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"

View File

@ -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"

29
main.go
View File

@ -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"

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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"