mirror of
https://github.com/kairos-io/kairos-sdk.git
synced 2025-04-28 03:20:52 +00:00
Adds raw disk utils
Adds raw disk utils to convert a raw disk into a GCE or Azure image Adds a new constants package to store constants that can be reused across all of our projects Expands KairosFs interface to be in line with whats used on other projects so we can use it
This commit is contained in:
parent
d334d86d43
commit
26187e369e
8
constants/constants.go
Normal file
8
constants/constants.go
Normal file
@ -0,0 +1,8 @@
|
||||
// Package constants This file contains all the constants that can be reused across the project
|
||||
package constants
|
||||
|
||||
const (
|
||||
MB = int64(1024 * 1024)
|
||||
GB = 1024 * MB
|
||||
FilePerm = 0644
|
||||
)
|
16
go.mod
16
go.mod
@ -34,9 +34,9 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
atomicgo.dev/cursor v0.1.3 // indirect
|
||||
atomicgo.dev/cursor v0.2.0 // indirect
|
||||
atomicgo.dev/keyboard v0.2.9 // indirect
|
||||
atomicgo.dev/schedule v0.0.2 // indirect
|
||||
atomicgo.dev/schedule v0.1.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.12.9 // indirect
|
||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
@ -71,7 +71,7 @@ require (
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gookit/color v1.5.3 // indirect
|
||||
github.com/gookit/color v1.5.4 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/itchyny/timefmt-go v0.1.6 // indirect
|
||||
github.com/jaypipes/pcidb v1.0.1 // indirect
|
||||
@ -79,7 +79,7 @@ require (
|
||||
github.com/lithammer/fuzzysearch v1.1.8 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/sys/mountinfo v0.7.2 // indirect
|
||||
@ -114,10 +114,10 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/term v0.25.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/term v0.26.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.26.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
|
18
go.sum
18
go.sum
@ -2,10 +2,12 @@ atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg=
|
||||
atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ=
|
||||
atomicgo.dev/cursor v0.1.3 h1:w8GcylMdZRyFzvDiGm3wy3fhZYYT7BwaqNjUFHxo0NU=
|
||||
atomicgo.dev/cursor v0.1.3/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU=
|
||||
atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU=
|
||||
atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8=
|
||||
atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ=
|
||||
atomicgo.dev/schedule v0.0.2 h1:2e/4KY6t3wokja01Cyty6qgkQM8MotJzjtqCH70oX2Q=
|
||||
atomicgo.dev/schedule v0.0.2/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
|
||||
atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
@ -96,6 +98,7 @@ github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn
|
||||
github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||
github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ=
|
||||
github.com/containerd/containerd v1.7.23/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
|
||||
github.com/containerd/containerd/v2 v2.0.0/go.mod h1:j25kDy9P48/ngb1sxWIFfK6GsnqOHoSqo1EpAod20VQ=
|
||||
github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
|
||||
github.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
@ -244,6 +247,7 @@ github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQ
|
||||
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
|
||||
github.com/gookit/color v1.5.3 h1:twfIhZs4QLCtimkP7MOxlF3A0U/5cDPseRT9M/+2SCE=
|
||||
github.com/gookit/color v1.5.3/go.mod h1:NUzwzeehUfl7GIb36pqId+UGmRfQcU/WiiyTTeNjHtE=
|
||||
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@ -262,6 +266,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/itchyny/gojq v0.12.16 h1:yLfgLxhIr/6sJNVmYfQjTIv0jGctu6/DgDoivmxTr7g=
|
||||
github.com/itchyny/gojq v0.12.16/go.mod h1:6abHbdC2uB9ogMS38XsErnfqJ94UlngIJGlRAIj4jTM=
|
||||
github.com/itchyny/gojq v0.12.17/go.mod h1:WBrEMkgAfAGO1LUcGOckBl5O726KPp+OlkKug0I/FEY=
|
||||
github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q=
|
||||
github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg=
|
||||
github.com/jaypipes/ghw v0.13.0 h1:log8MXuB8hzTNnSktqpXMHc0c/2k/WgjOMSUtnI1RV4=
|
||||
@ -300,6 +305,7 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
@ -318,6 +324,7 @@ 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/yip v1.12.0 h1:wuf103kHd0Zrxb7afquH8DxKeXqVSeqiRhBW/1gDHZQ=
|
||||
github.com/mudler/yip v1.12.0/go.mod h1:gwH7iGcr1Jimox2xKtN2AprEO00GzY7smvuycqCL7+Y=
|
||||
github.com/mudler/yip v1.13.0/go.mod h1:gwH7iGcr1Jimox2xKtN2AprEO00GzY7smvuycqCL7+Y=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
@ -330,11 +337,13 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
|
||||
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
||||
github.com/onsi/gomega v1.36.0/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
@ -359,6 +368,7 @@ github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5b
|
||||
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
|
||||
github.com/pterm/pterm v0.12.63 h1:fHlrpFiI9qLtEU0TWDWMU+tAt4qKJ/s157BEAPtGm8w=
|
||||
github.com/pterm/pterm v0.12.63/go.mod h1:Bq1eoUJ6BhUzzXG8WxA4l7T3s7d3Ogwg7v9VXlsVat0=
|
||||
github.com/pterm/pterm v0.12.80/go.mod h1:c6DeF9bSnOSeFPZlfs4ZRAFcf5SCoTwvwQ5xaKGQlHo=
|
||||
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/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
@ -372,8 +382,10 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/saferwall/pe v1.5.4 h1:tLmMggEMUfeqrpJ25zS/okUQmyFdD5xWKL2+z9njCqg=
|
||||
github.com/saferwall/pe v1.5.4/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
|
||||
github.com/saferwall/pe v1.5.6/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d h1:RQqyEogx5J6wPdoxqL132b100j8KjcVHO1c0KLRoIhc=
|
||||
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d/go.mod h1:PegD7EVqlN88z7TpCqH92hHP+GBpfomGCCnw1PFtNOA=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
@ -431,6 +443,7 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zcalusic/sysinfo v1.1.2 h1:38KUgZQmCxlN9vUTt4miis4rU5ISJXGXOJ2rY7bMC8g=
|
||||
github.com/zcalusic/sysinfo v1.1.2/go.mod h1:NX+qYnWGtJVPV0yWldff9uppNKU4h40hJIRPf/pGLv4=
|
||||
github.com/zcalusic/sysinfo v1.1.3/go.mod h1:NX+qYnWGtJVPV0yWldff9uppNKU4h40hJIRPf/pGLv4=
|
||||
go.mozilla.org/pkcs7 v0.9.0 h1:yM4/HS9dYv7ri2biPtxt8ikvB37a980dg69/pKmS+eI=
|
||||
go.mozilla.org/pkcs7 v0.9.0/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
@ -506,6 +519,7 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -568,6 +582,7 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -626,6 +641,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@ -633,6 +649,7 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -644,6 +661,7 @@ 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.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
23
types/fs.go
23
types/fs.go
@ -3,13 +3,32 @@ package types
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// KairosFS is our interface for methods that need an FS
|
||||
type KairosFS interface {
|
||||
ReadFile(filename string) ([]byte, error)
|
||||
Stat(name string) (fs.FileInfo, error)
|
||||
Open(name string) (fs.File, error)
|
||||
Chmod(name string, mode os.FileMode) error
|
||||
Create(name string) (*os.File, error)
|
||||
Mkdir(name string, perm os.FileMode) error
|
||||
Stat(name string) (os.FileInfo, error)
|
||||
Lstat(name string) (os.FileInfo, error)
|
||||
RemoveAll(path string) error
|
||||
ReadFile(filename string) ([]byte, error)
|
||||
Readlink(name string) (string, error)
|
||||
RawPath(name string) (string, error)
|
||||
ReadDir(dirname string) ([]fs.DirEntry, error)
|
||||
Remove(name string) error
|
||||
OpenFile(name string, flag int, perm fs.FileMode) (*os.File, error)
|
||||
WriteFile(filename string, data []byte, perm os.FileMode) error
|
||||
Rename(oldpath, newpath string) error
|
||||
Truncate(name string, size int64) error
|
||||
Chown(name string, uid, git int) error
|
||||
Chtimes(name string, atime, mtime time.Time) error
|
||||
Glob(pattern string) ([]string, error)
|
||||
Lchown(name string, uid, git int) error
|
||||
Link(oldname, newname string) error
|
||||
PathSeparator() rune
|
||||
Symlink(oldname, newname string) error
|
||||
}
|
||||
|
188
utils/rawDisk.go
Normal file
188
utils/rawDisk.go
Normal file
@ -0,0 +1,188 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
|
||||
"github.com/kairos-io/kairos-sdk/constants"
|
||||
"github.com/kairos-io/kairos-sdk/types"
|
||||
)
|
||||
|
||||
// Raw2Azure converts a raw disk to a VHD disk compatible with Azure
|
||||
// All VHDs on Azure must have a virtual size aligned to 1 MB (1024 × 1024 bytes)
|
||||
// The Hyper-V virtual hard disk (VHDX) format isn't supported in Azure, only fixed VHD
|
||||
func Raw2Azure(source string, logger types.KairosLogger) error {
|
||||
logger.Logger.Info().Str("source", source).Msg("Converting raw disk to Azure VHD")
|
||||
// Copy raw to new image with VHD appended
|
||||
// rename file to .vhd
|
||||
err := os.Rename(source, fmt.Sprintf("%s.vhd", source))
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error renaming raw image to vhd")
|
||||
return err
|
||||
}
|
||||
// Open it
|
||||
vhdFile, _ := os.OpenFile(fmt.Sprintf("%s.vhd", source), os.O_APPEND|os.O_WRONLY, constants.FilePerm)
|
||||
// Calculate rounded size
|
||||
info, err := vhdFile.Stat()
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error getting file info")
|
||||
return err
|
||||
}
|
||||
actualSize := info.Size()
|
||||
finalSizeBytes := ((actualSize + 1024*1024 - 1) / 1024 * 1024) * 1024 * 1024
|
||||
// Don't forget to remove 512 bytes for the header that we are going to add afterwards!
|
||||
finalSizeBytes = finalSizeBytes - 512
|
||||
// For smaller than 1 MB images, this calculation doesn't work, so we round up to 1 MB
|
||||
if finalSizeBytes == 0 {
|
||||
finalSizeBytes = 1*1024*1024 - 512
|
||||
}
|
||||
if actualSize != finalSizeBytes {
|
||||
logger.Logger.Info().Int64("actualSize", actualSize).Int64("finalSize", finalSizeBytes).Msg("Resizing image")
|
||||
// If you do not seek, you will override the data
|
||||
_, err = vhdFile.Seek(0, io.SeekEnd)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error seeking to end")
|
||||
return err
|
||||
}
|
||||
err = vhdFile.Truncate(finalSizeBytes)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error truncating file")
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Transform it to VHD
|
||||
info, err = vhdFile.Stat() // Stat again to get the new size
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error getting file info")
|
||||
return err
|
||||
}
|
||||
size := uint64(info.Size())
|
||||
header := newVHDFixed(size)
|
||||
err = binary.Write(vhdFile, binary.BigEndian, header)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error writing header")
|
||||
return err
|
||||
}
|
||||
err = vhdFile.Close()
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error closing file")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Raw2Gce transforms an image from RAW format into GCE format
|
||||
// The RAW image file must have a size in an increment of 1 GB. For example, the file must be either 10 GB or 11 GB but not 10.5 GB.
|
||||
// The disk image filename must be disk.raw.
|
||||
// The compressed file must be a .tar.gz file that uses gzip compression and the --format=oldgnu option for the tar utility.
|
||||
func Raw2Gce(source string, kairosFs types.KairosFS, logger types.KairosLogger) error {
|
||||
logger.Logger.Info().Msg("Transforming raw image into gce format")
|
||||
actImg, err := kairosFs.OpenFile(source, os.O_CREATE|os.O_APPEND|os.O_WRONLY, constants.FilePerm)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("file", source).Msg("Error opening file")
|
||||
return err
|
||||
}
|
||||
info, err := actImg.Stat()
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("file", source).Msg("Error getting file info")
|
||||
return err
|
||||
}
|
||||
actualSize := info.Size()
|
||||
finalSizeGB := actualSize/constants.GB + 1
|
||||
finalSizeBytes := finalSizeGB * constants.GB
|
||||
logger.Logger.Info().Int64("current", actualSize).Int64("final", finalSizeGB).Str("file", source).Msg("Resizing image")
|
||||
// REMEMBER TO SEEK!
|
||||
_, err = actImg.Seek(0, io.SeekEnd)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("file", source).Msg("Error seeking to end")
|
||||
return err
|
||||
}
|
||||
err = actImg.Truncate(finalSizeBytes)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("file", source).Msg("Error truncating file")
|
||||
return err
|
||||
}
|
||||
err = actImg.Close()
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("file", source).Msg("Error closing file")
|
||||
return err
|
||||
}
|
||||
|
||||
// Tar gz the image
|
||||
|
||||
// Create destination file
|
||||
file, err := kairosFs.Create(fmt.Sprintf("%s.tar.gz", source))
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("destination", fmt.Sprintf("%s.tar.gz", source)).Msg("Error creating destination file")
|
||||
return err
|
||||
}
|
||||
logger.Logger.Info().Str("destination", file.Name()).Msg("Compressing raw image into a tar.gz")
|
||||
|
||||
defer func(file *os.File) {
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("destination", file.Name()).Msg("Error closing destination file")
|
||||
}
|
||||
}(file)
|
||||
// Create gzip writer
|
||||
gzipWriter, err := gzip.NewWriterLevel(file, gzip.BestSpeed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(gzipWriter *gzip.Writer) {
|
||||
err := gzipWriter.Close()
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("destination", file.Name()).Msg("Error closing gzip writer")
|
||||
}
|
||||
}(gzipWriter)
|
||||
// Create tarwriter pointing to our gzip writer
|
||||
tarWriter := tar.NewWriter(gzipWriter)
|
||||
defer func(tarWriter *tar.Writer) {
|
||||
err = tarWriter.Close()
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("destination", file.Name()).Msg("Error closing tar writer")
|
||||
}
|
||||
}(tarWriter)
|
||||
|
||||
// Open disk.raw
|
||||
sourceFile, _ := kairosFs.Open(source)
|
||||
sourceStat, _ := sourceFile.Stat()
|
||||
defer func(sourceFile fs.File) {
|
||||
err = sourceFile.Close()
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error closing source file")
|
||||
}
|
||||
}(sourceFile)
|
||||
|
||||
// Add disk.raw file
|
||||
header := &tar.Header{
|
||||
Name: sourceStat.Name(),
|
||||
Size: sourceStat.Size(),
|
||||
Mode: int64(sourceStat.Mode()),
|
||||
Format: tar.FormatGNU,
|
||||
}
|
||||
// Write header with all the info
|
||||
err = tarWriter.WriteHeader(header)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error writing header")
|
||||
return err
|
||||
}
|
||||
// copy the actual data
|
||||
_, err = io.Copy(tarWriter, sourceFile)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error copying data")
|
||||
return err
|
||||
}
|
||||
// Remove full raw image, we already got the compressed one
|
||||
err = kairosFs.RemoveAll(source)
|
||||
if err != nil {
|
||||
logger.Logger.Error().Err(err).Str("source", source).Msg("Error removing full raw image")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
146
utils/vhd.go
Normal file
146
utils/vhd.go
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
Copyright © 2022 - 2024 SUSE LLC
|
||||
Copyright © 2024 Kairos authors
|
||||
|
||||
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 utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
uuidPkg "github.com/google/uuid"
|
||||
)
|
||||
|
||||
// This file contains utils to work with VHD disks
|
||||
|
||||
type VHDHeader struct {
|
||||
Cookie [8]byte // Cookies are used to uniquely identify the original creator of the hard disk image
|
||||
Features [4]byte // This is a bit field used to indicate specific feature support. Can be 0x00000000 (no features), 0x00000001 (Temporary, candidate for deletion on shutdown) or 0x00000002 (Reserved)
|
||||
FileFormatVersion [4]byte // Divided into a major/minor version and matches the version of the specification used in creating the file.
|
||||
DataOffset [8]byte // For fixed disks, this field should be set to 0xFFFFFFFF.
|
||||
Timestamp [4]byte // Stores the creation time of a hard disk image. This is the number of seconds since January 1, 2000 12:00:00 AM in UTC/GMT.
|
||||
CreatorApplication [4]byte // Used to document which application created the hard disk.
|
||||
CreatorVersion [4]byte // This field holds the major/minor version of the application that created the hard disk image.
|
||||
CreatorHostOS [4]byte // This field stores the type of host operating system this disk image is created on.
|
||||
OriginalSize [8]byte // This field stores the size of the hard disk in bytes, from the perspective of the virtual machine, at creation time. Info only
|
||||
CurrentSize [8]byte // This field stores the current size of the hard disk, in bytes, from the perspective of the virtual machine.
|
||||
DiskGeometry [4]byte // This field stores the cylinder, heads, and sectors per track value for the hard disk.
|
||||
DiskType [4]byte // Fixed = 2, Dynamic = 3, Differencing = 4
|
||||
Checksum [4]byte // This field holds a basic checksum of the hard disk footer. It is just a one’s complement of the sum of all the bytes in the footer without the checksum field.
|
||||
UniqueID [16]byte // This is a 128-bit universally unique identifier (UUID).
|
||||
SavedState [1]byte // This field holds a one-byte flag that describes whether the system is in saved state. If the hard disk is in the saved state the value is set to 1
|
||||
Reserved [427]byte // This field contains zeroes.
|
||||
}
|
||||
|
||||
// Lots of magic numbers here, but they are all defined in the VHD format spec
|
||||
func newVHDFixed(size uint64) VHDHeader {
|
||||
header := VHDHeader{}
|
||||
hexToField("00000002", header.Features[:])
|
||||
hexToField("00010000", header.FileFormatVersion[:])
|
||||
hexToField("ffffffffffffffff", header.DataOffset[:])
|
||||
t := uint32(time.Now().Unix() - 946684800)
|
||||
binary.BigEndian.PutUint32(header.Timestamp[:], t)
|
||||
hexToField("656c656d", header.CreatorApplication[:]) // Cos
|
||||
hexToField("73757365", header.CreatorHostOS[:]) // SUSE
|
||||
binary.BigEndian.PutUint64(header.OriginalSize[:], size)
|
||||
binary.BigEndian.PutUint64(header.CurrentSize[:], size)
|
||||
// Divide size into 512 to get the total sectors
|
||||
totalSectors := float64(size / 512)
|
||||
geometry := chsCalculation(uint64(totalSectors))
|
||||
binary.BigEndian.PutUint16(header.DiskGeometry[:2], uint16(geometry.cylinders))
|
||||
header.DiskGeometry[2] = uint8(geometry.heads)
|
||||
header.DiskGeometry[3] = uint8(geometry.sectorsPerTrack)
|
||||
hexToField("00000002", header.DiskType[:]) // Fixed 0x00000002
|
||||
hexToField("00000000", header.Checksum[:])
|
||||
uuid := uuidPkg.New() // Generate a new UUID v4!
|
||||
copy(header.UniqueID[:], uuid.String())
|
||||
generateChecksum(&header)
|
||||
return header
|
||||
}
|
||||
|
||||
// generateChecksum generates the checksum of the vhd header
|
||||
// Lifted from the official VHD Format Spec
|
||||
func generateChecksum(header *VHDHeader) {
|
||||
buffer := new(bytes.Buffer)
|
||||
_ = binary.Write(buffer, binary.BigEndian, header)
|
||||
checksum := 0
|
||||
bb := buffer.Bytes()
|
||||
for counter := 0; counter < 512; counter++ {
|
||||
checksum += int(bb[counter])
|
||||
}
|
||||
binary.BigEndian.PutUint32(header.Checksum[:], uint32(^checksum))
|
||||
}
|
||||
|
||||
// hexToField decodes an hex to bytes and copies it to the given header field
|
||||
func hexToField(hexs string, field []byte) {
|
||||
h, _ := hex.DecodeString(hexs)
|
||||
copy(field, h)
|
||||
}
|
||||
|
||||
// chs is a simple struct to represent the cylinders/heads/sectors for a given sector count
|
||||
type chs struct {
|
||||
cylinders uint
|
||||
heads uint
|
||||
sectorsPerTrack uint
|
||||
}
|
||||
|
||||
// chsCalculation calculates the cylinders, headers and sectors per track for a given sector count
|
||||
// Exactly the same code on the official VHD format spec
|
||||
func chsCalculation(sectors uint64) chs {
|
||||
var sectorsPerTrack,
|
||||
heads,
|
||||
cylinderTimesHeads,
|
||||
cylinders float64
|
||||
totalSectors := float64(sectors)
|
||||
|
||||
if totalSectors > 65535*16*255 {
|
||||
totalSectors = 65535 * 16 * 255
|
||||
}
|
||||
|
||||
if totalSectors >= 65535*16*63 {
|
||||
sectorsPerTrack = 255
|
||||
heads = 16
|
||||
cylinderTimesHeads = math.Floor(totalSectors / sectorsPerTrack)
|
||||
} else {
|
||||
sectorsPerTrack = 17
|
||||
cylinderTimesHeads = math.Floor(totalSectors / sectorsPerTrack)
|
||||
heads = math.Floor((cylinderTimesHeads + 1023) / 1024)
|
||||
if heads < 4 {
|
||||
heads = 4
|
||||
}
|
||||
if (cylinderTimesHeads >= (heads * 1024)) || heads > 16 {
|
||||
sectorsPerTrack = 31
|
||||
heads = 16
|
||||
cylinderTimesHeads = math.Floor(totalSectors / sectorsPerTrack)
|
||||
}
|
||||
if cylinderTimesHeads >= (heads * 1024) {
|
||||
sectorsPerTrack = 63
|
||||
heads = 16
|
||||
cylinderTimesHeads = math.Floor(totalSectors / sectorsPerTrack)
|
||||
}
|
||||
}
|
||||
|
||||
cylinders = cylinderTimesHeads / heads
|
||||
|
||||
return chs{
|
||||
cylinders: uint(cylinders),
|
||||
heads: uint(heads),
|
||||
sectorsPerTrack: uint(sectorsPerTrack),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user