diff --git a/go.mod b/go.mod index 0b0d6a95..16984cbb 100644 --- a/go.mod +++ b/go.mod @@ -95,7 +95,6 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.3.3 // indirect github.com/imdario/mergo v0.3.15 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/itchyny/gojq v0.12.12 // indirect github.com/itchyny/timefmt-go v0.1.5 // indirect github.com/jaypipes/pcidb v1.0.0 // indirect @@ -148,7 +147,6 @@ require ( github.com/spectrocloud-labs/herd v0.4.2 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect diff --git a/go.sum b/go.sum index 81276103..a5511723 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,6 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/itchyny/gojq v0.12.12 h1:x+xGI9BXqKoJQZkr95ibpe3cdrTbY8D9lonrK433rcA= github.com/itchyny/gojq v0.12.12/go.mod h1:j+3sVkjxwd7A7Z5jrbKibgOLn0ZfLWkV+Awxr/pyzJE= github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= @@ -450,12 +448,6 @@ github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 h1:FaZD86+A9mV github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5/go.mod h1:WmKcT8ONmhDQIqQ+HxU+tkGWjzBEyY/KFO8LTGCu4AI= github.com/mudler/go-processmanager v0.0.0-20220724164624-c45b5c61312d h1:/lAg9vPAAU+s35cDMCx1IyeMn+4OYfCBPqi08Q8vXDg= github.com/mudler/go-processmanager v0.0.0-20220724164624-c45b5c61312d/go.mod h1:HGGAOJhipApckwNV8ZTliRJqxctUv3xRY+zbQEwuytc= -github.com/mudler/yip v1.3.1 h1:zkkgloHJAJShELt4Zha7is2iU5WdBWz2+6f55nTK/Ms= -github.com/mudler/yip v1.3.1/go.mod h1:3WeDh6tGX1yYPJom05E7xEjw8dNVlkH2WFxLi7Gflzk= -github.com/mudler/yip v1.4.0 h1:wQxzJaDNmT5E2KdO1dTGZWUKROZ/+V4RfgBlI7KQILc= -github.com/mudler/yip v1.4.0/go.mod h1:LfUDdI6xtPbnVsxfXapP2mrZKZXoxca1v70zxXG3epA= -github.com/mudler/yip v1.4.1 h1:vqWRQyQaXY8CHlNWDBHRzuk4F+HJfEu3XcQ57yuJvPs= -github.com/mudler/yip v1.4.1/go.mod h1:LfUDdI6xtPbnVsxfXapP2mrZKZXoxca1v70zxXG3epA= github.com/mudler/yip v1.4.2 h1:HaX1xdz/KHAKbLCESDFoo0zAq/QR3N16gxQwe3iGf6s= github.com/mudler/yip v1.4.2/go.mod h1:LfUDdI6xtPbnVsxfXapP2mrZKZXoxca1v70zxXG3epA= github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= @@ -541,8 +533,6 @@ github.com/pterm/pterm v0.12.65 h1:HNMNCh2Zi6Lk+g5b8pORrFM9Ygz10GZUUcCFUkGpK2Q= github.com/pterm/pterm v0.12.65/go.mod h1:CpJq+fr0+xKGlPFDhKTkepte2fY3Ydr5bzSJ9di67uI= github.com/qeesung/image2ascii v1.0.1 h1:Fe5zTnX/v/qNC3OC4P/cfASOXS501Xyw2UUcgrLgtp4= github.com/qeesung/image2ascii v1.0.1/go.mod h1:kZKhyX0h2g/YXa/zdJR3JnLnJ8avHjZ3LrvEKSYyAyU= -github.com/rancher-sandbox/linuxkit v1.0.1-0.20230517173613-432a87ba3e09 h1:/yNp//3ZC5J7KUaUPDmomQ78j8VUD/2T/uT+TvS4M0w= -github.com/rancher-sandbox/linuxkit v1.0.1-0.20230517173613-432a87ba3e09/go.mod h1:n6Fkjc5qoMeWrnLSA5oqUF8ZzFKMrM960CtBwfvH1ZM= github.com/rancher-sandbox/linuxkit v1.0.1 h1:LYKmv1XozmQGRV6Ilm88Fx/t54okVa8rx00wLJPZkBw= github.com/rancher-sandbox/linuxkit v1.0.1/go.mod h1:n6Fkjc5qoMeWrnLSA5oqUF8ZzFKMrM960CtBwfvH1ZM= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -594,8 +584,6 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -706,8 +694,6 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -796,8 +782,6 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -809,8 +793,6 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -903,8 +885,6 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc 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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -913,8 +893,6 @@ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -928,8 +906,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 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.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1094,8 +1070,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= diff --git a/internal/agent/agent.go b/internal/agent/agent.go index 9cc122d5..4d4bb376 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -2,10 +2,11 @@ package agent import ( "fmt" - v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1" "os" "path/filepath" + v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1" + hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks" "github.com/kairos-io/kairos-agent/v2/internal/bus" config "github.com/kairos-io/kairos-agent/v2/pkg/config" diff --git a/internal/agent/install.go b/internal/agent/install.go index 97b71842..48ec6871 100644 --- a/internal/agent/install.go +++ b/internal/agent/install.go @@ -5,8 +5,6 @@ import ( "encoding/json" "errors" "fmt" - fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs" - "github.com/sanity-io/litter" "net/url" "os" "path/filepath" @@ -14,6 +12,9 @@ import ( "syscall" "time" + fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs" + "github.com/sanity-io/litter" + hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks" "github.com/kairos-io/kairos-agent/v2/internal/bus" "github.com/kairos-io/kairos-agent/v2/internal/cmd" diff --git a/internal/agent/reset.go b/internal/agent/reset.go index 1e5963b8..bbc9b0ca 100644 --- a/internal/agent/reset.go +++ b/internal/agent/reset.go @@ -3,6 +3,10 @@ package agent import ( "encoding/json" "fmt" + "os" + "sync" + "time" + hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks" "github.com/kairos-io/kairos-agent/v2/internal/bus" "github.com/kairos-io/kairos-agent/v2/internal/cmd" @@ -12,16 +16,13 @@ import ( "github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos-sdk/machine" "github.com/kairos-io/kairos-sdk/utils" - "os" - "sync" - "time" "github.com/mudler/go-pluggable" ) func Reset(reboot, unattended bool, dir ...string) error { bus.Manager.Initialize() - + // This config is only for reset branding. agentConfig, err := LoadConfig() if err != nil { diff --git a/internal/agent/upgrade.go b/internal/agent/upgrade.go index 12422c06..8231a344 100644 --- a/internal/agent/upgrade.go +++ b/internal/agent/upgrade.go @@ -4,10 +4,12 @@ import ( "context" "encoding/json" "fmt" - hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks" - "github.com/spf13/viper" "sort" + "github.com/spf13/viper" + + hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks" + "github.com/Masterminds/semver/v3" "github.com/kairos-io/kairos-agent/v2/internal/bus" "github.com/kairos-io/kairos-agent/v2/pkg/action" diff --git a/main.go b/main.go index 11211d00..3d34a369 100644 --- a/main.go +++ b/main.go @@ -3,14 +3,16 @@ package main import ( "context" "encoding/json" + "errors" "fmt" - "github.com/kairos-io/kairos-agent/v2/pkg/utils" "os" "path/filepath" "regexp" "runtime" "strings" + "github.com/kairos-io/kairos-agent/v2/pkg/utils" + "github.com/kairos-io/kairos-agent/v2/internal/agent" "github.com/kairos-io/kairos-agent/v2/internal/bus" "github.com/kairos-io/kairos-agent/v2/internal/common" @@ -118,7 +120,8 @@ See https://kairos.io/docs/upgrade/manual/ for documentation. return fmt.Errorf("source %s does not match any of oci:, dir: or file: ", source) } } - return nil + + return checkRoot() }, Action: func(c *cli.Context) error { var v string @@ -229,6 +232,9 @@ E.g. kairos-agent install-bundle container:quay.io/kairos/kairos... }, }, UsageText: "Install a bundle manually in the node", + Before: func(c *cli.Context) error { + return checkRoot() + }, Action: func(c *cli.Context) error { if c.Args().Len() != 1 { return fmt.Errorf("bundle name required") @@ -381,6 +387,9 @@ This command is meant to be used from the boot GRUB menu, but can be also starte }, }, Usage: "Starts interactive installation", + Before: func(c *cli.Context) error { + return checkRoot() + }, Action: func(c *cli.Context) error { return agent.InteractiveInstall(c.Bool("debug"), c.Bool("shell")) }, @@ -402,6 +411,9 @@ This command is meant to be used from the boot GRUB menu, but can be also starte Name: "reboot", }, }, + Before: func(c *cli.Context) error { + return checkRoot() + }, Action: func(c *cli.Context) error { if c.NArg() == 0 { return fmt.Errorf("expect one argument. the config file - if you don't have it, use the interactive-install") @@ -423,6 +435,9 @@ See also https://kairos.io/docs/installation/qrcode/ for documentation. This command is meant to be used from the boot GRUB menu, but can be started manually`, Aliases: []string{"i"}, + Before: func(c *cli.Context) error { + return checkRoot() + }, Action: func(c *cli.Context) error { return agent.Install(configScanDir...) }, @@ -456,6 +471,9 @@ This command is meant to be used from the boot GRUB menu, but can likely be used Usage: "Do not wait for user input and provide ttys after reset. Also sets the fast mode (do not wait 60 seconds before reset)", }, }, + Before: func(c *cli.Context) error { + return checkRoot() + }, Action: func(c *cli.Context) error { reboot := c.Bool("reboot") unattended := c.Bool("unattended") @@ -534,7 +552,8 @@ The validate command expects a configuration file as its only argument. Local fi _ = cli.ShowSubcommandHelp(c) return fmt.Errorf("") } - return nil + + return checkRoot() }, Action: func(c *cli.Context) error { stage := c.Args().First() @@ -573,11 +592,7 @@ The validate command expects a configuration file as its only argument. Local fi return fmt.Errorf("") } - if os.Geteuid() != 0 { - return fmt.Errorf("this command requires root privileges") - } - - return nil + return checkRoot() }, Action: func(c *cli.Context) error { image := c.Args().Get(0) @@ -663,3 +678,11 @@ The kairos agent is a component to abstract away node ops, providing a common fe os.Exit(1) } } + +func checkRoot() error { + if os.Geteuid() != 0 { + return errors.New("this command requires root privileges") + } + + return nil +}