diff --git a/go.mod b/go.mod index bd6f11e6c..421e6f47a 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,15 @@ module github.com/knative/client require ( - contrib.go.opencensus.io/exporter/stackdriver v0.11.0 // indirect github.com/cpuguy83/go-md2man v1.0.10 // indirect - github.com/evanphx/json-patch v4.1.0+incompatible // indirect + github.com/evanphx/json-patch v4.2.0+incompatible // indirect + github.com/ghodss/yaml v1.0.0 // indirect github.com/gogo/protobuf v1.2.1 // indirect - github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/golang/protobuf v1.3.1 // indirect github.com/google/btree v1.0.0 // indirect - github.com/google/go-containerregistry v0.0.0-20190424210018-7d6d1d3cd63b // indirect + github.com/google/go-cmp v0.3.0 // indirect + github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5 // indirect github.com/google/gofuzz v1.0.0 // indirect github.com/googleapis/gnostic v0.2.0 // indirect github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect @@ -15,29 +17,25 @@ require ( github.com/imdario/mergo v0.3.7 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/json-iterator/go v1.1.6 // indirect - github.com/knative/build v0.5.0 // indirect - github.com/knative/pkg v0.0.0-20190329155329-916205998db9 - github.com/knative/serving v0.5.2 + github.com/knative/build v0.6.0 // indirect + github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2 + github.com/knative/serving v0.6.0 github.com/knative/test-infra v0.0.0-20190517181617-d1bb39bbca6e github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/modern-go/reflect2 v1.0.1 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/pkg/errors v0.8.1 // indirect github.com/spf13/cobra v0.0.3 github.com/spf13/pflag v1.0.3 github.com/spf13/viper v1.3.1 - go.uber.org/atomic v1.3.2 // indirect - go.uber.org/multierr v1.1.0 // indirect - go.uber.org/zap v1.9.1 // indirect - golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 // indirect - golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a // indirect + golang.org/x/net v0.0.0-20190514140710-3ec191127204 // indirect + golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 // indirect golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/api v0.0.0-20190226173710-145d52631d00 k8s.io/apimachinery v0.0.0-20190221084156-01f179d85dbc k8s.io/cli-runtime v0.0.0-20190226180714-082c0831af2b k8s.io/client-go v0.0.0-20190226174127-78295b709ec6 - k8s.io/kube-openapi v0.0.0-20190418160015-6b3d3b2d5666 // indirect + k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 // indirect sigs.k8s.io/yaml v1.1.0 ) diff --git a/go.sum b/go.sum index d3619b3ae..2cb890807 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,8 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/evanphx/json-patch v4.1.0+incompatible h1:K1MDoo4AZ4wU0GIU/fPmtZg7VpzLjCxu+UwBD1FvwOc= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= @@ -84,8 +86,12 @@ github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-containerregistry v0.0.0-20190424210018-7d6d1d3cd63b h1:3KvxrcCoYX4wIZoeCMFfBPD840fopFkyjQeZDv5B+T8= github.com/google/go-containerregistry v0.0.0-20190424210018-7d6d1d3cd63b/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk= +github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5 h1:wXZCVr9/0naJbZhAzKDzj/sgnduf8qn9ldjkI/CND9k= +github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -125,10 +131,16 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/knative/build v0.5.0 h1:q2W4+BmT3jEOSOXZ44UXndJUAHLWUd20QtMQAFGWzsU= github.com/knative/build v0.5.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/build v0.6.0 h1:tAhqGbRL3/wFOfEc4srO8XDNV8DxUE+z6TzKW0JPWsE= +github.com/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= github.com/knative/pkg v0.0.0-20190329155329-916205998db9 h1:DnGe2nwEq+ibifGZt4HoD4akmX1K9Tcx3CjNwFpSZow= github.com/knative/pkg v0.0.0-20190329155329-916205998db9/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2 h1:OA4f02os85BMZbC6DxNL5gbGHRxPgjQW+IDENES7QFc= +github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= github.com/knative/serving v0.5.2 h1:jsmeIN7B6oDHrK0jmtFRf7hWWr+KrjXVHuArK8jo5Nw= github.com/knative/serving v0.5.2/go.mod h1:ljvMfwQy2qanaM/8xnBSK4Mz3Vv2NawC2fo5kFRJS1A= +github.com/knative/serving v0.6.0 h1:2SOr1jAvrUPO1y0mJvpiTe3bJTSMd2tKXflmHCM0MAA= +github.com/knative/serving v0.6.0/go.mod h1:ljvMfwQy2qanaM/8xnBSK4Mz3Vv2NawC2fo5kFRJS1A= github.com/knative/test-infra v0.0.0-20190404172656-4ce16d390c55 h1:2tpTEN6OydMWVmkKJC3iVNrYbA+iHNL9qjLXe7hocfE= github.com/knative/test-infra v0.0.0-20190404172656-4ce16d390c55/go.mod h1:l77IWBscEV5T4sYb64/9iwRCVY4UXEIqMcAppsblHW4= github.com/knative/test-infra v0.0.0-20190509163238-a721698dbe49 h1:TEv7xkUjVofC2lqiSNeYjOYhC3XosGAfr0HG8x/lpC0= @@ -254,11 +266,15 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 h1:FP8hkuE6yUEaJnK7O2eTuejKWwW+Rhfj80dQ2JcKxCU= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190514140710-3ec191127204 h1:4yG6GqBtw9C+UrLp6s2wtSniayy/Vd/3F7ffLE427XI= +golang.org/x/net v0.0.0-20190514140710-3ec191127204/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 h1:XC1K3wNjuz44KaI+cj85C9TW85w/46RH7J+DTXNH5Wk= +golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 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= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= @@ -336,6 +352,9 @@ k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/kube-openapi v0.0.0-20190418160015-6b3d3b2d5666 h1:hlzz2EvLPcefAcG/j0tOZpds4LWSElZzxpZuhxbblbc= k8s.io/kube-openapi v0.0.0-20190418160015-6b3d3b2d5666/go.mod h1:jqYp7BKXW0Jl+F1dWXBieUmcHKMPpGHGWA0uqfpOZZ4= +k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 h1:f0BTap/vrgs21vVbJ1ySdsNtcivpA1x4ut6Wla9HKKw= +k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= sigs.k8s.io/structured-merge-diff v0.0.0-20181214233322-d43a45b8663b/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/pkg/kn/commands/revision_describe_test.go b/pkg/kn/commands/revision_describe_test.go index e5fe48697..14aa9708d 100644 --- a/pkg/kn/commands/revision_describe_test.go +++ b/pkg/kn/commands/revision_describe_test.go @@ -66,7 +66,7 @@ func TestDescribeRevisionYaml(t *testing.T) { Namespace: "default", }, Spec: v1alpha1.RevisionSpec{ - Container: corev1.Container{ + DeprecatedContainer: &corev1.Container{ Name: "some-container", Image: "knative/test:latest", }, diff --git a/pkg/kn/commands/service_create.go b/pkg/kn/commands/service_create.go index bda6eaa33..50a81bb39 100644 --- a/pkg/kn/commands/service_create.go +++ b/pkg/kn/commands/service_create.go @@ -21,6 +21,7 @@ import ( serving_lib "github.com/knative/client/pkg/serving" servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -69,7 +70,16 @@ func NewServiceCreateCommand(p *KnParams) *cobra.Command { Namespace: namespace, }, } - service.Spec.RunLatest = &servingv1alpha1.RunLatestType{} + + service.Spec.DeprecatedRunLatest = &servingv1alpha1.RunLatestType{ + Configuration: servingv1alpha1.ConfigurationSpec{ + DeprecatedRevisionTemplate: &servingv1alpha1.RevisionTemplateSpec{ + Spec: servingv1alpha1.RevisionSpec{ + DeprecatedContainer: &corev1.Container{}, + }, + }, + }, + } config, err := serving_lib.GetConfiguration(&service) if err != nil { diff --git a/pkg/kn/commands/service_create_test.go b/pkg/kn/commands/service_create_test.go index 4cca9b59a..c08e1a7ac 100644 --- a/pkg/kn/commands/service_create_test.go +++ b/pkg/kn/commands/service_create_test.go @@ -77,8 +77,8 @@ func TestServiceCreateImage(t *testing.T) { conf, err := servinglib.GetConfiguration(created) if err != nil { t.Fatal(err) - } else if conf.RevisionTemplate.Spec.Container.Image != "gcr.io/foo/bar:baz" { - t.Fatalf("wrong image set: %v", conf.RevisionTemplate.Spec.Container.Image) + } else if conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image != "gcr.io/foo/bar:baz" { + t.Fatalf("wrong image set: %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image) } else if !strings.Contains(output, "foo") || !strings.Contains(output, "created") || !strings.Contains(output, "default") { t.Fatalf("wrong stdout message: %v", output) @@ -100,19 +100,19 @@ func TestServiceCreateEnv(t *testing.T) { "B": "WOLVES"} conf, err := servinglib.GetConfiguration(created) - actualEnvVars, err := servinglib.EnvToMap(conf.RevisionTemplate.Spec.Container.Env) + actualEnvVars, err := servinglib.EnvToMap(conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) if err != nil { t.Fatal(err) } if err != nil { t.Fatal(err) - } else if conf.RevisionTemplate.Spec.Container.Image != "gcr.io/foo/bar:baz" { - t.Fatalf("wrong image set: %v", conf.RevisionTemplate.Spec.Container.Image) + } else if conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image != "gcr.io/foo/bar:baz" { + t.Fatalf("wrong image set: %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image) } else if !reflect.DeepEqual( actualEnvVars, expectedEnvVars) { - t.Fatalf("wrong env vars %v", conf.RevisionTemplate.Spec.Container.Env) + t.Fatalf("wrong env vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) } } @@ -136,9 +136,9 @@ func TestServiceCreateWithRequests(t *testing.T) { if err != nil { t.Fatal(err) } else if !reflect.DeepEqual( - conf.RevisionTemplate.Spec.Container.Resources.Requests, + conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests, expectedRequestsVars) { - t.Fatalf("wrong requests vars %v", conf.RevisionTemplate.Spec.Container.Resources.Requests) + t.Fatalf("wrong requests vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests) } } @@ -162,9 +162,9 @@ func TestServiceCreateWithLimits(t *testing.T) { if err != nil { t.Fatal(err) } else if !reflect.DeepEqual( - conf.RevisionTemplate.Spec.Container.Resources.Limits, + conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits, expectedLimitsVars) { - t.Fatalf("wrong limits vars %v", conf.RevisionTemplate.Spec.Container.Resources.Limits) + t.Fatalf("wrong limits vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits) } } @@ -192,15 +192,15 @@ func TestServiceCreateRequestsLimitsCPU(t *testing.T) { t.Fatal(err) } else { if !reflect.DeepEqual( - conf.RevisionTemplate.Spec.Container.Resources.Requests, + conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests, expectedRequestsVars) { - t.Fatalf("wrong requests vars %v", conf.RevisionTemplate.Spec.Container.Resources.Requests) + t.Fatalf("wrong requests vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests) } if !reflect.DeepEqual( - conf.RevisionTemplate.Spec.Container.Resources.Limits, + conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits, expectedLimitsVars) { - t.Fatalf("wrong limits vars %v", conf.RevisionTemplate.Spec.Container.Resources.Limits) + t.Fatalf("wrong limits vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits) } } } @@ -229,15 +229,15 @@ func TestServiceCreateRequestsLimitsMemory(t *testing.T) { t.Fatal(err) } else { if !reflect.DeepEqual( - conf.RevisionTemplate.Spec.Container.Resources.Requests, + conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests, expectedRequestsVars) { - t.Fatalf("wrong requests vars %v", conf.RevisionTemplate.Spec.Container.Resources.Requests) + t.Fatalf("wrong requests vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests) } if !reflect.DeepEqual( - conf.RevisionTemplate.Spec.Container.Resources.Limits, + conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits, expectedLimitsVars) { - t.Fatalf("wrong limits vars %v", conf.RevisionTemplate.Spec.Container.Resources.Limits) + t.Fatalf("wrong limits vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits) } } } @@ -270,15 +270,15 @@ func TestServiceCreateRequestsLimitsCPUMemory(t *testing.T) { t.Fatal(err) } else { if !reflect.DeepEqual( - conf.RevisionTemplate.Spec.Container.Resources.Requests, + conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests, expectedRequestsVars) { - t.Fatalf("wrong requests vars %v", conf.RevisionTemplate.Spec.Container.Resources.Requests) + t.Fatalf("wrong requests vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests) } if !reflect.DeepEqual( - conf.RevisionTemplate.Spec.Container.Resources.Limits, + conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits, expectedLimitsVars) { - t.Fatalf("wrong limits vars %v", conf.RevisionTemplate.Spec.Container.Resources.Limits) + t.Fatalf("wrong limits vars %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits) } } } @@ -307,8 +307,8 @@ func TestServiceCreateImageForce(t *testing.T) { conf, err := servinglib.GetConfiguration(created) if err != nil { t.Fatal(err) - } else if conf.RevisionTemplate.Spec.Container.Image != "gcr.io/foo/bar:v2" { - t.Fatalf("wrong image set: %v", conf.RevisionTemplate.Spec.Container.Image) + } else if conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image != "gcr.io/foo/bar:v2" { + t.Fatalf("wrong image set: %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image) } else if !strings.Contains(output, "foo") || !strings.Contains(output, "default") { t.Fatalf("wrong output: %s", output) } @@ -334,18 +334,18 @@ func TestServiceCreateEnvForce(t *testing.T) { "B": "LIONS"} conf, err := servinglib.GetConfiguration(created) - actualEnvVars, err := servinglib.EnvToMap(conf.RevisionTemplate.Spec.Container.Env) + actualEnvVars, err := servinglib.EnvToMap(conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) if err != nil { t.Fatal(err) } if err != nil { t.Fatal(err) - } else if conf.RevisionTemplate.Spec.Container.Image != "gcr.io/foo/bar:v2" { - t.Fatalf("wrong image set: %v", conf.RevisionTemplate.Spec.Container.Image) + } else if conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image != "gcr.io/foo/bar:v2" { + t.Fatalf("wrong image set: %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image) } else if !reflect.DeepEqual( actualEnvVars, expectedEnvVars) { - t.Fatalf("wrong env vars:%v", conf.RevisionTemplate.Spec.Container.Env) + t.Fatalf("wrong env vars:%v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) } else if !strings.Contains(output, "foo") || !strings.Contains(output, "default") { t.Fatalf("wrong output: %s", output) } diff --git a/pkg/kn/commands/service_get_flags.go b/pkg/kn/commands/service_get_flags.go index 2bfe67aed..40980e388 100644 --- a/pkg/kn/commands/service_get_flags.go +++ b/pkg/kn/commands/service_get_flags.go @@ -17,7 +17,8 @@ package commands import ( "fmt" hprinters "github.com/knative/client/pkg/printers" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -95,7 +96,7 @@ func ServiceGetHandlers(h hprinters.PrintHandler) { } // conditionsValue returns the True conditions count among total conditions -func conditionsValue(conditions duckv1alpha1.Conditions) string { +func conditionsValue(conditions duckv1beta1.Conditions) string { var ok int for _, condition := range conditions { if condition.Status == "True" { @@ -106,18 +107,18 @@ func conditionsValue(conditions duckv1alpha1.Conditions) string { } // readyCondition returns status of resource's Ready type condition -func readyCondition(conditions duckv1alpha1.Conditions) string { +func readyCondition(conditions duckv1beta1.Conditions) string { for _, condition := range conditions { - if condition.Type == duckv1alpha1.ConditionReady { + if condition.Type == apis.ConditionReady { return string(condition.Status) } } return "" } -func nonReadyConditionReason(conditions duckv1alpha1.Conditions) string { +func nonReadyConditionReason(conditions duckv1beta1.Conditions) string { for _, condition := range conditions { - if condition.Type == duckv1alpha1.ConditionReady { + if condition.Type == apis.ConditionReady { if string(condition.Status) == "True" { return "" } @@ -155,7 +156,7 @@ func printKServiceList(kServiceList *servingv1alpha1.ServiceList, options hprint // printKService populates the knative service table rows func printKService(kService *servingv1alpha1.Service, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) { name := kService.Name - domain := kService.Status.Domain + domain := kService.Status.RouteStatusFields.DeprecatedDomain //lastCreatedRevision := kService.Status.LatestCreatedRevisionName //lastReadyRevision := kService.Status.LatestReadyRevisionName generation := kService.Status.ObservedGeneration diff --git a/pkg/kn/commands/service_get_test.go b/pkg/kn/commands/service_get_test.go index ace3210a1..17ec61e8c 100644 --- a/pkg/kn/commands/service_get_test.go +++ b/pkg/kn/commands/service_get_test.go @@ -19,7 +19,7 @@ import ( "strings" "testing" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" v1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" servingclient "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake" @@ -101,13 +101,13 @@ func createMockServiceWithParams(name, domain string, generation int64) *v1alpha Namespace: "default", }, Spec: v1alpha1.ServiceSpec{ - RunLatest: &v1alpha1.RunLatestType{}, + DeprecatedRunLatest: &v1alpha1.RunLatestType{}, }, Status: v1alpha1.ServiceStatus{ - Status: duckv1alpha1.Status{ + Status: duckv1beta1.Status{ ObservedGeneration: generation}, RouteStatusFields: v1alpha1.RouteStatusFields{ - Domain: domain, + DeprecatedDomain: domain, }, }, } diff --git a/pkg/kn/commands/service_update_test.go b/pkg/kn/commands/service_update_test.go index c064ebb7c..6e3869fc0 100644 --- a/pkg/kn/commands/service_update_test.go +++ b/pkg/kn/commands/service_update_test.go @@ -81,7 +81,15 @@ func TestServiceUpdateImage(t *testing.T) { Namespace: "default", }, Spec: v1alpha1.ServiceSpec{ - RunLatest: &v1alpha1.RunLatestType{}, + DeprecatedRunLatest: &v1alpha1.RunLatestType{ + Configuration: v1alpha1.ConfigurationSpec{ + DeprecatedRevisionTemplate: &v1alpha1.RevisionTemplateSpec{ + Spec: v1alpha1.RevisionSpec{ + DeprecatedContainer: &corev1.Container{}, + }, + }, + }, + }, }, } @@ -103,8 +111,8 @@ func TestServiceUpdateImage(t *testing.T) { conf, err := servinglib.GetConfiguration(updated) if err != nil { t.Fatal(err) - } else if conf.RevisionTemplate.Spec.Container.Image != "gcr.io/foo/quux:xyzzy" { - t.Fatalf("wrong image set: %v", conf.RevisionTemplate.Spec.Container.Image) + } else if conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image != "gcr.io/foo/quux:xyzzy" { + t.Fatalf("wrong image set: %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image) } } @@ -119,7 +127,15 @@ func TestServiceUpdateEnv(t *testing.T) { Namespace: "default", }, Spec: v1alpha1.ServiceSpec{ - RunLatest: &v1alpha1.RunLatestType{}, + DeprecatedRunLatest: &v1alpha1.RunLatestType{ + Configuration: v1alpha1.ConfigurationSpec{ + DeprecatedRevisionTemplate: &v1alpha1.RevisionTemplateSpec{ + Spec: v1alpha1.RevisionSpec{ + DeprecatedContainer: &corev1.Container{}, + }, + }, + }, + }, }, } @@ -146,10 +162,10 @@ func TestServiceUpdateEnv(t *testing.T) { conf, err := servinglib.GetConfiguration(updated) if err != nil { t.Fatal(err) - } else if conf.RevisionTemplate.Spec.Container.Image != "gcr.io/foo/bar:baz" { - t.Fatalf("wrong image set: %v", conf.RevisionTemplate.Spec.Container.Image) - } else if conf.RevisionTemplate.Spec.Container.Env[0] != expectedEnvVar { - t.Fatalf("wrong env set: %v", conf.RevisionTemplate.Spec.Container.Env) + } else if conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image != "gcr.io/foo/bar:baz" { + t.Fatalf("wrong image set: %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image) + } else if conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env[0] != expectedEnvVar { + t.Fatalf("wrong env set: %v", conf.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) } } @@ -178,15 +194,15 @@ func TestServiceUpdateRequestsLimitsCPU(t *testing.T) { t.Fatal(err) } else { if !reflect.DeepEqual( - newConfig.RevisionTemplate.Spec.Container.Resources.Requests, + newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests, expectedRequestsVars) { - t.Fatalf("wrong requests vars %v", newConfig.RevisionTemplate.Spec.Container.Resources.Requests) + t.Fatalf("wrong requests vars %v", newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests) } if !reflect.DeepEqual( - newConfig.RevisionTemplate.Spec.Container.Resources.Limits, + newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits, expectedLimitsVars) { - t.Fatalf("wrong limits vars %v", newConfig.RevisionTemplate.Spec.Container.Resources.Limits) + t.Fatalf("wrong limits vars %v", newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits) } } } @@ -216,15 +232,15 @@ func TestServiceUpdateRequestsLimitsMemory(t *testing.T) { t.Fatal(err) } else { if !reflect.DeepEqual( - newConfig.RevisionTemplate.Spec.Container.Resources.Requests, + newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests, expectedRequestsVars) { - t.Fatalf("wrong requests vars %v", newConfig.RevisionTemplate.Spec.Container.Resources.Requests) + t.Fatalf("wrong requests vars %v", newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests) } if !reflect.DeepEqual( - newConfig.RevisionTemplate.Spec.Container.Resources.Limits, + newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits, expectedLimitsVars) { - t.Fatalf("wrong limits vars %v", newConfig.RevisionTemplate.Spec.Container.Resources.Limits) + t.Fatalf("wrong limits vars %v", newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits) } } } @@ -256,15 +272,15 @@ func TestServiceUpdateRequestsLimitsCPU_and_Memory(t *testing.T) { t.Fatal(err) } else { if !reflect.DeepEqual( - newConfig.RevisionTemplate.Spec.Container.Resources.Requests, + newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests, expectedRequestsVars) { - t.Fatalf("wrong requests vars %v", newConfig.RevisionTemplate.Spec.Container.Resources.Requests) + t.Fatalf("wrong requests vars %v", newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests) } if !reflect.DeepEqual( - newConfig.RevisionTemplate.Spec.Container.Resources.Limits, + newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits, expectedLimitsVars) { - t.Fatalf("wrong limits vars %v", newConfig.RevisionTemplate.Spec.Container.Resources.Limits) + t.Fatalf("wrong limits vars %v", newConfig.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits) } } } @@ -280,7 +296,15 @@ func createMockServiceWithResources(t *testing.T, requestCPU, requestMemory, lim Namespace: "default", }, Spec: v1alpha1.ServiceSpec{ - RunLatest: &v1alpha1.RunLatestType{}, + DeprecatedRunLatest: &v1alpha1.RunLatestType{ + Configuration: v1alpha1.ConfigurationSpec{ + DeprecatedRevisionTemplate: &v1alpha1.RevisionTemplateSpec{ + Spec: v1alpha1.RevisionSpec{ + DeprecatedContainer: &corev1.Container{}, + }, + }, + }, + }, }, } @@ -289,7 +313,7 @@ func createMockServiceWithResources(t *testing.T, requestCPU, requestMemory, lim t.Fatal(err) } - config.RevisionTemplate.Spec.Container.Resources = corev1.ResourceRequirements{ + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources = corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse(requestCPU), corev1.ResourceMemory: resource.MustParse(requestMemory), diff --git a/pkg/serving/config_changes.go b/pkg/serving/config_changes.go index 3c33f907b..56430cc79 100644 --- a/pkg/serving/config_changes.go +++ b/pkg/serving/config_changes.go @@ -26,8 +26,8 @@ import ( // new env vars and change the values of existing ones. func UpdateEnvVars(config *servingv1alpha1.ConfigurationSpec, vars map[string]string) error { set := make(map[string]bool) - for i, _ := range config.RevisionTemplate.Spec.Container.Env { - envVar := &config.RevisionTemplate.Spec.Container.Env[i] + for i, _ := range config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env { + envVar := &config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env[i] value, present := vars[envVar.Name] if present { envVar.Value = value @@ -36,8 +36,8 @@ func UpdateEnvVars(config *servingv1alpha1.ConfigurationSpec, vars map[string]st } for name, value := range vars { if !set[name] { - config.RevisionTemplate.Spec.Container.Env = append( - config.RevisionTemplate.Spec.Container.Env, + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env = append( + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env, corev1.EnvVar{ Name: name, Value: value, @@ -63,25 +63,25 @@ func EnvToMap(vars []corev1.EnvVar) (map[string]string, error) { } func UpdateImage(config *servingv1alpha1.ConfigurationSpec, image string) error { - config.RevisionTemplate.Spec.Container.Image = image + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Image = image return nil } func UpdateResources(config *servingv1alpha1.ConfigurationSpec, requestsResourceList corev1.ResourceList, limitsResourceList corev1.ResourceList) error { - if config.RevisionTemplate.Spec.Container.Resources.Requests == nil { - config.RevisionTemplate.Spec.Container.Resources.Requests = corev1.ResourceList{} + if config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests == nil { + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests = corev1.ResourceList{} } for k, v := range requestsResourceList { - config.RevisionTemplate.Spec.Container.Resources.Requests[k] = v + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Requests[k] = v } - if config.RevisionTemplate.Spec.Container.Resources.Limits == nil { - config.RevisionTemplate.Spec.Container.Resources.Limits = corev1.ResourceList{} + if config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits == nil { + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits = corev1.ResourceList{} } for k, v := range limitsResourceList { - config.RevisionTemplate.Spec.Container.Resources.Limits[k] = v + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Resources.Limits[k] = v } return nil diff --git a/pkg/serving/config_changes_test.go b/pkg/serving/config_changes_test.go index 6622d339a..d4dbe2d0b 100644 --- a/pkg/serving/config_changes_test.go +++ b/pkg/serving/config_changes_test.go @@ -23,7 +23,7 @@ import ( ) func TestUpdateEnvVarsNew(t *testing.T) { - config := servingv1alpha1.ConfigurationSpec{} + config := getEmptyConfigurationSpec() env := map[string]string{ "a": "foo", "b": "bar", @@ -32,7 +32,7 @@ func TestUpdateEnvVarsNew(t *testing.T) { if err != nil { t.Fatal(err) } - found, err := EnvToMap(config.RevisionTemplate.Spec.Container.Env) + found, err := EnvToMap(config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) if err != nil { t.Fatal(err) } @@ -42,8 +42,8 @@ func TestUpdateEnvVarsNew(t *testing.T) { } func TestUpdateEnvVarsAppend(t *testing.T) { - config := servingv1alpha1.ConfigurationSpec{} - config.RevisionTemplate.Spec.Container.Env = []corev1.EnvVar{ + config := getEmptyConfigurationSpec() + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env = []corev1.EnvVar{ corev1.EnvVar{Name: "a", Value: "foo"}} env := map[string]string{ "b": "bar", @@ -58,7 +58,7 @@ func TestUpdateEnvVarsAppend(t *testing.T) { "b": "bar", } - found, err := EnvToMap(config.RevisionTemplate.Spec.Container.Env) + found, err := EnvToMap(config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) if err != nil { t.Fatal(err) } @@ -68,8 +68,8 @@ func TestUpdateEnvVarsAppend(t *testing.T) { } func TestUpdateEnvVarsModify(t *testing.T) { - config := servingv1alpha1.ConfigurationSpec{} - config.RevisionTemplate.Spec.Container.Env = []corev1.EnvVar{ + config := getEmptyConfigurationSpec() + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env = []corev1.EnvVar{ corev1.EnvVar{Name: "a", Value: "foo"}} env := map[string]string{ "a": "fancy", @@ -83,7 +83,7 @@ func TestUpdateEnvVarsModify(t *testing.T) { "a": "fancy", } - found, err := EnvToMap(config.RevisionTemplate.Spec.Container.Env) + found, err := EnvToMap(config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) if err != nil { t.Fatal(err) } @@ -93,8 +93,8 @@ func TestUpdateEnvVarsModify(t *testing.T) { } func TestUpdateEnvVarsBoth(t *testing.T) { - config := servingv1alpha1.ConfigurationSpec{} - config.RevisionTemplate.Spec.Container.Env = []corev1.EnvVar{ + config := getEmptyConfigurationSpec() + config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env = []corev1.EnvVar{ corev1.EnvVar{Name: "a", Value: "foo"}, corev1.EnvVar{Name: "c", Value: "caroline"}} env := map[string]string{ @@ -112,7 +112,7 @@ func TestUpdateEnvVarsBoth(t *testing.T) { "c": "caroline", } - found, err := EnvToMap(config.RevisionTemplate.Spec.Container.Env) + found, err := EnvToMap(config.DeprecatedRevisionTemplate.Spec.DeprecatedContainer.Env) if err != nil { t.Fatal(err) } @@ -120,3 +120,13 @@ func TestUpdateEnvVarsBoth(t *testing.T) { t.Fatalf("Env did not match expected %v found %v", env, found) } } + +func getEmptyConfigurationSpec() servingv1alpha1.ConfigurationSpec { + return servingv1alpha1.ConfigurationSpec{ + DeprecatedRevisionTemplate: &servingv1alpha1.RevisionTemplateSpec{ + Spec: servingv1alpha1.RevisionSpec{ + DeprecatedContainer: &corev1.Container{}, + }, + }, + } +} diff --git a/pkg/serving/service.go b/pkg/serving/service.go index 8238ec15e..f146956a7 100644 --- a/pkg/serving/service.go +++ b/pkg/serving/service.go @@ -21,10 +21,10 @@ import ( ) func GetConfiguration(service *servingv1alpha1.Service) (*servingv1alpha1.ConfigurationSpec, error) { - if service.Spec.RunLatest != nil { - return &service.Spec.RunLatest.Configuration, nil - } else if service.Spec.Release != nil { - return &service.Spec.Release.Configuration, nil + if service.Spec.DeprecatedRunLatest != nil { + return &service.Spec.DeprecatedRunLatest.Configuration, nil + } else if service.Spec.DeprecatedRelease != nil { + return &service.Spec.DeprecatedRelease.Configuration, nil } else if service.Spec.DeprecatedPinned != nil { return &service.Spec.DeprecatedPinned.Configuration, nil } else { diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go index 125b7033c..0d929a619 100644 --- a/vendor/cloud.google.com/go/compute/metadata/metadata.go +++ b/vendor/cloud.google.com/go/compute/metadata/metadata.go @@ -137,7 +137,7 @@ func testOnGCE() bool { resc := make(chan bool, 2) // Try two strategies in parallel. - // See https://github.com/googleapis/google-cloud-go/issues/194 + // See https://github.com/GoogleCloudPlatform/google-cloud-go/issues/194 go func() { req, _ := http.NewRequest("GET", "http://"+metadataIP, nil) req.Header.Set("User-Agent", userAgent) @@ -300,8 +300,8 @@ func (c *Client) getETag(suffix string) (value, etag string, err error) { // being stable anyway. host = metadataIP } - u := "http://" + host + "/computeMetadata/v1/" + suffix - req, _ := http.NewRequest("GET", u, nil) + url := "http://" + host + "/computeMetadata/v1/" + suffix + req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Metadata-Flavor", "Google") req.Header.Set("User-Agent", userAgent) res, err := c.hc.Do(req) @@ -312,13 +312,13 @@ func (c *Client) getETag(suffix string) (value, etag string, err error) { if res.StatusCode == http.StatusNotFound { return "", "", NotDefinedError(suffix) } + if res.StatusCode != 200 { + return "", "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url) + } all, err := ioutil.ReadAll(res.Body) if err != nil { return "", "", err } - if res.StatusCode != 200 { - return "", "", &Error{Code: res.StatusCode, Message: string(all)} - } return string(all), res.Header.Get("Etag"), nil } @@ -499,15 +499,3 @@ func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) erro } } } - -// Error contains an error response from the server. -type Error struct { - // Code is the HTTP response status code. - Code int - // Message is the server response message. - Message string -} - -func (e *Error) Error() string { - return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message) -} diff --git a/vendor/github.com/evanphx/json-patch/README.md b/vendor/github.com/evanphx/json-patch/README.md index a711d7961..9c7f87f7c 100644 --- a/vendor/github.com/evanphx/json-patch/README.md +++ b/vendor/github.com/evanphx/json-patch/README.md @@ -28,10 +28,15 @@ go get -u github.com/evanphx/json-patch # Configuration -There is a single global configuration variable `jsonpatch.SupportNegativeIndices'. This -defaults to `true` and enables the non-standard practice of allowing negative indices -to mean indices starting at the end of an array. This functionality can be disabled -by setting `jsonpatch.SupportNegativeIndices = false`. +* There is a global configuration variable `jsonpatch.SupportNegativeIndices`. + This defaults to `true` and enables the non-standard practice of allowing + negative indices to mean indices starting at the end of an array. This + functionality can be disabled by setting `jsonpatch.SupportNegativeIndices = + false`. + +* There is a global configuration variable `jsonpatch.AccumulatedCopySizeLimit`, + which limits the total size increase in bytes caused by "copy" operations in a + patch. It defaults to 0, which means there is no limit. ## Create and apply a merge patch Given both an original JSON document and a modified JSON document, you can create diff --git a/vendor/github.com/evanphx/json-patch/errors.go b/vendor/github.com/evanphx/json-patch/errors.go new file mode 100644 index 000000000..75304b443 --- /dev/null +++ b/vendor/github.com/evanphx/json-patch/errors.go @@ -0,0 +1,38 @@ +package jsonpatch + +import "fmt" + +// AccumulatedCopySizeError is an error type returned when the accumulated size +// increase caused by copy operations in a patch operation has exceeded the +// limit. +type AccumulatedCopySizeError struct { + limit int64 + accumulated int64 +} + +// NewAccumulatedCopySizeError returns an AccumulatedCopySizeError. +func NewAccumulatedCopySizeError(l, a int64) *AccumulatedCopySizeError { + return &AccumulatedCopySizeError{limit: l, accumulated: a} +} + +// Error implements the error interface. +func (a *AccumulatedCopySizeError) Error() string { + return fmt.Sprintf("Unable to complete the copy, the accumulated size increase of copy is %d, exceeding the limit %d", a.accumulated, a.limit) +} + +// ArraySizeError is an error type returned when the array size has exceeded +// the limit. +type ArraySizeError struct { + limit int + size int +} + +// NewArraySizeError returns an ArraySizeError. +func NewArraySizeError(l, s int) *ArraySizeError { + return &ArraySizeError{limit: l, size: s} +} + +// Error implements the error interface. +func (a *ArraySizeError) Error() string { + return fmt.Sprintf("Unable to create array of size %d, limit is %d", a.size, a.limit) +} diff --git a/vendor/github.com/evanphx/json-patch/patch.go b/vendor/github.com/evanphx/json-patch/patch.go index f26b6824b..c9cf59021 100644 --- a/vendor/github.com/evanphx/json-patch/patch.go +++ b/vendor/github.com/evanphx/json-patch/patch.go @@ -14,7 +14,15 @@ const ( eAry ) -var SupportNegativeIndices bool = true +var ( + // SupportNegativeIndices decides whether to support non-standard practice of + // allowing negative indices to mean indices starting at the end of an array. + // Default to true. + SupportNegativeIndices bool = true + // AccumulatedCopySizeLimit limits the total size increase in bytes caused by + // "copy" operations in a patch. + AccumulatedCopySizeLimit int64 = 0 +) type lazyNode struct { raw *json.RawMessage @@ -63,6 +71,20 @@ func (n *lazyNode) UnmarshalJSON(data []byte) error { return nil } +func deepCopy(src *lazyNode) (*lazyNode, int, error) { + if src == nil { + return nil, 0, nil + } + a, err := src.MarshalJSON() + if err != nil { + return nil, 0, err + } + sz := len(a) + ra := make(json.RawMessage, sz) + copy(ra, a) + return newLazyNode(&ra), sz, nil +} + func (n *lazyNode) intoDoc() (*partialDoc, error) { if n.which == eDoc { return &n.doc, nil @@ -344,35 +366,14 @@ func (d *partialDoc) remove(key string) error { return nil } +// set should only be used to implement the "replace" operation, so "key" must +// be an already existing index in "d". func (d *partialArray) set(key string, val *lazyNode) error { - if key == "-" { - *d = append(*d, val) - return nil - } - idx, err := strconv.Atoi(key) if err != nil { return err } - - sz := len(*d) - if idx+1 > sz { - sz = idx + 1 - } - - ary := make([]*lazyNode, sz) - - cur := *d - - copy(ary, cur) - - if idx >= len(ary) { - return fmt.Errorf("Unable to access invalid index: %d", idx) - } - - ary[idx] = val - - *d = ary + (*d)[idx] = val return nil } @@ -387,7 +388,9 @@ func (d *partialArray) add(key string, val *lazyNode) error { return err } - ary := make([]*lazyNode, len(*d)+1) + sz := len(*d) + 1 + + ary := make([]*lazyNode, sz) cur := *d @@ -527,7 +530,7 @@ func (p Patch) move(doc *container, op operation) error { return fmt.Errorf("jsonpatch move operation does not apply: doc is missing destination path: %s", path) } - return con.set(key, val) + return con.add(key, val) } func (p Patch) test(doc *container, op operation) error { @@ -561,7 +564,7 @@ func (p Patch) test(doc *container, op operation) error { return fmt.Errorf("Testing value %s failed", path) } -func (p Patch) copy(doc *container, op operation) error { +func (p Patch) copy(doc *container, op operation, accumulatedCopySize *int64) error { from := op.from() con, key := findObject(doc, from) @@ -583,7 +586,16 @@ func (p Patch) copy(doc *container, op operation) error { return fmt.Errorf("jsonpatch copy operation does not apply: doc is missing destination path: %s", path) } - return con.set(key, val) + valCopy, sz, err := deepCopy(val) + if err != nil { + return err + } + (*accumulatedCopySize) += int64(sz) + if AccumulatedCopySizeLimit > 0 && *accumulatedCopySize > AccumulatedCopySizeLimit { + return NewAccumulatedCopySizeError(AccumulatedCopySizeLimit, *accumulatedCopySize) + } + + return con.add(key, valCopy) } // Equal indicates if 2 JSON documents have the same structural equality. @@ -636,6 +648,8 @@ func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) { err = nil + var accumulatedCopySize int64 + for _, op := range p { switch op.kind() { case "add": @@ -649,7 +663,7 @@ func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) { case "test": err = p.test(&pd, op) case "copy": - err = p.copy(&pd, op) + err = p.copy(&pd, op, &accumulatedCopySize) default: err = fmt.Errorf("Unexpected kind: %s", op.kind()) } diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go index 7e215f220..2133562b0 100644 --- a/vendor/github.com/google/go-cmp/cmp/compare.go +++ b/vendor/github.com/google/go-cmp/cmp/compare.go @@ -29,26 +29,17 @@ package cmp import ( "fmt" "reflect" + "strings" "github.com/google/go-cmp/cmp/internal/diff" + "github.com/google/go-cmp/cmp/internal/flags" "github.com/google/go-cmp/cmp/internal/function" "github.com/google/go-cmp/cmp/internal/value" ) -// BUG(dsnet): Maps with keys containing NaN values cannot be properly compared due to -// the reflection package's inability to retrieve such entries. Equal will panic -// anytime it comes across a NaN key, but this behavior may change. -// -// See https://golang.org/issue/11104 for more details. - -var nothing = reflect.Value{} - // Equal reports whether x and y are equal by recursively applying the // following rules in the given order to x and y and all of their sub-values: // -// • If two values are not of the same type, then they are never equal -// and the overall result is false. -// // • Let S be the set of all Ignore, Transformer, and Comparer options that // remain after applying all path filters, value filters, and type filters. // If at least one Ignore exists in S, then the comparison is ignored. @@ -61,43 +52,79 @@ var nothing = reflect.Value{} // // • If the values have an Equal method of the form "(T) Equal(T) bool" or // "(T) Equal(I) bool" where T is assignable to I, then use the result of -// x.Equal(y) even if x or y is nil. -// Otherwise, no such method exists and evaluation proceeds to the next rule. +// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and +// evaluation proceeds to the next rule. // // • Lastly, try to compare x and y based on their basic kinds. // Simple kinds like booleans, integers, floats, complex numbers, strings, and // channels are compared using the equivalent of the == operator in Go. // Functions are only equal if they are both nil, otherwise they are unequal. -// Pointers are equal if the underlying values they point to are also equal. -// Interfaces are equal if their underlying concrete values are also equal. // -// Structs are equal if all of their fields are equal. If a struct contains -// unexported fields, Equal panics unless the AllowUnexported option is used or -// an Ignore option (e.g., cmpopts.IgnoreUnexported) ignores that field. +// Structs are equal if recursively calling Equal on all fields report equal. +// If a struct contains unexported fields, Equal panics unless an Ignore option +// (e.g., cmpopts.IgnoreUnexported) ignores that field or the AllowUnexported +// option explicitly permits comparing the unexported field. // -// Arrays, slices, and maps are equal if they are both nil or both non-nil -// with the same length and the elements at each index or key are equal. -// Note that a non-nil empty slice and a nil slice are not equal. -// To equate empty slices and maps, consider using cmpopts.EquateEmpty. +// Slices are equal if they are both nil or both non-nil, where recursively +// calling Equal on all non-ignored slice or array elements report equal. +// Empty non-nil slices and nil slices are not equal; to equate empty slices, +// consider using cmpopts.EquateEmpty. +// +// Maps are equal if they are both nil or both non-nil, where recursively +// calling Equal on all non-ignored map entries report equal. // Map keys are equal according to the == operator. // To use custom comparisons for map keys, consider using cmpopts.SortMaps. +// Empty non-nil maps and nil maps are not equal; to equate empty maps, +// consider using cmpopts.EquateEmpty. +// +// Pointers and interfaces are equal if they are both nil or both non-nil, +// where they have the same underlying concrete type and recursively +// calling Equal on the underlying values reports equal. func Equal(x, y interface{}, opts ...Option) bool { + vx := reflect.ValueOf(x) + vy := reflect.ValueOf(y) + + // If the inputs are different types, auto-wrap them in an empty interface + // so that they have the same parent type. + var t reflect.Type + if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() { + t = reflect.TypeOf((*interface{})(nil)).Elem() + if vx.IsValid() { + vvx := reflect.New(t).Elem() + vvx.Set(vx) + vx = vvx + } + if vy.IsValid() { + vvy := reflect.New(t).Elem() + vvy.Set(vy) + vy = vvy + } + } else { + t = vx.Type() + } + s := newState(opts) - s.compareAny(reflect.ValueOf(x), reflect.ValueOf(y)) + s.compareAny(&pathStep{t, vx, vy}) return s.result.Equal() } // Diff returns a human-readable report of the differences between two values. // It returns an empty string if and only if Equal returns true for the same -// input values and options. The output string will use the "-" symbol to -// indicate elements removed from x, and the "+" symbol to indicate elements -// added to y. +// input values and options. // -// Do not depend on this output being stable. +// The output is displayed as a literal in pseudo-Go syntax. +// At the start of each line, a "-" prefix indicates an element removed from x, +// a "+" prefix to indicates an element added to y, and the lack of a prefix +// indicates an element common to both x and y. If possible, the output +// uses fmt.Stringer.String or error.Error methods to produce more humanly +// readable outputs. In such cases, the string is prefixed with either an +// 's' or 'e' character, respectively, to indicate that the method was called. +// +// Do not depend on this output being stable. If you need the ability to +// programmatically interpret the difference, consider using a custom Reporter. func Diff(x, y interface{}, opts ...Option) string { r := new(defaultReporter) - opts = Options{Options(opts), r} - eq := Equal(x, y, opts...) + eq := Equal(x, y, Options(opts), Reporter(r)) d := r.String() if (d == "") != eq { panic("inconsistent difference and equality results") @@ -108,9 +135,13 @@ func Diff(x, y interface{}, opts ...Option) string { type state struct { // These fields represent the "comparison state". // Calling statelessCompare must not result in observable changes to these. - result diff.Result // The current result of comparison - curPath Path // The current path in the value tree - reporter reporter // Optional reporter used for difference formatting + result diff.Result // The current result of comparison + curPath Path // The current path in the value tree + reporters []reporter // Optional reporters + + // recChecker checks for infinite cycles applying the same set of + // transformers upon the output of itself. + recChecker recChecker // dynChecker triggers pseudo-random checks for option correctness. // It is safe for statelessCompare to mutate this value. @@ -122,10 +153,9 @@ type state struct { } func newState(opts []Option) *state { - s := new(state) - for _, opt := range opts { - s.processOption(opt) - } + // Always ensure a validator option exists to validate the inputs. + s := &state{opts: Options{validator{}}} + s.processOption(Options(opts)) return s } @@ -152,10 +182,7 @@ func (s *state) processOption(opt Option) { s.exporters[t] = true } case reporter: - if s.reporter != nil { - panic("difference reporter already registered") - } - s.reporter = opt + s.reporters = append(s.reporters, opt) default: panic(fmt.Sprintf("unknown option %T", opt)) } @@ -164,153 +191,88 @@ func (s *state) processOption(opt Option) { // statelessCompare compares two values and returns the result. // This function is stateless in that it does not alter the current result, // or output to any registered reporters. -func (s *state) statelessCompare(vx, vy reflect.Value) diff.Result { +func (s *state) statelessCompare(step PathStep) diff.Result { // We do not save and restore the curPath because all of the compareX // methods should properly push and pop from the path. // It is an implementation bug if the contents of curPath differs from // when calling this function to when returning from it. - oldResult, oldReporter := s.result, s.reporter + oldResult, oldReporters := s.result, s.reporters s.result = diff.Result{} // Reset result - s.reporter = nil // Remove reporter to avoid spurious printouts - s.compareAny(vx, vy) + s.reporters = nil // Remove reporters to avoid spurious printouts + s.compareAny(step) res := s.result - s.result, s.reporter = oldResult, oldReporter + s.result, s.reporters = oldResult, oldReporters return res } -func (s *state) compareAny(vx, vy reflect.Value) { - // TODO: Support cyclic data structures. +func (s *state) compareAny(step PathStep) { + // Update the path stack. + s.curPath.push(step) + defer s.curPath.pop() + for _, r := range s.reporters { + r.PushStep(step) + defer r.PopStep() + } + s.recChecker.Check(s.curPath) - // Rule 0: Differing types are never equal. - if !vx.IsValid() || !vy.IsValid() { - s.report(vx.IsValid() == vy.IsValid(), vx, vy) - return - } - if vx.Type() != vy.Type() { - s.report(false, vx, vy) // Possible for path to be empty - return - } - t := vx.Type() - if len(s.curPath) == 0 { - s.curPath.push(&pathStep{typ: t}) - defer s.curPath.pop() - } - vx, vy = s.tryExporting(vx, vy) + // Obtain the current type and values. + t := step.Type() + vx, vy := step.Values() // Rule 1: Check whether an option applies on this node in the value tree. - if s.tryOptions(vx, vy, t) { + if s.tryOptions(t, vx, vy) { return } // Rule 2: Check whether the type has a valid Equal method. - if s.tryMethod(vx, vy, t) { + if s.tryMethod(t, vx, vy) { return } - // Rule 3: Recursively descend into each value's underlying kind. + // Rule 3: Compare based on the underlying kind. switch t.Kind() { case reflect.Bool: - s.report(vx.Bool() == vy.Bool(), vx, vy) - return + s.report(vx.Bool() == vy.Bool(), 0) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - s.report(vx.Int() == vy.Int(), vx, vy) - return + s.report(vx.Int() == vy.Int(), 0) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - s.report(vx.Uint() == vy.Uint(), vx, vy) - return + s.report(vx.Uint() == vy.Uint(), 0) case reflect.Float32, reflect.Float64: - s.report(vx.Float() == vy.Float(), vx, vy) - return + s.report(vx.Float() == vy.Float(), 0) case reflect.Complex64, reflect.Complex128: - s.report(vx.Complex() == vy.Complex(), vx, vy) - return + s.report(vx.Complex() == vy.Complex(), 0) case reflect.String: - s.report(vx.String() == vy.String(), vx, vy) - return + s.report(vx.String() == vy.String(), 0) case reflect.Chan, reflect.UnsafePointer: - s.report(vx.Pointer() == vy.Pointer(), vx, vy) - return + s.report(vx.Pointer() == vy.Pointer(), 0) case reflect.Func: - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - case reflect.Ptr: - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - s.curPath.push(&indirect{pathStep{t.Elem()}}) - defer s.curPath.pop() - s.compareAny(vx.Elem(), vy.Elem()) - return - case reflect.Interface: - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - if vx.Elem().Type() != vy.Elem().Type() { - s.report(false, vx.Elem(), vy.Elem()) - return - } - s.curPath.push(&typeAssertion{pathStep{vx.Elem().Type()}}) - defer s.curPath.pop() - s.compareAny(vx.Elem(), vy.Elem()) - return - case reflect.Slice: - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - fallthrough - case reflect.Array: - s.compareArray(vx, vy, t) - return - case reflect.Map: - s.compareMap(vx, vy, t) - return + s.report(vx.IsNil() && vy.IsNil(), 0) case reflect.Struct: - s.compareStruct(vx, vy, t) - return + s.compareStruct(t, vx, vy) + case reflect.Slice, reflect.Array: + s.compareSlice(t, vx, vy) + case reflect.Map: + s.compareMap(t, vx, vy) + case reflect.Ptr: + s.comparePtr(t, vx, vy) + case reflect.Interface: + s.compareInterface(t, vx, vy) default: panic(fmt.Sprintf("%v kind not handled", t.Kind())) } } -func (s *state) tryExporting(vx, vy reflect.Value) (reflect.Value, reflect.Value) { - if sf, ok := s.curPath[len(s.curPath)-1].(*structField); ok && sf.unexported { - if sf.force { - // Use unsafe pointer arithmetic to get read-write access to an - // unexported field in the struct. - vx = unsafeRetrieveField(sf.pvx, sf.field) - vy = unsafeRetrieveField(sf.pvy, sf.field) - } else { - // We are not allowed to export the value, so invalidate them - // so that tryOptions can panic later if not explicitly ignored. - vx = nothing - vy = nothing - } - } - return vx, vy -} - -func (s *state) tryOptions(vx, vy reflect.Value, t reflect.Type) bool { - // If there were no FilterValues, we will not detect invalid inputs, - // so manually check for them and append invalid if necessary. - // We still evaluate the options since an ignore can override invalid. - opts := s.opts - if !vx.IsValid() || !vy.IsValid() { - opts = Options{opts, invalid{}} - } - +func (s *state) tryOptions(t reflect.Type, vx, vy reflect.Value) bool { // Evaluate all filters and apply the remaining options. - if opt := opts.filter(s, vx, vy, t); opt != nil { + if opt := s.opts.filter(s, t, vx, vy); opt != nil { opt.apply(s, vx, vy) return true } return false } -func (s *state) tryMethod(vx, vy reflect.Value, t reflect.Type) bool { +func (s *state) tryMethod(t reflect.Type, vx, vy reflect.Value) bool { // Check if this type even has an Equal method. m, ok := t.MethodByName("Equal") if !ok || !function.IsType(m.Type, function.EqualAssignable) { @@ -318,11 +280,11 @@ func (s *state) tryMethod(vx, vy reflect.Value, t reflect.Type) bool { } eq := s.callTTBFunc(m.Func, vx, vy) - s.report(eq, vx, vy) + s.report(eq, reportByMethod) return true } -func (s *state) callTRFunc(f, v reflect.Value) reflect.Value { +func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value { v = sanitizeValue(v, f.Type().In(0)) if !s.dynChecker.Next() { return f.Call([]reflect.Value{v})[0] @@ -333,15 +295,15 @@ func (s *state) callTRFunc(f, v reflect.Value) reflect.Value { // unsafe mutations to the input. c := make(chan reflect.Value) go detectRaces(c, f, v) + got := <-c want := f.Call([]reflect.Value{v})[0] - if got := <-c; !s.statelessCompare(got, want).Equal() { + if step.vx, step.vy = got, want; !s.statelessCompare(step).Equal() { // To avoid false-positives with non-reflexive equality operations, // we sanity check whether a value is equal to itself. - if !s.statelessCompare(want, want).Equal() { + if step.vx, step.vy = want, want; !s.statelessCompare(step).Equal() { return want } - fn := getFuncName(f.Pointer()) - panic(fmt.Sprintf("non-deterministic function detected: %s", fn)) + panic(fmt.Sprintf("non-deterministic function detected: %s", function.NameOf(f))) } return want } @@ -359,10 +321,10 @@ func (s *state) callTTBFunc(f, x, y reflect.Value) bool { // unsafe mutations to the input. c := make(chan reflect.Value) go detectRaces(c, f, y, x) + got := <-c want := f.Call([]reflect.Value{x, y})[0].Bool() - if got := <-c; !got.IsValid() || got.Bool() != want { - fn := getFuncName(f.Pointer()) - panic(fmt.Sprintf("non-deterministic or non-symmetric function detected: %s", fn)) + if !got.IsValid() || got.Bool() != want { + panic(fmt.Sprintf("non-deterministic or non-symmetric function detected: %s", function.NameOf(f))) } return want } @@ -380,140 +342,241 @@ func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) { // assuming that T is assignable to R. // Otherwise, it returns the input value as is. func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value { - // TODO(dsnet): Remove this hacky workaround. - // See https://golang.org/issue/22143 - if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t { - return reflect.New(t).Elem() + // TODO(dsnet): Workaround for reflect bug (https://golang.org/issue/22143). + if !flags.AtLeastGo110 { + if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t { + return reflect.New(t).Elem() + } } return v } -func (s *state) compareArray(vx, vy reflect.Value, t reflect.Type) { - step := &sliceIndex{pathStep{t.Elem()}, 0, 0} - s.curPath.push(step) - - // Compute an edit-script for slices vx and vy. - es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result { - step.xkey, step.ykey = ix, iy - return s.statelessCompare(vx.Index(ix), vy.Index(iy)) - }) - - // Report the entire slice as is if the arrays are of primitive kind, - // and the arrays are different enough. - isPrimitive := false - switch t.Elem().Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, - reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: - isPrimitive = true - } - if isPrimitive && es.Dist() > (vx.Len()+vy.Len())/4 { - s.curPath.pop() // Pop first since we are reporting the whole slice - s.report(false, vx, vy) - return - } - - // Replay the edit-script. - var ix, iy int - for _, e := range es { - switch e { - case diff.UniqueX: - step.xkey, step.ykey = ix, -1 - s.report(false, vx.Index(ix), nothing) - ix++ - case diff.UniqueY: - step.xkey, step.ykey = -1, iy - s.report(false, nothing, vy.Index(iy)) - iy++ - default: - step.xkey, step.ykey = ix, iy - if e == diff.Identity { - s.report(true, vx.Index(ix), vy.Index(iy)) - } else { - s.compareAny(vx.Index(ix), vy.Index(iy)) - } - ix++ - iy++ - } - } - s.curPath.pop() - return -} - -func (s *state) compareMap(vx, vy reflect.Value, t reflect.Type) { - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - - // We combine and sort the two map keys so that we can perform the - // comparisons in a deterministic order. - step := &mapIndex{pathStep: pathStep{t.Elem()}} - s.curPath.push(step) - defer s.curPath.pop() - for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) { - step.key = k - vvx := vx.MapIndex(k) - vvy := vy.MapIndex(k) - switch { - case vvx.IsValid() && vvy.IsValid(): - s.compareAny(vvx, vvy) - case vvx.IsValid() && !vvy.IsValid(): - s.report(false, vvx, nothing) - case !vvx.IsValid() && vvy.IsValid(): - s.report(false, nothing, vvy) - default: - // It is possible for both vvx and vvy to be invalid if the - // key contained a NaN value in it. There is no way in - // reflection to be able to retrieve these values. - // See https://golang.org/issue/11104 - panic(fmt.Sprintf("%#v has map key with NaNs", s.curPath)) - } - } -} - -func (s *state) compareStruct(vx, vy reflect.Value, t reflect.Type) { +func (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) { var vax, vay reflect.Value // Addressable versions of vx and vy - step := &structField{} - s.curPath.push(step) - defer s.curPath.pop() + step := StructField{&structField{}} for i := 0; i < t.NumField(); i++ { - vvx := vx.Field(i) - vvy := vy.Field(i) step.typ = t.Field(i).Type + step.vx = vx.Field(i) + step.vy = vy.Field(i) step.name = t.Field(i).Name step.idx = i step.unexported = !isExported(step.name) if step.unexported { + if step.name == "_" { + continue + } // Defer checking of unexported fields until later to give an // Ignore a chance to ignore the field. if !vax.IsValid() || !vay.IsValid() { - // For unsafeRetrieveField to work, the parent struct must + // For retrieveUnexportedField to work, the parent struct must // be addressable. Create a new copy of the values if // necessary to make them addressable. vax = makeAddressable(vx) vay = makeAddressable(vy) } - step.force = s.exporters[t] + step.mayForce = s.exporters[t] step.pvx = vax step.pvy = vay step.field = t.Field(i) } - s.compareAny(vvx, vvy) + s.compareAny(step) } } -// report records the result of a single comparison. -// It also calls Report if any reporter is registered. -func (s *state) report(eq bool, vx, vy reflect.Value) { - if eq { - s.result.NSame++ - } else { - s.result.NDiff++ +func (s *state) compareSlice(t reflect.Type, vx, vy reflect.Value) { + isSlice := t.Kind() == reflect.Slice + if isSlice && (vx.IsNil() || vy.IsNil()) { + s.report(vx.IsNil() && vy.IsNil(), 0) + return } - if s.reporter != nil { - s.reporter.Report(vx, vy, eq, s.curPath) + + // TODO: Support cyclic data structures. + + step := SliceIndex{&sliceIndex{pathStep: pathStep{typ: t.Elem()}}} + withIndexes := func(ix, iy int) SliceIndex { + if ix >= 0 { + step.vx, step.xkey = vx.Index(ix), ix + } else { + step.vx, step.xkey = reflect.Value{}, -1 + } + if iy >= 0 { + step.vy, step.ykey = vy.Index(iy), iy + } else { + step.vy, step.ykey = reflect.Value{}, -1 + } + return step + } + + // Ignore options are able to ignore missing elements in a slice. + // However, detecting these reliably requires an optimal differencing + // algorithm, for which diff.Difference is not. + // + // Instead, we first iterate through both slices to detect which elements + // would be ignored if standing alone. The index of non-discarded elements + // are stored in a separate slice, which diffing is then performed on. + var indexesX, indexesY []int + var ignoredX, ignoredY []bool + for ix := 0; ix < vx.Len(); ix++ { + ignored := s.statelessCompare(withIndexes(ix, -1)).NumDiff == 0 + if !ignored { + indexesX = append(indexesX, ix) + } + ignoredX = append(ignoredX, ignored) + } + for iy := 0; iy < vy.Len(); iy++ { + ignored := s.statelessCompare(withIndexes(-1, iy)).NumDiff == 0 + if !ignored { + indexesY = append(indexesY, iy) + } + ignoredY = append(ignoredY, ignored) + } + + // Compute an edit-script for slices vx and vy (excluding ignored elements). + edits := diff.Difference(len(indexesX), len(indexesY), func(ix, iy int) diff.Result { + return s.statelessCompare(withIndexes(indexesX[ix], indexesY[iy])) + }) + + // Replay the ignore-scripts and the edit-script. + var ix, iy int + for ix < vx.Len() || iy < vy.Len() { + var e diff.EditType + switch { + case ix < len(ignoredX) && ignoredX[ix]: + e = diff.UniqueX + case iy < len(ignoredY) && ignoredY[iy]: + e = diff.UniqueY + default: + e, edits = edits[0], edits[1:] + } + switch e { + case diff.UniqueX: + s.compareAny(withIndexes(ix, -1)) + ix++ + case diff.UniqueY: + s.compareAny(withIndexes(-1, iy)) + iy++ + default: + s.compareAny(withIndexes(ix, iy)) + ix++ + iy++ + } + } +} + +func (s *state) compareMap(t reflect.Type, vx, vy reflect.Value) { + if vx.IsNil() || vy.IsNil() { + s.report(vx.IsNil() && vy.IsNil(), 0) + return + } + + // TODO: Support cyclic data structures. + + // We combine and sort the two map keys so that we can perform the + // comparisons in a deterministic order. + step := MapIndex{&mapIndex{pathStep: pathStep{typ: t.Elem()}}} + for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) { + step.vx = vx.MapIndex(k) + step.vy = vy.MapIndex(k) + step.key = k + if !step.vx.IsValid() && !step.vy.IsValid() { + // It is possible for both vx and vy to be invalid if the + // key contained a NaN value in it. + // + // Even with the ability to retrieve NaN keys in Go 1.12, + // there still isn't a sensible way to compare the values since + // a NaN key may map to multiple unordered values. + // The most reasonable way to compare NaNs would be to compare the + // set of values. However, this is impossible to do efficiently + // since set equality is provably an O(n^2) operation given only + // an Equal function. If we had a Less function or Hash function, + // this could be done in O(n*log(n)) or O(n), respectively. + // + // Rather than adding complex logic to deal with NaNs, make it + // the user's responsibility to compare such obscure maps. + const help = "consider providing a Comparer to compare the map" + panic(fmt.Sprintf("%#v has map key with NaNs\n%s", s.curPath, help)) + } + s.compareAny(step) + } +} + +func (s *state) comparePtr(t reflect.Type, vx, vy reflect.Value) { + if vx.IsNil() || vy.IsNil() { + s.report(vx.IsNil() && vy.IsNil(), 0) + return + } + + // TODO: Support cyclic data structures. + + vx, vy = vx.Elem(), vy.Elem() + s.compareAny(Indirect{&indirect{pathStep{t.Elem(), vx, vy}}}) +} + +func (s *state) compareInterface(t reflect.Type, vx, vy reflect.Value) { + if vx.IsNil() || vy.IsNil() { + s.report(vx.IsNil() && vy.IsNil(), 0) + return + } + vx, vy = vx.Elem(), vy.Elem() + if vx.Type() != vy.Type() { + s.report(false, 0) + return + } + s.compareAny(TypeAssertion{&typeAssertion{pathStep{vx.Type(), vx, vy}}}) +} + +func (s *state) report(eq bool, rf resultFlags) { + if rf&reportByIgnore == 0 { + if eq { + s.result.NumSame++ + rf |= reportEqual + } else { + s.result.NumDiff++ + rf |= reportUnequal + } + } + for _, r := range s.reporters { + r.Report(Result{flags: rf}) + } +} + +// recChecker tracks the state needed to periodically perform checks that +// user provided transformers are not stuck in an infinitely recursive cycle. +type recChecker struct{ next int } + +// Check scans the Path for any recursive transformers and panics when any +// recursive transformers are detected. Note that the presence of a +// recursive Transformer does not necessarily imply an infinite cycle. +// As such, this check only activates after some minimal number of path steps. +func (rc *recChecker) Check(p Path) { + const minLen = 1 << 16 + if rc.next == 0 { + rc.next = minLen + } + if len(p) < rc.next { + return + } + rc.next <<= 1 + + // Check whether the same transformer has appeared at least twice. + var ss []string + m := map[Option]int{} + for _, ps := range p { + if t, ok := ps.(Transform); ok { + t := t.Option() + if m[t] == 1 { // Transformer was used exactly once before + tf := t.(*transformer).fnc.Type() + ss = append(ss, fmt.Sprintf("%v: %v => %v", t, tf.In(0), tf.Out(0))) + } + m[t]++ + } + } + if len(ss) > 0 { + const warning = "recursive set of Transformers detected" + const help = "consider using cmpopts.AcyclicTransformer" + set := strings.Join(ss, "\n\t") + panic(fmt.Sprintf("%s:\n\t%s\n%s", warning, set, help)) } } diff --git a/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go b/vendor/github.com/google/go-cmp/cmp/export_panic.go similarity index 60% rename from vendor/github.com/google/go-cmp/cmp/unsafe_panic.go rename to vendor/github.com/google/go-cmp/cmp/export_panic.go index d1518eb3a..abc3a1c3e 100644 --- a/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go +++ b/vendor/github.com/google/go-cmp/cmp/export_panic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE.md file. -// +build purego appengine js +// +build purego package cmp @@ -10,6 +10,6 @@ import "reflect" const supportAllowUnexported = false -func unsafeRetrieveField(reflect.Value, reflect.StructField) reflect.Value { - panic("unsafeRetrieveField is not implemented") +func retrieveUnexportedField(reflect.Value, reflect.StructField) reflect.Value { + panic("retrieveUnexportedField is not implemented") } diff --git a/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go b/vendor/github.com/google/go-cmp/cmp/export_unsafe.go similarity index 64% rename from vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go rename to vendor/github.com/google/go-cmp/cmp/export_unsafe.go index 579b65507..59d4ee91b 100644 --- a/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go +++ b/vendor/github.com/google/go-cmp/cmp/export_unsafe.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE.md file. -// +build !purego,!appengine,!js +// +build !purego package cmp @@ -13,11 +13,11 @@ import ( const supportAllowUnexported = true -// unsafeRetrieveField uses unsafe to forcibly retrieve any field from a struct -// such that the value has read-write permissions. +// retrieveUnexportedField uses unsafe to forcibly retrieve any field from +// a struct such that the value has read-write permissions. // // The parent struct, v, must be addressable, while f must be a StructField // describing the field to retrieve. -func unsafeRetrieveField(v reflect.Value, f reflect.StructField) reflect.Value { +func retrieveUnexportedField(v reflect.Value, f reflect.StructField) reflect.Value { return reflect.NewAt(f.Type, unsafe.Pointer(v.UnsafeAddr()+f.Offset)).Elem() } diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go index 42afa4960..fe98dcc67 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE.md file. -// +build !debug +// +build !cmp_debug package diff diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go index fd9f7f177..597b6ae56 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE.md file. -// +build debug +// +build cmp_debug package diff @@ -14,7 +14,7 @@ import ( ) // The algorithm can be seen running in real-time by enabling debugging: -// go test -tags=debug -v +// go test -tags=cmp_debug -v // // Example output: // === RUN TestDifference/#34 diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go index 260befea2..3d2e42662 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go @@ -85,22 +85,31 @@ func (es EditScript) LenY() int { return len(es) - es.stats().NX } type EqualFunc func(ix int, iy int) Result // Result is the result of comparison. -// NSame is the number of sub-elements that are equal. -// NDiff is the number of sub-elements that are not equal. -type Result struct{ NSame, NDiff int } +// NumSame is the number of sub-elements that are equal. +// NumDiff is the number of sub-elements that are not equal. +type Result struct{ NumSame, NumDiff int } + +// BoolResult returns a Result that is either Equal or not Equal. +func BoolResult(b bool) Result { + if b { + return Result{NumSame: 1} // Equal, Similar + } else { + return Result{NumDiff: 2} // Not Equal, not Similar + } +} // Equal indicates whether the symbols are equal. Two symbols are equal -// if and only if NDiff == 0. If Equal, then they are also Similar. -func (r Result) Equal() bool { return r.NDiff == 0 } +// if and only if NumDiff == 0. If Equal, then they are also Similar. +func (r Result) Equal() bool { return r.NumDiff == 0 } // Similar indicates whether two symbols are similar and may be represented // by using the Modified type. As a special case, we consider binary comparisons // (i.e., those that return Result{1, 0} or Result{0, 1}) to be similar. // -// The exact ratio of NSame to NDiff to determine similarity may change. +// The exact ratio of NumSame to NumDiff to determine similarity may change. func (r Result) Similar() bool { - // Use NSame+1 to offset NSame so that binary comparisons are similar. - return r.NSame+1 >= r.NDiff + // Use NumSame+1 to offset NumSame so that binary comparisons are similar. + return r.NumSame+1 >= r.NumDiff } // Difference reports whether two lists of lengths nx and ny are equal @@ -191,9 +200,9 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { // that two lists commonly differ because elements were added to the front // or end of the other list. // - // Running the tests with the "debug" build tag prints a visualization of - // the algorithm running in real-time. This is educational for understanding - // how the algorithm works. See debug_enable.go. + // Running the tests with the "cmp_debug" build tag prints a visualization + // of the algorithm running in real-time. This is educational for + // understanding how the algorithm works. See debug_enable.go. f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es) for { // Forward search from the beginning. diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go new file mode 100644 index 000000000..a9e7fc0b5 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go @@ -0,0 +1,9 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package flags + +// Deterministic controls whether the output of Diff should be deterministic. +// This is only used for testing. +var Deterministic bool diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go new file mode 100644 index 000000000..01aed0a15 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go @@ -0,0 +1,10 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build !go1.10 + +package flags + +// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10. +const AtLeastGo110 = false diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go new file mode 100644 index 000000000..c0b667f58 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go @@ -0,0 +1,10 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build go1.10 + +package flags + +// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10. +const AtLeastGo110 = true diff --git a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go index 4c35ff11e..ace1dbe86 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go @@ -2,25 +2,34 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE.md file. -// Package function identifies function types. +// Package function provides functionality for identifying function types. package function -import "reflect" +import ( + "reflect" + "regexp" + "runtime" + "strings" +) type funcType int const ( _ funcType = iota + tbFunc // func(T) bool ttbFunc // func(T, T) bool + trbFunc // func(T, R) bool tibFunc // func(T, I) bool trFunc // func(T) R - Equal = ttbFunc // func(T, T) bool - EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool - Transformer = trFunc // func(T) R - ValueFilter = ttbFunc // func(T, T) bool - Less = ttbFunc // func(T, T) bool + Equal = ttbFunc // func(T, T) bool + EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool + Transformer = trFunc // func(T) R + ValueFilter = ttbFunc // func(T, T) bool + Less = ttbFunc // func(T, T) bool + ValuePredicate = tbFunc // func(T) bool + KeyValuePredicate = trbFunc // func(T, R) bool ) var boolType = reflect.TypeOf(true) @@ -32,10 +41,18 @@ func IsType(t reflect.Type, ft funcType) bool { } ni, no := t.NumIn(), t.NumOut() switch ft { + case tbFunc: // func(T) bool + if ni == 1 && no == 1 && t.Out(0) == boolType { + return true + } case ttbFunc: // func(T, T) bool if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType { return true } + case trbFunc: // func(T, R) bool + if ni == 2 && no == 1 && t.Out(0) == boolType { + return true + } case tibFunc: // func(T, I) bool if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType { return true @@ -47,3 +64,36 @@ func IsType(t reflect.Type, ft funcType) bool { } return false } + +var lastIdentRx = regexp.MustCompile(`[_\p{L}][_\p{L}\p{N}]*$`) + +// NameOf returns the name of the function value. +func NameOf(v reflect.Value) string { + fnc := runtime.FuncForPC(v.Pointer()) + if fnc == nil { + return "" + } + fullName := fnc.Name() // e.g., "long/path/name/mypkg.(*MyType).(long/path/name/mypkg.myMethod)-fm" + + // Method closures have a "-fm" suffix. + fullName = strings.TrimSuffix(fullName, "-fm") + + var name string + for len(fullName) > 0 { + inParen := strings.HasSuffix(fullName, ")") + fullName = strings.TrimSuffix(fullName, ")") + + s := lastIdentRx.FindString(fullName) + if s == "" { + break + } + name = s + "." + name + fullName = strings.TrimSuffix(fullName, s) + + if i := strings.LastIndexByte(fullName, '('); inParen && i >= 0 { + fullName = fullName[:i] + } + fullName = strings.TrimSuffix(fullName, ".") + } + return strings.TrimSuffix(name, ".") +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/format.go b/vendor/github.com/google/go-cmp/cmp/internal/value/format.go deleted file mode 100644 index 657e50877..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/format.go +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2017, The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE.md file. - -// Package value provides functionality for reflect.Value types. -package value - -import ( - "fmt" - "reflect" - "strconv" - "strings" - "unicode" -) - -var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() - -// Format formats the value v as a string. -// -// This is similar to fmt.Sprintf("%+v", v) except this: -// * Prints the type unless it can be elided -// * Avoids printing struct fields that are zero -// * Prints a nil-slice as being nil, not empty -// * Prints map entries in deterministic order -func Format(v reflect.Value, conf FormatConfig) string { - conf.printType = true - conf.followPointers = true - conf.realPointers = true - return formatAny(v, conf, nil) -} - -type FormatConfig struct { - UseStringer bool // Should the String method be used if available? - printType bool // Should we print the type before the value? - PrintPrimitiveType bool // Should we print the type of primitives? - followPointers bool // Should we recursively follow pointers? - realPointers bool // Should we print the real address of pointers? -} - -func formatAny(v reflect.Value, conf FormatConfig, visited map[uintptr]bool) string { - // TODO: Should this be a multi-line printout in certain situations? - - if !v.IsValid() { - return "" - } - if conf.UseStringer && v.Type().Implements(stringerIface) && v.CanInterface() { - if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && v.IsNil() { - return "" - } - - const stringerPrefix = "s" // Indicates that the String method was used - s := v.Interface().(fmt.Stringer).String() - return stringerPrefix + formatString(s) - } - - switch v.Kind() { - case reflect.Bool: - return formatPrimitive(v.Type(), v.Bool(), conf) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return formatPrimitive(v.Type(), v.Int(), conf) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - if v.Type().PkgPath() == "" || v.Kind() == reflect.Uintptr { - // Unnamed uints are usually bytes or words, so use hexadecimal. - return formatPrimitive(v.Type(), formatHex(v.Uint()), conf) - } - return formatPrimitive(v.Type(), v.Uint(), conf) - case reflect.Float32, reflect.Float64: - return formatPrimitive(v.Type(), v.Float(), conf) - case reflect.Complex64, reflect.Complex128: - return formatPrimitive(v.Type(), v.Complex(), conf) - case reflect.String: - return formatPrimitive(v.Type(), formatString(v.String()), conf) - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - return formatPointer(v, conf) - case reflect.Ptr: - if v.IsNil() { - if conf.printType { - return fmt.Sprintf("(%v)(nil)", v.Type()) - } - return "" - } - if visited[v.Pointer()] || !conf.followPointers { - return formatPointer(v, conf) - } - visited = insertPointer(visited, v.Pointer()) - return "&" + formatAny(v.Elem(), conf, visited) - case reflect.Interface: - if v.IsNil() { - if conf.printType { - return fmt.Sprintf("%v(nil)", v.Type()) - } - return "" - } - return formatAny(v.Elem(), conf, visited) - case reflect.Slice: - if v.IsNil() { - if conf.printType { - return fmt.Sprintf("%v(nil)", v.Type()) - } - return "" - } - if visited[v.Pointer()] { - return formatPointer(v, conf) - } - visited = insertPointer(visited, v.Pointer()) - fallthrough - case reflect.Array: - var ss []string - subConf := conf - subConf.printType = v.Type().Elem().Kind() == reflect.Interface - for i := 0; i < v.Len(); i++ { - s := formatAny(v.Index(i), subConf, visited) - ss = append(ss, s) - } - s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) - if conf.printType { - return v.Type().String() + s - } - return s - case reflect.Map: - if v.IsNil() { - if conf.printType { - return fmt.Sprintf("%v(nil)", v.Type()) - } - return "" - } - if visited[v.Pointer()] { - return formatPointer(v, conf) - } - visited = insertPointer(visited, v.Pointer()) - - var ss []string - keyConf, valConf := conf, conf - keyConf.printType = v.Type().Key().Kind() == reflect.Interface - keyConf.followPointers = false - valConf.printType = v.Type().Elem().Kind() == reflect.Interface - for _, k := range SortKeys(v.MapKeys()) { - sk := formatAny(k, keyConf, visited) - sv := formatAny(v.MapIndex(k), valConf, visited) - ss = append(ss, fmt.Sprintf("%s: %s", sk, sv)) - } - s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) - if conf.printType { - return v.Type().String() + s - } - return s - case reflect.Struct: - var ss []string - subConf := conf - subConf.printType = true - for i := 0; i < v.NumField(); i++ { - vv := v.Field(i) - if isZero(vv) { - continue // Elide zero value fields - } - name := v.Type().Field(i).Name - subConf.UseStringer = conf.UseStringer - s := formatAny(vv, subConf, visited) - ss = append(ss, fmt.Sprintf("%s: %s", name, s)) - } - s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) - if conf.printType { - return v.Type().String() + s - } - return s - default: - panic(fmt.Sprintf("%v kind not handled", v.Kind())) - } -} - -func formatString(s string) string { - // Use quoted string if it the same length as a raw string literal. - // Otherwise, attempt to use the raw string form. - qs := strconv.Quote(s) - if len(qs) == 1+len(s)+1 { - return qs - } - - // Disallow newlines to ensure output is a single line. - // Only allow printable runes for readability purposes. - rawInvalid := func(r rune) bool { - return r == '`' || r == '\n' || !unicode.IsPrint(r) - } - if strings.IndexFunc(s, rawInvalid) < 0 { - return "`" + s + "`" - } - return qs -} - -func formatPrimitive(t reflect.Type, v interface{}, conf FormatConfig) string { - if conf.printType && (conf.PrintPrimitiveType || t.PkgPath() != "") { - return fmt.Sprintf("%v(%v)", t, v) - } - return fmt.Sprintf("%v", v) -} - -func formatPointer(v reflect.Value, conf FormatConfig) string { - p := v.Pointer() - if !conf.realPointers { - p = 0 // For deterministic printing purposes - } - s := formatHex(uint64(p)) - if conf.printType { - return fmt.Sprintf("(%v)(%s)", v.Type(), s) - } - return s -} - -func formatHex(u uint64) string { - var f string - switch { - case u <= 0xff: - f = "0x%02x" - case u <= 0xffff: - f = "0x%04x" - case u <= 0xffffff: - f = "0x%06x" - case u <= 0xffffffff: - f = "0x%08x" - case u <= 0xffffffffff: - f = "0x%010x" - case u <= 0xffffffffffff: - f = "0x%012x" - case u <= 0xffffffffffffff: - f = "0x%014x" - case u <= 0xffffffffffffffff: - f = "0x%016x" - } - return fmt.Sprintf(f, u) -} - -// insertPointer insert p into m, allocating m if necessary. -func insertPointer(m map[uintptr]bool, p uintptr) map[uintptr]bool { - if m == nil { - m = make(map[uintptr]bool) - } - m[p] = true - return m -} - -// isZero reports whether v is the zero value. -// This does not rely on Interface and so can be used on unexported fields. -func isZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return v.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Complex64, reflect.Complex128: - return v.Complex() == 0 - case reflect.String: - return v.String() == "" - case reflect.UnsafePointer: - return v.Pointer() == 0 - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - for i := 0; i < v.Len(); i++ { - if !isZero(v.Index(i)) { - return false - } - } - return true - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - if !isZero(v.Field(i)) { - return false - } - } - return true - } - return false -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go new file mode 100644 index 000000000..0a01c4796 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go @@ -0,0 +1,23 @@ +// Copyright 2018, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build purego + +package value + +import "reflect" + +// Pointer is an opaque typed pointer and is guaranteed to be comparable. +type Pointer struct { + p uintptr + t reflect.Type +} + +// PointerOf returns a Pointer from v, which must be a +// reflect.Ptr, reflect.Slice, or reflect.Map. +func PointerOf(v reflect.Value) Pointer { + // NOTE: Storing a pointer as an uintptr is technically incorrect as it + // assumes that the GC implementation does not use a moving collector. + return Pointer{v.Pointer(), v.Type()} +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go new file mode 100644 index 000000000..da134ae2a --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go @@ -0,0 +1,26 @@ +// Copyright 2018, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build !purego + +package value + +import ( + "reflect" + "unsafe" +) + +// Pointer is an opaque typed pointer and is guaranteed to be comparable. +type Pointer struct { + p unsafe.Pointer + t reflect.Type +} + +// PointerOf returns a Pointer from v, which must be a +// reflect.Ptr, reflect.Slice, or reflect.Map. +func PointerOf(v reflect.Value) Pointer { + // The proper representation of a pointer is unsafe.Pointer, + // which is necessary if the GC ever uses a moving collector. + return Pointer{unsafe.Pointer(v.Pointer()), v.Type()} +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go index fe8aa27a0..938f646f0 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go @@ -19,7 +19,7 @@ func SortKeys(vs []reflect.Value) []reflect.Value { } // Sort the map keys. - sort.Sort(valueSorter(vs)) + sort.Slice(vs, func(i, j int) bool { return isLess(vs[i], vs[j]) }) // Deduplicate keys (fails for NaNs). vs2 := vs[:1] @@ -31,13 +31,6 @@ func SortKeys(vs []reflect.Value) []reflect.Value { return vs2 } -// TODO: Use sort.Slice once Google AppEngine is on Go1.8 or above. -type valueSorter []reflect.Value - -func (vs valueSorter) Len() int { return len(vs) } -func (vs valueSorter) Less(i, j int) bool { return isLess(vs[i], vs[j]) } -func (vs valueSorter) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } - // isLess is a generic function for sorting arbitrary map keys. // The inputs must be of the same type and must be comparable. func isLess(x, y reflect.Value) bool { diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go b/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go new file mode 100644 index 000000000..d13a12ccf --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go @@ -0,0 +1,45 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package value + +import "reflect" + +// IsZero reports whether v is the zero value. +// This does not rely on Interface and so can be used on unexported fields. +func IsZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return v.Bool() == false + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Complex64, reflect.Complex128: + return v.Complex() == 0 + case reflect.String: + return v.String() == "" + case reflect.UnsafePointer: + return v.Pointer() == 0 + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: + return v.IsNil() + case reflect.Array: + for i := 0; i < v.Len(); i++ { + if !IsZero(v.Index(i)) { + return false + } + } + return true + case reflect.Struct: + for i := 0; i < v.NumField(); i++ { + if !IsZero(v.Field(i)) { + return false + } + } + return true + } + return false +} diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go index 91d4b066e..793448160 100644 --- a/vendor/github.com/google/go-cmp/cmp/options.go +++ b/vendor/github.com/google/go-cmp/cmp/options.go @@ -7,7 +7,7 @@ package cmp import ( "fmt" "reflect" - "runtime" + "regexp" "strings" "github.com/google/go-cmp/cmp/internal/function" @@ -29,11 +29,11 @@ type Option interface { // An Options is returned only if multiple comparers or transformers // can apply simultaneously and will only contain values of those types // or sub-Options containing values of those types. - filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption + filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption } // applicableOption represents the following types: -// Fundamental: ignore | invalid | *comparer | *transformer +// Fundamental: ignore | validator | *comparer | *transformer // Grouping: Options type applicableOption interface { Option @@ -43,7 +43,7 @@ type applicableOption interface { } // coreOption represents the following types: -// Fundamental: ignore | invalid | *comparer | *transformer +// Fundamental: ignore | validator | *comparer | *transformer // Filters: *pathFilter | *valuesFilter type coreOption interface { Option @@ -63,19 +63,19 @@ func (core) isCore() {} // on all individual options held within. type Options []Option -func (opts Options) filter(s *state, vx, vy reflect.Value, t reflect.Type) (out applicableOption) { +func (opts Options) filter(s *state, t reflect.Type, vx, vy reflect.Value) (out applicableOption) { for _, opt := range opts { - switch opt := opt.filter(s, vx, vy, t); opt.(type) { + switch opt := opt.filter(s, t, vx, vy); opt.(type) { case ignore: return ignore{} // Only ignore can short-circuit evaluation - case invalid: - out = invalid{} // Takes precedence over comparer or transformer + case validator: + out = validator{} // Takes precedence over comparer or transformer case *comparer, *transformer, Options: switch out.(type) { case nil: out = opt - case invalid: - // Keep invalid + case validator: + // Keep validator case *comparer, *transformer, Options: out = Options{out, opt} // Conflicting comparers or transformers } @@ -106,6 +106,11 @@ func (opts Options) String() string { // FilterPath returns a new Option where opt is only evaluated if filter f // returns true for the current Path in the value tree. // +// This filter is called even if a slice element or map entry is missing and +// provides an opportunity to ignore such cases. The filter function must be +// symmetric such that the filter result is identical regardless of whether the +// missing value is from x or y. +// // The option passed in may be an Ignore, Transformer, Comparer, Options, or // a previously filtered Option. func FilterPath(f func(Path) bool, opt Option) Option { @@ -124,22 +129,22 @@ type pathFilter struct { opt Option } -func (f pathFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption { +func (f pathFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption { if f.fnc(s.curPath) { - return f.opt.filter(s, vx, vy, t) + return f.opt.filter(s, t, vx, vy) } return nil } func (f pathFilter) String() string { - fn := getFuncName(reflect.ValueOf(f.fnc).Pointer()) - return fmt.Sprintf("FilterPath(%s, %v)", fn, f.opt) + return fmt.Sprintf("FilterPath(%s, %v)", function.NameOf(reflect.ValueOf(f.fnc)), f.opt) } // FilterValues returns a new Option where opt is only evaluated if filter f, // which is a function of the form "func(T, T) bool", returns true for the -// current pair of values being compared. If the type of the values is not -// assignable to T, then this filter implicitly returns false. +// current pair of values being compared. If either value is invalid or +// the type of the values is not assignable to T, then this filter implicitly +// returns false. // // The filter function must be // symmetric (i.e., agnostic to the order of the inputs) and @@ -171,19 +176,18 @@ type valuesFilter struct { opt Option } -func (f valuesFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption { - if !vx.IsValid() || !vy.IsValid() { - return invalid{} +func (f valuesFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption { + if !vx.IsValid() || !vx.CanInterface() || !vy.IsValid() || !vy.CanInterface() { + return nil } if (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) { - return f.opt.filter(s, vx, vy, t) + return f.opt.filter(s, t, vx, vy) } return nil } func (f valuesFilter) String() string { - fn := getFuncName(f.fnc.Pointer()) - return fmt.Sprintf("FilterValues(%s, %v)", fn, f.opt) + return fmt.Sprintf("FilterValues(%s, %v)", function.NameOf(f.fnc), f.opt) } // Ignore is an Option that causes all comparisons to be ignored. @@ -194,19 +198,44 @@ func Ignore() Option { return ignore{} } type ignore struct{ core } func (ignore) isFiltered() bool { return false } -func (ignore) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return ignore{} } -func (ignore) apply(_ *state, _, _ reflect.Value) { return } +func (ignore) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { return ignore{} } +func (ignore) apply(s *state, _, _ reflect.Value) { s.report(true, reportByIgnore) } func (ignore) String() string { return "Ignore()" } -// invalid is a sentinel Option type to indicate that some options could not -// be evaluated due to unexported fields. -type invalid struct{ core } +// validator is a sentinel Option type to indicate that some options could not +// be evaluated due to unexported fields, missing slice elements, or +// missing map entries. Both values are validator only for unexported fields. +type validator struct{ core } -func (invalid) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return invalid{} } -func (invalid) apply(s *state, _, _ reflect.Value) { - const help = "consider using AllowUnexported or cmpopts.IgnoreUnexported" - panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help)) +func (validator) filter(_ *state, _ reflect.Type, vx, vy reflect.Value) applicableOption { + if !vx.IsValid() || !vy.IsValid() { + return validator{} + } + if !vx.CanInterface() || !vy.CanInterface() { + return validator{} + } + return nil } +func (validator) apply(s *state, vx, vy reflect.Value) { + // Implies missing slice element or map entry. + if !vx.IsValid() || !vy.IsValid() { + s.report(vx.IsValid() == vy.IsValid(), 0) + return + } + + // Unable to Interface implies unexported field without visibility access. + if !vx.CanInterface() || !vy.CanInterface() { + const help = "consider using a custom Comparer; if you control the implementation of type, you can also consider AllowUnexported or cmpopts.IgnoreUnexported" + panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help)) + } + + panic("not reachable") +} + +// identRx represents a valid identifier according to the Go specification. +const identRx = `[_\p{L}][_\p{L}\p{N}]*` + +var identsRx = regexp.MustCompile(`^` + identRx + `(\.` + identRx + `)*$`) // Transformer returns an Option that applies a transformation function that // converts values of a certain type into that of another. @@ -220,18 +249,25 @@ func (invalid) apply(s *state, _, _ reflect.Value) { // input and output types are the same), an implicit filter is added such that // a transformer is applicable only if that exact transformer is not already // in the tail of the Path since the last non-Transform step. +// For situations where the implicit filter is still insufficient, +// consider using cmpopts.AcyclicTransformer, which adds a filter +// to prevent the transformer from being recursively applied upon itself. // // The name is a user provided label that is used as the Transform.Name in the -// transformation PathStep. If empty, an arbitrary name is used. +// transformation PathStep (and eventually shown in the Diff output). +// The name must be a valid identifier or qualified identifier in Go syntax. +// If empty, an arbitrary name is used. func Transformer(name string, f interface{}) Option { v := reflect.ValueOf(f) if !function.IsType(v.Type(), function.Transformer) || v.IsNil() { panic(fmt.Sprintf("invalid transformer function: %T", f)) } if name == "" { - name = "λ" // Lambda-symbol as place-holder for anonymous transformer - } - if !isValid(name) { + name = function.NameOf(v) + if !identsRx.MatchString(name) { + name = "λ" // Lambda-symbol as placeholder name + } + } else if !identsRx.MatchString(name) { panic(fmt.Sprintf("invalid name: %q", name)) } tr := &transformer{name: name, fnc: reflect.ValueOf(f)} @@ -250,9 +286,9 @@ type transformer struct { func (tr *transformer) isFiltered() bool { return tr.typ != nil } -func (tr *transformer) filter(s *state, _, _ reflect.Value, t reflect.Type) applicableOption { +func (tr *transformer) filter(s *state, t reflect.Type, _, _ reflect.Value) applicableOption { for i := len(s.curPath) - 1; i >= 0; i-- { - if t, ok := s.curPath[i].(*transform); !ok { + if t, ok := s.curPath[i].(Transform); !ok { break // Hit most recent non-Transform step } else if tr == t.trans { return nil // Cannot directly use same Transform @@ -265,18 +301,15 @@ func (tr *transformer) filter(s *state, _, _ reflect.Value, t reflect.Type) appl } func (tr *transformer) apply(s *state, vx, vy reflect.Value) { - // Update path before calling the Transformer so that dynamic checks - // will use the updated path. - s.curPath.push(&transform{pathStep{tr.fnc.Type().Out(0)}, tr}) - defer s.curPath.pop() - - vx = s.callTRFunc(tr.fnc, vx) - vy = s.callTRFunc(tr.fnc, vy) - s.compareAny(vx, vy) + step := Transform{&transform{pathStep{typ: tr.fnc.Type().Out(0)}, tr}} + vvx := s.callTRFunc(tr.fnc, vx, step) + vvy := s.callTRFunc(tr.fnc, vy, step) + step.vx, step.vy = vvx, vvy + s.compareAny(step) } func (tr transformer) String() string { - return fmt.Sprintf("Transformer(%s, %s)", tr.name, getFuncName(tr.fnc.Pointer())) + return fmt.Sprintf("Transformer(%s, %s)", tr.name, function.NameOf(tr.fnc)) } // Comparer returns an Option that determines whether two values are equal @@ -311,7 +344,7 @@ type comparer struct { func (cm *comparer) isFiltered() bool { return cm.typ != nil } -func (cm *comparer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption { +func (cm *comparer) filter(_ *state, t reflect.Type, _, _ reflect.Value) applicableOption { if cm.typ == nil || t.AssignableTo(cm.typ) { return cm } @@ -320,11 +353,11 @@ func (cm *comparer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applica func (cm *comparer) apply(s *state, vx, vy reflect.Value) { eq := s.callTTBFunc(cm.fnc, vx, vy) - s.report(eq, vx, vy) + s.report(eq, reportByFunc) } func (cm comparer) String() string { - return fmt.Sprintf("Comparer(%s)", getFuncName(cm.fnc.Pointer())) + return fmt.Sprintf("Comparer(%s)", function.NameOf(cm.fnc)) } // AllowUnexported returns an Option that forcibly allows operations on @@ -338,7 +371,7 @@ func (cm comparer) String() string { // defined in an internal package where the semantic meaning of an unexported // field is in the control of the user. // -// For some cases, a custom Comparer should be used instead that defines +// In many cases, a custom Comparer should be used instead that defines // equality as a function of the public API of a type rather than the underlying // unexported implementation. // @@ -370,27 +403,92 @@ func AllowUnexported(types ...interface{}) Option { type visibleStructs map[reflect.Type]bool -func (visibleStructs) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { +func (visibleStructs) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { panic("not implemented") } -// reporter is an Option that configures how differences are reported. -type reporter interface { - // TODO: Not exported yet. +// Result represents the comparison result for a single node and +// is provided by cmp when calling Result (see Reporter). +type Result struct { + _ [0]func() // Make Result incomparable + flags resultFlags +} + +// Equal reports whether the node was determined to be equal or not. +// As a special case, ignored nodes are considered equal. +func (r Result) Equal() bool { + return r.flags&(reportEqual|reportByIgnore) != 0 +} + +// ByIgnore reports whether the node is equal because it was ignored. +// This never reports true if Equal reports false. +func (r Result) ByIgnore() bool { + return r.flags&reportByIgnore != 0 +} + +// ByMethod reports whether the Equal method determined equality. +func (r Result) ByMethod() bool { + return r.flags&reportByMethod != 0 +} + +// ByFunc reports whether a Comparer function determined equality. +func (r Result) ByFunc() bool { + return r.flags&reportByFunc != 0 +} + +type resultFlags uint + +const ( + _ resultFlags = (1 << iota) / 2 + + reportEqual + reportUnequal + reportByIgnore + reportByMethod + reportByFunc +) + +// Reporter is an Option that can be passed to Equal. When Equal traverses +// the value trees, it calls PushStep as it descends into each node in the +// tree and PopStep as it ascend out of the node. The leaves of the tree are +// either compared (determined to be equal or not equal) or ignored and reported +// as such by calling the Report method. +func Reporter(r interface { + // PushStep is called when a tree-traversal operation is performed. + // The PathStep itself is only valid until the step is popped. + // The PathStep.Values are valid for the duration of the entire traversal + // and must not be mutated. // - // Perhaps add PushStep and PopStep and change Report to only accept - // a PathStep instead of the full-path? Adding a PushStep and PopStep makes - // it clear that we are traversing the value tree in a depth-first-search - // manner, which has an effect on how values are printed. + // Equal always calls PushStep at the start to provide an operation-less + // PathStep used to report the root values. + // + // Within a slice, the exact set of inserted, removed, or modified elements + // is unspecified and may change in future implementations. + // The entries of a map are iterated through in an unspecified order. + PushStep(PathStep) - Option + // Report is called exactly once on leaf nodes to report whether the + // comparison identified the node as equal, unequal, or ignored. + // A leaf node is one that is immediately preceded by and followed by + // a pair of PushStep and PopStep calls. + Report(Result) - // Report is called for every comparison made and will be provided with - // the two values being compared, the equality result, and the - // current path in the value tree. It is possible for x or y to be an - // invalid reflect.Value if one of the values is non-existent; - // which is possible with maps and slices. - Report(x, y reflect.Value, eq bool, p Path) + // PopStep ascends back up the value tree. + // There is always a matching pop call for every push call. + PopStep() +}) Option { + return reporter{r} +} + +type reporter struct{ reporterIface } +type reporterIface interface { + PushStep(PathStep) + Report(Result) + PopStep() +} + +func (reporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { + panic("not implemented") } // normalizeOption normalizes the input options such that all Options groups @@ -424,30 +522,3 @@ func flattenOptions(dst, src Options) Options { } return dst } - -// getFuncName returns a short function name from the pointer. -// The string parsing logic works up until Go1.9. -func getFuncName(p uintptr) string { - fnc := runtime.FuncForPC(p) - if fnc == nil { - return "" - } - name := fnc.Name() // E.g., "long/path/name/mypkg.(mytype).(long/path/name/mypkg.myfunc)-fm" - if strings.HasSuffix(name, ")-fm") || strings.HasSuffix(name, ")·fm") { - // Strip the package name from method name. - name = strings.TrimSuffix(name, ")-fm") - name = strings.TrimSuffix(name, ")·fm") - if i := strings.LastIndexByte(name, '('); i >= 0 { - methodName := name[i+1:] // E.g., "long/path/name/mypkg.myfunc" - if j := strings.LastIndexByte(methodName, '.'); j >= 0 { - methodName = methodName[j+1:] // E.g., "myfunc" - } - name = name[:i] + methodName // E.g., "long/path/name/mypkg.(mytype)." + "myfunc" - } - } - if i := strings.LastIndexByte(name, '/'); i >= 0 { - // Strip the package name. - name = name[i+1:] // E.g., "mypkg.(mytype).myfunc" - } - return name -} diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go index c08a3cf80..96fffd291 100644 --- a/vendor/github.com/google/go-cmp/cmp/path.go +++ b/vendor/github.com/google/go-cmp/cmp/path.go @@ -12,80 +12,52 @@ import ( "unicode/utf8" ) -type ( - // Path is a list of PathSteps describing the sequence of operations to get - // from some root type to the current position in the value tree. - // The first Path element is always an operation-less PathStep that exists - // simply to identify the initial type. +// Path is a list of PathSteps describing the sequence of operations to get +// from some root type to the current position in the value tree. +// The first Path element is always an operation-less PathStep that exists +// simply to identify the initial type. +// +// When traversing structs with embedded structs, the embedded struct will +// always be accessed as a field before traversing the fields of the +// embedded struct themselves. That is, an exported field from the +// embedded struct will never be accessed directly from the parent struct. +type Path []PathStep + +// PathStep is a union-type for specific operations to traverse +// a value's tree structure. Users of this package never need to implement +// these types as values of this type will be returned by this package. +// +// Implementations of this interface are +// StructField, SliceIndex, MapIndex, Indirect, TypeAssertion, and Transform. +type PathStep interface { + String() string + + // Type is the resulting type after performing the path step. + Type() reflect.Type + + // Values is the resulting values after performing the path step. + // The type of each valid value is guaranteed to be identical to Type. // - // When traversing structs with embedded structs, the embedded struct will - // always be accessed as a field before traversing the fields of the - // embedded struct themselves. That is, an exported field from the - // embedded struct will never be accessed directly from the parent struct. - Path []PathStep + // In some cases, one or both may be invalid or have restrictions: + // • For StructField, both are not interface-able if the current field + // is unexported and the struct type is not explicitly permitted by + // AllowUnexported to traverse unexported fields. + // • For SliceIndex, one may be invalid if an element is missing from + // either the x or y slice. + // • For MapIndex, one may be invalid if an entry is missing from + // either the x or y map. + // + // The provided values must not be mutated. + Values() (vx, vy reflect.Value) +} - // PathStep is a union-type for specific operations to traverse - // a value's tree structure. Users of this package never need to implement - // these types as values of this type will be returned by this package. - PathStep interface { - String() string - Type() reflect.Type // Resulting type after performing the path step - isPathStep() - } - - // SliceIndex is an index operation on a slice or array at some index Key. - SliceIndex interface { - PathStep - Key() int // May return -1 if in a split state - - // SplitKeys returns the indexes for indexing into slices in the - // x and y values, respectively. These indexes may differ due to the - // insertion or removal of an element in one of the slices, causing - // all of the indexes to be shifted. If an index is -1, then that - // indicates that the element does not exist in the associated slice. - // - // Key is guaranteed to return -1 if and only if the indexes returned - // by SplitKeys are not the same. SplitKeys will never return -1 for - // both indexes. - SplitKeys() (x int, y int) - - isSliceIndex() - } - // MapIndex is an index operation on a map at some index Key. - MapIndex interface { - PathStep - Key() reflect.Value - isMapIndex() - } - // TypeAssertion represents a type assertion on an interface. - TypeAssertion interface { - PathStep - isTypeAssertion() - } - // StructField represents a struct field access on a field called Name. - StructField interface { - PathStep - Name() string - Index() int - isStructField() - } - // Indirect represents pointer indirection on the parent type. - Indirect interface { - PathStep - isIndirect() - } - // Transform is a transformation from the parent type to the current type. - Transform interface { - PathStep - Name() string - Func() reflect.Value - - // Option returns the originally constructed Transformer option. - // The == operator can be used to detect the exact option used. - Option() Option - - isTransform() - } +var ( + _ PathStep = StructField{} + _ PathStep = SliceIndex{} + _ PathStep = MapIndex{} + _ PathStep = Indirect{} + _ PathStep = TypeAssertion{} + _ PathStep = Transform{} ) func (pa *Path) push(s PathStep) { @@ -124,7 +96,7 @@ func (pa Path) Index(i int) PathStep { func (pa Path) String() string { var ss []string for _, s := range pa { - if _, ok := s.(*structField); ok { + if _, ok := s.(StructField); ok { ss = append(ss, s.String()) } } @@ -144,13 +116,13 @@ func (pa Path) GoString() string { nextStep = pa[i+1] } switch s := s.(type) { - case *indirect: + case Indirect: numIndirect++ pPre, pPost := "(", ")" switch nextStep.(type) { - case *indirect: + case Indirect: continue // Next step is indirection, so let them batch up - case *structField: + case StructField: numIndirect-- // Automatic indirection on struct fields case nil: pPre, pPost = "", "" // Last step; no need for parenthesis @@ -161,19 +133,10 @@ func (pa Path) GoString() string { } numIndirect = 0 continue - case *transform: + case Transform: ssPre = append(ssPre, s.trans.name+"(") ssPost = append(ssPost, ")") continue - case *typeAssertion: - // As a special-case, elide type assertions on anonymous types - // since they are typically generated dynamically and can be very - // verbose. For example, some transforms return interface{} because - // of Go's lack of generics, but typically take in and return the - // exact same concrete type. - if s.Type().PkgPath() == "" { - continue - } } ssPost = append(ssPost, s.String()) } @@ -183,44 +146,13 @@ func (pa Path) GoString() string { return strings.Join(ssPre, "") + strings.Join(ssPost, "") } -type ( - pathStep struct { - typ reflect.Type - } +type pathStep struct { + typ reflect.Type + vx, vy reflect.Value +} - sliceIndex struct { - pathStep - xkey, ykey int - } - mapIndex struct { - pathStep - key reflect.Value - } - typeAssertion struct { - pathStep - } - structField struct { - pathStep - name string - idx int - - // These fields are used for forcibly accessing an unexported field. - // pvx, pvy, and field are only valid if unexported is true. - unexported bool - force bool // Forcibly allow visibility - pvx, pvy reflect.Value // Parent values - field reflect.StructField // Field information - } - indirect struct { - pathStep - } - transform struct { - pathStep - trans *transformer - } -) - -func (ps pathStep) Type() reflect.Type { return ps.typ } +func (ps pathStep) Type() reflect.Type { return ps.typ } +func (ps pathStep) Values() (vx, vy reflect.Value) { return ps.vx, ps.vy } func (ps pathStep) String() string { if ps.typ == nil { return "" @@ -232,7 +164,54 @@ func (ps pathStep) String() string { return fmt.Sprintf("{%s}", s) } -func (si sliceIndex) String() string { +// StructField represents a struct field access on a field called Name. +type StructField struct{ *structField } +type structField struct { + pathStep + name string + idx int + + // These fields are used for forcibly accessing an unexported field. + // pvx, pvy, and field are only valid if unexported is true. + unexported bool + mayForce bool // Forcibly allow visibility + pvx, pvy reflect.Value // Parent values + field reflect.StructField // Field information +} + +func (sf StructField) Type() reflect.Type { return sf.typ } +func (sf StructField) Values() (vx, vy reflect.Value) { + if !sf.unexported { + return sf.vx, sf.vy // CanInterface reports true + } + + // Forcibly obtain read-write access to an unexported struct field. + if sf.mayForce { + vx = retrieveUnexportedField(sf.pvx, sf.field) + vy = retrieveUnexportedField(sf.pvy, sf.field) + return vx, vy // CanInterface reports true + } + return sf.vx, sf.vy // CanInterface reports false +} +func (sf StructField) String() string { return fmt.Sprintf(".%s", sf.name) } + +// Name is the field name. +func (sf StructField) Name() string { return sf.name } + +// Index is the index of the field in the parent struct type. +// See reflect.Type.Field. +func (sf StructField) Index() int { return sf.idx } + +// SliceIndex is an index operation on a slice or array at some index Key. +type SliceIndex struct{ *sliceIndex } +type sliceIndex struct { + pathStep + xkey, ykey int +} + +func (si SliceIndex) Type() reflect.Type { return si.typ } +func (si SliceIndex) Values() (vx, vy reflect.Value) { return si.vx, si.vy } +func (si SliceIndex) String() string { switch { case si.xkey == si.ykey: return fmt.Sprintf("[%d]", si.xkey) @@ -247,63 +226,83 @@ func (si sliceIndex) String() string { return fmt.Sprintf("[%d->%d]", si.xkey, si.ykey) } } -func (mi mapIndex) String() string { return fmt.Sprintf("[%#v]", mi.key) } -func (ta typeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) } -func (sf structField) String() string { return fmt.Sprintf(".%s", sf.name) } -func (in indirect) String() string { return "*" } -func (tf transform) String() string { return fmt.Sprintf("%s()", tf.trans.name) } -func (si sliceIndex) Key() int { +// Key is the index key; it may return -1 if in a split state +func (si SliceIndex) Key() int { if si.xkey != si.ykey { return -1 } return si.xkey } -func (si sliceIndex) SplitKeys() (x, y int) { return si.xkey, si.ykey } -func (mi mapIndex) Key() reflect.Value { return mi.key } -func (sf structField) Name() string { return sf.name } -func (sf structField) Index() int { return sf.idx } -func (tf transform) Name() string { return tf.trans.name } -func (tf transform) Func() reflect.Value { return tf.trans.fnc } -func (tf transform) Option() Option { return tf.trans } -func (pathStep) isPathStep() {} -func (sliceIndex) isSliceIndex() {} -func (mapIndex) isMapIndex() {} -func (typeAssertion) isTypeAssertion() {} -func (structField) isStructField() {} -func (indirect) isIndirect() {} -func (transform) isTransform() {} +// SplitKeys are the indexes for indexing into slices in the +// x and y values, respectively. These indexes may differ due to the +// insertion or removal of an element in one of the slices, causing +// all of the indexes to be shifted. If an index is -1, then that +// indicates that the element does not exist in the associated slice. +// +// Key is guaranteed to return -1 if and only if the indexes returned +// by SplitKeys are not the same. SplitKeys will never return -1 for +// both indexes. +func (si SliceIndex) SplitKeys() (ix, iy int) { return si.xkey, si.ykey } -var ( - _ SliceIndex = sliceIndex{} - _ MapIndex = mapIndex{} - _ TypeAssertion = typeAssertion{} - _ StructField = structField{} - _ Indirect = indirect{} - _ Transform = transform{} +// MapIndex is an index operation on a map at some index Key. +type MapIndex struct{ *mapIndex } +type mapIndex struct { + pathStep + key reflect.Value +} - _ PathStep = sliceIndex{} - _ PathStep = mapIndex{} - _ PathStep = typeAssertion{} - _ PathStep = structField{} - _ PathStep = indirect{} - _ PathStep = transform{} -) +func (mi MapIndex) Type() reflect.Type { return mi.typ } +func (mi MapIndex) Values() (vx, vy reflect.Value) { return mi.vx, mi.vy } +func (mi MapIndex) String() string { return fmt.Sprintf("[%#v]", mi.key) } + +// Key is the value of the map key. +func (mi MapIndex) Key() reflect.Value { return mi.key } + +// Indirect represents pointer indirection on the parent type. +type Indirect struct{ *indirect } +type indirect struct { + pathStep +} + +func (in Indirect) Type() reflect.Type { return in.typ } +func (in Indirect) Values() (vx, vy reflect.Value) { return in.vx, in.vy } +func (in Indirect) String() string { return "*" } + +// TypeAssertion represents a type assertion on an interface. +type TypeAssertion struct{ *typeAssertion } +type typeAssertion struct { + pathStep +} + +func (ta TypeAssertion) Type() reflect.Type { return ta.typ } +func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy } +func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) } + +// Transform is a transformation from the parent type to the current type. +type Transform struct{ *transform } +type transform struct { + pathStep + trans *transformer +} + +func (tf Transform) Type() reflect.Type { return tf.typ } +func (tf Transform) Values() (vx, vy reflect.Value) { return tf.vx, tf.vy } +func (tf Transform) String() string { return fmt.Sprintf("%s()", tf.trans.name) } + +// Name is the name of the Transformer. +func (tf Transform) Name() string { return tf.trans.name } + +// Func is the function pointer to the transformer function. +func (tf Transform) Func() reflect.Value { return tf.trans.fnc } + +// Option returns the originally constructed Transformer option. +// The == operator can be used to detect the exact option used. +func (tf Transform) Option() Option { return tf.trans } // isExported reports whether the identifier is exported. func isExported(id string) bool { r, _ := utf8.DecodeRuneInString(id) return unicode.IsUpper(r) } - -// isValid reports whether the identifier is valid. -// Empty and underscore-only strings are not valid. -func isValid(id string) bool { - ok := id != "" && id != "_" - for j, c := range id { - ok = ok && (j > 0 || !unicode.IsDigit(c)) - ok = ok && (c == '_' || unicode.IsLetter(c) || unicode.IsDigit(c)) - } - return ok -} diff --git a/vendor/github.com/google/go-cmp/cmp/report.go b/vendor/github.com/google/go-cmp/cmp/report.go new file mode 100644 index 000000000..6ddf29993 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/report.go @@ -0,0 +1,51 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +// defaultReporter implements the reporter interface. +// +// As Equal serially calls the PushStep, Report, and PopStep methods, the +// defaultReporter constructs a tree-based representation of the compared value +// and the result of each comparison (see valueNode). +// +// When the String method is called, the FormatDiff method transforms the +// valueNode tree into a textNode tree, which is a tree-based representation +// of the textual output (see textNode). +// +// Lastly, the textNode.String method produces the final report as a string. +type defaultReporter struct { + root *valueNode + curr *valueNode +} + +func (r *defaultReporter) PushStep(ps PathStep) { + r.curr = r.curr.PushStep(ps) + if r.root == nil { + r.root = r.curr + } +} +func (r *defaultReporter) Report(rs Result) { + r.curr.Report(rs) +} +func (r *defaultReporter) PopStep() { + r.curr = r.curr.PopStep() +} + +// String provides a full report of the differences detected as a structured +// literal in pseudo-Go syntax. String may only be called after the entire tree +// has been traversed. +func (r *defaultReporter) String() string { + assert(r.root != nil && r.curr == nil) + if r.root.NumDiff == 0 { + return "" + } + return formatOptions{}.FormatDiff(r.root).String() +} + +func assert(ok bool) { + if !ok { + panic("assertion failure") + } +} diff --git a/vendor/github.com/google/go-cmp/cmp/report_compare.go b/vendor/github.com/google/go-cmp/cmp/report_compare.go new file mode 100644 index 000000000..05efb992c --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/report_compare.go @@ -0,0 +1,296 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +import ( + "fmt" + "reflect" + + "github.com/google/go-cmp/cmp/internal/value" +) + +// TODO: Enforce limits? +// * Enforce maximum number of records to print per node? +// * Enforce maximum size in bytes allowed? +// * As a heuristic, use less verbosity for equal nodes than unequal nodes. +// TODO: Enforce unique outputs? +// * Avoid Stringer methods if it results in same output? +// * Print pointer address if outputs still equal? + +// numContextRecords is the number of surrounding equal records to print. +const numContextRecords = 2 + +type diffMode byte + +const ( + diffUnknown diffMode = 0 + diffIdentical diffMode = ' ' + diffRemoved diffMode = '-' + diffInserted diffMode = '+' +) + +type typeMode int + +const ( + // emitType always prints the type. + emitType typeMode = iota + // elideType never prints the type. + elideType + // autoType prints the type only for composite kinds + // (i.e., structs, slices, arrays, and maps). + autoType +) + +type formatOptions struct { + // DiffMode controls the output mode of FormatDiff. + // + // If diffUnknown, then produce a diff of the x and y values. + // If diffIdentical, then emit values as if they were equal. + // If diffRemoved, then only emit x values (ignoring y values). + // If diffInserted, then only emit y values (ignoring x values). + DiffMode diffMode + + // TypeMode controls whether to print the type for the current node. + // + // As a general rule of thumb, we always print the type of the next node + // after an interface, and always elide the type of the next node after + // a slice or map node. + TypeMode typeMode + + // formatValueOptions are options specific to printing reflect.Values. + formatValueOptions +} + +func (opts formatOptions) WithDiffMode(d diffMode) formatOptions { + opts.DiffMode = d + return opts +} +func (opts formatOptions) WithTypeMode(t typeMode) formatOptions { + opts.TypeMode = t + return opts +} + +// FormatDiff converts a valueNode tree into a textNode tree, where the later +// is a textual representation of the differences detected in the former. +func (opts formatOptions) FormatDiff(v *valueNode) textNode { + // Check whether we have specialized formatting for this node. + // This is not necessary, but helpful for producing more readable outputs. + if opts.CanFormatDiffSlice(v) { + return opts.FormatDiffSlice(v) + } + + // For leaf nodes, format the value based on the reflect.Values alone. + if v.MaxDepth == 0 { + switch opts.DiffMode { + case diffUnknown, diffIdentical: + // Format Equal. + if v.NumDiff == 0 { + outx := opts.FormatValue(v.ValueX, visitedPointers{}) + outy := opts.FormatValue(v.ValueY, visitedPointers{}) + if v.NumIgnored > 0 && v.NumSame == 0 { + return textEllipsis + } else if outx.Len() < outy.Len() { + return outx + } else { + return outy + } + } + + // Format unequal. + assert(opts.DiffMode == diffUnknown) + var list textList + outx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, visitedPointers{}) + outy := opts.WithTypeMode(elideType).FormatValue(v.ValueY, visitedPointers{}) + if outx != nil { + list = append(list, textRecord{Diff: '-', Value: outx}) + } + if outy != nil { + list = append(list, textRecord{Diff: '+', Value: outy}) + } + return opts.WithTypeMode(emitType).FormatType(v.Type, list) + case diffRemoved: + return opts.FormatValue(v.ValueX, visitedPointers{}) + case diffInserted: + return opts.FormatValue(v.ValueY, visitedPointers{}) + default: + panic("invalid diff mode") + } + } + + // Descend into the child value node. + if v.TransformerName != "" { + out := opts.WithTypeMode(emitType).FormatDiff(v.Value) + out = textWrap{"Inverse(" + v.TransformerName + ", ", out, ")"} + return opts.FormatType(v.Type, out) + } else { + switch k := v.Type.Kind(); k { + case reflect.Struct, reflect.Array, reflect.Slice, reflect.Map: + return opts.FormatType(v.Type, opts.formatDiffList(v.Records, k)) + case reflect.Ptr: + return textWrap{"&", opts.FormatDiff(v.Value), ""} + case reflect.Interface: + return opts.WithTypeMode(emitType).FormatDiff(v.Value) + default: + panic(fmt.Sprintf("%v cannot have children", k)) + } + } +} + +func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind) textNode { + // Derive record name based on the data structure kind. + var name string + var formatKey func(reflect.Value) string + switch k { + case reflect.Struct: + name = "field" + opts = opts.WithTypeMode(autoType) + formatKey = func(v reflect.Value) string { return v.String() } + case reflect.Slice, reflect.Array: + name = "element" + opts = opts.WithTypeMode(elideType) + formatKey = func(reflect.Value) string { return "" } + case reflect.Map: + name = "entry" + opts = opts.WithTypeMode(elideType) + formatKey = formatMapKey + } + + // Handle unification. + switch opts.DiffMode { + case diffIdentical, diffRemoved, diffInserted: + var list textList + var deferredEllipsis bool // Add final "..." to indicate records were dropped + for _, r := range recs { + // Elide struct fields that are zero value. + if k == reflect.Struct { + var isZero bool + switch opts.DiffMode { + case diffIdentical: + isZero = value.IsZero(r.Value.ValueX) || value.IsZero(r.Value.ValueX) + case diffRemoved: + isZero = value.IsZero(r.Value.ValueX) + case diffInserted: + isZero = value.IsZero(r.Value.ValueY) + } + if isZero { + continue + } + } + // Elide ignored nodes. + if r.Value.NumIgnored > 0 && r.Value.NumSame+r.Value.NumDiff == 0 { + deferredEllipsis = !(k == reflect.Slice || k == reflect.Array) + if !deferredEllipsis { + list.AppendEllipsis(diffStats{}) + } + continue + } + if out := opts.FormatDiff(r.Value); out != nil { + list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) + } + } + if deferredEllipsis { + list.AppendEllipsis(diffStats{}) + } + return textWrap{"{", list, "}"} + case diffUnknown: + default: + panic("invalid diff mode") + } + + // Handle differencing. + var list textList + groups := coalesceAdjacentRecords(name, recs) + for i, ds := range groups { + // Handle equal records. + if ds.NumDiff() == 0 { + // Compute the number of leading and trailing records to print. + var numLo, numHi int + numEqual := ds.NumIgnored + ds.NumIdentical + for numLo < numContextRecords && numLo+numHi < numEqual && i != 0 { + if r := recs[numLo].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 { + break + } + numLo++ + } + for numHi < numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 { + if r := recs[numEqual-numHi-1].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 { + break + } + numHi++ + } + if numEqual-(numLo+numHi) == 1 && ds.NumIgnored == 0 { + numHi++ // Avoid pointless coalescing of a single equal record + } + + // Format the equal values. + for _, r := range recs[:numLo] { + out := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value) + list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) + } + if numEqual > numLo+numHi { + ds.NumIdentical -= numLo + numHi + list.AppendEllipsis(ds) + } + for _, r := range recs[numEqual-numHi : numEqual] { + out := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value) + list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) + } + recs = recs[numEqual:] + continue + } + + // Handle unequal records. + for _, r := range recs[:ds.NumDiff()] { + switch { + case opts.CanFormatDiffSlice(r.Value): + out := opts.FormatDiffSlice(r.Value) + list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) + case r.Value.NumChildren == r.Value.MaxDepth: + outx := opts.WithDiffMode(diffRemoved).FormatDiff(r.Value) + outy := opts.WithDiffMode(diffInserted).FormatDiff(r.Value) + if outx != nil { + list = append(list, textRecord{Diff: diffRemoved, Key: formatKey(r.Key), Value: outx}) + } + if outy != nil { + list = append(list, textRecord{Diff: diffInserted, Key: formatKey(r.Key), Value: outy}) + } + default: + out := opts.FormatDiff(r.Value) + list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) + } + } + recs = recs[ds.NumDiff():] + } + assert(len(recs) == 0) + return textWrap{"{", list, "}"} +} + +// coalesceAdjacentRecords coalesces the list of records into groups of +// adjacent equal, or unequal counts. +func coalesceAdjacentRecords(name string, recs []reportRecord) (groups []diffStats) { + var prevCase int // Arbitrary index into which case last occurred + lastStats := func(i int) *diffStats { + if prevCase != i { + groups = append(groups, diffStats{Name: name}) + prevCase = i + } + return &groups[len(groups)-1] + } + for _, r := range recs { + switch rv := r.Value; { + case rv.NumIgnored > 0 && rv.NumSame+rv.NumDiff == 0: + lastStats(1).NumIgnored++ + case rv.NumDiff == 0: + lastStats(1).NumIdentical++ + case rv.NumDiff > 0 && !rv.ValueY.IsValid(): + lastStats(2).NumRemoved++ + case rv.NumDiff > 0 && !rv.ValueX.IsValid(): + lastStats(2).NumInserted++ + default: + lastStats(2).NumModified++ + } + } + return groups +} diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go new file mode 100644 index 000000000..5521c604c --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/report_reflect.go @@ -0,0 +1,279 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +import ( + "fmt" + "reflect" + "strconv" + "strings" + "unicode" + + "github.com/google/go-cmp/cmp/internal/flags" + "github.com/google/go-cmp/cmp/internal/value" +) + +type formatValueOptions struct { + // AvoidStringer controls whether to avoid calling custom stringer + // methods like error.Error or fmt.Stringer.String. + AvoidStringer bool + + // ShallowPointers controls whether to avoid descending into pointers. + // Useful when printing map keys, where pointer comparison is performed + // on the pointer address rather than the pointed-at value. + ShallowPointers bool + + // PrintAddresses controls whether to print the address of all pointers, + // slice elements, and maps. + PrintAddresses bool +} + +// FormatType prints the type as if it were wrapping s. +// This may return s as-is depending on the current type and TypeMode mode. +func (opts formatOptions) FormatType(t reflect.Type, s textNode) textNode { + // Check whether to emit the type or not. + switch opts.TypeMode { + case autoType: + switch t.Kind() { + case reflect.Struct, reflect.Slice, reflect.Array, reflect.Map: + if s.Equal(textNil) { + return s + } + default: + return s + } + case elideType: + return s + } + + // Determine the type label, applying special handling for unnamed types. + typeName := t.String() + if t.Name() == "" { + // According to Go grammar, certain type literals contain symbols that + // do not strongly bind to the next lexicographical token (e.g., *T). + switch t.Kind() { + case reflect.Chan, reflect.Func, reflect.Ptr: + typeName = "(" + typeName + ")" + } + typeName = strings.Replace(typeName, "struct {", "struct{", -1) + typeName = strings.Replace(typeName, "interface {", "interface{", -1) + } + + // Avoid wrap the value in parenthesis if unnecessary. + if s, ok := s.(textWrap); ok { + hasParens := strings.HasPrefix(s.Prefix, "(") && strings.HasSuffix(s.Suffix, ")") + hasBraces := strings.HasPrefix(s.Prefix, "{") && strings.HasSuffix(s.Suffix, "}") + if hasParens || hasBraces { + return textWrap{typeName, s, ""} + } + } + return textWrap{typeName + "(", s, ")"} +} + +// FormatValue prints the reflect.Value, taking extra care to avoid descending +// into pointers already in m. As pointers are visited, m is also updated. +func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out textNode) { + if !v.IsValid() { + return nil + } + t := v.Type() + + // Check whether there is an Error or String method to call. + if !opts.AvoidStringer && v.CanInterface() { + // Avoid calling Error or String methods on nil receivers since many + // implementations crash when doing so. + if (t.Kind() != reflect.Ptr && t.Kind() != reflect.Interface) || !v.IsNil() { + switch v := v.Interface().(type) { + case error: + return textLine("e" + formatString(v.Error())) + case fmt.Stringer: + return textLine("s" + formatString(v.String())) + } + } + } + + // Check whether to explicitly wrap the result with the type. + var skipType bool + defer func() { + if !skipType { + out = opts.FormatType(t, out) + } + }() + + var ptr string + switch t.Kind() { + case reflect.Bool: + return textLine(fmt.Sprint(v.Bool())) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return textLine(fmt.Sprint(v.Int())) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + // Unnamed uints are usually bytes or words, so use hexadecimal. + if t.PkgPath() == "" || t.Kind() == reflect.Uintptr { + return textLine(formatHex(v.Uint())) + } + return textLine(fmt.Sprint(v.Uint())) + case reflect.Float32, reflect.Float64: + return textLine(fmt.Sprint(v.Float())) + case reflect.Complex64, reflect.Complex128: + return textLine(fmt.Sprint(v.Complex())) + case reflect.String: + return textLine(formatString(v.String())) + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + return textLine(formatPointer(v)) + case reflect.Struct: + var list textList + for i := 0; i < v.NumField(); i++ { + vv := v.Field(i) + if value.IsZero(vv) { + continue // Elide fields with zero values + } + s := opts.WithTypeMode(autoType).FormatValue(vv, m) + list = append(list, textRecord{Key: t.Field(i).Name, Value: s}) + } + return textWrap{"{", list, "}"} + case reflect.Slice: + if v.IsNil() { + return textNil + } + if opts.PrintAddresses { + ptr = formatPointer(v) + } + fallthrough + case reflect.Array: + var list textList + for i := 0; i < v.Len(); i++ { + vi := v.Index(i) + if vi.CanAddr() { // Check for cyclic elements + p := vi.Addr() + if m.Visit(p) { + var out textNode + out = textLine(formatPointer(p)) + out = opts.WithTypeMode(emitType).FormatType(p.Type(), out) + out = textWrap{"*", out, ""} + list = append(list, textRecord{Value: out}) + continue + } + } + s := opts.WithTypeMode(elideType).FormatValue(vi, m) + list = append(list, textRecord{Value: s}) + } + return textWrap{ptr + "{", list, "}"} + case reflect.Map: + if v.IsNil() { + return textNil + } + if m.Visit(v) { + return textLine(formatPointer(v)) + } + + var list textList + for _, k := range value.SortKeys(v.MapKeys()) { + sk := formatMapKey(k) + sv := opts.WithTypeMode(elideType).FormatValue(v.MapIndex(k), m) + list = append(list, textRecord{Key: sk, Value: sv}) + } + if opts.PrintAddresses { + ptr = formatPointer(v) + } + return textWrap{ptr + "{", list, "}"} + case reflect.Ptr: + if v.IsNil() { + return textNil + } + if m.Visit(v) || opts.ShallowPointers { + return textLine(formatPointer(v)) + } + if opts.PrintAddresses { + ptr = formatPointer(v) + } + skipType = true // Let the underlying value print the type instead + return textWrap{"&" + ptr, opts.FormatValue(v.Elem(), m), ""} + case reflect.Interface: + if v.IsNil() { + return textNil + } + // Interfaces accept different concrete types, + // so configure the underlying value to explicitly print the type. + skipType = true // Print the concrete type instead + return opts.WithTypeMode(emitType).FormatValue(v.Elem(), m) + default: + panic(fmt.Sprintf("%v kind not handled", v.Kind())) + } +} + +// formatMapKey formats v as if it were a map key. +// The result is guaranteed to be a single line. +func formatMapKey(v reflect.Value) string { + var opts formatOptions + opts.TypeMode = elideType + opts.AvoidStringer = true + opts.ShallowPointers = true + s := opts.FormatValue(v, visitedPointers{}).String() + return strings.TrimSpace(s) +} + +// formatString prints s as a double-quoted or backtick-quoted string. +func formatString(s string) string { + // Use quoted string if it the same length as a raw string literal. + // Otherwise, attempt to use the raw string form. + qs := strconv.Quote(s) + if len(qs) == 1+len(s)+1 { + return qs + } + + // Disallow newlines to ensure output is a single line. + // Only allow printable runes for readability purposes. + rawInvalid := func(r rune) bool { + return r == '`' || r == '\n' || !(unicode.IsPrint(r) || r == '\t') + } + if strings.IndexFunc(s, rawInvalid) < 0 { + return "`" + s + "`" + } + return qs +} + +// formatHex prints u as a hexadecimal integer in Go notation. +func formatHex(u uint64) string { + var f string + switch { + case u <= 0xff: + f = "0x%02x" + case u <= 0xffff: + f = "0x%04x" + case u <= 0xffffff: + f = "0x%06x" + case u <= 0xffffffff: + f = "0x%08x" + case u <= 0xffffffffff: + f = "0x%010x" + case u <= 0xffffffffffff: + f = "0x%012x" + case u <= 0xffffffffffffff: + f = "0x%014x" + case u <= 0xffffffffffffffff: + f = "0x%016x" + } + return fmt.Sprintf(f, u) +} + +// formatPointer prints the address of the pointer. +func formatPointer(v reflect.Value) string { + p := v.Pointer() + if flags.Deterministic { + p = 0xdeadf00f // Only used for stable testing purposes + } + return fmt.Sprintf("⟪0x%x⟫", p) +} + +type visitedPointers map[value.Pointer]struct{} + +// Visit inserts pointer v into the visited map and reports whether it had +// already been visited before. +func (m visitedPointers) Visit(v reflect.Value) bool { + p := value.PointerOf(v) + _, visited := m[p] + m[p] = struct{}{} + return visited +} diff --git a/vendor/github.com/google/go-cmp/cmp/report_slices.go b/vendor/github.com/google/go-cmp/cmp/report_slices.go new file mode 100644 index 000000000..8cb3265e7 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/report_slices.go @@ -0,0 +1,333 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +import ( + "bytes" + "fmt" + "reflect" + "strings" + "unicode" + "unicode/utf8" + + "github.com/google/go-cmp/cmp/internal/diff" +) + +// CanFormatDiffSlice reports whether we support custom formatting for nodes +// that are slices of primitive kinds or strings. +func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool { + switch { + case opts.DiffMode != diffUnknown: + return false // Must be formatting in diff mode + case v.NumDiff == 0: + return false // No differences detected + case v.NumIgnored+v.NumCompared+v.NumTransformed > 0: + // TODO: Handle the case where someone uses bytes.Equal on a large slice. + return false // Some custom option was used to determined equality + case !v.ValueX.IsValid() || !v.ValueY.IsValid(): + return false // Both values must be valid + } + + switch t := v.Type; t.Kind() { + case reflect.String: + case reflect.Array, reflect.Slice: + // Only slices of primitive types have specialized handling. + switch t.Elem().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: + default: + return false + } + + // If a sufficient number of elements already differ, + // use specialized formatting even if length requirement is not met. + if v.NumDiff > v.NumSame { + return true + } + default: + return false + } + + // Use specialized string diffing for longer slices or strings. + const minLength = 64 + return v.ValueX.Len() >= minLength && v.ValueY.Len() >= minLength +} + +// FormatDiffSlice prints a diff for the slices (or strings) represented by v. +// This provides custom-tailored logic to make printing of differences in +// textual strings and slices of primitive kinds more readable. +func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { + assert(opts.DiffMode == diffUnknown) + t, vx, vy := v.Type, v.ValueX, v.ValueY + + // Auto-detect the type of the data. + var isLinedText, isText, isBinary bool + var sx, sy string + switch { + case t.Kind() == reflect.String: + sx, sy = vx.String(), vy.String() + isText = true // Initial estimate, verify later + case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)): + sx, sy = string(vx.Bytes()), string(vy.Bytes()) + isBinary = true // Initial estimate, verify later + case t.Kind() == reflect.Array: + // Arrays need to be addressable for slice operations to work. + vx2, vy2 := reflect.New(t).Elem(), reflect.New(t).Elem() + vx2.Set(vx) + vy2.Set(vy) + vx, vy = vx2, vy2 + } + if isText || isBinary { + var numLines, lastLineIdx, maxLineLen int + isBinary = false + for i, r := range sx + sy { + if !(unicode.IsPrint(r) || unicode.IsSpace(r)) || r == utf8.RuneError { + isBinary = true + break + } + if r == '\n' { + if maxLineLen < i-lastLineIdx { + lastLineIdx = i - lastLineIdx + } + lastLineIdx = i + 1 + numLines++ + } + } + isText = !isBinary + isLinedText = isText && numLines >= 4 && maxLineLen <= 256 + } + + // Format the string into printable records. + var list textList + var delim string + switch { + // If the text appears to be multi-lined text, + // then perform differencing across individual lines. + case isLinedText: + ssx := strings.Split(sx, "\n") + ssy := strings.Split(sy, "\n") + list = opts.formatDiffSlice( + reflect.ValueOf(ssx), reflect.ValueOf(ssy), 1, "line", + func(v reflect.Value, d diffMode) textRecord { + s := formatString(v.Index(0).String()) + return textRecord{Diff: d, Value: textLine(s)} + }, + ) + delim = "\n" + // If the text appears to be single-lined text, + // then perform differencing in approximately fixed-sized chunks. + // The output is printed as quoted strings. + case isText: + list = opts.formatDiffSlice( + reflect.ValueOf(sx), reflect.ValueOf(sy), 64, "byte", + func(v reflect.Value, d diffMode) textRecord { + s := formatString(v.String()) + return textRecord{Diff: d, Value: textLine(s)} + }, + ) + delim = "" + // If the text appears to be binary data, + // then perform differencing in approximately fixed-sized chunks. + // The output is inspired by hexdump. + case isBinary: + list = opts.formatDiffSlice( + reflect.ValueOf(sx), reflect.ValueOf(sy), 16, "byte", + func(v reflect.Value, d diffMode) textRecord { + var ss []string + for i := 0; i < v.Len(); i++ { + ss = append(ss, formatHex(v.Index(i).Uint())) + } + s := strings.Join(ss, ", ") + comment := commentString(fmt.Sprintf("%c|%v|", d, formatASCII(v.String()))) + return textRecord{Diff: d, Value: textLine(s), Comment: comment} + }, + ) + // For all other slices of primitive types, + // then perform differencing in approximately fixed-sized chunks. + // The size of each chunk depends on the width of the element kind. + default: + var chunkSize int + if t.Elem().Kind() == reflect.Bool { + chunkSize = 16 + } else { + switch t.Elem().Bits() { + case 8: + chunkSize = 16 + case 16: + chunkSize = 12 + case 32: + chunkSize = 8 + default: + chunkSize = 8 + } + } + list = opts.formatDiffSlice( + vx, vy, chunkSize, t.Elem().Kind().String(), + func(v reflect.Value, d diffMode) textRecord { + var ss []string + for i := 0; i < v.Len(); i++ { + switch t.Elem().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + ss = append(ss, fmt.Sprint(v.Index(i).Int())) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + ss = append(ss, formatHex(v.Index(i).Uint())) + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: + ss = append(ss, fmt.Sprint(v.Index(i).Interface())) + } + } + s := strings.Join(ss, ", ") + return textRecord{Diff: d, Value: textLine(s)} + }, + ) + } + + // Wrap the output with appropriate type information. + var out textNode = textWrap{"{", list, "}"} + if !isText { + // The "{...}" byte-sequence literal is not valid Go syntax for strings. + // Emit the type for extra clarity (e.g. "string{...}"). + if t.Kind() == reflect.String { + opts = opts.WithTypeMode(emitType) + } + return opts.FormatType(t, out) + } + switch t.Kind() { + case reflect.String: + out = textWrap{"strings.Join(", out, fmt.Sprintf(", %q)", delim)} + if t != reflect.TypeOf(string("")) { + out = opts.FormatType(t, out) + } + case reflect.Slice: + out = textWrap{"bytes.Join(", out, fmt.Sprintf(", %q)", delim)} + if t != reflect.TypeOf([]byte(nil)) { + out = opts.FormatType(t, out) + } + } + return out +} + +// formatASCII formats s as an ASCII string. +// This is useful for printing binary strings in a semi-legible way. +func formatASCII(s string) string { + b := bytes.Repeat([]byte{'.'}, len(s)) + for i := 0; i < len(s); i++ { + if ' ' <= s[i] && s[i] <= '~' { + b[i] = s[i] + } + } + return string(b) +} + +func (opts formatOptions) formatDiffSlice( + vx, vy reflect.Value, chunkSize int, name string, + makeRec func(reflect.Value, diffMode) textRecord, +) (list textList) { + es := diff.Difference(vx.Len(), vy.Len(), func(ix int, iy int) diff.Result { + return diff.BoolResult(vx.Index(ix).Interface() == vy.Index(iy).Interface()) + }) + + appendChunks := func(v reflect.Value, d diffMode) int { + n0 := v.Len() + for v.Len() > 0 { + n := chunkSize + if n > v.Len() { + n = v.Len() + } + list = append(list, makeRec(v.Slice(0, n), d)) + v = v.Slice(n, v.Len()) + } + return n0 - v.Len() + } + + groups := coalesceAdjacentEdits(name, es) + groups = coalesceInterveningIdentical(groups, chunkSize/4) + for i, ds := range groups { + // Print equal. + if ds.NumDiff() == 0 { + // Compute the number of leading and trailing equal bytes to print. + var numLo, numHi int + numEqual := ds.NumIgnored + ds.NumIdentical + for numLo < chunkSize*numContextRecords && numLo+numHi < numEqual && i != 0 { + numLo++ + } + for numHi < chunkSize*numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 { + numHi++ + } + if numEqual-(numLo+numHi) <= chunkSize && ds.NumIgnored == 0 { + numHi = numEqual - numLo // Avoid pointless coalescing of single equal row + } + + // Print the equal bytes. + appendChunks(vx.Slice(0, numLo), diffIdentical) + if numEqual > numLo+numHi { + ds.NumIdentical -= numLo + numHi + list.AppendEllipsis(ds) + } + appendChunks(vx.Slice(numEqual-numHi, numEqual), diffIdentical) + vx = vx.Slice(numEqual, vx.Len()) + vy = vy.Slice(numEqual, vy.Len()) + continue + } + + // Print unequal. + nx := appendChunks(vx.Slice(0, ds.NumIdentical+ds.NumRemoved+ds.NumModified), diffRemoved) + vx = vx.Slice(nx, vx.Len()) + ny := appendChunks(vy.Slice(0, ds.NumIdentical+ds.NumInserted+ds.NumModified), diffInserted) + vy = vy.Slice(ny, vy.Len()) + } + assert(vx.Len() == 0 && vy.Len() == 0) + return list +} + +// coalesceAdjacentEdits coalesces the list of edits into groups of adjacent +// equal or unequal counts. +func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) { + var prevCase int // Arbitrary index into which case last occurred + lastStats := func(i int) *diffStats { + if prevCase != i { + groups = append(groups, diffStats{Name: name}) + prevCase = i + } + return &groups[len(groups)-1] + } + for _, e := range es { + switch e { + case diff.Identity: + lastStats(1).NumIdentical++ + case diff.UniqueX: + lastStats(2).NumRemoved++ + case diff.UniqueY: + lastStats(2).NumInserted++ + case diff.Modified: + lastStats(2).NumModified++ + } + } + return groups +} + +// coalesceInterveningIdentical coalesces sufficiently short (<= windowSize) +// equal groups into adjacent unequal groups that currently result in a +// dual inserted/removed printout. This acts as a high-pass filter to smooth +// out high-frequency changes within the windowSize. +func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats { + groups, groupsOrig := groups[:0], groups + for i, ds := range groupsOrig { + if len(groups) >= 2 && ds.NumDiff() > 0 { + prev := &groups[len(groups)-2] // Unequal group + curr := &groups[len(groups)-1] // Equal group + next := &groupsOrig[i] // Unequal group + hadX, hadY := prev.NumRemoved > 0, prev.NumInserted > 0 + hasX, hasY := next.NumRemoved > 0, next.NumInserted > 0 + if ((hadX || hasX) && (hadY || hasY)) && curr.NumIdentical <= windowSize { + *prev = (*prev).Append(*curr).Append(*next) + groups = groups[:len(groups)-1] // Truncate off equal group + continue + } + } + groups = append(groups, ds) + } + return groups +} diff --git a/vendor/github.com/google/go-cmp/cmp/report_text.go b/vendor/github.com/google/go-cmp/cmp/report_text.go new file mode 100644 index 000000000..80605d0e4 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/report_text.go @@ -0,0 +1,382 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +import ( + "bytes" + "fmt" + "math/rand" + "strings" + "time" + + "github.com/google/go-cmp/cmp/internal/flags" +) + +var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0 + +type indentMode int + +func (n indentMode) appendIndent(b []byte, d diffMode) []byte { + if flags.Deterministic || randBool { + // Use regular spaces (U+0020). + switch d { + case diffUnknown, diffIdentical: + b = append(b, " "...) + case diffRemoved: + b = append(b, "- "...) + case diffInserted: + b = append(b, "+ "...) + } + } else { + // Use non-breaking spaces (U+00a0). + switch d { + case diffUnknown, diffIdentical: + b = append(b, "  "...) + case diffRemoved: + b = append(b, "- "...) + case diffInserted: + b = append(b, "+ "...) + } + } + return repeatCount(n).appendChar(b, '\t') +} + +type repeatCount int + +func (n repeatCount) appendChar(b []byte, c byte) []byte { + for ; n > 0; n-- { + b = append(b, c) + } + return b +} + +// textNode is a simplified tree-based representation of structured text. +// Possible node types are textWrap, textList, or textLine. +type textNode interface { + // Len reports the length in bytes of a single-line version of the tree. + // Nested textRecord.Diff and textRecord.Comment fields are ignored. + Len() int + // Equal reports whether the two trees are structurally identical. + // Nested textRecord.Diff and textRecord.Comment fields are compared. + Equal(textNode) bool + // String returns the string representation of the text tree. + // It is not guaranteed that len(x.String()) == x.Len(), + // nor that x.String() == y.String() implies that x.Equal(y). + String() string + + // formatCompactTo formats the contents of the tree as a single-line string + // to the provided buffer. Any nested textRecord.Diff and textRecord.Comment + // fields are ignored. + // + // However, not all nodes in the tree should be collapsed as a single-line. + // If a node can be collapsed as a single-line, it is replaced by a textLine + // node. Since the top-level node cannot replace itself, this also returns + // the current node itself. + // + // This does not mutate the receiver. + formatCompactTo([]byte, diffMode) ([]byte, textNode) + // formatExpandedTo formats the contents of the tree as a multi-line string + // to the provided buffer. In order for column alignment to operate well, + // formatCompactTo must be called before calling formatExpandedTo. + formatExpandedTo([]byte, diffMode, indentMode) []byte +} + +// textWrap is a wrapper that concatenates a prefix and/or a suffix +// to the underlying node. +type textWrap struct { + Prefix string // e.g., "bytes.Buffer{" + Value textNode // textWrap | textList | textLine + Suffix string // e.g., "}" +} + +func (s textWrap) Len() int { + return len(s.Prefix) + s.Value.Len() + len(s.Suffix) +} +func (s1 textWrap) Equal(s2 textNode) bool { + if s2, ok := s2.(textWrap); ok { + return s1.Prefix == s2.Prefix && s1.Value.Equal(s2.Value) && s1.Suffix == s2.Suffix + } + return false +} +func (s textWrap) String() string { + var d diffMode + var n indentMode + _, s2 := s.formatCompactTo(nil, d) + b := n.appendIndent(nil, d) // Leading indent + b = s2.formatExpandedTo(b, d, n) // Main body + b = append(b, '\n') // Trailing newline + return string(b) +} +func (s textWrap) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) { + n0 := len(b) // Original buffer length + b = append(b, s.Prefix...) + b, s.Value = s.Value.formatCompactTo(b, d) + b = append(b, s.Suffix...) + if _, ok := s.Value.(textLine); ok { + return b, textLine(b[n0:]) + } + return b, s +} +func (s textWrap) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte { + b = append(b, s.Prefix...) + b = s.Value.formatExpandedTo(b, d, n) + b = append(b, s.Suffix...) + return b +} + +// textList is a comma-separated list of textWrap or textLine nodes. +// The list may be formatted as multi-lines or single-line at the discretion +// of the textList.formatCompactTo method. +type textList []textRecord +type textRecord struct { + Diff diffMode // e.g., 0 or '-' or '+' + Key string // e.g., "MyField" + Value textNode // textWrap | textLine + Comment fmt.Stringer // e.g., "6 identical fields" +} + +// AppendEllipsis appends a new ellipsis node to the list if none already +// exists at the end. If cs is non-zero it coalesces the statistics with the +// previous diffStats. +func (s *textList) AppendEllipsis(ds diffStats) { + hasStats := ds != diffStats{} + if len(*s) == 0 || !(*s)[len(*s)-1].Value.Equal(textEllipsis) { + if hasStats { + *s = append(*s, textRecord{Value: textEllipsis, Comment: ds}) + } else { + *s = append(*s, textRecord{Value: textEllipsis}) + } + return + } + if hasStats { + (*s)[len(*s)-1].Comment = (*s)[len(*s)-1].Comment.(diffStats).Append(ds) + } +} + +func (s textList) Len() (n int) { + for i, r := range s { + n += len(r.Key) + if r.Key != "" { + n += len(": ") + } + n += r.Value.Len() + if i < len(s)-1 { + n += len(", ") + } + } + return n +} + +func (s1 textList) Equal(s2 textNode) bool { + if s2, ok := s2.(textList); ok { + if len(s1) != len(s2) { + return false + } + for i := range s1 { + r1, r2 := s1[i], s2[i] + if !(r1.Diff == r2.Diff && r1.Key == r2.Key && r1.Value.Equal(r2.Value) && r1.Comment == r2.Comment) { + return false + } + } + return true + } + return false +} + +func (s textList) String() string { + return textWrap{"{", s, "}"}.String() +} + +func (s textList) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) { + s = append(textList(nil), s...) // Avoid mutating original + + // Determine whether we can collapse this list as a single line. + n0 := len(b) // Original buffer length + var multiLine bool + for i, r := range s { + if r.Diff == diffInserted || r.Diff == diffRemoved { + multiLine = true + } + b = append(b, r.Key...) + if r.Key != "" { + b = append(b, ": "...) + } + b, s[i].Value = r.Value.formatCompactTo(b, d|r.Diff) + if _, ok := s[i].Value.(textLine); !ok { + multiLine = true + } + if r.Comment != nil { + multiLine = true + } + if i < len(s)-1 { + b = append(b, ", "...) + } + } + // Force multi-lined output when printing a removed/inserted node that + // is sufficiently long. + if (d == diffInserted || d == diffRemoved) && len(b[n0:]) > 80 { + multiLine = true + } + if !multiLine { + return b, textLine(b[n0:]) + } + return b, s +} + +func (s textList) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte { + alignKeyLens := s.alignLens( + func(r textRecord) bool { + _, isLine := r.Value.(textLine) + return r.Key == "" || !isLine + }, + func(r textRecord) int { return len(r.Key) }, + ) + alignValueLens := s.alignLens( + func(r textRecord) bool { + _, isLine := r.Value.(textLine) + return !isLine || r.Value.Equal(textEllipsis) || r.Comment == nil + }, + func(r textRecord) int { return len(r.Value.(textLine)) }, + ) + + // Format the list as a multi-lined output. + n++ + for i, r := range s { + b = n.appendIndent(append(b, '\n'), d|r.Diff) + if r.Key != "" { + b = append(b, r.Key+": "...) + } + b = alignKeyLens[i].appendChar(b, ' ') + + b = r.Value.formatExpandedTo(b, d|r.Diff, n) + if !r.Value.Equal(textEllipsis) { + b = append(b, ',') + } + b = alignValueLens[i].appendChar(b, ' ') + + if r.Comment != nil { + b = append(b, " // "+r.Comment.String()...) + } + } + n-- + + return n.appendIndent(append(b, '\n'), d) +} + +func (s textList) alignLens( + skipFunc func(textRecord) bool, + lenFunc func(textRecord) int, +) []repeatCount { + var startIdx, endIdx, maxLen int + lens := make([]repeatCount, len(s)) + for i, r := range s { + if skipFunc(r) { + for j := startIdx; j < endIdx && j < len(s); j++ { + lens[j] = repeatCount(maxLen - lenFunc(s[j])) + } + startIdx, endIdx, maxLen = i+1, i+1, 0 + } else { + if maxLen < lenFunc(r) { + maxLen = lenFunc(r) + } + endIdx = i + 1 + } + } + for j := startIdx; j < endIdx && j < len(s); j++ { + lens[j] = repeatCount(maxLen - lenFunc(s[j])) + } + return lens +} + +// textLine is a single-line segment of text and is always a leaf node +// in the textNode tree. +type textLine []byte + +var ( + textNil = textLine("nil") + textEllipsis = textLine("...") +) + +func (s textLine) Len() int { + return len(s) +} +func (s1 textLine) Equal(s2 textNode) bool { + if s2, ok := s2.(textLine); ok { + return bytes.Equal([]byte(s1), []byte(s2)) + } + return false +} +func (s textLine) String() string { + return string(s) +} +func (s textLine) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) { + return append(b, s...), s +} +func (s textLine) formatExpandedTo(b []byte, _ diffMode, _ indentMode) []byte { + return append(b, s...) +} + +type diffStats struct { + Name string + NumIgnored int + NumIdentical int + NumRemoved int + NumInserted int + NumModified int +} + +func (s diffStats) NumDiff() int { + return s.NumRemoved + s.NumInserted + s.NumModified +} + +func (s diffStats) Append(ds diffStats) diffStats { + assert(s.Name == ds.Name) + s.NumIgnored += ds.NumIgnored + s.NumIdentical += ds.NumIdentical + s.NumRemoved += ds.NumRemoved + s.NumInserted += ds.NumInserted + s.NumModified += ds.NumModified + return s +} + +// String prints a humanly-readable summary of coalesced records. +// +// Example: +// diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields" +func (s diffStats) String() string { + var ss []string + var sum int + labels := [...]string{"ignored", "identical", "removed", "inserted", "modified"} + counts := [...]int{s.NumIgnored, s.NumIdentical, s.NumRemoved, s.NumInserted, s.NumModified} + for i, n := range counts { + if n > 0 { + ss = append(ss, fmt.Sprintf("%d %v", n, labels[i])) + } + sum += n + } + + // Pluralize the name (adjusting for some obscure English grammar rules). + name := s.Name + if sum > 1 { + name = name + "s" + if strings.HasSuffix(name, "ys") { + name = name[:len(name)-2] + "ies" // e.g., "entrys" => "entries" + } + } + + // Format the list according to English grammar (with Oxford comma). + switch n := len(ss); n { + case 0: + return "" + case 1, 2: + return strings.Join(ss, " and ") + " " + name + default: + return strings.Join(ss[:n-1], ", ") + ", and " + ss[n-1] + " " + name + } +} + +type commentString string + +func (s commentString) String() string { return string(s) } diff --git a/vendor/github.com/google/go-cmp/cmp/report_value.go b/vendor/github.com/google/go-cmp/cmp/report_value.go new file mode 100644 index 000000000..83031a7f5 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/report_value.go @@ -0,0 +1,121 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +import "reflect" + +// valueNode represents a single node within a report, which is a +// structured representation of the value tree, containing information +// regarding which nodes are equal or not. +type valueNode struct { + parent *valueNode + + Type reflect.Type + ValueX reflect.Value + ValueY reflect.Value + + // NumSame is the number of leaf nodes that are equal. + // All descendants are equal only if NumDiff is 0. + NumSame int + // NumDiff is the number of leaf nodes that are not equal. + NumDiff int + // NumIgnored is the number of leaf nodes that are ignored. + NumIgnored int + // NumCompared is the number of leaf nodes that were compared + // using an Equal method or Comparer function. + NumCompared int + // NumTransformed is the number of non-leaf nodes that were transformed. + NumTransformed int + // NumChildren is the number of transitive descendants of this node. + // This counts from zero; thus, leaf nodes have no descendants. + NumChildren int + // MaxDepth is the maximum depth of the tree. This counts from zero; + // thus, leaf nodes have a depth of zero. + MaxDepth int + + // Records is a list of struct fields, slice elements, or map entries. + Records []reportRecord // If populated, implies Value is not populated + + // Value is the result of a transformation, pointer indirect, of + // type assertion. + Value *valueNode // If populated, implies Records is not populated + + // TransformerName is the name of the transformer. + TransformerName string // If non-empty, implies Value is populated +} +type reportRecord struct { + Key reflect.Value // Invalid for slice element + Value *valueNode +} + +func (parent *valueNode) PushStep(ps PathStep) (child *valueNode) { + vx, vy := ps.Values() + child = &valueNode{parent: parent, Type: ps.Type(), ValueX: vx, ValueY: vy} + switch s := ps.(type) { + case StructField: + assert(parent.Value == nil) + parent.Records = append(parent.Records, reportRecord{Key: reflect.ValueOf(s.Name()), Value: child}) + case SliceIndex: + assert(parent.Value == nil) + parent.Records = append(parent.Records, reportRecord{Value: child}) + case MapIndex: + assert(parent.Value == nil) + parent.Records = append(parent.Records, reportRecord{Key: s.Key(), Value: child}) + case Indirect: + assert(parent.Value == nil && parent.Records == nil) + parent.Value = child + case TypeAssertion: + assert(parent.Value == nil && parent.Records == nil) + parent.Value = child + case Transform: + assert(parent.Value == nil && parent.Records == nil) + parent.Value = child + parent.TransformerName = s.Name() + parent.NumTransformed++ + default: + assert(parent == nil) // Must be the root step + } + return child +} + +func (r *valueNode) Report(rs Result) { + assert(r.MaxDepth == 0) // May only be called on leaf nodes + + if rs.ByIgnore() { + r.NumIgnored++ + } else { + if rs.Equal() { + r.NumSame++ + } else { + r.NumDiff++ + } + } + assert(r.NumSame+r.NumDiff+r.NumIgnored == 1) + + if rs.ByMethod() { + r.NumCompared++ + } + if rs.ByFunc() { + r.NumCompared++ + } + assert(r.NumCompared <= 1) +} + +func (child *valueNode) PopStep() (parent *valueNode) { + if child.parent == nil { + return nil + } + parent = child.parent + parent.NumSame += child.NumSame + parent.NumDiff += child.NumDiff + parent.NumIgnored += child.NumIgnored + parent.NumCompared += child.NumCompared + parent.NumTransformed += child.NumTransformed + parent.NumChildren += child.NumChildren + 1 + if parent.MaxDepth < child.MaxDepth+1 { + parent.MaxDepth = child.MaxDepth + 1 + } + return parent +} diff --git a/vendor/github.com/google/go-cmp/cmp/reporter.go b/vendor/github.com/google/go-cmp/cmp/reporter.go deleted file mode 100644 index 20e9f18e0..000000000 --- a/vendor/github.com/google/go-cmp/cmp/reporter.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017, The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE.md file. - -package cmp - -import ( - "fmt" - "reflect" - "strings" - - "github.com/google/go-cmp/cmp/internal/value" -) - -type defaultReporter struct { - Option - diffs []string // List of differences, possibly truncated - ndiffs int // Total number of differences - nbytes int // Number of bytes in diffs - nlines int // Number of lines in diffs -} - -var _ reporter = (*defaultReporter)(nil) - -func (r *defaultReporter) Report(x, y reflect.Value, eq bool, p Path) { - if eq { - return // Ignore equal results - } - const maxBytes = 4096 - const maxLines = 256 - r.ndiffs++ - if r.nbytes < maxBytes && r.nlines < maxLines { - sx := value.Format(x, value.FormatConfig{UseStringer: true}) - sy := value.Format(y, value.FormatConfig{UseStringer: true}) - if sx == sy { - // Unhelpful output, so use more exact formatting. - sx = value.Format(x, value.FormatConfig{PrintPrimitiveType: true}) - sy = value.Format(y, value.FormatConfig{PrintPrimitiveType: true}) - } - s := fmt.Sprintf("%#v:\n\t-: %s\n\t+: %s\n", p, sx, sy) - r.diffs = append(r.diffs, s) - r.nbytes += len(s) - r.nlines += strings.Count(s, "\n") - } -} - -func (r *defaultReporter) String() string { - s := strings.Join(r.diffs, "") - if r.ndiffs == len(r.diffs) { - return s - } - return fmt.Sprintf("%s... %d more differences ...", s, r.ndiffs-len(r.diffs)) -} diff --git a/vendor/github.com/google/go-containerregistry/pkg/name/digest.go b/vendor/github.com/google/go-containerregistry/pkg/name/digest.go index d10856de7..2dc0f7f37 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/name/digest.go +++ b/vendor/github.com/google/go-containerregistry/pkg/name/digest.go @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package name defines structured types for representing image references. package name import ( diff --git a/vendor/github.com/google/go-containerregistry/pkg/name/doc.go b/vendor/github.com/google/go-containerregistry/pkg/name/doc.go new file mode 100644 index 000000000..b294794dc --- /dev/null +++ b/vendor/github.com/google/go-containerregistry/pkg/name/doc.go @@ -0,0 +1,42 @@ +// Copyright 2018 Google LLC All Rights Reserved. +// +// 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 name defines structured types for representing image references. +// +// What's in a name? For image references, not nearly enough! +// +// Image references look a lot like URLs, but they differ in that they don't +// contain the scheme (http or https), they can end with a :tag or a @digest +// (the latter being validated), and they perform defaulting for missing +// components. +// +// Since image references don't contain the scheme, we do our best to infer +// if we use http or https from the given hostname. We allow http fallback for +// any host that looks like localhost (localhost, 127.0.0.1, ::1), ends in +// ".local", or is in the "private" address space per RFC 1918. For everything +// else, we assume https only. To override this heuristic, use the Insecure +// option. +// +// Image references with a digest signal to us that we should verify the content +// of the image matches the digest. E.g. when pulling a Digest reference, we'll +// calculate the sha256 of the manifest returned by the registry and error out +// if it doesn't match what we asked for. +// +// For defaulting, we interpret "ubuntu" as +// "index.docker.io/library/ubuntu:latest" because we add the missing repo +// "library", the missing registry "index.docker.io", and the missing tag +// "latest". To disable this defaulting, use the StrictValidation option. This +// is useful e.g. to only allow image references that explicitly set a tag or +// digest, so that you don't accidentally pull "latest". +package name diff --git a/vendor/github.com/knative/pkg/apis/condition_set.go b/vendor/github.com/knative/pkg/apis/condition_set.go new file mode 100644 index 000000000..d4c70098e --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/condition_set.go @@ -0,0 +1,335 @@ +/* +Copyright 2019 The Knative 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 apis + +import ( + "reflect" + "sort" + "time" + + "fmt" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Conditions is the interface for a Resource that implements the getter and +// setter for accessing a Condition collection. +// +k8s:deepcopy-gen=true +type ConditionsAccessor interface { + GetConditions() Conditions + SetConditions(Conditions) +} + +// ConditionSet is an abstract collection of the possible ConditionType values +// that a particular resource might expose. It also holds the "happy condition" +// for that resource, which we define to be one of Ready or Succeeded depending +// on whether it is a Living or Batch process respectively. +// +k8s:deepcopy-gen=false +type ConditionSet struct { + happy ConditionType + dependents []ConditionType +} + +// ConditionManager allows a resource to operate on its Conditions using higher +// order operations. +type ConditionManager interface { + // IsHappy looks at the happy condition and returns true if that condition is + // set to true. + IsHappy() bool + + // GetCondition finds and returns the Condition that matches the ConditionType + // previously set on Conditions. + GetCondition(t ConditionType) *Condition + + // SetCondition sets or updates the Condition on Conditions for Condition.Type. + // If there is an update, Conditions are stored back sorted. + SetCondition(new Condition) + + // MarkTrue sets the status of t to true, and then marks the happy condition to + // true if all dependents are true. + MarkTrue(t ConditionType) + + // MarkUnknown sets the status of t to Unknown and also sets the happy condition + // to Unknown if no other dependent condition is in an error state. + MarkUnknown(t ConditionType, reason, messageFormat string, messageA ...interface{}) + + // MarkFalse sets the status of t and the happy condition to False. + MarkFalse(t ConditionType, reason, messageFormat string, messageA ...interface{}) + + // InitializeConditions updates all Conditions in the ConditionSet to Unknown + // if not set. + InitializeConditions() +} + +// NewLivingConditionSet returns a ConditionSet to hold the conditions for the +// living resource. ConditionReady is used as the happy condition. +// The set of condition types provided are those of the terminal subconditions. +func NewLivingConditionSet(d ...ConditionType) ConditionSet { + return newConditionSet(ConditionReady, d...) +} + +// NewBatchConditionSet returns a ConditionSet to hold the conditions for the +// batch resource. ConditionSucceeded is used as the happy condition. +// The set of condition types provided are those of the terminal subconditions. +func NewBatchConditionSet(d ...ConditionType) ConditionSet { + return newConditionSet(ConditionSucceeded, d...) +} + +// newConditionSet returns a ConditionSet to hold the conditions that are +// important for the caller. The first ConditionType is the overarching status +// for that will be used to signal the resources' status is Ready or Succeeded. +func newConditionSet(happy ConditionType, dependents ...ConditionType) ConditionSet { + var deps []ConditionType + for _, d := range dependents { + // Skip duplicates + if d == happy || contains(deps, d) { + continue + } + deps = append(deps, d) + } + return ConditionSet{ + happy: happy, + dependents: deps, + } +} + +func contains(ct []ConditionType, t ConditionType) bool { + for _, c := range ct { + if c == t { + return true + } + } + return false +} + +// Check that conditionsImpl implements ConditionManager. +var _ ConditionManager = (*conditionsImpl)(nil) + +// conditionsImpl implements the helper methods for evaluating Conditions. +// +k8s:deepcopy-gen=false +type conditionsImpl struct { + ConditionSet + accessor ConditionsAccessor +} + +// Manage creates a ConditionManager from a accessor object using the original +// ConditionSet as a reference. Status must be or point to a struct. +func (r ConditionSet) Manage(status ConditionsAccessor) ConditionManager { + return conditionsImpl{ + accessor: status, + ConditionSet: r, + } +} + +// IsHappy looks at the happy condition and returns true if that condition is +// set to true. +func (r conditionsImpl) IsHappy() bool { + if c := r.GetCondition(r.happy); c == nil || !c.IsTrue() { + return false + } + return true +} + +// GetCondition finds and returns the Condition that matches the ConditionType +// previously set on Conditions. +func (r conditionsImpl) GetCondition(t ConditionType) *Condition { + if r.accessor == nil { + return nil + } + + for _, c := range r.accessor.GetConditions() { + if c.Type == t { + return &c + } + } + return nil +} + +// SetCondition sets or updates the Condition on Conditions for Condition.Type. +// If there is an update, Conditions are stored back sorted. +func (r conditionsImpl) SetCondition(new Condition) { + if r.accessor == nil { + return + } + t := new.Type + var conditions Conditions + for _, c := range r.accessor.GetConditions() { + if c.Type != t { + conditions = append(conditions, c) + } else { + // If we'd only update the LastTransitionTime, then return. + new.LastTransitionTime = c.LastTransitionTime + if reflect.DeepEqual(&new, &c) { + return + } + } + } + new.LastTransitionTime = VolatileTime{Inner: metav1.NewTime(time.Now())} + conditions = append(conditions, new) + // Sorted for convenience of the consumer, i.e. kubectl. + sort.Slice(conditions, func(i, j int) bool { return conditions[i].Type < conditions[j].Type }) + r.accessor.SetConditions(conditions) +} + +func (r conditionsImpl) isTerminal(t ConditionType) bool { + for _, cond := range r.dependents { + if cond == t { + return true + } + } + + if t == r.happy { + return true + } + + return false +} + +func (r conditionsImpl) severity(t ConditionType) ConditionSeverity { + if r.isTerminal(t) { + return ConditionSeverityError + } + return ConditionSeverityInfo +} + +// MarkTrue sets the status of t to true, and then marks the happy condition to +// true if all other dependents are also true. +func (r conditionsImpl) MarkTrue(t ConditionType) { + // set the specified condition + r.SetCondition(Condition{ + Type: t, + Status: corev1.ConditionTrue, + Severity: r.severity(t), + }) + + // check the dependents. + for _, cond := range r.dependents { + c := r.GetCondition(cond) + // Failed or Unknown conditions trump true conditions + if !c.IsTrue() { + return + } + } + + // set the happy condition + r.SetCondition(Condition{ + Type: r.happy, + Status: corev1.ConditionTrue, + Severity: r.severity(r.happy), + }) +} + +// MarkUnknown sets the status of t to Unknown and also sets the happy condition +// to Unknown if no other dependent condition is in an error state. +func (r conditionsImpl) MarkUnknown(t ConditionType, reason, messageFormat string, messageA ...interface{}) { + // set the specified condition + r.SetCondition(Condition{ + Type: t, + Status: corev1.ConditionUnknown, + Reason: reason, + Message: fmt.Sprintf(messageFormat, messageA...), + Severity: r.severity(t), + }) + + // check the dependents. + isDependent := false + for _, cond := range r.dependents { + c := r.GetCondition(cond) + // Failed conditions trump Unknown conditions + if c.IsFalse() { + // Double check that the happy condition is also false. + happy := r.GetCondition(r.happy) + if !happy.IsFalse() { + r.MarkFalse(r.happy, reason, messageFormat, messageA...) + } + return + } + if cond == t { + isDependent = true + } + } + + if isDependent { + // set the happy condition, if it is one of our dependent subconditions. + r.SetCondition(Condition{ + Type: r.happy, + Status: corev1.ConditionUnknown, + Reason: reason, + Message: fmt.Sprintf(messageFormat, messageA...), + Severity: r.severity(r.happy), + }) + } +} + +// MarkFalse sets the status of t and the happy condition to False. +func (r conditionsImpl) MarkFalse(t ConditionType, reason, messageFormat string, messageA ...interface{}) { + types := []ConditionType{t} + for _, cond := range r.dependents { + if cond == t { + types = append(types, r.happy) + } + } + + for _, t := range types { + r.SetCondition(Condition{ + Type: t, + Status: corev1.ConditionFalse, + Reason: reason, + Message: fmt.Sprintf(messageFormat, messageA...), + Severity: r.severity(t), + }) + } +} + +// InitializeConditions updates all Conditions in the ConditionSet to Unknown +// if not set. +func (r conditionsImpl) InitializeConditions() { + happy := r.GetCondition(r.happy) + if happy == nil { + happy = &Condition{ + Type: r.happy, + Status: corev1.ConditionUnknown, + Severity: ConditionSeverityError, + } + r.SetCondition(*happy) + } + // If the happy state is true, it implies that all of the terminal + // subconditions must be true, so initialize any unset conditions to + // true if our happy condition is true, otherwise unknown. + status := corev1.ConditionUnknown + if happy.Status == corev1.ConditionTrue { + status = corev1.ConditionTrue + } + for _, t := range r.dependents { + r.initializeTerminalCondition(t, status) + } +} + +// initializeTerminalCondition initializes a Condition to the given status if unset. +func (r conditionsImpl) initializeTerminalCondition(t ConditionType, status corev1.ConditionStatus) *Condition { + if c := r.GetCondition(t); c != nil { + return c + } + c := Condition{ + Type: t, + Status: status, + Severity: ConditionSeverityError, + } + r.SetCondition(c) + return &c +} diff --git a/vendor/github.com/knative/pkg/apis/condition_types.go b/vendor/github.com/knative/pkg/apis/condition_types.go new file mode 100644 index 000000000..8f5603c0f --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/condition_types.go @@ -0,0 +1,109 @@ +/* +Copyright 2019 The Knative 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 apis + +import ( + corev1 "k8s.io/api/core/v1" +) + +// Conditions is the schema for the conditions portion of the payload +type Conditions []Condition + +// ConditionType is a camel-cased condition type. +type ConditionType string + +const ( + // ConditionReady specifies that the resource is ready. + // For long-running resources. + ConditionReady ConditionType = "Ready" + // ConditionSucceeded specifies that the resource has finished. + // For resource which run to completion. + ConditionSucceeded ConditionType = "Succeeded" +) + +// ConditionSeverity expresses the severity of a Condition Type failing. +type ConditionSeverity string + +const ( + // ConditionSeverityError specifies that a failure of a condition type + // should be viewed as an error. As "Error" is the default for conditions + // we use the empty string (coupled with omitempty) to avoid confusion in + // the case where the condition is in state "True" (aka nothing is wrong). + ConditionSeverityError ConditionSeverity = "" + // ConditionSeverityWarning specifies that a failure of a condition type + // should be viewed as a warning, but that things could still work. + ConditionSeverityWarning ConditionSeverity = "Warning" + // ConditionSeverityInfo specifies that a failure of a condition type + // should be viewed as purely informational, and that things could still work. + ConditionSeverityInfo ConditionSeverity = "Info" +) + +// Conditions defines a readiness condition for a Knative resource. +// See: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#typical-status-properties +// +k8s:deepcopy-gen=true +type Condition struct { + // Type of condition. + // +required + Type ConditionType `json:"type" description:"type of status condition"` + + // Status of the condition, one of True, False, Unknown. + // +required + Status corev1.ConditionStatus `json:"status" description:"status of the condition, one of True, False, Unknown"` + + // Severity with which to treat failures of this type of condition. + // When this is not specified, it defaults to Error. + // +optional + Severity ConditionSeverity `json:"severity,omitempty" description:"how to interpret failures of this condition, one of Error, Warning, Info"` + + // LastTransitionTime is the last time the condition transitioned from one status to another. + // We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic + // differences (all other things held constant). + // +optional + LastTransitionTime VolatileTime `json:"lastTransitionTime,omitempty" description:"last time the condition transit from one status to another"` + + // The reason for the condition's last transition. + // +optional + Reason string `json:"reason,omitempty" description:"one-word CamelCase reason for the condition's last transition"` + + // A human readable message indicating details about the transition. + // +optional + Message string `json:"message,omitempty" description:"human-readable message indicating details about last transition"` +} + +// IsTrue is true if the condition is True +func (c *Condition) IsTrue() bool { + if c == nil { + return false + } + return c.Status == corev1.ConditionTrue +} + +// IsFalse is true if the condition is False +func (c *Condition) IsFalse() bool { + if c == nil { + return false + } + return c.Status == corev1.ConditionFalse +} + +// IsUnknown is true if the condition is Unknown +func (c *Condition) IsUnknown() bool { + if c == nil { + return true + } + return c.Status == corev1.ConditionUnknown +} diff --git a/vendor/github.com/knative/pkg/apis/contexts.go b/vendor/github.com/knative/pkg/apis/contexts.go new file mode 100644 index 000000000..466b89809 --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/contexts.go @@ -0,0 +1,152 @@ +/* +Copyright 2019 The Knative 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 apis + +import ( + "context" + + authenticationv1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// This is attached to contexts passed to webhook interfaces when +// the receiver being validated is being created. +type inCreateKey struct{} + +// WithinCreate is used to note that the webhook is calling within +// the context of a Create operation. +func WithinCreate(ctx context.Context) context.Context { + return context.WithValue(ctx, inCreateKey{}, struct{}{}) +} + +// IsInCreate checks whether the context is a Create. +func IsInCreate(ctx context.Context) bool { + return ctx.Value(inCreateKey{}) != nil +} + +// This is attached to contexts passed to webhook interfaces when +// the receiver being validated is being updated. +type inUpdateKey struct{} + +// WithinUpdate is used to note that the webhook is calling within +// the context of a Update operation. +func WithinUpdate(ctx context.Context, base interface{}) context.Context { + return context.WithValue(ctx, inUpdateKey{}, base) +} + +// IsInUpdate checks whether the context is an Update. +func IsInUpdate(ctx context.Context) bool { + return ctx.Value(inUpdateKey{}) != nil +} + +// GetBaseline returns the baseline of the update, or nil when we +// are not within an update context. +func GetBaseline(ctx context.Context) interface{} { + return ctx.Value(inUpdateKey{}) +} + +// This is attached to contexts passed to webhook interfaces when +// the receiver being validated is being created. +type userInfoKey struct{} + +// WithUserInfo is used to note that the webhook is calling within +// the context of a Create operation. +func WithUserInfo(ctx context.Context, ui *authenticationv1.UserInfo) context.Context { + return context.WithValue(ctx, userInfoKey{}, ui) +} + +// GetUserInfo accesses the UserInfo attached to the webhook context. +func GetUserInfo(ctx context.Context) *authenticationv1.UserInfo { + if ui, ok := ctx.Value(userInfoKey{}).(*authenticationv1.UserInfo); ok { + return ui + } + return nil +} + +// This is attached to contexts as they are passed down through a resource +// being validated or defaulted to signal the ObjectMeta of the enclosing +// resource. +type parentMetaKey struct{} + +// WithinParent attaches the ObjectMeta of the resource enclosing the +// nested resources we are validating. This is intended for use with +// interfaces like apis.Defaultable and apis.Validatable. +func WithinParent(ctx context.Context, om metav1.ObjectMeta) context.Context { + return context.WithValue(ctx, parentMetaKey{}, om) +} + +// ParentMeta accesses the ObjectMeta of the enclosing parent resource +// from the context. See WithinParent for how to attach the parent's +// ObjectMeta to the context. +func ParentMeta(ctx context.Context) metav1.ObjectMeta { + if om, ok := ctx.Value(parentMetaKey{}).(metav1.ObjectMeta); ok { + return om + } + return metav1.ObjectMeta{} +} + +// This is attached to contexts as they are passed down through a resource +// being validated or defaulted to signal that we are within a Spec. +type inSpec struct{} + +// WithinSpec notes on the context that further validation or defaulting +// is within the context of a Spec. This is intended for use with +// interfaces like apis.Defaultable and apis.Validatable. +func WithinSpec(ctx context.Context) context.Context { + return context.WithValue(ctx, inSpec{}, struct{}{}) +} + +// IsInSpec returns whether the context of validation or defaulting is +// the Spec of the parent resource. +func IsInSpec(ctx context.Context) bool { + return ctx.Value(inSpec{}) != nil +} + +// This is attached to contexts as they are passed down through a resource +// being validated or defaulted to signal that we are within a Status. +type inStatus struct{} + +// WithinStatus notes on the context that further validation or defaulting +// is within the context of a Status. This is intended for use with +// interfaces like apis.Defaultable and apis.Validatable. +func WithinStatus(ctx context.Context) context.Context { + return context.WithValue(ctx, inStatus{}, struct{}{}) +} + +// IsInStatus returns whether the context of validation or defaulting is +// the Status of the parent resource. +func IsInStatus(ctx context.Context) bool { + return ctx.Value(inStatus{}) != nil +} + +// This is attached to contexts as they are passed down through a resource +// being validated to direct them to disallow deprecated fields. +type disallowDeprecated struct{} + +// DisallowDeprecated notes on the context that further validation +// should disallow the used of deprecated fields. This may be used +// to ensure that new paths through resources to a common type don't +// allow the mistakes of old versions to be introduced. +func DisallowDeprecated(ctx context.Context) context.Context { + return context.WithValue(ctx, disallowDeprecated{}, struct{}{}) +} + +// IsDeprecatedAllowed checks the context to see whether deprecated fields +// are allowed. +func IsDeprecatedAllowed(ctx context.Context) bool { + return ctx.Value(disallowDeprecated{}) == nil +} diff --git a/vendor/github.com/knative/pkg/apis/deprecated.go b/vendor/github.com/knative/pkg/apis/deprecated.go new file mode 100644 index 000000000..c73f5be7c --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/deprecated.go @@ -0,0 +1,180 @@ +/* +Copyright 2019 The Knative 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 apis + +import ( + "context" + "reflect" + "strings" +) + +const ( + deprecatedPrefix = "Deprecated" +) + +// CheckDeprecated checks whether the provided named deprecated fields +// are set in a context where deprecation is disallowed. +// This is a shallow check. +func CheckDeprecated(ctx context.Context, obj interface{}) *FieldError { + return CheckDeprecatedUpdate(ctx, obj, nil) +} + +// CheckDeprecated checks whether the provided named deprecated fields +// are set in a context where deprecation is disallowed. +// This is a json shallow check. We will recursively check inlined structs. +func CheckDeprecatedUpdate(ctx context.Context, obj interface{}, original interface{}) *FieldError { + if IsDeprecatedAllowed(ctx) { + return nil + } + + var errs *FieldError + objFields, objInlined := getPrefixedNamedFieldValues(deprecatedPrefix, obj) + + if nonZero(reflect.ValueOf(original)) { + originalFields, originalInlined := getPrefixedNamedFieldValues(deprecatedPrefix, original) + + // We only have to walk obj Fields because the assumption is that obj + // and original are of the same type. + for name, value := range objFields { + if nonZero(value) { + if differ(originalFields[name], value) { + // Not allowed to update the value. + errs = errs.Also(ErrDisallowedUpdateDeprecatedFields(name)) + } + } + } + // Look for deprecated inlined updates. + if len(objInlined) > 0 { + for name, value := range objInlined { + errs = errs.Also(CheckDeprecatedUpdate(ctx, value, originalInlined[name])) + } + } + } else { + for name, value := range objFields { + if nonZero(value) { + // Not allowed to set the value. + errs = errs.Also(ErrDisallowedFields(name)) + } + } + // Look for deprecated inlined creates. + if len(objInlined) > 0 { + for _, value := range objInlined { + errs = errs.Also(CheckDeprecated(ctx, value)) + } + } + } + return errs +} + +func getPrefixedNamedFieldValues(prefix string, obj interface{}) (map[string]reflect.Value, map[string]interface{}) { + fields := make(map[string]reflect.Value, 0) + inlined := make(map[string]interface{}, 0) + + objValue := reflect.Indirect(reflect.ValueOf(obj)) + + // If res is not valid or a struct, don't even try to use it. + if !objValue.IsValid() || objValue.Kind() != reflect.Struct { + return fields, inlined + } + + for i := 0; i < objValue.NumField(); i++ { + tf := objValue.Type().Field(i) + if v := objValue.Field(i); v.IsValid() { + jTag := tf.Tag.Get("json") + if strings.HasPrefix(tf.Name, prefix) { + name := strings.Split(jTag, ",")[0] + if name == "" { + // Default to field name in go struct if no json name. + name = tf.Name + } + fields[name] = v + } else if jTag == ",inline" { + inlined[tf.Name] = getInterface(v) + } + } + } + return fields, inlined +} + +// getInterface returns the interface value of the reflected object. +func getInterface(a reflect.Value) interface{} { + switch a.Kind() { + case reflect.Ptr: + if a.IsNil() { + return nil + } + return a.Elem().Interface() + + case reflect.Map, reflect.Slice, reflect.Array: + return a.Elem().Interface() + + // This is a nil interface{} type. + case reflect.Invalid: + return nil + + default: + return a.Interface() + } +} + +// nonZero returns true if a is nil or reflect.Zero. +func nonZero(a reflect.Value) bool { + switch a.Kind() { + case reflect.Ptr: + if a.IsNil() { + return false + } + return nonZero(a.Elem()) + + case reflect.Map, reflect.Slice, reflect.Array: + if a.IsNil() { + return false + } + return true + + // This is a nil interface{} type. + case reflect.Invalid: + return false + + default: + if reflect.DeepEqual(a.Interface(), reflect.Zero(a.Type()).Interface()) { + return false + } + return true + } +} + +// differ returns true if a != b +func differ(a, b reflect.Value) bool { + if a.Kind() != b.Kind() { + return true + } + + switch a.Kind() { + case reflect.Ptr: + if a.IsNil() || b.IsNil() { + return a.IsNil() != b.IsNil() + } + return differ(a.Elem(), b.Elem()) + + default: + if reflect.DeepEqual(a.Interface(), b.Interface()) { + return false + } + return true + } +} diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/addressable_types.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/addressable_types.go index bc7917975..48f9f99dd 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/addressable_types.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/addressable_types.go @@ -22,18 +22,18 @@ import ( "github.com/knative/pkg/apis" "github.com/knative/pkg/apis/duck" + "github.com/knative/pkg/apis/duck/v1beta1" ) // Addressable provides a generic mechanism for a custom resource // definition to indicate a destination for message delivery. -// (Currently, only hostname is supported, and HTTP is implied. In the -// future, additional schemes may be supported, and path components -// ala UI may also be supported.) // Addressable is the schema for the destination information. This is // typically stored in the object's `status`, as this information may // be generated by the controller. type Addressable struct { + v1beta1.Addressable `json:",omitempty"` + Hostname string `json:"hostname,omitempty"` } @@ -60,12 +60,14 @@ type AddressStatus struct { Address *Addressable `json:"address,omitempty"` } -// Verify AddressableType resources meet duck contracts. -var _ duck.Populatable = (*AddressableType)(nil) -var _ apis.Listable = (*AddressableType)(nil) +var ( + // Verify AddressableType resources meet duck contracts. + _ duck.Populatable = (*AddressableType)(nil) + _ apis.Listable = (*AddressableType)(nil) +) // GetFullType implements duck.Implementable -func (_ *Addressable) GetFullType() duck.Populatable { +func (*Addressable) GetFullType() duck.Populatable { return &AddressableType{} } @@ -80,7 +82,7 @@ func (t *AddressableType) Populate() { } // GetListType implements apis.Listable -func (r *AddressableType) GetListType() runtime.Object { +func (*AddressableType) GetListType() runtime.Object { return &AddressableTypeList{} } diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/condition_set.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/condition_set.go index 1c550ed19..72d4bf605 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/condition_set.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/condition_set.go @@ -153,7 +153,7 @@ func (r ConditionSet) Manage(status interface{}) ConditionManager { } } - // We tried. This object is not understood by the the condition manager. + // We tried. This object is not understood by the condition manager. //panic(fmt.Sprintf("Error converting %T into a ConditionsAccessor", status)) // TODO: not sure which way. using panic above means passing nil status panics the system. return conditionsImpl{ diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/conditions_types.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/conditions_types.go index 37c54d0b0..b82de3c4c 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/conditions_types.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/conditions_types.go @@ -159,7 +159,7 @@ var _ duck.Populatable = (*KResource)(nil) var _ apis.Listable = (*KResource)(nil) // GetFullType implements duck.Implementable -func (_ *Conditions) GetFullType() duck.Populatable { +func (*Conditions) GetFullType() duck.Populatable { return &KResource{} } @@ -187,7 +187,7 @@ func (t *KResource) Populate() { } // GetListType implements apis.Listable -func (r *KResource) GetListType() runtime.Object { +func (*KResource) GetListType() runtime.Object { return &KResourceList{} } diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/legacy_targetable_types.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/legacy_targetable_types.go index 3e13d9eaf..5e4d6f2e3 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/legacy_targetable_types.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/legacy_targetable_types.go @@ -67,7 +67,7 @@ var _ duck.Populatable = (*LegacyTarget)(nil) var _ apis.Listable = (*LegacyTarget)(nil) // GetFullType implements duck.Implementable -func (_ *LegacyTargetable) GetFullType() duck.Populatable { +func (*LegacyTargetable) GetFullType() duck.Populatable { return &LegacyTarget{} } @@ -80,7 +80,7 @@ func (t *LegacyTarget) Populate() { } // GetListType implements apis.Listable -func (r *LegacyTarget) GetListType() runtime.Object { +func (*LegacyTarget) GetListType() runtime.Object { return &LegacyTargetList{} } diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/retired_targetable_types.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/retired_targetable_types.go index ab578e523..0e91aef8a 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/retired_targetable_types.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/retired_targetable_types.go @@ -60,14 +60,16 @@ type TargetStatus struct { Targetable *Targetable `json:"targetable,omitempty"` } -// In order for Targetable to be Implementable, Target must be Populatable. -var _ duck.Populatable = (*Target)(nil) +var ( + // In order for Targetable to be Implementable, Target must be Populatable. + _ duck.Populatable = (*Target)(nil) -// Ensure Target satisfies apis.Listable -var _ apis.Listable = (*Target)(nil) + // Ensure Target satisfies apis.Listable + _ apis.Listable = (*Target)(nil) +) // GetFullType implements duck.Implementable -func (_ *Targetable) GetFullType() duck.Populatable { +func (*Targetable) GetFullType() duck.Populatable { return &Target{} } @@ -82,7 +84,7 @@ func (t *Target) Populate() { } // GetListType implements apis.Listable -func (r *Target) GetListType() runtime.Object { +func (*Target) GetListType() runtime.Object { return &TargetList{} } diff --git a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go index cf36c40bb..a59e67ce3 100644 --- a/vendor/github.com/knative/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/knative/pkg/apis/duck/v1alpha1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 The Knative Authors +Copyright 2019 The Knative Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ func (in *AddressStatus) DeepCopyInto(out *AddressStatus) { if in.Address != nil { in, out := &in.Address, &out.Address *out = new(Addressable) - **out = **in + (*in).DeepCopyInto(*out) } return } @@ -48,6 +48,7 @@ func (in *AddressStatus) DeepCopy() *AddressStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Addressable) DeepCopyInto(out *Addressable) { *out = *in + in.Addressable.DeepCopyInto(&out.Addressable) return } diff --git a/vendor/github.com/knative/pkg/apis/duck/v1beta1/addressable_types.go b/vendor/github.com/knative/pkg/apis/duck/v1beta1/addressable_types.go new file mode 100644 index 000000000..379098e7f --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/duck/v1beta1/addressable_types.go @@ -0,0 +1,97 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + "github.com/knative/pkg/apis" + "github.com/knative/pkg/apis/duck" +) + +// Addressable provides a generic mechanism for a custom resource +// definition to indicate a destination for message delivery. + +// Addressable is the schema for the destination information. This is +// typically stored in the object's `status`, as this information may +// be generated by the controller. +type Addressable struct { + URL *apis.URL `json:"url,omitempty"` +} + +// Addressable is an Implementable "duck type". +var _ duck.Implementable = (*Addressable)(nil) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AddressableType is a skeleton type wrapping Addressable in the manner we expect +// resource writers defining compatible resources to embed it. We will +// typically use this type to deserialize Addressable ObjectReferences and +// access the Addressable data. This is not a real resource. +type AddressableType struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Status AddressStatus `json:"status"` +} + +// AddressStatus shows how we expect folks to embed Addressable in +// their Status field. +type AddressStatus struct { + Address *Addressable `json:"address,omitempty"` +} + +var ( + // Verify AddressableType resources meet duck contracts. + _ duck.Populatable = (*AddressableType)(nil) + _ apis.Listable = (*AddressableType)(nil) +) + +// GetFullType implements duck.Implementable +func (*Addressable) GetFullType() duck.Populatable { + return &AddressableType{} +} + +// Populate implements duck.Populatable +func (t *AddressableType) Populate() { + t.Status = AddressStatus{ + &Addressable{ + // Populate ALL fields + URL: &apis.URL{ + Scheme: "http", + Host: "foo.com", + }, + }, + } +} + +// GetListType implements apis.Listable +func (*AddressableType) GetListType() runtime.Object { + return &AddressableTypeList{} +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AddressableTypeList is a list of AddressableType resources +type AddressableTypeList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []AddressableType `json:"items"` +} diff --git a/vendor/github.com/knative/pkg/apis/duck/v1beta1/doc.go b/vendor/github.com/knative/pkg/apis/duck/v1beta1/doc.go new file mode 100644 index 000000000..6dbd7ff8a --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/duck/v1beta1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Api versions allow the api contract for a resource to be changed while keeping +// backward compatibility by support multiple concurrent versions +// of the same resource + +// +k8s:deepcopy-gen=package +// +groupName=duck.knative.dev +package v1beta1 diff --git a/vendor/github.com/knative/pkg/apis/duck/v1beta1/register.go b/vendor/github.com/knative/pkg/apis/duck/v1beta1/register.go new file mode 100644 index 000000000..c337e4a61 --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/duck/v1beta1/register.go @@ -0,0 +1,55 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "github.com/knative/pkg/apis/duck" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: duck.GroupName, Version: "v1beta1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes( + SchemeGroupVersion, + &KResource{}, + (&KResource{}).GetListType(), + &AddressableType{}, + (&AddressableType{}).GetListType(), + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/github.com/knative/pkg/apis/duck/v1beta1/status_types.go b/vendor/github.com/knative/pkg/apis/duck/v1beta1/status_types.go new file mode 100644 index 000000000..b999737ae --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/duck/v1beta1/status_types.go @@ -0,0 +1,140 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + "github.com/knative/pkg/apis" + "github.com/knative/pkg/apis/duck" +) + +// Conditions is a simple wrapper around apis.Conditions to implement duck.Implementable. +type Conditions apis.Conditions + +// Conditions is an Implementable "duck type". +var _ duck.Implementable = (*Conditions)(nil) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// KResource is a skeleton type wrapping Conditions in the manner we expect +// resource writers defining compatible resources to embed it. We will +// typically use this type to deserialize Conditions ObjectReferences and +// access the Conditions data. This is not a real resource. +type KResource struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Status Status `json:"status"` +} + +// Status shows how we expect folks to embed Conditions in +// their Status field. +// WARNING: Adding fields to this struct will add them to all Knative resources. +type Status struct { + // ObservedGeneration is the 'Generation' of the Service that + // was last processed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Conditions the latest available observations of a resource's current state. + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + Conditions Conditions `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +var _ apis.ConditionsAccessor = (*Status)(nil) + +// GetConditions implements apis.ConditionsAccessor +func (s *Status) GetConditions() apis.Conditions { + return apis.Conditions(s.Conditions) +} + +// SetConditions implements apis.ConditionsAccessor +func (s *Status) SetConditions(c apis.Conditions) { + s.Conditions = Conditions(c) +} + +// In order for Conditions to be Implementable, KResource must be Populatable. +var _ duck.Populatable = (*KResource)(nil) + +// Ensure KResource satisfies apis.Listable +var _ apis.Listable = (*KResource)(nil) + +// GetFullType implements duck.Implementable +func (*Conditions) GetFullType() duck.Populatable { + return &KResource{} +} + +// GetCondition fetches the condition of the specified type. +func (s *Status) GetCondition(t apis.ConditionType) *apis.Condition { + for _, cond := range s.Conditions { + if cond.Type == t { + return &cond + } + } + return nil +} + +// ConvertTo helps implement apis.Convertible for types embedding this Status. +func (source *Status) ConvertTo(ctx context.Context, sink *Status) { + sink.ObservedGeneration = source.ObservedGeneration + for _, c := range source.Conditions { + switch c.Type { + // Copy over the "happy" condition, which is the only condition that + // we can reliably transfer. + case apis.ConditionReady, apis.ConditionSucceeded: + sink.SetConditions(apis.Conditions{c}) + return + } + } +} + +// Populate implements duck.Populatable +func (t *KResource) Populate() { + t.Status.ObservedGeneration = 42 + t.Status.Conditions = Conditions{{ + // Populate ALL fields + Type: "Birthday", + Status: corev1.ConditionTrue, + LastTransitionTime: apis.VolatileTime{Inner: metav1.NewTime(time.Date(1984, 02, 28, 18, 52, 00, 00, time.UTC))}, + Reason: "Celebrate", + Message: "n3wScott, find your party hat :tada:", + }} +} + +// GetListType implements apis.Listable +func (*KResource) GetListType() runtime.Object { + return &KResourceList{} +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// KResourceList is a list of KResource resources +type KResourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []KResource `json:"items"` +} diff --git a/vendor/github.com/knative/pkg/apis/duck/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/knative/pkg/apis/duck/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 000000000..791c06d96 --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/duck/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,233 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + apis "github.com/knative/pkg/apis" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddressStatus) DeepCopyInto(out *AddressStatus) { + *out = *in + if in.Address != nil { + in, out := &in.Address, &out.Address + *out = new(Addressable) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressStatus. +func (in *AddressStatus) DeepCopy() *AddressStatus { + if in == nil { + return nil + } + out := new(AddressStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Addressable) DeepCopyInto(out *Addressable) { + *out = *in + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(apis.URL) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Addressable. +func (in *Addressable) DeepCopy() *Addressable { + if in == nil { + return nil + } + out := new(Addressable) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddressableType) DeepCopyInto(out *AddressableType) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressableType. +func (in *AddressableType) DeepCopy() *AddressableType { + if in == nil { + return nil + } + out := new(AddressableType) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AddressableType) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddressableTypeList) DeepCopyInto(out *AddressableTypeList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AddressableType, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressableTypeList. +func (in *AddressableTypeList) DeepCopy() *AddressableTypeList { + if in == nil { + return nil + } + out := new(AddressableTypeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AddressableTypeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Conditions) DeepCopyInto(out *Conditions) { + { + in := &in + *out = make(Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Conditions. +func (in Conditions) DeepCopy() Conditions { + if in == nil { + return nil + } + out := new(Conditions) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KResource) DeepCopyInto(out *KResource) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KResource. +func (in *KResource) DeepCopy() *KResource { + if in == nil { + return nil + } + out := new(KResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KResource) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KResourceList) DeepCopyInto(out *KResourceList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KResource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KResourceList. +func (in *KResourceList) DeepCopy() *KResourceList { + if in == nil { + return nil + } + out := new(KResourceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KResourceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Status) DeepCopyInto(out *Status) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. +func (in *Status) DeepCopy() *Status { + if in == nil { + return nil + } + out := new(Status) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/knative/pkg/apis/field_error.go b/vendor/github.com/knative/pkg/apis/field_error.go index eafc09b02..8b56be976 100644 --- a/vendor/github.com/knative/pkg/apis/field_error.go +++ b/vendor/github.com/knative/pkg/apis/field_error.go @@ -20,6 +20,8 @@ import ( "fmt" "sort" "strings" + + "github.com/knative/pkg/kmp" ) // CurrentField is a constant to supply as a fieldPath for when there is @@ -300,17 +302,26 @@ func ErrDisallowedFields(fieldPaths ...string) *FieldError { } } -// ErrInvalidArrayValue consturcts a FieldError for a repetetive `field` +// ErrDisallowedUpdateDeprecatedFields is a variadic helper method for +// constructing a FieldError for updating of deprecated fields. +func ErrDisallowedUpdateDeprecatedFields(fieldPaths ...string) *FieldError { + return &FieldError{ + Message: "must not update deprecated field(s)", + Paths: fieldPaths, + } +} + +// ErrInvalidArrayValue constructs a FieldError for a repetetive `field` // at `index` that has received an invalid string value. -func ErrInvalidArrayValue(value, field string, index int) *FieldError { +func ErrInvalidArrayValue(value interface{}, field string, index int) *FieldError { return ErrInvalidValue(value, CurrentField).ViaFieldIndex(field, index) } // ErrInvalidValue constructs a FieldError for a field that has received an // invalid string value. -func ErrInvalidValue(value, fieldPath string) *FieldError { +func ErrInvalidValue(value interface{}, fieldPath string) *FieldError { return &FieldError{ - Message: fmt.Sprintf("invalid value %q", value), + Message: fmt.Sprintf("invalid value: %v", value), Paths: []string{fieldPath}, } } @@ -335,9 +346,9 @@ func ErrMultipleOneOf(fieldPaths ...string) *FieldError { // ErrInvalidKeyName is a variadic helper method for constructing a FieldError // that specifies a key name that is invalid. -func ErrInvalidKeyName(value, fieldPath string, details ...string) *FieldError { +func ErrInvalidKeyName(key, fieldPath string, details ...string) *FieldError { return &FieldError{ - Message: fmt.Sprintf("invalid key name %q", value), + Message: fmt.Sprintf("invalid key name %q", key), Paths: []string{fieldPath}, Details: strings.Join(details, ", "), } @@ -345,9 +356,24 @@ func ErrInvalidKeyName(value, fieldPath string, details ...string) *FieldError { // ErrOutOfBoundsValue constructs a FieldError for a field that has received an // out of bound value. -func ErrOutOfBoundsValue(value, lower, upper, fieldPath string) *FieldError { +func ErrOutOfBoundsValue(value, lower, upper interface{}, fieldPath string) *FieldError { return &FieldError{ - Message: fmt.Sprintf("expected %s <= %s <= %s", lower, value, upper), + Message: fmt.Sprintf("expected %v <= %v <= %v", lower, value, upper), Paths: []string{fieldPath}, } } + +// CheckDisallowedFields compares the request object against a masked request object. Fields +// that are set in the request object that are unset in the mask are reported back as disallowed fields. If +// there is an error comparing the two objects FieldError of "Internal Error" is returned. +func CheckDisallowedFields(request, maskedRequest interface{}) *FieldError { + if disallowed, err := kmp.CompareSetFields(request, maskedRequest); err != nil { + return &FieldError{ + Message: fmt.Sprintf("Internal Error"), + Paths: []string{CurrentField}, + } + } else if len(disallowed) > 0 { + return ErrDisallowedFields(disallowed...) + } + return nil +} diff --git a/vendor/github.com/knative/pkg/apis/interfaces.go b/vendor/github.com/knative/pkg/apis/interfaces.go index 12ddd2aa0..601d083dd 100644 --- a/vendor/github.com/knative/pkg/apis/interfaces.go +++ b/vendor/github.com/knative/pkg/apis/interfaces.go @@ -19,7 +19,6 @@ package apis import ( "context" - authenticationv1 "k8s.io/api/authentication/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -35,8 +34,19 @@ type Validatable interface { Validate(context.Context) *FieldError } +// Convertible indicates that a particular type supports conversions to/from +// "higher" versions of the same type. +type Convertible interface { + // ConvertUp up-converts the receiver into `to`. + ConvertUp(ctx context.Context, to Convertible) error + + // ConvertDown down-converts from `from` into the receiver. + ConvertDown(ctx context.Context, from Convertible) error +} + // Immutable indicates that a particular type has fields that should // not change after creation. +// DEPRECATED: Use WithinUpdate / GetBaseline from within Validatable instead. type Immutable interface { // CheckImmutableFields checks that the current instance's immutable // fields haven't changed from the provided original. @@ -52,6 +62,7 @@ type Listable interface { } // Annotatable indicates that a particular type applies various annotations. -type Annotatable interface { - AnnotateUserInfo(ctx context.Context, previous Annotatable, ui *authenticationv1.UserInfo) -} +// DEPRECATED: Use WithUserInfo / GetUserInfo from within SetDefaults instead. +// The webhook functionality for this has been turned down, which is why this +// interface is empty. +type Annotatable interface{} diff --git a/vendor/github.com/knative/pkg/apis/metadata_validation.go b/vendor/github.com/knative/pkg/apis/metadata_validation.go new file mode 100644 index 000000000..d65fa7dd2 --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/metadata_validation.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 The Knative 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 apis + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/validation" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ValidateObjectMetadata validates that `metadata` stanza of the +// resources is correct. +func ValidateObjectMetadata(meta metav1.Object) *FieldError { + name := meta.GetName() + generateName := meta.GetGenerateName() + + if generateName != "" { + msgs := validation.NameIsDNS1035Label(generateName, true) + + if len(msgs) > 0 { + return &FieldError{ + Message: fmt.Sprintf("not a DNS 1035 label prefix: %v", msgs), + Paths: []string{"generateName"}, + } + } + } + + if name != "" { + msgs := validation.NameIsDNS1035Label(name, false) + + if len(msgs) > 0 { + return &FieldError{ + Message: fmt.Sprintf("not a DNS 1035 label: %v", msgs), + Paths: []string{"name"}, + } + } + } + + if generateName == "" && name == "" { + return &FieldError{ + Message: "name or generateName is required", + Paths: []string{"name"}, + } + } + + return nil +} diff --git a/vendor/github.com/knative/pkg/apis/url.go b/vendor/github.com/knative/pkg/apis/url.go new file mode 100644 index 000000000..c0402016f --- /dev/null +++ b/vendor/github.com/knative/pkg/apis/url.go @@ -0,0 +1,73 @@ +/* +Copyright 2019 The Knative 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 apis + +import ( + "encoding/json" + "fmt" + "net/url" +) + +// URL is an alias of url.URL. +// It has custom json marshal methods that enable it to be used in K8s CRDs +// such that the CRD resource will have the URL but operator code can can work with url.URL struct +type URL url.URL + +// ParseURL attempts to parse the given string as a URL. +func ParseURL(u string) (*URL, error) { + if u == "" { + return nil, nil + } + pu, err := url.Parse(u) + if err != nil { + return nil, err + } + return (*URL)(pu), nil +} + +// MarshalJSON implements a custom json marshal method used when this type is +// marshaled using json.Marshal. +// json.Marshaler impl +func (u URL) MarshalJSON() ([]byte, error) { + b := fmt.Sprintf("%q", u.String()) + return []byte(b), nil +} + +// UnmarshalJSON implements the json unmarshal method used when this type is +// unmarsheled using json.Unmarshal. +// json.Unmarshaler impl +func (u *URL) UnmarshalJSON(b []byte) error { + var ref string + if err := json.Unmarshal(b, &ref); err != nil { + return err + } + r, err := ParseURL(ref) + if err != nil { + return err + } + *u = *r + return nil +} + +// String returns the full string representation of the URL. +func (u *URL) String() string { + if u == nil { + return "" + } + uu := url.URL(*u) + return uu.String() +} diff --git a/vendor/github.com/knative/pkg/apis/zz_generated.deepcopy.go b/vendor/github.com/knative/pkg/apis/zz_generated.deepcopy.go index 76db35ce1..be670d4a8 100644 --- a/vendor/github.com/knative/pkg/apis/zz_generated.deepcopy.go +++ b/vendor/github.com/knative/pkg/apis/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 The Knative Authors +Copyright 2019 The Knative Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,6 +20,49 @@ limitations under the License. package apis +import ( + url "net/url" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Condition) DeepCopyInto(out *Condition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. +func (in *Condition) DeepCopy() *Condition { + if in == nil { + return nil + } + out := new(Condition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Conditions) DeepCopyInto(out *Conditions) { + { + in := &in + *out = make(Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Conditions. +func (in Conditions) DeepCopy() Conditions { + if in == nil { + return nil + } + out := new(Conditions) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FieldError) DeepCopyInto(out *FieldError) { *out = *in @@ -48,6 +91,27 @@ func (in *FieldError) DeepCopy() *FieldError { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *URL) DeepCopyInto(out *URL) { + *out = *in + if in.User != nil { + in, out := &in.User, &out.User + *out = new(url.Userinfo) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new URL. +func (in *URL) DeepCopy() *URL { + if in == nil { + return nil + } + out := new(URL) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolatileTime) DeepCopyInto(out *VolatileTime) { *out = *in diff --git a/vendor/github.com/knative/pkg/configmap/informed_watcher.go b/vendor/github.com/knative/pkg/configmap/informed_watcher.go index 2e8b492e5..5903d59d7 100644 --- a/vendor/github.com/knative/pkg/configmap/informed_watcher.go +++ b/vendor/github.com/knative/pkg/configmap/informed_watcher.go @@ -8,7 +8,7 @@ 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 -istributed under the License is istributed on an "AS IS" BASIS, +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. @@ -21,6 +21,7 @@ import ( "time" corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" informers "k8s.io/client-go/informers" corev1informers "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/kubernetes" @@ -34,7 +35,7 @@ func NewDefaultWatcher(kc kubernetes.Interface, namespace string) *InformedWatch return NewInformedWatcher(kc, namespace) } -// NewInformedWatcherFromFactory watchers a Kubernetes namespace for configmap changs +// NewInformedWatcherFromFactory watches a Kubernetes namespace for configmap changes. func NewInformedWatcherFromFactory(sif informers.SharedInformerFactory, namespace string) *InformedWatcher { return &InformedWatcher{ sif: sif, @@ -42,10 +43,11 @@ func NewInformedWatcherFromFactory(sif informers.SharedInformerFactory, namespac ManualWatcher: ManualWatcher{ Namespace: namespace, }, + defaults: make(map[string]*corev1.ConfigMap), } } -// NewInformedWatcher watchers a Kubernetes namespace for configmap changs +// NewInformedWatcher watches a Kubernetes namespace for configmap changes. func NewInformedWatcher(kc kubernetes.Interface, namespace string) *InformedWatcher { return NewInformedWatcherFromFactory(informers.NewSharedInformerFactoryWithOptions( kc, @@ -61,24 +63,58 @@ type InformedWatcher struct { informer corev1informers.ConfigMapInformer started bool + // defaults are the default ConfigMaps to use if the real ones do not exist or are deleted. + defaults map[string]*corev1.ConfigMap + // Embedding this struct allows us to reuse the logic // of registering and notifying observers. This simplifies the - // InformedWatcher to just setting up the Kubernetes informer + // InformedWatcher to just setting up the Kubernetes informer. ManualWatcher } // Asserts that InformedWatcher implements Watcher. var _ Watcher = (*InformedWatcher)(nil) -// Start implements Watcher +// Asserts that InformedWatcher implements DefaultingWatcher. +var _ DefaultingWatcher = (*InformedWatcher)(nil) + +// WatchWithDefault implements DefaultingWatcher. +func (i *InformedWatcher) WatchWithDefault(cm corev1.ConfigMap, o Observer) { + i.defaults[cm.Name] = &cm + + i.m.Lock() + started := i.started + i.m.Unlock() + if started { + // TODO make both Watch and WatchWithDefault work after the InformedWatcher has started. + // This likely entails changing this to `o(&cm)` and having Watch check started, if it has + // started, then ensuring i.informer.Lister().ConfigMaps(i.Namespace).Get(cmName) exists and + // calling this observer on it. It may require changing Watch and WatchWithDefault to return + // an error. + panic("cannot WatchWithDefault after the InformedWatcher has started") + } + + i.Watch(cm.Name, o) +} + +// Start implements Watcher. func (i *InformedWatcher) Start(stopCh <-chan struct{}) error { + // Pretend that all the defaulted ConfigMaps were just created. This is done before we start + // the informer to ensure that if a defaulted ConfigMap does exist, then the real value is + // processed after the default one. + for k := range i.observers { + if def, ok := i.defaults[k]; ok { + i.addConfigMapEvent(def) + } + } + if err := i.registerCallbackAndStartInformer(stopCh); err != nil { return err } // Wait until it has been synced (WITHOUT holing the mutex, so callbacks happen) if ok := cache.WaitForCacheSync(stopCh, i.informer.Informer().HasSynced); !ok { - return errors.New("Error waiting for ConfigMap informer to sync.") + return errors.New("error waiting for ConfigMap informer to sync") } return i.checkObservedResourcesExist() @@ -88,16 +124,17 @@ func (i *InformedWatcher) registerCallbackAndStartInformer(stopCh <-chan struct{ i.m.Lock() defer i.m.Unlock() if i.started { - return errors.New("Watcher already started!") + return errors.New("watcher already started") } i.started = true i.informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: i.addConfigMapEvent, UpdateFunc: i.updateConfigMapEvent, + DeleteFunc: i.deleteConfigMapEvent, }) - // Start the shared informer factory (non-blocking) + // Start the shared informer factory (non-blocking). i.sif.Start(stopCh) return nil } @@ -109,6 +146,12 @@ func (i *InformedWatcher) checkObservedResourcesExist() error { for k := range i.observers { _, err := i.informer.Lister().ConfigMaps(i.Namespace).Get(k) if err != nil { + if k8serrors.IsNotFound(err) { + if _, ok := i.defaults[k]; ok { + // It is defaulted, so it is OK that it doesn't exist. + continue + } + } return err } } @@ -124,3 +167,11 @@ func (i *InformedWatcher) updateConfigMapEvent(old, new interface{}) { configMap := new.(*corev1.ConfigMap) i.OnChange(configMap) } + +func (i *InformedWatcher) deleteConfigMapEvent(obj interface{}) { + configMap := obj.(*corev1.ConfigMap) + if def, ok := i.defaults[configMap.Name]; ok { + i.OnChange(def) + } + // If there is no default value, then don't do anything. +} diff --git a/vendor/github.com/knative/pkg/configmap/manual_watcher.go b/vendor/github.com/knative/pkg/configmap/manual_watcher.go index b14c5ac7b..759641058 100644 --- a/vendor/github.com/knative/pkg/configmap/manual_watcher.go +++ b/vendor/github.com/knative/pkg/configmap/manual_watcher.go @@ -29,7 +29,6 @@ type ManualWatcher struct { // Guards mutations to defaultImpl fields m sync.Mutex - started bool observers map[string][]Observer } diff --git a/vendor/github.com/knative/pkg/configmap/store.go b/vendor/github.com/knative/pkg/configmap/store.go index 62cab4324..612d07930 100644 --- a/vendor/github.com/knative/pkg/configmap/store.go +++ b/vendor/github.com/knative/pkg/configmap/store.go @@ -44,7 +44,7 @@ type Constructors map[string]interface{} // An UntypedStore is a responsible for storing and // constructing configs from Kubernetes ConfigMaps // -// WatchConfigs should be used with a configmap,Watcher +// WatchConfigs should be used with a configmap.Watcher // in order for this store to remain up to date type UntypedStore struct { name string diff --git a/vendor/github.com/knative/pkg/configmap/watcher.go b/vendor/github.com/knative/pkg/configmap/watcher.go index d248bbd73..71a18f495 100644 --- a/vendor/github.com/knative/pkg/configmap/watcher.go +++ b/vendor/github.com/knative/pkg/configmap/watcher.go @@ -26,7 +26,7 @@ import ( // contents). type Observer func(*corev1.ConfigMap) -// Watcher defined the interface that a configmap implementation must implement. +// Watcher defines the interface that a configmap implementation must implement. type Watcher interface { // Watch is called to register a callback to be notified when a named ConfigMap changes. Watch(string, Observer) @@ -36,3 +36,14 @@ type Watcher interface { // initial state of the ConfigMaps they are watching. Start(<-chan struct{}) error } + +// DefaultingWatcher is similar to Watcher, but if a ConfigMap is absent, then a code provided +// default will be used. +type DefaultingWatcher interface { + Watcher + + // WatchWithDefault is called to register a callback to be notified when a named ConfigMap + // changes. The provided default value is always observed before any real ConfigMap with that + // name is. If the real ConfigMap with that name is deleted, then the default value is observed. + WatchWithDefault(cm corev1.ConfigMap, o Observer) +} diff --git a/vendor/github.com/knative/pkg/kmp/diff.go b/vendor/github.com/knative/pkg/kmp/diff.go index ef9bae39e..09c041446 100644 --- a/vendor/github.com/knative/pkg/kmp/diff.go +++ b/vendor/github.com/knative/pkg/kmp/diff.go @@ -36,6 +36,8 @@ func init() { // SafeDiff wraps cmp.Diff but recovers from panics and uses custom Comparers for: // * k8s.io/apimachinery/pkg/api/resource.Quantity +// SafeDiff should be used instead of cmp.Diff in non-test code to protect the running +// process from crashing. func SafeDiff(x, y interface{}, opts ...cmp.Option) (diff string, err error) { // cmp.Diff will panic if we miss something; return error instead of crashing. defer func() { @@ -50,6 +52,10 @@ func SafeDiff(x, y interface{}, opts ...cmp.Option) (diff string, err error) { return } +// SafeEqual wraps cmp.Equal but recovers from panics and uses custom Comparers for: +// * k8s.io/apimachinery/pkg/api/resource.Quantity +// SafeEqual should be used instead of cmp.Equal in non-test code to protect the running +// process from crashing. func SafeEqual(x, y interface{}, opts ...cmp.Option) (equal bool, err error) { // cmp.Equal will panic if we miss something; return error instead of crashing. defer func() { @@ -63,3 +69,24 @@ func SafeEqual(x, y interface{}, opts ...cmp.Option) (equal bool, err error) { return } + +// CompareSetFields returns a list of field names that differ between +// x and y. Uses SafeEqual for comparison. +func CompareSetFields(x, y interface{}, opts ...cmp.Option) ([]string, error) { + r := new(FieldListReporter) + opts = append(opts, cmp.Reporter(r)) + _, err := SafeEqual(x, y, opts...) + return r.Fields(), err +} + +// ShortDiff returns a zero-context, unified human-readable diff. +// Uses SafeEqual for comparison. +func ShortDiff(prev, cur interface{}, opts ...cmp.Option) (string, error) { + r := new(ShortDiffReporter) + opts = append(opts, cmp.Reporter(r)) + var err error + if _, err = SafeEqual(prev, cur, opts...); err != nil { + return "", err + } + return r.Diff() +} diff --git a/vendor/github.com/knative/pkg/kmp/reporters.go b/vendor/github.com/knative/pkg/kmp/reporters.go new file mode 100644 index 000000000..e09cf2f37 --- /dev/null +++ b/vendor/github.com/knative/pkg/kmp/reporters.go @@ -0,0 +1,136 @@ +/* +Copyright 2019 The Knative 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 kmp + +import ( + "fmt" + "reflect" + "sort" + "strings" + + "github.com/google/go-cmp/cmp" +) + +// FieldListReporter implements the cmp.Reporter interface. It keeps +// track of the field names that differ between two structs and reports +// them through the Fields() function. +type FieldListReporter struct { + path cmp.Path + fieldNames []string +} + +// PushStep implements the cmp.Reporter. +func (r *FieldListReporter) PushStep(ps cmp.PathStep) { + r.path = append(r.path, ps) +} + +// fieldName returns a readable name for the field. If the field has JSON annotations it +// returns the JSON key. If the field does not have JSON annotations or the JSON annotation +// marks the field as ignored it returns the field's go name +func (r *FieldListReporter) fieldName() string { + if len(r.path) < 2 { + return r.path.Index(0).String() + } else { + fieldName := strings.TrimPrefix(r.path.Index(1).String(), ".") + // Prefer JSON name to fieldName if it exists + structField, exists := r.path.Index(0).Type().FieldByName(fieldName) + if exists { + tag := structField.Tag.Get("json") + if tag != "" && tag != "-" { + return strings.SplitN(tag, ",", 2)[0] + } + + } + return fieldName + } +} + +// Report implements the cmp.Reporter. +func (r *FieldListReporter) Report(rs cmp.Result) { + if rs.Equal() { + return + } + name := r.fieldName() + // Only append elements we don't already have. + for _, v := range r.fieldNames { + if name == v { + return + } + } + r.fieldNames = append(r.fieldNames, name) +} + +// PopStep implements cmp.Reporter. +func (r *FieldListReporter) PopStep() { + r.path = r.path[:len(r.path)-1] +} + +// Fields returns the field names that differed between the two +// objects after calling cmp.Equal with the FieldListReporter. Field names +// are returned in alphabetical order. +func (r *FieldListReporter) Fields() []string { + sort.Strings(r.fieldNames) + return r.fieldNames +} + +// ShortDiffReporter implements the cmp.Reporter interface. It reports +// on fields which have diffing values in a short zero-context, unified diff +// format. +type ShortDiffReporter struct { + path cmp.Path + diffs []string + err error +} + +// PushStep implements the cmp.Reporter. +func (r *ShortDiffReporter) PushStep(ps cmp.PathStep) { + r.path = append(r.path, ps) +} + +// Report implements the cmp.Reporter. +func (r *ShortDiffReporter) Report(rs cmp.Result) { + if rs.Equal() { + return + } + cur := r.path.Last() + vx, vy := cur.Values() + t := cur.Type() + var diff string + // Prefix struct values with the types to add clarity in output + if !vx.IsValid() || !vy.IsValid() { + r.err = fmt.Errorf("Unable to diff %+v and %+v on path %#v", vx, vy, r.path) + } else if t.Kind() == reflect.Struct { + diff = fmt.Sprintf("%#v:\n\t-: %+v: \"%+v\"\n\t+: %+v: \"%+v\"\n", r.path, t, vx, t, vy) + } else { + diff = fmt.Sprintf("%#v:\n\t-: \"%+v\"\n\t+: \"%+v\"\n", r.path, vx, vy) + } + r.diffs = append(r.diffs, diff) +} + +// PopStep implements the cmp.Reporter. +func (r *ShortDiffReporter) PopStep() { + r.path = r.path[:len(r.path)-1] +} + +// Diff returns the generated short diff for this object. +// cmp.Equal should be called before this method. +func (r *ShortDiffReporter) Diff() (string, error) { + if r.err != nil { + return "", r.err + } + return strings.Join(r.diffs, ""), nil +} diff --git a/vendor/github.com/knative/pkg/ptr/doc.go b/vendor/github.com/knative/pkg/ptr/doc.go new file mode 100644 index 000000000..1ebcea284 --- /dev/null +++ b/vendor/github.com/knative/pkg/ptr/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2019 The Knative 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 ptr holds utilities for taking pointer references to values. +package ptr diff --git a/vendor/github.com/knative/pkg/ptr/ptr.go b/vendor/github.com/knative/pkg/ptr/ptr.go new file mode 100644 index 000000000..356464733 --- /dev/null +++ b/vendor/github.com/knative/pkg/ptr/ptr.go @@ -0,0 +1,41 @@ +/* +Copyright 2019 The Knative 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 ptr + +// Int32 is a helper for turning integers into pointers for use in +// API types that want *int32. +func Int32(i int32) *int32 { + return &i +} + +// Int64 is a helper for turning integers into pointers for use in +// API types that want *int64. +func Int64(i int64) *int64 { + return &i +} + +// Bool is a helper for turning bools into pointers for use in +// API types that want *bool. +func Bool(b bool) *bool { + return &b +} + +// String is a helper for turning strings into pointers for use in +// API types that want *string. +func String(s string) *string { + return &s +} diff --git a/vendor/github.com/knative/serving/pkg/apis/autoscaling/annotation_validation.go b/vendor/github.com/knative/serving/pkg/apis/autoscaling/annotation_validation.go new file mode 100644 index 000000000..9777914f9 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/autoscaling/annotation_validation.go @@ -0,0 +1,63 @@ +/* +Copyright 2019 The Knative 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 autoscaling + +import ( + "fmt" + "strconv" + + "github.com/knative/pkg/apis" +) + +func getIntGE0(m map[string]string, k string) (int64, *apis.FieldError) { + v, ok := m[k] + if !ok { + return 0, nil + } + i, err := strconv.ParseInt(v, 10, 32) + if err != nil || i < 0 { + return 0, &apis.FieldError{ + Message: fmt.Sprintf("Invalid %s annotation value: must be an integer equal or greater than 0", k), + Paths: []string{k}, + } + } + return i, nil +} + +func ValidateAnnotations(annotations map[string]string) *apis.FieldError { + if len(annotations) == 0 { + return nil + } + + min, err := getIntGE0(annotations, MinScaleAnnotationKey) + if err != nil { + return err + } + max, err := getIntGE0(annotations, MaxScaleAnnotationKey) + if err != nil { + return err + } + + if max != 0 && max < min { + return &apis.FieldError{ + Message: fmt.Sprintf("%s=%v is less than %s=%v", MaxScaleAnnotationKey, max, MinScaleAnnotationKey, min), + Paths: []string{MaxScaleAnnotationKey, MinScaleAnnotationKey}, + } + } + + return nil +} diff --git a/vendor/github.com/knative/serving/pkg/apis/autoscaling/register.go b/vendor/github.com/knative/serving/pkg/apis/autoscaling/register.go index 90c8201a8..6807e7194 100644 --- a/vendor/github.com/knative/serving/pkg/apis/autoscaling/register.go +++ b/vendor/github.com/knative/serving/pkg/apis/autoscaling/register.go @@ -16,6 +16,8 @@ limitations under the License. package autoscaling +import "time" + const ( InternalGroupName = "autoscaling.internal.knative.dev" @@ -52,8 +54,80 @@ const ( // TargetAnnotationKey is the annotation to specify what metric value the // PodAutoscaler should attempt to maintain. For example, // autoscaling.knative.dev/metric: cpu - // autoscaling.knative.dev/target: 75 # target 75% cpu utilization + // autoscaling.knative.dev/target: "75" # target 75% cpu utilization TargetAnnotationKey = GroupName + "/target" + // TargetMin is the minimum allowable target. Values less than + // zero don't make sense. + TargetMin = 1 + + // WindowAnnotationKey is the annotation to specify the time + // interval over which to calculate the average metric. Larger + // values result in more smoothing. For example, + // autoscaling.knative.dev/metric: concurrency + // autoscaling.knative.dev/window: "2m" + // Only the kpa.autoscaling.knative.dev class autoscaler supports + // the window annotation. + WindowAnnotationKey = GroupName + "/window" + // WindowMin is the minimum allowable stable autoscaling + // window. KPA-class autoscalers calculate the desired replica + // count every 2 seconds (tick-interval in config-autoscaler) so + // the closer the window gets to that value, the more likely data + // points will be missed entirely by the panic window which is + // smaller than the stable window. Anything less than 6 second + // isn't going to work well. + WindowMin = 6 * time.Second + + // PanicWindowPercentageAnnotationKey is the annotation to + // specify the time interval over which to calculate the average + // metric during a spike. Where a spike is defined as the metric + // reaching panic level within the panic window (e.g. panic + // mode). Lower values make panic mode more sensitive. Note: + // Panic threshold can be overridden with the + // PanicThresholdPercentageAnnotationKey. For example, + // autoscaling.knative.dev/panicWindowPercentage: "5.0" + // autoscaling.knative.dev/panicThresholdPercentage: "150.0" + // Only the kpa.autoscaling.knative.dev class autoscaler supports + // the panicWindowPercentage annotation. + // Panic window is specified as a percentag to maintain the + // autoscaler's algorithm behavior when only the stable window is + // specified. The panic window will change along with the stable + // window at the default percentage. + PanicWindowPercentageAnnotationKey = GroupName + "/panicWindowPercentage" + // PanicWindowPercentageMin is the minimum allowable panic window + // percentage. The autoscaler calculates desired replicas every 2 + // seconds (tick-interval in config-autoscaler), so a panic + // window less than 2 seconds will be missing data points. One + // percent is a very small ratio and would require a stable + // window of at least 3.4 minutes. Anything less doesn't make + // sense. + PanicWindowPercentageMin = 1.0 + // PanicWindowPercentageMax is the maximum allowable panic window + // percentage. The KPA autoscaler's panic feature allows the + // autoscaler to be more responsive over a smaller time scale + // when necessary. So the panic window cannot be larger than the + // stable window. + PanicWindowPercentageMax = 100.0 + + // PanicThresholdPercentageAnnotationKey is the annotation to specify + // the level at what level panic mode will engage when reached within + // in the panic window. The level is defined as a percentage of + // the metric target. Lower values make panic mode more + // sensitive. For example, + // autoscaling.knative.dev/panicWindowPercentage: "5.0" + // autoscaling.knative.dev/panicThresholdPercentage: "150.0" + // Only the kpa.autoscaling.knative.dev class autoscaler supports + // the panicThresholdPercentage annotation + PanicThresholdPercentageAnnotationKey = GroupName + "/panicThresholdPercentage" + // PanicThresholdPercentageMin is the minimum allowable panic + // threshold percentage. The KPA autoscaler's panic feature + // allows the autoscaler to be more responsive over a smaller + // time scale when necessary. To prevent flapping, during panic + // mode the autoscaler never decreases the number of replicas. If + // the panic threshold was as small as the stable target, the + // autoscaler would always be panicking and the autoscaler would + // never scale down. One hundred and ten percent is about the + // smallest useful value. + PanicThresholdPercentageMin = 110.0 // KPALabelKey is the label key attached to a K8s Service to hint to the KPA // which services/endpoints should trigger reconciles. diff --git a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_defaults.go b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_defaults.go index 5ab0f2ac8..0eb93b22c 100644 --- a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_defaults.go +++ b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_defaults.go @@ -19,12 +19,12 @@ package v1alpha1 import ( "context" + "github.com/knative/pkg/apis" "github.com/knative/serving/pkg/apis/autoscaling" - servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" ) func (r *PodAutoscaler) SetDefaults(ctx context.Context) { - r.Spec.SetDefaults(ctx) + r.Spec.SetDefaults(apis.WithinSpec(ctx)) if r.Annotations == nil { r.Annotations = make(map[string]string) } @@ -45,10 +45,4 @@ func (r *PodAutoscaler) SetDefaults(ctx context.Context) { } } -func (rs *PodAutoscalerSpec) SetDefaults(ctx context.Context) { - // When ConcurrencyModel is specified but ContainerConcurrency - // is not (0), use the ConcurrencyModel value. - if rs.ConcurrencyModel == servingv1alpha1.RevisionRequestConcurrencyModelSingle && rs.ContainerConcurrency == 0 { - rs.ContainerConcurrency = 1 - } -} +func (rs *PodAutoscalerSpec) SetDefaults(ctx context.Context) {} diff --git a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_lifecycle.go index 8153f7ab6..6606ac540 100644 --- a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_lifecycle.go +++ b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_lifecycle.go @@ -21,13 +21,14 @@ import ( "strconv" "time" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/serving/pkg/apis/autoscaling" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" ) -var podCondSet = duckv1alpha1.NewLivingConditionSet( +var podCondSet = apis.NewLivingConditionSet( PodAutoscalerConditionActive, ) @@ -55,6 +56,15 @@ func (pa *PodAutoscaler) annotationInt32(key string) int32 { return 0 } +func (pa *PodAutoscaler) annotationFloat64(key string) (float64, bool) { + if s, ok := pa.Annotations[key]; ok { + if f, err := strconv.ParseFloat(s, 64); err == nil { + return f, true + } + } + return 0.0, false +} + // ScaleBounds returns scale bounds annotations values as a tuple: // `(min, max int32)`. The value of 0 for any of min or max means the bound is // not set @@ -77,78 +87,118 @@ func (pa *PodAutoscaler) Target() (target int32, ok bool) { return 0, false } -// IsReady looks at the conditions and if the Status has a condition -// PodAutoscalerConditionReady returns true if ConditionStatus is True -func (rs *PodAutoscalerStatus) IsReady() bool { - return podCondSet.Manage(rs).IsHappy() +// Window returns the window annotation value or false if not present. +func (pa *PodAutoscaler) Window() (window time.Duration, ok bool) { + if s, ok := pa.Annotations[autoscaling.WindowAnnotationKey]; ok { + d, err := time.ParseDuration(s) + if err != nil { + return 0, false + } + if d < autoscaling.WindowMin { + return 0, false + } + return d, true + } + return 0, false } -// IsActivating assumes the pod autoscaler is Activating if it is neither -// Active nor Inactive -func (rs *PodAutoscalerStatus) IsActivating() bool { - cond := rs.GetCondition(PodAutoscalerConditionActive) +// PanicWindowPercentage returns panic window annotation value or false if not present. +func (pa *PodAutoscaler) PanicWindowPercentage() (percentage float64, ok bool) { + percentage, ok = pa.annotationFloat64(autoscaling.PanicWindowPercentageAnnotationKey) + if !ok || percentage > autoscaling.PanicWindowPercentageMax || + percentage < autoscaling.PanicWindowPercentageMin { + return 0, false + } + return percentage, ok +} +// PanicThresholdPercentage return the panic target annotation value or false if not present. +func (pa *PodAutoscaler) PanicThresholdPercentage() (percentage float64, ok bool) { + percentage, ok = pa.annotationFloat64(autoscaling.PanicThresholdPercentageAnnotationKey) + if !ok || percentage < autoscaling.PanicThresholdPercentageMin { + return 0, false + } + return percentage, ok +} + +// IsReady looks at the conditions and if the Status has a condition +// PodAutoscalerConditionReady returns true if ConditionStatus is True +func (pas *PodAutoscalerStatus) IsReady() bool { + return podCondSet.Manage(pas.duck()).IsHappy() +} + +// IsActivating returns true if the pod autoscaler is Activating if it is neither +// Active nor Inactive +func (pas *PodAutoscalerStatus) IsActivating() bool { + cond := pas.GetCondition(PodAutoscalerConditionActive) return cond != nil && cond.Status == corev1.ConditionUnknown } -func (rs *PodAutoscalerStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { - return podCondSet.Manage(rs).GetCondition(t) +// IsInactive returns true if the pod autoscaler is Inactive. +func (pas *PodAutoscalerStatus) IsInactive() bool { + cond := pas.GetCondition(PodAutoscalerConditionActive) + return cond != nil && cond.Status == corev1.ConditionFalse } -func (rs *PodAutoscalerStatus) InitializeConditions() { - podCondSet.Manage(rs).InitializeConditions() +// GetCondition gets the condition `t`. +func (pas *PodAutoscalerStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return podCondSet.Manage(pas.duck()).GetCondition(t) } -func (rs *PodAutoscalerStatus) MarkActive() { - podCondSet.Manage(rs).MarkTrue(PodAutoscalerConditionActive) +// InitializeConditions initializes the conditionhs of the PA. +func (pas *PodAutoscalerStatus) InitializeConditions() { + podCondSet.Manage(pas.duck()).InitializeConditions() } -func (rs *PodAutoscalerStatus) MarkActivating(reason, message string) { - podCondSet.Manage(rs).MarkUnknown(PodAutoscalerConditionActive, reason, message) +// MarkActive marks the PA active. +func (pas *PodAutoscalerStatus) MarkActive() { + podCondSet.Manage(pas.duck()).MarkTrue(PodAutoscalerConditionActive) } -func (rs *PodAutoscalerStatus) MarkInactive(reason, message string) { - podCondSet.Manage(rs).MarkFalse(PodAutoscalerConditionActive, reason, message) +// MarkActivating marks the PA as activating. +func (pas *PodAutoscalerStatus) MarkActivating(reason, message string) { + podCondSet.Manage(pas.duck()).MarkUnknown(PodAutoscalerConditionActive, reason, message) +} + +// MarkInactive marks the PA as inactive. +func (pas *PodAutoscalerStatus) MarkInactive(reason, message string) { + podCondSet.Manage(pas.duck()).MarkFalse(PodAutoscalerConditionActive, reason, message) } // MarkResourceNotOwned changes the "Active" condition to false to reflect that the // resource of the given kind and name has already been created, and we do not own it. -func (rs *PodAutoscalerStatus) MarkResourceNotOwned(kind, name string) { - rs.MarkInactive("NotOwned", +func (pas *PodAutoscalerStatus) MarkResourceNotOwned(kind, name string) { + pas.MarkInactive("NotOwned", fmt.Sprintf("There is an existing %s %q that we do not own.", kind, name)) } // MarkResourceFailedCreation changes the "Active" condition to false to reflect that a // critical resource of the given kind and name was unable to be created. -func (rs *PodAutoscalerStatus) MarkResourceFailedCreation(kind, name string) { - rs.MarkInactive("FailedCreate", +func (pas *PodAutoscalerStatus) MarkResourceFailedCreation(kind, name string) { + pas.MarkInactive("FailedCreate", fmt.Sprintf("Failed to create %s %q.", kind, name)) } // CanScaleToZero checks whether the pod autoscaler has been in an inactive state // for at least the specified grace period. -func (rs *PodAutoscalerStatus) CanScaleToZero(gracePeriod time.Duration) bool { - if cond := rs.GetCondition(PodAutoscalerConditionActive); cond != nil { - switch cond.Status { - case corev1.ConditionFalse: - // Check that this PodAutoscaler has been inactive for - // at least the grace period. - return time.Now().After(cond.LastTransitionTime.Inner.Add(gracePeriod)) - } - } - return false +func (pas *PodAutoscalerStatus) CanScaleToZero(gracePeriod time.Duration) bool { + return pas.inStatusFor(corev1.ConditionFalse, gracePeriod) } // CanMarkInactive checks whether the pod autoscaler has been in an active state // for at least the specified idle period. -func (rs *PodAutoscalerStatus) CanMarkInactive(idlePeriod time.Duration) bool { - if cond := rs.GetCondition(PodAutoscalerConditionActive); cond != nil { - switch cond.Status { - case corev1.ConditionTrue: - // Check that this PodAutoscaler has been active for - // at least the grace period. - return time.Now().After(cond.LastTransitionTime.Inner.Add(idlePeriod)) - } - } - return false +func (pas *PodAutoscalerStatus) CanMarkInactive(idlePeriod time.Duration) bool { + return pas.inStatusFor(corev1.ConditionTrue, idlePeriod) +} + +// inStatusFor returns true if the PodAutoscalerStatus's Active condition has stayed in +// the specified status for at least the specified duration. Otherwise it returns false, +// including when the status is undetermined (Active condition is not found.) +func (pas *PodAutoscalerStatus) inStatusFor(status corev1.ConditionStatus, dur time.Duration) bool { + cond := pas.GetCondition(PodAutoscalerConditionActive) + return cond != nil && cond.Status == status && time.Now().After(cond.LastTransitionTime.Inner.Add(dur)) +} + +func (pas *PodAutoscalerStatus) duck() *duckv1beta1.Status { + return (*duckv1beta1.Status)(&pas.Status) } diff --git a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_types.go b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_types.go index eeee538a9..00217b896 100644 --- a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_types.go @@ -18,11 +18,12 @@ package v1alpha1 import ( "github.com/knative/pkg/apis" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/pkg/kmeta" net "github.com/knative/serving/pkg/apis/networking" servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" - autoscalingv1 "k8s.io/api/autoscaling/v1" + servingv1beta1 "github.com/knative/serving/pkg/apis/serving/v1beta1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -52,7 +53,6 @@ var ( // Check that PodAutoscaler can be validated, can be defaulted, and has immutable fields. _ apis.Validatable = (*PodAutoscaler)(nil) _ apis.Defaultable = (*PodAutoscaler)(nil) - _ apis.Immutable = (*PodAutoscaler)(nil) // Check that we can create OwnerReferences to a PodAutoscaler. _ kmeta.OwnerRefable = (*PodAutoscaler)(nil) @@ -71,11 +71,9 @@ type PodAutoscalerSpec struct { // +optional DeprecatedGeneration int64 `json:"generation,omitempty"` - // ConcurrencyModel specifies the desired concurrency model - // (Single or Multi) for the scale target. Defaults to Multi. - // Deprecated in favor of ContainerConcurrency. + // DeprecatedConcurrencyModel no longer does anything, use ContainerConcurrency. // +optional - ConcurrencyModel servingv1alpha1.RevisionRequestConcurrencyModelType `json:"concurrencyModel,omitempty"` + DeprecatedConcurrencyModel servingv1alpha1.RevisionRequestConcurrencyModelType `json:"concurrencyModel,omitempty"` // ContainerConcurrency specifies the maximum allowed // in-flight (concurrent) requests per container of the Revision. @@ -83,15 +81,15 @@ type PodAutoscalerSpec struct { // This field replaces ConcurrencyModel. A value of `1` // is equivalent to `Single` and `0` is equivalent to `Multi`. // +optional - ContainerConcurrency servingv1alpha1.RevisionContainerConcurrencyType `json:"containerConcurrency,omitempty"` + ContainerConcurrency servingv1beta1.RevisionContainerConcurrencyType `json:"containerConcurrency,omitempty"` // ScaleTargetRef defines the /scale-able resource that this PodAutoscaler // is responsible for quickly right-sizing. - ScaleTargetRef autoscalingv1.CrossVersionObjectReference `json:"scaleTargetRef"` + ScaleTargetRef corev1.ObjectReference `json:"scaleTargetRef"` - // ServiceName holds the name of a core Kubernetes Service resource that + // DeprecatedServiceName holds the name of a core Kubernetes Service resource that // load balances over the pods referenced by the ScaleTargetRef. - ServiceName string `json:"serviceName"` + DeprecatedServiceName string `json:"serviceName"` // The application-layer protocol. Matches `ProtocolType` inferred from the revision spec. ProtocolType net.ProtocolType @@ -100,13 +98,19 @@ type PodAutoscalerSpec struct { const ( // PodAutoscalerConditionReady is set when the revision is starting to materialize // runtime resources, and becomes true when those resources are ready. - PodAutoscalerConditionReady = duckv1alpha1.ConditionReady + PodAutoscalerConditionReady = apis.ConditionReady // PodAutoscalerConditionActive is set when the PodAutoscaler's ScaleTargetRef is receiving traffic. - PodAutoscalerConditionActive duckv1alpha1.ConditionType = "Active" + PodAutoscalerConditionActive apis.ConditionType = "Active" ) // PodAutoscalerStatus communicates the observed state of the PodAutoscaler (from the controller). -type PodAutoscalerStatus duckv1alpha1.Status +type PodAutoscalerStatus struct { + duckv1beta1.Status + + // ServiceName is the K8s Service name that serves the revision, scaled by this PA. + // The service is created and owned by the ServerlessService object owned by this PA. + ServiceName string `json:"serviceName"` +} // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_validation.go b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_validation.go index 688e6eee9..3ef326280 100644 --- a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_validation.go +++ b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/pa_validation.go @@ -24,16 +24,44 @@ import ( "github.com/knative/pkg/apis" "github.com/knative/pkg/kmp" "github.com/knative/serving/pkg/apis/autoscaling" - servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1" - autoscalingv1 "k8s.io/api/autoscaling/v1" + "github.com/knative/serving/pkg/apis/serving" "k8s.io/apimachinery/pkg/api/equality" ) func (pa *PodAutoscaler) Validate(ctx context.Context) *apis.FieldError { - return servingv1alpha1.ValidateObjectMetadata(pa.GetObjectMeta()). - ViaField("metadata"). - Also(pa.Spec.Validate(ctx).ViaField("spec")). - Also(pa.validateMetric()) + errs := serving.ValidateObjectMetadata(pa.GetObjectMeta()).ViaField("metadata") + errs = errs.Also(pa.validateMetric()) + errs = errs.Also(pa.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + if apis.IsInUpdate(ctx) { + original := apis.GetBaseline(ctx).(*PodAutoscaler) + errs = errs.Also(pa.checkImmutableFields(ctx, original)) + } + return errs +} + +func (current *PodAutoscaler) checkImmutableFields(ctx context.Context, original *PodAutoscaler) *apis.FieldError { + if diff, err := compareSpec(original, current); err != nil { + return &apis.FieldError{ + Message: "Failed to diff PodAutoscaler", + Paths: []string{"spec"}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec"}, + Details: diff, + } + } + // Verify the PA class does not change. + // For backward compatibility, we allow a new class where there was none before. + if oldClass, newClass, annotationChanged := classAnnotationChanged(original, current); annotationChanged { + return &apis.FieldError{ + Message: fmt.Sprintf("Immutable class annotation changed (-%q +%q)", oldClass, newClass), + Paths: []string{"annotations[autoscaling.knative.dev/class]"}, + } + } + return nil } // Validate validates PodAutoscaler Spec. @@ -41,44 +69,21 @@ func (rs *PodAutoscalerSpec) Validate(ctx context.Context) *apis.FieldError { if equality.Semantic.DeepEqual(rs, &PodAutoscalerSpec{}) { return apis.ErrMissingField(apis.CurrentField) } - errs := validateReference(rs.ScaleTargetRef).ViaField("scaleTargetRef") - if rs.ServiceName == "" { - errs = errs.Also(apis.ErrMissingField("serviceName")) - } - if err := rs.ConcurrencyModel.Validate(ctx); err != nil { - errs = errs.Also(err.ViaField("concurrencyModel")) - } else if err := servingv1alpha1.ValidateContainerConcurrency(rs.ContainerConcurrency, rs.ConcurrencyModel); err != nil { - errs = errs.Also(err) - } - return errs.Also(validateSKSFields(rs)) + errs := serving.ValidateNamespacedObjectReference(&rs.ScaleTargetRef).ViaField("scaleTargetRef") + errs = errs.Also(rs.ContainerConcurrency.Validate(ctx). + ViaField("containerConcurrency")) + return errs.Also(validateSKSFields(ctx, rs)) } -func validateSKSFields(rs *PodAutoscalerSpec) *apis.FieldError { +func validateSKSFields(ctx context.Context, rs *PodAutoscalerSpec) *apis.FieldError { var all *apis.FieldError // TODO(vagababov) stop permitting empty protocol type, once SKS controller is live. if string(rs.ProtocolType) != "" { - all = all.Also(rs.ProtocolType.Validate()).ViaField("protocolType") + all = all.Also(rs.ProtocolType.Validate(ctx)).ViaField("protocolType") } return all } -func validateReference(ref autoscalingv1.CrossVersionObjectReference) *apis.FieldError { - if equality.Semantic.DeepEqual(ref, autoscalingv1.CrossVersionObjectReference{}) { - return apis.ErrMissingField(apis.CurrentField) - } - var errs *apis.FieldError - if ref.Kind == "" { - errs = errs.Also(apis.ErrMissingField("kind")) - } - if ref.Name == "" { - errs = errs.Also(apis.ErrMissingField("name")) - } - if ref.APIVersion == "" { - errs = errs.Also(apis.ErrMissingField("apiVersion")) - } - return errs -} - func (pa *PodAutoscaler) validateMetric() *apis.FieldError { if metric, ok := pa.Annotations[autoscaling.MetricAnnotationKey]; ok { switch pa.Class() { @@ -106,13 +111,7 @@ func (pa *PodAutoscaler) validateMetric() *apis.FieldError { return nil } -// CheckImmutableFields checks the immutability of the PodAutoscaler. -func (current *PodAutoscaler) CheckImmutableFields(ctx context.Context, og apis.Immutable) *apis.FieldError { - original, ok := og.(*PodAutoscaler) - if !ok { - return &apis.FieldError{Message: "The provided original was not a PodAutoscaler"} - } - +func compareSpec(original *PodAutoscaler, current *PodAutoscaler) (string, error) { // TODO(vagababov): remove after 0.6. This is temporary plug for backwards compatibility. opt := cmp.FilterPath( func(p cmp.Path) bool { @@ -120,28 +119,18 @@ func (current *PodAutoscaler) CheckImmutableFields(ctx context.Context, og apis. }, cmp.Ignore(), ) - if diff, err := kmp.SafeDiff(original.Spec, current.Spec, opt); err != nil { - return &apis.FieldError{ - Message: "Failed to diff PodAutoscaler", - Paths: []string{"spec"}, - Details: err.Error(), - } - } else if diff != "" { - return &apis.FieldError{ - Message: "Immutable fields changed (-old +new)", - Paths: []string{"spec"}, - Details: diff, - } - } - // Verify the PA class does not change. - // For backward compatibility, we allow a new class where there was none before. - if oldClass, ok := original.Annotations[autoscaling.ClassAnnotationKey]; ok { - if newClass, ok := current.Annotations[autoscaling.ClassAnnotationKey]; !ok || oldClass != newClass { - return &apis.FieldError{ - Message: fmt.Sprintf("Immutable class annotation changed (-%q +%q)", oldClass, newClass), - Paths: []string{"annotations[autoscaling.knative.dev/class]"}, - } - } - } - return nil + + return kmp.ShortDiff(original.Spec, current.Spec, opt) +} + +func classAnnotationChanged(original *PodAutoscaler, current *PodAutoscaler) (string, string, bool) { + oldClass, ok := original.Annotations[autoscaling.ClassAnnotationKey] + if !ok { + return "", "", false + } + newClass, ok := current.Annotations[autoscaling.ClassAnnotationKey] + if ok && oldClass == newClass { + return "", "", false + } + return oldClass, newClass, true } diff --git a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/podscalable_types.go b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/podscalable_types.go new file mode 100644 index 000000000..4455986ad --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/podscalable_types.go @@ -0,0 +1,112 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "github.com/knative/pkg/apis" + "github.com/knative/pkg/apis/duck" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodScalable is a duck type that the resources referenced by the +// PodAutoscaler's ScaleTargetRef must implement. They must also +// implement the `/scale` sub-resource for use with `/scale` based +// implementations (e.g. HPA), but this further constrains the shape +// the referenced resources may take. +type PodScalable struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PodScalableSpec `json:"spec"` + Status PodScalableStatus `json:"status"` +} + +// PodScalableSpec is the specification for the desired state of a +// PodScalable (or at least our shared portion). +type PodScalableSpec struct { + Replicas *int32 `json:"replicas,omitempty"` + Selector *metav1.LabelSelector `json:"selector"` + Template corev1.PodTemplateSpec `json:"template"` +} + +// PodScalableStatus is the observed state of a PodScalable (or at +// least our shared portion). +type PodScalableStatus struct { + Replicas int32 `json:"replicas,omitempty"` +} + +var _ duck.Populatable = (*PodScalable)(nil) +var _ duck.Implementable = (*PodScalable)(nil) +var _ apis.Listable = (*PodScalable)(nil) + +// GetFullType implements duck.Implementable +func (*PodScalable) GetFullType() duck.Populatable { + return &PodScalable{} +} + +// Populate implements duck.Populatable +func (t *PodScalable) Populate() { + twelve := int32(12) + t.Spec = PodScalableSpec{ + Replicas: &twelve, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "foo": "bar", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{{ + Key: "foo", + Operator: "In", + Values: []string{"baz", "blah"}, + }}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "container-name", + Image: "container-image:latest", + }}, + }, + }, + } + t.Status = PodScalableStatus{ + Replicas: 42, + } +} + +// GetListType implements apis.Listable +func (*PodScalable) GetListType() runtime.Object { + return &PodScalableList{} +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodScalableList is a list of PodScalable resources +type PodScalableList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []PodScalable `json:"items"` +} diff --git a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/zz_generated.deepcopy.go index b797cae94..2c4a51122 100644 --- a/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/knative/serving/pkg/apis/autoscaling/v1alpha1/zz_generated.deepcopy.go @@ -16,12 +16,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This file was autogenerated by deepcopy-gen. Do not edit it manually! +// Code generated by deepcopy-gen. DO NOT EDIT. package v1alpha1 import ( - duck_v1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -49,9 +49,8 @@ func (in *PodAutoscaler) DeepCopy() *PodAutoscaler { func (in *PodAutoscaler) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -83,9 +82,8 @@ func (in *PodAutoscalerList) DeepCopy() *PodAutoscalerList { func (in *PodAutoscalerList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -108,13 +106,7 @@ func (in *PodAutoscalerSpec) DeepCopy() *PodAutoscalerSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodAutoscalerStatus) DeepCopyInto(out *PodAutoscalerStatus) { *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make(duck_v1alpha1.Conditions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + in.Status.DeepCopyInto(&out.Status) return } @@ -127,3 +119,107 @@ func (in *PodAutoscalerStatus) DeepCopy() *PodAutoscalerStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodScalable) DeepCopyInto(out *PodScalable) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodScalable. +func (in *PodScalable) DeepCopy() *PodScalable { + if in == nil { + return nil + } + out := new(PodScalable) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodScalable) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodScalableList) DeepCopyInto(out *PodScalableList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PodScalable, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodScalableList. +func (in *PodScalableList) DeepCopy() *PodScalableList { + if in == nil { + return nil + } + out := new(PodScalableList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodScalableList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodScalableSpec) DeepCopyInto(out *PodScalableSpec) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + in.Template.DeepCopyInto(&out.Template) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodScalableSpec. +func (in *PodScalableSpec) DeepCopy() *PodScalableSpec { + if in == nil { + return nil + } + out := new(PodScalableSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodScalableStatus) DeepCopyInto(out *PodScalableStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodScalableStatus. +func (in *PodScalableStatus) DeepCopy() *PodScalableStatus { + if in == nil { + return nil + } + out := new(PodScalableStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/knative/serving/pkg/apis/config/defaults.go b/vendor/github.com/knative/serving/pkg/apis/config/defaults.go index 7791a3320..232475e33 100644 --- a/vendor/github.com/knative/serving/pkg/apis/config/defaults.go +++ b/vendor/github.com/knative/serving/pkg/apis/config/defaults.go @@ -55,20 +55,26 @@ func NewDefaultsConfigFromMap(data map[string]string) (*Defaults, error) { // Process resource quantity fields for _, rsrc := range []struct { key string - field *resource.Quantity - // specified exactly when optional - defaultValue resource.Quantity + field **resource.Quantity }{{ - key: "revision-cpu-request", - field: &nc.RevisionCPURequest, - defaultValue: DefaultRevisionCPURequest, + key: "revision-cpu-request", + field: &nc.RevisionCPURequest, + }, { + key: "revision-memory-request", + field: &nc.RevisionMemoryRequest, + }, { + key: "revision-cpu-limit", + field: &nc.RevisionCPULimit, + }, { + key: "revision-memory-limit", + field: &nc.RevisionMemoryLimit, }} { if raw, ok := data[rsrc.key]; !ok { - *rsrc.field = rsrc.defaultValue + *rsrc.field = nil } else if val, err := resource.ParseQuantity(raw); err != nil { return nil, err } else { - *rsrc.field = val + *rsrc.field = &val } } @@ -85,15 +91,12 @@ const ( DefaultRevisionTimeoutSeconds = 5 * 60 ) -// Pseudo-constants -var ( - // DefaultRevisionCPURequest will be set if resources.requests.cpu is not specified. - DefaultRevisionCPURequest = resource.MustParse("400m") -) - // Defaults includes the default values to be populated by the webhook. type Defaults struct { RevisionTimeoutSeconds int64 - RevisionCPURequest resource.Quantity + RevisionCPURequest *resource.Quantity + RevisionCPULimit *resource.Quantity + RevisionMemoryRequest *resource.Quantity + RevisionMemoryLimit *resource.Quantity } diff --git a/vendor/github.com/knative/serving/pkg/apis/config/zz_generated.deepcopy.go b/vendor/github.com/knative/serving/pkg/apis/config/zz_generated.deepcopy.go index 2f5685127..d0e78d8c0 100644 --- a/vendor/github.com/knative/serving/pkg/apis/config/zz_generated.deepcopy.go +++ b/vendor/github.com/knative/serving/pkg/apis/config/zz_generated.deepcopy.go @@ -16,14 +16,33 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This file was autogenerated by deepcopy-gen. Do not edit it manually! +// Code generated by deepcopy-gen. DO NOT EDIT. package config // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Defaults) DeepCopyInto(out *Defaults) { *out = *in - out.RevisionCPURequest = in.RevisionCPURequest.DeepCopy() + if in.RevisionCPURequest != nil { + in, out := &in.RevisionCPURequest, &out.RevisionCPURequest + x := (*in).DeepCopy() + *out = &x + } + if in.RevisionCPULimit != nil { + in, out := &in.RevisionCPULimit, &out.RevisionCPULimit + x := (*in).DeepCopy() + *out = &x + } + if in.RevisionMemoryRequest != nil { + in, out := &in.RevisionMemoryRequest, &out.RevisionMemoryRequest + x := (*in).DeepCopy() + *out = &x + } + if in.RevisionMemoryLimit != nil { + in, out := &in.RevisionMemoryLimit, &out.RevisionMemoryLimit + x := (*in).DeepCopy() + *out = &x + } return } diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/generic_types.go b/vendor/github.com/knative/serving/pkg/apis/networking/generic_types.go index d13cbf1a1..7edf4fe04 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/generic_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/generic_types.go @@ -16,7 +16,11 @@ limitations under the License. package networking -import "github.com/knative/pkg/apis" +import ( + "context" + + "github.com/knative/pkg/apis" +) // This files contains the versionless types and enums that are strongly // unlikely to change from version to version. @@ -33,10 +37,10 @@ const ( ) // Validate validates that ProtocolType has a correct enum value. -func (p ProtocolType) Validate() *apis.FieldError { +func (p ProtocolType) Validate(context.Context) *apis.FieldError { switch p { case ProtocolH2C, ProtocolHTTP1: return nil } - return apis.ErrInvalidValue(string(p), apis.CurrentField) + return apis.ErrInvalidValue(p, apis.CurrentField) } diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/ports.go b/vendor/github.com/knative/serving/pkg/apis/networking/ports.go new file mode 100644 index 000000000..d2a7e1c86 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/networking/ports.go @@ -0,0 +1,63 @@ +/* +Copyright 2019 The Knative 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 networking + +// The ports we setup on our services. +const ( + // ServiceHTTPPort is the port that we setup our Serving and Activator K8s services for + // HTTP/1 endpoints. + ServiceHTTPPort = 80 + + // ServiceHTTP2Port is the port that we setup our Serving and Activator K8s services for + // HTTP/2 endpoints. + ServiceHTTP2Port = 81 + + // BackendHTTPPort is the backend, i.e. `targetPort` that we setup for HTTP services. + BackendHTTPPort = 8012 + + // BackendHTTP2Port is the backend, i.e. `targetPort` that we setup for HTTP services. + BackendHTTP2Port = 8013 + + // RequestQueueAdminPort specifies the port number for + // health check and lifecyle hooks for queue-proxy. + RequestQueueAdminPort = 8022 + + // RequestQueueMetricsPort specifies the port number for metrics emitted + // by queue-proxy. + RequestQueueMetricsPort = 9090 + + // ServicePortNameHTTP1 is the name of the external port of the service for HTTP/1.1 + ServicePortNameHTTP1 = "http" + // ServicePortNameH2C is the name of the external port of the service for HTTP/2 + ServicePortNameH2C = "http2" +) + +// ServicePortName returns the port for the app level protocol. +func ServicePortName(proto ProtocolType) string { + if proto == ProtocolH2C { + return ServicePortNameH2C + } + return ServicePortNameHTTP1 +} + +// ServicePort chooses the service (load balancer) port for the public service. +func ServicePort(proto ProtocolType) int { + if proto == ProtocolH2C { + return ServiceHTTP2Port + } + return ServiceHTTPPort +} diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/register.go b/vendor/github.com/knative/serving/pkg/apis/networking/register.go index a430d55d2..9e52e6c0e 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/register.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/register.go @@ -16,7 +16,12 @@ limitations under the License. package networking +import ( + "time" +) + const ( + // GroupName is the name for the networking API group. GroupName = "networking.internal.knative.dev" // IngressClassAnnotationKey is the annotation for the @@ -37,4 +42,45 @@ const ( // IngressLabelKey is the label key attached to underlying network programming // resources to indicate which ClusterIngress triggered their creation. IngressLabelKey = GroupName + "/clusteringress" + + // SKSLabelKey is the label key that SKS Controller attaches to the + // underlying resources it controls. + SKSLabelKey = GroupName + "/serverlessservice" + + // ServiceTypeKey is the label key attached to a service specifying the type of service. + // e.g. Public, Metrics + ServiceTypeKey = GroupName + "/serviceType" + + // OriginSecretNameLabelKey is the label key attached to the TLS secret to indicate + // the name of the origin secret that the TLS secret is copied from. + OriginSecretNameLabelKey = GroupName + "/originSecretName" + + // OriginSecretNamespaceLabelKey is the label key attached to the TLS secret + // to indicate the namespace of the origin secret that the TLS secret is copied from. + OriginSecretNamespaceLabelKey = GroupName + "/originSecretNamespace" +) + +// ServiceType is the enumeration type for the Kubernetes services +// that we have in our system, classified by usage purpose. +type ServiceType string + +const ( + // ServiceTypePrivate is the label value for internal only services + // for user applications. + ServiceTypePrivate ServiceType = "Private" + // ServiceTypePublic is the label value for externally reachable + // services for user applications. + ServiceTypePublic ServiceType = "Public" + // ServiceTypeMetrics is the label value for Metrics services. Such services + // are used for meric scraping. + ServiceTypeMetrics ServiceType = "Metrics" +) + +// Pseudo-constants +var ( + // DefaultTimeout will be set if timeout not specified. + DefaultTimeout = 10 * time.Minute + + // DefaultRetryCount will be set if Attempts not specified. + DefaultRetryCount = 3 ) diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_lifecycle.go index 90c446415..7af58af03 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_lifecycle.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_lifecycle.go @@ -17,7 +17,10 @@ limitations under the License. package v1alpha1 import ( - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "fmt" + + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -28,7 +31,24 @@ func (cs *CertificateStatus) InitializeConditions() { // MarkReady marks the certificate as ready to use. func (cs *CertificateStatus) MarkReady() { - certificateCondSet.Manage(cs).MarkTrue(CertificateCondidtionReady) + certificateCondSet.Manage(cs).MarkTrue(CertificateConditionReady) +} + +// MarkUnknown marks the certificate status as unknown. +func (cs *CertificateStatus) MarkUnknown(reason, message string) { + certificateCondSet.Manage(cs).MarkUnknown(CertificateConditionReady, reason, message) +} + +// MarkNotReady marks the certificate as not ready. +func (cs *CertificateStatus) MarkNotReady(reason, message string) { + certificateCondSet.Manage(cs).MarkFalse(CertificateConditionReady, reason, message) +} + +// MarkResourceNotOwned changes the ready condition to false to reflect that we don't own the +// resource of the given kind and name. +func (cs *CertificateStatus) MarkResourceNotOwned(kind, name string) { + certificateCondSet.Manage(cs).MarkFalse(CertificateConditionReady, "NotOwned", + fmt.Sprintf("There is an existing %s %q that we do not own.", kind, name)) } // IsReady returns true is the Certificate is ready. @@ -37,7 +57,7 @@ func (cs *CertificateStatus) IsReady() bool { } // GetCondition gets a speicifc condition of the Certificate status. -func (cs *CertificateStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { +func (cs *CertificateStatus) GetCondition(t apis.ConditionType) *apis.Condition { return certificateCondSet.Manage(cs).GetCondition(t) } @@ -45,12 +65,16 @@ func (cs *CertificateStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1a const ( // CertificateConditionReady is set when the requested certificate // is provioned and valid. - CertificateCondidtionReady = duckv1alpha1.ConditionReady + CertificateConditionReady = apis.ConditionReady ) -var certificateCondSet = duckv1alpha1.NewLivingConditionSet(CertificateCondidtionReady) +var certificateCondSet = apis.NewLivingConditionSet(CertificateConditionReady) // GetGroupVersionKind returns the GroupVersionKind of Certificate. func (c *Certificate) GetGroupVersionKind() schema.GroupVersionKind { return SchemeGroupVersion.WithKind("Certificate") } + +func (cs *CertificateStatus) duck() *duckv1beta1.Status { + return &cs.Status +} diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_types.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_types.go index 49bf5c0ea..4b07570cf 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_types.go @@ -18,7 +18,7 @@ package v1alpha1 import ( "github.com/knative/pkg/apis" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/pkg/kmeta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -83,7 +83,11 @@ type CertificateSpec struct { // CertificateStatus defines the observed state of a `Certificate`. type CertificateStatus struct { - duckv1alpha1.Status `json:",inline"` + // When Certificate status is ready, it means: + // - The target secret exists + // - The target secret contains a certificate that has not expired + // - The target secret contains a private key valid for the certificate + duckv1beta1.Status `json:",inline"` // The expiration time of the TLS certificate stored in the secret named // by this resource in spec.secretName. diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_validation.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_validation.go index b99d4879d..5fd29c738 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_validation.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/certificate_validation.go @@ -24,7 +24,7 @@ import ( // Validate inspects and validates Certificate object. func (c *Certificate) Validate(ctx context.Context) *apis.FieldError { - return c.Spec.Validate(ctx).ViaField("spec") + return c.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec") } // Validate inspects and validates CertificateSpec object. diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_defaults.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_defaults.go index a015794d7..77587358c 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_defaults.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_defaults.go @@ -18,20 +18,15 @@ package v1alpha1 import ( "context" - "time" + "github.com/knative/pkg/apis" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) -const ( - // DefaultTimeout will be set if timeout not specified. - DefaultTimeout = 10 * time.Minute - // DefaultRetryCount will be set if Attempts not specified. - DefaultRetryCount = 3 + "github.com/knative/serving/pkg/apis/networking" ) func (c *ClusterIngress) SetDefaults(ctx context.Context) { - c.Spec.SetDefaults(ctx) + c.Spec.SetDefaults(apis.WithinSpec(ctx)) } func (c *IngressSpec) SetDefaults(ctx context.Context) { @@ -74,16 +69,16 @@ func (p *HTTPClusterIngressPath) SetDefaults(ctx context.Context) { } if p.Timeout == nil { - p.Timeout = &metav1.Duration{Duration: DefaultTimeout} + p.Timeout = &metav1.Duration{Duration: networking.DefaultTimeout} } if p.Retries == nil { p.Retries = &HTTPRetry{ - PerTryTimeout: &metav1.Duration{Duration: DefaultTimeout}, - Attempts: DefaultRetryCount, + PerTryTimeout: &metav1.Duration{Duration: networking.DefaultTimeout}, + Attempts: networking.DefaultRetryCount, } } if p.Retries.PerTryTimeout == nil { - p.Retries.PerTryTimeout = &metav1.Duration{Duration: DefaultTimeout} + p.Retries.PerTryTimeout = &metav1.Duration{Duration: networking.DefaultTimeout} } } diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_lifecycle.go index 98391afb2..7e3613a52 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_lifecycle.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_lifecycle.go @@ -19,11 +19,12 @@ package v1alpha1 import ( "fmt" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "k8s.io/apimachinery/pkg/runtime/schema" ) -var clusterIngressCondSet = duckv1alpha1.NewLivingConditionSet( +var clusterIngressCondSet = apis.NewLivingConditionSet( ClusterIngressConditionNetworkConfigured, ClusterIngressConditionLoadBalancerReady, ) @@ -37,7 +38,7 @@ func (ci *ClusterIngress) IsPublic() bool { return ci.Spec.Visibility == "" || ci.Spec.Visibility == IngressVisibilityExternalIP } -func (cis *IngressStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { +func (cis *IngressStatus) GetCondition(t apis.ConditionType) *apis.Condition { return clusterIngressCondSet.Manage(cis).GetCondition(t) } @@ -71,3 +72,7 @@ func (cis *IngressStatus) MarkLoadBalancerReady(lbs []LoadBalancerIngressStatus) func (cis *IngressStatus) IsReady() bool { return clusterIngressCondSet.Manage(cis).IsHappy() } + +func (cis *IngressStatus) duck() *duckv1beta1.Status { + return &cis.Status +} diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_types.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_types.go index 4e09a0dad..7d4b771ef 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_types.go @@ -18,7 +18,7 @@ package v1alpha1 import ( "github.com/knative/pkg/apis" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/pkg/kmeta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -142,7 +142,7 @@ type ClusterIngressTLS struct { SecretNamespace string `json:"secretNamespace,omitempty"` // ServerCertificate identifies the certificate filename in the secret. - // Defaults to `tls.cert`. + // Defaults to `tls.crt`. // +optional ServerCertificate string `json:"serverCertificate,omitempty"` @@ -238,6 +238,13 @@ type ClusterIngressBackendSplit struct { // // NOTE: This differs from K8s Ingress to allow percentage split. Percent int `json:"percent,omitempty"` + + // AppendHeaders allow specifying additional HTTP headers to add + // before forwarding a request to the destination service. + // + // NOTE: This differs from K8s Ingress which doesn't allow header appending. + // +optional + AppendHeaders map[string]string `json:"appendHeaders,omitempty"` } // ClusterIngressBackend describes all endpoints for a given service and port. @@ -265,7 +272,7 @@ type HTTPRetry struct { // IngressStatus describe the current state of the ClusterIngress. type IngressStatus struct { - duckv1alpha1.Status `json:",inline"` + duckv1beta1.Status `json:",inline"` // LoadBalancer contains the current status of the load-balancer. // +optional @@ -310,15 +317,15 @@ type LoadBalancerIngressStatus struct { const ( // ClusterIngressConditionReady is set when the clusterIngress networking setting is // configured and it has a load balancer address. - ClusterIngressConditionReady = duckv1alpha1.ConditionReady + ClusterIngressConditionReady = apis.ConditionReady // ClusterIngressConditionNetworkConfigured is set when the ClusterIngress's underlying // network programming has been configured. This doesn't include conditions of the // backends, so even if this should remain true when network is configured and backends // are not ready. - ClusterIngressConditionNetworkConfigured duckv1alpha1.ConditionType = "NetworkConfigured" + ClusterIngressConditionNetworkConfigured apis.ConditionType = "NetworkConfigured" // ClusterIngressConditionLoadBalancerReady is set when the ClusterIngress has // a ready LoadBalancer. - ClusterIngressConditionLoadBalancerReady duckv1alpha1.ConditionType = "LoadBalancerReady" + ClusterIngressConditionLoadBalancerReady apis.ConditionType = "LoadBalancerReady" ) diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_validation.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_validation.go index 024e37905..70514cc56 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_validation.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/clusteringress_validation.go @@ -27,7 +27,7 @@ import ( // Validate inspects and validates ClusterIngress object. func (ci *ClusterIngress) Validate(ctx context.Context) *apis.FieldError { - return ci.Spec.Validate(ctx).ViaField("spec") + return ci.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec") } // Validate inspects and validates IngressSpec object. @@ -122,7 +122,7 @@ func (s ClusterIngressBackendSplit) Validate(ctx context.Context) *apis.FieldErr var all *apis.FieldError // Percent must be between 0 and 100. if s.Percent < 0 || s.Percent > 100 { - all = all.Also(apis.ErrInvalidValue(strconv.Itoa(s.Percent), "percent")) + all = all.Also(apis.ErrInvalidValue(s.Percent, "percent")) } return all.Also(s.ClusterIngressBackend.Validate(ctx)) } @@ -151,7 +151,7 @@ func (b ClusterIngressBackend) Validate(ctx context.Context) *apis.FieldError { func (r *HTTPRetry) Validate(ctx context.Context) *apis.FieldError { // Attempts must be greater than 0. if r.Attempts < 0 { - return apis.ErrInvalidValue(strconv.Itoa(r.Attempts), "attempts") + return apis.ErrInvalidValue(r.Attempts, "attempts") } return nil } diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_lifecycle.go index c264a1521..0c74f8724 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_lifecycle.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_lifecycle.go @@ -17,11 +17,12 @@ limitations under the License. package v1alpha1 import ( - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "k8s.io/apimachinery/pkg/runtime/schema" ) -var serverlessServiceCondSet = duckv1alpha1.NewLivingConditionSet( +var serverlessServiceCondSet = apis.NewLivingConditionSet( ServerlessServiceConditionEndspointsPopulated, ) @@ -31,7 +32,7 @@ func (ss *ServerlessService) GetGroupVersionKind() schema.GroupVersionKind { } // GetCondition returns the value of the condition `t`. -func (sss *ServerlessServiceStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { +func (sss *ServerlessServiceStatus) GetCondition(t apis.ConditionType) *apis.Condition { return serverlessServiceCondSet.Manage(sss).GetCondition(t) } @@ -40,12 +41,30 @@ func (sss *ServerlessServiceStatus) InitializeConditions() { serverlessServiceCondSet.Manage(sss).InitializeConditions() } -// MarkEndpointsPopulated marks the ServerlessServiceStatus endpoints populated condition to true. -func (sss *ServerlessServiceStatus) MarkEndpointsPopulated() { +// MarkEndpointsReady marks the ServerlessServiceStatus endpoints populated condition to true. +func (sss *ServerlessServiceStatus) MarkEndpointsReady() { serverlessServiceCondSet.Manage(sss).MarkTrue(ServerlessServiceConditionEndspointsPopulated) } +// MarkEndpointsNotOwned marks that we don't own K8s service. +func (sss *ServerlessServiceStatus) MarkEndpointsNotOwned(kind, name string) { + serverlessServiceCondSet.Manage(sss).MarkFalse( + ServerlessServiceConditionEndspointsPopulated, "NotOwned", + "Resource %s of type %s is not owned by SKS", name, kind) +} + +// MarkEndpointsNotReady marks the ServerlessServiceStatus endpoints populated conditiohn to unknown. +func (sss *ServerlessServiceStatus) MarkEndpointsNotReady(reason string) { + serverlessServiceCondSet.Manage(sss).MarkUnknown( + ServerlessServiceConditionEndspointsPopulated, reason, + "K8s Service is not ready") +} + // IsReady returns true if ServerlessService is ready. func (sss *ServerlessServiceStatus) IsReady() bool { return serverlessServiceCondSet.Manage(sss).IsHappy() } + +func (sss *ServerlessServiceStatus) duck() *duckv1beta1.Status { + return &sss.Status +} diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_types.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_types.go index 75a186d47..47fa1a5b4 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_types.go @@ -18,9 +18,10 @@ package v1alpha1 import ( "github.com/knative/pkg/apis" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/pkg/kmeta" networking "github.com/knative/serving/pkg/apis/networking" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -92,10 +93,9 @@ type ServerlessServiceSpec struct { // Mode describes the mode of operation of the ServerlessService. Mode ServerlessServiceOperationMode `json:"mode,omitempty"` - // Selector describes the pod labels for selection of pods for the - // revision. Same as K8s service selector. - // See: https://kubernetes.io/docs/concepts/services-networking/service/. - Selector map[string]string `json:"selector,omitempty"` + // ObjectRef defines the resource that this ServerlessService + // is responsible for making "serverless". + ObjectRef corev1.ObjectReference `json:"objectRef"` // The application-layer protocol. Matches `RevisionProtocolType` set on the owning pa/revision. // serving imports networking, so just use string. @@ -104,21 +104,26 @@ type ServerlessServiceSpec struct { // ServerlessServiceStatus describes the current state of the ServerlessService. type ServerlessServiceStatus struct { - duckv1alpha1.Status `json:",inline"` + duckv1beta1.Status `json:",inline"` // ServiceName holds the name of a core K8s Service resource that // load balances over the pods backing this Revision (activator or revision). // +optional ServiceName string `json:"serviceName,omitempty"` + + // PrivateServiceName holds the name of a core K8s Service resource that + // load balances over the user service pods backing this Revision. + // +optional + PrivateServiceName string `json:"privateServiceName,omitempty"` } // ConditionType represents a ServerlessService condition value const ( // ServerlessServiceConditionReady is set when the clusterIngress networking setting is // configured and it has a load balancer address. - ServerlessServiceConditionReady = duckv1alpha1.ConditionReady + ServerlessServiceConditionReady = apis.ConditionReady // ServerlessServiceConditionEndspointsPopulated is set when the ServerlessService's underlying // Revision K8s Service has been populated with endpoints. - ServerlessServiceConditionEndspointsPopulated duckv1alpha1.ConditionType = "EndpointsPopulated" + ServerlessServiceConditionEndspointsPopulated apis.ConditionType = "EndpointsPopulated" ) diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_validation.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_validation.go index 2b8a647c2..fe5151a5d 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_validation.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/serverlessservice_validation.go @@ -20,12 +20,13 @@ import ( "context" "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/serving" "k8s.io/apimachinery/pkg/api/equality" ) // Validate inspects and validates ClusterServerlessService object. func (ci *ServerlessService) Validate(ctx context.Context) *apis.FieldError { - return ci.Spec.Validate(ctx).ViaField("spec") + return ci.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec") } // Validate inspects and validates ServerlessServiceSpec object. @@ -42,20 +43,10 @@ func (spec *ServerlessServiceSpec) Validate(ctx context.Context) *apis.FieldErro case "": all = all.Also(apis.ErrMissingField("mode")) default: - all = all.Also(apis.ErrInvalidValue(string(spec.Mode), "mode")) - } - if len(spec.Selector) == 0 { - all = all.Also(apis.ErrMissingField("selector")) - } else { - for k, v := range spec.Selector { - if k == "" { - all = all.Also(apis.ErrInvalidKeyName(k, "selector", "empty key is not permitted")) - } - if v == "" { - all = all.Also(apis.ErrInvalidValue(v, apis.CurrentField).ViaKey(k).ViaField("selector")) - } - } + all = all.Also(apis.ErrInvalidValue(spec.Mode, "mode")) } - return all.Also(spec.ProtocolType.Validate().ViaField("protocolType")) + all = all.Also(serving.ValidateNamespacedObjectReference(&spec.ObjectRef).ViaField("objectRef")) + + return all.Also(spec.ProtocolType.Validate(ctx).ViaField("protocolType")) } diff --git a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/zz_generated.deepcopy.go index 026e3a7de..3f0781682 100644 --- a/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/knative/serving/pkg/apis/networking/v1alpha1/zz_generated.deepcopy.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This file was autogenerated by deepcopy-gen. Do not edit it manually! +// Code generated by deepcopy-gen. DO NOT EDIT. package v1alpha1 @@ -49,9 +49,8 @@ func (in *Certificate) DeepCopy() *Certificate { func (in *Certificate) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -83,9 +82,8 @@ func (in *CertificateList) DeepCopy() *CertificateList { func (in *CertificateList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -115,12 +113,7 @@ func (in *CertificateStatus) DeepCopyInto(out *CertificateStatus) { in.Status.DeepCopyInto(&out.Status) if in.NotAfter != nil { in, out := &in.NotAfter, &out.NotAfter - if *in == nil { - *out = nil - } else { - *out = new(v1.Time) - (*in).DeepCopyInto(*out) - } + *out = (*in).DeepCopy() } return } @@ -159,9 +152,8 @@ func (in *ClusterIngress) DeepCopy() *ClusterIngress { func (in *ClusterIngress) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -185,6 +177,13 @@ func (in *ClusterIngressBackend) DeepCopy() *ClusterIngressBackend { func (in *ClusterIngressBackendSplit) DeepCopyInto(out *ClusterIngressBackendSplit) { *out = *in out.ClusterIngressBackend = in.ClusterIngressBackend + if in.AppendHeaders != nil { + in, out := &in.AppendHeaders, &out.AppendHeaders + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } @@ -227,9 +226,8 @@ func (in *ClusterIngressList) DeepCopy() *ClusterIngressList { func (in *ClusterIngressList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -242,12 +240,8 @@ func (in *ClusterIngressRule) DeepCopyInto(out *ClusterIngressRule) { } if in.HTTP != nil { in, out := &in.HTTP, &out.HTTP - if *in == nil { - *out = nil - } else { - *out = new(HTTPClusterIngressRuleValue) - (*in).DeepCopyInto(*out) - } + *out = new(HTTPClusterIngressRuleValue) + (*in).DeepCopyInto(*out) } return } @@ -289,7 +283,9 @@ func (in *HTTPClusterIngressPath) DeepCopyInto(out *HTTPClusterIngressPath) { if in.Splits != nil { in, out := &in.Splits, &out.Splits *out = make([]ClusterIngressBackendSplit, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.AppendHeaders != nil { in, out := &in.AppendHeaders, &out.AppendHeaders @@ -300,21 +296,13 @@ func (in *HTTPClusterIngressPath) DeepCopyInto(out *HTTPClusterIngressPath) { } if in.Timeout != nil { in, out := &in.Timeout, &out.Timeout - if *in == nil { - *out = nil - } else { - *out = new(v1.Duration) - **out = **in - } + *out = new(v1.Duration) + **out = **in } if in.Retries != nil { in, out := &in.Retries, &out.Retries - if *in == nil { - *out = nil - } else { - *out = new(HTTPRetry) - (*in).DeepCopyInto(*out) - } + *out = new(HTTPRetry) + (*in).DeepCopyInto(*out) } return } @@ -357,12 +345,8 @@ func (in *HTTPRetry) DeepCopyInto(out *HTTPRetry) { *out = *in if in.PerTryTimeout != nil { in, out := &in.PerTryTimeout, &out.PerTryTimeout - if *in == nil { - *out = nil - } else { - *out = new(v1.Duration) - **out = **in - } + *out = new(v1.Duration) + **out = **in } return } @@ -413,12 +397,8 @@ func (in *IngressStatus) DeepCopyInto(out *IngressStatus) { in.Status.DeepCopyInto(&out.Status) if in.LoadBalancer != nil { in, out := &in.LoadBalancer, &out.LoadBalancer - if *in == nil { - *out = nil - } else { - *out = new(LoadBalancerStatus) - (*in).DeepCopyInto(*out) - } + *out = new(LoadBalancerStatus) + (*in).DeepCopyInto(*out) } return } @@ -475,7 +455,7 @@ func (in *ServerlessService) DeepCopyInto(out *ServerlessService) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) + out.Spec = in.Spec in.Status.DeepCopyInto(&out.Status) return } @@ -494,9 +474,8 @@ func (in *ServerlessService) DeepCopy() *ServerlessService { func (in *ServerlessService) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -528,21 +507,14 @@ func (in *ServerlessServiceList) DeepCopy() *ServerlessServiceList { func (in *ServerlessServiceList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServerlessServiceSpec) DeepCopyInto(out *ServerlessServiceSpec) { *out = *in - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } + out.ObjectRef = in.ObjectRef return } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/fieldmask.go b/vendor/github.com/knative/serving/pkg/apis/serving/fieldmask.go new file mode 100644 index 000000000..4a3b61e9e --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/fieldmask.go @@ -0,0 +1,492 @@ +/* +Copyright 2019 The Knative 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 serving + +import ( + corev1 "k8s.io/api/core/v1" +) + +// VolumeMask performs a _shallow_ copy of the Kubernetes Volume object to a new +// Kubernetes Volume object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func VolumeMask(in *corev1.Volume) *corev1.Volume { + if in == nil { + return nil + } + + out := new(corev1.Volume) + + // Allowed fields + out.Name = in.Name + out.VolumeSource = in.VolumeSource + + return out +} + +// VolumeSourceMask performs a _shallow_ copy of the Kubernetes VolumeSource object to a new +// Kubernetes VolumeSource object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func VolumeSourceMask(in *corev1.VolumeSource) *corev1.VolumeSource { + if in == nil { + return nil + } + + out := new(corev1.VolumeSource) + + // Allowed fields + out.Secret = in.Secret + out.ConfigMap = in.ConfigMap + + // Too many disallowed fields to list + + return out +} + +// PodSpecMask performs a _shallow_ copy of the Kubernetes PodSpec object to a new +// Kubernetes PodSpec object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func PodSpecMask(in *corev1.PodSpec) *corev1.PodSpec { + if in == nil { + return nil + } + + out := new(corev1.PodSpec) + + // Allowed fields + out.ServiceAccountName = in.ServiceAccountName + out.Containers = in.Containers + out.Volumes = in.Volumes + + // Disallowed fields + // This list is unnecessary, but added here for clarity + out.InitContainers = nil + out.RestartPolicy = "" + out.TerminationGracePeriodSeconds = nil + out.ActiveDeadlineSeconds = nil + out.DNSPolicy = "" + out.NodeSelector = nil + out.AutomountServiceAccountToken = nil + out.NodeName = "" + out.HostNetwork = false + out.HostPID = false + out.HostIPC = false + out.ShareProcessNamespace = nil + out.SecurityContext = nil + out.ImagePullSecrets = nil + out.Hostname = "" + out.Subdomain = "" + out.Affinity = nil + out.SchedulerName = "" + out.Tolerations = nil + out.HostAliases = nil + out.PriorityClassName = "" + out.Priority = nil + out.DNSConfig = nil + out.ReadinessGates = nil + out.RuntimeClassName = nil + // TODO(mattmoor): Coming in 1.13: out.EnableServiceLinks = nil + + return out +} + +// ContainerMask performs a _shallow_ copy of the Kubernetes Container object to a new +// Kubernetes Container object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func ContainerMask(in *corev1.Container) *corev1.Container { + if in == nil { + return nil + } + + out := new(corev1.Container) + + // Allowed fields + out.Args = in.Args + out.Command = in.Command + out.Env = in.Env + out.WorkingDir = in.WorkingDir + out.EnvFrom = in.EnvFrom + out.Image = in.Image + out.ImagePullPolicy = in.ImagePullPolicy + out.LivenessProbe = in.LivenessProbe + out.Ports = in.Ports + out.ReadinessProbe = in.ReadinessProbe + out.Resources = in.Resources + out.SecurityContext = in.SecurityContext + out.TerminationMessagePath = in.TerminationMessagePath + out.TerminationMessagePolicy = in.TerminationMessagePolicy + out.VolumeMounts = in.VolumeMounts + + // Disallowed fields + // This list is unnecessary, but added here for clarity + out.Lifecycle = nil + out.Name = "" + out.Stdin = false + out.StdinOnce = false + out.TTY = false + out.VolumeDevices = nil + + return out +} + +// VolumeMountMask performs a _shallow_ copy of the Kubernetes VolumeMount object to a new +// Kubernetes VolumeMount object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func VolumeMountMask(in *corev1.VolumeMount) *corev1.VolumeMount { + if in == nil { + return nil + } + + out := new(corev1.VolumeMount) + + // Allowed fields + out.Name = in.Name + out.ReadOnly = in.ReadOnly + out.MountPath = in.MountPath + out.SubPath = in.SubPath + + // Disallowed fields + // This list is unnecessary, but added here for clarity + out.MountPropagation = nil + + return out +} + +// ProbeMask performs a _shallow_ copy of the Kubernetes Probe object to a new +// Kubernetes Probe object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func ProbeMask(in *corev1.Probe) *corev1.Probe { + if in == nil { + return nil + } + out := new(corev1.Probe) + + // Allowed fields + out.Handler = in.Handler + out.InitialDelaySeconds = in.InitialDelaySeconds + out.TimeoutSeconds = in.TimeoutSeconds + out.PeriodSeconds = in.PeriodSeconds + out.SuccessThreshold = in.SuccessThreshold + out.FailureThreshold = in.FailureThreshold + + return out +} + +// HandlerMask performs a _shallow_ copy of the Kubernetes Handler object to a new +// Kubernetes Handler object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func HandlerMask(in *corev1.Handler) *corev1.Handler { + if in == nil { + return nil + } + out := new(corev1.Handler) + + // Allowed fields + out.Exec = in.Exec + out.HTTPGet = in.HTTPGet + out.TCPSocket = in.TCPSocket + + return out + +} + +// ExecActionMask performs a _shallow_ copy of the Kubernetes ExecAction object to a new +// Kubernetes ExecAction object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func ExecActionMask(in *corev1.ExecAction) *corev1.ExecAction { + if in == nil { + return nil + } + out := new(corev1.ExecAction) + + // Allowed fields + out.Command = in.Command + + return out +} + +// HTTPGetActionMask performs a _shallow_ copy of the Kubernetes HTTPGetAction object to a new +// Kubernetes HTTPGetAction object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func HTTPGetActionMask(in *corev1.HTTPGetAction) *corev1.HTTPGetAction { + if in == nil { + return nil + } + out := new(corev1.HTTPGetAction) + + // Allowed fields + out.Host = in.Host + out.Path = in.Path + out.Scheme = in.Scheme + out.HTTPHeaders = in.HTTPHeaders + + return out +} + +// TCPSocketActionMask performs a _shallow_ copy of the Kubernetes TCPSocketAction object to a new +// Kubernetes TCPSocketAction object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func TCPSocketActionMask(in *corev1.TCPSocketAction) *corev1.TCPSocketAction { + if in == nil { + return nil + } + out := new(corev1.TCPSocketAction) + + // Allowed fields + out.Host = in.Host + + return out +} + +// ContainerPortMask performs a _shallow_ copy of the Kubernetes ContainerPort object to a new +// Kubernetes ContainerPort object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func ContainerPortMask(in *corev1.ContainerPort) *corev1.ContainerPort { + if in == nil { + return nil + } + + out := new(corev1.ContainerPort) + + // Allowed fields + out.ContainerPort = in.ContainerPort + out.Name = in.Name + out.Protocol = in.Protocol + + //Disallowed fields + // This list is unnecessary, but added here for clarity + out.HostIP = "" + out.HostPort = 0 + + return out +} + +// EnvVarMask performs a _shallow_ copy of the Kubernetes EnvVar object to a new +// Kubernetes EnvVar object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func EnvVarMask(in *corev1.EnvVar) *corev1.EnvVar { + if in == nil { + return nil + } + + out := new(corev1.EnvVar) + + // Allowed fields + out.Name = in.Name + out.Value = in.Value + out.ValueFrom = in.ValueFrom + + return out +} + +// EnvVarSourceMask performs a _shallow_ copy of the Kubernetes EnvVarSource object to a new +// Kubernetes EnvVarSource object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func EnvVarSourceMask(in *corev1.EnvVarSource) *corev1.EnvVarSource { + if in == nil { + return nil + } + + out := new(corev1.EnvVarSource) + + // Allowed fields + out.ConfigMapKeyRef = in.ConfigMapKeyRef + out.SecretKeyRef = in.SecretKeyRef + + // Disallowed + // This list is unnecessary, but added here for clarity + out.FieldRef = nil + out.ResourceFieldRef = nil + + return out +} + +// LocalObjectReferenceMask performs a _shallow_ copy of the Kubernetes LocalObjectReference object to a new +// Kubernetes LocalObjectReference object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func LocalObjectReferenceMask(in *corev1.LocalObjectReference) *corev1.LocalObjectReference { + if in == nil { + return nil + } + + out := new(corev1.LocalObjectReference) + + out.Name = in.Name + + return out +} + +// ConfigMapKeySelectorMask performs a _shallow_ copy of the Kubernetes ConfigMapKeySelector object to a new +// Kubernetes ConfigMapKeySelector object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func ConfigMapKeySelectorMask(in *corev1.ConfigMapKeySelector) *corev1.ConfigMapKeySelector { + if in == nil { + return nil + } + + out := new(corev1.ConfigMapKeySelector) + + // Allowed fields + out.Key = in.Key + out.Optional = in.Optional + out.LocalObjectReference = in.LocalObjectReference + + return out + +} + +// SecretKeySelectorMask performs a _shallow_ copy of the Kubernetes SecretKeySelector object to a new +// Kubernetes SecretKeySelector object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func SecretKeySelectorMask(in *corev1.SecretKeySelector) *corev1.SecretKeySelector { + if in == nil { + return nil + } + + out := new(corev1.SecretKeySelector) + + // Allowed fields + out.Key = in.Key + out.Optional = in.Optional + out.LocalObjectReference = in.LocalObjectReference + + return out + +} + +// ConfigMapEnvSourceMask performs a _shallow_ copy of the Kubernetes ConfigMapEnvSource object to a new +// Kubernetes ConfigMapEnvSource object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func ConfigMapEnvSourceMask(in *corev1.ConfigMapEnvSource) *corev1.ConfigMapEnvSource { + if in == nil { + return nil + } + + out := new(corev1.ConfigMapEnvSource) + + // Allowed fields + out.Optional = in.Optional + out.LocalObjectReference = in.LocalObjectReference + + return out + +} + +// SecretEnvSourceMask performs a _shallow_ copy of the Kubernetes SecretEnvSource object to a new +// Kubernetes SecretEnvSource object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func SecretEnvSourceMask(in *corev1.SecretEnvSource) *corev1.SecretEnvSource { + if in == nil { + return nil + } + + out := new(corev1.SecretEnvSource) + + // Allowed fields + out.Optional = in.Optional + out.LocalObjectReference = in.LocalObjectReference + + return out + +} + +// EnvFromSourceMask performs a _shallow_ copy of the Kubernetes EnvFromSource object to a new +// Kubernetes EnvFromSource object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func EnvFromSourceMask(in *corev1.EnvFromSource) *corev1.EnvFromSource { + if in == nil { + return nil + } + + out := new(corev1.EnvFromSource) + + // Allowed fields + out.Prefix = in.Prefix + out.ConfigMapRef = in.ConfigMapRef + out.SecretRef = in.SecretRef + + return out +} + +// ResourceRequirementsMask performs a _shallow_ copy of the Kubernetes ResourceRequirements object to a new +// Kubernetes ResourceRequirements object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func ResourceRequirementsMask(in *corev1.ResourceRequirements) *corev1.ResourceRequirements { + if in == nil { + return nil + } + + out := new(corev1.ResourceRequirements) + + // Allowed fields + out.Limits = in.Limits + out.Requests = in.Requests + + return out + +} + +// SecurityContextMask performs a _shallow_ copy of the Kubernetes SecurityContext object to a new +// Kubernetes SecurityContext object bringing over only the fields allowed in the Knative API. This +// does not validate the contents or the bounds of the provided fields. +func SecurityContextMask(in *corev1.SecurityContext) *corev1.SecurityContext { + if in == nil { + return nil + } + + out := new(corev1.SecurityContext) + + // Allowed fields + out.RunAsUser = in.RunAsUser + + // Disallowed + // This list is unnecessary, but added here for clarity + out.Capabilities = nil + out.Privileged = nil + out.SELinuxOptions = nil + out.RunAsGroup = nil + out.RunAsNonRoot = nil + out.ReadOnlyRootFilesystem = nil + out.AllowPrivilegeEscalation = nil + out.ProcMount = nil + + return out +} + +// NamespacedObjectReferenceMask performs a _shallow_ copy of the Kubernetes ObjectReference +// object to a new Kubernetes ObjectReference object bringing over only the fields allowed in +// the Knative API. This does not validate the contents or the bounds of the provided fields. +func NamespacedObjectReferenceMask(in *corev1.ObjectReference) *corev1.ObjectReference { + if in == nil { + return nil + } + + out := new(corev1.ObjectReference) + + // Allowed fields + out.APIVersion = in.APIVersion + out.Kind = in.Kind + out.Name = in.Name + + // Disallowed + // This list is unnecessary, but added here for clarity + out.Namespace = "" + out.FieldPath = "" + out.ResourceVersion = "" + out.UID = "" + + return out +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/k8s_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/k8s_validation.go new file mode 100644 index 000000000..eebc97f0d --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/k8s_validation.go @@ -0,0 +1,382 @@ +/* +Copyright 2019 The Knative 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 serving + +import ( + "fmt" + "math" + "path/filepath" + "strings" + + "github.com/google/go-containerregistry/pkg/name" + "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/networking" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/validation" +) + +const ( + minUserID = 0 + maxUserID = math.MaxInt32 +) + +var ( + reservedPaths = sets.NewString( + "/", + "/dev", + "/dev/log", // Should be a domain socket + "/tmp", + "/var", + "/var/log", + ) + + reservedEnvVars = sets.NewString( + "PORT", + "K_SERVICE", + "K_CONFIGURATION", + "K_REVISION", + ) + + // The port is named "user-port" on the deployment, but a user cannot set an arbitrary name on the port + // in Configuration. The name field is reserved for content-negotiation. Currently 'h2c' and 'http1' are + // allowed. + // https://github.com/knative/serving/blob/master/docs/runtime-contract.md#inbound-network-connectivity + validPortNames = sets.NewString( + "h2c", + "http1", + "", + ) +) + +func ValidateVolumes(vs []corev1.Volume) (sets.String, *apis.FieldError) { + volumes := sets.NewString() + var errs *apis.FieldError + for i, volume := range vs { + if volumes.Has(volume.Name) { + errs = errs.Also((&apis.FieldError{ + Message: fmt.Sprintf("duplicate volume name %q", volume.Name), + Paths: []string{"name"}, + }).ViaIndex(i)) + } + errs = errs.Also(validateVolume(volume).ViaIndex(i)) + volumes.Insert(volume.Name) + } + return volumes, errs +} + +func validateVolume(volume corev1.Volume) *apis.FieldError { + errs := apis.CheckDisallowedFields(volume, *VolumeMask(&volume)) + if volume.Name == "" { + errs = apis.ErrMissingField("name") + } else if len(validation.IsDNS1123Label(volume.Name)) != 0 { + errs = apis.ErrInvalidValue(volume.Name, "name") + } + + vs := volume.VolumeSource + errs = errs.Also(apis.CheckDisallowedFields(vs, *VolumeSourceMask(&vs))) + if vs.Secret == nil && vs.ConfigMap == nil { + errs = errs.Also(apis.ErrMissingOneOf("secret", "configMap")) + } + return errs +} + +func validateEnvValueFrom(source *corev1.EnvVarSource) *apis.FieldError { + if source == nil { + return nil + } + return apis.CheckDisallowedFields(*source, *EnvVarSourceMask(source)) +} + +func validateEnvVar(env corev1.EnvVar) *apis.FieldError { + errs := apis.CheckDisallowedFields(env, *EnvVarMask(&env)) + + if env.Name == "" { + errs = errs.Also(apis.ErrMissingField("name")) + } else if reservedEnvVars.Has(env.Name) { + errs = errs.Also(&apis.FieldError{ + Message: fmt.Sprintf("%q is a reserved environment variable", env.Name), + Paths: []string{"name"}, + }) + } + + return errs.Also(validateEnvValueFrom(env.ValueFrom).ViaField("valueFrom")) +} + +func validateEnv(envVars []corev1.EnvVar) *apis.FieldError { + var errs *apis.FieldError + for i, env := range envVars { + errs = errs.Also(validateEnvVar(env).ViaIndex(i)) + } + return errs +} + +func validateEnvFrom(envFromList []corev1.EnvFromSource) *apis.FieldError { + var errs *apis.FieldError + for i, envFrom := range envFromList { + errs = errs.Also(apis.CheckDisallowedFields(envFrom, *EnvFromSourceMask(&envFrom)).ViaIndex(i)) + + cm := envFrom.ConfigMapRef + sm := envFrom.SecretRef + if sm != nil { + errs = errs.Also(apis.CheckDisallowedFields(*sm, *SecretEnvSourceMask(sm)).ViaIndex(i)) + errs = errs.Also(apis.CheckDisallowedFields( + sm.LocalObjectReference, *LocalObjectReferenceMask(&sm.LocalObjectReference))).ViaIndex(i).ViaField("secretRef") + } + + if cm != nil { + errs = errs.Also(apis.CheckDisallowedFields(*cm, *ConfigMapEnvSourceMask(cm)).ViaIndex(i)) + errs = errs.Also(apis.CheckDisallowedFields( + cm.LocalObjectReference, *LocalObjectReferenceMask(&cm.LocalObjectReference))).ViaIndex(i).ViaField("configMapRef") + } + if cm != nil && sm != nil { + errs = errs.Also(apis.ErrMultipleOneOf("configMapRef", "secretRef")) + } else if cm == nil && sm == nil { + errs = errs.Also(apis.ErrMissingOneOf("configMapRef", "secretRef")) + } + } + return errs +} + +func ValidatePodSpec(ps corev1.PodSpec) *apis.FieldError { + if equality.Semantic.DeepEqual(ps, corev1.PodSpec{}) { + return apis.ErrMissingField(apis.CurrentField) + } + + errs := apis.CheckDisallowedFields(ps, *PodSpecMask(&ps)) + + volumes, err := ValidateVolumes(ps.Volumes) + if err != nil { + errs = errs.Also(err.ViaField("volumes")) + } + + switch len(ps.Containers) { + case 0: + errs = errs.Also(apis.ErrMissingField("containers")) + case 1: + errs = errs.Also(ValidateContainer(ps.Containers[0], volumes). + ViaFieldIndex("containers", 0)) + default: + errs = errs.Also(apis.ErrMultipleOneOf("containers")) + } + return errs +} + +func ValidateContainer(container corev1.Container, volumes sets.String) *apis.FieldError { + if equality.Semantic.DeepEqual(container, corev1.Container{}) { + return apis.ErrMissingField(apis.CurrentField) + } + + errs := apis.CheckDisallowedFields(container, *ContainerMask(&container)) + + // Env + errs = errs.Also(validateEnv(container.Env).ViaField("env")) + // EnvFrom + errs = errs.Also(validateEnvFrom(container.EnvFrom).ViaField("envFrom")) + // Image + if _, err := name.ParseReference(container.Image, name.WeakValidation); err != nil { + fe := &apis.FieldError{ + Message: "Failed to parse image reference", + Paths: []string{"image"}, + Details: fmt.Sprintf("image: %q, error: %v", container.Image, err), + } + errs = errs.Also(fe) + } + // Liveness Probes + errs = errs.Also(validateProbe(container.LivenessProbe).ViaField("livenessProbe")) + // Ports + errs = errs.Also(validateContainerPorts(container.Ports).ViaField("ports")) + // Readiness Probes + errs = errs.Also(validateProbe(container.ReadinessProbe).ViaField("readinessProbe")) + // Resources + errs = errs.Also(validateResources(&container.Resources).ViaField("resources")) + // SecurityContext + errs = errs.Also(validateSecurityContext(container.SecurityContext).ViaField("securityContext")) + // TerminationMessagePolicy + switch container.TerminationMessagePolicy { + case corev1.TerminationMessageReadFile, corev1.TerminationMessageFallbackToLogsOnError, "": + default: + errs = errs.Also(apis.ErrInvalidValue(container.TerminationMessagePolicy, "terminationMessagePolicy")) + } + // VolumeMounts + errs = errs.Also(validateVolumeMounts(container.VolumeMounts, volumes).ViaField("volumeMounts")) + + return errs +} + +func validateResources(resources *corev1.ResourceRequirements) *apis.FieldError { + if resources == nil { + return nil + } + return apis.CheckDisallowedFields(*resources, *ResourceRequirementsMask(resources)) +} + +func validateSecurityContext(sc *corev1.SecurityContext) *apis.FieldError { + if sc == nil { + return nil + } + errs := apis.CheckDisallowedFields(*sc, *SecurityContextMask(sc)) + + if sc.RunAsUser != nil { + uid := *sc.RunAsUser + if uid < minUserID || uid > maxUserID { + errs = errs.Also(apis.ErrOutOfBoundsValue(uid, minUserID, maxUserID, "runAsUser")) + } + } + return errs +} + +func validateVolumeMounts(mounts []corev1.VolumeMount, volumes sets.String) *apis.FieldError { + var errs *apis.FieldError + // Check that volume mounts match names in "volumes", that "volumes" has 100% + // coverage, and the field restrictions. + seenName := sets.NewString() + seenMountPath := sets.NewString() + for i, vm := range mounts { + errs = errs.Also(apis.CheckDisallowedFields(vm, *VolumeMountMask(&vm)).ViaIndex(i)) + // This effectively checks that Name is non-empty because Volume name must be non-empty. + if !volumes.Has(vm.Name) { + errs = errs.Also((&apis.FieldError{ + Message: "volumeMount has no matching volume", + Paths: []string{"name"}, + }).ViaIndex(i)) + } + seenName.Insert(vm.Name) + + if vm.MountPath == "" { + errs = errs.Also(apis.ErrMissingField("mountPath").ViaIndex(i)) + } else if reservedPaths.Has(filepath.Clean(vm.MountPath)) { + errs = errs.Also((&apis.FieldError{ + Message: fmt.Sprintf("mountPath %q is a reserved path", filepath.Clean(vm.MountPath)), + Paths: []string{"mountPath"}, + }).ViaIndex(i)) + } else if !filepath.IsAbs(vm.MountPath) { + errs = errs.Also(apis.ErrInvalidValue(vm.MountPath, "mountPath").ViaIndex(i)) + } else if seenMountPath.Has(filepath.Clean(vm.MountPath)) { + errs = errs.Also(apis.ErrInvalidValue( + fmt.Sprintf("%q must be unique", vm.MountPath), "mountPath").ViaIndex(i)) + } + seenMountPath.Insert(filepath.Clean(vm.MountPath)) + + if !vm.ReadOnly { + errs = errs.Also(apis.ErrMissingField("readOnly").ViaIndex(i)) + } + + } + + if missing := volumes.Difference(seenName); missing.Len() > 0 { + errs = errs.Also(&apis.FieldError{ + Message: fmt.Sprintf("volumes not mounted: %v", missing.List()), + Paths: []string{apis.CurrentField}, + }) + } + return errs +} + +func validateContainerPorts(ports []corev1.ContainerPort) *apis.FieldError { + if len(ports) == 0 { + return nil + } + + var errs *apis.FieldError + + // user can set container port which names "user-port" to define application's port. + // Queue-proxy will use it to send requests to application + // if user didn't set any port, it will set default port user-port=8080. + if len(ports) > 1 { + errs = errs.Also(&apis.FieldError{ + Message: "More than one container port is set", + Paths: []string{apis.CurrentField}, + Details: "Only a single port is allowed", + }) + } + + userPort := ports[0] + + errs = errs.Also(apis.CheckDisallowedFields(userPort, *ContainerPortMask(&userPort))) + + // Only allow empty (defaulting to "TCP") or explicit TCP for protocol + if userPort.Protocol != "" && userPort.Protocol != corev1.ProtocolTCP { + errs = errs.Also(apis.ErrInvalidValue(userPort.Protocol, "protocol")) + } + + // Don't allow userPort to conflict with QueueProxy sidecar + if userPort.ContainerPort == networking.BackendHTTPPort || + userPort.ContainerPort == networking.BackendHTTP2Port || + userPort.ContainerPort == networking.RequestQueueAdminPort || + userPort.ContainerPort == networking.RequestQueueMetricsPort { + errs = errs.Also(apis.ErrInvalidValue(userPort.ContainerPort, "containerPort")) + } + + if userPort.ContainerPort < 1 || userPort.ContainerPort > 65535 { + errs = errs.Also(apis.ErrOutOfBoundsValue(userPort.ContainerPort, + 1, 65535, "containerPort")) + } + + if !validPortNames.Has(userPort.Name) { + errs = errs.Also(&apis.FieldError{ + Message: fmt.Sprintf("Port name %v is not allowed", ports[0].Name), + Paths: []string{apis.CurrentField}, + Details: "Name must be empty, or one of: 'h2c', 'http1'", + }) + } + + return errs +} + +func validateProbe(p *corev1.Probe) *apis.FieldError { + if p == nil { + return nil + } + errs := apis.CheckDisallowedFields(*p, *ProbeMask(p)) + + h := p.Handler + errs = errs.Also(apis.CheckDisallowedFields(h, *HandlerMask(&h))) + + switch { + case h.HTTPGet != nil: + errs = errs.Also(apis.CheckDisallowedFields(*h.HTTPGet, *HTTPGetActionMask(h.HTTPGet))).ViaField("httpGet") + case h.TCPSocket != nil: + errs = errs.Also(apis.CheckDisallowedFields(*h.TCPSocket, *TCPSocketActionMask(h.TCPSocket))).ViaField("tcpSocket") + } + return errs +} + +func ValidateNamespacedObjectReference(p *corev1.ObjectReference) *apis.FieldError { + if p == nil { + return nil + } + errs := apis.CheckDisallowedFields(*p, *NamespacedObjectReferenceMask(p)) + + if p.APIVersion == "" { + errs = errs.Also(apis.ErrMissingField("apiVersion")) + } else if verrs := validation.IsQualifiedName(p.APIVersion); len(verrs) != 0 { + errs = errs.Also(apis.ErrInvalidValue(strings.Join(verrs, ", "), "apiVersion")) + } + if p.Kind == "" { + errs = errs.Also(apis.ErrMissingField("kind")) + } else if verrs := validation.IsCIdentifier(p.Kind); len(verrs) != 0 { + errs = errs.Also(apis.ErrInvalidValue(strings.Join(verrs, ", "), "kind")) + } + if p.Name == "" { + errs = errs.Also(apis.ErrMissingField("name")) + } else if verrs := validation.IsDNS1123Label(p.Name); len(verrs) != 0 { + errs = errs.Also(apis.ErrInvalidValue(strings.Join(verrs, ", "), "name")) + } + return errs +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/metadata_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/metadata_validation.go new file mode 100644 index 000000000..2720374c1 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/metadata_validation.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative 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 serving + +import ( + "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/autoscaling" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ValidateObjectMetadata validates that `metadata` stanza of the +// resources is correct. +func ValidateObjectMetadata(meta metav1.Object) *apis.FieldError { + return apis.ValidateObjectMetadata(meta).Also( + autoscaling.ValidateAnnotations(meta.GetAnnotations()).ViaField("annotations")) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/register.go b/vendor/github.com/knative/serving/pkg/apis/serving/register.go index 1034e480a..f9bad3218 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/register.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/register.go @@ -57,11 +57,14 @@ const ( // metadata generation of the Configuration that created this revision ConfigurationGenerationLabelKey = GroupName + "/configurationGeneration" - // DeprecatedConfigurationMetadataGenerationLabelKey is the label key attached to a Revision indicating the - // metadata generation of the Configuration that created this revision - DeprecatedConfigurationMetadataGenerationLabelKey = GroupName + "/configurationMetadataGeneration" - // BuildHashLabelKey is the label key attached to a Build indicating the // hash of the spec from which they were created. BuildHashLabelKey = GroupName + "/buildHash" + + // CreatorAnnotation is the annotation key to describe the user that + // created the resource. + CreatorAnnotation = GroupName + "/creator" + // UpdaterAnnotation is the annotation key to describe the user that + // last updated the resource. + UpdaterAnnotation = GroupName + "/lastModifier" ) diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_conversion.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_conversion.go new file mode 100644 index 000000000..067d470d2 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_conversion.go @@ -0,0 +1,104 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/serving/v1beta1" +) + +// ConvertUp implements apis.Convertible +func (source *Configuration) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1beta1.Configuration: + sink.ObjectMeta = source.ObjectMeta + if err := source.Spec.ConvertUp(ctx, &sink.Spec); err != nil { + return err + } + return source.Status.ConvertUp(ctx, &sink.Status) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +// ConvertUp helps implement apis.Convertible +func (source *ConfigurationSpec) ConvertUp(ctx context.Context, sink *v1beta1.ConfigurationSpec) error { + if source.DeprecatedBuild != nil { + return ConvertErrorf("build", "build cannot be migrated forward.") + } + switch { + case source.DeprecatedRevisionTemplate != nil && source.Template != nil: + return apis.ErrMultipleOneOf("revisionTemplate", "template") + case source.DeprecatedRevisionTemplate != nil: + return source.DeprecatedRevisionTemplate.ConvertUp(ctx, &sink.Template) + case source.Template != nil: + return source.Template.ConvertUp(ctx, &sink.Template) + default: + return apis.ErrMissingOneOf("revisionTemplate", "template") + } +} + +// ConvertUp helps implement apis.Convertible +func (source *ConfigurationStatus) ConvertUp(ctx context.Context, sink *v1beta1.ConfigurationStatus) error { + source.Status.ConvertTo(ctx, &sink.Status) + + return source.ConfigurationStatusFields.ConvertUp(ctx, &sink.ConfigurationStatusFields) +} + +// ConvertUp helps implement apis.Convertible +func (source *ConfigurationStatusFields) ConvertUp(ctx context.Context, sink *v1beta1.ConfigurationStatusFields) error { + sink.LatestReadyRevisionName = source.LatestReadyRevisionName + sink.LatestCreatedRevisionName = source.LatestCreatedRevisionName + return nil +} + +// ConvertDown implements apis.Convertible +func (sink *Configuration) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1beta1.Configuration: + sink.ObjectMeta = source.ObjectMeta + if err := sink.Spec.ConvertDown(ctx, source.Spec); err != nil { + return err + } + return sink.Status.ConvertDown(ctx, source.Status) + default: + return fmt.Errorf("unknown version, got: %T", source) + } +} + +// ConvertDown helps implement apis.Convertible +func (sink *ConfigurationSpec) ConvertDown(ctx context.Context, source v1beta1.ConfigurationSpec) error { + sink.Template = &RevisionTemplateSpec{} + return sink.Template.ConvertDown(ctx, source.Template) +} + +// ConvertDown helps implement apis.Convertible +func (sink *ConfigurationStatus) ConvertDown(ctx context.Context, source v1beta1.ConfigurationStatus) error { + source.Status.ConvertTo(ctx, &sink.Status) + + return sink.ConfigurationStatusFields.ConvertDown(ctx, source.ConfigurationStatusFields) +} + +// ConvertDown helps implement apis.Convertible +func (sink *ConfigurationStatusFields) ConvertDown(ctx context.Context, source v1beta1.ConfigurationStatusFields) error { + sink.LatestReadyRevisionName = source.LatestReadyRevisionName + sink.LatestCreatedRevisionName = source.LatestCreatedRevisionName + return nil +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_defaults.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_defaults.go index 8a8937910..02dba97f4 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_defaults.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_defaults.go @@ -16,12 +16,28 @@ limitations under the License. package v1alpha1 -import "context" +import ( + "context" + + "github.com/knative/pkg/apis" + + "github.com/knative/serving/pkg/apis/serving/v1beta1" +) func (c *Configuration) SetDefaults(ctx context.Context) { - c.Spec.SetDefaults(ctx) + c.Spec.SetDefaults(apis.WithinSpec(ctx)) } func (cs *ConfigurationSpec) SetDefaults(ctx context.Context) { - cs.RevisionTemplate.Spec.SetDefaults(ctx) + if v1beta1.IsUpgradeViaDefaulting(ctx) { + beta := v1beta1.ConfigurationSpec{} + if cs.ConvertUp(ctx, &beta) == nil { + alpha := ConfigurationSpec{} + if alpha.ConvertDown(ctx, beta) == nil { + *cs = alpha + } + } + } + + cs.GetTemplate().Spec.SetDefaults(ctx) } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_lifecycle.go index 8814fb7d2..56c3dc3b5 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_lifecycle.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_lifecycle.go @@ -17,16 +17,44 @@ limitations under the License. package v1alpha1 import ( - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" ) -var confCondSet = duckv1alpha1.NewLivingConditionSet() +var confCondSet = apis.NewLivingConditionSet() func (r *Configuration) GetGroupVersionKind() schema.GroupVersionKind { return SchemeGroupVersion.WithKind("Configuration") } +// MarkResourceNotConvertible adds a Warning-severity condition to the resource noting that +// it cannot be converted to a higher version. +func (cs *ConfigurationStatus) MarkResourceNotConvertible(err *CannotConvertError) { + confCondSet.Manage(cs).SetCondition(apis.Condition{ + Type: ConditionTypeConvertible, + Status: corev1.ConditionFalse, + Severity: apis.ConditionSeverityWarning, + Reason: err.Field, + Message: err.Message, + }) +} + +// GetTemplate returns a pointer to the relevant RevisionTemplateSpec field. +// It is never nil and should be exactly the specified template as guaranteed +// by validation. +func (cs *ConfigurationSpec) GetTemplate() *RevisionTemplateSpec { + if cs.DeprecatedRevisionTemplate != nil { + return cs.DeprecatedRevisionTemplate + } + if cs.Template != nil { + return cs.Template + } + // Should be unreachable post-validation, but here to ease testing. + return &RevisionTemplateSpec{} +} + // IsReady looks at the conditions to see if they are happy. func (cs *ConfigurationStatus) IsReady() bool { return confCondSet.Manage(cs).IsHappy() @@ -40,7 +68,7 @@ func (cs *ConfigurationStatus) IsLatestReadyRevisionNameUpToDate() bool { cs.LatestCreatedRevisionName == cs.LatestReadyRevisionName } -func (cs *ConfigurationStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { +func (cs *ConfigurationStatus) GetCondition(t apis.ConditionType) *apis.Condition { return confCondSet.Manage(cs).GetCondition(t) } @@ -83,3 +111,7 @@ func (cs *ConfigurationStatus) MarkLatestReadyDeleted() { "RevisionDeleted", "Revision %q was deleted.", cs.LatestReadyRevisionName) } + +func (cs *ConfigurationStatus) duck() *duckv1beta1.Status { + return &cs.Status +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_types.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_types.go index 7fabcb773..1497c95a6 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_types.go @@ -18,7 +18,7 @@ package v1alpha1 import ( "github.com/knative/pkg/apis" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/pkg/kmeta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -52,6 +52,9 @@ var ( _ apis.Validatable = (*Configuration)(nil) _ apis.Defaultable = (*Configuration)(nil) + // Check that Configuration can be converted to higher versions. + _ apis.Convertible = (*Configuration)(nil) + // Check that we can create OwnerReferences to a Configuration. _ kmeta.OwnerRefable = (*Configuration)(nil) ) @@ -72,23 +75,29 @@ type ConfigurationSpec struct { // Build optionally holds the specification for the build to // perform to produce the Revision's container image. // +optional - Build *RawExtension `json:"build,omitempty"` + DeprecatedBuild *RawExtension `json:"build,omitempty"` - // RevisionTemplate holds the latest specification for the Revision to + // DeprecatedRevisionTemplate holds the latest specification for the Revision to // be stamped out. If a Build specification is provided, then the - // RevisionTemplate's BuildName field will be populated with the name of + // DeprecatedRevisionTemplate's BuildName field will be populated with the name of // the Build object created to produce the container for the Revision. + // DEPRECATED Use Template instead. // +optional - RevisionTemplate RevisionTemplateSpec `json:"revisionTemplate"` + DeprecatedRevisionTemplate *RevisionTemplateSpec `json:"revisionTemplate,omitempty"` + + // Template holds the latest specification for the Revision to + // be stamped out. + // +optional + Template *RevisionTemplateSpec `json:"template,omitempty"` } const ( // ConfigurationConditionReady is set when the configuration's latest // underlying revision has reported readiness. - ConfigurationConditionReady = duckv1alpha1.ConditionReady + ConfigurationConditionReady = apis.ConditionReady ) -// ConfigurationStatusFields holds all of the non-duckv1alpha1.Status status fields of a Route. +// ConfigurationStatusFields holds all of the non-duckv1beta1.Status status fields of a Route. // These are defined outline so that we can also inline them into Service, and more easily // copy them. type ConfigurationStatusFields struct { @@ -105,7 +114,7 @@ type ConfigurationStatusFields struct { // ConfigurationStatus communicates the observed state of the Configuration (from the controller). type ConfigurationStatus struct { - duckv1alpha1.Status `json:",inline"` + duckv1beta1.Status `json:",inline"` ConfigurationStatusFields `json:",inline"` } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_validation.go index 4221657f0..1e522826e 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_validation.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/configuration_validation.go @@ -24,12 +24,24 @@ import ( buildv1alpha1 "github.com/knative/build/pkg/apis/build/v1alpha1" "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/serving" ) // Validate makes sure that Configuration is properly configured. func (c *Configuration) Validate(ctx context.Context) *apis.FieldError { - return ValidateObjectMetadata(c.GetObjectMeta()).ViaField("metadata"). - Also(c.Spec.Validate(ctx).ViaField("spec")) + errs := serving.ValidateObjectMetadata(c.GetObjectMeta()).ViaField("metadata") + ctx = apis.WithinParent(ctx, c.ObjectMeta) + errs = errs.Also(c.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + + if apis.IsInUpdate(ctx) { + original := apis.GetBaseline(ctx).(*Configuration) + + err := c.Spec.GetTemplate().VerifyNameChange(ctx, + original.Spec.GetTemplate()) + errs = errs.Also(err.ViaField("spec.revisionTemplate")) + } + + return errs } // Validate makes sure that ConfigurationSpec is properly configured. @@ -37,18 +49,32 @@ func (cs *ConfigurationSpec) Validate(ctx context.Context) *apis.FieldError { if equality.Semantic.DeepEqual(cs, &ConfigurationSpec{}) { return apis.ErrMissingField(apis.CurrentField) } - var errs *apis.FieldError - // TODO(mattmoor): Check ObjectMeta for Name/Namespace/GenerateName - if cs.Build == nil { + errs := apis.CheckDeprecated(ctx, cs) + + if cs.DeprecatedBuild == nil { // No build was specified. - } else if err := cs.Build.As(&buildv1alpha1.BuildSpec{}); err == nil { + } else if err := cs.DeprecatedBuild.As(&buildv1alpha1.BuildSpec{}); err == nil { // It is a BuildSpec, this is the legacy path. - } else if err = cs.Build.As(&unstructured.Unstructured{}); err == nil { + } else if err = cs.DeprecatedBuild.As(&unstructured.Unstructured{}); err == nil { // It is an unstructured.Unstructured. } else { - errs = errs.Also(apis.ErrInvalidValue(err.Error(), "build")) + errs = errs.Also(apis.ErrInvalidValue(err, "build")) } - return errs.Also(cs.RevisionTemplate.Validate(ctx).ViaField("revisionTemplate")) + var templateField string + switch { + case cs.DeprecatedRevisionTemplate != nil && cs.Template != nil: + return apis.ErrMultipleOneOf("revisionTemplate", "template") + case cs.DeprecatedRevisionTemplate != nil: + templateField = "revisionTemplate" + case cs.Template != nil: + templateField = "template" + // Disallow the use of deprecated fields under "template". + ctx = apis.DisallowDeprecated(ctx) + default: + return apis.ErrMissingOneOf("revisionTemplate", "template") + } + + return errs.Also(cs.GetTemplate().Validate(ctx).ViaField(templateField)) } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/conversion_error.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/conversion_error.go new file mode 100644 index 000000000..96a40def7 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/conversion_error.go @@ -0,0 +1,51 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "fmt" + + "github.com/knative/pkg/apis" +) + +const ( + // ConditionTypeConvertible is a Warning condition that is set on + // resources when they cannot be converted to warn of a forthcoming + // breakage. + ConditionTypeConvertible apis.ConditionType = "Convertible" +) + +// CannotConvertError is returned when a field cannot be converted. +type CannotConvertError struct { + Message string + Field string +} + +var _ error = (*CannotConvertError)(nil) + +// Error implements error +func (cce *CannotConvertError) Error() string { + return cce.Message +} + +// ConvertErrorf creates a CannotConvertError from the field name and format string. +func ConvertErrorf(field, msg string, args ...interface{}) error { + return &CannotConvertError{ + Message: fmt.Sprintf(msg, args...), + Field: field, + } +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/metadata_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/metadata_validation.go deleted file mode 100644 index e14c24a9a..000000000 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/metadata_validation.go +++ /dev/null @@ -1,108 +0,0 @@ -/* -Copyright 2018 The Knative 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 v1alpha1 - -import ( - "fmt" - "strconv" - - "github.com/knative/pkg/apis" - "github.com/knative/serving/pkg/apis/autoscaling" - "k8s.io/apimachinery/pkg/api/validation" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// ValidateObjectMetadata validates that `metadata` stanza of the -// resources is correct. -func ValidateObjectMetadata(meta metav1.Object) *apis.FieldError { - name := meta.GetName() - generateName := meta.GetGenerateName() - - if generateName != "" { - msgs := validation.NameIsDNS1035Label(generateName, true) - - if len(msgs) > 0 { - return &apis.FieldError{ - Message: fmt.Sprintf("not a DNS 1035 label prefix: %v", msgs), - Paths: []string{"generateName"}, - } - } - } - - if name != "" { - msgs := validation.NameIsDNS1035Label(name, false) - - if len(msgs) > 0 { - return &apis.FieldError{ - Message: fmt.Sprintf("not a DNS 1035 label: %v", msgs), - Paths: []string{"name"}, - } - } - } - - if generateName == "" && name == "" { - return &apis.FieldError{ - Message: "name or generateName is required", - Paths: []string{"name"}, - } - } - - if err := validateScaleBoundsAnnotations(meta.GetAnnotations()); err != nil { - return err.ViaField("annotations") - } - - return nil -} - -func getIntGT0(m map[string]string, k string) (int64, *apis.FieldError) { - v, ok := m[k] - if ok { - i, err := strconv.ParseInt(v, 10, 32) - if err != nil || i < 1 { - return 0, &apis.FieldError{ - Message: fmt.Sprintf("Invalid %s annotation value: must be an integer greater than 0", k), - Paths: []string{k}, - } - } - return i, nil - } - return 0, nil -} - -func validateScaleBoundsAnnotations(annotations map[string]string) *apis.FieldError { - if annotations == nil { - return nil - } - - min, err := getIntGT0(annotations, autoscaling.MinScaleAnnotationKey) - if err != nil { - return err - } - max, err := getIntGT0(annotations, autoscaling.MaxScaleAnnotationKey) - if err != nil { - return err - } - - if max != 0 && max < min { - return &apis.FieldError{ - Message: fmt.Sprintf("%s=%v is less than %s=%v", autoscaling.MaxScaleAnnotationKey, max, autoscaling.MinScaleAnnotationKey, min), - Paths: []string{autoscaling.MaxScaleAnnotationKey, autoscaling.MinScaleAnnotationKey}, - } - } - - return nil -} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_conversion.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_conversion.go new file mode 100644 index 000000000..85e8b1cf8 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_conversion.go @@ -0,0 +1,117 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" + "github.com/knative/pkg/ptr" + "github.com/knative/serving/pkg/apis/serving/v1beta1" + corev1 "k8s.io/api/core/v1" +) + +// ConvertUp implements apis.Convertible +func (source *Revision) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1beta1.Revision: + sink.ObjectMeta = source.ObjectMeta + source.Status.ConvertUp(ctx, &sink.Status) + return source.Spec.ConvertUp(ctx, &sink.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +// ConvertUp helps implement apis.Convertible +func (source *RevisionTemplateSpec) ConvertUp(ctx context.Context, sink *v1beta1.RevisionTemplateSpec) error { + sink.ObjectMeta = source.ObjectMeta + return source.Spec.ConvertUp(ctx, &sink.Spec) +} + +// ConvertUp helps implement apis.Convertible +func (source *RevisionSpec) ConvertUp(ctx context.Context, sink *v1beta1.RevisionSpec) error { + sink.ContainerConcurrency = v1beta1.RevisionContainerConcurrencyType( + source.ContainerConcurrency) + if source.TimeoutSeconds != nil { + sink.TimeoutSeconds = ptr.Int64(*source.TimeoutSeconds) + } + switch { + case source.DeprecatedContainer != nil && len(source.Containers) > 0: + return apis.ErrMultipleOneOf("container", "containers") + case source.DeprecatedContainer != nil: + sink.PodSpec = v1beta1.PodSpec{ + ServiceAccountName: source.ServiceAccountName, + Containers: []corev1.Container{*source.DeprecatedContainer}, + Volumes: source.Volumes, + } + case len(source.Containers) == 1: + sink.PodSpec = source.PodSpec + case len(source.Containers) > 1: + return apis.ErrMultipleOneOf("containers") + default: + return apis.ErrMissingOneOf("container", "containers") + } + if source.DeprecatedBuildRef != nil { + return ConvertErrorf("buildRef", + "buildRef cannot be migrated forward, got: %#v", source.DeprecatedBuildRef) + } + return nil +} + +// ConvertUp helps implement apis.Convertible +func (source *RevisionStatus) ConvertUp(ctx context.Context, sink *v1beta1.RevisionStatus) { + source.Status.ConvertTo(ctx, &sink.Status) + + sink.ServiceName = source.ServiceName + sink.LogURL = source.LogURL + // TODO(mattmoor): ImageDigest? +} + +// ConvertDown implements apis.Convertible +func (sink *Revision) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1beta1.Revision: + sink.ObjectMeta = source.ObjectMeta + sink.Status.ConvertDown(ctx, source.Status) + return sink.Spec.ConvertDown(ctx, source.Spec) + default: + return fmt.Errorf("unknown version, got: %T", source) + } +} + +// ConvertDown helps implement apis.Convertible +func (sink *RevisionTemplateSpec) ConvertDown(ctx context.Context, source v1beta1.RevisionTemplateSpec) error { + sink.ObjectMeta = source.ObjectMeta + return sink.Spec.ConvertDown(ctx, source.Spec) +} + +// ConvertDown helps implement apis.Convertible +func (sink *RevisionSpec) ConvertDown(ctx context.Context, source v1beta1.RevisionSpec) error { + sink.RevisionSpec = *source.DeepCopy() + return nil +} + +// ConvertDown helps implement apis.Convertible +func (sink *RevisionStatus) ConvertDown(ctx context.Context, source v1beta1.RevisionStatus) { + source.Status.ConvertTo(ctx, &sink.Status) + + sink.ServiceName = source.ServiceName + sink.LogURL = source.LogURL + // TODO(mattmoor): ImageDigest? +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_defaults.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_defaults.go index 8b203293d..9ac6f6369 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_defaults.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_defaults.go @@ -19,17 +19,26 @@ package v1alpha1 import ( "context" + "github.com/knative/pkg/apis" corev1 "k8s.io/api/core/v1" - "github.com/knative/serving/pkg/apis/config" + "github.com/knative/serving/pkg/apis/serving/v1beta1" ) func (r *Revision) SetDefaults(ctx context.Context) { - r.Spec.SetDefaults(ctx) + r.Spec.SetDefaults(apis.WithinSpec(ctx)) } func (rs *RevisionSpec) SetDefaults(ctx context.Context) { - cfg := config.FromContextOrDefaults(ctx) + if v1beta1.IsUpgradeViaDefaulting(ctx) { + beta := v1beta1.RevisionSpec{} + if rs.ConvertUp(ctx, &beta) == nil { + alpha := RevisionSpec{} + if alpha.ConvertDown(ctx, beta) == nil { + *rs = alpha + } + } + } // When ConcurrencyModel is specified but ContainerConcurrency // is not (0), use the ConcurrencyModel value. @@ -37,19 +46,18 @@ func (rs *RevisionSpec) SetDefaults(ctx context.Context) { rs.ContainerConcurrency = 1 } - if rs.TimeoutSeconds == 0 { - rs.TimeoutSeconds = cfg.Defaults.RevisionTimeoutSeconds - } - - if rs.Container.Resources.Requests == nil { - rs.Container.Resources.Requests = corev1.ResourceList{} - } - if _, ok := rs.Container.Resources.Requests[corev1.ResourceCPU]; !ok { - rs.Container.Resources.Requests[corev1.ResourceCPU] = cfg.Defaults.RevisionCPURequest - } - - vms := rs.Container.VolumeMounts - for i := range vms { - vms[i].ReadOnly = true + // When the PodSpec has no containers, move the single Container + // into the PodSpec for the scope of defaulting and then move + // it back as we return. + if len(rs.Containers) == 0 { + if rs.DeprecatedContainer == nil { + rs.DeprecatedContainer = &corev1.Container{} + } + rs.Containers = []corev1.Container{*rs.DeprecatedContainer} + defer func() { + rs.DeprecatedContainer = &rs.Containers[0] + rs.Containers = nil + }() } + rs.RevisionSpec.SetDefaults(ctx) } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_lifecycle.go index 830d7bcd5..e33995cbb 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_lifecycle.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_lifecycle.go @@ -21,7 +21,9 @@ import ( "strconv" "time" + "github.com/knative/pkg/apis" duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" net "github.com/knative/serving/pkg/apis/networking" "github.com/knative/serving/pkg/apis/serving" corev1 "k8s.io/api/core/v1" @@ -38,32 +40,20 @@ const ( // use for connecting to the user container. DefaultUserPort = 8080 - // RequestQueuePortName specifies the port name to use for http requests - // in queue-proxy container. - RequestQueuePortName string = "queue-port" - - // RequestQueuePort specifies the port number to use for http requests - // in queue-proxy container. - RequestQueuePort = 8012 - // RequestQueueAdminPortName specifies the port name for // health check and lifecyle hooks for queue-proxy. RequestQueueAdminPortName string = "queueadm-port" - // RequestQueueAdminPort specifies the port number for - // health check and lifecyle hooks for queue-proxy. - RequestQueueAdminPort = 8022 - - // RequestQueueMetricsPort specifies the port number for metrics emitted - // by queue-proxy. - RequestQueueMetricsPort = 9090 - // RequestQueueMetricsPortName specifies the port name to use for metrics // emitted by queue-proxy. RequestQueueMetricsPortName = "queue-metrics" + + // ServiceQueueMetricsPortName is the name of the port that serves metrics + // on the Kubernetes service. + ServiceQueueMetricsPortName = "metrics" ) -var revCondSet = duckv1alpha1.NewLivingConditionSet( +var revCondSet = apis.NewLivingConditionSet( RevisionConditionResourcesAvailable, RevisionConditionContainerHealthy, RevisionConditionBuildSucceeded, @@ -75,9 +65,23 @@ func (r *Revision) GetGroupVersionKind() schema.GroupVersionKind { return SchemeGroupVersion.WithKind("Revision") } -func (r *Revision) BuildRef() *corev1.ObjectReference { - if r.Spec.BuildRef != nil { - buildRef := r.Spec.BuildRef.DeepCopy() +// GetContainer returns a pointer to the relevant corev1.Container field. +// It is never nil and should be exactly the specified container as guaranteed +// by validation. +func (rs *RevisionSpec) GetContainer() *corev1.Container { + if rs.DeprecatedContainer != nil { + return rs.DeprecatedContainer + } + if len(rs.Containers) > 0 { + return &rs.Containers[0] + } + // Should be unreachable post-validation, but here to ease testing. + return &corev1.Container{} +} + +func (r *Revision) DeprecatedBuildRef() *corev1.ObjectReference { + if r.Spec.DeprecatedBuildRef != nil { + buildRef := r.Spec.DeprecatedBuildRef.DeepCopy() if buildRef.Namespace == "" { buildRef.Namespace = r.Namespace } @@ -98,7 +102,7 @@ func (r *Revision) BuildRef() *corev1.ObjectReference { // GetProtocol returns the app level network protocol. func (r *Revision) GetProtocol() net.ProtocolType { - ports := r.Spec.Container.Ports + ports := r.Spec.GetContainer().Ports if len(ports) > 0 && ports[0].Name == string(net.ProtocolH2C) { return net.ProtocolH2C } @@ -120,7 +124,7 @@ func (rs *RevisionStatus) IsActivationRequired() bool { return false } -func (rs *RevisionStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { +func (rs *RevisionStatus) GetCondition(t apis.ConditionType) *apis.Condition { return revCondSet.Manage(rs).GetCondition(t) } @@ -143,6 +147,18 @@ func (rs *RevisionStatus) PropagateBuildStatus(bs duckv1alpha1.Status) { } } +// MarkResourceNotConvertible adds a Warning-severity condition to the resource noting that +// it cannot be converted to a higher version. +func (rs *RevisionStatus) MarkResourceNotConvertible(err *CannotConvertError) { + revCondSet.Manage(rs).SetCondition(apis.Condition{ + Type: ConditionTypeConvertible, + Status: corev1.ConditionFalse, + Severity: apis.ConditionSeverityWarning, + Reason: err.Field, + Message: err.Message, + }) +} + // MarkResourceNotOwned changes the "ResourcesAvailable" condition to false to reflect that the // resource of the given kind and name has already been created, and we do not own it. func (rs *RevisionStatus) MarkResourceNotOwned(kind, name string) { @@ -271,3 +287,7 @@ func (r *Revision) GetLastPinned() (time.Time, error) { return time.Unix(secs, 0), nil } + +func (rs *RevisionStatus) duck() *duckv1beta1.Status { + return &rs.Status +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_types.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_types.go index 5a3f55d45..33704ced3 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_types.go @@ -18,10 +18,12 @@ package v1alpha1 import ( "github.com/knative/pkg/apis" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/pkg/kmeta" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/knative/serving/pkg/apis/serving/v1beta1" ) // +genclient @@ -52,7 +54,9 @@ var ( // Check that Revision can be validated, can be defaulted, and has immutable fields. _ apis.Validatable = (*Revision)(nil) _ apis.Defaultable = (*Revision)(nil) - _ apis.Immutable = (*Revision)(nil) + + // Check that Revision can be converted to higher versions. + _ apis.Convertible = (*Revision)(nil) // Check that we can create OwnerReferences to a Revision. _ kmeta.OwnerRefable = (*Revision)(nil) @@ -89,7 +93,7 @@ const ( // RevisionRequestConcurrencyModelType is an enumeration of the // concurrency models supported by a Revision. -// Deprecated in favor of RevisionContainerConcurrencyType. +// DEPRECATED in favor of RevisionContainerConcurrencyType. type RevisionRequestConcurrencyModelType string const ( @@ -103,17 +107,10 @@ const ( RevisionRequestConcurrencyModelMulti RevisionRequestConcurrencyModelType = "Multi" ) -// RevisionContainerConcurrencyType is an integer expressing a number of -// in-flight (concurrent) requests. -type RevisionContainerConcurrencyType int64 - -const ( - // The maximum configurable container concurrency. - RevisionContainerConcurrencyMax RevisionContainerConcurrencyType = 1000 -) - // RevisionSpec holds the desired state of the Revision (from the client). type RevisionSpec struct { + v1beta1.RevisionSpec `json:",inline"` + // DeprecatedGeneration was used prior in Kubernetes versions <1.11 // when metadata.generation was not being incremented by the api server // @@ -139,34 +136,16 @@ type RevisionSpec struct { // +optional DeprecatedConcurrencyModel RevisionRequestConcurrencyModelType `json:"concurrencyModel,omitempty"` - // ContainerConcurrency specifies the maximum allowed - // in-flight (concurrent) requests per container of the Revision. - // Defaults to `0` which means unlimited concurrency. - // This field replaces ConcurrencyModel. A value of `1` - // is equivalent to `Single` and `0` is equivalent to `Multi`. - // +optional - ContainerConcurrency RevisionContainerConcurrencyType `json:"containerConcurrency,omitempty"` - - // ServiceAccountName holds the name of the Kubernetes service account - // as which the underlying K8s resources should be run. If unspecified - // this will default to the "default" service account for the namespace - // in which the Revision exists. - // This may be used to provide access to private container images by - // following: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account - // TODO(ZhiminXiang): verify the corresponding service account exists. - // +optional - ServiceAccountName string `json:"serviceAccountName,omitempty"` - // DeprecatedBuildName optionally holds the name of the Build responsible for // producing the container image for its Revision. - // DEPRECATED: Use BuildRef instead. + // DEPRECATED: Use DeprecatedBuildRef instead. // +optional DeprecatedBuildName string `json:"buildName,omitempty"` - // BuildRef holds the reference to the build (if there is one) responsible + // DeprecatedBuildRef holds the reference to the build (if there is one) responsible // for producing the container image for this Revision. Otherwise, nil // +optional - BuildRef *corev1.ObjectReference `json:"buildRef,omitempty"` + DeprecatedBuildRef *corev1.ObjectReference `json:"buildRef,omitempty"` // Container defines the unit of execution for this Revision. // In the context of a Revision, we disallow a number of the fields of @@ -175,42 +154,31 @@ type RevisionSpec struct { // environment: // https://github.com/knative/serving/blob/master/docs/runtime-contract.md // +optional - Container corev1.Container `json:"container,omitempty"` - - // Volumes defines a set of Kubernetes volumes to be mounted into the - // specified Container. Currently only ConfigMap and Secret volumes are - // supported. - Volumes []corev1.Volume `json:"volumes,omitempty"` - - // TimeoutSeconds holds the max duration the instance is allowed for responding to a request. - // +optional - TimeoutSeconds int64 `json:"timeoutSeconds,omitempty"` + DeprecatedContainer *corev1.Container `json:"container,omitempty"` } const ( // RevisionConditionReady is set when the revision is starting to materialize // runtime resources, and becomes true when those resources are ready. - RevisionConditionReady = duckv1alpha1.ConditionReady + RevisionConditionReady = apis.ConditionReady // RevisionConditionBuildSucceeded is set when the revision has an associated build // and is marked True if/once the Build has completed successfully. - RevisionConditionBuildSucceeded duckv1alpha1.ConditionType = "BuildSucceeded" + RevisionConditionBuildSucceeded apis.ConditionType = "BuildSucceeded" // RevisionConditionResourcesAvailable is set when underlying // Kubernetes resources have been provisioned. - RevisionConditionResourcesAvailable duckv1alpha1.ConditionType = "ResourcesAvailable" + RevisionConditionResourcesAvailable apis.ConditionType = "ResourcesAvailable" // RevisionConditionContainerHealthy is set when the revision readiness check completes. - RevisionConditionContainerHealthy duckv1alpha1.ConditionType = "ContainerHealthy" + RevisionConditionContainerHealthy apis.ConditionType = "ContainerHealthy" // RevisionConditionActive is set when the revision is receiving traffic. - RevisionConditionActive duckv1alpha1.ConditionType = "Active" + RevisionConditionActive apis.ConditionType = "Active" ) // RevisionStatus communicates the observed state of the Revision (from the controller). type RevisionStatus struct { - duckv1alpha1.Status `json:",inline"` + duckv1beta1.Status `json:",inline"` // ServiceName holds the name of a core Kubernetes Service resource that - // load balances over the pods backing this Revision. When the Revision - // is Active, this service would be an appropriate ingress target for - // targeting the revision. + // load balances over the pods backing this Revision. // +optional ServiceName string `json:"serviceName,omitempty"` diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_validation.go index 7dc130808..c8235f4f1 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_validation.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/revision_validation.go @@ -19,366 +19,17 @@ package v1alpha1 import ( "context" "fmt" - "path/filepath" - "strconv" + "strings" - "github.com/google/go-containerregistry/pkg/name" "github.com/knative/pkg/apis" "github.com/knative/pkg/kmp" - networkingv1alpha1 "github.com/knative/serving/pkg/apis/networking/v1alpha1" - corev1 "k8s.io/api/core/v1" + "github.com/knative/serving/pkg/apis/networking" + "github.com/knative/serving/pkg/apis/serving" "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/validation" ) -var ( - reservedPaths = sets.NewString( - "/", - "/dev", - "/dev/log", // Should be a domain socket - "/tmp", - "/var", - "/var/log", - ) -) - -// Validate ensures Revision is properly configured. -func (rt *Revision) Validate(ctx context.Context) *apis.FieldError { - return ValidateObjectMetadata(rt.GetObjectMeta()).ViaField("metadata"). - Also(rt.Spec.Validate(ctx).ViaField("spec")) -} - -// Validate ensures RevisionTemplateSpec is properly configured. -func (rt *RevisionTemplateSpec) Validate(ctx context.Context) *apis.FieldError { - var errs *apis.FieldError - if rt.GetName() != "" { - errs = errs.Also(apis.ErrDisallowedFields(apis.CurrentField).ViaField("metadata", "name")) - } - return errs.Also(rt.Spec.Validate(ctx).ViaField("spec")) -} - -// Validate ensures RevisionSpec is properly configured. -func (rs *RevisionSpec) Validate(ctx context.Context) *apis.FieldError { - if equality.Semantic.DeepEqual(rs, &RevisionSpec{}) { - return apis.ErrMissingField(apis.CurrentField) - } - - volumes := sets.NewString() - var errs *apis.FieldError - for i, volume := range rs.Volumes { - if volumes.Has(volume.Name) { - errs = errs.Also((&apis.FieldError{ - Message: fmt.Sprintf("duplicate volume name %q", volume.Name), - Paths: []string{"name"}, - }).ViaFieldIndex("volumes", i)) - } - errs = errs.Also(validateVolume(volume).ViaFieldIndex("volumes", i)) - volumes.Insert(volume.Name) - } - - errs = errs.Also(validateContainer(rs.Container, volumes).ViaField("container")) - errs = errs.Also(validateBuildRef(rs.BuildRef).ViaField("buildRef")) - - if err := rs.DeprecatedConcurrencyModel.Validate(ctx).ViaField("concurrencyModel"); err != nil { - errs = errs.Also(err) - } else { - errs = errs.Also(ValidateContainerConcurrency( - rs.ContainerConcurrency, rs.DeprecatedConcurrencyModel)) - } - - return errs.Also(validateTimeoutSeconds(rs.TimeoutSeconds)) -} - -func validateTimeoutSeconds(timeoutSeconds int64) *apis.FieldError { - if timeoutSeconds != 0 { - if timeoutSeconds > int64(networkingv1alpha1.DefaultTimeout.Seconds()) || timeoutSeconds < 0 { - return apis.ErrOutOfBoundsValue(fmt.Sprintf("%ds", timeoutSeconds), "0s", - fmt.Sprintf("%ds", int(networkingv1alpha1.DefaultTimeout.Seconds())), - "timeoutSeconds") - } - } - return nil -} - -// Validate ensures RevisionRequestConcurrencyModelType is properly configured. -func (ss DeprecatedRevisionServingStateType) Validate(ctx context.Context) *apis.FieldError { - switch ss { - case DeprecatedRevisionServingStateType(""), - DeprecatedRevisionServingStateRetired, - DeprecatedRevisionServingStateReserve, - DeprecatedRevisionServingStateActive: - return nil - default: - return apis.ErrInvalidValue(string(ss), apis.CurrentField) - } -} - -// Validate ensures RevisionRequestConcurrencyModelType is properly configured. -func (cm RevisionRequestConcurrencyModelType) Validate(ctx context.Context) *apis.FieldError { - switch cm { - case RevisionRequestConcurrencyModelType(""), - RevisionRequestConcurrencyModelMulti, - RevisionRequestConcurrencyModelSingle: - return nil - default: - return apis.ErrInvalidValue(string(cm), apis.CurrentField) - } -} - -// ValidateContainerConcurrency ensures ContainerConcurrency is properly configured. -func ValidateContainerConcurrency(cc RevisionContainerConcurrencyType, cm RevisionRequestConcurrencyModelType) *apis.FieldError { - // Validate ContainerConcurrency alone - if cc < 0 || cc > RevisionContainerConcurrencyMax { - return apis.ErrInvalidValue(strconv.Itoa(int(cc)), "containerConcurrency") - } - - // Validate combinations of ConcurrencyModel and ContainerConcurrency - if cc == 0 && cm != RevisionRequestConcurrencyModelMulti && cm != RevisionRequestConcurrencyModelType("") { - return apis.ErrMultipleOneOf("containerConcurrency", "concurrencyModel") - } - if cc == 1 && cm != RevisionRequestConcurrencyModelSingle && cm != RevisionRequestConcurrencyModelType("") { - return apis.ErrMultipleOneOf("containerConcurrency", "concurrencyModel") - } - if cc > 1 && cm != RevisionRequestConcurrencyModelType("") { - return apis.ErrMultipleOneOf("containerConcurrency", "concurrencyModel") - } - - return nil -} - -func validateVolume(volume corev1.Volume) *apis.FieldError { - var errs *apis.FieldError - if volume.Name == "" { - errs = apis.ErrMissingField("name") - } else if len(validation.IsDNS1123Label(volume.Name)) != 0 { - errs = apis.ErrInvalidValue(volume.Name, "name") - } - - vs := volume.VolumeSource - switch { - case vs.Secret != nil, vs.ConfigMap != nil: - // These are fine. - default: - errs = errs.Also(apis.ErrMissingOneOf("secret", "configMap")) - } - return errs -} - -func validateContainer(container corev1.Container, volumes sets.String) *apis.FieldError { - if equality.Semantic.DeepEqual(container, corev1.Container{}) { - return apis.ErrMissingField(apis.CurrentField) - } - - // Check that volume mounts match names in "volumes", that "volumes" has 100% - // coverage, and the field restrictions. - seen := sets.NewString() - var errs *apis.FieldError - for i, vm := range container.VolumeMounts { - // This effectively checks that Name is non-empty because Volume name must be non-empty. - if !volumes.Has(vm.Name) { - errs = errs.Also((&apis.FieldError{ - Message: "volumeMount has no matching volume", - Paths: []string{"name"}, - }).ViaFieldIndex("volumeMounts", i)) - } - seen.Insert(vm.Name) - - if vm.MountPath == "" { - errs = errs.Also(apis.ErrMissingField("mountPath").ViaFieldIndex("volumeMounts", i)) - } else if reservedPaths.Has(filepath.Clean(vm.MountPath)) { - errs = errs.Also((&apis.FieldError{ - Message: fmt.Sprintf("mountPath %q is a reserved path", filepath.Clean(vm.MountPath)), - Paths: []string{"mountPath"}, - }).ViaFieldIndex("volumeMounts", i)) - } else if !filepath.IsAbs(vm.MountPath) { - errs = errs.Also(apis.ErrInvalidValue(vm.MountPath, "mountPath").ViaFieldIndex("volumeMounts", i)) - } - if !vm.ReadOnly { - errs = errs.Also(apis.ErrMissingField("readOnly").ViaFieldIndex("volumeMounts", i)) - } - - if vm.SubPath != "" { - errs = errs.Also( - apis.ErrDisallowedFields("subPath").ViaFieldIndex("volumeMounts", i)) - } - if vm.MountPropagation != nil { - errs = errs.Also( - apis.ErrDisallowedFields("mountPropagation").ViaFieldIndex("volumeMounts", i)) - } - } - - if missing := volumes.Difference(seen); missing.Len() > 0 { - errs = errs.Also(&apis.FieldError{ - Message: fmt.Sprintf("volumes not mounted: %v", missing.List()), - Paths: []string{"volumeMounts"}, - }) - } - - // Some corev1.Container fields are set by Knative Serving controller. We disallow them - // here to avoid silently overwriting these fields and causing confusions for - // the users. See pkg/controller/revision/resources/deploy.go#makePodSpec. - var ignoredFields []string - if container.Name != "" { - ignoredFields = append(ignoredFields, "name") - } - - if container.Lifecycle != nil { - ignoredFields = append(ignoredFields, "lifecycle") - } - if len(ignoredFields) > 0 { - // Complain about all ignored fields so that user can remove them all at once. - errs = errs.Also(apis.ErrDisallowedFields(ignoredFields...)) - } - if err := validateContainerPorts(container.Ports); err != nil { - errs = errs.Also(err.ViaField("ports")) - } - // Validate our probes - if err := validateProbe(container.ReadinessProbe).ViaField("readinessProbe"); err != nil { - errs = errs.Also(err) - } - if err := validateProbe(container.LivenessProbe).ViaField("livenessProbe"); err != nil { - errs = errs.Also(err) - } - if _, err := name.ParseReference(container.Image, name.WeakValidation); err != nil { - fe := &apis.FieldError{ - Message: "Failed to parse image reference", - Paths: []string{"image"}, - Details: fmt.Sprintf("image: %q, error: %v", container.Image, err), - } - errs = errs.Also(fe) - } - return errs -} - -// The port is named "user-port" on the deployment, but a user cannot set an arbitrary name on the port -// in Configuration. The name field is reserved for content-negotiation. Currently 'h2c' and 'http1' are -// allowed. -// https://github.com/knative/serving/blob/master/docs/runtime-contract.md#inbound-network-connectivity -var validPortNames = sets.NewString( - "h2c", - "http1", - "", -) - -func validateContainerPorts(ports []corev1.ContainerPort) *apis.FieldError { - if len(ports) == 0 { - return nil - } - - var errs *apis.FieldError - - // user can set container port which names "user-port" to define application's port. - // Queue-proxy will use it to send requests to application - // if user didn't set any port, it will set default port user-port=8080. - if len(ports) > 1 { - errs = errs.Also(&apis.FieldError{ - Message: "More than one container port is set", - Paths: []string{apis.CurrentField}, - Details: "Only a single port is allowed", - }) - } - - userPort := ports[0] - // Only allow empty (defaulting to "TCP") or explicit TCP for protocol - if userPort.Protocol != "" && userPort.Protocol != corev1.ProtocolTCP { - errs = errs.Also(apis.ErrInvalidValue(string(userPort.Protocol), "Protocol")) - } - - // Don't allow HostIP or HostPort to be set - var disallowedFields []string - if userPort.HostIP != "" { - disallowedFields = append(disallowedFields, "HostIP") - - } - if userPort.HostPort != 0 { - disallowedFields = append(disallowedFields, "HostPort") - } - if len(disallowedFields) != 0 { - errs = errs.Also(apis.ErrDisallowedFields(disallowedFields...)) - } - - // Don't allow userPort to conflict with QueueProxy sidecar - if userPort.ContainerPort == RequestQueuePort || - userPort.ContainerPort == RequestQueueAdminPort || - userPort.ContainerPort == RequestQueueMetricsPort { - errs = errs.Also(apis.ErrInvalidValue(strconv.Itoa(int(userPort.ContainerPort)), "ContainerPort")) - } - - if userPort.ContainerPort < 1 || userPort.ContainerPort > 65535 { - errs = errs.Also(apis.ErrOutOfBoundsValue(strconv.Itoa(int(userPort.ContainerPort)), "1", "65535", "ContainerPort")) - } - - if !validPortNames.Has(userPort.Name) { - errs = errs.Also(&apis.FieldError{ - Message: fmt.Sprintf("Port name %v is not allowed", ports[0].Name), - Paths: []string{apis.CurrentField}, - Details: "Name must be empty, or one of: 'h2c', 'http1'", - }) - } - - return errs -} - -func validateBuildRef(buildRef *corev1.ObjectReference) *apis.FieldError { - if buildRef == nil { - return nil - } - if len(validation.IsQualifiedName(buildRef.APIVersion)) != 0 { - return apis.ErrInvalidValue(buildRef.APIVersion, "apiVersion") - } - if len(validation.IsCIdentifier(buildRef.Kind)) != 0 { - return apis.ErrInvalidValue(buildRef.Kind, "kind") - } - if len(validation.IsDNS1123Label(buildRef.Name)) != 0 { - return apis.ErrInvalidValue(buildRef.Name, "name") - } - var disallowedFields []string - if buildRef.Namespace != "" { - disallowedFields = append(disallowedFields, "namespace") - } - if buildRef.FieldPath != "" { - disallowedFields = append(disallowedFields, "fieldPath") - } - if buildRef.ResourceVersion != "" { - disallowedFields = append(disallowedFields, "resourceVersion") - } - if buildRef.UID != "" { - disallowedFields = append(disallowedFields, "uid") - } - if len(disallowedFields) != 0 { - return apis.ErrDisallowedFields(disallowedFields...) - } - return nil -} - -func validateProbe(p *corev1.Probe) *apis.FieldError { - if p == nil { - return nil - } - emptyPort := intstr.IntOrString{} - switch { - case p.Handler.HTTPGet != nil: - if p.Handler.HTTPGet.Port != emptyPort { - return apis.ErrDisallowedFields("httpGet.port") - } - case p.Handler.TCPSocket != nil: - if p.Handler.TCPSocket.Port != emptyPort { - return apis.ErrDisallowedFields("tcpSocket.port") - } - } - return nil -} - -// CheckImmutableFields checks the immutable fields are not modified. -func (current *Revision) CheckImmutableFields(ctx context.Context, og apis.Immutable) *apis.FieldError { - original, ok := og.(*Revision) - if !ok { - return &apis.FieldError{Message: "The provided original was not a Revision"} - } - - if diff, err := kmp.SafeDiff(original.Spec, current.Spec); err != nil { +func (r *Revision) checkImmutableFields(ctx context.Context, original *Revision) *apis.FieldError { + if diff, err := kmp.ShortDiff(original.Spec, r.Spec); err != nil { return &apis.FieldError{ Message: "Failed to diff Revision", Paths: []string{"spec"}, @@ -391,6 +42,145 @@ func (current *Revision) CheckImmutableFields(ctx context.Context, og apis.Immut Details: diff, } } - return nil } + +// Validate ensures Revision is properly configured. +func (r *Revision) Validate(ctx context.Context) *apis.FieldError { + errs := serving.ValidateObjectMetadata(r.GetObjectMeta()).ViaField("metadata") + errs = errs.Also(r.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + if apis.IsInUpdate(ctx) { + old := apis.GetBaseline(ctx).(*Revision) + errs = errs.Also(r.checkImmutableFields(ctx, old)) + } + return errs +} + +// Validate ensures RevisionTemplateSpec is properly configured. +func (rt *RevisionTemplateSpec) Validate(ctx context.Context) *apis.FieldError { + errs := rt.Spec.Validate(ctx).ViaField("spec") + + // If the DeprecatedRevisionTemplate has a name specified, then check that + // it follows the requirements on the name. + if rt.Name != "" { + om := apis.ParentMeta(ctx) + prefix := om.Name + "-" + if om.Name != "" { + // Even if there is GenerateName, allow the use + // of Name post-creation. + } else if om.GenerateName != "" { + // We disallow bringing your own name when the parent + // resource uses generateName (at creation). + return apis.ErrDisallowedFields("metadata.name") + } + + if !strings.HasPrefix(rt.Name, prefix) { + errs = errs.Also(apis.ErrInvalidValue( + fmt.Sprintf("%q must have prefix %q", rt.Name, prefix), + "metadata.name")) + } + } + + return errs +} + +// VerifyNameChange checks that if a user brought their own name previously that it +// changes at the appropriate times. +func (current *RevisionTemplateSpec) VerifyNameChange(ctx context.Context, og *RevisionTemplateSpec) *apis.FieldError { + if current.Name == "" { + // We only check that Name changes when the DeprecatedRevisionTemplate changes. + return nil + } + if current.Name != og.Name { + // The name changed, so we're good. + return nil + } + + if diff, err := kmp.ShortDiff(og, current); err != nil { + return &apis.FieldError{ + Message: "Failed to diff DeprecatedRevisionTemplate", + Paths: []string{apis.CurrentField}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Saw the following changes without a name change (-old +new)", + Paths: []string{apis.CurrentField}, + Details: diff, + } + } + return nil +} + +// Validate ensures RevisionSpec is properly configured. +func (rs *RevisionSpec) Validate(ctx context.Context) *apis.FieldError { + if equality.Semantic.DeepEqual(rs, &RevisionSpec{}) { + return apis.ErrMissingField(apis.CurrentField) + } + + errs := apis.CheckDeprecated(ctx, rs) + + switch { + case len(rs.PodSpec.Containers) > 0 && rs.DeprecatedContainer != nil: + errs = errs.Also(apis.ErrMultipleOneOf("container", "containers")) + case len(rs.PodSpec.Containers) > 0: + errs = errs.Also(rs.RevisionSpec.Validate(ctx)) + case rs.DeprecatedContainer != nil: + volumes, err := serving.ValidateVolumes(rs.Volumes) + if err != nil { + errs = errs.Also(err.ViaField("volumes")) + } + errs = errs.Also(serving.ValidateContainer( + *rs.DeprecatedContainer, volumes).ViaField("container")) + default: + errs = errs.Also(apis.ErrMissingOneOf("container", "containers")) + } + errs = errs.Also(serving.ValidateNamespacedObjectReference(rs.DeprecatedBuildRef).ViaField("buildRef")) + + if err := rs.DeprecatedConcurrencyModel.Validate(ctx).ViaField("concurrencyModel"); err != nil { + errs = errs.Also(err) + } else { + errs = errs.Also(rs.ContainerConcurrency.Validate(ctx).ViaField("containerConcurrency")) + } + + if rs.TimeoutSeconds != nil { + errs = errs.Also(validateTimeoutSeconds(*rs.TimeoutSeconds)) + } + return errs +} + +func validateTimeoutSeconds(timeoutSeconds int64) *apis.FieldError { + if timeoutSeconds != 0 { + if timeoutSeconds > int64(networking.DefaultTimeout.Seconds()) || timeoutSeconds < 0 { + return apis.ErrOutOfBoundsValue(timeoutSeconds, 0, + networking.DefaultTimeout.Seconds(), + "timeoutSeconds") + } + } + return nil +} + +// Validate ensures DeprecatedRevisionServingStateType is properly configured. +func (ss DeprecatedRevisionServingStateType) Validate(ctx context.Context) *apis.FieldError { + switch ss { + case DeprecatedRevisionServingStateType(""), + DeprecatedRevisionServingStateRetired, + DeprecatedRevisionServingStateReserve, + DeprecatedRevisionServingStateActive: + return nil + default: + return apis.ErrInvalidValue(ss, apis.CurrentField) + } +} + +// Validate ensures RevisionRequestConcurrencyModelType is properly configured. +func (cm RevisionRequestConcurrencyModelType) Validate(ctx context.Context) *apis.FieldError { + switch cm { + case RevisionRequestConcurrencyModelType(""), + RevisionRequestConcurrencyModelMulti, + RevisionRequestConcurrencyModelSingle: + return nil + default: + return apis.ErrInvalidValue(cm, apis.CurrentField) + } +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_conversion.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_conversion.go new file mode 100644 index 000000000..35d6c2fae --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_conversion.go @@ -0,0 +1,137 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" + duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "github.com/knative/serving/pkg/apis/serving/v1beta1" +) + +// ConvertUp implements apis.Convertible +func (source *Route) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1beta1.Route: + sink.ObjectMeta = source.ObjectMeta + source.Status.ConvertUp(apis.WithinStatus(ctx), &sink.Status) + return source.Spec.ConvertUp(apis.WithinSpec(ctx), &sink.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +// ConvertUp helps implement apis.Convertible +func (source *RouteSpec) ConvertUp(ctx context.Context, sink *v1beta1.RouteSpec) error { + sink.Traffic = make([]v1beta1.TrafficTarget, len(source.Traffic)) + for i := range source.Traffic { + if err := source.Traffic[i].ConvertUp(ctx, &sink.Traffic[i]); err != nil { + return err + } + } + return nil +} + +// ConvertUp helps implement apis.Convertible +func (source *TrafficTarget) ConvertUp(ctx context.Context, sink *v1beta1.TrafficTarget) error { + *sink = source.TrafficTarget + switch { + case source.Tag != "" && source.DeprecatedName != "": + if apis.IsInSpec(ctx) { + return apis.ErrMultipleOneOf("name", "tag") + } + case source.DeprecatedName != "": + sink.Tag = source.DeprecatedName + } + return nil +} + +// ConvertUp helps implement apis.Convertible +func (source *RouteStatus) ConvertUp(ctx context.Context, sink *v1beta1.RouteStatus) { + source.Status.ConvertTo(ctx, &sink.Status) + + source.RouteStatusFields.ConvertUp(ctx, &sink.RouteStatusFields) +} + +// ConvertUp helps implement apis.Convertible +func (source *RouteStatusFields) ConvertUp(ctx context.Context, sink *v1beta1.RouteStatusFields) { + if source.URL != nil { + sink.URL = source.URL.DeepCopy() + } + + if source.Address != nil { + sink.Address = source.Address.Addressable.DeepCopy() + } + + sink.Traffic = make([]v1beta1.TrafficTarget, len(source.Traffic)) + for i := range source.Traffic { + source.Traffic[i].ConvertUp(ctx, &sink.Traffic[i]) + } +} + +// ConvertDown implements apis.Convertible +func (sink *Route) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1beta1.Route: + sink.ObjectMeta = source.ObjectMeta + sink.Spec.ConvertDown(ctx, source.Spec) + sink.Status.ConvertDown(ctx, source.Status) + return nil + default: + return fmt.Errorf("unknown version, got: %T", source) + } +} + +// ConvertDown helps implement apis.Convertible +func (sink *RouteSpec) ConvertDown(ctx context.Context, source v1beta1.RouteSpec) { + sink.Traffic = make([]TrafficTarget, len(source.Traffic)) + for i := range source.Traffic { + sink.Traffic[i].ConvertDown(ctx, source.Traffic[i]) + } +} + +// ConvertDown helps implement apis.Convertible +func (sink *TrafficTarget) ConvertDown(ctx context.Context, source v1beta1.TrafficTarget) { + sink.TrafficTarget = source +} + +// ConvertDown helps implement apis.Convertible +func (sink *RouteStatus) ConvertDown(ctx context.Context, source v1beta1.RouteStatus) { + source.Status.ConvertTo(ctx, &sink.Status) + + sink.RouteStatusFields.ConvertDown(ctx, source.RouteStatusFields) +} + +// ConvertDown helps implement apis.Convertible +func (sink *RouteStatusFields) ConvertDown(ctx context.Context, source v1beta1.RouteStatusFields) { + if source.URL != nil { + sink.URL = source.URL.DeepCopy() + } + + if source.Address != nil { + sink.Address = &duckv1alpha1.Addressable{ + Addressable: *source.Address, + } + } + + sink.Traffic = make([]TrafficTarget, len(source.Traffic)) + for i := range source.Traffic { + sink.Traffic[i].ConvertDown(ctx, source.Traffic[i]) + } +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_defaults.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_defaults.go index e32055836..21f55bad1 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_defaults.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_defaults.go @@ -16,11 +16,38 @@ limitations under the License. package v1alpha1 -import "context" +import ( + "context" + + "github.com/knative/pkg/apis" + "github.com/knative/pkg/ptr" + "github.com/knative/serving/pkg/apis/serving/v1beta1" +) func (r *Route) SetDefaults(ctx context.Context) { - r.Spec.SetDefaults(ctx) + r.Spec.SetDefaults(apis.WithinSpec(ctx)) } func (rs *RouteSpec) SetDefaults(ctx context.Context) { + if v1beta1.IsUpgradeViaDefaulting(ctx) { + beta := v1beta1.RouteSpec{} + if rs.ConvertUp(ctx, &beta) == nil { + alpha := RouteSpec{} + alpha.ConvertDown(ctx, beta) + *rs = alpha + } + } + + if len(rs.Traffic) == 0 && v1beta1.HasDefaultConfigurationName(ctx) { + rs.Traffic = []TrafficTarget{{ + TrafficTarget: v1beta1.TrafficTarget{ + Percent: 100, + LatestRevision: ptr.Bool(true), + }, + }} + } + + for i := range rs.Traffic { + rs.Traffic[i].SetDefaults(ctx) + } } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_lifecycle.go index 8c89decfc..6ccc34ca1 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_lifecycle.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_lifecycle.go @@ -22,11 +22,12 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/serving/pkg/apis/networking/v1alpha1" ) -var routeCondSet = duckv1alpha1.NewLivingConditionSet( +var routeCondSet = apis.NewLivingConditionSet( RouteConditionAllTrafficAssigned, RouteConditionIngressReady, ) @@ -39,7 +40,7 @@ func (rs *RouteStatus) IsReady() bool { return routeCondSet.Manage(rs).IsHappy() } -func (rs *RouteStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { +func (rs *RouteStatus) GetCondition(t apis.ConditionType) *apis.Condition { return routeCondSet.Manage(rs).GetCondition(t) } @@ -47,6 +48,18 @@ func (rs *RouteStatus) InitializeConditions() { routeCondSet.Manage(rs).InitializeConditions() } +// // MarkResourceNotConvertible adds a Warning-severity condition to the resource noting that +// // it cannot be converted to a higher version. +// func (rs *RouteStatus) MarkResourceNotConvertible(err *CannotConvertError) { +// routeCondSet.Manage(rs).SetCondition(apis.Condition{ +// Type: ConditionTypeConvertible, +// Status: corev1.ConditionFalse, +// Severity: apis.ConditionSeverityWarning, +// Reason: err.Field, +// Message: err.Message, +// }) +// } + // MarkServiceNotOwned changes the IngressReady status to be false with the reason being that // there is a pre-existing placeholder service with the name we wanted to use. func (rs *RouteStatus) MarkServiceNotOwned(name string) { @@ -92,6 +105,46 @@ func (rs *RouteStatus) MarkMissingTrafficTarget(kind, name string) { "%s %q referenced in traffic not found.", kind, name) } +func (rs *RouteStatus) MarkCertificateProvisionFailed(name string) { + routeCondSet.Manage(rs).SetCondition(apis.Condition{ + Type: RouteConditionCertificateProvisioned, + Status: corev1.ConditionFalse, + Severity: apis.ConditionSeverityWarning, + Reason: "CertificateProvisionFailed", + Message: fmt.Sprintf("Certificate %s fails to be provisioned.", name), + }) +} + +func (rs *RouteStatus) MarkCertificateReady(name string) { + routeCondSet.Manage(rs).SetCondition(apis.Condition{ + Type: RouteConditionCertificateProvisioned, + Status: corev1.ConditionTrue, + Severity: apis.ConditionSeverityWarning, + Reason: "CertificateReady", + Message: fmt.Sprintf("Certificate %s is successfully provisioned", name), + }) +} + +func (rs *RouteStatus) MarkCertificateNotReady(name string) { + routeCondSet.Manage(rs).SetCondition(apis.Condition{ + Type: RouteConditionCertificateProvisioned, + Status: corev1.ConditionUnknown, + Severity: apis.ConditionSeverityWarning, + Reason: "CertificateNotReady", + Message: fmt.Sprintf("Certificate %s is not ready.", name), + }) +} + +func (rs *RouteStatus) MarkCertificateNotOwned(name string) { + routeCondSet.Manage(rs).SetCondition(apis.Condition{ + Type: RouteConditionCertificateProvisioned, + Status: corev1.ConditionFalse, + Severity: apis.ConditionSeverityWarning, + Reason: "CertificateNotOwned", + Message: fmt.Sprintf("There is an existing certificate %s that we don't own.", name), + }) +} + // PropagateClusterIngressStatus update RouteConditionIngressReady condition // in RouteStatus according to IngressStatus. func (rs *RouteStatus) PropagateClusterIngressStatus(cs v1alpha1.IngressStatus) { @@ -108,3 +161,7 @@ func (rs *RouteStatus) PropagateClusterIngressStatus(cs v1alpha1.IngressStatus) routeCondSet.Manage(rs).MarkFalse(RouteConditionIngressReady, cc.Reason, cc.Message) } } + +func (rs *RouteStatus) duck() *duckv1beta1.Status { + return &rs.Status +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_types.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_types.go index e4c0269d4..b0d5559df 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_types.go @@ -21,7 +21,10 @@ import ( "github.com/knative/pkg/apis" duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/pkg/kmeta" + + "github.com/knative/serving/pkg/apis/serving/v1beta1" ) // +genclient @@ -53,6 +56,9 @@ var ( _ apis.Validatable = (*Route)(nil) _ apis.Defaultable = (*Route)(nil) + // Check that Route can be converted to higher versions. + _ apis.Convertible = (*Route)(nil) + // Check that we can create OwnerReferences to a Route. _ kmeta.OwnerRefable = (*Route)(nil) ) @@ -62,30 +68,11 @@ type TrafficTarget struct { // Name is optionally used to expose a dedicated hostname for referencing this // target exclusively. It has the form: {name}.${route.status.domain} // +optional - Name string `json:"name,omitempty"` + DeprecatedName string `json:"name,omitempty"` - // RevisionName of a specific revision to which to send this portion of traffic. - // This is mutually exclusive with ConfigurationName. - // +optional - RevisionName string `json:"revisionName,omitempty"` - - // ConfigurationName of a configuration to whose latest revision we will send - // this portion of traffic. When the "status.latestReadyRevisionName" of the - // referenced configuration changes, we will automatically migrate traffic - // from the prior "latest ready" revision to the new one. - // This field is never set in Route's status, only its spec. - // This is mutually exclusive with RevisionName. - // +optional - ConfigurationName string `json:"configurationName,omitempty"` - - // Percent specifies percent of the traffic to this Revision or Configuration. - // This defaults to zero if unspecified. - Percent int `json:"percent"` - - // URL displays the URL for accessing named traffic targets. URL is displayed in - // status, and is disallowed on spec. URL must contain a scheme (e.g. http://) and - // a hostname, but may not contain anything else (e.g. basic auth, url path, etc.) - URL string `json:"url,omitempty"` + // We inherit most of our fields by inlining the v1beta1 type. + // Ultimately all non-v1beta1 fields will be deprecated. + v1beta1.TrafficTarget `json:",inline"` } // RouteSpec holds the desired state of the Route (from the client). @@ -109,26 +96,35 @@ type RouteSpec struct { const ( // RouteConditionReady is set when the service is configured // and has available backends ready to receive traffic. - RouteConditionReady = duckv1alpha1.ConditionReady + RouteConditionReady = apis.ConditionReady // RouteConditionAllTrafficAssigned is set to False when the // service is not configured properly or has no available // backends ready to receive traffic. - RouteConditionAllTrafficAssigned duckv1alpha1.ConditionType = "AllTrafficAssigned" + RouteConditionAllTrafficAssigned apis.ConditionType = "AllTrafficAssigned" // RouteConditionIngressReady is set to False when the // ClusterIngress fails to become Ready. - RouteConditionIngressReady duckv1alpha1.ConditionType = "IngressReady" + RouteConditionIngressReady apis.ConditionType = "IngressReady" + + // RouteConditionCertificateProvisioned is set to False when the + // Knative Certificates fail to be provisioned for the Route. + RouteConditionCertificateProvisioned apis.ConditionType = "CertificateProvisioned" ) -// RouteStatusFields holds all of the non-duckv1alpha1.Status status fields of a Route. +// RouteStatusFields holds all of the non-duckv1beta1.Status status fields of a Route. // These are defined outline so that we can also inline them into Service, and more easily // copy them. type RouteStatusFields struct { - // Domain holds the top-level domain that will distribute traffic over the provided targets. + // URL holds the url that will distribute traffic over the provided traffic targets. + // It generally has the form http[s]://{route-name}.{route-namespace}.{cluster-level-suffix} + // +optional + URL *apis.URL `json:"url,omitempty"` + + // DeprecatedDomain holds the top-level domain that will distribute traffic over the provided targets. // It generally has the form {route-name}.{route-namespace}.{cluster-level-suffix} // +optional - Domain string `json:"domain,omitempty"` + DeprecatedDomain string `json:"domain,omitempty"` // DeprecatedDomainInternal holds the top-level domain that will distribute traffic over the provided // targets from inside the cluster. It generally has the form @@ -151,7 +147,7 @@ type RouteStatusFields struct { // RouteStatus communicates the observed state of the Route (from the controller). type RouteStatus struct { - duckv1alpha1.Status `json:",inline"` + duckv1beta1.Status `json:",inline"` RouteStatusFields `json:",inline"` } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_validation.go index 3550a9d11..99f77815d 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_validation.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/route_validation.go @@ -19,17 +19,16 @@ package v1alpha1 import ( "context" "fmt" - "strconv" - - "k8s.io/apimachinery/pkg/api/equality" "github.com/knative/pkg/apis" - "k8s.io/apimachinery/pkg/util/validation" + "github.com/knative/serving/pkg/apis/serving" + "k8s.io/apimachinery/pkg/api/equality" ) func (r *Route) Validate(ctx context.Context) *apis.FieldError { - return ValidateObjectMetadata(r.GetObjectMeta()).ViaField("metadata"). - Also(r.Spec.Validate(ctx).ViaField("spec")) + errs := serving.ValidateObjectMetadata(r.GetObjectMeta()).ViaField("metadata") + errs = errs.Also(r.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + return errs } func (rs *RouteSpec) Validate(ctx context.Context) *apis.FieldError { @@ -37,43 +36,50 @@ func (rs *RouteSpec) Validate(ctx context.Context) *apis.FieldError { return apis.ErrMissingField(apis.CurrentField) } - // Where a named traffic target points - type namedTarget struct { - r string // revision name - c string // config name - i int // index of first occurrence + errs := apis.CheckDeprecated(ctx, rs) + + type diagnostic struct { + index int + field string } - // Track the targets of named TrafficTarget entries (to detect duplicates). - trafficMap := make(map[string]namedTarget) + trafficMap := make(map[string]diagnostic) - var errs *apis.FieldError percentSum := 0 for i, tt := range rs.Traffic { - errs = errs.Also(tt.Validate(ctx).ViaFieldIndex("traffic", i)) + // Delegate to the v1beta1 validation. + errs = errs.Also(tt.TrafficTarget.Validate(ctx).ViaFieldIndex("traffic", i)) percentSum += tt.Percent - if tt.Name == "" { + if tt.DeprecatedName != "" && tt.Tag != "" { + errs = errs.Also(apis.ErrMultipleOneOf("name", "tag"). + ViaFieldIndex("traffic", i)) + } else if tt.DeprecatedName == "" && tt.Tag == "" { // No Name field, so skip the uniqueness check. continue } - nt := namedTarget{ - r: tt.RevisionName, - c: tt.ConfigurationName, - i: i, + + errs = errs.Also(apis.CheckDeprecated(ctx, tt).ViaFieldIndex("traffic", i)) + + name := tt.DeprecatedName + field := "name" + if name == "" { + name = tt.Tag + field = "tag" } - if ent, ok := trafficMap[tt.Name]; !ok { + + if d, ok := trafficMap[name]; !ok { // No entry exists, so add ours - trafficMap[tt.Name] = nt + trafficMap[name] = diagnostic{i, field} } else { // We want only single definition of the route, even if it points // to the same config or revision. errs = errs.Also(&apis.FieldError{ - Message: fmt.Sprintf("Multiple definitions for %q", tt.Name), + Message: fmt.Sprintf("Multiple definitions for %q", name), Paths: []string{ - fmt.Sprintf("traffic[%d].name", ent.i), - fmt.Sprintf("traffic[%d].name", nt.i), + fmt.Sprintf("traffic[%d].%s", d.index, d.field), + fmt.Sprintf("traffic[%d].%s", i, field), }, }) } @@ -87,29 +93,3 @@ func (rs *RouteSpec) Validate(ctx context.Context) *apis.FieldError { } return errs } - -// Validate verifies that TrafficTarget is properly configured. -func (tt *TrafficTarget) Validate(ctx context.Context) *apis.FieldError { - var errs *apis.FieldError - switch { - case tt.RevisionName != "" && tt.ConfigurationName != "": - errs = apis.ErrMultipleOneOf("revisionName", "configurationName") - case tt.RevisionName != "": - if verrs := validation.IsQualifiedName(tt.RevisionName); len(verrs) > 0 { - errs = apis.ErrInvalidKeyName(tt.RevisionName, "revisionName", verrs...) - } - case tt.ConfigurationName != "": - if verrs := validation.IsQualifiedName(tt.ConfigurationName); len(verrs) > 0 { - errs = apis.ErrInvalidKeyName(tt.ConfigurationName, "configurationName", verrs...) - } - default: - errs = apis.ErrMissingOneOf("revisionName", "configurationName") - } - if tt.Percent < 0 || tt.Percent > 100 { - errs = errs.Also(apis.ErrOutOfBoundsValue(strconv.Itoa(tt.Percent), "0", "100", "percent")) - } - if tt.URL != "" { - errs = errs.Also(apis.ErrDisallowedFields("url")) - } - return errs -} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_conversion.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_conversion.go new file mode 100644 index 000000000..c95dba1a1 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_conversion.go @@ -0,0 +1,144 @@ +/* +Copyright 2019 The Knative 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 v1alpha1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" + "github.com/knative/pkg/ptr" + "github.com/knative/serving/pkg/apis/serving/v1beta1" +) + +// ConvertUp implements apis.Convertible +func (source *Service) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1beta1.Service: + sink.ObjectMeta = source.ObjectMeta + if err := source.Spec.ConvertUp(ctx, &sink.Spec); err != nil { + return err + } + return source.Status.ConvertUp(ctx, &sink.Status) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +// ConvertUp helps implement apis.Convertible +func (source *ServiceSpec) ConvertUp(ctx context.Context, sink *v1beta1.ServiceSpec) error { + switch { + case source.DeprecatedRunLatest != nil: + sink.RouteSpec = v1beta1.RouteSpec{ + Traffic: []v1beta1.TrafficTarget{{ + Percent: 100, + LatestRevision: ptr.Bool(true), + }}, + } + return source.DeprecatedRunLatest.Configuration.ConvertUp(ctx, &sink.ConfigurationSpec) + + case source.DeprecatedRelease != nil: + if len(source.DeprecatedRelease.Revisions) == 2 { + sink.RouteSpec = v1beta1.RouteSpec{ + Traffic: []v1beta1.TrafficTarget{{ + RevisionName: source.DeprecatedRelease.Revisions[0], + Percent: 100 - source.DeprecatedRelease.RolloutPercent, + Tag: "current", + }, { + RevisionName: source.DeprecatedRelease.Revisions[1], + Percent: source.DeprecatedRelease.RolloutPercent, + Tag: "candidate", + }, { + Percent: 0, + Tag: "latest", + LatestRevision: ptr.Bool(true), + }}, + } + } else { + sink.RouteSpec = v1beta1.RouteSpec{ + Traffic: []v1beta1.TrafficTarget{{ + RevisionName: source.DeprecatedRelease.Revisions[0], + Percent: 100, + Tag: "current", + }, { + Percent: 0, + Tag: "latest", + LatestRevision: ptr.Bool(true), + }}, + } + } + for i, tt := range sink.RouteSpec.Traffic { + if tt.RevisionName == "@latest" { + sink.RouteSpec.Traffic[i].RevisionName = "" + sink.RouteSpec.Traffic[i].LatestRevision = ptr.Bool(true) + } + } + return source.DeprecatedRelease.Configuration.ConvertUp(ctx, &sink.ConfigurationSpec) + + case source.DeprecatedPinned != nil: + sink.RouteSpec = v1beta1.RouteSpec{ + Traffic: []v1beta1.TrafficTarget{{ + RevisionName: source.DeprecatedPinned.RevisionName, + Percent: 100, + }}, + } + return source.DeprecatedPinned.Configuration.ConvertUp(ctx, &sink.ConfigurationSpec) + + case source.DeprecatedManual != nil: + return ConvertErrorf("manual", "manual mode cannot be migrated forward.") + + default: + source.RouteSpec.ConvertUp(ctx, &sink.RouteSpec) + return source.ConfigurationSpec.ConvertUp(ctx, &sink.ConfigurationSpec) + } +} + +// ConvertUp helps implement apis.Convertible +func (source *ServiceStatus) ConvertUp(ctx context.Context, sink *v1beta1.ServiceStatus) error { + source.Status.ConvertTo(ctx, &sink.Status) + + source.RouteStatusFields.ConvertUp(ctx, &sink.RouteStatusFields) + return source.ConfigurationStatusFields.ConvertUp(ctx, &sink.ConfigurationStatusFields) +} + +// ConvertDown implements apis.Convertible +func (sink *Service) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1beta1.Service: + sink.ObjectMeta = source.ObjectMeta + if err := sink.Spec.ConvertDown(ctx, source.Spec); err != nil { + return err + } + return sink.Status.ConvertDown(ctx, source.Status) + default: + return fmt.Errorf("unknown version, got: %T", source) + } +} + +// ConvertDown helps implement apis.Convertible +func (sink *ServiceSpec) ConvertDown(ctx context.Context, source v1beta1.ServiceSpec) error { + sink.RouteSpec.ConvertDown(ctx, source.RouteSpec) + return sink.ConfigurationSpec.ConvertDown(ctx, source.ConfigurationSpec) +} + +// ConvertDown helps implement apis.Convertible +func (sink *ServiceStatus) ConvertDown(ctx context.Context, source v1beta1.ServiceStatus) error { + source.Status.ConvertTo(ctx, &sink.Status) + + sink.RouteStatusFields.ConvertDown(ctx, source.RouteStatusFields) + return sink.ConfigurationStatusFields.ConvertDown(ctx, source.ConfigurationStatusFields) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_defaults.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_defaults.go index 6bcba797e..cfd6eca3c 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_defaults.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_defaults.go @@ -16,18 +16,59 @@ limitations under the License. package v1alpha1 -import "context" +import ( + "context" + + "github.com/knative/pkg/apis" + "k8s.io/apimachinery/pkg/api/equality" + + "github.com/knative/serving/pkg/apis/serving" + "github.com/knative/serving/pkg/apis/serving/v1beta1" +) func (s *Service) SetDefaults(ctx context.Context) { - s.Spec.SetDefaults(ctx) + s.Spec.SetDefaults(apis.WithinSpec(ctx)) + + if ui := apis.GetUserInfo(ctx); ui != nil { + ans := s.GetAnnotations() + if ans == nil { + ans = map[string]string{} + defer s.SetAnnotations(ans) + } + + if apis.IsInUpdate(ctx) { + old := apis.GetBaseline(ctx).(*Service) + if equality.Semantic.DeepEqual(old.Spec, s.Spec) { + return + } + ans[serving.UpdaterAnnotation] = ui.Username + } else { + ans[serving.CreatorAnnotation] = ui.Username + ans[serving.UpdaterAnnotation] = ui.Username + } + } } func (ss *ServiceSpec) SetDefaults(ctx context.Context) { - if ss.RunLatest != nil { - ss.RunLatest.Configuration.SetDefaults(ctx) + if v1beta1.IsUpgradeViaDefaulting(ctx) { + beta := v1beta1.ServiceSpec{} + if ss.ConvertUp(ctx, &beta) == nil { + alpha := ServiceSpec{} + if alpha.ConvertDown(ctx, beta) == nil { + *ss = alpha + } + } + } + + if ss.DeprecatedRunLatest != nil { + ss.DeprecatedRunLatest.Configuration.SetDefaults(ctx) } else if ss.DeprecatedPinned != nil { ss.DeprecatedPinned.Configuration.SetDefaults(ctx) - } else if ss.Release != nil { - ss.Release.Configuration.SetDefaults(ctx) + } else if ss.DeprecatedRelease != nil { + ss.DeprecatedRelease.Configuration.SetDefaults(ctx) + } else if ss.DeprecatedManual != nil { + } else { + ss.ConfigurationSpec.SetDefaults(ctx) + ss.RouteSpec.SetDefaults(v1beta1.WithDefaultConfigurationName(ctx)) } } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_lifecycle.go index 97684169b..75614542b 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_lifecycle.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_lifecycle.go @@ -17,19 +17,16 @@ limitations under the License. package v1alpha1 import ( - "context" "fmt" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/runtime/schema" "github.com/knative/pkg/apis" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" - authv1 "k8s.io/api/authentication/v1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" ) -var serviceCondSet = duckv1alpha1.NewLivingConditionSet( +var serviceCondSet = apis.NewLivingConditionSet( ServiceConditionConfigurationsReady, ServiceConditionRoutesReady, ) @@ -45,7 +42,7 @@ func (ss *ServiceStatus) IsReady() bool { } // GetCondition returns the condition by name. -func (ss *ServiceStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { +func (ss *ServiceStatus) GetCondition(t apis.ConditionType) *apis.Condition { return serviceCondSet.Manage(ss).GetCondition(t) } @@ -54,6 +51,18 @@ func (ss *ServiceStatus) InitializeConditions() { serviceCondSet.Manage(ss).InitializeConditions() } +// MarkResourceNotConvertible adds a Warning-severity condition to the resource noting that +// it cannot be converted to a higher version. +func (ss *ServiceStatus) MarkResourceNotConvertible(err *CannotConvertError) { + serviceCondSet.Manage(ss).SetCondition(apis.Condition{ + Type: ConditionTypeConvertible, + Status: corev1.ConditionFalse, + Severity: apis.ConditionSeverityWarning, + Reason: err.Field, + Message: err.Message, + }) +} + // MarkConfigurationNotOwned surfaces a failure via the ConfigurationsReady // status noting that the Configuration with the name we want has already // been created and we do not own it. @@ -88,6 +97,13 @@ func (ss *ServiceStatus) PropagateConfigurationStatus(cs *ConfigurationStatus) { } } +// MarkRevisionNameTaken notes that the Route has not been programmed because the revision name is taken by a +// conflicting revision definition. +func (ss *ServiceStatus) MarkRevisionNameTaken(name string) { + serviceCondSet.Manage(ss).MarkFalse(ServiceConditionRoutesReady, "RevisionNameTaken", + "The revision name %q is taken by a conflicting Revision, so traffic will not be migrated", name) +} + const ( trafficNotMigratedReason = "TrafficNotMigrated" trafficNotMigratedMessage = "Traffic is not yet migrated to the latest revision." @@ -142,44 +158,13 @@ func (ss *ServiceStatus) SetManualStatus() { serviceCondSet.Manage(newStatus).MarkUnknown(ServiceConditionRoutesReady, reason, message) newStatus.Address = ss.Address - newStatus.Domain = ss.Domain + newStatus.URL = ss.URL + newStatus.DeprecatedDomain = ss.DeprecatedDomain newStatus.DeprecatedDomainInternal = ss.DeprecatedDomainInternal *ss = *newStatus } -const ( - // CreatorAnnotation is the annotation key to describe the user that - // created the resource. - CreatorAnnotation = "serving.knative.dev/creator" - // UpdaterAnnotation is the annotation key to describe the user that - // last updated the resource. - UpdaterAnnotation = "serving.knative.dev/lastModifier" -) - -// AnnotateUserInfo satisfay the apis.Annotatable interface, and set the proper annotations -// on the Service resource about the user that performed the action. -func (s *Service) AnnotateUserInfo(ctx context.Context, prev apis.Annotatable, ui *authv1.UserInfo) { - ans := s.GetAnnotations() - if ans == nil { - ans = map[string]string{} - defer s.SetAnnotations(ans) - } - - // WebHook makes sure we get the proper type here. - ps, _ := prev.(*Service) - - // Creation. - if ps == nil { - ans[CreatorAnnotation] = ui.Username - ans[UpdaterAnnotation] = ui.Username - return - } - - // Compare the Spec's, we update the `lastModifier` key iff - // there's a change in the spec. - if equality.Semantic.DeepEqual(ps.Spec, s.Spec) { - return - } - ans[UpdaterAnnotation] = ui.Username +func (ss *ServiceStatus) duck() *duckv1beta1.Status { + return &ss.Status } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_types.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_types.go index fbd59479e..f230f4483 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_types.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_types.go @@ -20,7 +20,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/knative/pkg/apis" - duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" "github.com/knative/pkg/kmeta" ) @@ -55,6 +55,9 @@ var ( _ apis.Validatable = (*Service)(nil) _ apis.Defaultable = (*Service)(nil) + // Check that Route can be converted to higher versions. + _ apis.Convertible = (*Service)(nil) + // Check that we can create OwnerReferences to a Service. _ kmeta.OwnerRefable = (*Service)(nil) ) @@ -75,32 +78,40 @@ type ServiceSpec struct { // +optional DeprecatedGeneration int64 `json:"generation,omitempty"` - // RunLatest defines a simple Service. It will automatically + // DeprecatedRunLatest defines a simple Service. It will automatically // configure a route that keeps the latest ready revision // from the supplied configuration running. // +optional - RunLatest *RunLatestType `json:"runLatest,omitempty"` + DeprecatedRunLatest *RunLatestType `json:"runLatest,omitempty"` // DeprecatedPinned is DEPRECATED in favor of ReleaseType // +optional DeprecatedPinned *PinnedType `json:"pinned,omitempty"` - // Manual mode enables users to start managing the underlying Route and Configuration + // DeprecatedManual mode enables users to start managing the underlying Route and Configuration // resources directly. This advanced usage is intended as a path for users to graduate // from the limited capabilities of Service to the full power of Route. // +optional - Manual *ManualType `json:"manual,omitempty"` + DeprecatedManual *ManualType `json:"manual,omitempty"` // Release enables gradual promotion of new revisions by allowing traffic // to be split between two revisions. This type replaces the deprecated Pinned type. // +optional - Release *ReleaseType `json:"release,omitempty"` + DeprecatedRelease *ReleaseType `json:"release,omitempty"` + + // We are moving to a shape where the Configuration and Route specifications + // are inlined into the Service, which gives them compatible shapes. We are + // staging this change here as a path to this in v1beta1, which drops the + // "mode" based specifications above. Ultimately all non-v1beta1 fields will + // be deprecated, and then dropped in v1beta1. + ConfigurationSpec `json:",inline"` + RouteSpec `json:",inline"` } // ManualType contains the options for configuring a manual service. See ServiceSpec for // more details. type ManualType struct { - // Manual type does not contain a configuration as this type provides the + // DeprecatedManual type does not contain a configuration as this type provides the // user complete control over the configuration and route. } @@ -154,18 +165,18 @@ type PinnedType struct { const ( // ServiceConditionReady is set when the service is configured // and has available backends ready to receive traffic. - ServiceConditionReady = duckv1alpha1.ConditionReady + ServiceConditionReady = apis.ConditionReady // ServiceConditionRoutesReady is set when the service's underlying // routes have reported readiness. - ServiceConditionRoutesReady duckv1alpha1.ConditionType = "RoutesReady" + ServiceConditionRoutesReady apis.ConditionType = "RoutesReady" // ServiceConditionConfigurationsReady is set when the service's underlying // configurations have reported readiness. - ServiceConditionConfigurationsReady duckv1alpha1.ConditionType = "ConfigurationsReady" + ServiceConditionConfigurationsReady apis.ConditionType = "ConfigurationsReady" ) // ServiceStatus represents the Status stanza of the Service resource. type ServiceStatus struct { - duckv1alpha1.Status `json:",inline"` + duckv1beta1.Status `json:",inline"` RouteStatusFields `json:",inline"` diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_validation.go index f8aedba81..42429c8ed 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_validation.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/service_validation.go @@ -19,16 +19,55 @@ package v1alpha1 import ( "context" "fmt" - "strconv" "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/serving" + "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/util/validation" + + "github.com/knative/serving/pkg/apis/serving/v1beta1" ) // Validate validates the fields belonging to Service func (s *Service) Validate(ctx context.Context) *apis.FieldError { - return ValidateObjectMetadata(s.GetObjectMeta()).ViaField("metadata"). - Also(s.Spec.Validate(ctx).ViaField("spec")) + errs := serving.ValidateObjectMetadata(s.GetObjectMeta()).ViaField("metadata") + ctx = apis.WithinParent(ctx, s.ObjectMeta) + errs = errs.Also(s.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + + if apis.IsInUpdate(ctx) { + original := apis.GetBaseline(ctx).(*Service) + + field, currentConfig := s.Spec.getConfigurationSpec() + _, originalConfig := original.Spec.getConfigurationSpec() + + if currentConfig != nil && originalConfig != nil { + templateField := "template" + if currentConfig.GetTemplate() == currentConfig.DeprecatedRevisionTemplate { + templateField = "revisionTemplate" + } + err := currentConfig.GetTemplate().VerifyNameChange(ctx, + originalConfig.GetTemplate()) + errs = errs.Also(err.ViaField( + "spec", field, "configuration", templateField)) + } + } + + return errs +} + +func (ss *ServiceSpec) getConfigurationSpec() (string, *ConfigurationSpec) { + switch { + case ss.DeprecatedRunLatest != nil: + return "runLatest", &ss.DeprecatedRunLatest.Configuration + case ss.DeprecatedRelease != nil: + return "release", &ss.DeprecatedRelease.Configuration + case ss.DeprecatedManual != nil: + return "", nil + case ss.DeprecatedPinned != nil: + return "pinned", &ss.DeprecatedPinned.Configuration + default: + return "", &ss.ConfigurationSpec + } } // Validate validates the fields belonging to ServiceSpec recursively @@ -40,30 +79,52 @@ func (ss *ServiceSpec) Validate(ctx context.Context) *apis.FieldError { // return apis.ErrMissingField(currentField) // } - var errs *apis.FieldError + errs := apis.CheckDeprecated(ctx, ss) + set := []string{} - if ss.RunLatest != nil { + if ss.DeprecatedRunLatest != nil { set = append(set, "runLatest") - errs = errs.Also(ss.RunLatest.Validate(ctx).ViaField("runLatest")) + errs = errs.Also(ss.DeprecatedRunLatest.Validate(ctx).ViaField("runLatest")) } - if ss.Release != nil { + if ss.DeprecatedRelease != nil { set = append(set, "release") - errs = errs.Also(ss.Release.Validate(ctx).ViaField("release")) + errs = errs.Also(ss.DeprecatedRelease.Validate(ctx).ViaField("release")) } - if ss.Manual != nil { + if ss.DeprecatedManual != nil { set = append(set, "manual") - errs = errs.Also(ss.Manual.Validate(ctx).ViaField("manual")) + errs = errs.Also(ss.DeprecatedManual.Validate(ctx).ViaField("manual")) } if ss.DeprecatedPinned != nil { set = append(set, "pinned") errs = errs.Also(ss.DeprecatedPinned.Validate(ctx).ViaField("pinned")) } + // Before checking ConfigurationSpec, check RouteSpec. + if len(set) > 0 && len(ss.RouteSpec.Traffic) > 0 { + errs = errs.Also(apis.ErrMultipleOneOf( + append([]string{"traffic"}, set...)...)) + } + + if !equality.Semantic.DeepEqual(ss.ConfigurationSpec, ConfigurationSpec{}) { + set = append(set, "template") + + // Disallow the use of deprecated fields within our inlined + // Configuration and Route specs. + ctx = apis.DisallowDeprecated(ctx) + + errs = errs.Also(ss.ConfigurationSpec.Validate(ctx)) + errs = errs.Also(ss.RouteSpec.Validate( + // Within the context of Service, the RouteSpec has a default + // configurationName. + v1beta1.WithDefaultConfigurationName(ctx))) + } + if len(set) > 1 { errs = errs.Also(apis.ErrMultipleOneOf(set...)) } else if len(set) == 0 { - errs = errs.Also(apis.ErrMissingOneOf("runLatest", "release", "manual", "pinned")) + errs = errs.Also(apis.ErrMissingOneOf("runLatest", "release", "manual", + "pinned", "template")) } return errs } @@ -92,12 +153,11 @@ func (rt *ReleaseType) Validate(ctx context.Context) *apis.FieldError { var errs *apis.FieldError numRevisions := len(rt.Revisions) - if numRevisions == 0 { errs = errs.Also(apis.ErrMissingField("revisions")) } if numRevisions > 2 { - errs = errs.Also(apis.ErrOutOfBoundsValue(strconv.Itoa(numRevisions), "1", "2", "revisions")) + errs = errs.Also(apis.ErrOutOfBoundsValue(numRevisions, 1, 2, "revisions")) } for i, r := range rt.Revisions { // Skip over the last revision special keyword. @@ -106,16 +166,19 @@ func (rt *ReleaseType) Validate(ctx context.Context) *apis.FieldError { } if msgs := validation.IsDNS1035Label(r); len(msgs) > 0 { errs = errs.Also(apis.ErrInvalidArrayValue( - fmt.Sprintf("not a DNS 1035 label: %v", msgs), "revisions", i)) + fmt.Sprintf("not a DNS 1035 label: %v", msgs), + "revisions", i)) } } if numRevisions < 2 && rt.RolloutPercent != 0 { - errs = errs.Also(apis.ErrInvalidValue(strconv.Itoa(rt.RolloutPercent), "rolloutPercent")) + errs = errs.Also(apis.ErrInvalidValue(rt.RolloutPercent, "rolloutPercent")) } if rt.RolloutPercent < 0 || rt.RolloutPercent > 99 { - errs = errs.Also(apis.ErrOutOfBoundsValue(strconv.Itoa(rt.RolloutPercent), "0", "99", "rolloutPercent")) + errs = errs.Also(apis.ErrOutOfBoundsValue( + rt.RolloutPercent, 0, 99, + "rolloutPercent")) } return errs.Also(rt.Configuration.Validate(ctx).ViaField("configuration")) diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/zz_generated.deepcopy.go index 6d6106e15..086339384 100644 --- a/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1alpha1/zz_generated.deepcopy.go @@ -16,17 +16,34 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This file was autogenerated by deepcopy-gen. Do not edit it manually! +// Code generated by deepcopy-gen. DO NOT EDIT. package v1alpha1 import ( - build_v1alpha1 "github.com/knative/build/pkg/apis/build/v1alpha1" - duck_v1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + buildv1alpha1 "github.com/knative/build/pkg/apis/build/v1alpha1" + apis "github.com/knative/pkg/apis" + duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" v1 "k8s.io/api/core/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CannotConvertError) DeepCopyInto(out *CannotConvertError) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CannotConvertError. +func (in *CannotConvertError) DeepCopy() *CannotConvertError { + if in == nil { + return nil + } + out := new(CannotConvertError) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Configuration) DeepCopyInto(out *Configuration) { *out = *in @@ -51,9 +68,8 @@ func (in *Configuration) DeepCopy() *Configuration { func (in *Configuration) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -85,24 +101,28 @@ func (in *ConfigurationList) DeepCopy() *ConfigurationList { func (in *ConfigurationList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConfigurationSpec) DeepCopyInto(out *ConfigurationSpec) { *out = *in - if in.Build != nil { - in, out := &in.Build, &out.Build - if *in == nil { - *out = nil - } else { - *out = new(RawExtension) - (*in).DeepCopyInto(*out) - } + if in.DeprecatedBuild != nil { + in, out := &in.DeprecatedBuild, &out.DeprecatedBuild + *out = new(RawExtension) + (*in).DeepCopyInto(*out) + } + if in.DeprecatedRevisionTemplate != nil { + in, out := &in.DeprecatedRevisionTemplate, &out.DeprecatedRevisionTemplate + *out = new(RevisionTemplateSpec) + (*in).DeepCopyInto(*out) + } + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(RevisionTemplateSpec) + (*in).DeepCopyInto(*out) } - in.RevisionTemplate.DeepCopyInto(&out.RevisionTemplate) return } @@ -191,19 +211,13 @@ func (in *RawExtension) DeepCopyInto(out *RawExtension) { *out = make([]byte, len(*in)) copy(*out, *in) } - if in.Object == nil { - out.Object = nil - } else { + if in.Object != nil { out.Object = in.Object.DeepCopyObject() } if in.BuildSpec != nil { in, out := &in.BuildSpec, &out.BuildSpec - if *in == nil { - *out = nil - } else { - *out = new(build_v1alpha1.BuildSpec) - (*in).DeepCopyInto(*out) - } + *out = new(buildv1alpha1.BuildSpec) + (*in).DeepCopyInto(*out) } return } @@ -264,9 +278,8 @@ func (in *Revision) DeepCopy() *Revision { func (in *Revision) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -298,30 +311,23 @@ func (in *RevisionList) DeepCopy() *RevisionList { func (in *RevisionList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RevisionSpec) DeepCopyInto(out *RevisionSpec) { *out = *in - if in.BuildRef != nil { - in, out := &in.BuildRef, &out.BuildRef - if *in == nil { - *out = nil - } else { - *out = new(v1.ObjectReference) - **out = **in - } + in.RevisionSpec.DeepCopyInto(&out.RevisionSpec) + if in.DeprecatedBuildRef != nil { + in, out := &in.DeprecatedBuildRef, &out.DeprecatedBuildRef + *out = new(v1.ObjectReference) + **out = **in } - in.Container.DeepCopyInto(&out.Container) - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make([]v1.Volume, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + if in.DeprecatedContainer != nil { + in, out := &in.DeprecatedContainer, &out.DeprecatedContainer + *out = new(v1.Container) + (*in).DeepCopyInto(*out) } return } @@ -395,9 +401,8 @@ func (in *Route) DeepCopy() *Route { func (in *Route) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -429,9 +434,8 @@ func (in *RouteList) DeepCopy() *RouteList { func (in *RouteList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -440,7 +444,9 @@ func (in *RouteSpec) DeepCopyInto(out *RouteSpec) { if in.Traffic != nil { in, out := &in.Traffic, &out.Traffic *out = make([]TrafficTarget, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -476,19 +482,22 @@ func (in *RouteStatus) DeepCopy() *RouteStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RouteStatusFields) DeepCopyInto(out *RouteStatusFields) { *out = *in + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(apis.URL) + (*in).DeepCopyInto(*out) + } if in.Address != nil { in, out := &in.Address, &out.Address - if *in == nil { - *out = nil - } else { - *out = new(duck_v1alpha1.Addressable) - **out = **in - } + *out = new(duckv1alpha1.Addressable) + (*in).DeepCopyInto(*out) } if in.Traffic != nil { in, out := &in.Traffic, &out.Traffic *out = make([]TrafficTarget, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -544,9 +553,8 @@ func (in *Service) DeepCopy() *Service { func (in *Service) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -578,50 +586,35 @@ func (in *ServiceList) DeepCopy() *ServiceList { func (in *ServiceList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c - } else { - return nil } + return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { *out = *in - if in.RunLatest != nil { - in, out := &in.RunLatest, &out.RunLatest - if *in == nil { - *out = nil - } else { - *out = new(RunLatestType) - (*in).DeepCopyInto(*out) - } + if in.DeprecatedRunLatest != nil { + in, out := &in.DeprecatedRunLatest, &out.DeprecatedRunLatest + *out = new(RunLatestType) + (*in).DeepCopyInto(*out) } if in.DeprecatedPinned != nil { in, out := &in.DeprecatedPinned, &out.DeprecatedPinned - if *in == nil { - *out = nil - } else { - *out = new(PinnedType) - (*in).DeepCopyInto(*out) - } + *out = new(PinnedType) + (*in).DeepCopyInto(*out) } - if in.Manual != nil { - in, out := &in.Manual, &out.Manual - if *in == nil { - *out = nil - } else { - *out = new(ManualType) - **out = **in - } + if in.DeprecatedManual != nil { + in, out := &in.DeprecatedManual, &out.DeprecatedManual + *out = new(ManualType) + **out = **in } - if in.Release != nil { - in, out := &in.Release, &out.Release - if *in == nil { - *out = nil - } else { - *out = new(ReleaseType) - (*in).DeepCopyInto(*out) - } + if in.DeprecatedRelease != nil { + in, out := &in.DeprecatedRelease, &out.DeprecatedRelease + *out = new(ReleaseType) + (*in).DeepCopyInto(*out) } + in.ConfigurationSpec.DeepCopyInto(&out.ConfigurationSpec) + in.RouteSpec.DeepCopyInto(&out.RouteSpec) return } @@ -657,6 +650,7 @@ func (in *ServiceStatus) DeepCopy() *ServiceStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TrafficTarget) DeepCopyInto(out *TrafficTarget) { *out = *in + in.TrafficTarget.DeepCopyInto(&out.TrafficTarget) return } diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_conversion.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_conversion.go new file mode 100644 index 000000000..24d17044d --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" +) + +// ConvertUp implements apis.Convertible +func (source *Configuration) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", sink) +} + +// ConvertDown implements apis.Convertible +func (sink *Configuration) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", source) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_defaults.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_defaults.go new file mode 100644 index 000000000..1583abe03 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_defaults.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + + "github.com/knative/pkg/apis" +) + +// SetDefaults implements apis.Defaultable +func (c *Configuration) SetDefaults(ctx context.Context) { + ctx = apis.WithinParent(ctx, c.ObjectMeta) + c.Spec.SetDefaults(apis.WithinSpec(ctx)) +} + +// SetDefaults implements apis.Defaultable +func (cs *ConfigurationSpec) SetDefaults(ctx context.Context) { + cs.Template.SetDefaults(ctx) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_lifecycle.go new file mode 100644 index 000000000..27be3f649 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_lifecycle.go @@ -0,0 +1,29 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "github.com/knative/pkg/apis" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var confCondSet = apis.NewLivingConditionSet() + +// GetGroupVersionKind returns the GroupVersionKind. +func (r *Configuration) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Configuration") +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_types.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_types.go new file mode 100644 index 000000000..b33fe0018 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_types.go @@ -0,0 +1,102 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" + "github.com/knative/pkg/kmeta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Configuration represents the "floating HEAD" of a linear history of Revisions. +// Users create new Revisions by updating the Configuration's spec. +// The "latest created" revision's name is available under status, as is the +// "latest ready" revision's name. +// See also: https://github.com/knative/serving/blob/master/docs/spec/overview.md#configuration +type Configuration struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +optional + Spec ConfigurationSpec `json:"spec,omitempty"` + + // +optional + Status ConfigurationStatus `json:"status,omitempty"` +} + +// Verify that Configuration adheres to the appropriate interfaces. +var ( + // Check that Configuration may be validated and defaulted. + _ apis.Validatable = (*Configuration)(nil) + _ apis.Defaultable = (*Configuration)(nil) + + // Check that Configuration can be converted to higher versions. + _ apis.Convertible = (*Configuration)(nil) + + // Check that we can create OwnerReferences to a Configuration. + _ kmeta.OwnerRefable = (*Configuration)(nil) +) + +// ConfigurationSpec holds the desired state of the Configuration (from the client). +type ConfigurationSpec struct { + // Template holds the latest specification for the Revision to be stamped out. + // +optional + Template RevisionTemplateSpec `json:"template"` +} + +const ( + // ConfigurationConditionReady is set when the configuration's latest + // underlying revision has reported readiness. + ConfigurationConditionReady = apis.ConditionReady +) + +// ConfigurationStatusFields holds the fields of Configuration's status that +// are not generally shared. This is defined separately and inlined so that +// other types can readily consume these fields via duck typing. +type ConfigurationStatusFields struct { + // LatestReadyRevisionName holds the name of the latest Revision stamped out + // from this Configuration that has had its "Ready" condition become "True". + // +optional + LatestReadyRevisionName string `json:"latestReadyRevisionName,omitempty"` + + // LatestCreatedRevisionName is the last revision that was created from this + // Configuration. It might not be ready yet, for that use LatestReadyRevisionName. + // +optional + LatestCreatedRevisionName string `json:"latestCreatedRevisionName,omitempty"` +} + +// ConfigurationStatus communicates the observed state of the Configuration (from the controller). +type ConfigurationStatus struct { + duckv1beta1.Status `json:",inline"` + + ConfigurationStatusFields `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ConfigurationList is a list of Configuration resources +type ConfigurationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Configuration `json:"items"` +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_validation.go new file mode 100644 index 000000000..105f00549 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/configuration_validation.go @@ -0,0 +1,56 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + + "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/serving" +) + +// Validate makes sure that Configuration is properly configured. +func (c *Configuration) Validate(ctx context.Context) *apis.FieldError { + errs := serving.ValidateObjectMetadata(c.GetObjectMeta()).ViaField("metadata") + ctx = apis.WithinParent(ctx, c.ObjectMeta) + errs = errs.Also(c.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + errs = errs.Also(c.Status.Validate(apis.WithinStatus(ctx)).ViaField("status")) + + if apis.IsInUpdate(ctx) { + original := apis.GetBaseline(ctx).(*Configuration) + + err := c.Spec.Template.VerifyNameChange(ctx, original.Spec.Template) + errs = errs.Also(err.ViaField("spec.template")) + } + + return errs +} + +// Validate implements apis.Validatable +func (cs *ConfigurationSpec) Validate(ctx context.Context) *apis.FieldError { + return cs.Template.Validate(ctx).ViaField("template") +} + +// Validate implements apis.Validatable +func (cs *ConfigurationStatus) Validate(ctx context.Context) *apis.FieldError { + return cs.ConfigurationStatusFields.Validate(ctx) +} + +// Validate implements apis.Validatable +func (csf *ConfigurationStatusFields) Validate(ctx context.Context) *apis.FieldError { + return nil +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/contexts.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/contexts.go new file mode 100644 index 000000000..9cc23937a --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/contexts.go @@ -0,0 +1,52 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import "context" + +// hdcnKey is used as the key for associating information +// with a context.Context. +type hdcnKey struct{} + +// WithDefaultConfigurationName notes on the context for nested validation +// that there is a default configuration name, which affects how an empty +// configurationName is validated. +func WithDefaultConfigurationName(ctx context.Context) context.Context { + return context.WithValue(ctx, hdcnKey{}, struct{}{}) +} + +// HasDefaultConfigurationName checks to see whether the given context has +// been marked as having a default configurationName. +func HasDefaultConfigurationName(ctx context.Context) bool { + return ctx.Value(hdcnKey{}) != nil +} + +// lemonadeKey is used as the key for associating information +// with a context.Context. +type lemonadeKey struct{} + +// WithUpgradeViaDefaulting notes on the context that we want defaulting to rewrite +// from v1alpha1 to v1beta1. +func WithUpgradeViaDefaulting(ctx context.Context) context.Context { + return context.WithValue(ctx, lemonadeKey{}, struct{}{}) +} + +// IsUpgradeViaDefaulting checks whether we should be "defaulting" from v1alpha1 to +// the v1beta1 subset. +func IsUpgradeViaDefaulting(ctx context.Context) bool { + return ctx.Value(lemonadeKey{}) != nil +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/doc.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/doc.go new file mode 100644 index 000000000..1aad21df5 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2019 The Knative 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. +*/ + +// Api versions allow the api contract for a resource to be changed while keeping +// backward compatibility by support multiple concurrent versions +// of the same resource + +// +k8s:deepcopy-gen=package +// +groupName=serving.knative.dev +package v1beta1 diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/register.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/register.go new file mode 100644 index 000000000..564de1046 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/register.go @@ -0,0 +1,59 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "github.com/knative/serving/pkg/apis/serving" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: serving.GroupName, Version: "v1beta1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &Revision{}, + &RevisionList{}, + &Configuration{}, + &ConfigurationList{}, + &Route{}, + &RouteList{}, + &Service{}, + &ServiceList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_conversion.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_conversion.go new file mode 100644 index 000000000..fabd1e73e --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" +) + +// ConvertUp implements apis.Convertible +func (source *Revision) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", sink) +} + +// ConvertDown implements apis.Convertible +func (sink *Revision) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", source) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_defaults.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_defaults.go new file mode 100644 index 000000000..3f2ba93f2 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_defaults.go @@ -0,0 +1,87 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + + corev1 "k8s.io/api/core/v1" + + "github.com/knative/serving/pkg/apis/config" +) + +// SetDefaults implements apis.Defaultable +func (r *Revision) SetDefaults(ctx context.Context) { + r.Spec.SetDefaults(ctx) +} + +// SetDefaults implements apis.Defaultable +func (rts *RevisionTemplateSpec) SetDefaults(ctx context.Context) { + rts.Spec.SetDefaults(ctx) +} + +// SetDefaults implements apis.Defaultable +func (rs *RevisionSpec) SetDefaults(ctx context.Context) { + cfg := config.FromContextOrDefaults(ctx) + + // Default TimeoutSeconds based on our configmap + if rs.TimeoutSeconds == nil { + ts := cfg.Defaults.RevisionTimeoutSeconds + rs.TimeoutSeconds = &ts + } + + var container corev1.Container + if len(rs.PodSpec.Containers) == 1 { + container = rs.PodSpec.Containers[0] + } + defer func() { + rs.PodSpec.Containers = []corev1.Container{container} + }() + + if container.Resources.Requests == nil { + container.Resources.Requests = corev1.ResourceList{} + } + if _, ok := container.Resources.Requests[corev1.ResourceCPU]; !ok { + if rsrc := cfg.Defaults.RevisionCPURequest; rsrc != nil { + container.Resources.Requests[corev1.ResourceCPU] = *rsrc + } + } + if _, ok := container.Resources.Requests[corev1.ResourceMemory]; !ok { + if rsrc := cfg.Defaults.RevisionMemoryRequest; rsrc != nil { + container.Resources.Requests[corev1.ResourceMemory] = *rsrc + } + } + + if container.Resources.Limits == nil { + container.Resources.Limits = corev1.ResourceList{} + } + if _, ok := container.Resources.Limits[corev1.ResourceCPU]; !ok { + if rsrc := cfg.Defaults.RevisionCPULimit; rsrc != nil { + container.Resources.Limits[corev1.ResourceCPU] = *rsrc + } + } + if _, ok := container.Resources.Limits[corev1.ResourceMemory]; !ok { + if rsrc := cfg.Defaults.RevisionMemoryLimit; rsrc != nil { + container.Resources.Limits[corev1.ResourceMemory] = *rsrc + } + } + + vms := container.VolumeMounts + for i := range vms { + vms[i].ReadOnly = true + } +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_lifecycle.go new file mode 100644 index 000000000..92a774b36 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_lifecycle.go @@ -0,0 +1,29 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "github.com/knative/pkg/apis" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var revCondSet = apis.NewLivingConditionSet() + +// GetGroupVersionKind returns the GroupVersionKind. +func (r *Revision) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Revision") +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_types.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_types.go new file mode 100644 index 000000000..e5bee971b --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_types.go @@ -0,0 +1,170 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" + "github.com/knative/pkg/kmeta" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Revision is an immutable snapshot of code and configuration. A revision +// references a container image. Revisions are created by updates to a +// Configuration. +// +// See also: https://github.com/knative/serving/blob/master/docs/spec/overview.md#revision +type Revision struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +optional + Spec RevisionSpec `json:"spec,omitempty"` + + // +optional + Status RevisionStatus `json:"status,omitempty"` +} + +// Verify that Revision adheres to the appropriate interfaces. +var ( + // Check that Revision can be validated, can be defaulted, and has immutable fields. + _ apis.Validatable = (*Revision)(nil) + _ apis.Defaultable = (*Revision)(nil) + + // Check that Revision can be converted to higher versions. + _ apis.Convertible = (*Revision)(nil) + + // Check that we can create OwnerReferences to a Revision. + _ kmeta.OwnerRefable = (*Revision)(nil) +) + +// RevisionTemplateSpec describes the data a revision should have when created from a template. +// Based on: https://github.com/kubernetes/api/blob/e771f807/core/v1/types.go#L3179-L3190 +type RevisionTemplateSpec struct { + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +optional + Spec RevisionSpec `json:"spec,omitempty"` +} + +// RevisionContainerConcurrencyType is an integer expressing the maximum number of +// in-flight (concurrent) requests. +type RevisionContainerConcurrencyType int64 + +const ( + // RevisionContainerConcurrencyMax is the maximum configurable + // container concurrency. + RevisionContainerConcurrencyMax RevisionContainerConcurrencyType = 1000 +) + +// PodSpec is our standing for corev1.PodSpec. +// TODO(mattmoor): We cannot inline PodSpec until 0.7 when the containers +// field it introduces has been available for a release because this +// definition doesn't "omitempty" the containers field, which means that +// 0.6 clients would send `containers: null`, which 0.5 webhooks will +// reject. Once we ship a webhook that will parse the null properly, we +// can switch to the PodSpec definition. +type PodSpec struct { + // ServiceAccountName holds the name of the Kubernetes service account + // as which the underlying K8s resources should be run. If unspecified + // this will default to the "default" service account for the namespace + // in which the Revision exists. + // This may be used to provide access to private container images by + // following: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account + // TODO(ZhiminXiang): verify the corresponding service account exists. + // +optional + ServiceAccountName string `json:"serviceAccountName,omitempty"` + + // Containers holds the single container that defines the unit of + // execution for this Revision. + // In the context of a Revision, we disallow a number of the fields of + // this Container, including: name and lifecycle. + // See also the runtime contract for more information about the execution + // environment: + // https://github.com/knative/serving/blob/master/docs/runtime-contract.md + // +optional + Containers []corev1.Container `json:"containers,omitempty"` + + // Volumes defines a set of Kubernetes volumes to be mounted into the + // specified Container. Currently only ConfigMap and Secret volumes are + // supported. + // +optional + Volumes []corev1.Volume `json:"volumes,omitempty"` +} + +// RevisionSpec holds the desired state of the Revision (from the client). +type RevisionSpec struct { + PodSpec `json:",inline"` + + // ContainerConcurrency specifies the maximum allowed in-flight (concurrent) + // requests per container of the Revision. Defaults to `0` which means + // unlimited concurrency. + // +optional + ContainerConcurrency RevisionContainerConcurrencyType `json:"containerConcurrency,omitempty"` + + // TimeoutSeconds holds the max duration the instance is allowed for + // responding to a request. If unspecified, a system default will + // be provided. + // +optional + TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty"` +} + +const ( + // RevisionConditionReady is set when the revision is starting to materialize + // runtime resources, and becomes true when those resources are ready. + RevisionConditionReady = apis.ConditionReady +) + +// RevisionStatus communicates the observed state of the Revision (from the controller). +type RevisionStatus struct { + duckv1beta1.Status `json:",inline"` + + // ServiceName holds the name of a core Kubernetes Service resource that + // load balances over the pods backing this Revision. + // +optional + ServiceName string `json:"serviceName,omitempty"` + + // LogURL specifies the generated logging url for this particular revision + // based on the revision url template specified in the controller's config. + // +optional + LogURL string `json:"logUrl,omitempty"` + + // TODO(mattmoor): Revisit the way we resolve tag-to-digest. + // ImageDigest holds the resolved digest for the image specified + // within .Spec.Container.Image. The digest is resolved during the creation + // of Revision. This field holds the digest value regardless of whether + // a tag or digest was originally specified in the Container object. It + // may be empty if the image comes from a registry listed to skip resolution. + // +optional + // ImageDigest string `json:"imageDigest,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RevisionList is a list of Revision resources +type RevisionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Revision `json:"items"` +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_validation.go new file mode 100644 index 000000000..b8d7cd35b --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/revision_validation.go @@ -0,0 +1,160 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + "fmt" + "strings" + + "github.com/knative/pkg/apis" + "github.com/knative/pkg/kmp" + "github.com/knative/serving/pkg/apis/networking" + "github.com/knative/serving/pkg/apis/serving" +) + +// Validate ensures Revision is properly configured. +func (r *Revision) Validate(ctx context.Context) *apis.FieldError { + errs := serving.ValidateObjectMetadata(r.GetObjectMeta()).ViaField("metadata") + errs = errs.Also(r.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + errs = errs.Also(r.Status.Validate(apis.WithinStatus(ctx)).ViaField("status")) + + if apis.IsInUpdate(ctx) { + original := apis.GetBaseline(ctx).(*Revision) + if diff, err := kmp.ShortDiff(original.Spec, r.Spec); err != nil { + return &apis.FieldError{ + Message: "Failed to diff Revision", + Paths: []string{"spec"}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec"}, + Details: diff, + } + } + } + + return errs +} + +// Validate implements apis.Validatable +func (rts *RevisionTemplateSpec) Validate(ctx context.Context) *apis.FieldError { + errs := rts.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec") + + // If the RevisionTemplateSpec has a name specified, then check that + // it follows the requirements on the name. + if rts.Name != "" { + var prefix string + if om := apis.ParentMeta(ctx); om.Name == "" { + prefix = om.GenerateName + } else { + prefix = om.Name + "-" + } + + if !strings.HasPrefix(rts.Name, prefix) { + errs = errs.Also(apis.ErrInvalidValue( + fmt.Sprintf("%q must have prefix %q", rts.Name, prefix), + "metadata.name")) + } + } + + return errs +} + +// VerifyNameChange checks that if a user brought their own name previously that it +// changes at the appropriate times. +func (current *RevisionTemplateSpec) VerifyNameChange(ctx context.Context, og RevisionTemplateSpec) *apis.FieldError { + if current.Name == "" { + // We only check that Name changes when the RevisionTemplate changes. + return nil + } + if current.Name != og.Name { + // The name changed, so we're good. + return nil + } + + if diff, err := kmp.ShortDiff(&og, current); err != nil { + return &apis.FieldError{ + Message: "Failed to diff RevisionTemplate", + Paths: []string{apis.CurrentField}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Saw the following changes without a name change (-old +new)", + Paths: []string{apis.CurrentField}, + Details: diff, + } + } + return nil +} + +// Validate helps implement apis.Validatable +func (ps *PodSpec) Validate(ctx context.Context) (errs *apis.FieldError) { + // TODO(mattmoor): Once we have the whole corev1.PodSpec, this should + // move to pkg/apis/serving/k8s_validation.go and needs a field mask. + + volumes, err := serving.ValidateVolumes(ps.Volumes) + if err != nil { + errs = errs.Also(err.ViaField("volumes")) + } + + switch len(ps.Containers) { + case 0: + errs = errs.Also(apis.ErrMissingField("containers")) + case 1: + errs = errs.Also(serving.ValidateContainer(ps.Containers[0], volumes). + ViaFieldIndex("containers", 0)) + default: + errs = errs.Also(apis.ErrMultipleOneOf("containers")) + } + return errs +} + +// Validate implements apis.Validatable +func (rs *RevisionSpec) Validate(ctx context.Context) *apis.FieldError { + err := rs.ContainerConcurrency.Validate(ctx).ViaField("containerConcurrency") + + err = err.Also(rs.PodSpec.Validate(ctx)) + + if rs.TimeoutSeconds != nil { + ts := *rs.TimeoutSeconds + max := int64(networking.DefaultTimeout.Seconds()) + if ts < 0 || ts > max { + err = err.Also(apis.ErrOutOfBoundsValue( + ts, 0, max, "timeoutSeconds")) + } + } + + return err +} + +// Validate implements apis.Validatable. +func (cc RevisionContainerConcurrencyType) Validate(ctx context.Context) *apis.FieldError { + if cc < 0 || cc > RevisionContainerConcurrencyMax { + return apis.ErrOutOfBoundsValue( + cc, 0, RevisionContainerConcurrencyMax, apis.CurrentField) + } + return nil +} + +// Validate implements apis.Validatable +func (rs *RevisionStatus) Validate(ctx context.Context) *apis.FieldError { + return nil +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_conversion.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_conversion.go new file mode 100644 index 000000000..11fc3527b --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" +) + +// ConvertUp implements apis.Convertible +func (source *Route) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", sink) +} + +// ConvertDown implements apis.Convertible +func (sink *Route) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", source) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_defaults.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_defaults.go new file mode 100644 index 000000000..fd1627f76 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_defaults.go @@ -0,0 +1,51 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + + "github.com/knative/pkg/apis" + "github.com/knative/pkg/ptr" +) + +// SetDefaults implements apis.Defaultable +func (r *Route) SetDefaults(ctx context.Context) { + r.Spec.SetDefaults(apis.WithinSpec(ctx)) +} + +// SetDefaults implements apis.Defaultable +func (rs *RouteSpec) SetDefaults(ctx context.Context) { + if len(rs.Traffic) == 0 && HasDefaultConfigurationName(ctx) { + rs.Traffic = []TrafficTarget{{ + Percent: 100, + LatestRevision: ptr.Bool(true), + }} + } + + for idx := range rs.Traffic { + rs.Traffic[idx].SetDefaults(ctx) + } +} + +// SetDefaults implements apis.Defaultable +func (tt *TrafficTarget) SetDefaults(ctx context.Context) { + if tt.LatestRevision == nil { + sense := (tt.RevisionName == "") + tt.LatestRevision = &sense + } +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_lifecycle.go new file mode 100644 index 000000000..adb9800ce --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_lifecycle.go @@ -0,0 +1,29 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "github.com/knative/pkg/apis" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var routeCondSet = apis.NewLivingConditionSet() + +// GetGroupVersionKind returns the GroupVersionKind. +func (r *Route) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Route") +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_types.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_types.go new file mode 100644 index 000000000..f1e4e9076 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_types.go @@ -0,0 +1,154 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" + "github.com/knative/pkg/kmeta" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Route is responsible for configuring ingress over a collection of Revisions. +// Some of the Revisions a Route distributes traffic over may be specified by +// referencing the Configuration responsible for creating them; in these cases +// the Route is additionally responsible for monitoring the Configuration for +// "latest ready revision" changes, and smoothly rolling out latest revisions. +// See also: https://github.com/knative/serving/blob/master/docs/spec/overview.md#route +type Route struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec holds the desired state of the Route (from the client). + // +optional + Spec RouteSpec `json:"spec,omitempty"` + + // Status communicates the observed state of the Route (from the controller). + // +optional + Status RouteStatus `json:"status,omitempty"` +} + +// Verify that Route adheres to the appropriate interfaces. +var ( + // Check that Route may be validated and defaulted. + _ apis.Validatable = (*Route)(nil) + _ apis.Defaultable = (*Route)(nil) + + // Check that Route can be converted to higher versions. + _ apis.Convertible = (*Route)(nil) + + // Check that we can create OwnerReferences to a Route. + _ kmeta.OwnerRefable = (*Route)(nil) +) + +// TrafficTarget holds a single entry of the routing table for a Route. +type TrafficTarget struct { + // Tag is optionally used to expose a dedicated url for referencing + // this target exclusively. + // +optional + // TODO(mattmoor): Discuss alternative naming options. + Tag string `json:"tag,omitempty"` + + // RevisionName of a specific revision to which to send this portion of + // traffic. This is mutually exclusive with ConfigurationName. + // +optional + RevisionName string `json:"revisionName,omitempty"` + + // ConfigurationName of a configuration to whose latest revision we will send + // this portion of traffic. When the "status.latestReadyRevisionName" of the + // referenced configuration changes, we will automatically migrate traffic + // from the prior "latest ready" revision to the new one. This field is never + // set in Route's status, only its spec. This is mutually exclusive with + // RevisionName. + // +optional + ConfigurationName string `json:"configurationName,omitempty"` + + // LatestRevision may be optionally provided to indicate that the latest + // ready Revision of the Configuration should be used for this traffic + // target. When provided LatestRevision must be true if RevisionName is + // empty; it must be false when RevisionName is non-empty. + // +optional + LatestRevision *bool `json:"latestRevision,omitempty"` + + // Percent specifies percent of the traffic to this Revision or Configuration. + // This defaults to zero if unspecified. + // +optional + Percent int `json:"percent"` + + // URL displays the URL for accessing named traffic targets. URL is displayed in + // status, and is disallowed on spec. URL must contain a scheme (e.g. http://) and + // a hostname, but may not contain anything else (e.g. basic auth, url path, etc.) + // +optional + URL *apis.URL `json:"url,omitempty"` +} + +// RouteSpec holds the desired state of the Route (from the client). +type RouteSpec struct { + // Traffic specifies how to distribute traffic over a collection of + // revisions and configurations. + // +optional + Traffic []TrafficTarget `json:"traffic,omitempty"` +} + +const ( + // RouteConditionReady is set when the service is configured + // and has available backends ready to receive traffic. + RouteConditionReady = apis.ConditionReady +) + +// RouteStatusFields holds the fields of Route's status that +// are not generally shared. This is defined separately and inlined so that +// other types can readily consume these fields via duck typing. +type RouteStatusFields struct { + // URL holds the url that will distribute traffic over the provided traffic targets. + // It generally has the form http[s]://{route-name}.{route-namespace}.{cluster-level-suffix} + // +optional + URL *apis.URL `json:"url,omitempty"` + + // Address holds the information needed for a Route to be the target of an event. + // +optional + Address *duckv1beta1.Addressable `json:"address,omitempty"` + + // Traffic holds the configured traffic distribution. + // These entries will always contain RevisionName references. + // When ConfigurationName appears in the spec, this will hold the + // LatestReadyRevisionName that we last observed. + // +optional + Traffic []TrafficTarget `json:"traffic,omitempty"` +} + +// RouteStatus communicates the observed state of the Route (from the controller). +type RouteStatus struct { + duckv1beta1.Status `json:",inline"` + + RouteStatusFields `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RouteList is a list of Route resources +type RouteList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Route `json:"items"` +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_validation.go new file mode 100644 index 000000000..48e062afe --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/route_validation.go @@ -0,0 +1,171 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/serving" + "k8s.io/apimachinery/pkg/util/validation" +) + +// Validate makes sure that Route is properly configured. +func (r *Route) Validate(ctx context.Context) *apis.FieldError { + errs := serving.ValidateObjectMetadata(r.GetObjectMeta()).ViaField("metadata") + errs = errs.Also(r.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + errs = errs.Also(r.Status.Validate(apis.WithinStatus(ctx)).ViaField("status")) + return errs +} + +func validateTrafficList(ctx context.Context, traffic []TrafficTarget) *apis.FieldError { + var errs *apis.FieldError + + // Track the targets of named TrafficTarget entries (to detect duplicates). + trafficMap := make(map[string]int) + + sum := 0 + for i, tt := range traffic { + errs = errs.Also(tt.Validate(ctx).ViaIndex(i)) + + if idx, ok := trafficMap[tt.Tag]; ok { + // We want only single definition of the route, even if it points + // to the same config or revision. + errs = errs.Also(&apis.FieldError{ + Message: fmt.Sprintf("Multiple definitions for %q", tt.Tag), + Paths: []string{ + fmt.Sprintf("[%d].tag", i), + fmt.Sprintf("[%d].tag", idx), + }, + }) + } else { + trafficMap[tt.Tag] = i + } + sum += tt.Percent + } + + if sum != 100 { + errs = errs.Also(&apis.FieldError{ + Message: fmt.Sprintf("Traffic targets sum to %d, want 100", sum), + Paths: []string{apis.CurrentField}, + }) + } + return errs +} + +// Validate implements apis.Validatable +func (rs *RouteSpec) Validate(ctx context.Context) *apis.FieldError { + return validateTrafficList(ctx, rs.Traffic).ViaField("traffic") +} + +// Validate verifies that TrafficTarget is properly configured. +func (tt *TrafficTarget) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + + // We only validate the sense of latestRevision in the context of a Spec, + // and only when it is specified. + if apis.IsInSpec(ctx) && tt.LatestRevision != nil { + lr := *tt.LatestRevision + pinned := tt.RevisionName != "" + if pinned == lr { + // The senses for whether to pin to a particular revision or + // float forward to the latest revision must match. + errs = errs.Also(apis.ErrInvalidValue(lr, "latestRevision")) + } + } + + switch { + // When we have a default configurationName, we don't + // allow one to be specified. + case HasDefaultConfigurationName(ctx) && tt.ConfigurationName != "": + errs = errs.Also(apis.ErrDisallowedFields("configurationName")) + + // Both revisionName and configurationName are never allowed to + // appear concurrently. + case tt.RevisionName != "" && tt.ConfigurationName != "": + errs = errs.Also(apis.ErrMultipleOneOf( + "revisionName", "configurationName")) + + // When a revisionName appears, we must check that the name is valid. + case tt.RevisionName != "": + if el := validation.IsQualifiedName(tt.RevisionName); len(el) > 0 { + errs = errs.Also(apis.ErrInvalidKeyName( + tt.RevisionName, "revisionName", el...)) + } + + // When revisionName is missing in Status report an error. + case apis.IsInStatus(ctx): + errs = errs.Also(apis.ErrMissingField("revisionName")) + + // When configurationName is specified, we must check that the name is valid. + case tt.ConfigurationName != "": + if el := validation.IsQualifiedName(tt.ConfigurationName); len(el) > 0 { + errs = errs.Also(apis.ErrInvalidKeyName( + tt.ConfigurationName, "configurationName", el...)) + } + + // When we are using a default configurationName, it must be a valid name already. + case HasDefaultConfigurationName(ctx): + + // All other cases are missing one of revisionName or configurationName. + default: + errs = errs.Also(apis.ErrMissingOneOf( + "revisionName", "configurationName")) + } + + // Check that the traffic Percentage is within bounds. + if tt.Percent < 0 || tt.Percent > 100 { + errs = errs.Also(apis.ErrOutOfBoundsValue( + tt.Percent, 0, 100, "percent")) + } + + // Check that we set the URL appropriately. + if tt.URL.String() != "" { + // URL is not allowed in traffic under spec. + if apis.IsInSpec(ctx) { + errs = errs.Also(apis.ErrDisallowedFields("url")) + } + + // URL is not allowed in any traffic target without a name. + if tt.Tag == "" { + errs = errs.Also(apis.ErrDisallowedFields("url")) + } + } else if tt.Tag != "" { + // URL must be specified in status when name is specified. + if apis.IsInStatus(ctx) { + errs = errs.Also(apis.ErrMissingField("url")) + } + } + + return errs +} + +// Validate implements apis.Validatable +func (rs *RouteStatus) Validate(ctx context.Context) *apis.FieldError { + return rs.RouteStatusFields.Validate(ctx) +} + +// Validate implements apis.Validatable +func (rsf *RouteStatusFields) Validate(ctx context.Context) *apis.FieldError { + // TODO(mattmoor): Validate other status fields. + + if len(rsf.Traffic) != 0 { + return validateTrafficList(ctx, rsf.Traffic).ViaField("traffic") + } + return nil +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_conversion.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_conversion.go new file mode 100644 index 000000000..72092831b --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + "fmt" + + "github.com/knative/pkg/apis" +) + +// ConvertUp implements apis.Convertible +func (source *Service) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", sink) +} + +// ConvertDown implements apis.Convertible +func (sink *Service) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1beta1 is the highest known version, got: %T", source) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_defaults.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_defaults.go new file mode 100644 index 000000000..6be301174 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_defaults.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + + "github.com/knative/pkg/apis" +) + +// SetDefaults implements apis.Defaultable +func (s *Service) SetDefaults(ctx context.Context) { + ctx = apis.WithinParent(ctx, s.ObjectMeta) + s.Spec.SetDefaults(apis.WithinSpec(ctx)) + + // TODO(mattmoor): UserInfo stuff. +} + +// SetDefaults implements apis.Defaultable +func (ss *ServiceSpec) SetDefaults(ctx context.Context) { + ss.ConfigurationSpec.SetDefaults(ctx) + ss.RouteSpec.SetDefaults(WithDefaultConfigurationName(ctx)) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_lifecycle.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_lifecycle.go new file mode 100644 index 000000000..6f6f84bee --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_lifecycle.go @@ -0,0 +1,29 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "github.com/knative/pkg/apis" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var serviceCondSet = apis.NewLivingConditionSet() + +// GetGroupVersionKind returns the GroupVersionKind. +func (s *Service) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("Service") +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_types.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_types.go new file mode 100644 index 000000000..95a680a92 --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_types.go @@ -0,0 +1,113 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" + "github.com/knative/pkg/kmeta" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Service acts as a top-level container that manages a Route and Configuration +// which implement a network service. Service exists to provide a singular +// abstraction which can be access controlled, reasoned about, and which +// encapsulates software lifecycle decisions such as rollout policy and +// team resource ownership. Service acts only as an orchestrator of the +// underlying Routes and Configurations (much as a kubernetes Deployment +// orchestrates ReplicaSets), and its usage is optional but recommended. +// +// The Service's controller will track the statuses of its owned Configuration +// and Route, reflecting their statuses and conditions as its own. +// +// See also: https://github.com/knative/serving/blob/master/docs/spec/overview.md#service +type Service struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +optional + Spec ServiceSpec `json:"spec,omitempty"` + + // +optional + Status ServiceStatus `json:"status,omitempty"` +} + +// Verify that Service adheres to the appropriate interfaces. +var ( + // Check that Service may be validated and defaulted. + _ apis.Validatable = (*Service)(nil) + _ apis.Defaultable = (*Service)(nil) + + // Check that Service can be converted to higher versions. + _ apis.Convertible = (*Service)(nil) + + // Check that we can create OwnerReferences to a Service. + _ kmeta.OwnerRefable = (*Service)(nil) +) + +// ServiceSpec represents the configuration for the Service object. +// A Service's specification is the union of the specifications for a Route +// and Configuration. The Service restricts what can be expressed in these +// fields, e.g. the Route must reference the provided Configuration; +// however, these limitations also enable friendlier defaulting, +// e.g. Route never needs a Configuration name, and may be defaulted to +// the appropriate "run latest" spec. +type ServiceSpec struct { + // ServiceSpec inlines an unrestricted ConfigurationSpec. + ConfigurationSpec `json:",inline"` + + // ServiceSpec inlines RouteSpec and restricts/defaults its fields + // via webhook. In particular, this spec can only reference this + // Service's configuration and revisions (which also influences + // defaults). + RouteSpec `json:",inline"` +} + +// ConditionType represents a Service condition value +const ( + // ServiceConditionReady is set when the service is configured + // and has available backends ready to receive traffic. + ServiceConditionReady = apis.ConditionReady +) + +// ServiceStatus represents the Status stanza of the Service resource. +type ServiceStatus struct { + duckv1beta1.Status `json:",inline"` + + // In addition to inlining ConfigurationSpec, we also inline the fields + // specific to ConfigurationStatus. + ConfigurationStatusFields `json:",inline"` + + // In addition to inlining RouteSpec, we also inline the fields + // specific to RouteStatus. + RouteStatusFields `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ServiceList is a list of Service resources +type ServiceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Service `json:"items"` +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_validation.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_validation.go new file mode 100644 index 000000000..6a6aa171b --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/service_validation.go @@ -0,0 +1,56 @@ +/* +Copyright 2019 The Knative 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 v1beta1 + +import ( + "context" + + "github.com/knative/pkg/apis" + "github.com/knative/serving/pkg/apis/serving" +) + +// Validate makes sure that Service is properly configured. +func (s *Service) Validate(ctx context.Context) *apis.FieldError { + errs := serving.ValidateObjectMetadata(s.GetObjectMeta()).ViaField("metadata") + ctx = apis.WithinParent(ctx, s.ObjectMeta) + errs = errs.Also(s.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + errs = errs.Also(s.Status.Validate(apis.WithinStatus(ctx)).ViaField("status")) + + if apis.IsInUpdate(ctx) { + original := apis.GetBaseline(ctx).(*Service) + + err := s.Spec.ConfigurationSpec.Template.VerifyNameChange(ctx, + original.Spec.ConfigurationSpec.Template) + errs = errs.Also(err.ViaField("spec.template")) + } + + return errs +} + +// Validate implements apis.Validatable +func (ss *ServiceSpec) Validate(ctx context.Context) *apis.FieldError { + return ss.ConfigurationSpec.Validate(ctx).Also( + // Within the context of Service, the RouteSpec has a default + // configurationName. + ss.RouteSpec.Validate(WithDefaultConfigurationName(ctx))) +} + +// Validate implements apis.Validatable +func (ss *ServiceStatus) Validate(ctx context.Context) *apis.FieldError { + return ss.ConfigurationStatusFields.Validate(ctx).Also( + ss.RouteStatusFields.Validate(ctx)) +} diff --git a/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 000000000..2ab7514cc --- /dev/null +++ b/vendor/github.com/knative/serving/pkg/apis/serving/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,547 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 The Knative 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + apis "github.com/knative/pkg/apis" + duckv1beta1 "github.com/knative/pkg/apis/duck/v1beta1" + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Configuration) DeepCopyInto(out *Configuration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Configuration. +func (in *Configuration) DeepCopy() *Configuration { + if in == nil { + return nil + } + out := new(Configuration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Configuration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigurationList) DeepCopyInto(out *ConfigurationList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Configuration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigurationList. +func (in *ConfigurationList) DeepCopy() *ConfigurationList { + if in == nil { + return nil + } + out := new(ConfigurationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ConfigurationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigurationSpec) DeepCopyInto(out *ConfigurationSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigurationSpec. +func (in *ConfigurationSpec) DeepCopy() *ConfigurationSpec { + if in == nil { + return nil + } + out := new(ConfigurationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigurationStatus) DeepCopyInto(out *ConfigurationStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + out.ConfigurationStatusFields = in.ConfigurationStatusFields + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigurationStatus. +func (in *ConfigurationStatus) DeepCopy() *ConfigurationStatus { + if in == nil { + return nil + } + out := new(ConfigurationStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigurationStatusFields) DeepCopyInto(out *ConfigurationStatusFields) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigurationStatusFields. +func (in *ConfigurationStatusFields) DeepCopy() *ConfigurationStatusFields { + if in == nil { + return nil + } + out := new(ConfigurationStatusFields) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSpec) DeepCopyInto(out *PodSpec) { + *out = *in + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = make([]v1.Container, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSpec. +func (in *PodSpec) DeepCopy() *PodSpec { + if in == nil { + return nil + } + out := new(PodSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Revision) DeepCopyInto(out *Revision) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Revision. +func (in *Revision) DeepCopy() *Revision { + if in == nil { + return nil + } + out := new(Revision) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Revision) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RevisionList) DeepCopyInto(out *RevisionList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Revision, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionList. +func (in *RevisionList) DeepCopy() *RevisionList { + if in == nil { + return nil + } + out := new(RevisionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RevisionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RevisionSpec) DeepCopyInto(out *RevisionSpec) { + *out = *in + in.PodSpec.DeepCopyInto(&out.PodSpec) + if in.TimeoutSeconds != nil { + in, out := &in.TimeoutSeconds, &out.TimeoutSeconds + *out = new(int64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionSpec. +func (in *RevisionSpec) DeepCopy() *RevisionSpec { + if in == nil { + return nil + } + out := new(RevisionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RevisionStatus) DeepCopyInto(out *RevisionStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionStatus. +func (in *RevisionStatus) DeepCopy() *RevisionStatus { + if in == nil { + return nil + } + out := new(RevisionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RevisionTemplateSpec) DeepCopyInto(out *RevisionTemplateSpec) { + *out = *in + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionTemplateSpec. +func (in *RevisionTemplateSpec) DeepCopy() *RevisionTemplateSpec { + if in == nil { + return nil + } + out := new(RevisionTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Route) DeepCopyInto(out *Route) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route. +func (in *Route) DeepCopy() *Route { + if in == nil { + return nil + } + out := new(Route) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Route) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteList) DeepCopyInto(out *RouteList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Route, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteList. +func (in *RouteList) DeepCopy() *RouteList { + if in == nil { + return nil + } + out := new(RouteList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RouteList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteSpec) DeepCopyInto(out *RouteSpec) { + *out = *in + if in.Traffic != nil { + in, out := &in.Traffic, &out.Traffic + *out = make([]TrafficTarget, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteSpec. +func (in *RouteSpec) DeepCopy() *RouteSpec { + if in == nil { + return nil + } + out := new(RouteSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteStatus) DeepCopyInto(out *RouteStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + in.RouteStatusFields.DeepCopyInto(&out.RouteStatusFields) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteStatus. +func (in *RouteStatus) DeepCopy() *RouteStatus { + if in == nil { + return nil + } + out := new(RouteStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteStatusFields) DeepCopyInto(out *RouteStatusFields) { + *out = *in + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(apis.URL) + (*in).DeepCopyInto(*out) + } + if in.Address != nil { + in, out := &in.Address, &out.Address + *out = new(duckv1beta1.Addressable) + (*in).DeepCopyInto(*out) + } + if in.Traffic != nil { + in, out := &in.Traffic, &out.Traffic + *out = make([]TrafficTarget, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteStatusFields. +func (in *RouteStatusFields) DeepCopy() *RouteStatusFields { + if in == nil { + return nil + } + out := new(RouteStatusFields) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Service) DeepCopyInto(out *Service) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Service. +func (in *Service) DeepCopy() *Service { + if in == nil { + return nil + } + out := new(Service) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Service) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceList) DeepCopyInto(out *ServiceList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Service, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceList. +func (in *ServiceList) DeepCopy() *ServiceList { + if in == nil { + return nil + } + out := new(ServiceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { + *out = *in + in.ConfigurationSpec.DeepCopyInto(&out.ConfigurationSpec) + in.RouteSpec.DeepCopyInto(&out.RouteSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSpec. +func (in *ServiceSpec) DeepCopy() *ServiceSpec { + if in == nil { + return nil + } + out := new(ServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceStatus) DeepCopyInto(out *ServiceStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + out.ConfigurationStatusFields = in.ConfigurationStatusFields + in.RouteStatusFields.DeepCopyInto(&out.RouteStatusFields) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceStatus. +func (in *ServiceStatus) DeepCopy() *ServiceStatus { + if in == nil { + return nil + } + out := new(ServiceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TrafficTarget) DeepCopyInto(out *TrafficTarget) { + *out = *in + if in.LatestRevision != nil { + in, out := &in.LatestRevision, &out.LatestRevision + *out = new(bool) + **out = **in + } + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(apis.URL) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficTarget. +func (in *TrafficTarget) DeepCopy() *TrafficTarget { + if in == nil { + return nil + } + out := new(TrafficTarget) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/scheme/doc.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/scheme/doc.go index 90a95408c..7d7653848 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/scheme/doc.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/scheme/doc.go @@ -13,5 +13,8 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + // This package contains the scheme of the automatically generated clientset. package scheme diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/scheme/register.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/scheme/register.go index 3d70a2c31..3ea369ad5 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/scheme/register.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/scheme/register.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package scheme import ( @@ -23,7 +26,7 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" - util_runtime "k8s.io/apimachinery/pkg/util/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" ) var Scheme = runtime.NewScheme() @@ -53,5 +56,5 @@ var AddToScheme = localSchemeBuilder.AddToScheme func init() { v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) - util_runtime.Must(AddToScheme(Scheme)) + utilruntime.Must(AddToScheme(Scheme)) } diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/configuration.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/configuration.go index c766b0d28..17c02afdc 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/configuration.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/configuration.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package v1alpha1 import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/doc.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/doc.go index 1a38cd798..a1c6bb9fe 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/doc.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/doc.go @@ -13,5 +13,8 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + // This package has the automatically generated typed clients. package v1alpha1 diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/doc.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/doc.go index fb7bee471..a00e5d7b2 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/doc.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/doc.go @@ -13,5 +13,8 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + // Package fake has the automatically generated clients. package fake diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_configuration.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_configuration.go index 0e82efaa8..2c51bec82 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_configuration.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_configuration.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package fake import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_revision.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_revision.go index 6710514c0..c74ee900c 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_revision.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_revision.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package fake import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_route.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_route.go index 56087f4c4..dfd64ce30 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_route.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_route.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package fake import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_service.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_service.go index c62b0c03d..d270541e3 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_service.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_service.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package fake import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_serving_client.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_serving_client.go index 6b4a6f47f..eff1c692a 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_serving_client.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake/fake_serving_client.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package fake import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/generated_expansion.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/generated_expansion.go index d8186b319..6ce17decf 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/generated_expansion.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/generated_expansion.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package v1alpha1 type ConfigurationExpansion interface{} diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/revision.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/revision.go index 1460b686e..429930661 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/revision.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/revision.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package v1alpha1 import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/route.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/route.go index 403e5e7aa..320477113 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/route.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/route.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package v1alpha1 import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/service.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/service.go index 28e6afd01..1309f2fb3 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/service.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/service.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package v1alpha1 import ( diff --git a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/serving_client.go b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/serving_client.go index 9d820f551..0a75f4a86 100644 --- a/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/serving_client.go +++ b/vendor/github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/serving_client.go @@ -13,6 +13,9 @@ 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. */ + +// Code generated by client-gen. DO NOT EDIT. + package v1alpha1 import ( diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 4ec0792eb..c0c80d893 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -28,6 +28,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" "golang.org/x/net/http/httpguts" @@ -199,6 +200,7 @@ type ClientConn struct { t *Transport tconn net.Conn // usually *tls.Conn, except specialized impls tlsState *tls.ConnectionState // nil only for specialized impls + reused uint32 // whether conn is being reused; atomic singleUse bool // whether being used for a single http.Request // readLoop goroutine fields: @@ -440,7 +442,8 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err) return nil, err } - traceGotConn(req, cc) + reused := !atomic.CompareAndSwapUint32(&cc.reused, 0, 1) + traceGotConn(req, cc, reused) res, gotErrAfterReqBodyWrite, err := cc.roundTrip(req) if err != nil && retry <= 6 { if req, err = shouldRetryRequest(req, err, gotErrAfterReqBodyWrite); err == nil { @@ -2559,15 +2562,15 @@ func traceGetConn(req *http.Request, hostPort string) { trace.GetConn(hostPort) } -func traceGotConn(req *http.Request, cc *ClientConn) { +func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { trace := httptrace.ContextClientTrace(req.Context()) if trace == nil || trace.GotConn == nil { return } ci := httptrace.GotConnInfo{Conn: cc.tconn} + ci.Reused = reused cc.mu.Lock() - ci.Reused = cc.nextStreamID > 1 - ci.WasIdle = len(cc.streams) == 0 && ci.Reused + ci.WasIdle = len(cc.streams) == 0 && reused if ci.WasIdle && !cc.lastActive.IsZero() { ci.IdleTime = time.Now().Sub(cc.lastActive) } diff --git a/vendor/golang.org/x/oauth2/jwt/jwt.go b/vendor/golang.org/x/oauth2/jwt/jwt.go index 99f3e0a32..b2bf18298 100644 --- a/vendor/golang.org/x/oauth2/jwt/jwt.go +++ b/vendor/golang.org/x/oauth2/jwt/jwt.go @@ -66,6 +66,14 @@ type Config struct { // request. If empty, the value of TokenURL is used as the // intended audience. Audience string + + // PrivateClaims optionally specifies custom private claims in the JWT. + // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3 + PrivateClaims map[string]interface{} + + // UseIDToken optionally specifies whether ID token should be used instead + // of access token when the server returns both. + UseIDToken bool } // TokenSource returns a JWT TokenSource using the configuration @@ -97,9 +105,10 @@ func (js jwtSource) Token() (*oauth2.Token, error) { } hc := oauth2.NewClient(js.ctx, nil) claimSet := &jws.ClaimSet{ - Iss: js.conf.Email, - Scope: strings.Join(js.conf.Scopes, " "), - Aud: js.conf.TokenURL, + Iss: js.conf.Email, + Scope: strings.Join(js.conf.Scopes, " "), + Aud: js.conf.TokenURL, + PrivateClaims: js.conf.PrivateClaims, } if subject := js.conf.Subject; subject != "" { claimSet.Sub = subject @@ -166,5 +175,11 @@ func (js jwtSource) Token() (*oauth2.Token, error) { } token.Expiry = time.Unix(claimSet.Exp, 0) } + if js.conf.UseIDToken { + if tokenRes.IDToken == "" { + return nil, fmt.Errorf("oauth2: response doesn't have JWT token") + } + token.AccessToken = tokenRes.IDToken + } return token, nil } diff --git a/vendor/golang.org/x/text/encoding/encoding.go b/vendor/golang.org/x/text/encoding/encoding.go index a0bd7cd4d..221f175c0 100644 --- a/vendor/golang.org/x/text/encoding/encoding.go +++ b/vendor/golang.org/x/text/encoding/encoding.go @@ -124,7 +124,7 @@ func (e *Encoder) Writer(w io.Writer) io.Writer { } // ASCIISub is the ASCII substitute character, as recommended by -// https://unicode.org/reports/tr36/#Text_Comparison +// http://unicode.org/reports/tr36/#Text_Comparison const ASCIISub = '\x1a' // Nop is the nop encoding. Its transformed bytes are the same as the source diff --git a/vendor/golang.org/x/text/encoding/internal/identifier/identifier.go b/vendor/golang.org/x/text/encoding/internal/identifier/identifier.go index 5c9b85c28..7351b4ef8 100644 --- a/vendor/golang.org/x/text/encoding/internal/identifier/identifier.go +++ b/vendor/golang.org/x/text/encoding/internal/identifier/identifier.go @@ -34,7 +34,7 @@ package identifier // - http://www.iana.org/assignments/character-sets/character-sets.xhtml // - http://www.iana.org/assignments/ianacharset-mib/ianacharset-mib // - http://www.ietf.org/rfc/rfc2978.txt -// - https://www.unicode.org/reports/tr22/ +// - http://www.unicode.org/reports/tr22/ // - http://www.w3.org/TR/encoding/ // - https://encoding.spec.whatwg.org/ // - https://encoding.spec.whatwg.org/encodings.json diff --git a/vendor/golang.org/x/text/encoding/internal/identifier/mib.go b/vendor/golang.org/x/text/encoding/internal/identifier/mib.go index 8cc29021c..768842b0a 100644 --- a/vendor/golang.org/x/text/encoding/internal/identifier/mib.go +++ b/vendor/golang.org/x/text/encoding/internal/identifier/mib.go @@ -884,27 +884,27 @@ const ( // CESU8 is the MIB identifier with IANA name CESU-8. // - // https://www.unicode.org/unicode/reports/tr26 + // http://www.unicode.org/unicode/reports/tr26 CESU8 MIB = 1016 // UTF32 is the MIB identifier with IANA name UTF-32. // - // https://www.unicode.org/unicode/reports/tr19/ + // http://www.unicode.org/unicode/reports/tr19/ UTF32 MIB = 1017 // UTF32BE is the MIB identifier with IANA name UTF-32BE. // - // https://www.unicode.org/unicode/reports/tr19/ + // http://www.unicode.org/unicode/reports/tr19/ UTF32BE MIB = 1018 // UTF32LE is the MIB identifier with IANA name UTF-32LE. // - // https://www.unicode.org/unicode/reports/tr19/ + // http://www.unicode.org/unicode/reports/tr19/ UTF32LE MIB = 1019 // BOCU1 is the MIB identifier with IANA name BOCU-1. // - // https://www.unicode.org/notes/tn6/ + // http://www.unicode.org/notes/tn6/ BOCU1 MIB = 1020 // Windows30Latin1 is the MIB identifier with IANA name ISO-8859-1-Windows-3.0-Latin-1. diff --git a/vendor/golang.org/x/text/encoding/unicode/unicode.go b/vendor/golang.org/x/text/encoding/unicode/unicode.go index 4850ff365..579cadfb1 100644 --- a/vendor/golang.org/x/text/encoding/unicode/unicode.go +++ b/vendor/golang.org/x/text/encoding/unicode/unicode.go @@ -145,7 +145,7 @@ func (utf8Decoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err e // and consumed in a greater context that implies a certain endianness, use // IgnoreBOM. Otherwise, use ExpectBOM and always produce and consume a BOM. // -// In the language of https://www.unicode.org/faq/utf_bom.html#bom10, IgnoreBOM +// In the language of http://www.unicode.org/faq/utf_bom.html#bom10, IgnoreBOM // corresponds to "Where the precise type of the data stream is known... the // BOM should not be used" and ExpectBOM corresponds to "A particular // protocol... may require use of the BOM". diff --git a/vendor/golang.org/x/text/unicode/bidi/bidi.go b/vendor/golang.org/x/text/unicode/bidi/bidi.go index e8edc54cc..3fc4a6252 100644 --- a/vendor/golang.org/x/text/unicode/bidi/bidi.go +++ b/vendor/golang.org/x/text/unicode/bidi/bidi.go @@ -6,7 +6,7 @@ // Package bidi contains functionality for bidirectional text support. // -// See https://www.unicode.org/reports/tr9. +// See http://www.unicode.org/reports/tr9. // // NOTE: UNDER CONSTRUCTION. This API may change in backwards incompatible ways // and without notice. diff --git a/vendor/golang.org/x/text/unicode/bidi/bracket.go b/vendor/golang.org/x/text/unicode/bidi/bracket.go index 3fef31627..601e25920 100644 --- a/vendor/golang.org/x/text/unicode/bidi/bracket.go +++ b/vendor/golang.org/x/text/unicode/bidi/bracket.go @@ -12,7 +12,7 @@ import ( // This file contains a port of the reference implementation of the // Bidi Parentheses Algorithm: -// https://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/BidiPBAReference.java +// http://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/BidiPBAReference.java // // The implementation in this file covers definitions BD14-BD16 and rule N0 // of UAX#9. diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index 48d144008..d4c1399f0 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -7,7 +7,7 @@ package bidi import "log" // This implementation is a port based on the reference implementation found at: -// https://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/ +// http://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/ // // described in Unicode Bidirectional Algorithm (UAX #9). // diff --git a/vendor/golang.org/x/text/unicode/bidi/gen.go b/vendor/golang.org/x/text/unicode/bidi/gen.go index 987fc169c..4e1c7ba0b 100644 --- a/vendor/golang.org/x/text/unicode/bidi/gen.go +++ b/vendor/golang.org/x/text/unicode/bidi/gen.go @@ -26,7 +26,7 @@ func main() { } // bidiClass names and codes taken from class "bc" in -// https://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt +// http://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt var bidiClass = map[string]Class{ "AL": AL, // ArabicLetter "AN": AN, // ArabicNumber diff --git a/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go b/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go index 02c3b505d..51bd68fa7 100644 --- a/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go +++ b/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go @@ -15,7 +15,7 @@ import ( ) // These tables are hand-extracted from: -// https://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt +// http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt func visitDefaults(fn func(r rune, c Class)) { // first write default values for ranges listed above. visitRunes(fn, AL, []rune{ diff --git a/vendor/golang.org/x/text/unicode/norm/composition.go b/vendor/golang.org/x/text/unicode/norm/composition.go index 9f37ef0ce..bab4c5de0 100644 --- a/vendor/golang.org/x/text/unicode/norm/composition.go +++ b/vendor/golang.org/x/text/unicode/norm/composition.go @@ -407,7 +407,7 @@ func decomposeHangul(buf []byte, r rune) int { // decomposeHangul algorithmically decomposes a Hangul rune into // its Jamo components. -// See https://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul. +// See http://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul. func (rb *reorderBuffer) decomposeHangul(r rune) { r -= hangulBase x := r % jamoTCount @@ -420,7 +420,7 @@ func (rb *reorderBuffer) decomposeHangul(r rune) { } // combineHangul algorithmically combines Jamo character components into Hangul. -// See https://unicode.org/reports/tr15/#Hangul for details on combining Hangul. +// See http://unicode.org/reports/tr15/#Hangul for details on combining Hangul. func (rb *reorderBuffer) combineHangul(s, i, k int) { b := rb.rune[:] bn := rb.nrune diff --git a/vendor/golang.org/x/text/unicode/norm/forminfo.go b/vendor/golang.org/x/text/unicode/norm/forminfo.go index f7fbf86d1..e67e7655c 100644 --- a/vendor/golang.org/x/text/unicode/norm/forminfo.go +++ b/vendor/golang.org/x/text/unicode/norm/forminfo.go @@ -4,8 +4,6 @@ package norm -import "encoding/binary" - // This file contains Form-specific logic and wrappers for data in tables.go. // Rune info is stored in a separate trie per composing form. A composing form @@ -180,17 +178,6 @@ func (p Properties) TrailCCC() uint8 { return ccc[p.tccc] } -func buildRecompMap() { - recompMap = make(map[uint32]rune, len(recompMapPacked)/8) - var buf [8]byte - for i := 0; i < len(recompMapPacked); i += 8 { - copy(buf[:], recompMapPacked[i:i+8]) - key := binary.BigEndian.Uint32(buf[:4]) - val := binary.BigEndian.Uint32(buf[4:]) - recompMap[key] = rune(val) - } -} - // Recomposition // We use 32-bit keys instead of 64-bit for the two codepoint keys. // This clips off the bits of three entries, but we know this will not @@ -201,7 +188,6 @@ func buildRecompMap() { // combine returns the combined rune or 0 if it doesn't exist. func combine(a, b rune) rune { key := uint32(uint16(a))<<16 + uint32(uint16(b)) - recompMapOnce.Do(buildRecompMap) return recompMap[key] } diff --git a/vendor/golang.org/x/text/unicode/norm/maketables.go b/vendor/golang.org/x/text/unicode/norm/maketables.go index 30a3aa933..338c395ee 100644 --- a/vendor/golang.org/x/text/unicode/norm/maketables.go +++ b/vendor/golang.org/x/text/unicode/norm/maketables.go @@ -12,7 +12,6 @@ package main import ( "bytes" - "encoding/binary" "flag" "fmt" "io" @@ -262,7 +261,7 @@ func compactCCC() { // CompositionExclusions.txt has form: // 0958 # ... -// See https://unicode.org/reports/tr44/ for full explanation +// See http://unicode.org/reports/tr44/ for full explanation func loadCompositionExclusions() { f := gen.OpenUCDFile("CompositionExclusions.txt") defer f.Close() @@ -736,8 +735,6 @@ func makeTables() { max = n } } - fmt.Fprintln(w, `import "sync"`) - fmt.Fprintln(w) fmt.Fprintln(w, "const (") fmt.Fprintln(w, "\t// Version is the Unicode edition from which the tables are derived.") @@ -785,23 +782,16 @@ func makeTables() { sz := nrentries * 8 size += sz fmt.Fprintf(w, "// recompMap: %d bytes (entries only)\n", sz) - fmt.Fprintln(w, "var recompMap map[uint32]rune") - fmt.Fprintln(w, "var recompMapOnce sync.Once\n") - fmt.Fprintln(w, `const recompMapPacked = "" +`) - var buf [8]byte + fmt.Fprintln(w, "var recompMap = map[uint32]rune{") for i, c := range chars { f := c.forms[FCanonical] d := f.decomp if !f.isOneWay && len(d) > 0 { key := uint32(uint16(d[0]))<<16 + uint32(uint16(d[1])) - binary.BigEndian.PutUint32(buf[:4], key) - binary.BigEndian.PutUint32(buf[4:], uint32(i)) - fmt.Fprintf(w, "\t\t%q + // 0x%.8X: 0x%.8X\n", string(buf[:]), key, uint32(i)) + fmt.Fprintf(w, "0x%.8X: 0x%.4X,\n", key, i) } } - // hack so we don't have to special case the trailing plus sign - fmt.Fprintf(w, ` ""`) - fmt.Fprintln(w) + fmt.Fprintf(w, "}\n\n") } fmt.Fprintf(w, "// Total size of tables: %dKB (%d bytes)\n", (size+512)/1024, size) @@ -867,7 +857,7 @@ func verifyComputed() { // DerivedNormalizationProps.txt has form: // 00C0..00C5 ; NFD_QC; N # ... // 0374 ; NFD_QC; N # ... -// See https://unicode.org/reports/tr44/ for full explanation +// See http://unicode.org/reports/tr44/ for full explanation func testDerived() { f := gen.OpenUCDFile("DerivedNormalizationProps.txt") defer f.Close() diff --git a/vendor/golang.org/x/text/unicode/norm/normalize.go b/vendor/golang.org/x/text/unicode/norm/normalize.go index 95efcf26e..e28ac641a 100644 --- a/vendor/golang.org/x/text/unicode/norm/normalize.go +++ b/vendor/golang.org/x/text/unicode/norm/normalize.go @@ -29,8 +29,8 @@ import ( // proceed independently on both sides: // f(x) == append(f(x[0:n]), f(x[n:])...) // -// References: https://unicode.org/reports/tr15/ and -// https://unicode.org/notes/tn5/. +// References: http://unicode.org/reports/tr15/ and +// http://unicode.org/notes/tn5/. type Form int const ( diff --git a/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go index c48a97b0c..44dd3978c 100644 --- a/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go +++ b/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go @@ -4,8 +4,6 @@ package norm -import "sync" - const ( // Version is the Unicode edition from which the tables are derived. Version = "10.0.0" @@ -6709,949 +6707,947 @@ var nfkcSparseValues = [869]valueRange{ } // recompMap: 7520 bytes (entries only) -var recompMap map[uint32]rune -var recompMapOnce sync.Once +var recompMap = map[uint32]rune{ + 0x00410300: 0x00C0, + 0x00410301: 0x00C1, + 0x00410302: 0x00C2, + 0x00410303: 0x00C3, + 0x00410308: 0x00C4, + 0x0041030A: 0x00C5, + 0x00430327: 0x00C7, + 0x00450300: 0x00C8, + 0x00450301: 0x00C9, + 0x00450302: 0x00CA, + 0x00450308: 0x00CB, + 0x00490300: 0x00CC, + 0x00490301: 0x00CD, + 0x00490302: 0x00CE, + 0x00490308: 0x00CF, + 0x004E0303: 0x00D1, + 0x004F0300: 0x00D2, + 0x004F0301: 0x00D3, + 0x004F0302: 0x00D4, + 0x004F0303: 0x00D5, + 0x004F0308: 0x00D6, + 0x00550300: 0x00D9, + 0x00550301: 0x00DA, + 0x00550302: 0x00DB, + 0x00550308: 0x00DC, + 0x00590301: 0x00DD, + 0x00610300: 0x00E0, + 0x00610301: 0x00E1, + 0x00610302: 0x00E2, + 0x00610303: 0x00E3, + 0x00610308: 0x00E4, + 0x0061030A: 0x00E5, + 0x00630327: 0x00E7, + 0x00650300: 0x00E8, + 0x00650301: 0x00E9, + 0x00650302: 0x00EA, + 0x00650308: 0x00EB, + 0x00690300: 0x00EC, + 0x00690301: 0x00ED, + 0x00690302: 0x00EE, + 0x00690308: 0x00EF, + 0x006E0303: 0x00F1, + 0x006F0300: 0x00F2, + 0x006F0301: 0x00F3, + 0x006F0302: 0x00F4, + 0x006F0303: 0x00F5, + 0x006F0308: 0x00F6, + 0x00750300: 0x00F9, + 0x00750301: 0x00FA, + 0x00750302: 0x00FB, + 0x00750308: 0x00FC, + 0x00790301: 0x00FD, + 0x00790308: 0x00FF, + 0x00410304: 0x0100, + 0x00610304: 0x0101, + 0x00410306: 0x0102, + 0x00610306: 0x0103, + 0x00410328: 0x0104, + 0x00610328: 0x0105, + 0x00430301: 0x0106, + 0x00630301: 0x0107, + 0x00430302: 0x0108, + 0x00630302: 0x0109, + 0x00430307: 0x010A, + 0x00630307: 0x010B, + 0x0043030C: 0x010C, + 0x0063030C: 0x010D, + 0x0044030C: 0x010E, + 0x0064030C: 0x010F, + 0x00450304: 0x0112, + 0x00650304: 0x0113, + 0x00450306: 0x0114, + 0x00650306: 0x0115, + 0x00450307: 0x0116, + 0x00650307: 0x0117, + 0x00450328: 0x0118, + 0x00650328: 0x0119, + 0x0045030C: 0x011A, + 0x0065030C: 0x011B, + 0x00470302: 0x011C, + 0x00670302: 0x011D, + 0x00470306: 0x011E, + 0x00670306: 0x011F, + 0x00470307: 0x0120, + 0x00670307: 0x0121, + 0x00470327: 0x0122, + 0x00670327: 0x0123, + 0x00480302: 0x0124, + 0x00680302: 0x0125, + 0x00490303: 0x0128, + 0x00690303: 0x0129, + 0x00490304: 0x012A, + 0x00690304: 0x012B, + 0x00490306: 0x012C, + 0x00690306: 0x012D, + 0x00490328: 0x012E, + 0x00690328: 0x012F, + 0x00490307: 0x0130, + 0x004A0302: 0x0134, + 0x006A0302: 0x0135, + 0x004B0327: 0x0136, + 0x006B0327: 0x0137, + 0x004C0301: 0x0139, + 0x006C0301: 0x013A, + 0x004C0327: 0x013B, + 0x006C0327: 0x013C, + 0x004C030C: 0x013D, + 0x006C030C: 0x013E, + 0x004E0301: 0x0143, + 0x006E0301: 0x0144, + 0x004E0327: 0x0145, + 0x006E0327: 0x0146, + 0x004E030C: 0x0147, + 0x006E030C: 0x0148, + 0x004F0304: 0x014C, + 0x006F0304: 0x014D, + 0x004F0306: 0x014E, + 0x006F0306: 0x014F, + 0x004F030B: 0x0150, + 0x006F030B: 0x0151, + 0x00520301: 0x0154, + 0x00720301: 0x0155, + 0x00520327: 0x0156, + 0x00720327: 0x0157, + 0x0052030C: 0x0158, + 0x0072030C: 0x0159, + 0x00530301: 0x015A, + 0x00730301: 0x015B, + 0x00530302: 0x015C, + 0x00730302: 0x015D, + 0x00530327: 0x015E, + 0x00730327: 0x015F, + 0x0053030C: 0x0160, + 0x0073030C: 0x0161, + 0x00540327: 0x0162, + 0x00740327: 0x0163, + 0x0054030C: 0x0164, + 0x0074030C: 0x0165, + 0x00550303: 0x0168, + 0x00750303: 0x0169, + 0x00550304: 0x016A, + 0x00750304: 0x016B, + 0x00550306: 0x016C, + 0x00750306: 0x016D, + 0x0055030A: 0x016E, + 0x0075030A: 0x016F, + 0x0055030B: 0x0170, + 0x0075030B: 0x0171, + 0x00550328: 0x0172, + 0x00750328: 0x0173, + 0x00570302: 0x0174, + 0x00770302: 0x0175, + 0x00590302: 0x0176, + 0x00790302: 0x0177, + 0x00590308: 0x0178, + 0x005A0301: 0x0179, + 0x007A0301: 0x017A, + 0x005A0307: 0x017B, + 0x007A0307: 0x017C, + 0x005A030C: 0x017D, + 0x007A030C: 0x017E, + 0x004F031B: 0x01A0, + 0x006F031B: 0x01A1, + 0x0055031B: 0x01AF, + 0x0075031B: 0x01B0, + 0x0041030C: 0x01CD, + 0x0061030C: 0x01CE, + 0x0049030C: 0x01CF, + 0x0069030C: 0x01D0, + 0x004F030C: 0x01D1, + 0x006F030C: 0x01D2, + 0x0055030C: 0x01D3, + 0x0075030C: 0x01D4, + 0x00DC0304: 0x01D5, + 0x00FC0304: 0x01D6, + 0x00DC0301: 0x01D7, + 0x00FC0301: 0x01D8, + 0x00DC030C: 0x01D9, + 0x00FC030C: 0x01DA, + 0x00DC0300: 0x01DB, + 0x00FC0300: 0x01DC, + 0x00C40304: 0x01DE, + 0x00E40304: 0x01DF, + 0x02260304: 0x01E0, + 0x02270304: 0x01E1, + 0x00C60304: 0x01E2, + 0x00E60304: 0x01E3, + 0x0047030C: 0x01E6, + 0x0067030C: 0x01E7, + 0x004B030C: 0x01E8, + 0x006B030C: 0x01E9, + 0x004F0328: 0x01EA, + 0x006F0328: 0x01EB, + 0x01EA0304: 0x01EC, + 0x01EB0304: 0x01ED, + 0x01B7030C: 0x01EE, + 0x0292030C: 0x01EF, + 0x006A030C: 0x01F0, + 0x00470301: 0x01F4, + 0x00670301: 0x01F5, + 0x004E0300: 0x01F8, + 0x006E0300: 0x01F9, + 0x00C50301: 0x01FA, + 0x00E50301: 0x01FB, + 0x00C60301: 0x01FC, + 0x00E60301: 0x01FD, + 0x00D80301: 0x01FE, + 0x00F80301: 0x01FF, + 0x0041030F: 0x0200, + 0x0061030F: 0x0201, + 0x00410311: 0x0202, + 0x00610311: 0x0203, + 0x0045030F: 0x0204, + 0x0065030F: 0x0205, + 0x00450311: 0x0206, + 0x00650311: 0x0207, + 0x0049030F: 0x0208, + 0x0069030F: 0x0209, + 0x00490311: 0x020A, + 0x00690311: 0x020B, + 0x004F030F: 0x020C, + 0x006F030F: 0x020D, + 0x004F0311: 0x020E, + 0x006F0311: 0x020F, + 0x0052030F: 0x0210, + 0x0072030F: 0x0211, + 0x00520311: 0x0212, + 0x00720311: 0x0213, + 0x0055030F: 0x0214, + 0x0075030F: 0x0215, + 0x00550311: 0x0216, + 0x00750311: 0x0217, + 0x00530326: 0x0218, + 0x00730326: 0x0219, + 0x00540326: 0x021A, + 0x00740326: 0x021B, + 0x0048030C: 0x021E, + 0x0068030C: 0x021F, + 0x00410307: 0x0226, + 0x00610307: 0x0227, + 0x00450327: 0x0228, + 0x00650327: 0x0229, + 0x00D60304: 0x022A, + 0x00F60304: 0x022B, + 0x00D50304: 0x022C, + 0x00F50304: 0x022D, + 0x004F0307: 0x022E, + 0x006F0307: 0x022F, + 0x022E0304: 0x0230, + 0x022F0304: 0x0231, + 0x00590304: 0x0232, + 0x00790304: 0x0233, + 0x00A80301: 0x0385, + 0x03910301: 0x0386, + 0x03950301: 0x0388, + 0x03970301: 0x0389, + 0x03990301: 0x038A, + 0x039F0301: 0x038C, + 0x03A50301: 0x038E, + 0x03A90301: 0x038F, + 0x03CA0301: 0x0390, + 0x03990308: 0x03AA, + 0x03A50308: 0x03AB, + 0x03B10301: 0x03AC, + 0x03B50301: 0x03AD, + 0x03B70301: 0x03AE, + 0x03B90301: 0x03AF, + 0x03CB0301: 0x03B0, + 0x03B90308: 0x03CA, + 0x03C50308: 0x03CB, + 0x03BF0301: 0x03CC, + 0x03C50301: 0x03CD, + 0x03C90301: 0x03CE, + 0x03D20301: 0x03D3, + 0x03D20308: 0x03D4, + 0x04150300: 0x0400, + 0x04150308: 0x0401, + 0x04130301: 0x0403, + 0x04060308: 0x0407, + 0x041A0301: 0x040C, + 0x04180300: 0x040D, + 0x04230306: 0x040E, + 0x04180306: 0x0419, + 0x04380306: 0x0439, + 0x04350300: 0x0450, + 0x04350308: 0x0451, + 0x04330301: 0x0453, + 0x04560308: 0x0457, + 0x043A0301: 0x045C, + 0x04380300: 0x045D, + 0x04430306: 0x045E, + 0x0474030F: 0x0476, + 0x0475030F: 0x0477, + 0x04160306: 0x04C1, + 0x04360306: 0x04C2, + 0x04100306: 0x04D0, + 0x04300306: 0x04D1, + 0x04100308: 0x04D2, + 0x04300308: 0x04D3, + 0x04150306: 0x04D6, + 0x04350306: 0x04D7, + 0x04D80308: 0x04DA, + 0x04D90308: 0x04DB, + 0x04160308: 0x04DC, + 0x04360308: 0x04DD, + 0x04170308: 0x04DE, + 0x04370308: 0x04DF, + 0x04180304: 0x04E2, + 0x04380304: 0x04E3, + 0x04180308: 0x04E4, + 0x04380308: 0x04E5, + 0x041E0308: 0x04E6, + 0x043E0308: 0x04E7, + 0x04E80308: 0x04EA, + 0x04E90308: 0x04EB, + 0x042D0308: 0x04EC, + 0x044D0308: 0x04ED, + 0x04230304: 0x04EE, + 0x04430304: 0x04EF, + 0x04230308: 0x04F0, + 0x04430308: 0x04F1, + 0x0423030B: 0x04F2, + 0x0443030B: 0x04F3, + 0x04270308: 0x04F4, + 0x04470308: 0x04F5, + 0x042B0308: 0x04F8, + 0x044B0308: 0x04F9, + 0x06270653: 0x0622, + 0x06270654: 0x0623, + 0x06480654: 0x0624, + 0x06270655: 0x0625, + 0x064A0654: 0x0626, + 0x06D50654: 0x06C0, + 0x06C10654: 0x06C2, + 0x06D20654: 0x06D3, + 0x0928093C: 0x0929, + 0x0930093C: 0x0931, + 0x0933093C: 0x0934, + 0x09C709BE: 0x09CB, + 0x09C709D7: 0x09CC, + 0x0B470B56: 0x0B48, + 0x0B470B3E: 0x0B4B, + 0x0B470B57: 0x0B4C, + 0x0B920BD7: 0x0B94, + 0x0BC60BBE: 0x0BCA, + 0x0BC70BBE: 0x0BCB, + 0x0BC60BD7: 0x0BCC, + 0x0C460C56: 0x0C48, + 0x0CBF0CD5: 0x0CC0, + 0x0CC60CD5: 0x0CC7, + 0x0CC60CD6: 0x0CC8, + 0x0CC60CC2: 0x0CCA, + 0x0CCA0CD5: 0x0CCB, + 0x0D460D3E: 0x0D4A, + 0x0D470D3E: 0x0D4B, + 0x0D460D57: 0x0D4C, + 0x0DD90DCA: 0x0DDA, + 0x0DD90DCF: 0x0DDC, + 0x0DDC0DCA: 0x0DDD, + 0x0DD90DDF: 0x0DDE, + 0x1025102E: 0x1026, + 0x1B051B35: 0x1B06, + 0x1B071B35: 0x1B08, + 0x1B091B35: 0x1B0A, + 0x1B0B1B35: 0x1B0C, + 0x1B0D1B35: 0x1B0E, + 0x1B111B35: 0x1B12, + 0x1B3A1B35: 0x1B3B, + 0x1B3C1B35: 0x1B3D, + 0x1B3E1B35: 0x1B40, + 0x1B3F1B35: 0x1B41, + 0x1B421B35: 0x1B43, + 0x00410325: 0x1E00, + 0x00610325: 0x1E01, + 0x00420307: 0x1E02, + 0x00620307: 0x1E03, + 0x00420323: 0x1E04, + 0x00620323: 0x1E05, + 0x00420331: 0x1E06, + 0x00620331: 0x1E07, + 0x00C70301: 0x1E08, + 0x00E70301: 0x1E09, + 0x00440307: 0x1E0A, + 0x00640307: 0x1E0B, + 0x00440323: 0x1E0C, + 0x00640323: 0x1E0D, + 0x00440331: 0x1E0E, + 0x00640331: 0x1E0F, + 0x00440327: 0x1E10, + 0x00640327: 0x1E11, + 0x0044032D: 0x1E12, + 0x0064032D: 0x1E13, + 0x01120300: 0x1E14, + 0x01130300: 0x1E15, + 0x01120301: 0x1E16, + 0x01130301: 0x1E17, + 0x0045032D: 0x1E18, + 0x0065032D: 0x1E19, + 0x00450330: 0x1E1A, + 0x00650330: 0x1E1B, + 0x02280306: 0x1E1C, + 0x02290306: 0x1E1D, + 0x00460307: 0x1E1E, + 0x00660307: 0x1E1F, + 0x00470304: 0x1E20, + 0x00670304: 0x1E21, + 0x00480307: 0x1E22, + 0x00680307: 0x1E23, + 0x00480323: 0x1E24, + 0x00680323: 0x1E25, + 0x00480308: 0x1E26, + 0x00680308: 0x1E27, + 0x00480327: 0x1E28, + 0x00680327: 0x1E29, + 0x0048032E: 0x1E2A, + 0x0068032E: 0x1E2B, + 0x00490330: 0x1E2C, + 0x00690330: 0x1E2D, + 0x00CF0301: 0x1E2E, + 0x00EF0301: 0x1E2F, + 0x004B0301: 0x1E30, + 0x006B0301: 0x1E31, + 0x004B0323: 0x1E32, + 0x006B0323: 0x1E33, + 0x004B0331: 0x1E34, + 0x006B0331: 0x1E35, + 0x004C0323: 0x1E36, + 0x006C0323: 0x1E37, + 0x1E360304: 0x1E38, + 0x1E370304: 0x1E39, + 0x004C0331: 0x1E3A, + 0x006C0331: 0x1E3B, + 0x004C032D: 0x1E3C, + 0x006C032D: 0x1E3D, + 0x004D0301: 0x1E3E, + 0x006D0301: 0x1E3F, + 0x004D0307: 0x1E40, + 0x006D0307: 0x1E41, + 0x004D0323: 0x1E42, + 0x006D0323: 0x1E43, + 0x004E0307: 0x1E44, + 0x006E0307: 0x1E45, + 0x004E0323: 0x1E46, + 0x006E0323: 0x1E47, + 0x004E0331: 0x1E48, + 0x006E0331: 0x1E49, + 0x004E032D: 0x1E4A, + 0x006E032D: 0x1E4B, + 0x00D50301: 0x1E4C, + 0x00F50301: 0x1E4D, + 0x00D50308: 0x1E4E, + 0x00F50308: 0x1E4F, + 0x014C0300: 0x1E50, + 0x014D0300: 0x1E51, + 0x014C0301: 0x1E52, + 0x014D0301: 0x1E53, + 0x00500301: 0x1E54, + 0x00700301: 0x1E55, + 0x00500307: 0x1E56, + 0x00700307: 0x1E57, + 0x00520307: 0x1E58, + 0x00720307: 0x1E59, + 0x00520323: 0x1E5A, + 0x00720323: 0x1E5B, + 0x1E5A0304: 0x1E5C, + 0x1E5B0304: 0x1E5D, + 0x00520331: 0x1E5E, + 0x00720331: 0x1E5F, + 0x00530307: 0x1E60, + 0x00730307: 0x1E61, + 0x00530323: 0x1E62, + 0x00730323: 0x1E63, + 0x015A0307: 0x1E64, + 0x015B0307: 0x1E65, + 0x01600307: 0x1E66, + 0x01610307: 0x1E67, + 0x1E620307: 0x1E68, + 0x1E630307: 0x1E69, + 0x00540307: 0x1E6A, + 0x00740307: 0x1E6B, + 0x00540323: 0x1E6C, + 0x00740323: 0x1E6D, + 0x00540331: 0x1E6E, + 0x00740331: 0x1E6F, + 0x0054032D: 0x1E70, + 0x0074032D: 0x1E71, + 0x00550324: 0x1E72, + 0x00750324: 0x1E73, + 0x00550330: 0x1E74, + 0x00750330: 0x1E75, + 0x0055032D: 0x1E76, + 0x0075032D: 0x1E77, + 0x01680301: 0x1E78, + 0x01690301: 0x1E79, + 0x016A0308: 0x1E7A, + 0x016B0308: 0x1E7B, + 0x00560303: 0x1E7C, + 0x00760303: 0x1E7D, + 0x00560323: 0x1E7E, + 0x00760323: 0x1E7F, + 0x00570300: 0x1E80, + 0x00770300: 0x1E81, + 0x00570301: 0x1E82, + 0x00770301: 0x1E83, + 0x00570308: 0x1E84, + 0x00770308: 0x1E85, + 0x00570307: 0x1E86, + 0x00770307: 0x1E87, + 0x00570323: 0x1E88, + 0x00770323: 0x1E89, + 0x00580307: 0x1E8A, + 0x00780307: 0x1E8B, + 0x00580308: 0x1E8C, + 0x00780308: 0x1E8D, + 0x00590307: 0x1E8E, + 0x00790307: 0x1E8F, + 0x005A0302: 0x1E90, + 0x007A0302: 0x1E91, + 0x005A0323: 0x1E92, + 0x007A0323: 0x1E93, + 0x005A0331: 0x1E94, + 0x007A0331: 0x1E95, + 0x00680331: 0x1E96, + 0x00740308: 0x1E97, + 0x0077030A: 0x1E98, + 0x0079030A: 0x1E99, + 0x017F0307: 0x1E9B, + 0x00410323: 0x1EA0, + 0x00610323: 0x1EA1, + 0x00410309: 0x1EA2, + 0x00610309: 0x1EA3, + 0x00C20301: 0x1EA4, + 0x00E20301: 0x1EA5, + 0x00C20300: 0x1EA6, + 0x00E20300: 0x1EA7, + 0x00C20309: 0x1EA8, + 0x00E20309: 0x1EA9, + 0x00C20303: 0x1EAA, + 0x00E20303: 0x1EAB, + 0x1EA00302: 0x1EAC, + 0x1EA10302: 0x1EAD, + 0x01020301: 0x1EAE, + 0x01030301: 0x1EAF, + 0x01020300: 0x1EB0, + 0x01030300: 0x1EB1, + 0x01020309: 0x1EB2, + 0x01030309: 0x1EB3, + 0x01020303: 0x1EB4, + 0x01030303: 0x1EB5, + 0x1EA00306: 0x1EB6, + 0x1EA10306: 0x1EB7, + 0x00450323: 0x1EB8, + 0x00650323: 0x1EB9, + 0x00450309: 0x1EBA, + 0x00650309: 0x1EBB, + 0x00450303: 0x1EBC, + 0x00650303: 0x1EBD, + 0x00CA0301: 0x1EBE, + 0x00EA0301: 0x1EBF, + 0x00CA0300: 0x1EC0, + 0x00EA0300: 0x1EC1, + 0x00CA0309: 0x1EC2, + 0x00EA0309: 0x1EC3, + 0x00CA0303: 0x1EC4, + 0x00EA0303: 0x1EC5, + 0x1EB80302: 0x1EC6, + 0x1EB90302: 0x1EC7, + 0x00490309: 0x1EC8, + 0x00690309: 0x1EC9, + 0x00490323: 0x1ECA, + 0x00690323: 0x1ECB, + 0x004F0323: 0x1ECC, + 0x006F0323: 0x1ECD, + 0x004F0309: 0x1ECE, + 0x006F0309: 0x1ECF, + 0x00D40301: 0x1ED0, + 0x00F40301: 0x1ED1, + 0x00D40300: 0x1ED2, + 0x00F40300: 0x1ED3, + 0x00D40309: 0x1ED4, + 0x00F40309: 0x1ED5, + 0x00D40303: 0x1ED6, + 0x00F40303: 0x1ED7, + 0x1ECC0302: 0x1ED8, + 0x1ECD0302: 0x1ED9, + 0x01A00301: 0x1EDA, + 0x01A10301: 0x1EDB, + 0x01A00300: 0x1EDC, + 0x01A10300: 0x1EDD, + 0x01A00309: 0x1EDE, + 0x01A10309: 0x1EDF, + 0x01A00303: 0x1EE0, + 0x01A10303: 0x1EE1, + 0x01A00323: 0x1EE2, + 0x01A10323: 0x1EE3, + 0x00550323: 0x1EE4, + 0x00750323: 0x1EE5, + 0x00550309: 0x1EE6, + 0x00750309: 0x1EE7, + 0x01AF0301: 0x1EE8, + 0x01B00301: 0x1EE9, + 0x01AF0300: 0x1EEA, + 0x01B00300: 0x1EEB, + 0x01AF0309: 0x1EEC, + 0x01B00309: 0x1EED, + 0x01AF0303: 0x1EEE, + 0x01B00303: 0x1EEF, + 0x01AF0323: 0x1EF0, + 0x01B00323: 0x1EF1, + 0x00590300: 0x1EF2, + 0x00790300: 0x1EF3, + 0x00590323: 0x1EF4, + 0x00790323: 0x1EF5, + 0x00590309: 0x1EF6, + 0x00790309: 0x1EF7, + 0x00590303: 0x1EF8, + 0x00790303: 0x1EF9, + 0x03B10313: 0x1F00, + 0x03B10314: 0x1F01, + 0x1F000300: 0x1F02, + 0x1F010300: 0x1F03, + 0x1F000301: 0x1F04, + 0x1F010301: 0x1F05, + 0x1F000342: 0x1F06, + 0x1F010342: 0x1F07, + 0x03910313: 0x1F08, + 0x03910314: 0x1F09, + 0x1F080300: 0x1F0A, + 0x1F090300: 0x1F0B, + 0x1F080301: 0x1F0C, + 0x1F090301: 0x1F0D, + 0x1F080342: 0x1F0E, + 0x1F090342: 0x1F0F, + 0x03B50313: 0x1F10, + 0x03B50314: 0x1F11, + 0x1F100300: 0x1F12, + 0x1F110300: 0x1F13, + 0x1F100301: 0x1F14, + 0x1F110301: 0x1F15, + 0x03950313: 0x1F18, + 0x03950314: 0x1F19, + 0x1F180300: 0x1F1A, + 0x1F190300: 0x1F1B, + 0x1F180301: 0x1F1C, + 0x1F190301: 0x1F1D, + 0x03B70313: 0x1F20, + 0x03B70314: 0x1F21, + 0x1F200300: 0x1F22, + 0x1F210300: 0x1F23, + 0x1F200301: 0x1F24, + 0x1F210301: 0x1F25, + 0x1F200342: 0x1F26, + 0x1F210342: 0x1F27, + 0x03970313: 0x1F28, + 0x03970314: 0x1F29, + 0x1F280300: 0x1F2A, + 0x1F290300: 0x1F2B, + 0x1F280301: 0x1F2C, + 0x1F290301: 0x1F2D, + 0x1F280342: 0x1F2E, + 0x1F290342: 0x1F2F, + 0x03B90313: 0x1F30, + 0x03B90314: 0x1F31, + 0x1F300300: 0x1F32, + 0x1F310300: 0x1F33, + 0x1F300301: 0x1F34, + 0x1F310301: 0x1F35, + 0x1F300342: 0x1F36, + 0x1F310342: 0x1F37, + 0x03990313: 0x1F38, + 0x03990314: 0x1F39, + 0x1F380300: 0x1F3A, + 0x1F390300: 0x1F3B, + 0x1F380301: 0x1F3C, + 0x1F390301: 0x1F3D, + 0x1F380342: 0x1F3E, + 0x1F390342: 0x1F3F, + 0x03BF0313: 0x1F40, + 0x03BF0314: 0x1F41, + 0x1F400300: 0x1F42, + 0x1F410300: 0x1F43, + 0x1F400301: 0x1F44, + 0x1F410301: 0x1F45, + 0x039F0313: 0x1F48, + 0x039F0314: 0x1F49, + 0x1F480300: 0x1F4A, + 0x1F490300: 0x1F4B, + 0x1F480301: 0x1F4C, + 0x1F490301: 0x1F4D, + 0x03C50313: 0x1F50, + 0x03C50314: 0x1F51, + 0x1F500300: 0x1F52, + 0x1F510300: 0x1F53, + 0x1F500301: 0x1F54, + 0x1F510301: 0x1F55, + 0x1F500342: 0x1F56, + 0x1F510342: 0x1F57, + 0x03A50314: 0x1F59, + 0x1F590300: 0x1F5B, + 0x1F590301: 0x1F5D, + 0x1F590342: 0x1F5F, + 0x03C90313: 0x1F60, + 0x03C90314: 0x1F61, + 0x1F600300: 0x1F62, + 0x1F610300: 0x1F63, + 0x1F600301: 0x1F64, + 0x1F610301: 0x1F65, + 0x1F600342: 0x1F66, + 0x1F610342: 0x1F67, + 0x03A90313: 0x1F68, + 0x03A90314: 0x1F69, + 0x1F680300: 0x1F6A, + 0x1F690300: 0x1F6B, + 0x1F680301: 0x1F6C, + 0x1F690301: 0x1F6D, + 0x1F680342: 0x1F6E, + 0x1F690342: 0x1F6F, + 0x03B10300: 0x1F70, + 0x03B50300: 0x1F72, + 0x03B70300: 0x1F74, + 0x03B90300: 0x1F76, + 0x03BF0300: 0x1F78, + 0x03C50300: 0x1F7A, + 0x03C90300: 0x1F7C, + 0x1F000345: 0x1F80, + 0x1F010345: 0x1F81, + 0x1F020345: 0x1F82, + 0x1F030345: 0x1F83, + 0x1F040345: 0x1F84, + 0x1F050345: 0x1F85, + 0x1F060345: 0x1F86, + 0x1F070345: 0x1F87, + 0x1F080345: 0x1F88, + 0x1F090345: 0x1F89, + 0x1F0A0345: 0x1F8A, + 0x1F0B0345: 0x1F8B, + 0x1F0C0345: 0x1F8C, + 0x1F0D0345: 0x1F8D, + 0x1F0E0345: 0x1F8E, + 0x1F0F0345: 0x1F8F, + 0x1F200345: 0x1F90, + 0x1F210345: 0x1F91, + 0x1F220345: 0x1F92, + 0x1F230345: 0x1F93, + 0x1F240345: 0x1F94, + 0x1F250345: 0x1F95, + 0x1F260345: 0x1F96, + 0x1F270345: 0x1F97, + 0x1F280345: 0x1F98, + 0x1F290345: 0x1F99, + 0x1F2A0345: 0x1F9A, + 0x1F2B0345: 0x1F9B, + 0x1F2C0345: 0x1F9C, + 0x1F2D0345: 0x1F9D, + 0x1F2E0345: 0x1F9E, + 0x1F2F0345: 0x1F9F, + 0x1F600345: 0x1FA0, + 0x1F610345: 0x1FA1, + 0x1F620345: 0x1FA2, + 0x1F630345: 0x1FA3, + 0x1F640345: 0x1FA4, + 0x1F650345: 0x1FA5, + 0x1F660345: 0x1FA6, + 0x1F670345: 0x1FA7, + 0x1F680345: 0x1FA8, + 0x1F690345: 0x1FA9, + 0x1F6A0345: 0x1FAA, + 0x1F6B0345: 0x1FAB, + 0x1F6C0345: 0x1FAC, + 0x1F6D0345: 0x1FAD, + 0x1F6E0345: 0x1FAE, + 0x1F6F0345: 0x1FAF, + 0x03B10306: 0x1FB0, + 0x03B10304: 0x1FB1, + 0x1F700345: 0x1FB2, + 0x03B10345: 0x1FB3, + 0x03AC0345: 0x1FB4, + 0x03B10342: 0x1FB6, + 0x1FB60345: 0x1FB7, + 0x03910306: 0x1FB8, + 0x03910304: 0x1FB9, + 0x03910300: 0x1FBA, + 0x03910345: 0x1FBC, + 0x00A80342: 0x1FC1, + 0x1F740345: 0x1FC2, + 0x03B70345: 0x1FC3, + 0x03AE0345: 0x1FC4, + 0x03B70342: 0x1FC6, + 0x1FC60345: 0x1FC7, + 0x03950300: 0x1FC8, + 0x03970300: 0x1FCA, + 0x03970345: 0x1FCC, + 0x1FBF0300: 0x1FCD, + 0x1FBF0301: 0x1FCE, + 0x1FBF0342: 0x1FCF, + 0x03B90306: 0x1FD0, + 0x03B90304: 0x1FD1, + 0x03CA0300: 0x1FD2, + 0x03B90342: 0x1FD6, + 0x03CA0342: 0x1FD7, + 0x03990306: 0x1FD8, + 0x03990304: 0x1FD9, + 0x03990300: 0x1FDA, + 0x1FFE0300: 0x1FDD, + 0x1FFE0301: 0x1FDE, + 0x1FFE0342: 0x1FDF, + 0x03C50306: 0x1FE0, + 0x03C50304: 0x1FE1, + 0x03CB0300: 0x1FE2, + 0x03C10313: 0x1FE4, + 0x03C10314: 0x1FE5, + 0x03C50342: 0x1FE6, + 0x03CB0342: 0x1FE7, + 0x03A50306: 0x1FE8, + 0x03A50304: 0x1FE9, + 0x03A50300: 0x1FEA, + 0x03A10314: 0x1FEC, + 0x00A80300: 0x1FED, + 0x1F7C0345: 0x1FF2, + 0x03C90345: 0x1FF3, + 0x03CE0345: 0x1FF4, + 0x03C90342: 0x1FF6, + 0x1FF60345: 0x1FF7, + 0x039F0300: 0x1FF8, + 0x03A90300: 0x1FFA, + 0x03A90345: 0x1FFC, + 0x21900338: 0x219A, + 0x21920338: 0x219B, + 0x21940338: 0x21AE, + 0x21D00338: 0x21CD, + 0x21D40338: 0x21CE, + 0x21D20338: 0x21CF, + 0x22030338: 0x2204, + 0x22080338: 0x2209, + 0x220B0338: 0x220C, + 0x22230338: 0x2224, + 0x22250338: 0x2226, + 0x223C0338: 0x2241, + 0x22430338: 0x2244, + 0x22450338: 0x2247, + 0x22480338: 0x2249, + 0x003D0338: 0x2260, + 0x22610338: 0x2262, + 0x224D0338: 0x226D, + 0x003C0338: 0x226E, + 0x003E0338: 0x226F, + 0x22640338: 0x2270, + 0x22650338: 0x2271, + 0x22720338: 0x2274, + 0x22730338: 0x2275, + 0x22760338: 0x2278, + 0x22770338: 0x2279, + 0x227A0338: 0x2280, + 0x227B0338: 0x2281, + 0x22820338: 0x2284, + 0x22830338: 0x2285, + 0x22860338: 0x2288, + 0x22870338: 0x2289, + 0x22A20338: 0x22AC, + 0x22A80338: 0x22AD, + 0x22A90338: 0x22AE, + 0x22AB0338: 0x22AF, + 0x227C0338: 0x22E0, + 0x227D0338: 0x22E1, + 0x22910338: 0x22E2, + 0x22920338: 0x22E3, + 0x22B20338: 0x22EA, + 0x22B30338: 0x22EB, + 0x22B40338: 0x22EC, + 0x22B50338: 0x22ED, + 0x304B3099: 0x304C, + 0x304D3099: 0x304E, + 0x304F3099: 0x3050, + 0x30513099: 0x3052, + 0x30533099: 0x3054, + 0x30553099: 0x3056, + 0x30573099: 0x3058, + 0x30593099: 0x305A, + 0x305B3099: 0x305C, + 0x305D3099: 0x305E, + 0x305F3099: 0x3060, + 0x30613099: 0x3062, + 0x30643099: 0x3065, + 0x30663099: 0x3067, + 0x30683099: 0x3069, + 0x306F3099: 0x3070, + 0x306F309A: 0x3071, + 0x30723099: 0x3073, + 0x3072309A: 0x3074, + 0x30753099: 0x3076, + 0x3075309A: 0x3077, + 0x30783099: 0x3079, + 0x3078309A: 0x307A, + 0x307B3099: 0x307C, + 0x307B309A: 0x307D, + 0x30463099: 0x3094, + 0x309D3099: 0x309E, + 0x30AB3099: 0x30AC, + 0x30AD3099: 0x30AE, + 0x30AF3099: 0x30B0, + 0x30B13099: 0x30B2, + 0x30B33099: 0x30B4, + 0x30B53099: 0x30B6, + 0x30B73099: 0x30B8, + 0x30B93099: 0x30BA, + 0x30BB3099: 0x30BC, + 0x30BD3099: 0x30BE, + 0x30BF3099: 0x30C0, + 0x30C13099: 0x30C2, + 0x30C43099: 0x30C5, + 0x30C63099: 0x30C7, + 0x30C83099: 0x30C9, + 0x30CF3099: 0x30D0, + 0x30CF309A: 0x30D1, + 0x30D23099: 0x30D3, + 0x30D2309A: 0x30D4, + 0x30D53099: 0x30D6, + 0x30D5309A: 0x30D7, + 0x30D83099: 0x30D9, + 0x30D8309A: 0x30DA, + 0x30DB3099: 0x30DC, + 0x30DB309A: 0x30DD, + 0x30A63099: 0x30F4, + 0x30EF3099: 0x30F7, + 0x30F03099: 0x30F8, + 0x30F13099: 0x30F9, + 0x30F23099: 0x30FA, + 0x30FD3099: 0x30FE, + 0x109910BA: 0x1109A, + 0x109B10BA: 0x1109C, + 0x10A510BA: 0x110AB, + 0x11311127: 0x1112E, + 0x11321127: 0x1112F, + 0x1347133E: 0x1134B, + 0x13471357: 0x1134C, + 0x14B914BA: 0x114BB, + 0x14B914B0: 0x114BC, + 0x14B914BD: 0x114BE, + 0x15B815AF: 0x115BA, + 0x15B915AF: 0x115BB, +} -const recompMapPacked = "" + - "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0 - "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1 - "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2 - "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3 - "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4 - "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5 - "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7 - "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8 - "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9 - "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA - "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB - "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC - "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD - "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE - "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF - "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1 - "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2 - "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3 - "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4 - "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5 - "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6 - "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9 - "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA - "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB - "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC - "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD - "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0 - "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1 - "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2 - "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3 - "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4 - "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5 - "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7 - "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8 - "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9 - "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA - "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB - "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC - "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED - "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE - "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF - "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1 - "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2 - "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3 - "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4 - "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5 - "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6 - "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9 - "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA - "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB - "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC - "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD - "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF - "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100 - "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101 - "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102 - "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103 - "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104 - "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105 - "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106 - "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107 - "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108 - "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109 - "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A - "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B - "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C - "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D - "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E - "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F - "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112 - "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113 - "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114 - "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115 - "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116 - "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117 - "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118 - "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119 - "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A - "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B - "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C - "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D - "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E - "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F - "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120 - "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121 - "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122 - "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123 - "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124 - "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125 - "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128 - "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129 - "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A - "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B - "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C - "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D - "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E - "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F - "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130 - "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134 - "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135 - "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136 - "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137 - "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139 - "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A - "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B - "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C - "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D - "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E - "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143 - "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144 - "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145 - "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146 - "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147 - "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148 - "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C - "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D - "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E - "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F - "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150 - "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151 - "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154 - "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155 - "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156 - "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157 - "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158 - "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159 - "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A - "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B - "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C - "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D - "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E - "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F - "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160 - "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161 - "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162 - "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163 - "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164 - "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165 - "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168 - "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169 - "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A - "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B - "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C - "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D - "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E - "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F - "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170 - "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171 - "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172 - "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173 - "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174 - "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175 - "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176 - "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177 - "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178 - "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179 - "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A - "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B - "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C - "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D - "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E - "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0 - "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1 - "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF - "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0 - "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD - "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE - "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF - "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0 - "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1 - "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2 - "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3 - "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4 - "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5 - "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6 - "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7 - "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8 - "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9 - "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA - "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB - "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC - "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE - "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF - "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0 - "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1 - "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2 - "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3 - "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6 - "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7 - "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8 - "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9 - "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA - "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB - "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC - "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED - "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE - "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF - "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0 - "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4 - "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5 - "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8 - "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9 - "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA - "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB - "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC - "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD - "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE - "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF - "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200 - "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201 - "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202 - "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203 - "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204 - "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205 - "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206 - "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207 - "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208 - "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209 - "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A - "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B - "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C - "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D - "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E - "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F - "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210 - "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211 - "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212 - "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213 - "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214 - "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215 - "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216 - "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217 - "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218 - "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219 - "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A - "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B - "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E - "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F - "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226 - "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227 - "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228 - "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229 - "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A - "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B - "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C - "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D - "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E - "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F - "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230 - "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231 - "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232 - "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233 - "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385 - "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386 - "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388 - "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389 - "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A - "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C - "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E - "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F - "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390 - "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA - "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB - "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC - "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD - "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE - "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF - "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0 - "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA - "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB - "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC - "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD - "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE - "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3 - "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4 - "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400 - "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401 - "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403 - "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407 - "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C - "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D - "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E - "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419 - "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439 - "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450 - "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451 - "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453 - "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457 - "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C - "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D - "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E - "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476 - "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477 - "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1 - "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2 - "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0 - "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1 - "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2 - "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3 - "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6 - "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7 - "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA - "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB - "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC - "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD - "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE - "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF - "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2 - "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3 - "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4 - "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5 - "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6 - "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7 - "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA - "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB - "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC - "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED - "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE - "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF - "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0 - "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1 - "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2 - "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3 - "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4 - "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5 - "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8 - "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9 - "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622 - "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623 - "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624 - "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625 - "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626 - "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0 - "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2 - "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3 - "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929 - "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931 - "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934 - "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB - "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC - "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48 - "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B - "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C - "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94 - "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA - "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB - "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC - "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48 - "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0 - "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7 - "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8 - "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA - "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB - "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A - "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B - "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C - "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA - "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC - "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD - "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE - "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026 - "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06 - "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08 - "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A - "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C - "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E - "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12 - "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B - "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D - "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40 - "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41 - "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43 - "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00 - "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01 - "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02 - "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03 - "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04 - "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05 - "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06 - "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07 - "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08 - "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09 - "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A - "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B - "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C - "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D - "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E - "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F - "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10 - "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11 - "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12 - "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13 - "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14 - "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15 - "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16 - "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17 - "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18 - "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19 - "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A - "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B - "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C - "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D - "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E - "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F - "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20 - "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21 - "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22 - "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23 - "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24 - "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25 - "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26 - "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27 - "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28 - "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29 - "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A - "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B - "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C - "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D - "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E - "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F - "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30 - "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31 - "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32 - "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33 - "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34 - "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35 - "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36 - "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37 - "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38 - "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39 - "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A - "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B - "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C - "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D - "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E - "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F - "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40 - "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41 - "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42 - "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43 - "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44 - "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45 - "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46 - "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47 - "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48 - "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49 - "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A - "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B - "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C - "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D - "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E - "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F - "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50 - "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51 - "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52 - "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53 - "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54 - "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55 - "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56 - "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57 - "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58 - "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59 - "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A - "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B - "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C - "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D - "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E - "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F - "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60 - "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61 - "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62 - "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63 - "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64 - "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65 - "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66 - "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67 - "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68 - "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69 - "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A - "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B - "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C - "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D - "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E - "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F - "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70 - "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71 - "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72 - "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73 - "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74 - "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75 - "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76 - "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77 - "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78 - "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79 - "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A - "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B - "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C - "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D - "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E - "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F - "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 - "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 - "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 - "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83 - "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84 - "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85 - "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86 - "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87 - "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88 - "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89 - "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A - "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B - "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C - "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D - "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E - "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F - "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90 - "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91 - "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92 - "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93 - "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94 - "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95 - "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96 - "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 - "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 - "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 - "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B - "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 - "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 - "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 - "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3 - "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4 - "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5 - "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6 - "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7 - "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8 - "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9 - "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA - "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB - "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC - "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD - "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE - "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF - "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0 - "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1 - "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2 - "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3 - "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4 - "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5 - "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6 - "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7 - "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8 - "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9 - "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA - "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB - "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC - "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD - "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE - "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF - "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0 - "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1 - "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2 - "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3 - "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4 - "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5 - "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6 - "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7 - "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8 - "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9 - "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA - "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB - "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC - "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD - "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE - "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF - "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0 - "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1 - "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2 - "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3 - "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4 - "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5 - "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6 - "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7 - "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8 - "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9 - "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA - "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB - "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC - "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD - "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE - "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF - "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0 - "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1 - "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2 - "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3 - "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4 - "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5 - "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6 - "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7 - "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8 - "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9 - "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA - "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB - "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC - "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED - "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE - "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF - "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0 - "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1 - "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2 - "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3 - "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4 - "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5 - "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6 - "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7 - "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8 - "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9 - "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00 - "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01 - "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02 - "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03 - "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04 - "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05 - "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06 - "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07 - "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08 - "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09 - "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A - "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B - "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C - "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D - "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E - "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F - "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10 - "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11 - "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12 - "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13 - "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14 - "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15 - "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18 - "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19 - "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A - "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B - "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C - "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D - "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20 - "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21 - "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22 - "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23 - "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24 - "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25 - "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26 - "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27 - "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28 - "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29 - "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A - "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B - "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C - "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D - "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E - "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F - "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30 - "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31 - "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32 - "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33 - "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34 - "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35 - "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36 - "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37 - "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38 - "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39 - "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A - "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B - "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C - "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D - "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E - "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F - "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40 - "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41 - "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42 - "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43 - "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44 - "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45 - "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48 - "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49 - "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A - "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B - "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C - "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D - "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50 - "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51 - "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52 - "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53 - "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54 - "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55 - "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56 - "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57 - "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59 - "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B - "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D - "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F - "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60 - "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61 - "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62 - "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63 - "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64 - "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65 - "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66 - "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67 - "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68 - "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69 - "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A - "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B - "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C - "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D - "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E - "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F - "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70 - "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72 - "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74 - "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76 - "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78 - "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A - "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C - "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80 - "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81 - "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82 - "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83 - "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84 - "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85 - "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86 - "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87 - "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88 - "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89 - "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A - "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B - "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C - "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D - "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E - "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F - "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90 - "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91 - "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92 - "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93 - "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94 - "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95 - "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96 - "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97 - "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98 - "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99 - "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A - "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B - "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C - "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D - "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E - "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F - "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0 - "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1 - "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2 - "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3 - "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4 - "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5 - "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6 - "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7 - "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8 - "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9 - "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA - "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB - "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC - "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD - "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE - "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF - "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0 - "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1 - "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2 - "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3 - "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4 - "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6 - "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7 - "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8 - "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9 - "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA - "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC - "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1 - "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2 - "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3 - "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4 - "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6 - "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7 - "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8 - "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA - "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC - "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD - "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE - "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF - "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0 - "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1 - "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2 - "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6 - "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7 - "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8 - "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9 - "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA - "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD - "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE - "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF - "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0 - "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1 - "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2 - "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4 - "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5 - "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6 - "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7 - "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8 - "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9 - "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA - "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC - "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED - "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2 - "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3 - "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4 - "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6 - "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7 - "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8 - "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA - "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC - "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A - "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B - "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE - "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD - "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE - "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF - "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204 - "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209 - "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C - "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224 - "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226 - "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241 - "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244 - "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247 - "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249 - "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260 - "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262 - "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D - "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E - "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F - "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270 - "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271 - "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274 - "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275 - "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278 - "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279 - "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280 - "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281 - "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284 - "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285 - "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288 - "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289 - "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC - "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD - "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE - "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF - "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0 - "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1 - "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2 - "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3 - "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA - "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB - "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC - "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED - "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C - "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E - "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050 - "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052 - "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054 - "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056 - "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058 - "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A - "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C - "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E - "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060 - "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062 - "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065 - "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067 - "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069 - "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070 - "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071 - "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073 - "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074 - "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076 - "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077 - "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079 - "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A - "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C - "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D - "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094 - "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E - "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC - "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE - "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0 - "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2 - "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4 - "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6 - "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8 - "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA - "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC - "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE - "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0 - "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2 - "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5 - "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7 - "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9 - "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0 - "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1 - "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3 - "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4 - "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6 - "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7 - "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9 - "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA - "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC - "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD - "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4 - "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7 - "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8 - "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9 - "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA - "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE - "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A - "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C - "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB - "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E - "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F - "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B - "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C - "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB - "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC - "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE - "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA - "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB - "" - // Total size of tables: 53KB (54226 bytes) +// Total size of tables: 53KB (54226 bytes) diff --git a/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go index 942906929..a01274a8e 100644 --- a/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go +++ b/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go @@ -4,8 +4,6 @@ package norm -import "sync" - const ( // Version is the Unicode edition from which the tables are derived. Version = "9.0.0" @@ -6689,949 +6687,947 @@ var nfkcSparseValues = [875]valueRange{ } // recompMap: 7520 bytes (entries only) -var recompMap map[uint32]rune -var recompMapOnce sync.Once +var recompMap = map[uint32]rune{ + 0x00410300: 0x00C0, + 0x00410301: 0x00C1, + 0x00410302: 0x00C2, + 0x00410303: 0x00C3, + 0x00410308: 0x00C4, + 0x0041030A: 0x00C5, + 0x00430327: 0x00C7, + 0x00450300: 0x00C8, + 0x00450301: 0x00C9, + 0x00450302: 0x00CA, + 0x00450308: 0x00CB, + 0x00490300: 0x00CC, + 0x00490301: 0x00CD, + 0x00490302: 0x00CE, + 0x00490308: 0x00CF, + 0x004E0303: 0x00D1, + 0x004F0300: 0x00D2, + 0x004F0301: 0x00D3, + 0x004F0302: 0x00D4, + 0x004F0303: 0x00D5, + 0x004F0308: 0x00D6, + 0x00550300: 0x00D9, + 0x00550301: 0x00DA, + 0x00550302: 0x00DB, + 0x00550308: 0x00DC, + 0x00590301: 0x00DD, + 0x00610300: 0x00E0, + 0x00610301: 0x00E1, + 0x00610302: 0x00E2, + 0x00610303: 0x00E3, + 0x00610308: 0x00E4, + 0x0061030A: 0x00E5, + 0x00630327: 0x00E7, + 0x00650300: 0x00E8, + 0x00650301: 0x00E9, + 0x00650302: 0x00EA, + 0x00650308: 0x00EB, + 0x00690300: 0x00EC, + 0x00690301: 0x00ED, + 0x00690302: 0x00EE, + 0x00690308: 0x00EF, + 0x006E0303: 0x00F1, + 0x006F0300: 0x00F2, + 0x006F0301: 0x00F3, + 0x006F0302: 0x00F4, + 0x006F0303: 0x00F5, + 0x006F0308: 0x00F6, + 0x00750300: 0x00F9, + 0x00750301: 0x00FA, + 0x00750302: 0x00FB, + 0x00750308: 0x00FC, + 0x00790301: 0x00FD, + 0x00790308: 0x00FF, + 0x00410304: 0x0100, + 0x00610304: 0x0101, + 0x00410306: 0x0102, + 0x00610306: 0x0103, + 0x00410328: 0x0104, + 0x00610328: 0x0105, + 0x00430301: 0x0106, + 0x00630301: 0x0107, + 0x00430302: 0x0108, + 0x00630302: 0x0109, + 0x00430307: 0x010A, + 0x00630307: 0x010B, + 0x0043030C: 0x010C, + 0x0063030C: 0x010D, + 0x0044030C: 0x010E, + 0x0064030C: 0x010F, + 0x00450304: 0x0112, + 0x00650304: 0x0113, + 0x00450306: 0x0114, + 0x00650306: 0x0115, + 0x00450307: 0x0116, + 0x00650307: 0x0117, + 0x00450328: 0x0118, + 0x00650328: 0x0119, + 0x0045030C: 0x011A, + 0x0065030C: 0x011B, + 0x00470302: 0x011C, + 0x00670302: 0x011D, + 0x00470306: 0x011E, + 0x00670306: 0x011F, + 0x00470307: 0x0120, + 0x00670307: 0x0121, + 0x00470327: 0x0122, + 0x00670327: 0x0123, + 0x00480302: 0x0124, + 0x00680302: 0x0125, + 0x00490303: 0x0128, + 0x00690303: 0x0129, + 0x00490304: 0x012A, + 0x00690304: 0x012B, + 0x00490306: 0x012C, + 0x00690306: 0x012D, + 0x00490328: 0x012E, + 0x00690328: 0x012F, + 0x00490307: 0x0130, + 0x004A0302: 0x0134, + 0x006A0302: 0x0135, + 0x004B0327: 0x0136, + 0x006B0327: 0x0137, + 0x004C0301: 0x0139, + 0x006C0301: 0x013A, + 0x004C0327: 0x013B, + 0x006C0327: 0x013C, + 0x004C030C: 0x013D, + 0x006C030C: 0x013E, + 0x004E0301: 0x0143, + 0x006E0301: 0x0144, + 0x004E0327: 0x0145, + 0x006E0327: 0x0146, + 0x004E030C: 0x0147, + 0x006E030C: 0x0148, + 0x004F0304: 0x014C, + 0x006F0304: 0x014D, + 0x004F0306: 0x014E, + 0x006F0306: 0x014F, + 0x004F030B: 0x0150, + 0x006F030B: 0x0151, + 0x00520301: 0x0154, + 0x00720301: 0x0155, + 0x00520327: 0x0156, + 0x00720327: 0x0157, + 0x0052030C: 0x0158, + 0x0072030C: 0x0159, + 0x00530301: 0x015A, + 0x00730301: 0x015B, + 0x00530302: 0x015C, + 0x00730302: 0x015D, + 0x00530327: 0x015E, + 0x00730327: 0x015F, + 0x0053030C: 0x0160, + 0x0073030C: 0x0161, + 0x00540327: 0x0162, + 0x00740327: 0x0163, + 0x0054030C: 0x0164, + 0x0074030C: 0x0165, + 0x00550303: 0x0168, + 0x00750303: 0x0169, + 0x00550304: 0x016A, + 0x00750304: 0x016B, + 0x00550306: 0x016C, + 0x00750306: 0x016D, + 0x0055030A: 0x016E, + 0x0075030A: 0x016F, + 0x0055030B: 0x0170, + 0x0075030B: 0x0171, + 0x00550328: 0x0172, + 0x00750328: 0x0173, + 0x00570302: 0x0174, + 0x00770302: 0x0175, + 0x00590302: 0x0176, + 0x00790302: 0x0177, + 0x00590308: 0x0178, + 0x005A0301: 0x0179, + 0x007A0301: 0x017A, + 0x005A0307: 0x017B, + 0x007A0307: 0x017C, + 0x005A030C: 0x017D, + 0x007A030C: 0x017E, + 0x004F031B: 0x01A0, + 0x006F031B: 0x01A1, + 0x0055031B: 0x01AF, + 0x0075031B: 0x01B0, + 0x0041030C: 0x01CD, + 0x0061030C: 0x01CE, + 0x0049030C: 0x01CF, + 0x0069030C: 0x01D0, + 0x004F030C: 0x01D1, + 0x006F030C: 0x01D2, + 0x0055030C: 0x01D3, + 0x0075030C: 0x01D4, + 0x00DC0304: 0x01D5, + 0x00FC0304: 0x01D6, + 0x00DC0301: 0x01D7, + 0x00FC0301: 0x01D8, + 0x00DC030C: 0x01D9, + 0x00FC030C: 0x01DA, + 0x00DC0300: 0x01DB, + 0x00FC0300: 0x01DC, + 0x00C40304: 0x01DE, + 0x00E40304: 0x01DF, + 0x02260304: 0x01E0, + 0x02270304: 0x01E1, + 0x00C60304: 0x01E2, + 0x00E60304: 0x01E3, + 0x0047030C: 0x01E6, + 0x0067030C: 0x01E7, + 0x004B030C: 0x01E8, + 0x006B030C: 0x01E9, + 0x004F0328: 0x01EA, + 0x006F0328: 0x01EB, + 0x01EA0304: 0x01EC, + 0x01EB0304: 0x01ED, + 0x01B7030C: 0x01EE, + 0x0292030C: 0x01EF, + 0x006A030C: 0x01F0, + 0x00470301: 0x01F4, + 0x00670301: 0x01F5, + 0x004E0300: 0x01F8, + 0x006E0300: 0x01F9, + 0x00C50301: 0x01FA, + 0x00E50301: 0x01FB, + 0x00C60301: 0x01FC, + 0x00E60301: 0x01FD, + 0x00D80301: 0x01FE, + 0x00F80301: 0x01FF, + 0x0041030F: 0x0200, + 0x0061030F: 0x0201, + 0x00410311: 0x0202, + 0x00610311: 0x0203, + 0x0045030F: 0x0204, + 0x0065030F: 0x0205, + 0x00450311: 0x0206, + 0x00650311: 0x0207, + 0x0049030F: 0x0208, + 0x0069030F: 0x0209, + 0x00490311: 0x020A, + 0x00690311: 0x020B, + 0x004F030F: 0x020C, + 0x006F030F: 0x020D, + 0x004F0311: 0x020E, + 0x006F0311: 0x020F, + 0x0052030F: 0x0210, + 0x0072030F: 0x0211, + 0x00520311: 0x0212, + 0x00720311: 0x0213, + 0x0055030F: 0x0214, + 0x0075030F: 0x0215, + 0x00550311: 0x0216, + 0x00750311: 0x0217, + 0x00530326: 0x0218, + 0x00730326: 0x0219, + 0x00540326: 0x021A, + 0x00740326: 0x021B, + 0x0048030C: 0x021E, + 0x0068030C: 0x021F, + 0x00410307: 0x0226, + 0x00610307: 0x0227, + 0x00450327: 0x0228, + 0x00650327: 0x0229, + 0x00D60304: 0x022A, + 0x00F60304: 0x022B, + 0x00D50304: 0x022C, + 0x00F50304: 0x022D, + 0x004F0307: 0x022E, + 0x006F0307: 0x022F, + 0x022E0304: 0x0230, + 0x022F0304: 0x0231, + 0x00590304: 0x0232, + 0x00790304: 0x0233, + 0x00A80301: 0x0385, + 0x03910301: 0x0386, + 0x03950301: 0x0388, + 0x03970301: 0x0389, + 0x03990301: 0x038A, + 0x039F0301: 0x038C, + 0x03A50301: 0x038E, + 0x03A90301: 0x038F, + 0x03CA0301: 0x0390, + 0x03990308: 0x03AA, + 0x03A50308: 0x03AB, + 0x03B10301: 0x03AC, + 0x03B50301: 0x03AD, + 0x03B70301: 0x03AE, + 0x03B90301: 0x03AF, + 0x03CB0301: 0x03B0, + 0x03B90308: 0x03CA, + 0x03C50308: 0x03CB, + 0x03BF0301: 0x03CC, + 0x03C50301: 0x03CD, + 0x03C90301: 0x03CE, + 0x03D20301: 0x03D3, + 0x03D20308: 0x03D4, + 0x04150300: 0x0400, + 0x04150308: 0x0401, + 0x04130301: 0x0403, + 0x04060308: 0x0407, + 0x041A0301: 0x040C, + 0x04180300: 0x040D, + 0x04230306: 0x040E, + 0x04180306: 0x0419, + 0x04380306: 0x0439, + 0x04350300: 0x0450, + 0x04350308: 0x0451, + 0x04330301: 0x0453, + 0x04560308: 0x0457, + 0x043A0301: 0x045C, + 0x04380300: 0x045D, + 0x04430306: 0x045E, + 0x0474030F: 0x0476, + 0x0475030F: 0x0477, + 0x04160306: 0x04C1, + 0x04360306: 0x04C2, + 0x04100306: 0x04D0, + 0x04300306: 0x04D1, + 0x04100308: 0x04D2, + 0x04300308: 0x04D3, + 0x04150306: 0x04D6, + 0x04350306: 0x04D7, + 0x04D80308: 0x04DA, + 0x04D90308: 0x04DB, + 0x04160308: 0x04DC, + 0x04360308: 0x04DD, + 0x04170308: 0x04DE, + 0x04370308: 0x04DF, + 0x04180304: 0x04E2, + 0x04380304: 0x04E3, + 0x04180308: 0x04E4, + 0x04380308: 0x04E5, + 0x041E0308: 0x04E6, + 0x043E0308: 0x04E7, + 0x04E80308: 0x04EA, + 0x04E90308: 0x04EB, + 0x042D0308: 0x04EC, + 0x044D0308: 0x04ED, + 0x04230304: 0x04EE, + 0x04430304: 0x04EF, + 0x04230308: 0x04F0, + 0x04430308: 0x04F1, + 0x0423030B: 0x04F2, + 0x0443030B: 0x04F3, + 0x04270308: 0x04F4, + 0x04470308: 0x04F5, + 0x042B0308: 0x04F8, + 0x044B0308: 0x04F9, + 0x06270653: 0x0622, + 0x06270654: 0x0623, + 0x06480654: 0x0624, + 0x06270655: 0x0625, + 0x064A0654: 0x0626, + 0x06D50654: 0x06C0, + 0x06C10654: 0x06C2, + 0x06D20654: 0x06D3, + 0x0928093C: 0x0929, + 0x0930093C: 0x0931, + 0x0933093C: 0x0934, + 0x09C709BE: 0x09CB, + 0x09C709D7: 0x09CC, + 0x0B470B56: 0x0B48, + 0x0B470B3E: 0x0B4B, + 0x0B470B57: 0x0B4C, + 0x0B920BD7: 0x0B94, + 0x0BC60BBE: 0x0BCA, + 0x0BC70BBE: 0x0BCB, + 0x0BC60BD7: 0x0BCC, + 0x0C460C56: 0x0C48, + 0x0CBF0CD5: 0x0CC0, + 0x0CC60CD5: 0x0CC7, + 0x0CC60CD6: 0x0CC8, + 0x0CC60CC2: 0x0CCA, + 0x0CCA0CD5: 0x0CCB, + 0x0D460D3E: 0x0D4A, + 0x0D470D3E: 0x0D4B, + 0x0D460D57: 0x0D4C, + 0x0DD90DCA: 0x0DDA, + 0x0DD90DCF: 0x0DDC, + 0x0DDC0DCA: 0x0DDD, + 0x0DD90DDF: 0x0DDE, + 0x1025102E: 0x1026, + 0x1B051B35: 0x1B06, + 0x1B071B35: 0x1B08, + 0x1B091B35: 0x1B0A, + 0x1B0B1B35: 0x1B0C, + 0x1B0D1B35: 0x1B0E, + 0x1B111B35: 0x1B12, + 0x1B3A1B35: 0x1B3B, + 0x1B3C1B35: 0x1B3D, + 0x1B3E1B35: 0x1B40, + 0x1B3F1B35: 0x1B41, + 0x1B421B35: 0x1B43, + 0x00410325: 0x1E00, + 0x00610325: 0x1E01, + 0x00420307: 0x1E02, + 0x00620307: 0x1E03, + 0x00420323: 0x1E04, + 0x00620323: 0x1E05, + 0x00420331: 0x1E06, + 0x00620331: 0x1E07, + 0x00C70301: 0x1E08, + 0x00E70301: 0x1E09, + 0x00440307: 0x1E0A, + 0x00640307: 0x1E0B, + 0x00440323: 0x1E0C, + 0x00640323: 0x1E0D, + 0x00440331: 0x1E0E, + 0x00640331: 0x1E0F, + 0x00440327: 0x1E10, + 0x00640327: 0x1E11, + 0x0044032D: 0x1E12, + 0x0064032D: 0x1E13, + 0x01120300: 0x1E14, + 0x01130300: 0x1E15, + 0x01120301: 0x1E16, + 0x01130301: 0x1E17, + 0x0045032D: 0x1E18, + 0x0065032D: 0x1E19, + 0x00450330: 0x1E1A, + 0x00650330: 0x1E1B, + 0x02280306: 0x1E1C, + 0x02290306: 0x1E1D, + 0x00460307: 0x1E1E, + 0x00660307: 0x1E1F, + 0x00470304: 0x1E20, + 0x00670304: 0x1E21, + 0x00480307: 0x1E22, + 0x00680307: 0x1E23, + 0x00480323: 0x1E24, + 0x00680323: 0x1E25, + 0x00480308: 0x1E26, + 0x00680308: 0x1E27, + 0x00480327: 0x1E28, + 0x00680327: 0x1E29, + 0x0048032E: 0x1E2A, + 0x0068032E: 0x1E2B, + 0x00490330: 0x1E2C, + 0x00690330: 0x1E2D, + 0x00CF0301: 0x1E2E, + 0x00EF0301: 0x1E2F, + 0x004B0301: 0x1E30, + 0x006B0301: 0x1E31, + 0x004B0323: 0x1E32, + 0x006B0323: 0x1E33, + 0x004B0331: 0x1E34, + 0x006B0331: 0x1E35, + 0x004C0323: 0x1E36, + 0x006C0323: 0x1E37, + 0x1E360304: 0x1E38, + 0x1E370304: 0x1E39, + 0x004C0331: 0x1E3A, + 0x006C0331: 0x1E3B, + 0x004C032D: 0x1E3C, + 0x006C032D: 0x1E3D, + 0x004D0301: 0x1E3E, + 0x006D0301: 0x1E3F, + 0x004D0307: 0x1E40, + 0x006D0307: 0x1E41, + 0x004D0323: 0x1E42, + 0x006D0323: 0x1E43, + 0x004E0307: 0x1E44, + 0x006E0307: 0x1E45, + 0x004E0323: 0x1E46, + 0x006E0323: 0x1E47, + 0x004E0331: 0x1E48, + 0x006E0331: 0x1E49, + 0x004E032D: 0x1E4A, + 0x006E032D: 0x1E4B, + 0x00D50301: 0x1E4C, + 0x00F50301: 0x1E4D, + 0x00D50308: 0x1E4E, + 0x00F50308: 0x1E4F, + 0x014C0300: 0x1E50, + 0x014D0300: 0x1E51, + 0x014C0301: 0x1E52, + 0x014D0301: 0x1E53, + 0x00500301: 0x1E54, + 0x00700301: 0x1E55, + 0x00500307: 0x1E56, + 0x00700307: 0x1E57, + 0x00520307: 0x1E58, + 0x00720307: 0x1E59, + 0x00520323: 0x1E5A, + 0x00720323: 0x1E5B, + 0x1E5A0304: 0x1E5C, + 0x1E5B0304: 0x1E5D, + 0x00520331: 0x1E5E, + 0x00720331: 0x1E5F, + 0x00530307: 0x1E60, + 0x00730307: 0x1E61, + 0x00530323: 0x1E62, + 0x00730323: 0x1E63, + 0x015A0307: 0x1E64, + 0x015B0307: 0x1E65, + 0x01600307: 0x1E66, + 0x01610307: 0x1E67, + 0x1E620307: 0x1E68, + 0x1E630307: 0x1E69, + 0x00540307: 0x1E6A, + 0x00740307: 0x1E6B, + 0x00540323: 0x1E6C, + 0x00740323: 0x1E6D, + 0x00540331: 0x1E6E, + 0x00740331: 0x1E6F, + 0x0054032D: 0x1E70, + 0x0074032D: 0x1E71, + 0x00550324: 0x1E72, + 0x00750324: 0x1E73, + 0x00550330: 0x1E74, + 0x00750330: 0x1E75, + 0x0055032D: 0x1E76, + 0x0075032D: 0x1E77, + 0x01680301: 0x1E78, + 0x01690301: 0x1E79, + 0x016A0308: 0x1E7A, + 0x016B0308: 0x1E7B, + 0x00560303: 0x1E7C, + 0x00760303: 0x1E7D, + 0x00560323: 0x1E7E, + 0x00760323: 0x1E7F, + 0x00570300: 0x1E80, + 0x00770300: 0x1E81, + 0x00570301: 0x1E82, + 0x00770301: 0x1E83, + 0x00570308: 0x1E84, + 0x00770308: 0x1E85, + 0x00570307: 0x1E86, + 0x00770307: 0x1E87, + 0x00570323: 0x1E88, + 0x00770323: 0x1E89, + 0x00580307: 0x1E8A, + 0x00780307: 0x1E8B, + 0x00580308: 0x1E8C, + 0x00780308: 0x1E8D, + 0x00590307: 0x1E8E, + 0x00790307: 0x1E8F, + 0x005A0302: 0x1E90, + 0x007A0302: 0x1E91, + 0x005A0323: 0x1E92, + 0x007A0323: 0x1E93, + 0x005A0331: 0x1E94, + 0x007A0331: 0x1E95, + 0x00680331: 0x1E96, + 0x00740308: 0x1E97, + 0x0077030A: 0x1E98, + 0x0079030A: 0x1E99, + 0x017F0307: 0x1E9B, + 0x00410323: 0x1EA0, + 0x00610323: 0x1EA1, + 0x00410309: 0x1EA2, + 0x00610309: 0x1EA3, + 0x00C20301: 0x1EA4, + 0x00E20301: 0x1EA5, + 0x00C20300: 0x1EA6, + 0x00E20300: 0x1EA7, + 0x00C20309: 0x1EA8, + 0x00E20309: 0x1EA9, + 0x00C20303: 0x1EAA, + 0x00E20303: 0x1EAB, + 0x1EA00302: 0x1EAC, + 0x1EA10302: 0x1EAD, + 0x01020301: 0x1EAE, + 0x01030301: 0x1EAF, + 0x01020300: 0x1EB0, + 0x01030300: 0x1EB1, + 0x01020309: 0x1EB2, + 0x01030309: 0x1EB3, + 0x01020303: 0x1EB4, + 0x01030303: 0x1EB5, + 0x1EA00306: 0x1EB6, + 0x1EA10306: 0x1EB7, + 0x00450323: 0x1EB8, + 0x00650323: 0x1EB9, + 0x00450309: 0x1EBA, + 0x00650309: 0x1EBB, + 0x00450303: 0x1EBC, + 0x00650303: 0x1EBD, + 0x00CA0301: 0x1EBE, + 0x00EA0301: 0x1EBF, + 0x00CA0300: 0x1EC0, + 0x00EA0300: 0x1EC1, + 0x00CA0309: 0x1EC2, + 0x00EA0309: 0x1EC3, + 0x00CA0303: 0x1EC4, + 0x00EA0303: 0x1EC5, + 0x1EB80302: 0x1EC6, + 0x1EB90302: 0x1EC7, + 0x00490309: 0x1EC8, + 0x00690309: 0x1EC9, + 0x00490323: 0x1ECA, + 0x00690323: 0x1ECB, + 0x004F0323: 0x1ECC, + 0x006F0323: 0x1ECD, + 0x004F0309: 0x1ECE, + 0x006F0309: 0x1ECF, + 0x00D40301: 0x1ED0, + 0x00F40301: 0x1ED1, + 0x00D40300: 0x1ED2, + 0x00F40300: 0x1ED3, + 0x00D40309: 0x1ED4, + 0x00F40309: 0x1ED5, + 0x00D40303: 0x1ED6, + 0x00F40303: 0x1ED7, + 0x1ECC0302: 0x1ED8, + 0x1ECD0302: 0x1ED9, + 0x01A00301: 0x1EDA, + 0x01A10301: 0x1EDB, + 0x01A00300: 0x1EDC, + 0x01A10300: 0x1EDD, + 0x01A00309: 0x1EDE, + 0x01A10309: 0x1EDF, + 0x01A00303: 0x1EE0, + 0x01A10303: 0x1EE1, + 0x01A00323: 0x1EE2, + 0x01A10323: 0x1EE3, + 0x00550323: 0x1EE4, + 0x00750323: 0x1EE5, + 0x00550309: 0x1EE6, + 0x00750309: 0x1EE7, + 0x01AF0301: 0x1EE8, + 0x01B00301: 0x1EE9, + 0x01AF0300: 0x1EEA, + 0x01B00300: 0x1EEB, + 0x01AF0309: 0x1EEC, + 0x01B00309: 0x1EED, + 0x01AF0303: 0x1EEE, + 0x01B00303: 0x1EEF, + 0x01AF0323: 0x1EF0, + 0x01B00323: 0x1EF1, + 0x00590300: 0x1EF2, + 0x00790300: 0x1EF3, + 0x00590323: 0x1EF4, + 0x00790323: 0x1EF5, + 0x00590309: 0x1EF6, + 0x00790309: 0x1EF7, + 0x00590303: 0x1EF8, + 0x00790303: 0x1EF9, + 0x03B10313: 0x1F00, + 0x03B10314: 0x1F01, + 0x1F000300: 0x1F02, + 0x1F010300: 0x1F03, + 0x1F000301: 0x1F04, + 0x1F010301: 0x1F05, + 0x1F000342: 0x1F06, + 0x1F010342: 0x1F07, + 0x03910313: 0x1F08, + 0x03910314: 0x1F09, + 0x1F080300: 0x1F0A, + 0x1F090300: 0x1F0B, + 0x1F080301: 0x1F0C, + 0x1F090301: 0x1F0D, + 0x1F080342: 0x1F0E, + 0x1F090342: 0x1F0F, + 0x03B50313: 0x1F10, + 0x03B50314: 0x1F11, + 0x1F100300: 0x1F12, + 0x1F110300: 0x1F13, + 0x1F100301: 0x1F14, + 0x1F110301: 0x1F15, + 0x03950313: 0x1F18, + 0x03950314: 0x1F19, + 0x1F180300: 0x1F1A, + 0x1F190300: 0x1F1B, + 0x1F180301: 0x1F1C, + 0x1F190301: 0x1F1D, + 0x03B70313: 0x1F20, + 0x03B70314: 0x1F21, + 0x1F200300: 0x1F22, + 0x1F210300: 0x1F23, + 0x1F200301: 0x1F24, + 0x1F210301: 0x1F25, + 0x1F200342: 0x1F26, + 0x1F210342: 0x1F27, + 0x03970313: 0x1F28, + 0x03970314: 0x1F29, + 0x1F280300: 0x1F2A, + 0x1F290300: 0x1F2B, + 0x1F280301: 0x1F2C, + 0x1F290301: 0x1F2D, + 0x1F280342: 0x1F2E, + 0x1F290342: 0x1F2F, + 0x03B90313: 0x1F30, + 0x03B90314: 0x1F31, + 0x1F300300: 0x1F32, + 0x1F310300: 0x1F33, + 0x1F300301: 0x1F34, + 0x1F310301: 0x1F35, + 0x1F300342: 0x1F36, + 0x1F310342: 0x1F37, + 0x03990313: 0x1F38, + 0x03990314: 0x1F39, + 0x1F380300: 0x1F3A, + 0x1F390300: 0x1F3B, + 0x1F380301: 0x1F3C, + 0x1F390301: 0x1F3D, + 0x1F380342: 0x1F3E, + 0x1F390342: 0x1F3F, + 0x03BF0313: 0x1F40, + 0x03BF0314: 0x1F41, + 0x1F400300: 0x1F42, + 0x1F410300: 0x1F43, + 0x1F400301: 0x1F44, + 0x1F410301: 0x1F45, + 0x039F0313: 0x1F48, + 0x039F0314: 0x1F49, + 0x1F480300: 0x1F4A, + 0x1F490300: 0x1F4B, + 0x1F480301: 0x1F4C, + 0x1F490301: 0x1F4D, + 0x03C50313: 0x1F50, + 0x03C50314: 0x1F51, + 0x1F500300: 0x1F52, + 0x1F510300: 0x1F53, + 0x1F500301: 0x1F54, + 0x1F510301: 0x1F55, + 0x1F500342: 0x1F56, + 0x1F510342: 0x1F57, + 0x03A50314: 0x1F59, + 0x1F590300: 0x1F5B, + 0x1F590301: 0x1F5D, + 0x1F590342: 0x1F5F, + 0x03C90313: 0x1F60, + 0x03C90314: 0x1F61, + 0x1F600300: 0x1F62, + 0x1F610300: 0x1F63, + 0x1F600301: 0x1F64, + 0x1F610301: 0x1F65, + 0x1F600342: 0x1F66, + 0x1F610342: 0x1F67, + 0x03A90313: 0x1F68, + 0x03A90314: 0x1F69, + 0x1F680300: 0x1F6A, + 0x1F690300: 0x1F6B, + 0x1F680301: 0x1F6C, + 0x1F690301: 0x1F6D, + 0x1F680342: 0x1F6E, + 0x1F690342: 0x1F6F, + 0x03B10300: 0x1F70, + 0x03B50300: 0x1F72, + 0x03B70300: 0x1F74, + 0x03B90300: 0x1F76, + 0x03BF0300: 0x1F78, + 0x03C50300: 0x1F7A, + 0x03C90300: 0x1F7C, + 0x1F000345: 0x1F80, + 0x1F010345: 0x1F81, + 0x1F020345: 0x1F82, + 0x1F030345: 0x1F83, + 0x1F040345: 0x1F84, + 0x1F050345: 0x1F85, + 0x1F060345: 0x1F86, + 0x1F070345: 0x1F87, + 0x1F080345: 0x1F88, + 0x1F090345: 0x1F89, + 0x1F0A0345: 0x1F8A, + 0x1F0B0345: 0x1F8B, + 0x1F0C0345: 0x1F8C, + 0x1F0D0345: 0x1F8D, + 0x1F0E0345: 0x1F8E, + 0x1F0F0345: 0x1F8F, + 0x1F200345: 0x1F90, + 0x1F210345: 0x1F91, + 0x1F220345: 0x1F92, + 0x1F230345: 0x1F93, + 0x1F240345: 0x1F94, + 0x1F250345: 0x1F95, + 0x1F260345: 0x1F96, + 0x1F270345: 0x1F97, + 0x1F280345: 0x1F98, + 0x1F290345: 0x1F99, + 0x1F2A0345: 0x1F9A, + 0x1F2B0345: 0x1F9B, + 0x1F2C0345: 0x1F9C, + 0x1F2D0345: 0x1F9D, + 0x1F2E0345: 0x1F9E, + 0x1F2F0345: 0x1F9F, + 0x1F600345: 0x1FA0, + 0x1F610345: 0x1FA1, + 0x1F620345: 0x1FA2, + 0x1F630345: 0x1FA3, + 0x1F640345: 0x1FA4, + 0x1F650345: 0x1FA5, + 0x1F660345: 0x1FA6, + 0x1F670345: 0x1FA7, + 0x1F680345: 0x1FA8, + 0x1F690345: 0x1FA9, + 0x1F6A0345: 0x1FAA, + 0x1F6B0345: 0x1FAB, + 0x1F6C0345: 0x1FAC, + 0x1F6D0345: 0x1FAD, + 0x1F6E0345: 0x1FAE, + 0x1F6F0345: 0x1FAF, + 0x03B10306: 0x1FB0, + 0x03B10304: 0x1FB1, + 0x1F700345: 0x1FB2, + 0x03B10345: 0x1FB3, + 0x03AC0345: 0x1FB4, + 0x03B10342: 0x1FB6, + 0x1FB60345: 0x1FB7, + 0x03910306: 0x1FB8, + 0x03910304: 0x1FB9, + 0x03910300: 0x1FBA, + 0x03910345: 0x1FBC, + 0x00A80342: 0x1FC1, + 0x1F740345: 0x1FC2, + 0x03B70345: 0x1FC3, + 0x03AE0345: 0x1FC4, + 0x03B70342: 0x1FC6, + 0x1FC60345: 0x1FC7, + 0x03950300: 0x1FC8, + 0x03970300: 0x1FCA, + 0x03970345: 0x1FCC, + 0x1FBF0300: 0x1FCD, + 0x1FBF0301: 0x1FCE, + 0x1FBF0342: 0x1FCF, + 0x03B90306: 0x1FD0, + 0x03B90304: 0x1FD1, + 0x03CA0300: 0x1FD2, + 0x03B90342: 0x1FD6, + 0x03CA0342: 0x1FD7, + 0x03990306: 0x1FD8, + 0x03990304: 0x1FD9, + 0x03990300: 0x1FDA, + 0x1FFE0300: 0x1FDD, + 0x1FFE0301: 0x1FDE, + 0x1FFE0342: 0x1FDF, + 0x03C50306: 0x1FE0, + 0x03C50304: 0x1FE1, + 0x03CB0300: 0x1FE2, + 0x03C10313: 0x1FE4, + 0x03C10314: 0x1FE5, + 0x03C50342: 0x1FE6, + 0x03CB0342: 0x1FE7, + 0x03A50306: 0x1FE8, + 0x03A50304: 0x1FE9, + 0x03A50300: 0x1FEA, + 0x03A10314: 0x1FEC, + 0x00A80300: 0x1FED, + 0x1F7C0345: 0x1FF2, + 0x03C90345: 0x1FF3, + 0x03CE0345: 0x1FF4, + 0x03C90342: 0x1FF6, + 0x1FF60345: 0x1FF7, + 0x039F0300: 0x1FF8, + 0x03A90300: 0x1FFA, + 0x03A90345: 0x1FFC, + 0x21900338: 0x219A, + 0x21920338: 0x219B, + 0x21940338: 0x21AE, + 0x21D00338: 0x21CD, + 0x21D40338: 0x21CE, + 0x21D20338: 0x21CF, + 0x22030338: 0x2204, + 0x22080338: 0x2209, + 0x220B0338: 0x220C, + 0x22230338: 0x2224, + 0x22250338: 0x2226, + 0x223C0338: 0x2241, + 0x22430338: 0x2244, + 0x22450338: 0x2247, + 0x22480338: 0x2249, + 0x003D0338: 0x2260, + 0x22610338: 0x2262, + 0x224D0338: 0x226D, + 0x003C0338: 0x226E, + 0x003E0338: 0x226F, + 0x22640338: 0x2270, + 0x22650338: 0x2271, + 0x22720338: 0x2274, + 0x22730338: 0x2275, + 0x22760338: 0x2278, + 0x22770338: 0x2279, + 0x227A0338: 0x2280, + 0x227B0338: 0x2281, + 0x22820338: 0x2284, + 0x22830338: 0x2285, + 0x22860338: 0x2288, + 0x22870338: 0x2289, + 0x22A20338: 0x22AC, + 0x22A80338: 0x22AD, + 0x22A90338: 0x22AE, + 0x22AB0338: 0x22AF, + 0x227C0338: 0x22E0, + 0x227D0338: 0x22E1, + 0x22910338: 0x22E2, + 0x22920338: 0x22E3, + 0x22B20338: 0x22EA, + 0x22B30338: 0x22EB, + 0x22B40338: 0x22EC, + 0x22B50338: 0x22ED, + 0x304B3099: 0x304C, + 0x304D3099: 0x304E, + 0x304F3099: 0x3050, + 0x30513099: 0x3052, + 0x30533099: 0x3054, + 0x30553099: 0x3056, + 0x30573099: 0x3058, + 0x30593099: 0x305A, + 0x305B3099: 0x305C, + 0x305D3099: 0x305E, + 0x305F3099: 0x3060, + 0x30613099: 0x3062, + 0x30643099: 0x3065, + 0x30663099: 0x3067, + 0x30683099: 0x3069, + 0x306F3099: 0x3070, + 0x306F309A: 0x3071, + 0x30723099: 0x3073, + 0x3072309A: 0x3074, + 0x30753099: 0x3076, + 0x3075309A: 0x3077, + 0x30783099: 0x3079, + 0x3078309A: 0x307A, + 0x307B3099: 0x307C, + 0x307B309A: 0x307D, + 0x30463099: 0x3094, + 0x309D3099: 0x309E, + 0x30AB3099: 0x30AC, + 0x30AD3099: 0x30AE, + 0x30AF3099: 0x30B0, + 0x30B13099: 0x30B2, + 0x30B33099: 0x30B4, + 0x30B53099: 0x30B6, + 0x30B73099: 0x30B8, + 0x30B93099: 0x30BA, + 0x30BB3099: 0x30BC, + 0x30BD3099: 0x30BE, + 0x30BF3099: 0x30C0, + 0x30C13099: 0x30C2, + 0x30C43099: 0x30C5, + 0x30C63099: 0x30C7, + 0x30C83099: 0x30C9, + 0x30CF3099: 0x30D0, + 0x30CF309A: 0x30D1, + 0x30D23099: 0x30D3, + 0x30D2309A: 0x30D4, + 0x30D53099: 0x30D6, + 0x30D5309A: 0x30D7, + 0x30D83099: 0x30D9, + 0x30D8309A: 0x30DA, + 0x30DB3099: 0x30DC, + 0x30DB309A: 0x30DD, + 0x30A63099: 0x30F4, + 0x30EF3099: 0x30F7, + 0x30F03099: 0x30F8, + 0x30F13099: 0x30F9, + 0x30F23099: 0x30FA, + 0x30FD3099: 0x30FE, + 0x109910BA: 0x1109A, + 0x109B10BA: 0x1109C, + 0x10A510BA: 0x110AB, + 0x11311127: 0x1112E, + 0x11321127: 0x1112F, + 0x1347133E: 0x1134B, + 0x13471357: 0x1134C, + 0x14B914BA: 0x114BB, + 0x14B914B0: 0x114BC, + 0x14B914BD: 0x114BE, + 0x15B815AF: 0x115BA, + 0x15B915AF: 0x115BB, +} -const recompMapPacked = "" + - "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0 - "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1 - "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2 - "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3 - "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4 - "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5 - "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7 - "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8 - "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9 - "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA - "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB - "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC - "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD - "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE - "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF - "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1 - "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2 - "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3 - "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4 - "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5 - "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6 - "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9 - "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA - "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB - "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC - "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD - "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0 - "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1 - "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2 - "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3 - "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4 - "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5 - "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7 - "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8 - "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9 - "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA - "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB - "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC - "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED - "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE - "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF - "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1 - "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2 - "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3 - "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4 - "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5 - "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6 - "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9 - "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA - "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB - "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC - "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD - "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF - "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100 - "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101 - "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102 - "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103 - "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104 - "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105 - "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106 - "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107 - "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108 - "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109 - "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A - "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B - "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C - "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D - "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E - "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F - "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112 - "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113 - "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114 - "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115 - "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116 - "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117 - "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118 - "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119 - "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A - "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B - "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C - "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D - "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E - "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F - "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120 - "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121 - "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122 - "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123 - "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124 - "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125 - "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128 - "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129 - "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A - "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B - "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C - "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D - "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E - "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F - "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130 - "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134 - "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135 - "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136 - "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137 - "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139 - "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A - "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B - "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C - "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D - "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E - "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143 - "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144 - "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145 - "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146 - "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147 - "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148 - "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C - "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D - "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E - "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F - "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150 - "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151 - "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154 - "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155 - "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156 - "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157 - "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158 - "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159 - "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A - "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B - "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C - "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D - "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E - "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F - "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160 - "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161 - "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162 - "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163 - "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164 - "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165 - "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168 - "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169 - "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A - "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B - "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C - "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D - "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E - "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F - "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170 - "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171 - "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172 - "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173 - "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174 - "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175 - "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176 - "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177 - "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178 - "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179 - "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A - "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B - "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C - "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D - "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E - "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0 - "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1 - "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF - "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0 - "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD - "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE - "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF - "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0 - "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1 - "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2 - "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3 - "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4 - "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5 - "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6 - "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7 - "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8 - "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9 - "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA - "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB - "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC - "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE - "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF - "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0 - "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1 - "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2 - "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3 - "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6 - "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7 - "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8 - "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9 - "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA - "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB - "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC - "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED - "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE - "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF - "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0 - "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4 - "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5 - "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8 - "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9 - "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA - "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB - "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC - "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD - "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE - "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF - "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200 - "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201 - "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202 - "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203 - "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204 - "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205 - "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206 - "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207 - "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208 - "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209 - "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A - "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B - "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C - "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D - "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E - "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F - "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210 - "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211 - "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212 - "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213 - "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214 - "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215 - "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216 - "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217 - "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218 - "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219 - "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A - "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B - "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E - "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F - "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226 - "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227 - "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228 - "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229 - "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A - "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B - "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C - "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D - "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E - "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F - "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230 - "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231 - "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232 - "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233 - "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385 - "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386 - "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388 - "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389 - "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A - "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C - "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E - "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F - "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390 - "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA - "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB - "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC - "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD - "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE - "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF - "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0 - "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA - "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB - "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC - "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD - "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE - "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3 - "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4 - "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400 - "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401 - "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403 - "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407 - "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C - "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D - "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E - "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419 - "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439 - "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450 - "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451 - "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453 - "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457 - "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C - "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D - "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E - "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476 - "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477 - "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1 - "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2 - "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0 - "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1 - "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2 - "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3 - "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6 - "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7 - "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA - "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB - "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC - "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD - "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE - "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF - "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2 - "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3 - "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4 - "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5 - "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6 - "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7 - "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA - "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB - "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC - "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED - "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE - "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF - "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0 - "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1 - "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2 - "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3 - "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4 - "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5 - "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8 - "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9 - "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622 - "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623 - "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624 - "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625 - "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626 - "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0 - "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2 - "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3 - "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929 - "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931 - "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934 - "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB - "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC - "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48 - "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B - "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C - "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94 - "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA - "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB - "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC - "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48 - "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0 - "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7 - "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8 - "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA - "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB - "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A - "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B - "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C - "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA - "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC - "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD - "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE - "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026 - "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06 - "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08 - "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A - "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C - "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E - "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12 - "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B - "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D - "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40 - "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41 - "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43 - "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00 - "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01 - "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02 - "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03 - "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04 - "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05 - "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06 - "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07 - "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08 - "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09 - "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A - "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B - "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C - "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D - "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E - "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F - "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10 - "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11 - "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12 - "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13 - "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14 - "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15 - "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16 - "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17 - "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18 - "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19 - "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A - "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B - "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C - "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D - "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E - "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F - "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20 - "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21 - "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22 - "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23 - "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24 - "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25 - "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26 - "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27 - "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28 - "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29 - "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A - "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B - "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C - "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D - "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E - "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F - "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30 - "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31 - "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32 - "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33 - "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34 - "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35 - "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36 - "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37 - "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38 - "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39 - "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A - "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B - "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C - "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D - "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E - "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F - "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40 - "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41 - "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42 - "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43 - "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44 - "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45 - "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46 - "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47 - "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48 - "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49 - "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A - "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B - "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C - "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D - "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E - "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F - "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50 - "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51 - "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52 - "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53 - "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54 - "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55 - "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56 - "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57 - "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58 - "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59 - "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A - "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B - "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C - "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D - "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E - "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F - "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60 - "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61 - "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62 - "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63 - "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64 - "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65 - "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66 - "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67 - "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68 - "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69 - "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A - "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B - "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C - "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D - "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E - "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F - "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70 - "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71 - "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72 - "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73 - "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74 - "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75 - "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76 - "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77 - "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78 - "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79 - "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A - "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B - "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C - "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D - "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E - "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F - "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 - "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 - "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 - "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83 - "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84 - "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85 - "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86 - "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87 - "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88 - "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89 - "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A - "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B - "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C - "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D - "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E - "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F - "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90 - "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91 - "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92 - "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93 - "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94 - "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95 - "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96 - "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 - "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 - "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 - "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B - "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 - "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 - "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 - "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3 - "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4 - "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5 - "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6 - "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7 - "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8 - "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9 - "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA - "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB - "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC - "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD - "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE - "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF - "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0 - "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1 - "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2 - "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3 - "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4 - "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5 - "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6 - "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7 - "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8 - "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9 - "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA - "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB - "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC - "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD - "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE - "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF - "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0 - "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1 - "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2 - "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3 - "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4 - "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5 - "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6 - "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7 - "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8 - "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9 - "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA - "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB - "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC - "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD - "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE - "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF - "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0 - "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1 - "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2 - "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3 - "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4 - "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5 - "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6 - "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7 - "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8 - "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9 - "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA - "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB - "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC - "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD - "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE - "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF - "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0 - "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1 - "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2 - "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3 - "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4 - "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5 - "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6 - "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7 - "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8 - "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9 - "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA - "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB - "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC - "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED - "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE - "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF - "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0 - "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1 - "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2 - "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3 - "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4 - "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5 - "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6 - "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7 - "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8 - "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9 - "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00 - "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01 - "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02 - "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03 - "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04 - "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05 - "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06 - "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07 - "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08 - "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09 - "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A - "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B - "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C - "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D - "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E - "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F - "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10 - "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11 - "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12 - "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13 - "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14 - "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15 - "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18 - "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19 - "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A - "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B - "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C - "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D - "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20 - "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21 - "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22 - "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23 - "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24 - "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25 - "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26 - "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27 - "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28 - "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29 - "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A - "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B - "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C - "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D - "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E - "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F - "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30 - "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31 - "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32 - "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33 - "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34 - "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35 - "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36 - "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37 - "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38 - "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39 - "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A - "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B - "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C - "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D - "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E - "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F - "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40 - "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41 - "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42 - "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43 - "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44 - "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45 - "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48 - "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49 - "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A - "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B - "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C - "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D - "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50 - "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51 - "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52 - "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53 - "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54 - "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55 - "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56 - "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57 - "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59 - "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B - "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D - "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F - "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60 - "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61 - "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62 - "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63 - "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64 - "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65 - "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66 - "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67 - "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68 - "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69 - "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A - "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B - "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C - "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D - "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E - "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F - "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70 - "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72 - "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74 - "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76 - "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78 - "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A - "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C - "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80 - "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81 - "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82 - "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83 - "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84 - "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85 - "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86 - "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87 - "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88 - "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89 - "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A - "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B - "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C - "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D - "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E - "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F - "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90 - "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91 - "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92 - "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93 - "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94 - "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95 - "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96 - "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97 - "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98 - "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99 - "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A - "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B - "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C - "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D - "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E - "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F - "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0 - "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1 - "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2 - "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3 - "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4 - "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5 - "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6 - "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7 - "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8 - "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9 - "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA - "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB - "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC - "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD - "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE - "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF - "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0 - "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1 - "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2 - "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3 - "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4 - "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6 - "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7 - "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8 - "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9 - "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA - "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC - "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1 - "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2 - "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3 - "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4 - "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6 - "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7 - "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8 - "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA - "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC - "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD - "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE - "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF - "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0 - "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1 - "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2 - "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6 - "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7 - "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8 - "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9 - "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA - "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD - "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE - "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF - "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0 - "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1 - "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2 - "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4 - "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5 - "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6 - "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7 - "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8 - "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9 - "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA - "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC - "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED - "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2 - "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3 - "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4 - "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6 - "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7 - "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8 - "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA - "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC - "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A - "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B - "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE - "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD - "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE - "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF - "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204 - "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209 - "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C - "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224 - "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226 - "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241 - "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244 - "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247 - "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249 - "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260 - "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262 - "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D - "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E - "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F - "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270 - "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271 - "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274 - "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275 - "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278 - "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279 - "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280 - "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281 - "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284 - "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285 - "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288 - "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289 - "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC - "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD - "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE - "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF - "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0 - "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1 - "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2 - "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3 - "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA - "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB - "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC - "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED - "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C - "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E - "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050 - "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052 - "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054 - "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056 - "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058 - "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A - "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C - "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E - "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060 - "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062 - "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065 - "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067 - "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069 - "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070 - "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071 - "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073 - "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074 - "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076 - "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077 - "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079 - "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A - "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C - "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D - "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094 - "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E - "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC - "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE - "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0 - "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2 - "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4 - "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6 - "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8 - "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA - "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC - "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE - "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0 - "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2 - "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5 - "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7 - "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9 - "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0 - "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1 - "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3 - "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4 - "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6 - "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7 - "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9 - "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA - "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC - "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD - "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4 - "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7 - "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8 - "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9 - "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA - "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE - "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A - "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C - "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB - "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E - "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F - "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B - "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C - "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB - "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC - "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE - "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA - "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB - "" - // Total size of tables: 53KB (54006 bytes) +// Total size of tables: 53KB (54006 bytes) diff --git a/vendor/modules.txt b/vendor/modules.txt index de0e81817..8996c447e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,10 +1,10 @@ -# cloud.google.com/go v0.37.4 +# cloud.google.com/go v0.34.0 cloud.google.com/go/compute/metadata # github.com/cpuguy83/go-md2man v1.0.10 github.com/cpuguy83/go-md2man/md2man # github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew/spew -# github.com/evanphx/json-patch v4.1.0+incompatible +# github.com/evanphx/json-patch v4.2.0+incompatible github.com/evanphx/json-patch # github.com/fsnotify/fsnotify v1.4.7 github.com/fsnotify/fsnotify @@ -23,12 +23,13 @@ github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/timestamp # github.com/google/btree v1.0.0 github.com/google/btree -# github.com/google/go-cmp v0.2.0 +# github.com/google/go-cmp v0.3.0 github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp/internal/diff +github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/go-containerregistry v0.0.0-20190424210018-7d6d1d3cd63b +# github.com/google/go-containerregistry v0.0.0-20190503220729-1c6c7f61e8a5 github.com/google/go-containerregistry/pkg/name # github.com/google/gofuzz v1.0.0 github.com/google/gofuzz @@ -59,26 +60,29 @@ github.com/imdario/mergo github.com/inconshreveable/mousetrap # github.com/json-iterator/go v1.1.6 github.com/json-iterator/go -# github.com/knative/build v0.5.0 +# github.com/knative/build v0.6.0 github.com/knative/build/pkg/apis/build/v1alpha1 github.com/knative/build/pkg/apis/build -# github.com/knative/pkg v0.0.0-20190329155329-916205998db9 -github.com/knative/pkg/apis/duck/v1alpha1 +# github.com/knative/pkg v0.0.0-20190518173526-34792a92cec2 github.com/knative/pkg/apis -github.com/knative/pkg/apis/duck -github.com/knative/pkg/kmeta +github.com/knative/pkg/apis/duck/v1beta1 github.com/knative/pkg/kmp +github.com/knative/pkg/apis/duck +github.com/knative/pkg/apis/duck/v1alpha1 +github.com/knative/pkg/kmeta +github.com/knative/pkg/ptr github.com/knative/pkg/configmap -# github.com/knative/serving v0.5.2 +# github.com/knative/serving v0.6.0 github.com/knative/serving/pkg/apis/serving github.com/knative/serving/pkg/apis/serving/v1alpha1 github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1 github.com/knative/serving/pkg/apis/autoscaling -github.com/knative/serving/pkg/apis/config github.com/knative/serving/pkg/apis/networking github.com/knative/serving/pkg/apis/networking/v1alpha1 +github.com/knative/serving/pkg/apis/serving/v1beta1 github.com/knative/serving/pkg/client/clientset/versioned/scheme github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake +github.com/knative/serving/pkg/apis/config github.com/knative/serving/pkg/apis/autoscaling/v1alpha1 # github.com/knative/test-infra v0.0.0-20190517181617-d1bb39bbca6e github.com/knative/test-infra/scripts @@ -116,14 +120,14 @@ github.com/spf13/pflag github.com/spf13/viper # golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 golang.org/x/crypto/ssh/terminal -# golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 +# golang.org/x/net v0.0.0-20190514140710-3ec191127204 golang.org/x/net/http2 golang.org/x/net/http/httpguts golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/context/ctxhttp golang.org/x/net/context -# golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a +# golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 golang.org/x/oauth2 golang.org/x/oauth2/google golang.org/x/oauth2/internal @@ -132,7 +136,7 @@ golang.org/x/oauth2/jwt # golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 +# golang.org/x/text v0.3.0 golang.org/x/text/transform golang.org/x/text/unicode/norm golang.org/x/text/encoding/unicode @@ -163,7 +167,6 @@ gopkg.in/yaml.v2 # k8s.io/api v0.0.0-20190226173710-145d52631d00 k8s.io/api/core/v1 k8s.io/api/authentication/v1 -k8s.io/api/autoscaling/v1 k8s.io/api/admissionregistration/v1alpha1 k8s.io/api/admissionregistration/v1beta1 k8s.io/api/apps/v1 @@ -172,6 +175,7 @@ k8s.io/api/apps/v1beta2 k8s.io/api/authentication/v1beta1 k8s.io/api/authorization/v1 k8s.io/api/authorization/v1beta1 +k8s.io/api/autoscaling/v1 k8s.io/api/autoscaling/v2beta1 k8s.io/api/autoscaling/v2beta2 k8s.io/api/batch/v1 @@ -203,13 +207,13 @@ k8s.io/apimachinery/pkg/api/meta k8s.io/apimachinery/pkg/util/runtime k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/validation -k8s.io/apimachinery/pkg/apis/meta/v1/unstructured -k8s.io/apimachinery/pkg/util/intstr k8s.io/apimachinery/pkg/util/sets k8s.io/apimachinery/pkg/util/validation +k8s.io/apimachinery/pkg/apis/meta/v1/unstructured k8s.io/apimachinery/pkg/runtime/serializer k8s.io/apimachinery/pkg/types k8s.io/apimachinery/pkg/watch +k8s.io/apimachinery/pkg/util/intstr k8s.io/apimachinery/pkg/conversion k8s.io/apimachinery/pkg/fields k8s.io/apimachinery/pkg/labels @@ -272,14 +276,14 @@ k8s.io/client-go/tools/clientcmd/api/v1 k8s.io/client-go/tools/pager k8s.io/client-go/util/buffer k8s.io/client-go/util/retry -k8s.io/client-go/informers -k8s.io/client-go/informers/core/v1 -k8s.io/client-go/kubernetes k8s.io/client-go/pkg/apis/clientauthentication k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1 k8s.io/client-go/pkg/apis/clientauthentication/v1beta1 k8s.io/client-go/util/connrotation k8s.io/client-go/util/integer +k8s.io/client-go/informers +k8s.io/client-go/informers/core/v1 +k8s.io/client-go/kubernetes k8s.io/client-go/informers/admissionregistration k8s.io/client-go/informers/apps k8s.io/client-go/informers/autoscaling @@ -381,7 +385,7 @@ k8s.io/client-go/listers/settings/v1alpha1 k8s.io/client-go/listers/storage/v1 k8s.io/client-go/listers/storage/v1alpha1 k8s.io/client-go/listers/storage/v1beta1 -# k8s.io/kube-openapi v0.0.0-20190418160015-6b3d3b2d5666 +# k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 k8s.io/kube-openapi/pkg/util/proto # sigs.k8s.io/yaml v1.1.0 sigs.k8s.io/yaml