Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded / inline type aliases trigger panic #1088

Open
tsaarni opened this issue Nov 9, 2024 · 3 comments · May be fixed by #1089
Open

Embedded / inline type aliases trigger panic #1088

tsaarni opened this issue Nov 9, 2024 · 3 comments · May be fixed by #1089

Comments

@tsaarni
Copy link
Contributor

tsaarni commented Nov 9, 2024

A panic occurs when an embedded/inline field is a type alias and Alias types are enabled in Go.

To reproduce on the main branch:

  1. Apply the following example patch in controller-tools repository testdata:
diff --git a/pkg/crd/testdata/cronjob_types.go b/pkg/crd/testdata/cronjob_types.go
index e81a28ac..c6e16ab1 100644
--- a/pkg/crd/testdata/cronjob_types.go
+++ b/pkg/crd/testdata/cronjob_types.go
@@ -372,6 +372,9 @@ type CronJobSpec struct {

        // This tests that selectable field.
        SelectableFieldString string `json:"selectableFieldString,omitempty"`
+
+       // This tests that embedded struct, which is an alias type, is handled correctly.
+       InlineAlias `json:",inline"`
 }

 type StringAlias = string
@@ -380,6 +383,14 @@ type StringAlias = string
 // +kubebuilder:validation:MaxLength=255
 type StringAliasWithValidation = string

+type InlineAlias = EmbeddedStruct
+
+// EmbeddedStruct is for testing that embedded struct is handled correctly when it is used through an alias type.
+type EmbeddedStruct struct {
+       // FromEmbedded is a field from the embedded struct that was used through an alias type.
+       FromEmbedded string `json:"fromEmbedded,omitempty"`
+}
+
 type ContainsNestedMap struct {
        InnerMap map[string]string `json:"innerMap,omitempty"`
 }
  1. Make sure Alias types are enabled, then run generate
$ go version
go version go1.23.2 linux/amd64
$ cd pkg/crd/testdata
$ GODEBUG=gotypesalias=1 go generate

The output will be following

panic: interface conversion: *types.Struct is not interface { Obj() *types.TypeName }: missing method Obj

goroutine 1 [running]:
sigs.k8s.io/controller-tools/pkg/crd.localNamedToSchema(0xc0012a76e0, 0xc00057e180)
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:285 +0x3eb
sigs.k8s.io/controller-tools/pkg/crd.typeToSchema(0xc0012a76e0, {0xeb9220, 0xc00057e180})
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:206 +0xd9
sigs.k8s.io/controller-tools/pkg/crd.structToSchema(0xc004e2fe70, 0xc00068fc38)
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:463 +0x872
sigs.k8s.io/controller-tools/pkg/crd.typeToSchema(0xc004e2fe70, {0xeb91f0, 0xc00068fc38})
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:216 +0x93
sigs.k8s.io/controller-tools/pkg/crd.infoToSchema(0xc0063d3e70)
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:125 +0xc5
sigs.k8s.io/controller-tools/pkg/crd.(*Parser).NeedSchemaFor(0xc000138960, {0xc00040bbe0, {0xc000809bb0, 0xb}})
        /home/tsaarni/work/controller-tools/pkg/crd/parser.go:193 +0x290
sigs.k8s.io/controller-tools/pkg/crd.(*schemaContext).requestSchema(0xc0004616a0?, {0x0?, 0xd66e93?}, {0xc000809bb0?, 0x0?})
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:108 +0xdb
sigs.k8s.io/controller-tools/pkg/crd.localNamedToSchema(0xc006b08810, 0xc0005b5b60)
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:291 +0x4ae
sigs.k8s.io/controller-tools/pkg/crd.typeToSchema(0xc006b08810, {0xeb9220, 0xc0005b5b60})
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:206 +0xd9
sigs.k8s.io/controller-tools/pkg/crd.structToSchema(0xc004e30650, 0xc00012d140)
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:463 +0x872
sigs.k8s.io/controller-tools/pkg/crd.typeToSchema(0xc004e30650, {0xeb91f0, 0xc00012d140})
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:216 +0x93
sigs.k8s.io/controller-tools/pkg/crd.infoToSchema(0xc0063d4650)
        /home/tsaarni/work/controller-tools/pkg/crd/schema.go:125 +0xc5
sigs.k8s.io/controller-tools/pkg/crd.(*Parser).NeedSchemaFor(0xc000138960, {0xc00040bbe0, {0xc0006176c4, 0x7}})
        /home/tsaarni/work/controller-tools/pkg/crd/parser.go:193 +0x290
sigs.k8s.io/controller-tools/pkg/crd.(*Parser).NeedFlattenedSchemaFor(0xc000138960, {0xc00040bbe0, {0xc0006176c4, 0x7}})
        /home/tsaarni/work/controller-tools/pkg/crd/parser.go:205 +0xcd
sigs.k8s.io/controller-tools/pkg/crd.(*Parser).NeedCRDFor(0xc000138960, {{0xc0008077ae, 0x17}, {0xc0006176c4, 0x7}}, 0x0)
        /home/tsaarni/work/controller-tools/pkg/crd/spec.go:93 +0x57a
sigs.k8s.io/controller-tools/pkg/crd.Generator.Generate({0xc000016bd0, 0xc000016be0, 0x0, {0x0, 0x0, 0x0}, 0x0, {0x0, 0x0}, {0x0, ...}, ...}, ...)
        /home/tsaarni/work/controller-tools/pkg/crd/gen.go:182 +0x566
sigs.k8s.io/controller-tools/pkg/genall.(*Runtime).Run(0xc00033bb90)
        /home/tsaarni/work/controller-tools/pkg/genall/genall.go:272 +0x234
main.main.func1(0xc00048e300?, {0xc0002fbcb0?, 0x4?, 0xd64fa0?})
        /home/tsaarni/work/controller-tools/cmd/controller-gen/main.go:176 +0x6a
github.com/spf13/cobra.(*Command).execute(0xc0002d4c08, {0xc000136090, 0x3, 0x3})
        /home/tsaarni/go/pkg/mod/github.com/spf13/[email protected]/command.go:985 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0xc0002d4c08)
        /home/tsaarni/go/pkg/mod/github.com/spf13/[email protected]/command.go:1117 +0x3ff
github.com/spf13/cobra.(*Command).Execute(...)
        /home/tsaarni/go/pkg/mod/github.com/spf13/[email protected]/command.go:1041
main.main()
        /home/tsaarni/work/controller-tools/cmd/controller-gen/main.go:200 +0x2f6
exit status 2
cronjob_types.go:19: running "../../../.run-controller-gen.sh": exit status 1

When running GODEBUG=gotypesalias=0 go generate or just go generate there will not be panic. I assume this is because of Go language level in go.mod.

FYI: Interestingly, I found the issue while running controller-gen in another project using go run sigs.k8s.io/controller-tools/cmd/controller-gen ... with go1.23.x. However, using go run sigs.k8s.io/controller-tools/cmd/[email protected] ... avoids the panic. We have pinned controller-tools v0.16.5 in the project's go.mod but it makes difference if the go run command has the version or not. When running go run -x, I noticed that gotypesalias=0 is set when specifying @v0.16.5, whereas without it, no flag is set, and compiler enables Alias types by default, presumably because project's language level in go.mod got set to Go 1.23 as a side effect after bumping some dependencies.

@tsaarni
Copy link
Contributor Author

tsaarni commented Nov 9, 2024

I was trying to understand what was happening and managed to work around the error #1089. However, this is not the correct approach...

@sbueringer
Copy link
Member

cc @mtardy (Just fyi)

@mtardy
Copy link
Contributor

mtardy commented Nov 10, 2024

cc @mtardy (Just fyi)

Thanks for the note, I'll take a look next week :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants