vmware / govmomi

Go library for the VMware vSphere API
Apache License 2.0
2.27k stars 897 forks source link

[BUG] vcsim does not answer govc find after deleting a resource pool which had a child resource pool #3396

Closed chrischdi closed 3 months ago

chrischdi commented 3 months ago

Describe the bug A clear and concise description of what the bug is.

To Reproduce Steps to reproduce the behavior:

  1. govc pool.create /DC0/host/DC0_C0/Resources/foo
  2. govc pool.create /DC0/host/DC0_C0/Resources/foo/bar
  3. govc find -l /DC0/host/DC0_C0/Resources
  4. govc pool.destroy /DC0/host/DC0_C0/Resources/foo
  5. govc find -l /DC0/host/DC0_C0/Resources

govc command will be stuck forever and not return or exit.

Expected behavior Find returns the list of still existing objects.

Affected version

❯ govc version
govc 0.36.2

❯ vcsim version
Build Version: 0.36.2
Build Commit: f2a87d75
Build Date: 2024-03-27T04:34:21Z

Screenshots/Debug Output If applicable, add screenshots or debug output to help explain your problem.

Additional context

This command still works after govc pool.destroy /DC0/host/DC0_C0/Resources/foo:

❯ govc ls '/DC0/host/DC0_C0/Resources/*'
/DC0/host/DC0_C0/Resources/bar

The same happens when using govc object.destroy.

It does not happen for folders.

chrischdi commented 3 months ago

Unittest which could get used in simulator/finder_test.go for reproduction:


func TestFinderDestroyedParentResourcePool(t *testing.T) {
    ctx := context.Background()

    m := VPX()
    m.Datacenter = 3
    m.Folder = 2
    m.Pool = 1

    defer m.Remove()

    err := m.Create()
    if err != nil {
        t.Fatal(err)
    }

    s := m.Service.NewServer()
    defer s.Close()

    client, err := govmomi.NewClient(ctx, s.URL, true)
    if err != nil {
        t.Fatal(err)
    }

    finder := find.NewFinder(client.Client, false)
    dc, _ := finder.Datacenter(ctx, "/F0/DC1")
    finder.SetDatacenter(dc)

    rp, err := finder.ResourcePool(ctx, "/DC0/host/DC0_C0/Resources")
    if err != nil {
        t.Fatal(err)
    }

    foo, err := rp.Create(ctx, "foo", types.DefaultResourceConfigSpec())
    if err != nil {
        t.Fatal(err)
    }

    bar, err := foo.Create(ctx, "bar", types.DefaultResourceConfigSpec())
    if err != nil {
        t.Fatal(err)
    }

    task, err := foo.Destroy(ctx)
    if err != nil {
        t.Fatal(err)
    }
    if err := task.WaitEx(ctx); err != nil {
        t.Fatal(err)
    }

    if _, err := finder.Element(ctx, bar.Reference()); err != nil {
        t.Fatal(err)
    }
}
dougm commented 3 months ago

Thank you @chrischdi for the test cases to reproduce, fix opened for review #3399