diff --git a/go.mod b/go.mod index 36d5bd9..afe85c9 100644 --- a/go.mod +++ b/go.mod @@ -11,16 +11,16 @@ require ( github.com/getkin/kin-openapi v0.61.0 github.com/ghodss/yaml v1.0.0 github.com/go-ole/go-ole v1.2.5 // indirect - github.com/labstack/echo/v4 v4.3.0 + github.com/labstack/echo/v4 v4.6.3 github.com/mostlygeek/arp v0.0.0-20170424181311-541a2129847a github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil v3.21.5+incompatible github.com/spf13/cobra v1.0.0 github.com/tklauser/go-sysconf v0.3.6 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 - golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 - golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 - golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 + golang.org/x/net v0.0.0-20210913180222-943fd674d43e + golang.org/x/sys v0.0.0-20211103235746-7861aae1554b gorm.io/driver/sqlite v1.1.4 gorm.io/gorm v1.21.3 ) diff --git a/go.sum b/go.sum index 3ebef4c..4690c72 100644 --- a/go.sum +++ b/go.sum @@ -51,6 +51,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -85,8 +87,12 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/echo/v4 v4.3.0 h1:DCP6cbtT+Zu++K6evHOJzSgA2115cPMuCx0xg55q1EQ= github.com/labstack/echo/v4 v4.3.0/go.mod h1:PvmtTvhVqKDzDQy4d3bWzPjZLzom4iQbAZy2sgZ/qI8= +github.com/labstack/echo/v4 v4.6.3 h1:VhPuIZYxsbPmo4m9KAkMU/el2442eB7EBFFhNTTT9ac= +github.com/labstack/echo/v4 v4.6.3/go.mod h1:Hk5OiHj0kDqmFq7aHe7eDqI7CUhuCrfpupQtLGGLm7A= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= +github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= @@ -96,10 +102,14 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= @@ -152,6 +162,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4= github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= @@ -178,6 +189,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -192,6 +205,8 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210913180222-943fd674d43e h1:+b/22bPvDYt4NPDcy4xAGCmON713ONAWFeY3Z7I3tR8= +golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -218,6 +233,12 @@ golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -225,6 +246,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= @@ -252,6 +275,7 @@ 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-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= diff --git a/lib/drivers/vmx/vmx.go b/lib/drivers/vmx/vmx.go index 812f5c8..7ed1f5a 100644 --- a/lib/drivers/vmx/vmx.go +++ b/lib/drivers/vmx/vmx.go @@ -7,6 +7,7 @@ import ( "bytes" "errors" "fmt" + "io/ioutil" "log" "os" "os/exec" @@ -38,6 +39,7 @@ func (d *Driver) Prepare(config []byte) error { if err := d.cfg.Validate(); err != nil { return err } + // TODO: Cleanup the image directory in case the images are not good return nil } @@ -70,14 +72,15 @@ func (d *Driver) Allocate(definition string) (string, error) { vm_images_dir := filepath.Join(vm_dir, "images") // Load the required images - if err := d.loadImages(&def, vm_images_dir); err != nil { + img_path, err := d.loadImages(&def, vm_images_dir) + if err != nil { return vm_hwaddr, err } // Clone VM from the image vmx_path := filepath.Join(vm_dir, vm_id+".vmx") args := []string{"-T", "fusion", "clone", - filepath.Join(vm_images_dir, def.Image, def.Image+".vmx"), vmx_path, + img_path, vmx_path, "linked", "-snapshot", "original", } cmd := exec.Command(d.cfg.VmrunPath, args...) @@ -120,59 +123,88 @@ func (d *Driver) Allocate(definition string) (string, error) { return vm_hwaddr, nil } -func (d *Driver) loadImages(def *Definition, vm_images_dir string) error { +// Load images and returns the target image path for cloning +func (d *Driver) loadImages(def *Definition, vm_images_dir string) (string, error) { if err := os.MkdirAll(vm_images_dir, 0o755); err != nil { log.Println("VMX: Unable to create the vm images dir:", vm_images_dir) - return err + return "", err } + target_path := "" for name, url := range def.Images { archive_name := filepath.Base(url) image_archive := filepath.Join(d.cfg.WorkspacePath, archive_name) image_unpacked := filepath.Join(d.cfg.ImagesPath, strings.TrimSuffix(archive_name, ".tar.xz")) - image_vmx_path := filepath.Join(image_unpacked, name, name+".vmx") - log.Println("VMX: Loading the required image:", name, image_vmx_path, url) + log.Println("VMX: Loading the required image:", name, url) // Check the image is unpacked - if _, err := os.Stat(image_vmx_path); os.IsNotExist(err) { + if _, err := os.Stat(image_unpacked); os.IsNotExist(err) { // Download archive to workspace if err := util.DownloadUrl(url, image_archive); err != nil { log.Println("VMX: Unable to download image:", name, url) - return err + return "", err } defer os.Remove(image_archive) // Unpack archive if err := os.MkdirAll(image_unpacked, 0o755); err != nil { log.Println("VMX: Unable to create the image dir:", name, url) - return err + return "", err } if err := util.Unpack(image_archive, image_unpacked); err != nil { - log.Println("VMX: Unable to unpack image:", name, url) - return err + log.Println("VMX: Unable to unpack the image:", name, url) + return "", err } // Remove the archive if err := os.Remove(image_archive); err != nil { - log.Println("VMX: Unable to remove image archive:", image_archive, err) + log.Println("VMX: Unable to remove the image archive:", image_archive, err) + return "", err + } + } + + // Getting the subdir in the unpacked dir + subdir := "" + items, err := ioutil.ReadDir(image_unpacked) + if err != nil { + log.Println("VMX: Unable to read the unpacked directory:", image_unpacked, err) + return "", err + } + for _, f := range items { + if strings.HasPrefix(f.Name(), name) { + if f.Mode()&os.ModeSymlink != 0 { + // Potentially it can be a symlink (like used in local tests) + if _, err := os.Stat(filepath.Join(image_unpacked, f.Name())); err != nil { + log.Println("VMX: The image link is broken:", f.Name(), err) + continue + } + } + subdir = f.Name() + break } } + if subdir == "" { + log.Printf("VMX: Unpacked image '%s' has no subfolder '%s', only %s:\n", image_unpacked, name, items) + return "", errors.New("VMX: Can't find the subfolder in the unpacked image") + } - // Unfortunately the linked clones requires full path to the parent - // and modifies the image snapshots description during linked clone, - // so walk through the image files, link them to the workspace dir - // and copy the vmsd file with path to the workspace images dir - root_dir := filepath.Join(image_unpacked, name) - out_dir := filepath.Join(vm_images_dir, name) + // Unfortunately the clone operation modifies the image snapshots description + // so we walk through the image files, link them to the workspace dir and copy + // the files (except for vmdk bins) with path to the workspace images dir + root_dir := filepath.Join(image_unpacked, subdir) + out_dir := filepath.Join(vm_images_dir, subdir) + if def.Image == name { + target_path = filepath.Join(out_dir, def.Image+".vmx") + } if err := os.MkdirAll(out_dir, 0o755); err != nil { log.Println("VMX: Unable to create the vm image dir:", out_dir) - return err + return "", err } tocopy_list, err := os.ReadDir(root_dir) if err != nil { - log.Println("VMX: Unable to list image directory:", root_dir) - return err + log.Println("VMX: Unable to list the image directory:", root_dir) + return "", err } for _, entry := range tocopy_list { @@ -183,7 +215,7 @@ func (d *Driver) loadImages(def *Definition, vm_images_dir string) error { if strings.HasSuffix(entry.Name(), ".vmdk") && util.FileStartsWith(in_path, []byte("# Disk DescriptorFile")) != nil { // Just link the disk image to the vm image dir - we will not modify it anyway if err := os.Symlink(in_path, out_path); err != nil { - return err + return "", err } continue } @@ -191,9 +223,13 @@ func (d *Driver) loadImages(def *Definition, vm_images_dir string) error { // Copy VM file in order to prevent the image modification if err := util.FileCopy(in_path, out_path); err != nil { log.Println("VMX: Unable to copy image file", in_path, out_path) - return err + return "", err } + // Deprecated functionality + // Since aquarium-bait tag `20220118` the images are using only relative paths + // TODO: Remove it on release v1.0 + // // Modify the vmsd file cloneOf0 to replace token - it requires absolute path if strings.HasSuffix(entry.Name(), ".vmsd") { if err := util.FileReplaceToken(out_path, @@ -201,13 +237,13 @@ func (d *Driver) loadImages(def *Definition, vm_images_dir string) error { "", vm_images_dir, ); err != nil { log.Println("VMX: Unable to replace full path token in vmsd", name) - return err + return "", err } } } } - return nil + return target_path, nil } func (d *Driver) getAllocatedVMX(hwaddr string) string { diff --git a/lib/fish/fish.go b/lib/fish/fish.go index 0ef5ad6..e12502c 100644 --- a/lib/fish/fish.go +++ b/lib/fish/fish.go @@ -131,7 +131,10 @@ func (f *Fish) Init() error { return err } for _, res := range resources { - go f.executeApplication(res.ApplicationID) + if f.ApplicationIsAllocated(res.ApplicationID) == nil { + log.Println("Fish: Found allocated resource to serve:", res.ID) + go f.executeApplication(res.ApplicationID) + } } // Run node ping timer diff --git a/test/README.md b/test/README.md index c838ea8..1a2fe80 100644 --- a/test/README.md +++ b/test/README.md @@ -2,21 +2,14 @@ To show how to setup a simple VM with the images from aquarium-bait: -1. Build the macos-1015 images via aquarium-bait -2. In the directory where aquarium-fish is running create the next directory with symlinks: -``` -> ls -lh fish_vmx_images/* -fish_vmx_images/macos-1015-VERSION: -total 0 -lrwxr-xr-x 1 parshev staff 47 Mar 15 17:14 macos-1015 -> /Users/user/git/aquarium-bait/out/macos-1015 +1. Build the required images via aquarium-bait which will be placed into `aquarium-bait/out` dir. -fish_vmx_images/macos-1015-ci-VERSION: -total 0 -lrwxr-xr-x 1 parshev staff 50 Mar 15 17:14 macos-1015-ci -> /Users/user/git/aquarium-bait/out/macos-1015-ci +2. Locate the `fish_vmx_images` in the workdir of aquarium-fish. -fish_vmx_images/macos-1015-ci-xcode122-VERSION: -total 0 -lrwxr-xr-x 1 parshev staff 59 Mar 17 22:31 macos-1015-ci-xcode122 -> /Users/user/git/aquarium-bait/out/macos-1015-ci-xcode122 -``` -3. Now run the aquarium-fish and any `test-*` script with admin token as first argument which will -guide through the resource allocation and deallocation process +3. Run the `fill_images.sh` like that: + ``` + $ ./fill_images.sh <./path/to/fish_vmx_images> + ``` + +4. Now you can run the aquarium-fish node and required `run-*` script with admin token as first +argument which will guide through the resource allocation and deallocation process diff --git a/test/fill_images.sh b/test/fill_images.sh new file mode 100755 index 0000000..2609cd6 --- /dev/null +++ b/test/fill_images.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Script updates the specified fish_vmx_images directory based on the out dir in aquarium-bait repo +# +# Usage: +# $ ./test/fill_images.sh +# + +IMAGES_DIR=$1 +OUT_DIR=$2 + +[ -d "$IMAGES_DIR" ] || exit 1 +[ -d "$OUT_DIR" ] || exit 2 + +if [ "x$(dirname "$OUT_DIR" | cut -c1)" != 'x/' ]; then + echo "ERROR: Need absolute path to the out directory: $OUT_DIR" + exit 3 +fi + +for img in "$OUT_DIR"/*; do + # Processing only directories + [ -d "$img" ] || continue + + echo "Processing '$img'..." + + # Getting the image name + name=$(basename "$img" | rev | cut -d- -f2- | rev) + echo " name: $name" + + rm -rf "$IMAGES_DIR/$name-VERSION" + mkdir -p "$IMAGES_DIR/$name-VERSION" + ln -s "$img" "$IMAGES_DIR/$name-VERSION/" + + echo " done: $(ls -l "$IMAGES_DIR/$name-VERSION/" | tail -1)" +done diff --git a/test/run-macos1013-ci-xcode101.sh b/test/run-macos1013-ci-xcode101.sh new file mode 100755 index 0000000..767747e --- /dev/null +++ b/test/run-macos1013-ci-xcode101.sh @@ -0,0 +1,64 @@ +#!/bin/sh -e + +token=$1 +[ "$token" ] || exit 1 + +label=xcode10.1 +version=1 + +echo "Get or create the label" + +label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"%20AND%20version="'$version'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') + +if [ -z "$label_id" ]; then + label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":'$version', "driver":"vmx", + "definition": { + "image": "macos1013-ci-xcode101", + "images": { + "macos1013": "https://artifact-storage/aquarium/image/macos1013-VERSION/macos1013-VERSION.tar.xz", + "macos1013-ci": "https://artifact-storage/aquarium/image/macos1013-ci-VERSION/macos1013-ci-VERSION.tar.xz", + "macos1013-ci-xcode101": "https://artifact-storage/aquarium/image/macos1013-ci-xcode101-VERSION/macos1013-ci-xcode101-VERSION.tar.xz" + }, + "requirements": { + "cpu": 14, + "ram": 12, + "disks": { + "xcode101": { + "type": "hfs+", + "size": 100, + "reuse": true + } + } + } + }, + "metadata": { + "JENKINS_AGENT_WORKSPACE": "/Volumes/xcode101" + } + }' https://127.0.0.1:8001/api/v1/label/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +fi +echo "Label ID: ${label_id}" + +echo "Press key to get label" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/label/${label_id} + +echo "Press key to run application" +read w1 + +app_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"label_ID":'$label_id', "metadata":{ + "JENKINS_URL": "http://172.16.1.1:8085/", + "JENKINS_AGENT_SECRET": "03839eabcf945b1e780be8f9488d264c4c57bf388546da9a84588345555f29b0", + "JENKINS_AGENT_NAME": "test-node" +}}' https://127.0.0.1:8001/api/v1/application/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +echo "Application ID: ${app_id}" + +echo "Press key to check the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/resource + +echo "Press key to deallocate the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/deallocate diff --git a/test/run-macos1014-ci-xcode1131.sh b/test/run-macos1014-ci-xcode1131.sh new file mode 100755 index 0000000..d1ebfb8 --- /dev/null +++ b/test/run-macos1014-ci-xcode1131.sh @@ -0,0 +1,64 @@ +#!/bin/sh -e + +token=$1 +[ "$token" ] || exit 1 + +label=xcode10.1 +version=1 + +echo "Get or create the label" + +label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"%20AND%20version="'$version'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') + +if [ -z "$label_id" ]; then + label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":'$version', "driver":"vmx", + "definition": { + "image": "macos1014-ci-xcode1131", + "images": { + "macos1014": "https://artifact-storage/aquarium/image/macos1014-VERSION/macos1014-VERSION.tar.xz", + "macos1014-ci": "https://artifact-storage/aquarium/image/macos1014-ci-VERSION/macos1014-ci-VERSION.tar.xz", + "macos1014-ci-xcode1131": "https://artifact-storage/aquarium/image/macos1014-ci-xcode1131-VERSION/macos1014-ci-xcode1131-VERSION.tar.xz" + }, + "requirements": { + "cpu": 14, + "ram": 12, + "disks": { + "xcode101": { + "type": "hfs+", + "size": 100, + "reuse": true + } + } + } + }, + "metadata": { + "JENKINS_AGENT_WORKSPACE": "/Volumes/xcode101" + } + }' https://127.0.0.1:8001/api/v1/label/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +fi +echo "Label ID: ${label_id}" + +echo "Press key to get label" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/label/${label_id} + +echo "Press key to run application" +read w1 + +app_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"label_ID":'$label_id', "metadata":{ + "JENKINS_URL": "http://172.16.1.1:8085/", + "JENKINS_AGENT_SECRET": "03839eabcf945b1e780be8f9488d264c4c57bf388546da9a84588345555f29b0", + "JENKINS_AGENT_NAME": "test-node" +}}' https://127.0.0.1:8001/api/v1/application/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +echo "Application ID: ${app_id}" + +echo "Press key to check the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/resource + +echo "Press key to deallocate the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/deallocate diff --git a/test/test-xcode122.sh b/test/run-macos1015-ci-xcode122.sh similarity index 73% rename from test/test-xcode122.sh rename to test/run-macos1015-ci-xcode122.sh index f3ff085..f08ad9a 100755 --- a/test/test-xcode122.sh +++ b/test/run-macos1015-ci-xcode122.sh @@ -4,19 +4,20 @@ token=$1 [ "$token" ] || exit 1 label=xcode12.2 +version=1 echo "Get or create the label" -label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"%20AND%20version="'$version'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') if [ -z "$label_id" ]; then - label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":1, "driver":"vmx", + label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":'$version', "driver":"vmx", "definition": { - "image": "macos-1015-ci-xcode122", + "image": "macos1015-ci-xcode122", "images": { - "macos-1015": "https://artifact-storage/aquarium/image/macos-1015-VERSION/macos-1015-VERSION.tar.xz", - "macos-1015-ci": "https://artifact-storage/aquarium/image/macos-1015-ci-VERSION/macos-1015-ci-VERSION.tar.xz", - "macos-1015-ci-xcode122": "https://artifact-storage/aquarium/image/macos-1015-ci-xcode122-VERSION/macos-1015-ci-xcode122-VERSION.tar.xz" + "macos1015": "https://artifact-storage/aquarium/image/macos1015-VERSION/macos1015-VERSION.tar.xz", + "macos1015-ci": "https://artifact-storage/aquarium/image/macos1015-ci-VERSION/macos1015-ci-VERSION.tar.xz", + "macos1015-ci-xcode122": "https://artifact-storage/aquarium/image/macos1015-ci-xcode122-VERSION/macos1015-ci-xcode122-VERSION.tar.xz" }, "requirements": { "cpu": 14, diff --git a/test/test-ci.sh b/test/run-macos1015-ci.sh similarity index 78% rename from test/test-ci.sh rename to test/run-macos1015-ci.sh index 914f289..a4b6a61 100755 --- a/test/test-ci.sh +++ b/test/run-macos1015-ci.sh @@ -4,18 +4,19 @@ token=$1 [ "$token" ] || exit 1 label=ci +version=1 echo "Get or create the label" -label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"%20AND%20version="'$version'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') if [ -z "$label_id" ]; then - label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":1, "driver":"vmx", + label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":'$version', "driver":"vmx", "definition": { - "image": "macos-1015-ci", + "image": "macos1015-ci", "images": { - "macos-1015": "https://artifact-storage/aquarium/image/macos-1015-VERSION/macos-1015-VERSION.tar.xz", - "macos-1015-ci": "https://artifact-storage/aquarium/image/macos-1015-ci-VERSION/macos-1015-ci-VERSION.tar.xz" + "macos1015": "https://artifact-storage/aquarium/image/macos1015-VERSION/macos1015-VERSION.tar.xz", + "macos1015-ci": "https://artifact-storage/aquarium/image/macos1015-ci-VERSION/macos1015-ci-VERSION.tar.xz" }, "requirements": { "cpu": 14, diff --git a/test/run-macos1106-ci-xcode131.sh b/test/run-macos1106-ci-xcode131.sh new file mode 100755 index 0000000..c5d5c47 --- /dev/null +++ b/test/run-macos1106-ci-xcode131.sh @@ -0,0 +1,64 @@ +#!/bin/sh -e + +token=$1 +[ "$token" ] || exit 1 + +label=xcode13.1 +version=1 + +echo "Get or create the label" + +label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"%20AND%20version="'$version'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') + +if [ -z "$label_id" ]; then + label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":'$version', "driver":"vmx", + "definition": { + "image": "macos1106-ci-xcode131", + "images": { + "macos1106": "https://artifact-storage/aquarium/image/macos1106-VERSION/macos1106-VERSION.tar.xz", + "macos1106-ci": "https://artifact-storage/aquarium/image/macos1106-ci-VERSION/macos1106-ci-VERSION.tar.xz", + "macos1106-ci-xcode131": "https://artifact-storage/aquarium/image/macos1106-ci-xcode131-VERSION/macos1106-ci-xcode131-VERSION.tar.xz" + }, + "requirements": { + "cpu": 14, + "ram": 12, + "disks": { + "xcode131": { + "type": "hfs+", + "size": 100, + "reuse": true + } + } + } + }, + "metadata": { + "JENKINS_AGENT_WORKSPACE": "/Volumes/xcode131" + } + }' https://127.0.0.1:8001/api/v1/label/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +fi +echo "Label ID: ${label_id}" + +echo "Press key to get label" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/label/${label_id} + +echo "Press key to run application" +read w1 + +app_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"label_ID":'$label_id', "metadata":{ + "JENKINS_URL": "http://172.16.1.1:8085/", + "JENKINS_AGENT_SECRET": "03839eabcf945b1e780be8f9488d264c4c57bf388546da9a84588345555f29b0", + "JENKINS_AGENT_NAME": "test-node" +}}' https://127.0.0.1:8001/api/v1/application/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +echo "Application ID: ${app_id}" + +echo "Press key to check the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/resource + +echo "Press key to deallocate the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/deallocate diff --git a/test/run-winserver2019-ci-vs2019.sh b/test/run-winserver2019-ci-vs2019.sh new file mode 100755 index 0000000..7234330 --- /dev/null +++ b/test/run-winserver2019-ci-vs2019.sh @@ -0,0 +1,64 @@ +#!/bin/sh -e + +token=$1 +[ "$token" ] || exit 1 + +label=vs2019 +version=3 + +echo "Get or create the label" + +label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"%20AND%20version="'$version'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') + +if [ -z "$label_id" ]; then + label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":'$version', "driver":"vmx", + "definition": { + "image": "winserver2019-ci-vs2019", + "images": { + "winserver2019": "https://artifact-storage/aquarium/image/winserver2019-VERSION/winserver2019-VERSION.tar.xz", + "winserver2019-ci": "https://artifact-storage/aquarium/image/winserver2019-ci-VERSION/winserver2019-ci-VERSION.tar.xz", + "winserver2019-ci-vs2019": "https://artifact-storage/aquarium/image/winserver2019-ci-vs2019-VERSION/winserver2019-ci-vs2019-VERSION.tar.xz" + }, + "requirements": { + "cpu": 14, + "ram": 12, + "disks": { + "vs2019": { + "type": "exfat", + "size": 100, + "reuse": true + } + } + } + }, + "metadata": { + "JENKINS_AGENT_WORKSPACE": "D:\\" + } + }' https://127.0.0.1:8001/api/v1/label/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +fi +echo "Label ID: ${label_id}" + +echo "Press key to get label" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/label/${label_id} + +echo "Press key to run application" +read w1 + +app_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"label_ID":'$label_id', "metadata":{ + "JENKINS_URL": "http://172.16.1.1:8085/", + "JENKINS_AGENT_SECRET": "03839eabcf945b1e780be8f9488d264c4c57bf388546da9a84588345555f29b0", + "JENKINS_AGENT_NAME": "test-node" +}}' https://127.0.0.1:8001/api/v1/application/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +echo "Application ID: ${app_id}" + +echo "Press key to check the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/resource + +echo "Press key to deallocate the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/deallocate diff --git a/test/run-winserver2019-ci.sh b/test/run-winserver2019-ci.sh new file mode 100755 index 0000000..30f4d2e --- /dev/null +++ b/test/run-winserver2019-ci.sh @@ -0,0 +1,63 @@ +#!/bin/sh -e + +token=$1 +[ "$token" ] || exit 1 + +label=winserver2019-ci +version=1 + +echo "Get or create the label" + +label_id=$(curl -u "admin:$token" -k 'https://127.0.0.1:8001/api/v1/label/?filter=name="'$label'"%20AND%20version="'$version'"' | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') + +if [ -z "$label_id" ]; then + label_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"name":"'$label'", "version":'$version', "driver":"vmx", + "definition": { + "image": "winserver2019-ci", + "images": { + "winserver2019": "https://artifact-storage/aquarium/image/winserver2019-VERSION/winserver2019-VERSION.tar.xz", + "winserver2019-ci": "https://artifact-storage/aquarium/image/winserver2019-ci-VERSION/winserver2019-ci-VERSION.tar.xz" + }, + "requirements": { + "cpu": 14, + "ram": 12, + "disks": { + "ci": { + "type": "exfat", + "size": 100, + "reuse": true + } + } + } + }, + "metadata": { + "JENKINS_AGENT_WORKSPACE": "D:\\" + } + }' https://127.0.0.1:8001/api/v1/label/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +fi +echo "Label ID: ${label_id}" + +echo "Press key to get label" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/label/${label_id} + +echo "Press key to run application" +read w1 + +app_id=$(curl -u "admin:$token" -k -X POST -H 'Content-Type: application/json' -d '{"label_ID":'$label_id', "metadata":{ + "JENKINS_URL": "http://172.16.1.1:8085/", + "JENKINS_AGENT_SECRET": "03839eabcf945b1e780be8f9488d264c4c57bf388546da9a84588345555f29b0", + "JENKINS_AGENT_NAME": "test-node" +}}' https://127.0.0.1:8001/api/v1/application/ | grep -o '"ID": *[0-9]\+,' | tr -dc '0-9') +echo "Application ID: ${app_id}" + +echo "Press key to check the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/resource + +echo "Press key to deallocate the application resource" +read w1 + +curl -u "admin:$token" -k https://127.0.0.1:8001/api/v1/application/$app_id/deallocate