Use lsblk to detect partitions

like we did here:

https://github.com/kairos-io/kairos-sdk/pull/28/files

because ghw doesn't play well with lvm

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
(cherry picked from commit f225315a5a)
This commit is contained in:
Dimitris Karakasilis 2023-06-13 14:41:53 +03:00 committed by Itxaka
parent ed372395d2
commit 09f293c279
15 changed files with 604 additions and 207 deletions

View File

@ -79,4 +79,4 @@ webui-tests:
COPY . src/
WORKDIR src/
RUN .github/cypress_tests.sh
SAVE ARTIFACT /src/internal/webui/public/cypress/videos videos
SAVE ARTIFACT /src/internal/webui/public/cypress/videos videos

26
go.sum
View File

@ -95,8 +95,6 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z
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=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
@ -104,7 +102,6 @@ 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=
@ -133,7 +130,6 @@ 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=
@ -142,11 +138,8 @@ 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=
@ -183,8 +176,6 @@ 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=
@ -262,7 +253,6 @@ 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=
@ -381,8 +371,6 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
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=
github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
github.com/jaypipes/ghw v0.10.0 h1:UHu9UX08Py315iPojADFPOkmjTsNzHj4g4adsNKKteY=
@ -437,7 +425,6 @@ 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=
@ -471,7 +458,6 @@ 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=
@ -490,7 +476,6 @@ 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=
@ -499,11 +484,9 @@ 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=
@ -562,7 +545,6 @@ 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=
@ -667,7 +649,6 @@ 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=
@ -691,7 +672,6 @@ 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=
@ -725,7 +705,6 @@ 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=
@ -749,7 +728,6 @@ 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=
@ -761,7 +739,6 @@ 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=
@ -1200,13 +1177,11 @@ 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=
@ -1227,7 +1202,6 @@ 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

@ -16,8 +16,10 @@ limitations under the License.
package action_test
import (
"fmt"
"testing"
"github.com/kairos-io/kairos/v2/pkg/constants"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@ -26,3 +28,76 @@ func TestActionSuite(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Actions test suite")
}
func lsblkMockOutput() []byte {
return []byte(fmt.Sprintf(
`{
"blockdevices": [
{
"name": "mmcblk0",
"pkname": null,
"path": "/dev/mmcblk0",
"fstype": null,
"mountpoint": null,
"size": 64088965120,
"ro": false,
"label": null
},{
"name": "mmcblk0p1",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p1",
"fstype": "vfat",
"mountpoint": null,
"size": 100663296,
"ro": false,
"label": "COS_GRUB"
},{
"name": "mmcblk0p2",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p2",
"fstype": "ext4",
"mountpoint": "%s",
"size": 6501171200,
"ro": false,
"label": "COS_STATE"
},{
"name": "mmcblk0p3",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p3",
"fstype": "LVM2_member",
"mountpoint": null,
"size": 4471128064,
"ro": false,
"label": null
},{
"name": "mmcblk0p4",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p4",
"fstype": "ext4",
"mountpoint": "/usr/local",
"size": 67108864,
"ro": false,
"label": "COS_PERSISTENT"
},{
"name": "KairosVG-oem",
"pkname": "mmcblk0p3",
"path": "/dev/mapper/KairosVG-oem",
"fstype": "ext4",
"mountpoint": "/oem",
"size": 67108864,
"ro": false,
"label": "COS_OEM"
},{
"name": "KairosVG-recovery",
"pkname": "mmcblk0p3",
"path": "/dev/mapper/KairosVG-recovery",
"fstype": "ext4",
"mountpoint": null,
"mountpoint": "%s",
"size": 4399824896,
"ro": false,
"label": "COS_RECOVERY"
}
]
}`, constants.RunningStateDir, constants.LiveDir))
}

View File

@ -23,7 +23,6 @@ import (
"path/filepath"
"regexp"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos/v2/pkg/action"
"github.com/kairos-io/kairos/v2/pkg/constants"
conf "github.com/kairos-io/kairos/v2/pkg/elementalConfig"
@ -47,7 +46,6 @@ var _ = Describe("Reset action tests", func() {
var cloudInit *v1mock.FakeCloudInitRunner
var cleanup func()
var memLog *bytes.Buffer
var ghwTest v1mock.GhwMock
var extractor *v1mock.FakeImageExtractor
BeforeEach(func() {
@ -60,7 +58,7 @@ var _ = Describe("Reset action tests", func() {
extractor = v1mock.NewFakeImageExtractor(logger)
var err error
fs, cleanup, err = vfst.NewTestFS(map[string]interface{}{})
Expect(err).Should(BeNil())
Expect(err).ToNot(HaveOccurred())
cloudInit = &v1mock.FakeCloudInitRunner{}
config = conf.NewRunConfig(
@ -82,9 +80,8 @@ var _ = Describe("Reset action tests", func() {
var reset *action.ResetAction
var cmdFail, bootedFrom string
var err error
BeforeEach(func() {
Expect(err).ShouldNot(HaveOccurred())
BeforeEach(func() {
cmdFail = ""
recoveryImg := filepath.Join(constants.RunningStateDir, "cOS", constants.RecoveryImgFile)
err = utils.MkdirAll(fs, filepath.Dir(recoveryImg), constants.DirPerm)
@ -92,40 +89,6 @@ var _ = Describe("Reset action tests", func() {
_, err = fs.Create(recoveryImg)
Expect(err).To(BeNil())
mainDisk := block.Disk{
Name: "device",
Partitions: []*block.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
},
{
Name: "device2",
FilesystemLabel: "COS_STATE",
Type: "ext4",
},
{
Name: "device3",
FilesystemLabel: "COS_PERSISTENT",
Type: "ext4",
},
{
Name: "device4",
FilesystemLabel: "COS_OEM",
Type: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_RECOVERY",
Type: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
fs.Create(constants.EfiDevice)
bootedFrom = constants.SystemLabel
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
@ -135,9 +98,13 @@ var _ = Describe("Reset action tests", func() {
switch cmd {
case "cat":
return []byte(bootedFrom), nil
default:
return []byte{}, nil
case "lsblk":
if args[0] == "--list" {
return lsblkMockOutput(), nil
}
}
return []byte{}, nil
}
spec, err = conf.NewResetSpec(config.Config)
@ -162,10 +129,6 @@ var _ = Describe("Reset action tests", func() {
reset = action.NewResetAction(config, spec)
})
AfterEach(func() {
ghwTest.Clean()
})
It("Successfully resets on non-squashfs recovery", func() {
config.Reboot = true
Expect(reset.Run()).To(BeNil())

View File

@ -21,7 +21,6 @@ import (
"fmt"
"path/filepath"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos/v2/pkg/action"
"github.com/kairos-io/kairos/v2/pkg/constants"
conf "github.com/kairos-io/kairos/v2/pkg/elementalConfig"
@ -46,7 +45,6 @@ var _ = Describe("Runtime Actions", func() {
var cloudInit *v1mock.FakeCloudInitRunner
var cleanup func()
var memLog *bytes.Buffer
var ghwTest v1mock.GhwMock
var extractor *v1mock.FakeImageExtractor
BeforeEach(func() {
@ -84,12 +82,14 @@ var _ = Describe("Runtime Actions", func() {
var spec *v1.UpgradeSpec
var upgrade *action.UpgradeAction
var memLog *bytes.Buffer
activeImg := fmt.Sprintf("%s/cOS/%s", constants.RunningStateDir, constants.ActiveImgFile)
passiveImg := fmt.Sprintf("%s/cOS/%s", constants.RunningStateDir, constants.PassiveImgFile)
recoveryImgSquash := fmt.Sprintf("%s/cOS/%s", constants.LiveDir, constants.RecoverySquashFile)
recoveryImg := fmt.Sprintf("%s/cOS/%s", constants.LiveDir, constants.RecoveryImgFile)
var activeImg, passiveImg, recoveryImgSquash, recoveryImg string
BeforeEach(func() {
activeImg = fmt.Sprintf("%s/cOS/%s", constants.RunningStateDir, constants.ActiveImgFile)
passiveImg = fmt.Sprintf("%s/cOS/%s", constants.RunningStateDir, constants.PassiveImgFile)
recoveryImgSquash = fmt.Sprintf("%s/cOS/%s", constants.LiveDir, constants.RecoverySquashFile)
recoveryImg = fmt.Sprintf("%s/cOS/%s", constants.LiveDir, constants.RecoveryImgFile)
memLog = &bytes.Buffer{}
logger = v1.NewBufferLogger(memLog)
extractor = v1mock.NewFakeImageExtractor(logger)
@ -97,49 +97,28 @@ var _ = Describe("Runtime Actions", func() {
config.ImageExtractor = extractor
logger.SetLevel(logrus.DebugLevel)
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "cat" && args[0] == "/proc/cmdline" {
return []byte(constants.RecoveryLabel), nil
}
if command == "mv" && args[0] == "-f" && args[1] == spec.Recovery.File && args[2] == recoveryImg {
// fake "move"
f, _ := fs.ReadFile(spec.Recovery.File)
_ = fs.WriteFile(recoveryImg, f, constants.FilePerm)
_ = fs.RemoveAll(spec.Recovery.File)
}
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
return []byte{}, nil
}
// Create paths used by tests
utils.MkdirAll(fs, fmt.Sprintf("%s/cOS", constants.RunningStateDir), constants.DirPerm)
utils.MkdirAll(fs, fmt.Sprintf("%s/cOS", constants.LiveDir), constants.DirPerm)
})
mainDisk := block.Disk{
Name: "device",
Partitions: []*block.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
},
{
Name: "device2",
FilesystemLabel: "COS_STATE",
Type: "ext4",
MountPoint: constants.RunningStateDir,
},
{
Name: "loop0",
FilesystemLabel: "COS_ACTIVE",
Type: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_RECOVERY",
Type: "ext4",
MountPoint: constants.LiveDir,
},
{
Name: "device6",
FilesystemLabel: "COS_OEM",
Type: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})
AfterEach(func() {
ghwTest.Clean()
})
Describe(fmt.Sprintf("Booting from %s", constants.ActiveLabel), Label("active_label"), func() {
var err error
BeforeEach(func() {
@ -507,7 +486,6 @@ var _ = Describe("Runtime Actions", func() {
// Transition squash should not exist
info, err = fs.Stat(spec.Recovery.File)
Expect(err).To(HaveOccurred())
})
})
Describe("Not using squashfs", Label("non-squashfs"), func() {
@ -517,28 +495,16 @@ var _ = Describe("Runtime Actions", func() {
err = fs.WriteFile(recoveryImg, []byte("recovery"), constants.FilePerm)
Expect(err).ShouldNot(HaveOccurred())
config.Runner = runner
spec, err = conf.NewUpgradeSpec(config.Config)
Expect(err).ShouldNot(HaveOccurred())
spec.Active.Size = 10
spec.Passive.Size = 10
spec.Recovery.Size = 10
spec.RecoveryUpgrade = true
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "cat" && args[0] == "/proc/cmdline" {
return []byte(constants.RecoveryLabel), nil
}
if command == "mv" && args[0] == "-f" && args[1] == spec.Recovery.File && args[2] == recoveryImg {
// fake "move"
f, _ := fs.ReadFile(spec.Recovery.File)
_ = fs.WriteFile(recoveryImg, f, constants.FilePerm)
_ = fs.RemoveAll(spec.Recovery.File)
}
return []byte{}, nil
}
config.Runner = runner
_ = fs.WriteFile(recoveryImg, []byte("recovery"), constants.FilePerm)
// Mount recovery partition as it is expected to be mounted when booting from recovery
mounter.Mount("device5", constants.LiveDir, "auto", []string{"ro"})

View File

@ -115,6 +115,9 @@ stages:
runner = v1mock.NewFakeRunner()
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
if cmd == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if cmd == cmdFail {
return []byte{}, errors.New("command error")
}
@ -250,7 +253,8 @@ stages:
`, device)), constants.FilePerm)
Expect(err).To(BeNil())
cloudRunner := NewYipCloudInitRunner(logger, runner, afs)
Expect(cloudRunner.Run("test", "/some/yip")).NotTo(BeNil())
res := cloudRunner.Run("test", "/some/yip")
Expect(res).NotTo(BeNil())
})
It("Fails to find device by path", func() {
err := afs.WriteFile("/some/yip/layout.yaml", []byte(`
@ -280,3 +284,28 @@ stages:
})
})
})
func lsblkMockOutput() []byte {
return []byte(`{ "blockdevices":
[
{
"name": "device",
"pkname": "",
"path": "/dev/device",
"fstype": "",
"mountpoint": "",
"size": 0,
"ro": false,
"label": ""
},{
"name": "device1",
"pkname": "device",
"path": "/dev/device1",
"fstype": "ext4",
"mountpoint": "/mnt/fake1",
"size": 0,
"ro": false,
"label": "DEV_LABEL"
}
]}`)
}

View File

@ -74,7 +74,7 @@ func layoutPlugin(l logger.Interface, s schema.Stage, fs vfs.FS, console plugins
}
if !dev.Exists() {
l.Errorf("Exiting, disk not found:\n %s", s.Layout.Device.Path)
l.Errorf("Exiting, disk not found: %s", s.Layout.Device.Path)
return errors.New("Target disk not found")
}

View File

@ -40,14 +40,14 @@ var _ = Describe("Layout", Label("layout"), func() {
Partitions: []*block.Partition{
{
Name: "device1",
FilesystemLabel: "FAKE",
FilesystemLabel: "FAKE1",
Type: "ext4",
MountPoint: "/mnt/fake",
SizeBytes: 0,
},
{
Name: "device2",
FilesystemLabel: "FAKE",
FilesystemLabel: "FAKE2",
Type: "ext4",
MountPoint: "/mnt/fake",
SizeBytes: 0,
@ -65,7 +65,7 @@ var _ = Describe("Layout", Label("layout"), func() {
layout := schema.Layout{
Device: &schema.Device{
Label: "FAKE",
Label: "FAKE1",
Path: device,
},
Expand: &schema.Expand{Size: defaultSizeForTest},
@ -76,6 +76,9 @@ var _ = Describe("Layout", Label("layout"), func() {
}
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if command == "parted" && args[4] == "unit" && args[5] == "s" && args[6] == "print" {
/*
@ -143,6 +146,9 @@ BYT;
It("Fails if there is not enough space", func() {
// Override runner side effect to return 0 sectors when asked
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if command == "parted" && args[4] == "unit" && args[5] == "s" && args[6] == "print" {
rtn := `
BYT;
@ -166,6 +172,9 @@ BYT;
It("Fails if new device didnt get created", func() {
// Override runner side effect to return error when partition is recreated
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if command == "parted" && args[4] == "unit" && args[5] == "s" && args[6] == "print" {
rtn := `
BYT;
@ -189,6 +198,9 @@ BYT;
It("Fails if new device didnt get created, even when command didnt return an error", func() {
// Override runner side effect to return error when partition is recreated
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if command == "parted" && args[4] == "unit" && args[5] == "s" && args[6] == "print" {
rtn := `
BYT;
@ -215,6 +227,9 @@ BYT;
Describe("Add partitions", Label("add", "partitions"), func() {
BeforeEach(func() {
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if command == "parted" && args[4] == "unit" && args[5] == "s" && args[6] == "print" {
rtn := `
BYT;
@ -235,7 +250,7 @@ BYT;
layout := schema.Layout{
Device: &schema.Device{
Label: "FAKE",
Label: "FAKE1",
Path: device,
},
Parts: []schema.Partition{
@ -251,6 +266,9 @@ BYT;
Layout: layout,
}
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if command == "parted" && args[4] == "unit" && args[5] == "s" && args[6] == "print" {
rtn := `
BYT;
@ -303,7 +321,7 @@ BYT;
layout := schema.Layout{
Device: &schema.Device{
Label: "FAKE",
Label: "FAKE1",
Path: device,
},
Parts: partitions,
@ -324,6 +342,10 @@ BYT;
createdPartitions := []partitionData{}
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if command == "parted" && args[4] == "unit" && args[5] == "s" && args[6] == "print" {
rtn := `
BYT;
@ -401,3 +423,37 @@ BYT;
})
})
})
func lsblkMockOutput() []byte {
return []byte(`{ "blockdevices":
[
{
"name": "device",
"pkname": "",
"path": "/dev/device",
"fstype": "",
"mountpoint": "",
"size": 0,
"ro": false,
"label": ""
},{
"name": "device1",
"pkname": "device",
"path": "/dev/device1",
"fstype": "ext4",
"mountpoint": "/mnt/fake1",
"size": 0,
"ro": false,
"label": "FAKE1"
},{
"name": "device2",
"pkname": "device",
"path": "/dev/device2",
"fstype": "ext4",
"mountpoint": "/mnt/fake2",
"size": 0,
"ro": false,
"label": "FAKE2"
}
]}`)
}

View File

@ -143,7 +143,7 @@ func (e Elemental) UnmountPartitions(parts v1.PartitionList) error {
if part.MountPoint != "" {
err = e.UnmountPartition(part)
if err != nil {
errMsg += fmt.Sprintf("Failed to unmount %s\n", part.MountPoint)
errMsg += fmt.Sprintf("Failed to unmount %s\n Error: %s\n", part.MountPoint, err.Error())
failure = true
}
}

View File

@ -298,9 +298,9 @@ func NewUpgradeSpec(cfg v1.Config) (*v1.UpgradeSpec, error) {
cfg.Logger.Warnf("failed reading installation state: %s", err.Error())
}
parts, err := utils.GetAllPartitions()
parts, err := utils.GetAllPartitions(cfg.Runner)
if err != nil {
return nil, fmt.Errorf("could not read host partitions")
return nil, fmt.Errorf("could not read host partitions %w", err)
}
ep := v1.NewElementalPartitionsFromList(parts)
@ -389,9 +389,9 @@ func NewResetSpec(cfg v1.Config) (*v1.ResetSpec, error) {
cfg.Logger.Warnf("failed reading installation state: %s", err.Error())
}
parts, err := utils.GetAllPartitions()
parts, err := utils.GetAllPartitions(cfg.Runner)
if err != nil {
return nil, fmt.Errorf("could not read host partitions")
return nil, fmt.Errorf("could not read host partitions %w", err)
}
ep := v1.NewElementalPartitionsFromList(parts)

View File

@ -17,9 +17,11 @@ limitations under the License.
package elementalConfig_test
import (
"k8s.io/mount-utils"
"fmt"
"path/filepath"
"k8s.io/mount-utils"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos/v2/pkg/constants"
"github.com/kairos-io/kairos/v2/pkg/elementalConfig"
@ -212,9 +214,12 @@ var _ = Describe("Types", Label("types", "config"), func() {
switch cmd {
case "cat":
return []byte(constants.SystemLabel), nil
default:
return []byte{}, nil
case "lsblk":
if args[0] == "--list" {
return lsblkMockOutput(), nil
}
}
return []byte{}, nil
}
})
AfterEach(func() {
@ -265,9 +270,12 @@ var _ = Describe("Types", Label("types", "config"), func() {
switch cmd {
case "cat":
return []byte(bootedFrom), nil
default:
return []byte{}, nil
case "lsblk":
if args[0] == "--list" {
return lsblkMockOutput(), nil
}
}
return []byte{}, nil
}
// Set an empty disk for tests, otherwise reads the hosts hardware
@ -294,12 +302,47 @@ var _ = Describe("Types", Label("types", "config"), func() {
Expect(err.Error()).To(ContainSubstring("reset can only be called from the recovery system"))
})
It("fails to set defaults if no recovery partition detected", func() {
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
switch cmd {
case "cat":
return []byte(bootedFrom), nil
case "lsblk":
if args[0] == "--list" {
return []byte(`{ "blockdevices": [
{
"name": "mmcblk0p2",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p2",
"fstype": "ext4",
"mountpoint": "%s",
"size": 6501171200,
"ro": false,
"label": "COS_STATE"
}
] }`), nil
}
}
return []byte{}, nil
}
bootedFrom = constants.SystemLabel
_, err := elementalConfig.NewResetSpec(*c)
Expect(err).Should(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("recovery partition not found"))
})
It("fails to set defaults if no state partition detected", func() {
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
switch cmd {
case "cat":
return []byte(bootedFrom), nil
case "lsblk":
if args[0] == "--list" {
return []byte(`{ "blockdevices": [] }`), nil
}
}
return []byte{}, nil
}
mainDisk := block.Disk{
Name: "device",
Partitions: []*block.Partition{},
@ -315,6 +358,29 @@ var _ = Describe("Types", Label("types", "config"), func() {
Expect(err.Error()).To(ContainSubstring("state partition not found"))
})
It("fails to set defaults if no efi partition on efi firmware", func() {
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
switch cmd {
case "cat":
return []byte(bootedFrom), nil
case "lsblk":
if args[0] == "--list" {
return []byte(`{ "blockdevices": [
{
"name": "mmcblk0p2",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p2",
"fstype": "ext4",
"mountpoint": "%s",
"size": 6501171200,
"ro": false,
"label": "COS_STATE"
}
] }`), nil
}
}
return []byte{}, nil
}
// Set EFI firmware detection
err = utils.MkdirAll(fs, filepath.Dir(constants.EfiDevice), constants.DirPerm)
Expect(err).ShouldNot(HaveOccurred())
@ -366,6 +432,16 @@ var _ = Describe("Types", Label("types", "config"), func() {
ghwTest = v1mock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
switch cmd {
case "lsblk":
if args[0] == "--list" {
return lsblkMockOutput(), nil
}
}
return []byte{}, nil
}
})
AfterEach(func() {
ghwTest.Clean()
@ -399,3 +475,76 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
})
})
func lsblkMockOutput() []byte {
return []byte(fmt.Sprintf(
`{
"blockdevices": [
{
"name": "mmcblk0",
"pkname": null,
"path": "/dev/mmcblk0",
"fstype": null,
"mountpoint": null,
"size": 64088965120,
"ro": false,
"label": null
},{
"name": "mmcblk0p1",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p1",
"fstype": "vfat",
"mountpoint": null,
"size": 100663296,
"ro": false,
"label": "COS_GRUB"
},{
"name": "mmcblk0p2",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p2",
"fstype": "ext4",
"mountpoint": "%s",
"size": 6501171200,
"ro": false,
"label": "COS_STATE"
},{
"name": "mmcblk0p3",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p3",
"fstype": "LVM2_member",
"mountpoint": null,
"size": 4471128064,
"ro": false,
"label": null
},{
"name": "mmcblk0p4",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p4",
"fstype": "ext4",
"mountpoint": "/usr/local",
"size": 67108864,
"ro": false,
"label": "COS_PERSISTENT"
},{
"name": "KairosVG-oem",
"pkname": "mmcblk0p3",
"path": "/dev/mapper/KairosVG-oem",
"fstype": "ext4",
"mountpoint": "/oem",
"size": 67108864,
"ro": false,
"label": "COS_OEM"
},{
"name": "KairosVG-recovery",
"pkname": "mmcblk0p3",
"path": "/dev/mapper/KairosVG-recovery",
"fstype": "ext4",
"mountpoint": null,
"mountpoint": "%s",
"size": 4399824896,
"ro": false,
"label": "COS_RECOVERY"
}
]
}`, constants.RunningStateDir, constants.LiveDir))
}

View File

@ -66,7 +66,7 @@ func GetDeviceByLabel(runner v1.Runner, label string, attempts int) (string, err
func GetFullDeviceByLabel(runner v1.Runner, label string, attempts int) (*v1.Partition, error) {
for tries := 0; tries < attempts; tries++ {
_, _ = runner.Run("udevadm", "settle")
parts, err := GetAllPartitions()
parts, err := GetAllPartitions(runner)
if err != nil {
return nil, err
}
@ -362,7 +362,7 @@ func GetTempDir(config *v1.Config, suffix string) string {
config.Logger.Debugf("Got tmpdir from TMPDIR var: %s", dir)
return filepath.Join(dir, elementalTmpDir)
}
parts, err := GetAllPartitions()
parts, err := GetAllPartitions(config.Runner)
if err != nil {
config.Logger.Debug("Could not get partitions, defaulting to /tmp")
return filepath.Join("/", "tmp", elementalTmpDir)

View File

@ -17,6 +17,7 @@ limitations under the License.
package utils
import (
"encoding/json"
"fmt"
"path/filepath"
"strings"
@ -30,35 +31,80 @@ import (
v1 "github.com/kairos-io/kairos/v2/pkg/types/v1"
)
// ghwPartitionToInternalPartition transforms a block.Partition from ghw lib to our v1.Partition type
func ghwPartitionToInternalPartition(partition *block.Partition) *v1.Partition {
return &v1.Partition{
FilesystemLabel: partition.FilesystemLabel,
Size: uint(partition.SizeBytes / (1024 * 1024)), // Converts B to MB
Name: partition.Name,
FS: partition.Type,
Flags: nil,
MountPoint: partition.MountPoint,
Path: filepath.Join("/dev", partition.Name),
Disk: filepath.Join("/dev", partition.Disk.Name),
}
type PartInfo struct {
Name string `json:"name,omitempty"`
PkName string `json:"pkname,omitempty"`
Path string `json:"path,omitempty"`
Mountpoint string `json:"mountpoint,omitempty"`
FsType string `json:"fstype,omitempty"`
Size uint `json:"size,omitempty"`
Label string `json:"label,omitempty"`
RO bool `json:"ro,omitempty"`
}
// Lsblk is the struct to marshal the output of lsblk
type Lsblk struct {
BlockDevices []PartInfo `json:"blockdevices,omitempty"`
}
// GetAllPartitions returns all partitions in the system for all disks
func GetAllPartitions() (v1.PartitionList, error) {
var parts []*v1.Partition
blockDevices, err := block.New(ghw.WithDisableTools(), ghw.WithDisableWarnings())
func GetAllPartitions(runner v1.Runner) (v1.PartitionList, error) {
parts := v1.PartitionList{}
// --list : show each partition only once
// --bytes: don't show sizes in human readable format but rather number of bytes
out, err := runner.Run("lsblk", "--list", "--bytes",
"/dev/disk/by-path/*", "-o", "NAME,PKNAME,PATH,FSTYPE,MOUNTPOINT,SIZE,RO,LABEL", "-J")
if err != nil {
return nil, err
return parts, fmt.Errorf("lsblk failed with: %w\nOutput: %s", err, string(out))
}
for _, d := range blockDevices.Disks {
for _, part := range d.Partitions {
parts = append(parts, ghwPartitionToInternalPartition(part))
return PartitionsFromLsblk(string(out))
}
func PartitionsFromLsblk(lsblkOutput string) (v1.PartitionList, error) {
lsblk := &Lsblk{}
parts := v1.PartitionList{}
parentsLookup := map[string]string{}
err := json.Unmarshal([]byte(lsblkOutput), lsblk)
if err != nil {
return parts, err
}
for _, p := range lsblk.BlockDevices {
part := v1.Partition{}
parentsLookup[p.Name] = p.PkName
part.Name = p.Name
part.FilesystemLabel = p.Label
part.Size = p.Size / (1024 * 1024) // Converts B to MB
part.Flags = nil
part.MountPoint = p.Mountpoint
part.FS = p.FsType
part.Path = p.Path
parts = append(parts, &part)
}
// Add `Disk` field to all partitions
for _, p := range parts {
disk := findDisk(parentsLookup, p.Name)
if disk != "" {
p.Disk = filepath.Join("/dev", disk)
}
}
return parts, nil
}
func findDisk(parentsLookup map[string]string, pName string) string {
parent, hasParent := parentsLookup[pName]
if !hasParent || parent == "" {
return pName // A disk's disk is itself
}
return findDisk(parentsLookup, parent)
}
// GetPartitionFS gets the FS of a partition given
func GetPartitionFS(partition string) (string, error) {
// We want to have the device always prefixed with a /dev

View File

@ -0,0 +1,93 @@
package utils_test
import (
"github.com/kairos-io/kairos/v2/pkg/utils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("PartitionsFromLsblk", func() {
var lsblkOutput string
BeforeEach(func() {
lsblkOutput = `{
"blockdevices": [
{
"name": "mmcblk0",
"pkname": null,
"path": "/dev/mmcblk0",
"fstype": null,
"mountpoint": null,
"size": 64088965120,
"ro": false,
"label": null
},{
"name": "mmcblk0p1",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p1",
"fstype": "vfat",
"mountpoint": null,
"size": 100663296,
"ro": false,
"label": "COS_GRUB"
},{
"name": "mmcblk0p2",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p2",
"fstype": "ext4",
"mountpoint": "/run/initramfs/cos-state",
"size": 6501171200,
"ro": false,
"label": "COS_STATE"
},{
"name": "mmcblk0p3",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p3",
"fstype": "LVM2_member",
"mountpoint": null,
"size": 4471128064,
"ro": false,
"label": null
},{
"name": "mmcblk0p4",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p4",
"fstype": "ext4",
"mountpoint": "/usr/local",
"size": 67108864,
"ro": false,
"label": "COS_PERSISTENT"
},{
"name": "KairosVG-oem",
"pkname": "mmcblk0p3",
"path": "/dev/mapper/KairosVG-oem",
"fstype": "ext4",
"mountpoint": "/oem",
"size": 67108864,
"ro": false,
"label": "COS_OEM"
},{
"name": "KairosVG-recovery",
"pkname": "mmcblk0p3",
"path": "/dev/mapper/KairosVG-recovery",
"fstype": "ext4",
"mountpoint": null,
"size": 4399824896,
"ro": false,
"label": "COS_RECOVERY"
}
]
}`
})
It("returns all partitions with `Disk` field populated correctly", func() {
parts, err := utils.PartitionsFromLsblk(lsblkOutput)
Expect(err).ToNot(HaveOccurred())
for _, p := range parts {
Expect(p.Disk).To(Equal("/dev/mmcblk0"))
}
Expect(len(parts)).To(Equal(7))
})
})

View File

@ -189,62 +189,80 @@ var _ = Describe("Utils", Label("utils"), func() {
BeforeEach(func() {
cmds = [][]string{
{"udevadm", "settle"},
{"lsblk --list --bytes /dev/disk/by-path/* -o NAME,PKNAME,PATH,FSTYPE,MOUNTPOINT,SIZE,RO,LABEL -J"},
}
})
It("returns found device", func() {
ghwTest := v1mock.GhwMock{}
disk := block.Disk{Name: "device", Partitions: []*block.Partition{
{
Name: "device1",
FilesystemLabel: "FAKE",
},
}}
ghwTest.AddDisk(disk)
ghwTest.CreateDevices()
defer ghwTest.Clean()
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
return []byte{}, nil
}
out, err := utils.GetDeviceByLabel(runner, "FAKE", 1)
Expect(err).To(BeNil())
Expect(out).To(Equal("/dev/device1"))
Expect(runner.CmdsMatch(cmds)).To(BeNil())
})
It("fails if no device is found in two attempts", func() {
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return []byte("{}"), nil
}
return []byte{}, nil
}
_, err := utils.GetDeviceByLabel(runner, "FAKE", 2)
Expect(err).NotTo(BeNil())
Expect(runner.CmdsMatch(append(cmds, cmds...))).To(BeNil())
})
})
Describe("GetAllPartitions", Label("lsblk", "partitions"), func() {
var ghwTest v1mock.GhwMock
BeforeEach(func() {
ghwTest = v1mock.GhwMock{}
disk1 := block.Disk{
Name: "sda",
Partitions: []*block.Partition{
{
Name: "sda1Test",
},
{
Name: "sda2Test",
},
},
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return []byte(`{
"blockdevices": [
{
"name": "sda1Test",
"pkname": "",
"path": "/dev/sda1",
"fstype": "fakefs",
"mountpoint": "/mnt/fake",
"size": 0,
"ro": false,
"label": "FAKE"
},
{
"name": "sda2Test",
"pkname": "",
"path": "/dev/sda2",
"fstype": "fakefs",
"mountpoint": "/mnt/fake",
"size": 0,
"ro": false,
"label": "FAKE"
},
{
"name": "sdb1Test",
"pkname": "",
"path": "/dev/sdb1",
"fstype": "fakefs",
"mountpoint": "/mnt/fake",
"size": 0,
"ro": false,
"label": "FAKE"
}
]
}`), nil
}
return []byte{}, nil
}
disk2 := block.Disk{
Name: "sdb",
Partitions: []*block.Partition{
{
Name: "sdb1Test",
},
},
}
ghwTest.AddDisk(disk1)
ghwTest.AddDisk(disk2)
ghwTest.CreateDevices()
})
AfterEach(func() {
ghwTest.Clean()
})
It("returns all found partitions", func() {
parts, err := utils.GetAllPartitions()
parts, err := utils.GetAllPartitions(runner)
Expect(err).To(BeNil())
var partNames []string
for _, p := range parts {
@ -328,6 +346,7 @@ var _ = Describe("Utils", Label("utils"), func() {
BeforeEach(func() {
cmds = [][]string{
{"udevadm", "settle"},
{"lsblk --list --bytes /dev/disk/by-path/* -o NAME,PKNAME,PATH,FSTYPE,MOUNTPOINT,SIZE,RO,LABEL -J"},
}
})
It("returns found v1.Partition", func() {
@ -345,6 +364,14 @@ var _ = Describe("Utils", Label("utils"), func() {
ghwTest.AddDisk(disk)
ghwTest.CreateDevices()
defer ghwTest.Clean()
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
return []byte{}, nil
}
out, err := utils.GetFullDeviceByLabel(runner, "FAKE", 1)
Expect(err).To(BeNil())
Expect(out.FilesystemLabel).To(Equal("FAKE"))
@ -554,6 +581,8 @@ var _ = Describe("Utils", Label("utils"), func() {
})
It("should NOT fail if destination does not exist", func() {
sourceDir, err := os.MkdirTemp("", "elemental")
defer os.RemoveAll(sourceDir)
Expect(err).ShouldNot(HaveOccurred())
err = os.WriteFile(filepath.Join(sourceDir, "testfile"), []byte("sdjfnsdjkfjkdsanfkjsnda"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = utils.SyncData(logger, nil, sourceDir, "/welp")
@ -1125,3 +1154,20 @@ var _ = Describe("Utils", Label("utils"), func() {
})
})
})
func lsblkMockOutput() []byte {
return []byte(`{
"blockdevices": [
{
"name": "device1",
"pkname": "",
"path": "/dev/device1",
"fstype": "fakefs",
"mountpoint": "/mnt/fake",
"size": 0,
"ro": false,
"label": "FAKE"
}
]
}`)
}