Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
f9281ee
wait for login progress
frhuelsz Dec 15, 2025
8c1579b
Merge branch 'main' into user/frhuelsz/storm/e2e-2
frhuelsz Dec 16, 2025
75da58c
retrieve serial
frhuelsz Dec 16, 2025
b7e00dc
remove all ansi from log
frhuelsz Dec 16, 2025
59442d1
Improve artifact management
frhuelsz Dec 16, 2025
8fa9296
Merge branch 'main' into user/frhuelsz/storm/e2e-2
frhuelsz Dec 21, 2025
8b23b74
serial updates
frhuelsz Dec 22, 2025
6402941
serial console
frhuelsz Dec 22, 2025
107f0a0
Fully functional console monitoring
frhuelsz Dec 23, 2025
8b38db0
undo update
frhuelsz Dec 23, 2025
5475842
Update pipeline invocation with output
frhuelsz Dec 23, 2025
8e28210
More reliability
frhuelsz Dec 23, 2025
e5f1ac9
Use storm v0.4.0-alpha1
frhuelsz Dec 23, 2025
1e4be22
cleanup
frhuelsz Dec 23, 2025
01a900f
pr comments
frhuelsz Dec 23, 2025
775ac0a
pr comments
frhuelsz Dec 23, 2025
62608b2
Address copilot feedback
frhuelsz Dec 30, 2025
47022ed
more copilot comments
frhuelsz Dec 30, 2025
a81f67f
pr comments
frhuelsz Dec 30, 2025
81cf17e
PR comments
frhuelsz Dec 30, 2025
ce5ff54
Comment
frhuelsz Dec 30, 2025
9df0e11
Fix deadlock
frhuelsz Dec 30, 2025
af24a13
Close channel on error
frhuelsz Dec 30, 2025
5e4370c
avoid resource leak
frhuelsz Dec 30, 2025
4f9ea11
more robust console exit
frhuelsz Dec 31, 2025
2d7996e
Better force exit console
frhuelsz Dec 31, 2025
a0a457d
pr comments
frhuelsz Jan 5, 2026
22c2ada
cleanup
frhuelsz Jan 5, 2026
5b5dc46
pr comments
frhuelsz Jan 5, 2026
66001c7
pr comments
frhuelsz Jan 5, 2026
305fc8c
pr comments
frhuelsz Jan 6, 2026
3c7333e
pr comments
frhuelsz Jan 22, 2026
0ae93ac
pr comments
frhuelsz Jan 22, 2026
5c0dce3
pr comments
frhuelsz Jan 22, 2026
bbabee7
pr comments
frhuelsz Jan 22, 2026
dfa2506
pr comments
frhuelsz Jan 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ stages:

mkdir -p $(ob_outputDirectory)

./bin/storm-trident run "$(scenario)" -- \
./bin/storm-trident run "$(scenario)" \
-o $(ob_outputDirectory) \
-- \
--pipeline-run \
--iso "./artifacts/iso/$(installerISOName).iso"
displayName: "🧪 Run E2E Test"
5 changes: 1 addition & 4 deletions tools/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ go 1.24.0

toolchain go1.24.2

// Deal with CVE-2024-45338, CVE-2025-22870, CVE-2025-22872
replace golang.org/x/net => golang.org/x/net v0.39.0

require (
github.com/bmc-toolbox/bmclib/v2 v2.0.1-0.20230530141715-da28e42c453f
github.com/digitalocean/go-libvirt v0.0.0-20250512231903-57024326652b
github.com/dustin/go-humanize v1.0.1
github.com/fatih/color v1.18.0
github.com/google/uuid v1.6.0
github.com/microsoft/storm v0.3.0
github.com/microsoft/storm v0.4.0-alpha1
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.13.9
github.com/sirupsen/logrus v1.9.3
Expand Down
44 changes: 35 additions & 9 deletions tools/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/microsoft/storm v0.3.0 h1:tT5mTFEUieoagL17hBPq0aewm2+M6ez2us4m8RDkMkA=
github.com/microsoft/storm v0.3.0/go.mod h1:QMLHpLhA/rI2bmMFor4Vxd6N99k1eadlrXv6lPLbXks=
github.com/microsoft/storm v0.4.0-alpha1 h1:U4Bn6rZQW33xrAq+s4pVT7D+RG7crWYTcOPboGysAyo=
github.com/microsoft/storm v0.4.0-alpha1/go.mod h1:QMLHpLhA/rI2bmMFor4Vxd6N99k1eadlrXv6lPLbXks=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
Expand Down Expand Up @@ -137,58 +137,84 @@ go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA=
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
16 changes: 16 additions & 0 deletions tools/pkg/ref/ref.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
package ref

import "reflect"

func Of[E any](e E) *E {
return &e
}

func IsNilInterface(v any) bool {
if v == nil {
return true
}
rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Func,
reflect.Interface, reflect.Chan, reflect.UnsafePointer:
return rv.IsNil()
default:
return false
}
}
6 changes: 5 additions & 1 deletion tools/pkg/virtdeploy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"

"github.com/digitalocean/go-libvirt"
"libvirt.org/go/libvirtxml"
)

type VirtDeployConfig struct {
Expand Down Expand Up @@ -54,7 +55,7 @@ type VirtDeployVM struct {
// MAC address of the VM
mac macAddress

// UUID of the VM according to libvirt
// Domain metadata from libvirt
domain libvirt.Domain

// Storage volumes for the VM
Expand All @@ -73,6 +74,9 @@ type VirtDeployVM struct {
nvramFile string
nvramPath string

// Final domain definition at creation time
domainDefinition *libvirtxml.Domain

// User-configurable fields

// Number of virtual CPUs
Expand Down
24 changes: 22 additions & 2 deletions tools/pkg/virtdeploy/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/digitalocean/go-libvirt"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"libvirt.org/go/libvirtxml"
)

const (
Expand Down Expand Up @@ -236,6 +237,8 @@ func (rc *virtDeployResourceConfig) construct() (*VirtDeployStatus, error) {
MACAddress: vm.mac.String(),
Uuid: uuid.UUID(vm.domain.UUID),
NvramPath: vm.nvramPath,
Definition: vm.domainDefinition,
Domain: vm.domain,
}
}

Expand Down Expand Up @@ -551,10 +554,10 @@ func (rc *virtDeployResourceConfig) setupVm(vm *VirtDeployVM) error {
vm.cdroms[i].device = fmt.Sprintf("sd%c", 'z'-i) // /dev/sdz, /dev/sdy, etc.
}

// Turn the configuration into XML
// Generate the final domain definition, and store it in the VM struct
domainXML, err := vm.asXml(rc.network, rc.nvramPool)
if err != nil {
return fmt.Errorf("generate domain XML: %w", err)
return fmt.Errorf("failed to produce domain XML: %w", err)
}

log.Tracef("Defining domain with XML:\n%s", domainXML)
Expand All @@ -565,6 +568,23 @@ func (rc *virtDeployResourceConfig) setupVm(vm *VirtDeployVM) error {
return fmt.Errorf("define domain: %w", err)
}

// Get the full domain XML definition from libvirt to store in the VM struct
// for status reporting. This ensures we have the final definition as
// libvirt sees it. We use the DomainGetXMLDesc method with 0 flags to get
// the full XML. The previous domainXML variable may not include all
// auto-generated fields.
rXml, err := rc.lv.DomainGetXMLDesc(vm.domain, 0)
if err != nil {
return fmt.Errorf("get domain XML description: %w", err)
}

// Initialize empty struct and unmarshal the XML into it
vm.domainDefinition = &libvirtxml.Domain{}
err = vm.domainDefinition.Unmarshal(rXml)
if err != nil {
return fmt.Errorf("unmarshal domain XML description: %w", err)
}

log.Infof("Created domain '%s'", vm.name)

return nil
Expand Down
16 changes: 15 additions & 1 deletion tools/pkg/virtdeploy/status.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package virtdeploy

import "github.com/google/uuid"
import (
"github.com/digitalocean/go-libvirt"
"github.com/google/uuid"
"libvirt.org/go/libvirtxml"
)

type VirtDeployStatus struct {
// Namespace in which the resources were created
Expand Down Expand Up @@ -28,4 +32,14 @@ type VirtDeployVMStatus struct {

// Path to the VM's NVRAM file on the host
NvramPath string `json:"nvramPath"`

// Full XML definition of the libvirt domain at creation time.
Definition *libvirtxml.Domain `json:"-"`

// Underlying libvirt Domain object
Domain libvirt.Domain `json:"-"`
}

func (v *VirtDeployVMStatus) LibvirtUUID() libvirt.UUID {
return libvirt.UUID(v.Uuid)
}
33 changes: 31 additions & 2 deletions tools/storm/e2e/scenario/install.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package scenario

import (
"context"
"errors"
"fmt"
"os"
"time"
"tridenttools/pkg/netlaunch"
"tridenttools/pkg/phonehome"

Expand Down Expand Up @@ -51,19 +54,45 @@ func (s *TridentE2EScenario) installOs(tc storm.TestCase) error {
MaxPhonehomeFailures: s.configParams.MaxExpectedFailures,
}

nlErr := netlaunch.RunNetlaunch(tc.Context(), &config)
timeoutCtx, cancel := context.WithTimeout(tc.Context(), time.Duration(s.args.VmWaitForLoginTimeout)*time.Second)
defer cancel()

// Start VM serial monitor (only runs if hardware is VM)
monWaitChan, monErr := s.spawnVMSerialMonitor(timeoutCtx, tc.ArtifactBroker().StreamArtifactData("install/serial.log"))
if monErr != nil {
return fmt.Errorf("failed to start VM serial monitor: %w", monErr)
}

nlErr := netlaunch.RunNetlaunch(timeoutCtx, &config)
if nlErr != nil {
// If this is a phonehome error, log the details and fail the test case
// immediately.
if phonehomeErr, ok := nlErr.(*phonehome.PhoneHomeFailureError); ok {
var phonehomeErr *phonehome.PhoneHomeFailureError
if errors.As(nlErr, &phonehomeErr) {
log.Errorf("Phonehome error details: %s", phonehomeErr.Message)
tc.FailFromError(nlErr)
}

// If this is a timeout error, log and fail the test case.
if errors.Is(nlErr, context.DeadlineExceeded) {
log.Errorln("Netlaunch operation timed out")
tc.FailFromError(nlErr)
}

// Otherwise just return the error
return nlErr
}

// If we got here netlaunch completed successfully, give some time for the
// serial monitor to get to the login prompt.
select {
case <-time.After(time.Minute):
log.Infof("Waited 1 minute for serial monitor to reach login prompt, cancelling monitor.")
cancel()
case <-monWaitChan:
// Monitor exited on its own
}

return nil
}

Expand Down
Loading