From 8c30923b8e15fe24bf6146454385140530079e14 Mon Sep 17 00:00:00 2001 From: Sohan Kunkerkar Date: Wed, 27 Jan 2021 22:53:48 -0500 Subject: [PATCH 1/5] mantle: go mod tidy --- mantle/go.sum | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/mantle/go.sum b/mantle/go.sum index d63862ae82..7e57905d2f 100644 --- a/mantle/go.sum +++ b/mantle/go.sum @@ -97,21 +97,12 @@ github.com/coreos/ignition v0.35.0 h1:UFodoYq1mOPrbEjtxIsZbThcDyQwAI1owczRDqWmKk github.com/coreos/ignition v0.35.0/go.mod h1:WJQapxzEn9DE0ryxsGvm8QnBajm/XsS/PkrDqSpz+bA= github.com/coreos/ignition/v2 v2.7.0 h1:JCKxJllVtnk1lQY1uisxrtFSHG5L2NI1LRzc8wBEk84= github.com/coreos/ignition/v2 v2.7.0/go.mod h1:3CjaRpg51hmJzPjarbzB0RvSZbLkNOczxKJobTl6nOY= -github.com/coreos/ignition/v2 v2.8.1 h1:gKCX6NwGGFh866MvpJlq2ZCqppVbWK0DA/uflL34tDU= -github.com/coreos/ignition/v2 v2.8.1/go.mod h1:A5lFFzA2/zvZQPVEvI1lR5WPLWRb7KZ7Q1QOeUMtcAc= github.com/coreos/ignition/v2 v2.9.0 h1:Zl5N08OyqlECB8BrBlMDp3Jf1ShwVTtREPcUq/YO034= github.com/coreos/ignition/v2 v2.9.0/go.mod h1:A5lFFzA2/zvZQPVEvI1lR5WPLWRb7KZ7Q1QOeUMtcAc= github.com/coreos/ioprogress v0.0.0-20151023204047-4637e494fd9b h1:mpeSDqY0vMUyJmazX0p62MrHtgwlmOf7Y8rqOYL1cmc= github.com/coreos/ioprogress v0.0.0-20151023204047-4637e494fd9b/go.mod h1:JIWRG8HSwVYUrjdR/JsFg7DEby0nhQcWFPIQvXJyih8= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/stream-metadata-go v0.0.0-20210107232620-d808ce9d237c h1:7VO10dpKljeaYJUQtObhqjNxpuTCUDELTviJsGy9OeM= -github.com/coreos/stream-metadata-go v0.0.0-20210107232620-d808ce9d237c/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= -github.com/coreos/stream-metadata-go v0.0.0-20210112152733-52b38c241a3d h1:a65dhEcT+kL9Bf5pDpdoOMdT5w0VjwUXE+XO2MoFuSg= -github.com/coreos/stream-metadata-go v0.0.0-20210115160721-ba77d4e64952 h1:t7IgMcyflINfXWPISnHTXwa/F+NxLgWGRGejoyfHUII= -github.com/coreos/stream-metadata-go v0.0.0-20210115160721-ba77d4e64952/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= -github.com/coreos/stream-metadata-go v0.0.0-20210120211222-7575c72c6f05 h1:GXgmcV54WyU3LDXRwf3vXtgkmajMHoYfQ/qCuPblr4A= -github.com/coreos/stream-metadata-go v0.0.0-20210120211222-7575c72c6f05/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= github.com/coreos/stream-metadata-go v0.0.0-20210121193119-2fbf8747cee7 h1:6LNM7FalzC7155uc5ecuUmD1x70QsOexZYGVHnLc4OE= github.com/coreos/stream-metadata-go v0.0.0-20210121193119-2fbf8747cee7/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= github.com/coreos/stream-metadata-go v0.0.0-20210216154348-7c4d5d7d95b5 h1:rFS+eq6Wghj4SOylbWmWcYWkAho4+35NHIMZBv9EozA= @@ -121,6 +112,7 @@ github.com/coreos/vcontext v0.0.0-20201120045928-b0e13dab675c h1:jA28WeORitsxGFV github.com/coreos/vcontext v0.0.0-20201120045928-b0e13dab675c/go.mod h1:z4pMVvaUrxs98RROlIYdAQCKhEicjnTirOaVyDRH5h8= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -188,6 +180,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -213,6 +206,7 @@ github.com/gophercloud/gophercloud v0.13.0 h1:1XkslZZRm6Ks0bLup+hBNth+KQf+0JA1Ue github.com/gophercloud/gophercloud v0.13.0/go.mod h1:VX0Ibx85B60B5XOrZr6kaNwrmPUzcmMpwxvQ1WQIIWM= github.com/gophercloud/utils v0.0.0-20201101202656-8677e053dcf1 h1:W9579vuRvR1tBzjDMn4E2HwYx4OZUWxH/7SQwWnKwbM= github.com/gophercloud/utils v0.0.0-20201101202656-8677e053dcf1/go.mod h1:ehWUbLQJPqS0Ep+CxeD559hsm9pthPXadJNKwZkp43w= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -234,6 +228,7 @@ github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 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/kballard/go-shellquote v0.0.0-20150810074751-d8ec1a69a250 h1:QyPDU73WRl/8CnuK3JltZLLuNhL3E4o3BROt4g8nFf0= @@ -243,8 +238,10 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v0.0.0-20150519154555-21cb3784d9bd h1:fQAexocAuf0oCEyjbn9Gd1GpkBkJjznx3ltKeDNdtrc= github.com/kylelemons/godebug v0.0.0-20150519154555-21cb3784d9bd/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= @@ -268,6 +265,7 @@ github.com/pin/tftp v2.1.0+incompatible/go.mod h1:xVpZOMCXTy+A5QMjEVN0Glwa1sUvaJ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -282,11 +280,14 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -304,6 +305,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -524,6 +526,7 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -614,6 +617,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk= @@ -626,6 +630,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20190502103701-55513cacd4ae/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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= From f85bc91b770aaaa4a20e91e6360b32f7427ef014 Mon Sep 17 00:00:00 2001 From: Sohan Kunkerkar Date: Tue, 26 Jan 2021 11:14:44 -0500 Subject: [PATCH 2/5] platform: add qemu specific information for boot-mirror RAID1 tests --- mantle/platform/machine/unprivqemu/machine.go | 4 + mantle/platform/qemu.go | 76 ++++++++++++++++++- mantle/platform/qmp_util.go | 13 ++++ 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/mantle/platform/machine/unprivqemu/machine.go b/mantle/platform/machine/unprivqemu/machine.go index c0c58cae26..b3b4dec23c 100644 --- a/mantle/platform/machine/unprivqemu/machine.go +++ b/mantle/platform/machine/unprivqemu/machine.go @@ -112,3 +112,7 @@ func (m *machine) JournalOutput() string { } return string(data) } + +func (m *machine) RemovePrimaryBlockDevice() error { + return m.inst.RemovePrimaryBlockDevice() +} diff --git a/mantle/platform/qemu.go b/mantle/platform/qemu.go index 172f992c7a..7a5cfefb94 100644 --- a/mantle/platform/qemu.go +++ b/mantle/platform/qemu.go @@ -71,6 +71,16 @@ type QemuMachineOptions struct { MultiPathDisk bool } +// QEMUMachine represents a qemu instance. +type QEMUMachine interface { + // Embedding the Machine interface + Machine + + // RemovePrimaryBlockDevice removes the primary device from a given qemu + // instance and sets the secondary device as primary. + RemovePrimaryBlockDevice() error +} + // Disk holds the details of a virtual disk. type Disk struct { Size string // disk image size in bytes, optional suffixes "K", "M", "G", "T" allowed. @@ -241,7 +251,7 @@ func (inst *QemuInstance) Destroy() { // Currently effective on aarch64: switches the boot order to boot from disk on reboot. For s390x and aarch64, bootindex // is used to boot from the network device (boot once is not supported). For s390x, the boot ordering was not a problem as it // would always read from disk first. For aarch64, the bootindex needs to be switched to boot from disk before a reboot -func (inst *QemuInstance) SwitchBootOrder() (err error) { +func (inst *QemuInstance) SwitchBootOrder() (err2 error) { if system.RpmArch() != "s390x" && system.RpmArch() != "aarch64" { //Not applicable for other arches return nil @@ -256,10 +266,10 @@ func (inst *QemuInstance) SwitchBootOrder() (err error) { defer func() { e := monitor.Disconnect() - if err != nil { - err = fmt.Errorf("%v; %v", err, e) + if err2 != nil { + err2 = fmt.Errorf("%v; %v", err2, e) } else { - err = e + err2 = e } }() devs, err := listQMPDevices(monitor, inst.tempdir) @@ -306,6 +316,64 @@ func (inst *QemuInstance) SwitchBootOrder() (err error) { return nil } +// RemovePrimaryBlockDevice deletes the primary device from a qemu instance +// and sets the seconday device as primary. It expects that all block devices +// are mirrors. +func (inst *QemuInstance) RemovePrimaryBlockDevice() (err2 error) { + var primaryDevice string + var secondaryDevicePath string + monitor, err := newQMPMonitor(inst.tempdir) + if err != nil { + return errors.Wrapf(err, "Could not connect to QMP device") + } + if err := monitor.Connect(); err != nil { + return errors.Wrapf(err, "Could not connect to QMP device") + } + + defer func() { + e := monitor.Disconnect() + if err2 != nil { + err2 = fmt.Errorf("%v; %v", err, e) + } else { + err2 = e + } + }() + blkdevs, err := listQMPBlkDevices(monitor, inst.tempdir) + if err != nil { + return errors.Wrapf(err, "Could not list block devices through qmp") + } + // This tries to identify the primary device by looking into a `BackingFileDepth` + // parameter of a device and check if it is a removable device and part of + // `virtio-blk-pci` devices. + for _, dev := range blkdevs.Return { + if !dev.Removable && strings.Contains(dev.DevicePath, "virtio-backend") { + if dev.Inserted.BackingFileDepth == 1 { + primaryDevice = dev.DevicePath + } else { + secondaryDevicePath = dev.DevicePath + } + } + } + err = setBootIndexForDevice(monitor, primaryDevice, -1) + if err != nil { + return errors.Wrapf(err, "Could not set bootindex for %v", primaryDevice) + } + primaryDevice = primaryDevice[:strings.LastIndex(primaryDevice, "/")] + err = deleteBlockDevice(monitor, primaryDevice) + if err != nil { + return errors.Wrapf(err, "Could not delete primary device %v", primaryDevice) + } + if len(secondaryDevicePath) == 0 { + return errors.Wrapf(err, "Could not find secondary device") + } + err = setBootIndexForDevice(monitor, secondaryDevicePath, 1) + if err != nil { + return errors.Wrapf(err, "Could not set bootindex for %v", secondaryDevicePath) + } + + return nil +} + // QemuBuilder is a configurator that can then create a qemu instance type QemuBuilder struct { // ConfigFile is a path to Ignition configuration diff --git a/mantle/platform/qmp_util.go b/mantle/platform/qmp_util.go index 706ef98781..56f2bd4bd4 100644 --- a/mantle/platform/qmp_util.go +++ b/mantle/platform/qmp_util.go @@ -40,6 +40,10 @@ type QOMBlkDev struct { Return []struct { Device string `json:"device"` DevicePath string `json:"qdev"` + Removable bool `json:"removable"` + Inserted struct { + BackingFileDepth int `json:"backing_file_depth"` + } `json:"inserted"` } `json:"return"` } @@ -98,3 +102,12 @@ func setBootIndexForDevice(monitor *qmp.SocketMonitor, device string, bootindex } return nil } + +// Delete a block device for the particular qemu instance +func deleteBlockDevice(monitor *qmp.SocketMonitor, device string) error { + cmd := fmt.Sprintf(`{ "execute": "device_del", "arguments": { "id":"%s" } }`, device) + if _, err := monitor.Run([]byte(cmd)); err != nil { + return errors.Wrapf(err, "Running QMP command") + } + return nil +} From 45ba8f248e16c3a7d1f2721f4a4eca0f51791abc Mon Sep 17 00:00:00 2001 From: Sohan Kunkerkar Date: Fri, 29 Jan 2021 05:24:24 -0500 Subject: [PATCH 3/5] util: refactor lukstest logic for better utilization --- mantle/kola/tests/ignition/luks.go | 81 +++++------------------------- mantle/kola/tests/util/luks.go | 81 ++++++++++++++++++++++++++++++ mantle/platform/qemu.go | 6 +-- 3 files changed, 97 insertions(+), 71 deletions(-) create mode 100644 mantle/kola/tests/util/luks.go diff --git a/mantle/kola/tests/ignition/luks.go b/mantle/kola/tests/ignition/luks.go index f574163fea..c4a3731f56 100644 --- a/mantle/kola/tests/ignition/luks.go +++ b/mantle/kola/tests/ignition/luks.go @@ -2,12 +2,12 @@ package ignition import ( "fmt" - "regexp" "time" "github.com/coreos/mantle/kola" "github.com/coreos/mantle/kola/cluster" "github.com/coreos/mantle/kola/register" + ut "github.com/coreos/mantle/kola/tests/util" "github.com/coreos/mantle/platform" "github.com/coreos/mantle/platform/conf" "github.com/coreos/mantle/platform/machine/unprivqemu" @@ -48,13 +48,7 @@ func init() { }) } -type tangServer struct { - machine platform.Machine - address string - thumbprint string -} - -func setupTangMachine(c cluster.TestCluster) tangServer { +func setupTangMachine(c cluster.TestCluster) ut.TangServer { var m platform.Machine var err error var thumbprint []byte @@ -120,67 +114,13 @@ func setupTangMachine(c cluster.TestCluster) tangServer { c.Fatalf("Unable to retrieve Tang keys: %v", err) } - return tangServer{ - machine: m, - address: tangAddress, - thumbprint: string(thumbprint), - } -} - -func mustMatch(c cluster.TestCluster, r string, output []byte) { - m, err := regexp.Match(r, output) - if err != nil { - c.Fatalf("Failed to match regexp %s: %v", r, err) - } - if !m { - c.Fatalf("Regexp %s did not match text: %s", r, output) + return ut.TangServer{ + Machine: m, + Address: tangAddress, + Thumbprint: string(thumbprint), } } -func mustNotMatch(c cluster.TestCluster, r string, output []byte) { - m, err := regexp.Match(r, output) - if err != nil { - c.Fatalf("Failed to match regexp %s: %v", r, err) - } - if m { - c.Fatalf("Regexp %s matched text: %s", r, output) - } -} - -func luksSanityTest(c cluster.TestCluster, tangd tangServer, m platform.Machine, tpm2, killTangAfterFirstBoot bool) { - rootPart := "/dev/disk/by-partlabel/root" - // hacky, but needed for s390x because of gpt issue with naming on big endian systems: https://bugzilla.redhat.com/show_bug.cgi?id=1899990 - if system.RpmArch() == "s390x" { - rootPart = "/dev/disk/by-id/virtio-primary-disk-part4" - } - - luksDump := c.MustSSH(m, "sudo cryptsetup luksDump "+rootPart) - // Yes, some hacky regexps. There is luksDump --debug-json but we'd have to massage the JSON - // out of other debug output and it's not clear to me it's going to be more stable. - // We're just going for a basic sanity check here. - mustMatch(c, "Cipher: *aes", luksDump) - mustNotMatch(c, "Cipher: *cipher_null-ecb", luksDump) - mustMatch(c, "0: *clevis", luksDump) - mustNotMatch(c, "9: *coreos", luksDump) - - s := c.MustSSH(m, "sudo clevis luks list -d "+rootPart) - mustMatch(c, "tang", s) - if tpm2 { - mustMatch(c, "tpm2", s) - } - // And validate we can automatically unlock it on reboot. - // We kill the tang server if we're testing thresholding - if killTangAfterFirstBoot { - tangd.machine.Destroy() - } - err := m.Reboot() - if err != nil { - c.Fatalf("Failed to reboot the machine: %v", err) - } - luksDump = c.MustSSH(m, "sudo cryptsetup luksDump "+rootPart) - mustMatch(c, "Cipher: *aes", luksDump) -} - func runTest(c cluster.TestCluster, tpm2 bool, threshold int, killTangAfterFirstBoot bool) { tangd := setupTangMachine(c) ignition := conf.Ignition(fmt.Sprintf(`{ @@ -215,7 +155,7 @@ func runTest(c cluster.TestCluster, tpm2 bool, threshold int, killTangAfterFirst } ] } - }`, tpm2, tangd.address, tangd.thumbprint, threshold)) + }`, tpm2, tangd.Address, tangd.Thumbprint, threshold)) opts := platform.MachineOptions{ MinMemory: 4096, @@ -229,7 +169,12 @@ func runTest(c cluster.TestCluster, tpm2 bool, threshold int, killTangAfterFirst if err != nil { c.Fatalf("Unable to create test machine: %v", err) } - luksSanityTest(c, tangd, m, tpm2, killTangAfterFirstBoot) + rootPart := "/dev/disk/by-partlabel/root" + // hacky, but needed for s390x because of gpt issue with naming on big endian systems: https://bugzilla.redhat.com/show_bug.cgi?id=1899990 + if system.RpmArch() == "s390x" { + rootPart = "/dev/disk/by-id/virtio-primary-disk-part4" + } + ut.LUKSSanityTest(c, tangd, m, tpm2, killTangAfterFirstBoot, rootPart) } // Verify that the rootfs is encrypted with Tang diff --git a/mantle/kola/tests/util/luks.go b/mantle/kola/tests/util/luks.go new file mode 100644 index 0000000000..a256930ee5 --- /dev/null +++ b/mantle/kola/tests/util/luks.go @@ -0,0 +1,81 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package util + +import ( + "regexp" + + "github.com/coreos/mantle/kola/cluster" + "github.com/coreos/mantle/platform" +) + +// TangServer contains fields required to set up a tang server +// Note: Placing it here to avoid circular dependency issue +type TangServer struct { + Machine platform.Machine + Address string + Thumbprint string +} + +func mustMatch(c cluster.TestCluster, r string, output []byte) { + m, err := regexp.Match(r, output) + if err != nil { + c.Fatalf("Failed to match regexp %s: %v", r, err) + } + if !m { + c.Fatalf("Regexp %s did not match text: %s", r, output) + } +} + +func mustNotMatch(c cluster.TestCluster, r string, output []byte) { + m, err := regexp.Match(r, output) + if err != nil { + c.Fatalf("Failed to match regexp %s: %v", r, err) + } + if m { + c.Fatalf("Regexp %s matched text: %s", r, output) + } +} + +// LUKSSanityTest verifies that the rootfs is encrypted with LUKS +func LUKSSanityTest(c cluster.TestCluster, tangd TangServer, m platform.Machine, tpm2, killTangAfterFirstBoot bool, rootPart string) { + luksDump := c.MustSSH(m, "sudo cryptsetup luksDump "+rootPart) + // Yes, some hacky regexps. There is luksDump --debug-json but we'd have to massage the JSON + // out of other debug output and it's not clear to me it's going to be more stable. + // We're just going for a basic sanity check here. + mustMatch(c, "Cipher: *aes", luksDump) + mustNotMatch(c, "Cipher: *cipher_null-ecb", luksDump) + mustMatch(c, "0: *clevis", luksDump) + mustNotMatch(c, "9: *coreos", luksDump) + + s := c.MustSSH(m, "sudo clevis luks list -d "+rootPart) + if tpm2 { + mustMatch(c, "tpm2", s) + } + tangConf := TangServer{} + if tangd != tangConf { + mustMatch(c, "tang", s) + // And validate we can automatically unlock it on reboot. + // We kill the tang server if we're testing thresholding + if killTangAfterFirstBoot { + tangd.Machine.Destroy() + } + } + err := m.Reboot() + if err != nil { + c.Fatalf("Failed to reboot the machine: %v", err) + } + luksDump = c.MustSSH(m, "sudo cryptsetup luksDump "+rootPart) + mustMatch(c, "Cipher: *aes", luksDump) +} diff --git a/mantle/platform/qemu.go b/mantle/platform/qemu.go index 7a5cfefb94..326c13c415 100644 --- a/mantle/platform/qemu.go +++ b/mantle/platform/qemu.go @@ -342,9 +342,9 @@ func (inst *QemuInstance) RemovePrimaryBlockDevice() (err2 error) { if err != nil { return errors.Wrapf(err, "Could not list block devices through qmp") } - // This tries to identify the primary device by looking into a `BackingFileDepth` - // parameter of a device and check if it is a removable device and part of - // `virtio-blk-pci` devices. + // This tries to identify the primary device by looking into + // a `BackingFileDepth` parameter of a device and check if + // it is a removable and part of `virtio-blk-pci` devices. for _, dev := range blkdevs.Return { if !dev.Removable && strings.Contains(dev.DevicePath, "virtio-backend") { if dev.Inserted.BackingFileDepth == 1 { From c605548bb8c82c1d25f7478e7fa2b80ba3b2da27 Mon Sep 17 00:00:00 2001 From: Sohan Kunkerkar Date: Fri, 5 Feb 2021 07:53:06 -0500 Subject: [PATCH 4/5] kola: add support for filtering tests by firmware --- mantle/kola/harness.go | 5 +++++ mantle/kola/register/register.go | 2 ++ 2 files changed, 7 insertions(+) diff --git a/mantle/kola/harness.go b/mantle/kola/harness.go index 55379a60f9..c74494136d 100644 --- a/mantle/kola/harness.go +++ b/mantle/kola/harness.go @@ -391,6 +391,11 @@ func filterTests(tests map[string]*register.Test, patterns []string, pltfrm stri if allowed, excluded := isAllowed(Options.Distribution, t.Distros, t.ExcludeDistros); !allowed || excluded { continue } + if pltfrm == "qemu-unpriv" { + if allowed, excluded := isAllowed(QEMUOptions.Firmware, t.Firmwares, t.ExcludeFirmwares); !allowed || excluded { + continue + } + } // Check native tests for arch-specific and distro-specfic exclusion for k, NativeFuncWrap := range t.NativeFuncs { diff --git a/mantle/kola/register/register.go b/mantle/kola/register/register.go index bc209e8b61..8c329df9b1 100644 --- a/mantle/kola/register/register.go +++ b/mantle/kola/register/register.go @@ -57,7 +57,9 @@ type Test struct { UserDataV3 *conf.UserData ClusterSize int Platforms []string // allowlist of platforms to run test against -- defaults to all + Firmwares []string // allowlist of firmwares to run test against -- defaults to all ExcludePlatforms []string // denylist of platforms to ignore -- defaults to none + ExcludeFirmwares []string // denylist of firmwares to ignore -- defaults to none Distros []string // allowlist of distributions to run test against -- defaults to all ExcludeDistros []string // denylist of distributions to ignore -- defaults to none Architectures []string // allowlist of machine architectures supported -- defaults to all From 1b88d519d145d66a3056affa11804c52d0ade025 Mon Sep 17 00:00:00 2001 From: Sohan Kunkerkar Date: Tue, 26 Jan 2021 11:19:25 -0500 Subject: [PATCH 5/5] kola: add test to validate boot-mirror RAID1 changes --- mantle/kola/tests/misc/boot-mirror.go | 465 ++++++++++++++++++++++++++ 1 file changed, 465 insertions(+) create mode 100644 mantle/kola/tests/misc/boot-mirror.go diff --git a/mantle/kola/tests/misc/boot-mirror.go b/mantle/kola/tests/misc/boot-mirror.go new file mode 100644 index 0000000000..a3f9e2ceb6 --- /dev/null +++ b/mantle/kola/tests/misc/boot-mirror.go @@ -0,0 +1,465 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package misc + +import ( + "strings" + + "github.com/coreos/mantle/kola" + "github.com/coreos/mantle/kola/cluster" + "github.com/coreos/mantle/kola/register" + "github.com/coreos/mantle/kola/tests/util" + "github.com/coreos/mantle/platform" + "github.com/coreos/mantle/platform/conf" + "github.com/coreos/mantle/platform/machine/unprivqemu" + "github.com/coreos/mantle/system" +) + +var ( + /* The FCCT config used for generating this ignition config: + variant: fcos + version: 1.3.0 + boot_device: + mirror: + devices: + - /dev/sda + - /dev/sdb + - /dev/sdc + */ + bootmirror = conf.Ignition(`{ + "ignition": { + "version": "3.2.0" + }, + "storage": { + "disks": [ + { + "device": "/dev/vda", + "partitions": [ + { + "label": "bios-1", + "sizeMiB": 1, + "typeGuid": "21686148-6449-6E6F-744E-656564454649" + }, + { + "label": "esp-1", + "sizeMiB": 127, + "typeGuid": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" + }, + { + "label": "boot-1", + "sizeMiB": 384 + }, + { + "label": "root-1" + } + ], + "wipeTable": true + }, + { + "device": "/dev/vdb", + "partitions": [ + { + "label": "bios-2", + "sizeMiB": 1, + "typeGuid": "21686148-6449-6E6F-744E-656564454649" + }, + { + "label": "esp-2", + "sizeMiB": 127, + "typeGuid": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" + }, + { + "label": "boot-2", + "sizeMiB": 384 + }, + { + "label": "root-2" + } + ], + "wipeTable": true + }, + { + "device": "/dev/vdc", + "partitions": [ + { + "label": "bios-3", + "sizeMiB": 1, + "typeGuid": "21686148-6449-6E6F-744E-656564454649" + }, + { + "label": "esp-3", + "sizeMiB": 127, + "typeGuid": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" + }, + { + "label": "boot-3", + "sizeMiB": 384 + }, + { + "label": "root-3" + } + ], + "wipeTable": true + } + ], + "filesystems": [ + { + "device": "/dev/disk/by-partlabel/esp-1", + "format": "vfat", + "label": "esp-1", + "wipeFilesystem": true + }, + { + "device": "/dev/disk/by-partlabel/esp-2", + "format": "vfat", + "label": "esp-2", + "wipeFilesystem": true + }, + { + "device": "/dev/disk/by-partlabel/esp-3", + "format": "vfat", + "label": "esp-3", + "wipeFilesystem": true + }, + { + "device": "/dev/md/md-boot", + "format": "ext4", + "label": "boot", + "wipeFilesystem": true + }, + { + "device": "/dev/md/md-root", + "format": "xfs", + "label": "root", + "wipeFilesystem": true + } + ], + "raid": [ + { + "devices": [ + "/dev/disk/by-partlabel/boot-1", + "/dev/disk/by-partlabel/boot-2", + "/dev/disk/by-partlabel/boot-3" + ], + "level": "raid1", + "name": "md-boot", + "options": [ + "--metadata=1.0" + ] + }, + { + "devices": [ + "/dev/disk/by-partlabel/root-1", + "/dev/disk/by-partlabel/root-2", + "/dev/disk/by-partlabel/root-3" + ], + "level": "raid1", + "name": "md-root" + } + ] + } + }`) + + /* The FCCT config used for generating this ignition config: + variant: fcos + version: 1.3.0 + boot_device: + luks: + tpm2: true + mirror: + devices: + - /dev/sda + - /dev/sdb + */ + bootmirrorluks = conf.Ignition(`{ + "ignition": { + "version": "3.2.0" + }, + "storage": { + "disks": [ + { + "device": "/dev/vda", + "partitions": [ + { + "label": "bios-1", + "sizeMiB": 1, + "typeGuid": "21686148-6449-6E6F-744E-656564454649" + }, + { + "label": "esp-1", + "sizeMiB": 127, + "typeGuid": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" + }, + { + "label": "boot-1", + "sizeMiB": 384 + }, + { + "label": "root-1" + } + ], + "wipeTable": true + }, + { + "device": "/dev/vdb", + "partitions": [ + { + "label": "bios-2", + "sizeMiB": 1, + "typeGuid": "21686148-6449-6E6F-744E-656564454649" + }, + { + "label": "esp-2", + "sizeMiB": 127, + "typeGuid": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" + }, + { + "label": "boot-2", + "sizeMiB": 384 + }, + { + "label": "root-2" + } + ], + "wipeTable": true + } + ], + "filesystems": [ + { + "device": "/dev/disk/by-partlabel/esp-1", + "format": "vfat", + "label": "esp1", + "wipeFilesystem": true + }, + { + "device": "/dev/disk/by-partlabel/esp-2", + "format": "vfat", + "label": "esp2", + "wipeFilesystem": true + }, + { + "device": "/dev/md/md-boot", + "format": "ext4", + "label": "boot", + "wipeFilesystem": true + }, + { + "device": "/dev/mapper/root", + "format": "xfs", + "label": "root", + "wipeFilesystem": true + } + ], + "luks": [ + { + "clevis": { + "tpm2": true + }, + "device": "/dev/md/md-root", + "label": "luks-root", + "name": "root", + "wipeVolume": true + } + ], + "raid": [ + { + "devices": [ + "/dev/disk/by-partlabel/boot-1", + "/dev/disk/by-partlabel/boot-2" + ], + "level": "raid1", + "name": "md-boot", + "options": [ + "--metadata=1.0" + ] + }, + { + "devices": [ + "/dev/disk/by-partlabel/root-1", + "/dev/disk/by-partlabel/root-2" + ], + "level": "raid1", + "name": "md-root" + } + ] + } + }`) +) + +func init() { + register.RegisterTest(®ister.Test{ + Run: runBootMirrorTest, + ClusterSize: 0, + Name: `coreos.boot-mirror`, + Platforms: []string{"qemu-unpriv"}, + // skipping this test on UEFI until https://github.com/coreos/coreos-assembler/issues/2039 + // gets resolved. + ExcludeFirmwares: []string{"uefi"}, + Tags: []string{"boot-mirror", "raid1"}, + FailFast: true, + }) + register.RegisterTest(®ister.Test{ + Run: runBootMirrorLUKSTest, + ClusterSize: 0, + Name: `coreos.boot-mirror.luks`, + Platforms: []string{"qemu-unpriv"}, + // aarch64 and ppc64le are added temporarily to avoid test failure until + // we support specifying FCC directly in kola. For more information: + // https://github.com/coreos/coreos-assembler/issues/2035 + // Also, TPM doesn't support s390x in qemu. + ExcludeArchitectures: []string{"aarch64", "ppc64le", "s390x"}, + // skipping this test on UEFI until https://github.com/coreos/coreos-assembler/issues/2039 + // gets resolved. + ExcludeFirmwares: []string{"uefi"}, + Tags: []string{"boot-mirror", "luks", "raid1", "tpm2", kola.NeedsInternetTag}, + FailFast: true, + }) +} + +// runBootMirrorTest verifies if the boot-mirror RAID1 +// flow works properly in both BIOS and UEFI modes. +func runBootMirrorTest(c cluster.TestCluster) { + var m platform.Machine + var err error + options := platform.QemuMachineOptions{ + MachineOptions: platform.MachineOptions{ + AdditionalDisks: []string{"5120M", "5120M"}, + MinMemory: 4096, + }, + } + m, err = c.Cluster.(*unprivqemu.Cluster).NewMachineWithQemuOptions(bootmirror, options) + if err != nil { + c.Fatal(err) + } + rootOutput := c.MustSSH(m, "sudo mdadm --export --detail /dev/md/md-root") + if !strings.Contains(string(rootOutput), "/dev/vda4") || !strings.Contains(string(rootOutput), "/dev/vdb4") || !strings.Contains(string(rootOutput), "/dev/vdc4") { + c.Fatalf("root raid device missing; found devices: %v", string(rootOutput)) + } + bootOutput := c.MustSSH(m, "sudo mdadm --export --detail /dev/md/md-boot") + if !strings.Contains(string(bootOutput), "/dev/vda3") || !strings.Contains(string(bootOutput), "/dev/vdb3") || !strings.Contains(string(bootOutput), "/dev/vdc3") { + c.Fatalf("boot raid device missing; found devices: %v", string(bootOutput)) + } + // Check for root + checkIfMountpointIsRaid(c, m, "/sysroot") + fsTypeForRoot := c.MustSSH(m, "findmnt -nvr /sysroot -o FSTYPE") + if strings.Compare(string(fsTypeForRoot), "xfs") != 0 { + c.Fatalf("didn't match fstype for root") + } + bootMirrorSanityTest(c, m) + + detachPrimaryBlockDevice(c, m) + // Check if there are two devices with the active raid + rootOutput = c.MustSSH(m, "sudo mdadm --export --detail /dev/md/md-root") + if strings.Contains(string(rootOutput), "/dev/vdc4") || !(strings.Contains(string(rootOutput), "/dev/vda4") && strings.Contains(string(rootOutput), "/dev/vdb4")) { + c.Fatalf("found unexpected root raid device; expected devices: %v", string(rootOutput)) + } + bootOutput = c.MustSSH(m, "sudo mdadm --export --detail /dev/md/md-boot") + if strings.Contains(string(bootOutput), "/dev/vdc3") || !(strings.Contains(string(bootOutput), "/dev/vda3") && strings.Contains(string(bootOutput), "/dev/vdb3")) { + c.Fatalf("found unexpected boot raid device; expected devices: %v", string(bootOutput)) + } + verifyBootMirrorAfterReboot(c, m) +} + +// runBootMirrorLUKSTest verifies if the boot-mirror+LUKS RAID1 +// flow works properly in both BIOS and UEFI modes. +func runBootMirrorLUKSTest(c cluster.TestCluster) { + var m platform.Machine + var err error + options := platform.QemuMachineOptions{ + MachineOptions: platform.MachineOptions{ + AdditionalDisks: []string{"5120M"}, + MinMemory: 4096, + }, + } + m, err = c.Cluster.(*unprivqemu.Cluster).NewMachineWithQemuOptions(bootmirrorluks, options) + if err != nil { + c.Fatal(err) + } + rootOutput := c.MustSSH(m, "sudo mdadm --export --detail /dev/md/md-root") + if !strings.Contains(string(rootOutput), "/dev/vda4") || !strings.Contains(string(rootOutput), "/dev/vdb4") { + c.Fatalf("root raid device missing; found devices: %v", string(rootOutput)) + } + bootOutput := c.MustSSH(m, "sudo mdadm --export --detail /dev/md/md-boot") + if !strings.Contains(string(bootOutput), "/dev/vda3") || !strings.Contains(string(bootOutput), "/dev/vdb3") { + c.Fatalf("boot raid device missing; found devices: %v", string(bootOutput)) + } + bootMirrorSanityTest(c, m) + luksTPMTest(c, m, true) + + detachPrimaryBlockDevice(c, m) + // Check if there's only one device with the active raid + rootOutput = c.MustSSH(m, "sudo mdadm --export --detail /dev/md/md-root") + if !strings.Contains(string(rootOutput), "/dev/vda4") || strings.Contains(string(rootOutput), "/dev/vdb4") { + c.Fatalf("found unexpected root raid device; expected devices: %v", string(rootOutput)) + } + bootOutput = c.MustSSH(m, "sudo mdadm --export --detail /dev/md/md-boot") + if !strings.Contains(string(bootOutput), "/dev/vda3") || strings.Contains(string(bootOutput), "/dev/vdb3") { + c.Fatalf("found unexpected boot raid device; expected devices: %v", string(bootOutput)) + } + verifyBootMirrorAfterReboot(c, m) + // Re-check luks device after rebooting a machine + luksTPMTest(c, m, true) +} + +func luksTPMTest(c cluster.TestCluster, m platform.Machine, tpm2 bool) { + rootPart := "/dev/md/md-root" + // hacky, but needed for s390x because of gpt issue with naming on big endian systems: https://bugzilla.redhat.com/show_bug.cgi?id=1899990 + if system.RpmArch() == "s390x" { + rootPart = "/dev/disk/by-id/virtio-primary-disk-part4" + } + var tangd util.TangServer + util.LUKSSanityTest(c, tangd, m, true, false, rootPart) +} + +func bootMirrorSanityTest(c cluster.TestCluster, m platform.Machine) { + c.Run("sanity-check", func(c cluster.TestCluster) { + // Check for boot + checkIfMountpointIsRaid(c, m, "/boot") + fsTypeForBoot := c.MustSSH(m, "findmnt -nvr /boot -o FSTYPE") + if strings.Compare(string(fsTypeForBoot), "ext4") != 0 { + c.Fatalf("didn't match fstype for boot") + } + // Check that growpart didn't run + c.MustSSH(m, "if [ -e /run/coreos-growpart.stamp ]; then exit 1; fi") + }) +} + +func detachPrimaryBlockDevice(c cluster.TestCluster, m platform.Machine) { + // Nuke primary block device and reboot the machine + c.Run("detach-primary", func(c cluster.TestCluster) { + if err := m.(platform.QEMUMachine).RemovePrimaryBlockDevice(); err != nil { + c.Fatalf("failed to delete the first boot disk: %v", err) + } + err := m.Reboot() + if err != nil { + c.Fatalf("Failed to reboot the machine: %v", err) + } + }) +} + +func verifyBootMirrorAfterReboot(c cluster.TestCluster, m platform.Machine) { + c.Run("verify-fallback", func(c cluster.TestCluster) { + // Check if the RAIDs are in degraded state + rootOutput := c.MustSSH(m, "sudo mdadm -Q --detail /dev/md/md-root") + if !strings.Contains(string(rootOutput), "degraded") { + c.Fatalf("didn't match the state of root raid device; expected degraded, found: %v", string(rootOutput)) + } + bootOutput := c.MustSSH(m, "sudo mdadm -Q --detail /dev/md/md-boot") + if !strings.Contains(string(bootOutput), "degraded") { + c.Fatalf("didn't match the state of boot raid device; expected degraded, found: %v", string(bootOutput)) + } + c.MustSSH(m, "grep root=UUID= /proc/cmdline") + c.MustSSH(m, "grep rd.md.uuid= /proc/cmdline") + }) +}