From 245428a225e995f5a26c7f76d284575129d3d664 Mon Sep 17 00:00:00 2001 From: shijieqin Date: Fri, 25 Mar 2022 12:16:49 +0800 Subject: [PATCH 01/41] Modify the compute logic for CPUs that cannot be reused, and NodeResourceManager will use both local and tsp data --- Dockerfile | 1 + cmd/crane-agent/app/agent.go | 6 +- cmd/crane-agent/app/options/option.go | 13 +- deploy/craned/deployment.yaml | 129 +++++- deploy/craned/service.yaml | 9 + docs/images/advanced_cpuset_manager.png | Bin 0 -> 60647 bytes .../20220228-advanced-cpuset-manger.md | 97 ++++ ...ctive-hpa-to-scaling-with-effectiveness.md | 4 +- examples/noderesource-tsp-template.yaml | 25 ++ go.mod | 110 ++++- pkg/agent/agent.go | 126 +++++- pkg/common/types.go | 1 + .../ehpa/hpa_replicas_controller.go | 2 +- pkg/ensurance/cm/advanced_cpu_manager.go | 365 +++++++++++++++ pkg/ensurance/cm/advanced_cpu_manager_test.go | 32 ++ pkg/ensurance/cm/advanced_policy_static.go | 171 +++++++ .../cm/advanced_policy_static_test.go | 74 +++ pkg/ensurance/cm/cpu_assignment.go | 203 +++++++++ pkg/ensurance/cm/cpu_assignment_test.go | 424 ++++++++++++++++++ pkg/ensurance/cm/policy.go | 21 + pkg/ensurance/cm/test/cpu_manager_state | 1 + pkg/ensurance/cm/util.go | 31 ++ .../collector/cadvisor/cadvisor_linux.go | 80 ++-- .../cadvisor/cadvisor_unsupported.go | 41 +- pkg/ensurance/collector/cadvisor/types.go | 12 + pkg/ensurance/collector/collector.go | 19 +- pkg/ensurance/collector/nodelocal/cpu.go | 70 ++- pkg/ensurance/collector/nodelocal/disk.go | 5 +- pkg/ensurance/collector/nodelocal/memory.go | 2 +- pkg/ensurance/collector/nodelocal/net.go | 3 +- .../collector/nodelocal/nodelocal.go | 27 +- pkg/ensurance/collector/types/types.go | 4 + pkg/ensurance/runtime/container.go | 20 +- pkg/ensurance/runtime/sandbox.go | 87 ++++ pkg/features/features.go | 4 + pkg/resource/node_resource_manager.go | 286 ++++++++---- pkg/resource/pod_resource_manger.go | 19 +- pkg/server/handler/clusters/cluster.go | 64 ++- pkg/server/router.go | 8 +- pkg/server/server.go | 6 +- pkg/server/service/cluster/cluster.go | 5 + pkg/server/store/cluster.go | 31 +- pkg/server/store/secret/cluster.go | 15 + pkg/utils/pod.go | 38 ++ pkg/utils/string.go | 17 +- 45 files changed, 2498 insertions(+), 210 deletions(-) create mode 100644 docs/images/advanced_cpuset_manager.png create mode 100644 docs/proposals/20220228-advanced-cpuset-manger.md create mode 100644 examples/noderesource-tsp-template.yaml create mode 100644 pkg/ensurance/cm/advanced_cpu_manager.go create mode 100644 pkg/ensurance/cm/advanced_cpu_manager_test.go create mode 100644 pkg/ensurance/cm/advanced_policy_static.go create mode 100644 pkg/ensurance/cm/advanced_policy_static_test.go create mode 100644 pkg/ensurance/cm/cpu_assignment.go create mode 100644 pkg/ensurance/cm/cpu_assignment_test.go create mode 100644 pkg/ensurance/cm/policy.go create mode 100644 pkg/ensurance/cm/test/cpu_manager_state create mode 100644 pkg/ensurance/cm/util.go create mode 100644 pkg/ensurance/collector/cadvisor/types.go create mode 100644 pkg/ensurance/runtime/sandbox.go diff --git a/Dockerfile b/Dockerfile index 0edfced5c..46a1ce05c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ COPY go.mod go.mod COPY go.sum go.sum # cache deps before building and copying source so that we don't need to re-download as much # and so that source changes don't invalidate our downloaded layer +RUN go env -w GOPROXY=https://goproxy.io,direct RUN go mod download # Copy the go source diff --git a/cmd/crane-agent/app/agent.go b/cmd/crane-agent/app/agent.go index 7d4ef09cb..6dd1c682d 100644 --- a/cmd/crane-agent/app/agent.go +++ b/cmd/crane-agent/app/agent.go @@ -99,8 +99,8 @@ func Run(ctx context.Context, opts *options.Options) error { actionInformer := craneInformerFactory.Ensurance().V1alpha1().AvoidanceActions() tspInformer := craneInformerFactory.Prediction().V1alpha1().TimeSeriesPredictions() - agent, err := agent.NewAgent(ctx, hostname, opts.RuntimeEndpoint, kubeClient, craneClient, - podInformer, nodeInformer, nepInformer, actionInformer, tspInformer, opts.Ifaces, healthCheck, opts.CollectInterval) + newAgent, err := agent.NewAgent(ctx, hostname, opts.RuntimeEndpoint, kubeClient, craneClient, + podInformer, nodeInformer, nepInformer, actionInformer, tspInformer, opts.NodeResourceOptions, opts.Ifaces, healthCheck, opts.CollectInterval) if err != nil { return err @@ -114,7 +114,7 @@ func Run(ctx context.Context, opts *options.Options) error { nodeInformerFactory.WaitForCacheSync(ctx.Done()) craneInformerFactory.WaitForCacheSync(ctx.Done()) - agent.Run(healthCheck, opts.EnableProfiling, opts.BindAddr) + newAgent.Run(healthCheck, opts.EnableProfiling, opts.BindAddr) return nil } diff --git a/cmd/crane-agent/app/options/option.go b/cmd/crane-agent/app/options/option.go index 5c11a3521..d657cf9c9 100644 --- a/cmd/crane-agent/app/options/option.go +++ b/cmd/crane-agent/app/options/option.go @@ -22,11 +22,20 @@ type Options struct { MaxInactivity time.Duration // Ifaces is the network devices to collect metric Ifaces []string + //NodeResourceOptions is the options of nodeResource + NodeResourceOptions NodeResourceOptions +} + +type NodeResourceOptions struct { + ReserveCpuPercentStr string + ReserveMemoryPercentStr string } // NewOptions builds an empty options. func NewOptions() *Options { - return &Options{} + return &Options{ + NodeResourceOptions: NodeResourceOptions{}, + } } // Complete completes all the required options. @@ -47,5 +56,7 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) { flags.StringVar(&o.BindAddr, "bind-address", "0.0.0.0:8081", "The address the agent binds to for metrics, health-check and pprof, default: 0.0.0.0:8081.") flags.DurationVar(&o.CollectInterval, "collect-interval", 10*time.Second, "Period for the state collector to collect metrics, default: 10s") flags.StringArrayVar(&o.Ifaces, "ifaces", []string{"eth0"}, "The network devices to collect metric, use comma to separated, default: eth0") + flags.StringVar(&o.NodeResourceOptions.ReserveCpuPercentStr, "reserve-cpu-percent", "", "reserve cpu percentage of node.") + flags.StringVar(&o.NodeResourceOptions.ReserveMemoryPercentStr, "reserve-memory-percent", "", "reserve memory percentage of node.") flags.DurationVar(&o.MaxInactivity, "max-inactivity", 5*time.Minute, "Maximum time from last recorded activity before automatic restart, default: 5min") } diff --git a/deploy/craned/deployment.yaml b/deploy/craned/deployment.yaml index 8fec48a0b..9d84ee387 100644 --- a/deploy/craned/deployment.yaml +++ b/deploy/craned/deployment.yaml @@ -52,6 +52,17 @@ spec: readOnly: true - name: config mountPath: /tmp/recommendation-config + readinessProbe: + httpGet: + path: /api/healthz + port: 8082 + scheme: HTTP + - image: docker.io/gocrane/dashboard:v0.2.0 + imagePullPolicy: IfNotPresent + name: dashboard + volumeMounts: + - mountPath: /etc/nginx/conf.d/ + name: nginx-conf volumes: - name: cert secret: @@ -60,6 +71,10 @@ spec: - name: config configMap: name: recommendation-config + - name: nginx-conf + configMap: + name: nginx-conf + --- apiVersion: v1 data: @@ -97,4 +112,116 @@ data: ehpa.fluctuation-threshold: "1.5" ehpa.min-cpu-target-utilization: "30" ehpa.max-cpu-target-utilization: "75" - ehpa.reference-hpa: "true" \ No newline at end of file + ehpa.reference-hpa: "true" + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-conf + namespace: crane-system +data: + nginx.conf: | + gzip_static on; + gzip on; + gzip_min_length 50000; + gzip_proxied expired no-cache no-store private auth; + gzip_types + application/atom+xml + application/geo+json + application/javascript + application/x-javascript + application/json + application/ld+json + application/manifest+json + application/rdf+xml + application/rss+xml + application/vnd.ms-fontobject + application/wasm + application/x-web-app-manifest+json + application/xhtml+xml + application/xml + font/eot + font/otf + font/ttf + image/bmp + image/svg+xml + text/cache-manifest + text/calendar + text/css + text/javascript + text/markdown + text/plain + text/xml + text/x-component + text/x-cross-domain-policy; + + upstream cluster { + server craned.crane-system:8082; + } + + upstream grafana { + server grafana.crane-system:8082; + } + + + server { + server_name _; + large_client_header_buffers 4 32k; + add_header Cache-Control "must-revalidate"; + add_header Cache-Control "max-age=300"; + add_header ETag "1.90.0-rc.0"; + listen 9090; + listen [::]:9090; + location / { + root /usr/share/nginx/html/; + include /etc/nginx/mime.types; + try_files $uri $uri/ /index.html; + + location /grafana { + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_pass http://grafana; + proxy_redirect off; + rewrite /grafana/(.*) /$1 break; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + location /api/v1/cluster { + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_pass http://cluster; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + location /api/v1/namespaces { + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_pass http://cluster; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + location /api { + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_pass http://cluster; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + } + } diff --git a/deploy/craned/service.yaml b/deploy/craned/service.yaml index 4020be4f3..cd26b1a73 100644 --- a/deploy/craned/service.yaml +++ b/deploy/craned/service.yaml @@ -9,5 +9,14 @@ spec: - port: 443 protocol: TCP targetPort: 9443 + name: craned + - port: 8082 + protocol: TCP + targetPort: 8082 + name: crane-server + - port: 9090 + protocol: TCP + targetPort: 9090 + name: dashboard-service selector: app: craned diff --git a/docs/images/advanced_cpuset_manager.png b/docs/images/advanced_cpuset_manager.png new file mode 100644 index 0000000000000000000000000000000000000000..60be3b964977210b9db9e153354204d481814ffa GIT binary patch literal 60647 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 B``!Qm literal 0 HcmV?d00001 diff --git a/docs/proposals/20220228-advanced-cpuset-manger.md b/docs/proposals/20220228-advanced-cpuset-manger.md new file mode 100644 index 000000000..a0578fb33 --- /dev/null +++ b/docs/proposals/20220228-advanced-cpuset-manger.md @@ -0,0 +1,97 @@ +--- +title: Advanced CPUSet Manager +authors: + - "@szy441687879" +reviewers: + - "@yan234280533" + - "@mfanjie" +creation-date: 2022-02-28 +last-updated: 2022-03-16 +status: provisional +--- + +# Advanced CPUSet Manager +- Static CPU manager is supported by kubelet, when a guaranteed Pod is running on a node, kubelet allocate specific cpu cores to the processes exclusively, which generally keeps the cpu utilization of the node low. +This proposal provides a new mechanism to manage cpusets, which allows sharing cpu cores with other processes while binds cpuset.It also allows to revise cpuset when pod is running and relaxes restrictions of binding cpus in kubelet. + +## Table of Contents + + + +- [Advanced CPUSet Manager](#advanced-cpuset-manager) + - [Table of Contents](#table-of-contents) + - [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals/Future Work](#non-goalsfuture-work) + - [Proposal](#proposal) + - [Relax restrictions of cpuset allocation](#relax-restrictions-of-cpuset-allocation) + - [Add new annotation to describe the requirement of cpuset contorl manger](#add-new-annotation-to-describe-the--requirement-of-cpuset-contorl-manger) + - [Advanced CPU Manager component](#advanced-cpu-manager-component) + - [User Stories](#user-stories) + - [Story 1](#story-1) + - [Story 2](#story-2) + - [Risks and Mitigations](#risks-and-mitigations) + + +## Motivation +Some latency-sensitive applications have lower lantency and cpu usage when running with specific cores, which results in fewer context switchs and higer cache affinity. +But kubelet will always exclude assigned cores in shared cores, which may waste resources.Offline and other online pods can running on the cores actually. In our experiment, for the most part, it is barely noticeable for performance of service. + +### Goals + +- Provide a new mechanism to manage cpuset bypass +- Provide a new cpuset manager method "shared" +- Allow revise cpuset when pod running +- Relax restrictions of binding cpus + + +### Non-Goals/Future Work + +- Solve the conflicts with kubelet static cpuset manager, you need to set kubelet cpuset manager to "none" +- Numa manager will support in future, CCX/CCD manager also be considered + +## Proposal +### Relax restrictions of cpuset allocation +Kubelet allocate cpus for containers should meet the conditions: + +1. requests and limits are specified for all the containers and they are equal + +2. the container's resource limit for the limit of CPU is an integer greater than or equal to one and equal to request request of CPU. + +In Crane, only need to meet condition No.2 +### Add new annotation to describe the requirement of cpuset contorl manger +```yaml +apiVersion: v1 +kind: Pod +metadata: + annotations: + qos.gocrane.io/cpu-manager: none/exclusive/share +``` +Provide three polices for cpuset manager: +- none: containers of this pod shares a set of cpus which not allocated to exclusive containers +- exclusive: containers of this pod monopolize the allocated CPUs , other containers not allowed to use. +- share: containers of this pod runs in theallocated CPUs , but other containers can also use. + +### Advanced CPU Manager component +
+ +- Crane-agent use podLister informs to sense the creation of pod. +- Crane-agent allocate cpus when pod is binded, and loop in cycle to addContainer(change cpuset) until the containers are created +- Update/Delete pod will handle in reconcile state. +- state.State referenced from kubelet and topology_cpu_assignment copied from kubelet + + +### User Stories + +- Users can update pod annotaion to control cpuset policy flexibly + +#### Story 1 + make pod from none to share without recreating pod +#### Story 2 + make pod from exclusive to share, so offline process can use these CPUs + +### Risks and Mitigations + +- kubelet cpu manger policy need to be set to none, otherwise will be conflicted with crane-agent +- if crane-agent can not allocate CPUs for pods, it will not refuse to start pod as kubelet + diff --git a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md index dabb93e36..36c537fcd 100644 --- a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md +++ b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md @@ -20,7 +20,7 @@ spec: name: php-apache minReplicas: 1 # MinReplicas is the lower limit replicas to the scale target which the autoscaler can scale down to. maxReplicas: 10 # MaxReplicas is the upper limit replicas to the scale target which the autoscaler can scale up to. - scaleStrategy: Auto # ScaleStrategy indicate the strategy to scaling target, value can be "Auto" and "Preview". + scaleStrategy: Auto # ScaleStrategy indicates the strategy to scaling target, value can be "Auto" and "Preview". # Metrics contains the specifications for which to use to calculate the desired replica count. metrics: - type: Resource @@ -45,7 +45,7 @@ spec: * spec.scaleTargetRef defines the reference to the workload that should be scaled. * spec.minReplicas is the lower limit replicas to the scale target which the autoscaler can scale down to. * spec.maxReplicas is the upper limit replicas to the scale target which the autoscaler can scale up to. -* spec.metrics indicate the strategy to scaling target, value can be "Auto" and "Preview". +* spec.scaleStrategy indicates the strategy to scaling target, value can be "Auto" and "Preview". * spec.metrics contains the specifications for which to use to calculate the desired replica count. Please refer to the details: * spec.prediction defines configurations for predict resources.If unspecified, defaults don't enable prediction. diff --git a/examples/noderesource-tsp-template.yaml b/examples/noderesource-tsp-template.yaml new file mode 100644 index 000000000..cf47619bd --- /dev/null +++ b/examples/noderesource-tsp-template.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +data: + spec: | + predictionMetrics: + - algorithm: + algorithmType: dsp + dsp: + estimators: + fft: + - highFrequencyThreshold: "0.05" + lowAmplitudeThreshold: "1.0" + marginFraction: "0.2" + maxNumOfSpectrumItems: 20 + minNumOfSpectrumItems: 10 + historyLength: 3d + sampleInterval: 60s + resourceIdentifier: cpu + type: ExpressionQuery + expressionQuery: + expression: 'node_cpu_cannot_be_reclaimed_seconds{node=~"({{nodename}})(:\\d+)?"}' + predictionWindowSeconds: 180 +kind: ConfigMap +metadata: + name: noderesource-tsp-template + namespace: default \ No newline at end of file diff --git a/go.mod b/go.mod index 3fe9cbc2f..096dc57da 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,115 @@ require ( k8s.io/kube-openapi v0.0.0-20210817084001-7fbd8d59e5b8 // indirect ) -require github.com/Microsoft/go-winio v0.5.1 // indirect +require ( + github.com/Microsoft/go-winio v0.5.1 // indirect + github.com/NYTimes/gziphandler v1.1.1 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bits-and-blooms/bitset v1.2.0 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect + github.com/checkpoint-restore/go-criu/v5 v5.0.0 // indirect + github.com/cilium/ebpf v0.6.2 // indirect + github.com/containerd/console v1.0.2 // indirect + github.com/containerd/containerd v1.4.4 // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/cyphar/filepath-securejoin v0.2.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/distribution v2.7.1+incompatible // indirect + github.com/docker/docker v20.10.2+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/emicklei/go-restful v2.15.0+incompatible // indirect + github.com/emicklei/go-restful-swagger12 v0.0.0-20201014110547-68ccff494617 // indirect + github.com/euank/go-kmsg-parser v2.0.0+incompatible // indirect + github.com/evanphx/json-patch v4.11.0+incompatible // indirect + github.com/felixge/httpsnoop v1.0.1 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-logr/logr v0.4.0 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.5 // indirect + github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-playground/locales v0.13.0 // indirect + github.com/go-playground/universal-translator v0.17.0 // indirect + github.com/go-playground/validator/v10 v10.4.1 // indirect + github.com/godbus/dbus/v5 v5.0.4 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect + github.com/gosimple/slug v1.1.1 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/karrick/godirwalk v1.16.1 // indirect + github.com/leodido/go-urn v1.2.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989 // indirect + github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect + github.com/moby/sys/mountinfo v0.4.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mrunalp/fileutils v0.5.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.0.1 // indirect + github.com/opencontainers/runc v1.0.2 // indirect + github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect + github.com/opencontainers/selinux v1.8.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be // indirect + github.com/seccomp/libseccomp-golang v0.9.1 // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + github.com/stretchr/objx v0.2.0 // indirect + github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect + github.com/tklauser/numcpus v0.3.0 // indirect + github.com/ugorji/go/codec v1.1.7 // indirect + github.com/vishvananda/netlink v1.1.0 // indirect + github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect + go.etcd.io/etcd/api/v3 v3.5.1 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.1 // indirect + go.etcd.io/etcd/client/v3 v3.5.0 // indirect + go.opentelemetry.io/contrib v0.20.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 // indirect + go.opentelemetry.io/otel v0.20.0 // indirect + go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect + go.opentelemetry.io/otel/metric v0.20.0 // indirect + go.opentelemetry.io/otel/sdk v0.20.0 // indirect + go.opentelemetry.io/otel/sdk/export/metric v0.20.0 // indirect + go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect + go.opentelemetry.io/otel/trace v0.20.0 // indirect + go.opentelemetry.io/proto/otlp v0.7.0 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.19.0 // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect + gopkg.in/warnings.v0 v0.1.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + k8s.io/apiextensions-apiserver v0.22.2 // indirect + k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect +) require ( cloud.google.com/go v0.84.0 // indirect diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 9dd56fed3..75078ea1a 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -2,11 +2,16 @@ package agent import ( "context" + "fmt" "net/http" + "strings" "time" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/apiserver/pkg/server/mux" "k8s.io/apiserver/pkg/server/routes" utilfeature "k8s.io/apiserver/pkg/util/feature" @@ -15,13 +20,19 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/component-base/metrics/legacyregistry" "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ensuranceapi "github.com/gocrane/api/ensurance/v1alpha1" craneclientset "github.com/gocrane/api/pkg/generated/clientset/versioned" "github.com/gocrane/api/pkg/generated/informers/externalversions/ensurance/v1alpha1" predictionv1 "github.com/gocrane/api/pkg/generated/informers/externalversions/prediction/v1alpha1" + v1alpha12 "github.com/gocrane/api/prediction/v1alpha1" + "github.com/gocrane/crane/cmd/crane-agent/app/options" "github.com/gocrane/crane/pkg/ensurance/analyzer" + "github.com/gocrane/crane/pkg/ensurance/cm" "github.com/gocrane/crane/pkg/ensurance/collector" + "github.com/gocrane/crane/pkg/ensurance/collector/cadvisor" "github.com/gocrane/crane/pkg/ensurance/executor" "github.com/gocrane/crane/pkg/ensurance/manager" "github.com/gocrane/crane/pkg/features" @@ -32,6 +43,7 @@ import ( type Agent struct { ctx context.Context name string + nodeName string kubeClient kubernetes.Interface craneClient craneclientset.Interface managers []manager.Manager @@ -46,39 +58,49 @@ func NewAgent(ctx context.Context, nepInformer v1alpha1.NodeQOSEnsurancePolicyInformer, actionInformer v1alpha1.AvoidanceActionInformer, tspInformer predictionv1.TimeSeriesPredictionInformer, + nodeResourceOptions options.NodeResourceOptions, ifaces []string, healthCheck *metrics.HealthCheck, CollectInterval time.Duration, ) (*Agent, error) { var managers []manager.Manager var noticeCh = make(chan executor.AvoidanceExecutor) + agent := &Agent{ + ctx: ctx, + name: getAgentName(nodeName), + nodeName: nodeName, + kubeClient: kubeClient, + craneClient: craneClient, + } utilruntime.Must(ensuranceapi.AddToScheme(scheme.Scheme)) - - stateCollector := collector.NewStateCollector(nodeName, nepInformer.Lister(), podInformer.Lister(), nodeInformer.Lister(), ifaces, healthCheck, CollectInterval) - managers = append(managers, stateCollector) + cadvisorManager := cadvisor.NewCadvisorManager() + exclusiveCPUSet := cm.DefaultExclusiveCPUSet + if craneCpuSetManager := utilfeature.DefaultFeatureGate.Enabled(features.CraneCpuSetManager); craneCpuSetManager { + cpuManager := cm.NewAdvancedCpuManager(podInformer, runtimeEndpoint, cadvisorManager) + exclusiveCPUSet = cpuManager.GetExclusiveCpu + managers = appendManagerIfNotNil(managers, cpuManager) + } + stateCollector := collector.NewStateCollector(nodeName, nepInformer.Lister(), podInformer.Lister(), nodeInformer.Lister(), ifaces, healthCheck, CollectInterval, exclusiveCPUSet, cadvisorManager) + managers = appendManagerIfNotNil(managers, stateCollector) analyzerManager := analyzer.NewAnormalyAnalyzer(kubeClient, nodeName, podInformer, nodeInformer, nepInformer, actionInformer, stateCollector.AnalyzerChann, noticeCh) - managers = append(managers, analyzerManager) + managers = appendManagerIfNotNil(managers, analyzerManager) avoidanceManager := executor.NewActionExecutor(kubeClient, nodeName, podInformer, nodeInformer, noticeCh, runtimeEndpoint) - managers = append(managers, avoidanceManager) + managers = appendManagerIfNotNil(managers, avoidanceManager) if nodeResource := utilfeature.DefaultFeatureGate.Enabled(features.CraneNodeResource); nodeResource { - nodeResourceManager := resource.NewNodeResourceManager(kubeClient, nodeName, podInformer, nodeInformer, tspInformer, runtimeEndpoint, stateCollector.NodeResourceChann) - managers = append(managers, nodeResourceManager) + nodeResourceManager := resource.NewNodeResourceManager(kubeClient, nodeName, nodeResourceOptions.ReserveCpuPercentStr, nodeResourceOptions.ReserveMemoryPercentStr, agent.CreateNodeResourceTsp(), nodeInformer, tspInformer, stateCollector.NodeResourceChann) + managers = appendManagerIfNotNil(managers, nodeResourceManager) } if podResource := utilfeature.DefaultFeatureGate.Enabled(features.CranePodResource); podResource { - podResourceManager := resource.NewPodResourceManager(kubeClient, nodeName, podInformer, runtimeEndpoint, stateCollector.PodResourceChann, stateCollector.GetCollectors()) - managers = append(managers, podResourceManager) + podResourceManager := resource.NewPodResourceManager(kubeClient, nodeName, podInformer, runtimeEndpoint, stateCollector.PodResourceChann, stateCollector.GetCadvisorManager()) + managers = appendManagerIfNotNil(managers, podResourceManager) } - return &Agent{ - ctx: ctx, - name: getAgentName(nodeName), - kubeClient: kubeClient, - craneClient: craneClient, - managers: managers, - }, nil + agent.managers = managers + + return agent, nil } func (a *Agent) Run(healthCheck *metrics.HealthCheck, enableProfiling bool, bindAddr string) { @@ -106,8 +128,78 @@ func (a *Agent) Run(healthCheck *metrics.HealthCheck, enableProfiling bool, bind }() <-a.ctx.Done() + + _ = a.DeleteNodeResourceTsp() } func getAgentName(nodeName string) string { - return nodeName + "_" + string(uuid.NewUUID()) + return nodeName + "." + string(uuid.NewUUID()) +} + +func (a *Agent) CreateNodeResourceTsp() string { + tsp, err := a.craneClient.PredictionV1alpha1().TimeSeriesPredictions(resource.TspNamespace).Get(context.TODO(), a.GenerateNodeResourceTspName(), metav1.GetOptions{}) + if err == nil { + klog.V(4).Infof("Found old tsp %s in namespace %s", a.GenerateNodeResourceTspName(), resource.TspNamespace) + err := a.DeleteNodeResourceTsp() + if err != nil { + klog.Exitf("Delete old tsp %s with error: %v", a.GenerateNodeResourceTspName(), err) + } + } + config, err := a.kubeClient.CoreV1().ConfigMaps(resource.TspNamespace).Get(context.TODO(), "noderesource-tsp-template", metav1.GetOptions{}) + + if err != nil { + klog.Exitf("Get noderesource tsp configmap noderesource-tsp-template with error: %v", err) + } + + if config == nil { + klog.Exitf("Can't get noderesource tsp configmap noderesource-tsp-template") + } + + spec := v1alpha12.TimeSeriesPredictionSpec{} + err = yaml.Unmarshal([]byte(strings.Replace(config.Data["spec"], "{{nodename}}", a.nodeName, -1)), &spec) + if err != nil { + klog.Exitf("Convert spec template error: %v", err) + } + + n, err := a.kubeClient.CoreV1().Nodes().Get(context.TODO(), a.nodeName, metav1.GetOptions{}) + if err != nil { + klog.Exitf("Get node error: %v", err) + } + + tsp = &v1alpha12.TimeSeriesPrediction{} + + tsp.Name = a.GenerateNodeResourceTspName() + tsp.Namespace = resource.TspNamespace + gvk, _ := apiutil.GVKForObject(n, scheme.Scheme) + spec.TargetRef = v1.ObjectReference{ + Kind: gvk.Kind, + APIVersion: gvk.GroupVersion().String(), + Name: a.nodeName, + } + tsp.Spec = spec + _ = controllerutil.SetControllerReference(n, tsp, scheme.Scheme) + _, err = a.craneClient.PredictionV1alpha1().TimeSeriesPredictions(tsp.Namespace).Create(context.TODO(), tsp, metav1.CreateOptions{}) + if err != nil { + klog.Exitf("Create noderesource tsp %s with error: %v", a.GenerateNodeResourceTspName(), err) + } + return a.GenerateNodeResourceTspName() +} + +func (a *Agent) DeleteNodeResourceTsp() error { + err := a.craneClient.PredictionV1alpha1().TimeSeriesPredictions(resource.TspNamespace).Delete(context.TODO(), a.GenerateNodeResourceTspName(), metav1.DeleteOptions{}) + if err != nil { + return err + } + return nil +} + +func (a *Agent) GenerateNodeResourceTspName() string { + return fmt.Sprintf("noderesource-%s", a.name) +} + +func appendManagerIfNotNil(managers []manager.Manager, m manager.Manager) []manager.Manager { + if m != nil { + return append(managers, m) + } + return managers } diff --git a/pkg/common/types.go b/pkg/common/types.go index 8e0e4af11..1fbc467d5 100644 --- a/pkg/common/types.go +++ b/pkg/common/types.go @@ -11,6 +11,7 @@ const ( LabelNamePodUid = "PodUid" LabelNameContainerName = "ContainerName" LabelNameContainerId = "ContainerId" + LabelNameHasExtRes = "HasExtRes" ) // TimeSeries is a stream of samples that belong to a metric with a set of labels diff --git a/pkg/controller/ehpa/hpa_replicas_controller.go b/pkg/controller/ehpa/hpa_replicas_controller.go index da7e5f735..ab1b4ed59 100644 --- a/pkg/controller/ehpa/hpa_replicas_controller.go +++ b/pkg/controller/ehpa/hpa_replicas_controller.go @@ -23,7 +23,7 @@ type HPAReplicasController struct { } func (c *HPAReplicasController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - klog.Infof("Got hpa %s", req.NamespacedName) + klog.V(8).Infof("Got hpa %s", req.NamespacedName) hpa := &autoscalingv2.HorizontalPodAutoscaler{} if err := c.Client.Get(ctx, req.NamespacedName, hpa); err != nil { diff --git a/pkg/ensurance/cm/advanced_cpu_manager.go b/pkg/ensurance/cm/advanced_cpu_manager.go new file mode 100644 index 000000000..c6911ae9a --- /dev/null +++ b/pkg/ensurance/cm/advanced_cpu_manager.go @@ -0,0 +1,365 @@ +package cm + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "strings" + "sync" + "time" + + "google.golang.org/grpc" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" + coreinformers "k8s.io/client-go/informers/core/v1" + corelisters "k8s.io/client-go/listers/core/v1" + "k8s.io/client-go/tools/cache" + pb "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" + "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/kubelet/cm/containermap" + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" + + "github.com/gocrane/crane/pkg/ensurance/collector/cadvisor" + cruntime "github.com/gocrane/crane/pkg/ensurance/runtime" +) + +const ( + // cpuManagerStateFileName is the file name where cpu manager stores its state + cpuManagerStateFileName = "cpu_manager_state" + craneCpusetPolicyName = "crane" + // stateFilePath holds the directory where the state file for checkpoints is held. + stateFilePath = "/rootvar/run/crane" + kubeletStateFilePath = "/kubelet/" + // cpusetReconcilePeriod is the duration between calls to reconcileState. + cpusetReconcilePeriod = 5 * time.Second + // intervalRetryAddContainer is the interval between try add container + intervalRetryAddContainer = 200 * time.Millisecond + // timeoutRetryAddContainer is the timeout for adding container + timeoutRetryAddContainer = 2 * time.Second +) + +var DefaultExclusiveCPUSet = func() cpuset.CPUSet { + return cpuset.NewCPUSet() +} + +type AdvancedCpuManager struct { + isStarted bool + + sync.RWMutex + policy Policy + + podLister corelisters.PodLister + podSynced cache.InformerSynced + + runtimeClient pb.RuntimeServiceClient + runtimeConn *grpc.ClientConn + + // reconcilePeriod is the duration between calls to reconcileState. + reconcilePeriod time.Duration + + // state allows pluggable CPU assignment policies while sharing a common + // representation of state for the system to inspect and reconcile. + state state.State + + // stateFileDirectory holds the directory where the state file for checkpoints is held. + stateFileDirectory string + + cadvisor.Manager +} + +func NewAdvancedCpuManager(podInformer coreinformers.PodInformer, runtimeEndpoint string, cadvisorManager cadvisor.Manager) *AdvancedCpuManager { + runtimeClient, runtimeConn, err := cruntime.GetRuntimeClient(runtimeEndpoint, true) + if err != nil { + klog.Errorf("GetRuntimeClient failed %s", err.Error()) + return nil + } + + m := &AdvancedCpuManager{ + podLister: podInformer.Lister(), + podSynced: podInformer.Informer().HasSynced, + runtimeClient: runtimeClient, + runtimeConn: runtimeConn, + reconcilePeriod: cpusetReconcilePeriod, + stateFileDirectory: stateFilePath, + Manager: cadvisorManager, + } + //pod add actions need to handle quickly, delete/update can handle in loop laterly + podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(new interface{}) { + pod := new.(*v1.Pod) + for _, container := range pod.Spec.Containers { + err := m.Allocate(pod, &container) + if err == nil { + _ = wait.PollImmediate(intervalRetryAddContainer, timeoutRetryAddContainer, + func() (bool, error) { + return m.AddContainer(pod, &container) == nil, nil + }) + } + } + }, + }) + return m +} + +func (m *AdvancedCpuManager) Name() string { + return "AdvancedCpuManager" +} + +func (m *AdvancedCpuManager) Run(stop <-chan struct{}) { + klog.Infof("Starting advanced cpu manager") + machineInfo, err := m.Manager.GetMachineInfo() + if err != nil { + klog.Errorf("GetMachineInfo failed %s", err.Error()) + return + } + topo, err := topology.Discover(machineInfo) + if err != nil { + klog.Errorf("Topology Discover failed %s", err.Error()) + return + } + klog.Infof("Node topology: %+v", topo) + m.policy, err = NewAdvancedStaticPolicy(topo) + if err != nil { + klog.Errorf("New static policy error: %v", err) + return + } + // Wait for the caches to be synced before starting workers + if !cache.WaitForNamedCacheSync("advanced-cpuset-manager", + stop, + m.podSynced, + ) { + return + } + + containerMap, err := buildContainerMapFromRuntime(m.runtimeClient) + if err != nil { + klog.Errorf("Failed to build ContainerMapFromRuntime: %v", err) + return + } + if p := m.loadKubeletPolicy(kubeletStateFilePath + cpuManagerStateFileName); p != "none" { + klog.Errorf("Can not read kubelet policy or is not none, %s", p) + return + } + stateImpl, err := state.NewCheckpointState(m.stateFileDirectory, cpuManagerStateFileName, craneCpusetPolicyName, containerMap) + if err != nil { + klog.Errorf("Could not initialize checkpoint manager: %v, please remove policy state file", err) + return + } + m.state = stateImpl + + err = m.policy.Start(m.state) + if err != nil { + klog.Errorf("[Advancedcpumanager] policy start error: %v", err) + return + } + + go wait.Until(func() { m.reconcileState() }, m.reconcilePeriod, stop) + m.isStarted = true +} + +func (m *AdvancedCpuManager) Allocate(p *v1.Pod, c *v1.Container) error { + // wait cpu manger start + _ = wait.PollImmediateUntil(100*time.Millisecond, func() (bool, error) { return m.isStarted, nil }, wait.NeverStop) + // Garbage collect any stranded resources before allocating CPUs, do not need to allocate + m.syncState(false) + + m.Lock() + defer m.Unlock() + + // Call down into the policy to assign this container CPUs if required. + err := m.policy.Allocate(m.state, p, c) + if err != nil { + klog.Errorf("[Advancedcpumanager] Allocate error: %v", err) + return err + } + return nil +} + +func (m *AdvancedCpuManager) AddContainer(p *v1.Pod, c *v1.Container) error { + containerID := GetContainerIdFromPod(p, c.Name) + cset, ok := m.state.GetCPUSet(string(p.UID), c.Name) + if !ok { + cset = m.getSharedCpu().Union(m.state.GetDefaultCPUSet()) + } + err := m.updateContainerCPUSet(containerID, cset) + if err != nil { + klog.Errorf("[Advancedcpumanager] AddContainer error: error updating CPUSet for container (pod: %s, container: %s, container id: %s, err: %v)", p.Name, c.Name, containerID, err) + return err + } + klog.V(5).Infof("[Advancedcpumanager] update container resources is skipped due to cpu set is empty") + return nil +} + +func (m *AdvancedCpuManager) reconcileState() { + m.syncState(true) + sharedCPUSet := m.getSharedCpu().Union(m.state.GetDefaultCPUSet()) + for _, pod := range m.activepods() { + for _, container := range pod.Spec.Containers { + containerID := GetContainerIdFromPod(pod, container.Name) + cset, ok := m.state.GetCPUSet(string(pod.UID), container.Name) + if !ok { + cset = sharedCPUSet + } + klog.Infof("[Advancedcpumanager] reconcileState: updating container (pod: %s, container: %s, container id: %s, cpuset: \"%v\")", + pod.Name, container.Name, containerID, cset) + err := m.updateContainerCPUSet(containerID, cset) + if err != nil { + klog.Errorf("[Advancedcpumanager] reconcileState: failed to update container (pod: %s, container: %s, container id: %s, cpuset: \"%v\", error: %v)", + pod.Name, container.Name, containerID, cset, err) + continue + } + } + } +} + +func (m *AdvancedCpuManager) syncState(doAllocate bool) { + // We grab the lock to ensure that no new containers will grab CPUs while + // executing the code below. Without this lock, its possible that we end up + // removing state that is newly added by an asynchronous call to + // AddContainer() during the execution of this code. + m.Lock() + defer m.Unlock() + assignments := m.state.GetCPUAssignments() + + // Build a list of (podUID, containerName) pairs for all need to be assigned containers in all active Pods. + toBeAssignedContainers := make(map[string]map[string]struct{}) + for _, pod := range m.activepods() { + toBeAssignedContainers[string(pod.UID)] = make(map[string]struct{}) + for _, container := range pod.Spec.Containers { + if m.policy.NeedAllocated(pod, &container) { + toBeAssignedContainers[string(pod.UID)][container.Name] = struct{}{} + if _, ok := assignments[string(pod.UID)][container.Name]; !ok && doAllocate { + err := m.policy.Allocate(m.state, pod, &container) + if err != nil { + klog.Errorf("[Advancedcpumanager] Allocate error: %v", err) + continue + } + } + } + } + } + + // Loop through the CPUManager state. Remove any state for containers not + // in the `toBeAssignedContainers` list built above. + for podUID := range assignments { + for containerName := range assignments[podUID] { + if _, ok := toBeAssignedContainers[podUID][containerName]; !ok { + klog.Errorf("[Advancedcpumanager] removeStaleState: removing (pod %s, container: %s)", podUID, containerName) + err := m.policyRemoveContainerByRef(podUID, containerName) + if err != nil { + klog.Errorf("[Advancedcpumanager] removeStaleState: failed to remove (pod %s, container %s), error: %v)", podUID, containerName, err) + } + } + } + } +} + +func (m *AdvancedCpuManager) policyRemoveContainerByRef(podUID string, containerName string) error { + err := m.policy.RemoveContainer(m.state, podUID, containerName) + return err +} + +func (m *AdvancedCpuManager) updateContainerCPUSet(containerID string, cpus cpuset.CPUSet) error { + return cruntime.UpdateContainerResources( + m.runtimeClient, + containerID, + cruntime.UpdateOptions{CpusetCpus: cpus.String()}, + ) +} + +func (m *AdvancedCpuManager) loadKubeletPolicy(fileName string) string { + data, err := ioutil.ReadFile(fileName) + if err != nil { + klog.Errorf("[Advancedcpumanager] loadKubeletPolicy: %v", err) + return "" + } + var cpumangerCheckpoint state.CPUManagerCheckpoint + err = json.Unmarshal(data, &cpumangerCheckpoint) + if err != nil { + klog.Errorf("[Advancedcpumanager] unmarshal KubeletPolicy: %v", err) + return "" + } + return cpumangerCheckpoint.PolicyName +} + +func (m *AdvancedCpuManager) getSharedCpu() cpuset.CPUSet { + sharedCPUSet := cpuset.NewCPUSet() + for _, pod := range m.activepods() { + for _, container := range pod.Spec.Containers { + if cset, ok := m.state.GetCPUSet(string(pod.UID), container.Name); ok { + if csp := GetPodCPUSetType(pod, &container); csp == CPUSetShare { + sharedCPUSet = sharedCPUSet.Union(cset) + } + } + } + } + return sharedCPUSet +} + +func (m *AdvancedCpuManager) GetExclusiveCpu() cpuset.CPUSet { + exclusiveCPUSet := cpuset.NewCPUSet() + for _, pod := range m.activepods() { + for _, container := range pod.Spec.Containers { + if cset, ok := m.state.GetCPUSet(string(pod.UID), container.Name); ok { + if csp := GetPodCPUSetType(pod, &container); csp == CPUSetExclusive { + exclusiveCPUSet = exclusiveCPUSet.Union(cset) + } + } + } + } + return exclusiveCPUSet +} + +func (m *AdvancedCpuManager) activepods() []*v1.Pod { + allPods, _ := m.podLister.List(labels.Everything()) + activePods := make([]*v1.Pod, 0, len(allPods)) + for _, pod := range allPods { + //todo judge terminating status + if pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded || + (pod.DeletionTimestamp != nil && IsPodNotRunning(pod.Status.ContainerStatuses)) { + continue + } + activePods = append(activePods, pod) + } + return activePods +} + +func buildContainerMapFromRuntime(runtimeClient pb.RuntimeServiceClient) (containermap.ContainerMap, error) { + podSandboxMap := make(map[string]string) + podSandboxList, _ := cruntime.ListPodSandboxes(runtimeClient, cruntime.ListOptions{}) + + for _, p := range podSandboxList { + podSandboxMap[p.Id] = p.Metadata.Uid + } + + containerMap := containermap.NewContainerMap() + containerList, _ := cruntime.ListContainers(runtimeClient, cruntime.ListOptions{}) + for _, c := range containerList { + if _, exists := podSandboxMap[c.PodSandboxId]; !exists { + return nil, fmt.Errorf("no PodsandBox found with Id '%s'", c.PodSandboxId) + } + containerMap.Add(podSandboxMap[c.PodSandboxId], c.Metadata.Name, c.Id) + } + + return containerMap, nil +} + +func GetContainerIdFromPod(pod *v1.Pod, name string) string { + if name == "" { + return "" + } + + for _, v := range pod.Status.ContainerStatuses { + if v.Name == name { + strList := strings.Split(v.ContainerID, "//") + if len(strList) > 0 { + return strList[len(strList)-1] + } + } + } + + return "" +} diff --git a/pkg/ensurance/cm/advanced_cpu_manager_test.go b/pkg/ensurance/cm/advanced_cpu_manager_test.go new file mode 100644 index 000000000..37d49ba4f --- /dev/null +++ b/pkg/ensurance/cm/advanced_cpu_manager_test.go @@ -0,0 +1,32 @@ +package cm + +import ( + "testing" +) + +func TestAdvancedCpuManager_loadKubeletPolicy(t *testing.T) { + tests := []struct { + name string + fileName string + want string + }{ + { + name: "file not exist", + fileName: "/not-exist", + want: "", + }, + { + name: "file get none", + fileName: "./test/" + cpuManagerStateFileName, + want: "none", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := &AdvancedCpuManager{} + if got := m.loadKubeletPolicy(tt.fileName); got != tt.want { + t.Errorf("AdvancedCpuManager.loadKubeletPolicy() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/ensurance/cm/advanced_policy_static.go b/pkg/ensurance/cm/advanced_policy_static.go new file mode 100644 index 000000000..dfb9b8d4b --- /dev/null +++ b/pkg/ensurance/cm/advanced_policy_static.go @@ -0,0 +1,171 @@ +package cm + +import ( + "fmt" + + v1 "k8s.io/api/core/v1" + "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" + "k8s.io/kubernetes/pkg/kubelet/util/format" +) + +// AdvancedPolicyStatic is the name of the advanced static policy +const AdvancedPolicyStatic policyName = "advanced-static" + +type advancedStaticPolicy struct { + // cpu socket topology + topology *topology.CPUTopology + // set of CPUs that is not available for exclusive assignment + reserved cpuset.CPUSet +} + +func NewAdvancedStaticPolicy(topology *topology.CPUTopology) (Policy, error) { + return &advancedStaticPolicy{ + topology: topology, + reserved: cpuset.MustParse("0"), + }, nil +} + +func (p *advancedStaticPolicy) Name() string { + return string(AdvancedPolicyStatic) +} + +func (p *advancedStaticPolicy) Start(s state.State) error { + if err := p.validateState(s); err != nil { + klog.Errorf("[Advancedcpumanager] advanced static policy invalid state: %v, please drain node and remove policy state file", err) + return err + } + return nil +} + +func (p *advancedStaticPolicy) validateState(s state.State) error { + tmpAssignments := s.GetCPUAssignments() + tmpDefaultCPUset := s.GetDefaultCPUSet() + + // Default cpuset cannot be empty when assignments exist + if tmpDefaultCPUset.IsEmpty() { + if len(tmpAssignments) != 0 { + return fmt.Errorf("default cpuset cannot be empty") + } + // state is empty initialize + allCPUs := p.topology.CPUDetails.CPUs() + s.SetDefaultCPUSet(allCPUs) + return nil + } + + // State has already been initialized from file (is not empty) + // 1. Check if the reserved cpuset is not part of default cpuset because: + // - kube/system reserved have changed (increased) - may lead to some containers not being able to start + // - user tampered with file + if !p.reserved.Intersection(tmpDefaultCPUset).Equals(p.reserved) { + return fmt.Errorf("not all reserved cpus: \"%s\" are present in defaultCpuSet: \"%s\"", + p.reserved.String(), tmpDefaultCPUset.String()) + } + + // 2. Check if state for static policy is consistent + for pod := range tmpAssignments { + for container, cset := range tmpAssignments[pod] { + // None of the cpu in DEFAULT cset should be in s.assignments + if !tmpDefaultCPUset.Intersection(cset).IsEmpty() { + return fmt.Errorf("pod: %s, container: %s cpuset: \"%s\" overlaps with default cpuset \"%s\"", + pod, container, cset.String(), tmpDefaultCPUset.String()) + } + } + } + + // 3. It's possible that the set of available CPUs has changed since + // the state was written. This can be due to for example + // offlining a CPU when kubelet is not running. If this happens, + // CPU manager will run into trouble when later it tries to + // assign non-existent CPUs to containers. Validate that the + // topology that was received during CPU manager startup matches with + // the set of CPUs stored in the state. + totalKnownCPUs := tmpDefaultCPUset.Clone() + tmpCPUSets := []cpuset.CPUSet{} + for pod := range tmpAssignments { + for _, cset := range tmpAssignments[pod] { + tmpCPUSets = append(tmpCPUSets, cset) + } + } + totalKnownCPUs = totalKnownCPUs.UnionAll(tmpCPUSets) + if !totalKnownCPUs.Equals(p.topology.CPUDetails.CPUs()) { + return fmt.Errorf("current set of available CPUs \"%s\" doesn't match with CPUs in state \"%s\"", + p.topology.CPUDetails.CPUs().String(), totalKnownCPUs.String()) + } + + return nil +} + +func (p *advancedStaticPolicy) Allocate(s state.State, pod *v1.Pod, container *v1.Container) error { + if numCPUs := p.guaranteedCPUs(pod, container); numCPUs != 0 { + klog.Infof("[Advancedcpumanager] advanced static policy: Allocate (pod: %s, container: %s)", format.Pod(pod), container.Name) + if _, ok := s.GetCPUSet(string(pod.UID), container.Name); ok { + klog.Infof("[Advancedcpumanager] advanced static policy: container already present in state, skipping (pod: %s, container: %s)", format.Pod(pod), container.Name) + return nil + } + + // Allocate CPUs according to the NUMA affinity contained in the hint. + cpuset, err := p.allocateCPUs(s, numCPUs) + if err != nil { + klog.Errorf("[Advancedcpumanager] unable to allocate %d CPUs (pod: %s, container: %s, error: %v)", numCPUs, format.Pod(pod), container.Name, err) + return err + } + s.SetCPUSet(string(pod.UID), container.Name, cpuset) + } + // container belongs in the shared pool (nothing to do; use default cpuset) + return nil +} + +func (p *advancedStaticPolicy) allocateCPUs(s state.State, numCPUs int) (cpuset.CPUSet, error) { + klog.Infof("[Advancedcpumanager] allocateCpus: (numCPUs: %d)", numCPUs) + + result := cpuset.NewCPUSet() + klog.Infof("[Advancedcpumanager] allocateCpu %+v", p.assignableCPUs(s)) + // Get any remaining CPUs from what's leftover after attempting to grab aligned ones. + remainingCPUs, err := takeByTopology(p.topology, p.assignableCPUs(s), numCPUs) + if err != nil { + return cpuset.NewCPUSet(), err + } + result = result.Union(remainingCPUs) + + // Remove allocated CPUs from the shared CPUSet. + s.SetDefaultCPUSet(s.GetDefaultCPUSet().Difference(result)) + + klog.Infof("[Advancedcpumanager] allocateCPUs: returning \"%v\"", result) + return result, nil +} + +// assignableCPUs returns the set of unassigned CPUs minus the reserved set. +func (p *advancedStaticPolicy) assignableCPUs(s state.State) cpuset.CPUSet { + return s.GetDefaultCPUSet().Difference(p.reserved) +} + +func (p *advancedStaticPolicy) RemoveContainer(s state.State, podUID string, containerName string) error { + klog.Infof("[Advancedcpumanager] static policy: RemoveContainer (pod: %s, container: %s)", podUID, containerName) + if toRelease, ok := s.GetCPUSet(podUID, containerName); ok { + s.Delete(podUID, containerName) + // Mutate the shared pool, adding released cpus. + s.SetDefaultCPUSet(s.GetDefaultCPUSet().Union(toRelease)) + } + return nil +} + +func (p *advancedStaticPolicy) NeedAllocated(pod *v1.Pod, container *v1.Container) bool { + return p.guaranteedCPUs(pod, container) > 0 +} + +func (p *advancedStaticPolicy) guaranteedCPUs(pod *v1.Pod, container *v1.Container) int { + cpuQuantity := container.Resources.Requests[v1.ResourceCPU] + if cpuQuantity.Value()*1000 != cpuQuantity.MilliValue() { + return 0 + } + if container.Resources.Requests[v1.ResourceCPU] != container.Resources.Limits[v1.ResourceCPU] { + return 0 + } + if csp := GetPodCPUSetType(pod, container); csp == CPUSetNone { + return 0 + } + return int(cpuQuantity.Value()) +} diff --git a/pkg/ensurance/cm/advanced_policy_static_test.go b/pkg/ensurance/cm/advanced_policy_static_test.go new file mode 100644 index 000000000..d6ab54514 --- /dev/null +++ b/pkg/ensurance/cm/advanced_policy_static_test.go @@ -0,0 +1,74 @@ +package cm + +import ( + "testing" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_advancedStaticPolicy_guaranteedCPUs(t *testing.T) { + type args struct { + pod *v1.Pod + container *v1.Container + } + tests := []struct { + name string + args args + want int + }{ + { + name: "pod guaranteedCPUs", + args: args{ + &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + CPUSetAnnotation: string(CPUSetShare), + }, + }, + }, + &v1.Container{ + Resources: v1.ResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("3"), + v1.ResourceMemory: resource.MustParse("1G"), + }, + Limits: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("3"), + v1.ResourceMemory: resource.MustParse("1G"), + }, + }, + }, + }, + want: 3, + }, + { + name: "pod guaranteedCPUs", + args: args{ + &v1.Pod{}, + &v1.Container{ + Resources: v1.ResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("3"), + v1.ResourceMemory: resource.MustParse("1G"), + }, + Limits: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("3"), + v1.ResourceMemory: resource.MustParse("1G"), + }, + }, + }, + }, + want: 0, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &advancedStaticPolicy{} + if got := p.guaranteedCPUs(tt.args.pod, tt.args.container); got != tt.want { + t.Errorf("advancedStaticPolicy.guaranteedCPUs() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/ensurance/cm/cpu_assignment.go b/pkg/ensurance/cm/cpu_assignment.go new file mode 100644 index 000000000..da0216fb0 --- /dev/null +++ b/pkg/ensurance/cm/cpu_assignment.go @@ -0,0 +1,203 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ +// copied from kubernetes/pkg/kubelet/cm/cpumanager/cpu_assignment.go +package cm + +import ( + "fmt" + "sort" + + "k8s.io/klog/v2" + + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" +) + +type cpuAccumulator struct { + topo *topology.CPUTopology + details topology.CPUDetails + numCPUsNeeded int + result cpuset.CPUSet +} + +func newCPUAccumulator(topo *topology.CPUTopology, availableCPUs cpuset.CPUSet, numCPUs int) *cpuAccumulator { + return &cpuAccumulator{ + topo: topo, + details: topo.CPUDetails.KeepOnly(availableCPUs), + numCPUsNeeded: numCPUs, + result: cpuset.NewCPUSet(), + } +} + +func (a *cpuAccumulator) take(cpus cpuset.CPUSet) { + a.result = a.result.Union(cpus) + a.details = a.details.KeepOnly(a.details.CPUs().Difference(a.result)) + a.numCPUsNeeded -= cpus.Size() +} + +// Returns true if the supplied socket is fully available in `topoDetails`. +func (a *cpuAccumulator) isSocketFree(socketID int) bool { + return a.details.CPUsInSockets(socketID).Size() == a.topo.CPUsPerSocket() +} + +// Returns true if the supplied core is fully available in `topoDetails`. +func (a *cpuAccumulator) isCoreFree(coreID int) bool { + return a.details.CPUsInCores(coreID).Size() == a.topo.CPUsPerCore() +} + +// Returns free socket IDs as a slice sorted by: +// - socket ID, ascending. +func (a *cpuAccumulator) freeSockets() []int { + return a.details.Sockets().Filter(a.isSocketFree).ToSlice() +} + +// Returns core IDs as a slice sorted by: +// - the number of whole available cores on the socket, ascending +// - socket ID, ascending +// - core ID, ascending +func (a *cpuAccumulator) freeCores() []int { + socketIDs := a.details.Sockets().ToSliceNoSort() + sort.Slice(socketIDs, + func(i, j int) bool { + iCores := a.details.CoresInSockets(socketIDs[i]).Filter(a.isCoreFree) + jCores := a.details.CoresInSockets(socketIDs[j]).Filter(a.isCoreFree) + return iCores.Size() < jCores.Size() || socketIDs[i] < socketIDs[j] + }) + + coreIDs := []int{} + for _, s := range socketIDs { + coreIDs = append(coreIDs, a.details.CoresInSockets(s).Filter(a.isCoreFree).ToSlice()...) + } + return coreIDs +} + +// Returns CPU IDs as a slice sorted by: +// - socket affinity with result +// - number of CPUs available on the same socket +// - number of CPUs available on the same core +// - socket ID. +// - core ID. +func (a *cpuAccumulator) freeCPUs() []int { + result := []int{} + cores := a.details.Cores().ToSlice() + + sort.Slice( + cores, + func(i, j int) bool { + iCore := cores[i] + jCore := cores[j] + + iCPUs := a.topo.CPUDetails.CPUsInCores(iCore).ToSlice() + jCPUs := a.topo.CPUDetails.CPUsInCores(jCore).ToSlice() + + iSocket := a.topo.CPUDetails[iCPUs[0]].SocketID + jSocket := a.topo.CPUDetails[jCPUs[0]].SocketID + + // Compute the number of CPUs in the result reside on the same socket + // as each core. + iSocketColoScore := a.topo.CPUDetails.CPUsInSockets(iSocket).Intersection(a.result).Size() + jSocketColoScore := a.topo.CPUDetails.CPUsInSockets(jSocket).Intersection(a.result).Size() + + // Compute the number of available CPUs available on the same socket + // as each core. + iSocketFreeScore := a.details.CPUsInSockets(iSocket).Size() + jSocketFreeScore := a.details.CPUsInSockets(jSocket).Size() + + // Compute the number of available CPUs on each core. + iCoreFreeScore := a.details.CPUsInCores(iCore).Size() + jCoreFreeScore := a.details.CPUsInCores(jCore).Size() + + return iSocketColoScore > jSocketColoScore || + iSocketFreeScore < jSocketFreeScore || + iCoreFreeScore < jCoreFreeScore || + iSocket < jSocket || + iCore < jCore + }) + + // For each core, append sorted CPU IDs to result. + for _, core := range cores { + result = append(result, a.details.CPUsInCores(core).ToSlice()...) + } + return result +} + +func (a *cpuAccumulator) needs(n int) bool { + return a.numCPUsNeeded >= n +} + +func (a *cpuAccumulator) isSatisfied() bool { + return a.numCPUsNeeded < 1 +} + +func (a *cpuAccumulator) isFailed() bool { + return a.numCPUsNeeded > a.details.CPUs().Size() +} + +func takeByTopology(topo *topology.CPUTopology, availableCPUs cpuset.CPUSet, numCPUs int) (cpuset.CPUSet, error) { + acc := newCPUAccumulator(topo, availableCPUs, numCPUs) + if acc.isSatisfied() { + return acc.result, nil + } + if acc.isFailed() { + return cpuset.NewCPUSet(), fmt.Errorf("not enough cpus available to satisfy request") + } + + // Algorithm: topology-aware best-fit + // 1. Acquire whole sockets, if available and the container requires at + // least a socket's-worth of CPUs. + if acc.needs(acc.topo.CPUsPerSocket()) { + for _, s := range acc.freeSockets() { + klog.V(4).Infof("[Advancedcpumanager] takeByTopology: claiming socket [%d]", s) + acc.take(acc.details.CPUsInSockets(s)) + if acc.isSatisfied() { + return acc.result, nil + } + if !acc.needs(acc.topo.CPUsPerSocket()) { + break + } + } + } + + // 2. Acquire whole cores, if available and the container requires at least + // a core's-worth of CPUs. + if acc.needs(acc.topo.CPUsPerCore()) { + for _, c := range acc.freeCores() { + klog.V(4).Infof("[Advancedcpumanager] takeByTopology: claiming core [%d]", c) + acc.take(acc.details.CPUsInCores(c)) + if acc.isSatisfied() { + return acc.result, nil + } + if !acc.needs(acc.topo.CPUsPerCore()) { + break + } + } + } + + // 3. Acquire single threads, preferring to fill partially-allocated cores + // on the same sockets as the whole cores we have already taken in this + // allocation. + for _, c := range acc.freeCPUs() { + klog.V(4).Infof("[Advancedcpumanager] takeByTopology: claiming CPU [%d]", c) + if acc.needs(1) { + acc.take(cpuset.NewCPUSet(c)) + } + if acc.isSatisfied() { + return acc.result, nil + } + } + + return cpuset.NewCPUSet(), fmt.Errorf("failed to allocate cpus") +} diff --git a/pkg/ensurance/cm/cpu_assignment_test.go b/pkg/ensurance/cm/cpu_assignment_test.go new file mode 100644 index 000000000..9965c46f5 --- /dev/null +++ b/pkg/ensurance/cm/cpu_assignment_test.go @@ -0,0 +1,424 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ +// copied from kubernetes/pkg/kubelet/cm/cpumanager/cpu_assignment_test.go + +package cm + +import ( + "reflect" + "testing" + + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" +) + +var ( + topoSingleSocketHT = &topology.CPUTopology{ + NumCPUs: 8, + NumSockets: 1, + NumCores: 4, + CPUDetails: map[int]topology.CPUInfo{ + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 2: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 3, SocketID: 0, NUMANodeID: 0}, + 4: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 5: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 6: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 7: {CoreID: 3, SocketID: 0, NUMANodeID: 0}, + }, + } + + topoDualSocketHT = &topology.CPUTopology{ + NumCPUs: 12, + NumSockets: 2, + NumCores: 6, + CPUDetails: map[int]topology.CPUInfo{ + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 1, SocketID: 1, NUMANodeID: 1}, + 2: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 4: {CoreID: 4, SocketID: 0, NUMANodeID: 0}, + 5: {CoreID: 5, SocketID: 1, NUMANodeID: 1}, + 6: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 7: {CoreID: 1, SocketID: 1, NUMANodeID: 1}, + 8: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 9: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 10: {CoreID: 4, SocketID: 0, NUMANodeID: 0}, + 11: {CoreID: 5, SocketID: 1, NUMANodeID: 1}, + }, + } +) + +func TestCPUAccumulatorFreeSockets(t *testing.T) { + testCases := []struct { + description string + topo *topology.CPUTopology + availableCPUs cpuset.CPUSet + expect []int + }{ + { + "single socket HT, 1 socket free", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + []int{0}, + }, + { + "single socket HT, 0 sockets free", + topoSingleSocketHT, + cpuset.NewCPUSet(1, 2, 3, 4, 5, 6, 7), + []int{}, + }, + { + "dual socket HT, 2 sockets free", + topoDualSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), + []int{0, 1}, + }, + { + "dual socket HT, 1 socket free", + topoDualSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11), + []int{1}, + }, + { + "dual socket HT, 0 sockets free", + topoDualSocketHT, + cpuset.NewCPUSet(0, 2, 3, 4, 5, 6, 7, 8, 9, 11), + []int{}, + }, + } + + for _, tc := range testCases { + acc := newCPUAccumulator(tc.topo, tc.availableCPUs, 0) + result := acc.freeSockets() + if !reflect.DeepEqual(result, tc.expect) { + t.Errorf("[%s] expected %v to equal %v", tc.description, result, tc.expect) + } + } +} + +func TestCPUAccumulatorFreeCores(t *testing.T) { + testCases := []struct { + description string + topo *topology.CPUTopology + availableCPUs cpuset.CPUSet + expect []int + }{ + { + "single socket HT, 4 cores free", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + []int{0, 1, 2, 3}, + }, + { + "single socket HT, 3 cores free", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 4, 5, 6), + []int{0, 1, 2}, + }, + { + "single socket HT, 3 cores free (1 partially consumed)", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6), + []int{0, 1, 2}, + }, + { + "single socket HT, 0 cores free", + topoSingleSocketHT, + cpuset.NewCPUSet(), + []int{}, + }, + { + "single socket HT, 0 cores free (4 partially consumed)", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3), + []int{}, + }, + { + "dual socket HT, 6 cores free", + topoDualSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), + []int{0, 2, 4, 1, 3, 5}, + }, + { + "dual socket HT, 5 cores free (1 consumed from socket 0)", + topoDualSocketHT, + cpuset.NewCPUSet(2, 1, 3, 4, 5, 7, 8, 9, 10, 11), + []int{2, 4, 1, 3, 5}, + }, + { + "dual socket HT, 4 cores free (1 consumed from each socket)", + topoDualSocketHT, + cpuset.NewCPUSet(2, 3, 4, 5, 8, 9, 10, 11), + []int{2, 4, 3, 5}, + }, + } + + for _, tc := range testCases { + acc := newCPUAccumulator(tc.topo, tc.availableCPUs, 0) + result := acc.freeCores() + if !reflect.DeepEqual(result, tc.expect) { + t.Errorf("[%s] expected %v to equal %v", tc.description, result, tc.expect) + } + } +} + +func TestCPUAccumulatorFreeCPUs(t *testing.T) { + testCases := []struct { + description string + topo *topology.CPUTopology + availableCPUs cpuset.CPUSet + expect []int + }{ + { + "single socket HT, 8 cpus free", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + []int{0, 4, 1, 5, 2, 6, 3, 7}, + }, + { + "single socket HT, 5 cpus free", + topoSingleSocketHT, + cpuset.NewCPUSet(3, 4, 5, 6, 7), + []int{4, 5, 6, 3, 7}, + }, + { + "dual socket HT, 12 cpus free", + topoDualSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), + []int{0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11}, + }, + { + "dual socket HT, 11 cpus free", + topoDualSocketHT, + cpuset.NewCPUSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), + []int{6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11}, + }, + { + "dual socket HT, 10 cpus free", + topoDualSocketHT, + cpuset.NewCPUSet(1, 2, 3, 4, 5, 7, 8, 9, 10, 11), + []int{2, 8, 4, 10, 1, 7, 3, 9, 5, 11}, + }, + } + + for _, tc := range testCases { + acc := newCPUAccumulator(tc.topo, tc.availableCPUs, 0) + result := acc.freeCPUs() + if !reflect.DeepEqual(result, tc.expect) { + t.Errorf("[%s] expected %v to equal %v", tc.description, result, tc.expect) + } + } +} + +func TestCPUAccumulatorTake(t *testing.T) { + testCases := []struct { + description string + topo *topology.CPUTopology + availableCPUs cpuset.CPUSet + takeCPUs []cpuset.CPUSet + numCPUs int + expectSatisfied bool + expectFailed bool + }{ + { + "take 0 cpus from a single socket HT, require 1", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + []cpuset.CPUSet{cpuset.NewCPUSet()}, + 1, + false, + false, + }, + { + "take 0 cpus from a single socket HT, require 1, none available", + topoSingleSocketHT, + cpuset.NewCPUSet(), + []cpuset.CPUSet{cpuset.NewCPUSet()}, + 1, + false, + true, + }, + { + "take 1 cpu from a single socket HT, require 1", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + []cpuset.CPUSet{cpuset.NewCPUSet(0)}, + 1, + true, + false, + }, + { + "take 1 cpu from a single socket HT, require 2", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + []cpuset.CPUSet{cpuset.NewCPUSet(0)}, + 2, + false, + false, + }, + { + "take 2 cpu from a single socket HT, require 4, expect failed", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2), + []cpuset.CPUSet{cpuset.NewCPUSet(0), cpuset.NewCPUSet(1)}, + 4, + false, + true, + }, + { + "take all cpus one at a time from a single socket HT, require 8", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + []cpuset.CPUSet{ + cpuset.NewCPUSet(0), + cpuset.NewCPUSet(1), + cpuset.NewCPUSet(2), + cpuset.NewCPUSet(3), + cpuset.NewCPUSet(4), + cpuset.NewCPUSet(5), + cpuset.NewCPUSet(6), + cpuset.NewCPUSet(7), + }, + 8, + true, + false, + }, + } + + for _, tc := range testCases { + acc := newCPUAccumulator(tc.topo, tc.availableCPUs, tc.numCPUs) + totalTaken := 0 + for _, cpus := range tc.takeCPUs { + acc.take(cpus) + totalTaken += cpus.Size() + } + if tc.expectSatisfied != acc.isSatisfied() { + t.Errorf("[%s] expected acc.isSatisfied() to be %t", tc.description, tc.expectSatisfied) + } + if tc.expectFailed != acc.isFailed() { + t.Errorf("[%s] expected acc.isFailed() to be %t", tc.description, tc.expectFailed) + } + for _, cpus := range tc.takeCPUs { + availableCPUs := acc.details.CPUs() + if cpus.Intersection(availableCPUs).Size() > 0 { + t.Errorf("[%s] expected intersection of taken cpus [%s] and acc.details.CPUs() [%s] to be empty", tc.description, cpus, availableCPUs) + } + if !cpus.IsSubsetOf(acc.result) { + t.Errorf("[%s] expected [%s] to be a subset of acc.result [%s]", tc.description, cpus, acc.result) + } + } + expNumCPUsNeeded := tc.numCPUs - totalTaken + if acc.numCPUsNeeded != expNumCPUsNeeded { + t.Errorf("[%s] expected acc.numCPUsNeeded to be %d (got %d)", tc.description, expNumCPUsNeeded, acc.numCPUsNeeded) + } + } +} + +func TestTakeByTopology(t *testing.T) { + testCases := []struct { + description string + topo *topology.CPUTopology + availableCPUs cpuset.CPUSet + numCPUs int + expErr string + expResult cpuset.CPUSet + }{ + { + "take more cpus than are available from single socket with HT", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 2, 4, 6), + 5, + "not enough cpus available to satisfy request", + cpuset.NewCPUSet(), + }, + { + "take zero cpus from single socket with HT", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + 0, + "", + cpuset.NewCPUSet(), + }, + { + "take one cpu from single socket with HT", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + 1, + "", + cpuset.NewCPUSet(0), + }, + { + "take one cpu from single socket with HT, some cpus are taken", + topoSingleSocketHT, + cpuset.NewCPUSet(1, 3, 5, 6, 7), + 1, + "", + cpuset.NewCPUSet(6), + }, + { + "take two cpus from single socket with HT", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + 2, + "", + cpuset.NewCPUSet(0, 4), + }, + { + "take all cpus from single socket with HT", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + 8, + "", + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + }, + { + "take two cpus from single socket with HT, only one core totally free", + topoSingleSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 6), + 2, + "", + cpuset.NewCPUSet(2, 6), + }, + { + "take one cpu from dual socket with HT - core from Socket 0", + topoDualSocketHT, + cpuset.NewCPUSet(1, 2, 3, 4, 5, 7, 8, 9, 10, 11), + 1, + "", + cpuset.NewCPUSet(2), + }, + { + "take a socket of cpus from dual socket with HT", + topoDualSocketHT, + cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), + 6, + "", + cpuset.NewCPUSet(0, 2, 4, 6, 8, 10), + }, + } + + for _, tc := range testCases { + result, err := takeByTopology(tc.topo, tc.availableCPUs, tc.numCPUs) + if tc.expErr != "" && err.Error() != tc.expErr { + t.Errorf("expected error to be [%v] but it was [%v] in test \"%s\"", tc.expErr, err, tc.description) + } + if !result.Equals(tc.expResult) { + t.Errorf("expected result [%s] to equal [%s] in test \"%s\"", result, tc.expResult, tc.description) + } + } +} diff --git a/pkg/ensurance/cm/policy.go b/pkg/ensurance/cm/policy.go new file mode 100644 index 000000000..639f07534 --- /dev/null +++ b/pkg/ensurance/cm/policy.go @@ -0,0 +1,21 @@ +package cm + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" +) + +type policyName string + +// Policy implements logic for pod container to CPU assignment. +type Policy interface { + Name() string + // Start is only called once to start policy + Start(s state.State) error + // Allocate call is idempotent to allocate cpus for containers + Allocate(s state.State, pod *v1.Pod, container *v1.Container) error + // RemoveContainer call is idempotent to reclaim cpus + RemoveContainer(s state.State, podUID string, containerName string) error + // NeedAllocated is called to judge if container needs to allocate cpu + NeedAllocated(pod *v1.Pod, container *v1.Container) bool +} diff --git a/pkg/ensurance/cm/test/cpu_manager_state b/pkg/ensurance/cm/test/cpu_manager_state new file mode 100644 index 000000000..bb91085a9 --- /dev/null +++ b/pkg/ensurance/cm/test/cpu_manager_state @@ -0,0 +1 @@ +{"policyName":"none","defaultCpuSet":"","checksum":3242152201} \ No newline at end of file diff --git a/pkg/ensurance/cm/util.go b/pkg/ensurance/cm/util.go new file mode 100644 index 000000000..02abcea08 --- /dev/null +++ b/pkg/ensurance/cm/util.go @@ -0,0 +1,31 @@ +package cm + +import v1 "k8s.io/api/core/v1" + +const CPUSetAnnotation string = "qos.gocrane.io/cpu-manager" + +// CPUSetPolicy the type for cpuset +type CPUSetPolicy string + +const ( + CPUSetNone CPUSetPolicy = "none" + CPUSetExclusive CPUSetPolicy = "exclusive" + CPUSetShare CPUSetPolicy = "share" +) + +func GetPodCPUSetType(pod *v1.Pod, _ *v1.Container) CPUSetPolicy { + csp := CPUSetPolicy(pod.GetAnnotations()[CPUSetAnnotation]) + if csp == "" { + return CPUSetNone + } + return csp +} + +func IsPodNotRunning(statuses []v1.ContainerStatus) bool { + for _, status := range statuses { + if status.State.Terminated == nil && status.State.Waiting == nil { + return false + } + } + return true +} diff --git a/pkg/ensurance/collector/cadvisor/cadvisor_linux.go b/pkg/ensurance/collector/cadvisor/cadvisor_linux.go index e1e895c9f..4caf2c042 100644 --- a/pkg/ensurance/collector/cadvisor/cadvisor_linux.go +++ b/pkg/ensurance/collector/cadvisor/cadvisor_linux.go @@ -5,7 +5,7 @@ package cadvisor import ( "net/http" - "strings" + "strconv" "time" cmemory "github.com/google/cadvisor/cache/memory" @@ -39,14 +39,27 @@ type ContainerState struct { //CadvisorCollector is the collector to collect container state type CadvisorCollector struct { - Manager cmanager.Manager + Manager Manager podLister corelisters.PodLister latestContainersStates map[string]ContainerState } -func NewCadvisor(podLister corelisters.PodLister) *CadvisorCollector { +type CadvisorManager struct { + cmanager.Manager +} + +var _ Manager = new(CadvisorManager) + +func NewCadvisorCollector(podLister corelisters.PodLister, manager Manager) *CadvisorCollector { + c := CadvisorCollector{ + Manager: manager, + podLister: podLister, + } + return &c +} +func NewCadvisorManager() Manager { var includedMetrics = cadvisorcontainer.MetricSet{ cadvisorcontainer.CpuUsageMetrics: struct{}{}, cadvisorcontainer.ProcessSchedulerMetrics: struct{}{}, @@ -64,28 +77,18 @@ func NewCadvisor(podLister corelisters.PodLister) *CadvisorCollector { return nil } - c := CadvisorCollector{ - Manager: m, - podLister: podLister, - } - - if err := c.Manager.Start(); err != nil { + if err := m.Start(); err != nil { klog.Errorf("Failed to start cadvisor manager: %v", err) return nil } - return &c + return &CadvisorManager{ + m, + } } // Stop cadvisor and clear existing factory func (c *CadvisorCollector) Stop() error { - if err := c.Manager.Stop(); err != nil { - return err - } - - // clear existing factory - cadvisorcontainer.ClearContainerHandlerFactories() - return nil } @@ -101,6 +104,7 @@ func (c *CadvisorCollector) Collect() (map[string][]common.TimeSeries, error) { klog.Errorf("Failed to list all pods: %v", err) return nil, err } + var extResCpuUse float64 = 0 var stateMap = make(map[string][]common.TimeSeries) for _, pod := range allPods { @@ -114,14 +118,16 @@ func (c *CadvisorCollector) Collect() (map[string][]common.TimeSeries, error) { klog.Errorf("GetContainerInfoV2 failed: %v", err) continue } - for key, v := range containers { containerId := utils.GetContainerIdFromKey(key) - containerName := GetContainerNameFromPod(pod, containerId) + containerName := utils.GetContainerNameFromPod(pod, containerId) // Filter the sandbox container if (containerId != "") && (containerName == "") { continue } + + _, hasExtRes := utils.GetContainerExtCpuResFromPod(pod, containerName) + // In the GetContainerInfoV2 not collect the cpu quota and period // We used GetContainerInfo instead // issue https://github.com/google/cadvisor/issues/3040 @@ -133,23 +139,27 @@ func (c *CadvisorCollector) Collect() (map[string][]common.TimeSeries, error) { } if state, ok := c.latestContainersStates[key]; ok { - var labels = GetContainerLabels(pod, containerId, containerName) + var containerLabels = GetContainerLabels(pod, containerId, containerName, hasExtRes) cpuUsageSample, schedRunqueueTime := caculateCPUUsage(&v, &state) if cpuUsageSample == 0 && schedRunqueueTime == 0 { continue } - addSampleToStateMap(types.MetricNameContainerCpuTotalUsage, composeSample(labels, cpuUsageSample, now), stateMap) - addSampleToStateMap(types.MetricNameContainerSchedRunQueueTime, composeSample(labels, schedRunqueueTime, now), stateMap) - addSampleToStateMap(types.MetricNameContainerCpuLimit, composeSample(labels, float64(state.stat.Spec.Cpu.Limit), now), stateMap) - addSampleToStateMap(types.MetricNameContainerCpuQuota, composeSample(labels, float64(containerInfoV1.Spec.Cpu.Quota), now), stateMap) - addSampleToStateMap(types.MetricNameContainerCpuPeriod, composeSample(labels, float64(containerInfoV1.Spec.Cpu.Period), now), stateMap) + if hasExtRes { + extResCpuUse += cpuUsageSample + } + addSampleToStateMap(types.MetricNameContainerCpuTotalUsage, composeSample(containerLabels, cpuUsageSample, now), stateMap) + addSampleToStateMap(types.MetricNameContainerSchedRunQueueTime, composeSample(containerLabels, schedRunqueueTime, now), stateMap) + addSampleToStateMap(types.MetricNameContainerCpuLimit, composeSample(containerLabels, float64(state.stat.Spec.Cpu.Limit), now), stateMap) + addSampleToStateMap(types.MetricNameContainerCpuQuota, composeSample(containerLabels, float64(containerInfoV1.Spec.Cpu.Quota), now), stateMap) + addSampleToStateMap(types.MetricNameContainerCpuPeriod, composeSample(containerLabels, float64(containerInfoV1.Spec.Cpu.Period), now), stateMap) klog.V(10).Infof("Pod: %s, containerName: %s, key %s, scheduler run queue time %.2f", klog.KObj(pod), containerName, key, schedRunqueueTime) } containerStates[key] = ContainerState{stat: v, timestamp: now} } } + addSampleToStateMap(types.MetricNameExtResContainerCpuTotalUsage, composeSample(make([]common.Label, 0), extResCpuUse, time.Now()), stateMap) c.latestContainersStates = containerStates @@ -191,30 +201,14 @@ func caculateCPUUsage(info *cadvisorapiv2.ContainerInfo, state *ContainerState) return cpuUsageSample, schedRunqueueTime } -func GetContainerNameFromPod(pod *v1.Pod, containerId string) string { - if containerId == "" { - return "" - } - - for _, v := range pod.Status.ContainerStatuses { - strList := strings.Split(v.ContainerID, "//") - if len(strList) > 0 { - if strList[len(strList)-1] == containerId { - return v.Name - } - } - } - - return "" -} - -func GetContainerLabels(pod *v1.Pod, containerId, containerName string) []common.Label { +func GetContainerLabels(pod *v1.Pod, containerId, containerName string, hasExtRes bool) []common.Label { return []common.Label{ {Name: common.LabelNamePodName, Value: pod.Name}, {Name: common.LabelNamePodNamespace, Value: pod.Namespace}, {Name: common.LabelNamePodUid, Value: string(pod.UID)}, {Name: common.LabelNameContainerName, Value: containerName}, {Name: common.LabelNameContainerId, Value: containerId}, + {Name: common.LabelNameHasExtRes, Value: strconv.FormatBool(hasExtRes)}, } } diff --git a/pkg/ensurance/collector/cadvisor/cadvisor_unsupported.go b/pkg/ensurance/collector/cadvisor/cadvisor_unsupported.go index cdcba56f4..b53cfce86 100644 --- a/pkg/ensurance/collector/cadvisor/cadvisor_unsupported.go +++ b/pkg/ensurance/collector/cadvisor/cadvisor_unsupported.go @@ -4,28 +4,51 @@ package cadvisor import ( + info "github.com/google/cadvisor/info/v1" + cadvisorapiv2 "github.com/google/cadvisor/info/v2" + corelisters "k8s.io/client-go/listers/core/v1" + "github.com/gocrane/crane/pkg/common" "github.com/gocrane/crane/pkg/ensurance/collector/types" - corelisters "k8s.io/client-go/listers/core/v1" ) +var errUnsupported = errors.New("cAdvisor is unsupported in this build") + +type CadvisorCollectorUnsupport struct { + Manager Manager +} + +type CadvisorManagerUnsupport struct {} -type CadvisorCollector struct { +func NewCadvisorManager() Manager { + return &CadvisorManagerUnsupport{} } -func NewCadvisor(_ corelisters.PodLister) *CadvisorCollector { - return &CadvisorCollector{} +func NewCadvisorCollector(_ corelisters.PodLister, manager Manager) *CadvisorCollectorUnsupport { + return &CadvisorCollectorUnsupport{} } -func (c *CadvisorCollector) Stop() error { - return nil +func (c *CadvisorCollectorUnsupport) Stop() error { + return errUnsupported } -func (c *CadvisorCollector) GetType() types.CollectType { +func (c *CadvisorCollectorUnsupport) GetType() types.CollectType { return types.CadvisorCollectorType } -func (c *CadvisorCollector) Collect() (map[string][]common.TimeSeries, error) { - return nil, nil +func (c *CadvisorCollectorUnsupport) Collect() (map[string][]common.TimeSeries, error) { + return nil, errUnsupported +} + +func (m *CadvisorManagerUnsupport) GetContainerInfoV2(containerName string, options cadvisorapiv2.RequestOptions) (map[string]cadvisorapiv2.ContainerInfo, error) { + return nil, errUnsupported +} + +func (m *CadvisorManagerUnsupport) GetContainerInfo(containerName string, query *info.ContainerInfoRequest) (*info.ContainerInfo, error) { + return nil, errUnsupported +} + +func (m *CadvisorManagerUnsupport) GetMachineInfo() (*info.MachineInfo, error) { + return nil, errUnsupported } func CheckMetricNameExist(name string) bool { diff --git a/pkg/ensurance/collector/cadvisor/types.go b/pkg/ensurance/collector/cadvisor/types.go new file mode 100644 index 000000000..471f0b397 --- /dev/null +++ b/pkg/ensurance/collector/cadvisor/types.go @@ -0,0 +1,12 @@ +package cadvisor + +import ( + info "github.com/google/cadvisor/info/v1" + cadvisorapiv2 "github.com/google/cadvisor/info/v2" +) + +type Manager interface { + GetContainerInfoV2(containerName string, options cadvisorapiv2.RequestOptions) (map[string]cadvisorapiv2.ContainerInfo, error) + GetContainerInfo(containerName string, query *info.ContainerInfoRequest) (*info.ContainerInfo, error) + GetMachineInfo() (*info.MachineInfo, error) +} diff --git a/pkg/ensurance/collector/collector.go b/pkg/ensurance/collector/collector.go index a97a4652d..3024caac7 100644 --- a/pkg/ensurance/collector/collector.go +++ b/pkg/ensurance/collector/collector.go @@ -8,6 +8,7 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" corelisters "k8s.io/client-go/listers/core/v1" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" ensuranceListers "github.com/gocrane/api/pkg/generated/listers/ensurance/v1alpha1" "github.com/gocrane/crane/pkg/common" @@ -28,14 +29,16 @@ type StateCollector struct { healthCheck *metrics.HealthCheck collectInterval time.Duration ifaces []string + exclusiveCPUSet func() cpuset.CPUSet collectors *sync.Map + cadvisorManager cadvisor.Manager AnalyzerChann chan map[string][]common.TimeSeries NodeResourceChann chan map[string][]common.TimeSeries PodResourceChann chan map[string][]common.TimeSeries } func NewStateCollector(nodeName string, nepLister ensuranceListers.NodeQOSEnsurancePolicyLister, podLister corelisters.PodLister, - nodeLister corelisters.NodeLister, ifaces []string, healthCheck *metrics.HealthCheck, collectInterval time.Duration) *StateCollector { + nodeLister corelisters.NodeLister, ifaces []string, healthCheck *metrics.HealthCheck, collectInterval time.Duration, exclusiveCPUSet func() cpuset.CPUSet, manager cadvisor.Manager) *StateCollector { analyzerChann := make(chan map[string][]common.TimeSeries) nodeResourceChann := make(chan map[string][]common.TimeSeries) podResourceChann := make(chan map[string][]common.TimeSeries) @@ -51,6 +54,8 @@ func NewStateCollector(nodeName string, nepLister ensuranceListers.NodeQOSEnsura NodeResourceChann: nodeResourceChann, PodResourceChann: podResourceChann, collectors: &sync.Map{}, + cadvisorManager: manager, + exclusiveCPUSet: exclusiveCPUSet, } } @@ -59,6 +64,7 @@ func (s *StateCollector) Name() string { } func (s *StateCollector) Run(stop <-chan struct{}) { + s.UpdateCollectors() go func() { updateTicker := time.NewTicker(s.collectInterval) defer updateTicker.Stop() @@ -166,15 +172,12 @@ func (s *StateCollector) UpdateCollectors() { nodeLocal = true if _, exists := s.collectors.Load(types.NodeLocalCollectorType); !exists { - nc := nodelocal.NewNodeLocal(s.ifaces) + nc := nodelocal.NewNodeLocal(s.ifaces, s.exclusiveCPUSet) s.collectors.Store(types.NodeLocalCollectorType, nc) } if _, exists := s.collectors.Load(types.CadvisorCollectorType); !exists { - c := cadvisor.NewCadvisor(s.podLister) - if c != nil { - s.collectors.Store(types.CadvisorCollectorType, c) - } + s.collectors.Store(types.CadvisorCollectorType, cadvisor.NewCadvisorCollector(s.podLister, s.GetCadvisorManager())) } break } @@ -200,6 +203,10 @@ func (s *StateCollector) GetCollectors() *sync.Map { return s.collectors } +func (s *StateCollector) GetCadvisorManager() cadvisor.Manager { + return s.cadvisorManager +} + func (s *StateCollector) StopCollectors() { klog.Infof("StopCollectors") diff --git a/pkg/ensurance/collector/nodelocal/cpu.go b/pkg/ensurance/collector/nodelocal/cpu.go index 16d72e146..1b350bd5a 100644 --- a/pkg/ensurance/collector/nodelocal/cpu.go +++ b/pkg/ensurance/collector/nodelocal/cpu.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "math" + "strconv" + "strings" "time" "github.com/shirou/gopsutil/cpu" @@ -20,18 +22,19 @@ const ( ) func init() { - registerCollector(cpuCollectorName, []types.MetricName{types.MetricNameCpuTotalUsage, types.MetricNameCpuTotalUtilization}, collectCPU) + registerCollector(cpuCollectorName, []types.MetricName{types.MetricNameCpuTotalUsage, types.MetricNameCpuTotalUtilization, types.MetricNameExclusiveCPUIdle}, collectCPU) registerCollector(cpuLoadCollectorName, []types.MetricName{types.MetricNameCpuLoad1Min, types.MetricNameCpuLoad5Min, types.MetricNameCpuLoad15Min}, collectCPULoad) } type CpuTimeStampState struct { stat cpu.TimesStat + perStat map[int]cpu.TimesStat timestamp time.Time } -func collectCPU(nodeState *nodeState) (map[string][]common.TimeSeries, error) { +func collectCPU(nodeLocalContext *nodeLocalContext) (map[string][]common.TimeSeries, error) { var now = time.Now() - + nodeState := nodeLocalContext.nodeState // if the cpu core number is not set, to initialize it if nodeState.cpuCoreNumbers == 0 { if cpuInfos, err := cpu.Info(); err != nil { @@ -41,20 +44,38 @@ func collectCPU(nodeState *nodeState) (map[string][]common.TimeSeries, error) { } } - stats, err := cpu.Times(false) + totalCpuStat, err := cpu.Times(false) if err != nil { return nil, err } + if len(totalCpuStat) != 1 { + return nil, fmt.Errorf("len totalCpuStat is not 1") + } - if len(stats) != 1 { - return nil, fmt.Errorf("len stat is not 1") + perCpuStats, err := cpu.Times(true) + if err != nil { + return nil, err + } + + if len(perCpuStats) == 0 { + return nil, fmt.Errorf("len perCpuStats is 0") } currentCpuState := &CpuTimeStampState{ - stat: stats[0], timestamp: now, + stat: totalCpuStat[0], } + statsMap := make(map[int]cpu.TimesStat) + for _, stat := range perCpuStats { + cpuId, err := strconv.ParseInt(strings.TrimPrefix(stat.CPU, "cpu"), 10, 64) + if err != nil { + continue + } + statsMap[int(cpuId)] = stat + } + currentCpuState.perStat = statsMap + // if the latest cpu state is empty, to initialize it if nodeState.latestCpuState == nil { nodeState.latestCpuState = currentCpuState @@ -64,18 +85,31 @@ func collectCPU(nodeState *nodeState) (map[string][]common.TimeSeries, error) { usagePercent := calculateBusy(nodeState.latestCpuState.stat, currentCpuState.stat) usageCore := usagePercent * float64(nodeState.cpuCoreNumbers) * 1000 / types.MaxPercentage - klog.V(6).Infof("CpuCollector collected,usagePercent %v, usageCore %v", usagePercent, usageCore) + cpuSet := nodeLocalContext.exclusiveCPUSet() + var exclusiveCPUIdle float64 = 0 + + for cpuId, stat := range currentCpuState.perStat { + if !cpuSet.Contains(cpuId) { + continue + } + if oldStat, ok := nodeState.latestCpuState.perStat[cpuId]; ok { + exclusiveCPUIdle += calculateIdle(oldStat, stat) * 1000 / types.MaxPercentage + } + } + + klog.V(6).Infof("CpuCollector collected,usagePercent %v, usageCore %v, exclusiveCPUIdle %v", usagePercent, usageCore, exclusiveCPUIdle) nodeState.latestCpuState = currentCpuState var data = make(map[string][]common.TimeSeries, 2) data[string(types.MetricNameCpuTotalUsage)] = []common.TimeSeries{{Samples: []common.Sample{{Value: usageCore, Timestamp: now.Unix()}}}} data[string(types.MetricNameCpuTotalUtilization)] = []common.TimeSeries{{Samples: []common.Sample{{Value: usagePercent, Timestamp: now.Unix()}}}} + data[string(types.MetricNameExclusiveCPUIdle)] = []common.TimeSeries{{Samples: []common.Sample{{Value: exclusiveCPUIdle, Timestamp: now.Unix()}}}} return data, nil } -func collectCPULoad(_ *nodeState) (map[string][]common.TimeSeries, error) { +func collectCPULoad(_ *nodeLocalContext) (map[string][]common.TimeSeries, error) { var now = time.Now() stat, err := load.Avg() if err != nil { @@ -113,3 +147,21 @@ func getAllBusy(stat cpu.TimesStat) (float64, float64) { busy := stat.User + stat.System + stat.Nice + stat.Iowait + stat.Irq + stat.Softirq + stat.Steal return busy + stat.Idle, busy } + +func calculateIdle(stat1 cpu.TimesStat, stat2 cpu.TimesStat) float64 { + stat1All, stat1Idle := getAllIdle(stat1) + stat2All, stat2Idle := getAllIdle(stat2) + if stat2Idle <= stat1Idle { + return types.MinPercentage + } + if stat2All <= stat1All { + return types.MaxPercentage + } + + return math.Min(types.MaxPercentage, math.Max(types.MinPercentage, (stat2Idle-stat1Idle)/(stat2All-stat1All)*100)) +} + +func getAllIdle(stat cpu.TimesStat) (float64, float64) { + busy := stat.User + stat.System + stat.Nice + stat.Iowait + stat.Irq + stat.Softirq + stat.Steal + return busy + stat.Idle, stat.Idle +} diff --git a/pkg/ensurance/collector/nodelocal/disk.go b/pkg/ensurance/collector/nodelocal/disk.go index 7d6cdf813..54e1cfea4 100644 --- a/pkg/ensurance/collector/nodelocal/disk.go +++ b/pkg/ensurance/collector/nodelocal/disk.go @@ -33,8 +33,9 @@ type DiskIOUsage struct { Utilization float64 } -func collectDiskIO(nodeState *nodeState) (map[string][]common.TimeSeries, error) { +func collectDiskIO(nodeLocalContext *nodeLocalContext) (map[string][]common.TimeSeries, error) { var now = time.Now() + nodeState := nodeLocalContext.nodeState devices, err := sysBlockDevices(sysBlockPath) if err != nil { @@ -84,7 +85,7 @@ func sysBlockDevices(sysBlockPath string) ([]string, error) { if err != nil { return nil, err } - devices := []string{} + devices := make([]string, 0) for _, dir := range dirs { devices = append(devices, dir.Name()) } diff --git a/pkg/ensurance/collector/nodelocal/memory.go b/pkg/ensurance/collector/nodelocal/memory.go index 1693ff619..177a4b02f 100644 --- a/pkg/ensurance/collector/nodelocal/memory.go +++ b/pkg/ensurance/collector/nodelocal/memory.go @@ -19,7 +19,7 @@ func init() { registerCollector(memoryCollectorName, []types.MetricName{types.MetricNameMemoryTotalUsage, types.MetricNameMemoryTotalUtilization}, collectMemory) } -func collectMemory(_ *nodeState) (map[string][]common.TimeSeries, error) { +func collectMemory(_ *nodeLocalContext) (map[string][]common.TimeSeries, error) { var now = time.Now() stat, err := mem.VirtualMemory() if err != nil { diff --git a/pkg/ensurance/collector/nodelocal/net.go b/pkg/ensurance/collector/nodelocal/net.go index 16658282f..b18a1a4b7 100644 --- a/pkg/ensurance/collector/nodelocal/net.go +++ b/pkg/ensurance/collector/nodelocal/net.go @@ -39,8 +39,9 @@ type NetInterfaceUsage struct { DropOut float64 } -func collectNetIO(nodeState *nodeState) (map[string][]common.TimeSeries, error) { +func collectNetIO(nodeLocalContext *nodeLocalContext) (map[string][]common.TimeSeries, error) { var now = time.Now() + nodeState := nodeLocalContext.nodeState netIOStats, err := net.IOCounters(true) if err != nil { diff --git a/pkg/ensurance/collector/nodelocal/nodelocal.go b/pkg/ensurance/collector/nodelocal/nodelocal.go index 90c798208..d4857d752 100644 --- a/pkg/ensurance/collector/nodelocal/nodelocal.go +++ b/pkg/ensurance/collector/nodelocal/nodelocal.go @@ -4,14 +4,19 @@ import ( "strings" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "github.com/gocrane/crane/pkg/common" "github.com/gocrane/crane/pkg/ensurance/collector/types" ) -type collectFunc func(nodeState *nodeState) (map[string][]common.TimeSeries, error) +type nodeLocalContext struct { + nodeState *nodeState + exclusiveCPUSet func() cpuset.CPUSet +} + +type collectFunc func(nodeLocalContext *nodeLocalContext) (map[string][]common.TimeSeries, error) var nodeLocalMetric = make(map[string][]types.MetricName, 10) var collectFuncMap = make(map[string]collectFunc, 10) @@ -35,16 +40,18 @@ type nodeState struct { } type NodeLocal struct { - name types.CollectType - nodeState *nodeState + name types.CollectType + nodeState *nodeState + exclusiveCPUSet func() cpuset.CPUSet } -func NewNodeLocal(ifaces []string) *NodeLocal { +func NewNodeLocal(ifaces []string, exclusiveCPUSet func() cpuset.CPUSet) *NodeLocal { klog.V(2).Infof("New NodeLocal collector on interfaces %v", ifaces) n := NodeLocal{ - name: types.NodeLocalCollectorType, - nodeState: &nodeState{ifaces: sets.NewString(ifaces...)}, + name: types.NodeLocalCollectorType, + nodeState: &nodeState{ifaces: sets.NewString(ifaces...)}, + exclusiveCPUSet: exclusiveCPUSet, } return &n @@ -58,8 +65,12 @@ func (n *NodeLocal) Collect() (map[string][]common.TimeSeries, error) { klog.V(6).Infof("Node local collecting") var status = make(map[string][]common.TimeSeries) + nodeLocalContext := &nodeLocalContext{ + nodeState: n.nodeState, + exclusiveCPUSet: n.exclusiveCPUSet, + } for name, collect := range collectFuncMap { - if data, err := collect(n.nodeState); err == nil { + if data, err := collect(nodeLocalContext); err == nil { for key, d := range data { status[key] = d } diff --git a/pkg/ensurance/collector/types/types.go b/pkg/ensurance/collector/types/types.go index a84428d95..d26c6fd89 100644 --- a/pkg/ensurance/collector/types/types.go +++ b/pkg/ensurance/collector/types/types.go @@ -26,6 +26,8 @@ const ( MetricNameCpuLoad5Min MetricName = "cpu_load_5_min" MetricNameCpuLoad15Min MetricName = "cpu_load_15_min" + MetricNameExclusiveCPUIdle MetricName = "exclusive_cpu_idle" + MetricNameMemoryTotalUsage MetricName = "memory_total_usage" MetricNameMemoryTotalUtilization MetricName = "memory_total_utilization" @@ -47,6 +49,8 @@ const ( MetricNameContainerCpuQuota MetricName = "container_cpu_quota" MetricNameContainerCpuPeriod MetricName = "container_cpu_period" MetricNameContainerSchedRunQueueTime MetricName = "container_sched_run_queue_time" + + MetricNameExtResContainerCpuTotalUsage MetricName = "ext_res_container_cpu_total_usage" ) func GetCgroupPath(p *v1.Pod) string { diff --git a/pkg/ensurance/runtime/container.go b/pkg/ensurance/runtime/container.go index 2e826995a..c4e183227 100644 --- a/pkg/ensurance/runtime/container.go +++ b/pkg/ensurance/runtime/container.go @@ -41,6 +41,8 @@ type ListOptions struct { podID string // Regular expression pattern to match pod or container nameRegexp string + // Regular expression pattern to match the pod namespace + podNamespaceRegexp string // state of the sandbox state string // labels are selectors for the sandbox @@ -184,10 +186,8 @@ func filterContainersList(containersList []*pb.Container, opts ListOptions) []*p var filtered = []*pb.Container{} for _, c := range containersList { - if matched, err := regexp.MatchString(opts.nameRegexp, c.Metadata.Name); err == nil { - if matched { - filtered = append(filtered, c) - } + if matchRegex(opts.nameRegexp, c.Metadata.Name) { + filtered = append(filtered, c) } } @@ -210,3 +210,15 @@ func filterContainersList(containersList []*pb.Container, opts ListOptions) []*p return filtered[:n] } + +func matchRegex(pattern, target string) bool { + if pattern == "" { + return true + } + matched, err := regexp.MatchString(pattern, target) + if err != nil { + // Assume it's not a match if an error occurs. + return false + } + return matched +} diff --git a/pkg/ensurance/runtime/sandbox.go b/pkg/ensurance/runtime/sandbox.go new file mode 100644 index 000000000..64e919b41 --- /dev/null +++ b/pkg/ensurance/runtime/sandbox.go @@ -0,0 +1,87 @@ +package runtime + +import ( + "context" + "fmt" + "sort" + "strings" + + pb "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" + "k8s.io/klog/v2" +) + +type sandboxByCreated []*pb.PodSandbox + +func (a sandboxByCreated) Len() int { return len(a) } +func (a sandboxByCreated) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a sandboxByCreated) Less(i, j int) bool { + return a[i].CreatedAt > a[j].CreatedAt +} + +// ListPodSandboxes sends a ListPodSandboxRequest to the server, and parses +// the returned ListPodSandboxResponse. +// copied from kubernetes-sigs/cri-tools/cmd/crictl/sandbox.go +func ListPodSandboxes(client pb.RuntimeServiceClient, opts ListOptions) ([]*pb.PodSandbox, error) { + filter := &pb.PodSandboxFilter{} + if opts.id != "" { + filter.Id = opts.id + } + if opts.state != "" { + st := &pb.PodSandboxStateValue{} + st.State = pb.PodSandboxState_SANDBOX_NOTREADY + switch strings.ToLower(opts.state) { + case "ready": + st.State = pb.PodSandboxState_SANDBOX_READY + filter.State = st + case "notready": + st.State = pb.PodSandboxState_SANDBOX_NOTREADY + filter.State = st + default: + klog.Errorf("state should be ready or notready") + return []*pb.PodSandbox{}, fmt.Errorf("state should be ready or notready") + } + } + if opts.labels != nil { + filter.LabelSelector = opts.labels + } + request := &pb.ListPodSandboxRequest{ + Filter: filter, + } + klog.V(6).Info("ListPodSandboxRequest: %v", request) + r, err := client.ListPodSandbox(context.Background(), request) + if err != nil { + return []*pb.PodSandbox{}, err + } + klog.V(6).Info("ListPodSandboxResponse: %v", r) + + r.Items = filterSandboxesList(r.GetItems(), opts) + return r.Items, nil +} + +func filterSandboxesList(sandboxesList []*pb.PodSandbox, opts ListOptions) []*pb.PodSandbox { + filtered := []*pb.PodSandbox{} + for _, p := range sandboxesList { + // Filter by pod name/namespace regular expressions. + if matchRegex(opts.nameRegexp, p.Metadata.Name) && + matchRegex(opts.podNamespaceRegexp, p.Metadata.Namespace) { + filtered = append(filtered, p) + } + } + + sort.Sort(sandboxByCreated(filtered)) + n := len(filtered) + if opts.latest { + n = 1 + } + if opts.last > 0 { + n = opts.last + } + n = func(a, b int) int { + if a < b { + return a + } + return b + }(n, len(filtered)) + + return filtered[:n] +} diff --git a/pkg/features/features.go b/pkg/features/features.go index 9f44fc1cd..77a40c5c6 100644 --- a/pkg/features/features.go +++ b/pkg/features/features.go @@ -24,6 +24,9 @@ const ( // CraneTimeSeriesPrediction enables the time series prediction features. CraneTimeSeriesPrediction featuregate.Feature = "TimeSeriesPrediction" + + // CraneCpuSetManager enables the cpuset manger features. + CraneCpuSetManager featuregate.Feature = "CpusetManager" ) var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ @@ -33,6 +36,7 @@ var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ CranePodResource: {Default: true, PreRelease: featuregate.Alpha}, CraneClusterNodePrediction: {Default: false, PreRelease: featuregate.Alpha}, CraneTimeSeriesPrediction: {Default: true, PreRelease: featuregate.Alpha}, + CraneCpuSetManager: {Default: false, PreRelease: featuregate.Alpha}, } func init() { diff --git a/pkg/resource/node_resource_manager.go b/pkg/resource/node_resource_manager.go index eb95d9316..3870365c1 100644 --- a/pkg/resource/node_resource_manager.go +++ b/pkg/resource/node_resource_manager.go @@ -2,6 +2,7 @@ package resource import ( "context" + "encoding/json" "fmt" "math" "strconv" @@ -11,29 +12,44 @@ import ( "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" coreinformers "k8s.io/client-go/informers/core/v1" clientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" corelisters "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/record" "k8s.io/klog/v2" predictionv1 "github.com/gocrane/api/pkg/generated/informers/externalversions/prediction/v1alpha1" predictionlisters "github.com/gocrane/api/pkg/generated/listers/prediction/v1alpha1" predictionapi "github.com/gocrane/api/prediction/v1alpha1" "github.com/gocrane/crane/pkg/common" + "github.com/gocrane/crane/pkg/ensurance/collector/types" "github.com/gocrane/crane/pkg/known" "github.com/gocrane/crane/pkg/metrics" - "github.com/gocrane/crane/pkg/prediction/config" "github.com/gocrane/crane/pkg/utils" ) const ( - MinDeltaRatio = 0.1 - StateExpiration = 1 * time.Minute - TspUpdateInterval = 20 * time.Second + MinDeltaRatio = 0.1 + StateExpiration = 1 * time.Minute + TspUpdateInterval = 20 * time.Second + TspNamespace = "default" + NodeReserveResourcePercentageAnnotationPrefix = "reserve.node.gocrane.io/%s" ) +var idToResourceMap = map[string]v1.ResourceName{ + v1.ResourceCPU.String(): v1.ResourceCPU, + v1.ResourceMemory.String(): v1.ResourceMemory, +} + +// ReserveResource is the cpu and memory reserve configuration +type ReserveResource struct { + CpuPercent *float64 + MemPercent *float64 +} + type NodeResourceManager struct { nodeName string client clientset.Interface @@ -44,17 +60,30 @@ type NodeResourceManager struct { tspLister predictionlisters.TimeSeriesPredictionLister tspSynced cache.InformerSynced + recorder record.EventRecorder + stateChann chan map[string][]common.TimeSeries - //TODO: use state to be a backup of tsp - // A copy of data from stateChann state map[string][]common.TimeSeries // Updated when get new data from stateChann, used to determine whether state has expired lastStateTime time.Time + + reserveResource ReserveResource + + tspName string } -func NewNodeResourceManager(client clientset.Interface, nodeName string, podInformer coreinformers.PodInformer, nodeInformer coreinformers.NodeInformer, - tspInformer predictionv1.TimeSeriesPredictionInformer, runtimeEndpoint string, stateChann chan map[string][]common.TimeSeries) *NodeResourceManager { +func NewNodeResourceManager(client clientset.Interface, nodeName string, reserveCpuPercentStr string, + reserveMemoryPercentStr string, tspName string, nodeInformer coreinformers.NodeInformer, + tspInformer predictionv1.TimeSeriesPredictionInformer, stateChann chan map[string][]common.TimeSeries) *NodeResourceManager { + reserveCpuPercent, _ := utils.ParsePercentage(reserveCpuPercentStr) + reserveMemoryPercent, _ := utils.ParsePercentage(reserveMemoryPercentStr) + + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartStructuredLogging(0) + eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: client.CoreV1().Events("")}) + recorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "crane-agent"}) + o := &NodeResourceManager{ nodeName: nodeName, client: client, @@ -62,7 +91,13 @@ func NewNodeResourceManager(client clientset.Interface, nodeName string, podInfo nodeSynced: nodeInformer.Informer().HasSynced, tspLister: tspInformer.Lister(), tspSynced: tspInformer.Informer().HasSynced, + recorder: recorder, stateChann: stateChann, + reserveResource: ReserveResource{ + CpuPercent: &reserveCpuPercent, + MemPercent: &reserveMemoryPercent, + }, + tspName: tspName, } return o } @@ -107,12 +142,6 @@ func (o *NodeResourceManager) Run(stop <-chan struct{}) { } func (o *NodeResourceManager) UpdateNodeResource() { - tsps, err := o.tspLister.List(labels.Everything()) - if err != nil { - klog.Errorf("Failed to list tsp: %#v", err) - return - } - node := o.getNode() if len(node.Status.Addresses) == 0 { klog.Error("Node addresses is empty") @@ -120,34 +149,16 @@ func (o *NodeResourceManager) UpdateNodeResource() { } nodeCopy := node.DeepCopy() - for _, tsp := range tsps { - // Get current node info - target := tsp.Spec.TargetRef - if target.Kind != config.TargetKindNode { + resourcesFrom := o.BuildNodeStatus(nodeCopy) + if !equality.Semantic.DeepEqual(&node.Status, &nodeCopy.Status) { + // Update Node status extend-resource info + // TODO fix: strategic merge patch kubernetes + if _, err := o.client.CoreV1().Nodes().Update(context.TODO(), nodeCopy, metav1.UpdateOptions{}); err != nil { + klog.Errorf("Failed to update node %s's status extend-resource, %v", nodeCopy.Name, err) return } - - // Whether tsp is matched with this node - tspMatched, err := o.FindTargetNode(tsp, node.Status.Addresses) - if err != nil { - klog.Error(err.Error()) - } - - if !tspMatched { - return - } - - o.BuildNodeStatus(tsp, nodeCopy) - if !equality.Semantic.DeepEqual(&node.Status, &nodeCopy.Status) { - // Update Node status extend-resource info - // TODO fix: strategic merge patch kubernetes - if _, err := o.client.CoreV1().Nodes().Update(context.TODO(), nodeCopy, metav1.UpdateOptions{}); err != nil { - klog.Errorf("Failed to update node %s's status extend-resource, %v", nodeCopy.Name, err) - return - } - klog.V(4).Infof("Update Node %s Extend Resource Success according to TSP %s", node.Name, tsp.Name) - } - return + klog.V(4).Infof("Update Node %s Extend Resource Success", node.Name) + o.recorder.Event(node, v1.EventTypeNormal, "UpdateNode", generateUpdateEventMessage(resourcesFrom)) } } @@ -163,7 +174,7 @@ func (o *NodeResourceManager) getNode() *v1.Node { func (o *NodeResourceManager) FindTargetNode(tsp *predictionapi.TimeSeriesPrediction, addresses []v1.NodeAddress) (bool, error) { address := tsp.Spec.TargetRef.Name if address == "" { - return false, fmt.Errorf("Tsp %s target is not specified", tsp.Name) + return false, fmt.Errorf("tsp %s target is not specified", tsp.Name) } // the reason we use node ip instead of node name as the target name is @@ -177,23 +188,91 @@ func (o *NodeResourceManager) FindTargetNode(tsp *predictionapi.TimeSeriesPredic return false, nil } -func (o *NodeResourceManager) BuildNodeStatus(tsp *predictionapi.TimeSeriesPrediction, node *v1.Node) { - idToResourceMap := map[string]*v1.ResourceName{} - for _, metrics := range tsp.Spec.PredictionMetrics { - if metrics.ResourceQuery == nil { +func (o *NodeResourceManager) BuildNodeStatus(node *v1.Node) map[v1.ResourceName]string{ + tspCanNotBeReclaimedResource := o.GetCanNotBeReclaimedResourceFromTsp(node) + localCanNotBeReclaimedResource := o.GetCanNotBeReclaimedResourceFromLocal() + reserveCpuPercent := o.reserveResource.CpuPercent + if nodeReserveCpuPercent, ok := getReserveResourcePercentFromNodeAnnotations(node.GetAnnotations(), v1.ResourceCPU.String()); ok { + reserveCpuPercent = &nodeReserveCpuPercent + } + + extResourceFrom := map[v1.ResourceName]string{} + + for resourceName, value := range tspCanNotBeReclaimedResource { + resourceFrom := "tsp" + maxUsage := value + if localCanNotBeReclaimedResource[resourceName] > maxUsage { + maxUsage = localCanNotBeReclaimedResource[resourceName] + resourceFrom = "local" + } + var nextRecommendation float64 + switch resourceName { + case v1.ResourceCPU: + // cpu need to be scaled to m as ext resource cannot be decimal + if reserveCpuPercent != nil { + nextRecommendation = (float64(node.Status.Allocatable.Cpu().Value())**reserveCpuPercent - maxUsage) * 1000 + } else { + nextRecommendation = (float64(node.Status.Allocatable.Cpu().Value()) - maxUsage) * 1000 + } + case v1.ResourceMemory: + // unit of memory in prometheus is in Ki, need to be converted to byte + nextRecommendation = float64(node.Status.Allocatable.Memory().Value()) - (maxUsage * 1000) + default: continue } - idToResourceMap[metrics.ResourceIdentifier] = metrics.ResourceQuery + if nextRecommendation < 0 { + nextRecommendation = 0 + } + extResourceName := fmt.Sprintf(utils.ExtResourcePrefixFormat, string(resourceName)) + resValue, exists := node.Status.Capacity[v1.ResourceName(extResourceName)] + if exists && resValue.Value() != 0 && + math.Abs(float64(resValue.Value())- + nextRecommendation)/float64(resValue.Value()) <= MinDeltaRatio { + continue + } + node.Status.Capacity[v1.ResourceName(extResourceName)] = + *resource.NewQuantity(int64(nextRecommendation), resource.DecimalSI) + node.Status.Allocatable[v1.ResourceName(extResourceName)] = + *resource.NewQuantity(int64(nextRecommendation), resource.DecimalSI) + + extResourceFrom[resourceName] = resourceFrom + } + + return extResourceFrom +} + +func (o *NodeResourceManager) GetCanNotBeReclaimedResourceFromTsp(node *v1.Node) map[v1.ResourceName]float64 { + canNotBeReclaimedResource := map[v1.ResourceName]float64{ + v1.ResourceCPU: 0, + v1.ResourceMemory: 0, + } + + tsp, err := o.tspLister.TimeSeriesPredictions(TspNamespace).Get(o.tspName) + if err != nil { + klog.Errorf("Failed to get tsp: %#v", err) + return canNotBeReclaimedResource + } + + tspMatched, err := o.FindTargetNode(tsp, node.Status.Addresses) + if err != nil { + klog.Error(err.Error()) + return canNotBeReclaimedResource } + + if !tspMatched { + klog.Errorf("Found tsp %s, but tsp not matched to node %s", o.tspName, node.Name) + return canNotBeReclaimedResource + } + // build node status nextPredictionResourceStatus := &tsp.Status - for _, metrics := range nextPredictionResourceStatus.PredictionMetrics { - resourceName, exists := idToResourceMap[metrics.ResourceIdentifier] + for _, predictionMetric := range nextPredictionResourceStatus.PredictionMetrics { + resourceName, exists := idToResourceMap[predictionMetric.ResourceIdentifier] if !exists { continue } - for _, timeSeries := range metrics.Prediction { - var maxUsage, nextUsage float64 + for _, timeSeries := range predictionMetric.Prediction { + var nextUsage float64 var nextUsageFloat float64 var err error for _, sample := range timeSeries.Samples { @@ -202,36 +281,85 @@ func (o *NodeResourceManager) BuildNodeStatus(tsp *predictionapi.TimeSeriesPredi continue } nextUsage = nextUsageFloat - if maxUsage < nextUsage { - maxUsage = nextUsage + if canNotBeReclaimedResource[resourceName] < nextUsage { + canNotBeReclaimedResource[resourceName] = nextUsage } } - var nextRecommendation float64 - switch *resourceName { - case v1.ResourceCPU: - // cpu need to be scaled to m as ext resource cannot be decimal - nextRecommendation = (float64(node.Status.Allocatable.Cpu().Value()) - maxUsage) * 1000 - case v1.ResourceMemory: - // unit of memory in prometheus is in Ki, need to be converted to byte - nextRecommendation = float64(node.Status.Allocatable.Memory().Value()) - (maxUsage * 1000) - default: - continue - } - if nextRecommendation < 0 { - klog.V(4).Infof("Unexpected recommendation,nodeName %s, maxUsage %v, nextRecommendation %v", node.Name, maxUsage, nextRecommendation) - continue - } - extResourceName := fmt.Sprintf(utils.ExtResourcePrefixFormat, string(*resourceName)) - resValue, exists := node.Status.Capacity[v1.ResourceName(extResourceName)] - if exists && resValue.Value() != 0 && - math.Abs(float64(resValue.Value())- - nextRecommendation)/float64(resValue.Value()) <= MinDeltaRatio { - continue - } - node.Status.Capacity[v1.ResourceName(extResourceName)] = - *resource.NewQuantity(int64(nextRecommendation), resource.DecimalSI) - node.Status.Allocatable[v1.ResourceName(extResourceName)] = - *resource.NewQuantity(int64(nextRecommendation), resource.DecimalSI) } } + return canNotBeReclaimedResource +} + +func (o *NodeResourceManager) GetCanNotBeReclaimedResourceFromLocal() map[v1.ResourceName]float64 { + return map[v1.ResourceName]float64{ + v1.ResourceCPU: o.GetCpuCoreCanNotBeReclaimedFromLocal(), + v1.ResourceMemory: 0, + } +} + +func (o *NodeResourceManager) GetCpuCoreCanNotBeReclaimedFromLocal() float64 { + if o.lastStateTime.Before(time.Now().Add(-20 * time.Second)) { + klog.V(1).Infof("NodeResourceManager local state has expired") + return 0 + } + + nodeCpuUsageTotalTimeSeries, ok := o.state[string(types.MetricNameCpuTotalUsage)] + if !ok { + klog.V(1).Infof("Can't get %s from NodeResourceManager local state", types.MetricNameCpuTotalUsage) + return 0 + } + nodeCpuUsageTotal := nodeCpuUsageTotalTimeSeries[0].Samples[0].Value + + var extResContainerCpuUsageTotal float64 = 0 + extResContainerCpuUsageTotalTimeSeries, ok := o.state[string(types.MetricNameExtResContainerCpuTotalUsage)] + if ok { + extResContainerCpuUsageTotal = extResContainerCpuUsageTotalTimeSeries[0].Samples[0].Value + } else { + klog.V(1).Infof("Can't get %s from NodeResourceManager local state", types.MetricNameExtResContainerCpuTotalUsage) + } + + var exclusiveCPUIdle float64 = 0 + exclusiveCPUIdleTimeSeries, ok := o.state[string(types.MetricNameExclusiveCPUIdle)] + if ok { + exclusiveCPUIdle = exclusiveCPUIdleTimeSeries[0].Samples[0].Value + } else { + klog.V(1).Infof("Can't get %s from NodeResourceManager local state", types.MetricNameExclusiveCPUIdle) + } + + // 1. Exclusive tethered CPU cannot be reclaimed even if the free part is free, so add the exclusive CPUIdle to the CanNotBeReclaimed CPU + // 2. The CPU used by extRes-container needs to be reclaimed, otherwise it will be double-counted due to the allotted mechanism of k8s, so the extResContainerCpuUsageTotal is subtracted from the CanNotBeReclaimedCpu + return nodeCpuUsageTotal + exclusiveCPUIdle - extResContainerCpuUsageTotal +} + +func getReserveResourcePercentFromNodeAnnotations(annotations map[string]string, resourceName string) (float64, bool) { + if annotations == nil { + return 0, false + } + var reserveResourcePercentStr string + var ok = false + switch resourceName { + case v1.ResourceCPU.String(): + reserveResourcePercentStr, ok = annotations[fmt.Sprintf(NodeReserveResourcePercentageAnnotationPrefix, v1.ResourceCPU.String())] + case v1.ResourceMemory.String(): + reserveResourcePercentStr, ok = annotations[fmt.Sprintf(NodeReserveResourcePercentageAnnotationPrefix, v1.ResourceMemory.String())] + default: + } + if !ok { + return 0, false + } + + reserveResourcePercent, err := utils.ParsePercentage(reserveResourcePercentStr) + if err != nil { + return 0, false + } + + return reserveResourcePercent, ok +} + +func generateUpdateEventMessage(resourcesFrom map[v1.ResourceName]string) string { + message, err := json.Marshal(resourcesFrom) + if err != nil { + return "" + } + return string(message) } diff --git a/pkg/resource/pod_resource_manger.go b/pkg/resource/pod_resource_manger.go index 0f9ec9b13..6b8e136e3 100644 --- a/pkg/resource/pod_resource_manger.go +++ b/pkg/resource/pod_resource_manger.go @@ -3,7 +3,6 @@ package resource import ( "fmt" "strings" - "sync" "time" info "github.com/google/cadvisor/info/v1" @@ -19,7 +18,6 @@ import ( "github.com/gocrane/crane/pkg/common" "github.com/gocrane/crane/pkg/ensurance/collector/cadvisor" - "github.com/gocrane/crane/pkg/ensurance/collector/types" stypes "github.com/gocrane/crane/pkg/ensurance/collector/types" "github.com/gocrane/crane/pkg/ensurance/executor" cgrpc "github.com/gocrane/crane/pkg/ensurance/grpc" @@ -45,11 +43,11 @@ type PodResourceManager struct { // Updated when get new data from stateChann, used to determine whether state has expired lastStateTime time.Time - collectors *sync.Map + cadvisor.Manager } func NewPodResourceManager(client clientset.Interface, nodeName string, podInformer coreinformers.PodInformer, - runtimeEndpoint string, stateChann chan map[string][]common.TimeSeries, collectors *sync.Map) *PodResourceManager { + runtimeEndpoint string, stateChann chan map[string][]common.TimeSeries, cadvisorManager cadvisor.Manager) *PodResourceManager { runtimeClient, runtimeConn, err := cruntime.GetRuntimeClient(runtimeEndpoint, true) if err != nil { klog.Errorf("GetRuntimeClient failed %s", err.Error()) @@ -64,7 +62,7 @@ func NewPodResourceManager(client clientset.Interface, nodeName string, podInfor runtimeClient: runtimeClient, runtimeConn: runtimeConn, stateChann: stateChann, - collectors: collectors, + Manager: cadvisorManager, } podInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ // Focused on pod belonged to this node @@ -188,16 +186,12 @@ func (o *PodResourceManager) updatePodExtResToCgroup(pod *v1.Pod) { metrics.UpdateDurationFromStart(string(known.ModulePodResourceManager), metrics.StepUpdatePodResource, start) } -// Get cpu period from local if cadvisor collector exists and state is not expired; +// Get cpu period from local state is not expired; // Otherwise, get value from CRI func (o *PodResourceManager) getCPUPeriod(pod *v1.Pod, containerId string) float64 { - value, exists := o.collectors.Load(types.CadvisorCollectorType) - if !exists { - return 0.0 - } now := time.Now() - if exists && o.state != nil && !now.After(o.lastStateTime.Add(StateExpiration)) { + if o.state != nil && !now.After(o.lastStateTime.Add(StateExpiration)) { _, containerCPUPeriods := executor.GetPodUsage(string(stypes.MetricNameContainerCpuPeriod), o.state, pod) for _, period := range containerCPUPeriods { if period.ContainerId == containerId { @@ -207,9 +201,8 @@ func (o *PodResourceManager) getCPUPeriod(pod *v1.Pod, containerId string) float } // Use CRI to get cpu period directly - c := value.(*cadvisor.CadvisorCollector) var query = info.ContainerInfoRequest{} - containerInfoV1, err := c.Manager.GetContainerInfo(containerId, &query) + containerInfoV1, err := o.Manager.GetContainerInfo(containerId, &query) if err != nil { metrics.PodResourceUpdateErrorCounterInc(metrics.SubComponentPodResource, metrics.StepGetPeriod) klog.Errorf("ContainerInfoRequest failed for container %s: %v ", containerId, err) diff --git a/pkg/server/handler/clusters/cluster.go b/pkg/server/handler/clusters/cluster.go index c0b858748..b8719f62b 100644 --- a/pkg/server/handler/clusters/cluster.go +++ b/pkg/server/handler/clusters/cluster.go @@ -46,24 +46,46 @@ func (ch *ClusterHandler) AddClusters(c *gin.Context) { return } - clustersMap := map[string]*store.Cluster{} + if len(r.Clusters) == 0 { + ginwrapper.WriteResponse(c, fmt.Errorf("req is empty, check your input para"), nil) + return + } + + clustersMap, err := ch.getClusterMap() + if err != nil { + ginwrapper.WriteResponse(c, err, nil) + return + } for _, cluster := range r.Clusters { - if cluster.CraneUrl == "" || cluster.Id == "" || cluster.Name == "" { - err := fmt.Errorf("cluster CraneUrl, Id, Name field must not be empty") + if cluster.CraneUrl == "" || cluster.Name == "" { + err := fmt.Errorf("cluster CraneUrl, Name field must not be empty") ginwrapper.WriteResponse(c, err, nil) return } + if !IsUrl(cluster.CraneUrl) { err := fmt.Errorf("cluster CraneUrl %v is not valid url", cluster.CraneUrl) ginwrapper.WriteResponse(c, err, nil) return } + + if cluster.Id == "" { + cluster.Id = store.GenerateClusterName("cls") + } + if _, ok := clustersMap[cluster.Id]; ok { err := fmt.Errorf("cluster id %v duplicated", cluster.Id) ginwrapper.WriteResponse(c, err, nil) return } + + if cluster.CraneUrlDuplicated(clustersMap) { + err := fmt.Errorf("cluster CraneUlr %v duplicated", cluster.CraneUrl) + ginwrapper.WriteResponse(c, err, nil) + return + } + clustersMap[cluster.Id] = cluster } @@ -93,6 +115,18 @@ func (ch *ClusterHandler) UpdateCluster(c *gin.Context) { old.GrafanaUrl = r.GrafanaUrl old.CraneUrl = r.CraneUrl + clustersMap, err := ch.getClusterMap() + if err != nil { + ginwrapper.WriteResponse(c, err, nil) + return + } + + if r.CraneUrlDuplicated(clustersMap) { + err := fmt.Errorf("cluster CraneUlr %v duplicated", r.CraneUrl) + ginwrapper.WriteResponse(c, err, nil) + return + } + err = ch.clusterSrv.UpdateCluster(context.TODO(), old) if err != nil { ginwrapper.WriteResponse(c, err, nil) @@ -123,7 +157,31 @@ func (ch *ClusterHandler) GetCluster(c *gin.Context) { ginwrapper.WriteResponse(c, nil, getCluster) } +// GetNamespaces return namespaces in specified cluster +func (ch *ClusterHandler) ListNamespaces(c *gin.Context) { + getNamespaces, err := ch.clusterSrv.ListNamespaces(context.TODO(), c.Param("clusterid")) + if err != nil { + ginwrapper.WriteResponse(c, err, nil) + return + } + ginwrapper.WriteResponse(c, nil, getNamespaces) +} + func IsUrl(str string) bool { u, err := url.Parse(str) return err == nil && u.Scheme != "" && u.Host != "" } + +func (ch *ClusterHandler) getClusterMap() (map[string]*store.Cluster, error) { + clustersMap := map[string]*store.Cluster{} + + clusterList, err := ch.clusterSrv.ListClusters(context.TODO()) + if err != nil { + return nil, fmt.Errorf("list cluster err: %v", err) + } + + for _, clu := range clusterList.Items { + clustersMap[clu.Id] = clu + } + return clustersMap, nil +} diff --git a/pkg/server/router.go b/pkg/server/router.go index fad4a99b7..2ceb5f3ac 100644 --- a/pkg/server/router.go +++ b/pkg/server/router.go @@ -13,7 +13,7 @@ func (s *apiServer) installHandler() { clusterHandler := clusters.NewClusterHandler(s.clusterSrv) - v1 := s.Group("/v1") + v1 := s.Group("/api/v1") { //dashboard panels if s.config.EnableGrafana { @@ -36,6 +36,12 @@ func (s *apiServer) installHandler() { clustersv1.PUT(":clusterid", clusterHandler.UpdateCluster) clustersv1.GET(":clusterid", clusterHandler.GetCluster) } + + // namespaces + nsv1 := v1.Group("/namespaces") + { + nsv1.GET(":clusterid", clusterHandler.ListNamespaces) + } } } diff --git a/pkg/server/server.go b/pkg/server/server.go index 1336d5eb2..eac0a9b38 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -67,15 +67,15 @@ func (s *apiServer) installGenericAPIs() { } // install healthz handler - s.GET("/healthz", func(c *gin.Context) { + s.GET("/api/healthz", func(c *gin.Context) { ginwrapper.WriteResponse(c, nil, map[string]string{"status": "ok"}) }) // install version handler - s.GET("/version", func(c *gin.Context) { + s.GET("/api/version", func(c *gin.Context) { ginwrapper.WriteResponse(c, nil, version.GetVersionInfo()) }) - s.GET("/klog", func(c *gin.Context) { + s.GET("/api/klog", func(c *gin.Context) { v := c.Query("v") if v != "" { err := flag.Lookup("v").Value.Set(v) diff --git a/pkg/server/service/cluster/cluster.go b/pkg/server/service/cluster/cluster.go index 2fa6575a6..66fde41ae 100644 --- a/pkg/server/service/cluster/cluster.go +++ b/pkg/server/service/cluster/cluster.go @@ -12,6 +12,7 @@ type Service interface { UpdateCluster(ctx context.Context, cluster *store.Cluster) error GetCluster(ctx context.Context, clusterid string) (*store.Cluster, error) ListClusters(ctx context.Context) (*store.ClusterList, error) + ListNamespaces(ctx context.Context, clusterid string) (*store.NamespaceList, error) } type clusterService struct { @@ -41,3 +42,7 @@ func (s *clusterService) GetCluster(ctx context.Context, clusterid string) (*sto func (s *clusterService) ListClusters(ctx context.Context) (*store.ClusterList, error) { return s.datastore.Clusters().ListClusters(ctx) } + +func (s *clusterService) ListNamespaces(ctx context.Context, clusterid string) (*store.NamespaceList, error) { + return s.datastore.Clusters().ListNamespaces(ctx, clusterid) +} diff --git a/pkg/server/store/cluster.go b/pkg/server/store/cluster.go index 0141b2b64..59a3348b9 100644 --- a/pkg/server/store/cluster.go +++ b/pkg/server/store/cluster.go @@ -1,6 +1,11 @@ package store -import "context" +import ( + "context" + "strings" + + utilrand "k8s.io/apimachinery/pkg/util/rand" +) // Cluster define the craned endpoint and information about the cluster the craned deployed in type Cluster struct { @@ -19,6 +24,11 @@ type ClusterList struct { Items []*Cluster `json:"items"` } +type NamespaceList struct { + TotalCount int `json:"totalCount"` + Items []string `json:"items"` +} + // ClusterStore define the cluster store CURD interface type ClusterStore interface { AddCluster(ctx context.Context, cluster *Cluster) error @@ -26,4 +36,23 @@ type ClusterStore interface { UpdateCluster(ctx context.Context, cluster *Cluster) error GetCluster(ctx context.Context, clusterid string) (*Cluster, error) ListClusters(ctx context.Context) (*ClusterList, error) + ListNamespaces(ctx context.Context, clusterid string) (*NamespaceList, error) +} + +func (c Cluster) CraneUrlDuplicated(store map[string]*Cluster) bool { + for id, cluster := range store { + if id != c.Id { + if cluster.CraneUrl == c.CraneUrl { + return true + } + } + } + return false +} + +func GenerateClusterName(base string) string { + if strings.HasSuffix(base, "-") { + return base + utilrand.String(8) + } + return base + "-" + utilrand.String(8) } diff --git a/pkg/server/store/secret/cluster.go b/pkg/server/store/secret/cluster.go index ace757f8f..c47c5d66a 100644 --- a/pkg/server/store/secret/cluster.go +++ b/pkg/server/store/secret/cluster.go @@ -175,6 +175,21 @@ func (c *clusters) ListClusters(ctx context.Context) (*store.ClusterList, error) return listClusterInSecret(secret) } +func (c *clusters) ListNamespaces(ctx context.Context, clusterid string) (*store.NamespaceList, error) { + ns := &store.NamespaceList{} + + namespaces, err := c.k8s.client.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) + if err != nil { + return ns, err + } + for _, namespace := range namespaces.Items { + ns.Items = append(ns.Items, namespace.Name) + } + ns.TotalCount = len(ns.Items) + + return ns, nil +} + func NewClusters(datastore *datastore) store.ClusterStore { return &clusters{k8s: datastore} } diff --git a/pkg/utils/pod.go b/pkg/utils/pod.go index c103cded2..c08758e36 100644 --- a/pkg/utils/pod.go +++ b/pkg/utils/pod.go @@ -141,6 +141,44 @@ func GetExtCpuRes(container v1.Container) (resource.Quantity, bool) { return resource.Quantity{}, false } +func GetContainerNameFromPod(pod *v1.Pod, containerId string) string { + if containerId == "" { + return "" + } + + for _, v := range pod.Status.ContainerStatuses { + strList := strings.Split(v.ContainerID, "//") + if len(strList) > 0 { + if strList[len(strList)-1] == containerId { + return v.Name + } + } + } + + return "" +} + +func GetContainerFromPod(pod *v1.Pod, containerName string) *v1.Container { + if containerName == ""{ + return nil + } + for _, v := range pod.Spec.Containers { + if v.Name == containerName { + return &v + } + } + return nil +} + +// GetExtCpuRes get container's gocrane.io/cpu usage +func GetContainerExtCpuResFromPod(pod *v1.Pod, containerName string) (resource.Quantity, bool) { + c := GetContainerFromPod(pod, containerName) + if c == nil { + return resource.Quantity{}, false + } + return GetExtCpuRes(*c) +} + func GetContainerStatus(pod *v1.Pod, container v1.Container) v1.ContainerState { for _, cs := range pod.Status.ContainerStatuses { if cs.Name == container.Name { diff --git a/pkg/utils/string.go b/pkg/utils/string.go index 591115c4f..5ec868f56 100644 --- a/pkg/utils/string.go +++ b/pkg/utils/string.go @@ -1,6 +1,9 @@ package utils -import "strconv" +import ( + "strconv" + "strings" +) func ContainsString(slice []string, str string) bool { for _, s := range slice { @@ -17,3 +20,15 @@ func ParseFloat(str string, defaultValue float64) (float64, error) { } return strconv.ParseFloat(str, 64) } + +// parsePercentage parse the percent string value +func ParsePercentage(input string) (float64, error) { + if len(input) == 0 { + return 0, nil + } + value, err := strconv.ParseFloat(strings.TrimRight(input, "%"), 64) + if err != nil { + return 0, err + } + return value / 100, nil +} \ No newline at end of file From 8b269b6c166f8733957b68c8e68923a3bbf8835a Mon Sep 17 00:00:00 2001 From: patricklai Date: Fri, 25 Mar 2022 14:56:38 +0800 Subject: [PATCH 02/41] chore(dashboard): remove runtime-env-cra in dockerfile --- pkg/web/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/web/Dockerfile b/pkg/web/Dockerfile index 2cfc13b84..5cf0c4102 100644 --- a/pkg/web/Dockerfile +++ b/pkg/web/Dockerfile @@ -23,4 +23,5 @@ RUN npm i -g runtime-env-cra@0.2.0 WORKDIR /usr/share/nginx/html EXPOSE 9090 -CMD ["/bin/sh", "-c", "runtime-env-cra && nginx -g \"daemon off;\""] \ No newline at end of file +# CMD ["/bin/sh", "-c", "runtime-env-cra && nginx -g \"daemon off;\""] +CMD ["/bin/sh", "-c", "nginx -g \"daemon off;\""] \ No newline at end of file From eaf446f4adb9f40bf3a8477d191f74fa715c5fdc Mon Sep 17 00:00:00 2001 From: kitianFresh <1549722424@qq.com> Date: Mon, 28 Mar 2022 20:41:01 +0800 Subject: [PATCH 03/41] refine querybuilder factory to register way, to avoid switch case mode. each implementer only register by init way --- pkg/metricnaming/naming.go | 11 ++-------- .../metricserver/builder.go | 4 ++++ .../prometheus/builder.go | 4 ++++ pkg/querybuilder/query.go | 21 +++++++++++++++++++ 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/pkg/metricnaming/naming.go b/pkg/metricnaming/naming.go index 9e29e9fcd..38dc19492 100644 --- a/pkg/metricnaming/naming.go +++ b/pkg/metricnaming/naming.go @@ -3,8 +3,6 @@ package metricnaming import ( "github.com/gocrane/crane/pkg/metricquery" "github.com/gocrane/crane/pkg/querybuilder" - msbuilder "github.com/gocrane/crane/pkg/querybuilder-providers/metricserver" - prombuilder "github.com/gocrane/crane/pkg/querybuilder-providers/prometheus" ) // MetricNamer is an interface. it is the bridge between predictor and different data sources and other component. @@ -38,13 +36,8 @@ type queryBuilderFactory struct { } func (q queryBuilderFactory) Builder(source metricquery.MetricSource) querybuilder.Builder { - switch source { - case metricquery.MetricServerMetricSource: - return msbuilder.NewMetricServerQueryBuilder(q.metric) - case metricquery.PrometheusMetricSource: - return prombuilder.NewPromQueryBuilder(q.metric) - } - return prombuilder.NewPromQueryBuilder(q.metric) + initFunc := querybuilder.GetBuilderFactory(source) + return initFunc(q.metric) } func NewQueryBuilder(metric *metricquery.Metric) querybuilder.QueryBuilder { diff --git a/pkg/querybuilder-providers/metricserver/builder.go b/pkg/querybuilder-providers/metricserver/builder.go index b57cb0bef..b8692d799 100644 --- a/pkg/querybuilder-providers/metricserver/builder.go +++ b/pkg/querybuilder-providers/metricserver/builder.go @@ -27,3 +27,7 @@ func metricServerQuery(query *metricquery.MetricServerQuery) *metricquery.Query MetricServer: query, } } + +func init() { + querybuilder.RegisterBuilderFactory(metricquery.MetricServerMetricSource, NewMetricServerQueryBuilder) +} diff --git a/pkg/querybuilder-providers/prometheus/builder.go b/pkg/querybuilder-providers/prometheus/builder.go index 9281570d3..67c371beb 100644 --- a/pkg/querybuilder-providers/prometheus/builder.go +++ b/pkg/querybuilder-providers/prometheus/builder.go @@ -154,3 +154,7 @@ func promQuery(prom *metricquery.PrometheusQuery) *metricquery.Query { Prometheus: prom, } } + +func init() { + querybuilder.RegisterBuilderFactory(metricquery.PrometheusMetricSource, NewPromQueryBuilder) +} diff --git a/pkg/querybuilder/query.go b/pkg/querybuilder/query.go index f8f010b06..2bca48246 100644 --- a/pkg/querybuilder/query.go +++ b/pkg/querybuilder/query.go @@ -1,6 +1,8 @@ package querybuilder import ( + "sync" + "github.com/gocrane/crane/pkg/metricquery" ) @@ -13,3 +15,22 @@ type Builder interface { type QueryBuilder interface { Builder(source metricquery.MetricSource) Builder } + +var ( + factoryLock sync.Mutex + builderFactory = make(map[metricquery.MetricSource]BuilderFactoryFunc) +) + +type BuilderFactoryFunc func(metric *metricquery.Metric) Builder + +func RegisterBuilderFactory(metricSource metricquery.MetricSource, initFunc BuilderFactoryFunc) { + factoryLock.Lock() + defer factoryLock.Unlock() + builderFactory[metricSource] = initFunc +} + +func GetBuilderFactory(metricSource metricquery.MetricSource) BuilderFactoryFunc { + factoryLock.Lock() + defer factoryLock.Unlock() + return builderFactory[metricSource] +} From 88c285f0264ca91229f546a02eab04cfd6272913 Mon Sep 17 00:00:00 2001 From: qmhu Date: Wed, 30 Mar 2022 17:49:45 +0800 Subject: [PATCH 04/41] update image version --- deploy/crane-agent/daemonset.yaml | 2 +- deploy/craned/deployment.yaml | 4 ++-- deploy/metric-adapter/deployment.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/crane-agent/daemonset.yaml b/deploy/crane-agent/daemonset.yaml index 335eed8a5..b36939a88 100644 --- a/deploy/crane-agent/daemonset.yaml +++ b/deploy/crane-agent/daemonset.yaml @@ -29,7 +29,7 @@ spec: fieldRef: apiVersion: v1 fieldPath: spec.nodeName - image: docker.io/gocrane/crane-agent + image: docker.io/gocrane/crane-agent:v0.3.0 imagePullPolicy: Always command: - /crane-agent diff --git a/deploy/craned/deployment.yaml b/deploy/craned/deployment.yaml index 9d84ee387..0999d3b3f 100644 --- a/deploy/craned/deployment.yaml +++ b/deploy/craned/deployment.yaml @@ -35,7 +35,7 @@ spec: operator: Exists containers: - name: craned - image: docker.io/gocrane/craned:v0.2.0 + image: docker.io/gocrane/craned:v0.3.0 imagePullPolicy: IfNotPresent env: - name: TZ @@ -57,7 +57,7 @@ spec: path: /api/healthz port: 8082 scheme: HTTP - - image: docker.io/gocrane/dashboard:v0.2.0 + - image: docker.io/gocrane/dashboard:v0.3.0 imagePullPolicy: IfNotPresent name: dashboard volumeMounts: diff --git a/deploy/metric-adapter/deployment.yaml b/deploy/metric-adapter/deployment.yaml index 7ea8d83c6..13177c3fc 100644 --- a/deploy/metric-adapter/deployment.yaml +++ b/deploy/metric-adapter/deployment.yaml @@ -27,7 +27,7 @@ spec: serviceAccountName: metric-adapter containers: - name: metric-adapter - image: docker.io/gocrane/metric-adapter:v0.2.0 + image: docker.io/gocrane/metric-adapter:v0.3.0 imagePullPolicy: IfNotPresent env: - name: TZ From 0e96f8fbdf44a84e7027994e7c1fb1c939ff9c4f Mon Sep 17 00:00:00 2001 From: kitianFresh <1549722424@qq.com> Date: Thu, 31 Mar 2022 17:42:23 +0800 Subject: [PATCH 05/41] add more log for datasource prom query, add some timeout contex --- cmd/craned/app/options/options.go | 2 +- pkg/prediction/percentile/prediction.go | 37 ++++------------------- pkg/providers/prom/ctx.go | 16 ++++++---- pkg/providers/prom/prometheus.go | 17 +++++++---- pkg/recommend/advisor/resource_request.go | 4 +-- 5 files changed, 30 insertions(+), 46 deletions(-) diff --git a/cmd/craned/app/options/options.go b/cmd/craned/app/options/options.go index 90710da43..f55cb9afe 100644 --- a/cmd/craned/app/options/options.go +++ b/cmd/craned/app/options/options.go @@ -98,7 +98,7 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) { flags.IntVar(&o.DataSourcePromConfig.QueryConcurrency, "prometheus-query-concurrency", 10, "prometheus query concurrency") flags.BoolVar(&o.DataSourcePromConfig.InsecureSkipVerify, "prometheus-insecure-skip-verify", false, "prometheus insecure skip verify") flags.DurationVar(&o.DataSourcePromConfig.KeepAlive, "prometheus-keepalive", 60*time.Second, "prometheus keep alive") - flags.DurationVar(&o.DataSourcePromConfig.Timeout, "prometheus-timeout", 60*time.Second, "prometheus timeout") + flags.DurationVar(&o.DataSourcePromConfig.Timeout, "prometheus-timeout", 3*time.Minute, "prometheus timeout") flags.BoolVar(&o.DataSourcePromConfig.BRateLimit, "prometheus-bratelimit", false, "prometheus bratelimit") flags.IntVar(&o.DataSourcePromConfig.MaxPointsLimitPerTimeSeries, "prometheus-maxpoints", 11000, "prometheus max points limit per time series") flags.StringVar(&o.DataSourceMockConfig.SeedFile, "seed-file", "", "mock provider seed file") diff --git a/pkg/prediction/percentile/prediction.go b/pkg/prediction/percentile/prediction.go index f6f7153b1..9e5119b5b 100644 --- a/pkg/prediction/percentile/prediction.go +++ b/pkg/prediction/percentile/prediction.go @@ -3,7 +3,6 @@ package percentile import ( "context" "fmt" - "math" "sync" "time" @@ -173,8 +172,6 @@ func (p *percentilePrediction) QueryRealtimePredictedValuesOnce(ctx context.Cont // process is a stateless function to get estimation of a metric series by constructing a histogram then get estimation data. func (p *percentilePrediction) process(namer metricnaming.MetricNamer, config config.Config) ([]*common.TimeSeries, error) { var predictedTimeSeriesList []*common.TimeSeries - maxAttempts := 10 - attempts := 0 var historyTimeSeriesList []*common.TimeSeries var err error queryExpr := namer.BuildUniqueKey() @@ -184,19 +181,9 @@ func (p *percentilePrediction) process(namer metricnaming.MetricNamer, config co } klog.V(4).Infof("process analyzing metric namer: %v, config: %+v", namer.BuildUniqueKey(), *cfg) - for attempts < maxAttempts { - historyTimeSeriesList, err = p.queryHistoryTimeSeries(namer, cfg) - if err != nil { - attempts++ - t := time.Second * time.Duration(math.Pow(2., float64(attempts))) - klog.ErrorS(err, "Failed to get time series.", "queryExpr", queryExpr, "attempts", attempts) - time.Sleep(t) - } else { - break - } - } - if attempts == maxAttempts { - klog.Errorf("After attempting %d times, still cannot get history time series for query expression '%s'.", maxAttempts, queryExpr) + historyTimeSeriesList, err = p.queryHistoryTimeSeries(namer, cfg) + if err != nil { + klog.Errorf("Failed to query history time series for query expression '%s'.", queryExpr) return nil, err } @@ -414,23 +401,11 @@ func (p *percentilePrediction) init(namer metricnaming.MetricNamer) error { queryExpr := namer.BuildUniqueKey() cfg := p.a.GetConfig(queryExpr) // Query history data for prediction - maxAttempts := 10 - attempts := 0 var historyTimeSeriesList []*common.TimeSeries var err error - for attempts < maxAttempts { - historyTimeSeriesList, err = p.queryHistoryTimeSeries(namer, cfg) - if err != nil { - attempts++ - t := time.Second * time.Duration(math.Pow(2., float64(attempts))) - klog.ErrorS(err, "Failed to get time series.", "queryExpr", queryExpr, "attempts", attempts) - time.Sleep(t) - } else { - break - } - } - if attempts == maxAttempts { - klog.Errorf("After attempting %d times, still cannot get history time series for query expression '%s'.", maxAttempts, queryExpr) + historyTimeSeriesList, err = p.queryHistoryTimeSeries(namer, cfg) + if err != nil { + klog.Errorf("Failed to query history time series for query expression '%s'.", queryExpr) return err } diff --git a/pkg/providers/prom/ctx.go b/pkg/providers/prom/ctx.go index 480740b32..c8212de41 100644 --- a/pkg/providers/prom/ctx.go +++ b/pkg/providers/prom/ctx.go @@ -51,17 +51,18 @@ func (c *context) QueryRangeSync(ctx gocontext.Context, query string, start, end } shards := c.computeShards(query, &r) if len(shards.windows) <= 1 { + klog.V(4).InfoS("Prom query directly", "query", query) var ts []*common.TimeSeries results, warnings, err := c.api.QueryRange(ctx, query, r) if len(warnings) != 0 { - klog.V(4).InfoS("prom query range warnings", "warnings", warnings) + klog.V(4).InfoS("Prom query range warnings", "warnings", warnings) } // todo: parse err to see its max limit dynamically if err != nil { return ts, err } - if klog.V(10).Enabled() { - klog.V(10).InfoS("prom query range result", "result", results.String(), "resultsType", results.Type()) + if klog.V(7).Enabled() { + klog.V(7).InfoS("Prom query range result", "query", query, "result", results.String(), "resultsType", results.Type()) } return c.convertPromResultsToTimeSeries(results) @@ -74,17 +75,18 @@ func (c *context) QuerySync(ctx gocontext.Context, query string) ([]*common.Time var ts []*common.TimeSeries results, warnings, err := c.api.Query(ctx, query, time.Now()) if len(warnings) != 0 { - klog.InfoS("prom query warnings", "warnings", warnings) + klog.InfoS("Prom query warnings", "warnings", warnings) } if err != nil { return ts, err } - klog.V(8).InfoS("prom query result", "result", results.String(), "resultsType", results.Type()) + klog.V(8).InfoS("Prom query result", "result", results.String(), "resultsType", results.Type()) return c.convertPromResultsToTimeSeries(results) } func (c *context) queryByShards(ctx gocontext.Context, queryShards *QueryShards) ([]*common.TimeSeries, error) { + klog.V(4).InfoS("Prom query range by shards", "query", queryShards.query) resultsCh := make(chan *QueryShardResult, len(queryShards.windows)) var wg sync.WaitGroup for _, window := range queryShards.windows { @@ -92,9 +94,10 @@ func (c *context) queryByShards(ctx gocontext.Context, queryShards *QueryShards) go func(ctx gocontext.Context, window *promapiv1.Range) { defer runtime.HandleCrash() defer wg.Done() + klog.V(6).InfoS("Prom query range by shards", "query", queryShards.query, "window", window) value, warnings, err := c.api.QueryRange(ctx, queryShards.query, *window) if len(warnings) != 0 { - klog.V(4).InfoS("prom query range warnings", "warnings", warnings, "window", window, "query", queryShards.query) + klog.V(4).InfoS("Prom query range warnings", "warnings", warnings, "window", window, "query", queryShards.query) } if err != nil { resultsCh <- &QueryShardResult{ @@ -126,6 +129,7 @@ func (c *context) queryByShards(ctx gocontext.Context, queryShards *QueryShards) wg.Wait() close(resultsCh) + klog.V(4).InfoS("Prom query range by shards, all shards query done", "query", queryShards.query) var errs []error resultsMap := make(map[string]*common.TimeSeries) var results []*common.TimeSeries diff --git a/pkg/providers/prom/prometheus.go b/pkg/providers/prom/prometheus.go index c5436867b..00f0f72ca 100644 --- a/pkg/providers/prom/prometheus.go +++ b/pkg/providers/prom/prometheus.go @@ -13,7 +13,8 @@ import ( ) type prom struct { - ctx *context + ctx *context + config *providers.PromConfig } // NewProvider return a prometheus data provider @@ -26,7 +27,7 @@ func NewProvider(config *providers.PromConfig) (providers.Interface, error) { ctx := NewContext(client, config.MaxPointsLimitPerTimeSeries) - return &prom{ctx: ctx}, nil + return &prom{ctx: ctx, config: config}, nil } func (p *prom) QueryTimeSeries(namer metricnaming.MetricNamer, startTime time.Time, endTime time.Time, step time.Duration) ([]*common.TimeSeries, error) { @@ -36,12 +37,14 @@ func (p *prom) QueryTimeSeries(namer metricnaming.MetricNamer, startTime time.Ti klog.Errorf("Failed to BuildQuery: %v", err) return nil, err } - timeSeries, err := p.ctx.QueryRangeSync(gocontext.TODO(), promQuery.Prometheus.Query, startTime, endTime, step) + klog.V(6).Infof("QueryTimeSeries metricNamer %v, timeout: %v", namer.BuildUniqueKey(), p.config.Timeout) + timeoutCtx, cancelFunc := gocontext.WithTimeout(gocontext.Background(), p.config.Timeout) + defer cancelFunc() + timeSeries, err := p.ctx.QueryRangeSync(timeoutCtx, promQuery.Prometheus.Query, startTime, endTime, step) if err != nil { klog.Errorf("Failed to QueryTimeSeries: %v, metricNamer: %v, query: %v", err, namer.BuildUniqueKey(), promQuery.Prometheus.Query) return nil, err } - klog.V(6).Infof("QueryTimeSeries metricNamer %v", namer.BuildUniqueKey()) return timeSeries, nil } @@ -56,11 +59,13 @@ func (p *prom) QueryLatestTimeSeries(namer metricnaming.MetricNamer) ([]*common. //end := time.Now() // avoid no data latest. multiply 2 //start := end.Add(-step * 2) - timeSeries, err := p.ctx.QuerySync(gocontext.TODO(), promQuery.Prometheus.Query) + klog.V(6).Infof("QueryLatestTimeSeries metricNamer %v, timeout: %v", namer.BuildUniqueKey(), p.config.Timeout) + timeoutCtx, cancelFunc := gocontext.WithTimeout(gocontext.Background(), p.config.Timeout) + defer cancelFunc() + timeSeries, err := p.ctx.QuerySync(timeoutCtx, promQuery.Prometheus.Query) if err != nil { klog.Errorf("Failed to QueryLatestTimeSeries: %v, metricNamer: %v, query: %v", err, namer.BuildUniqueKey(), promQuery.Prometheus.Query) return nil, err } - klog.V(6).Infof("QueryLatestTimeSeries metricNamer %v", namer.BuildUniqueKey()) return timeSeries, nil } diff --git a/pkg/recommend/advisor/resource_request.go b/pkg/recommend/advisor/resource_request.go index 8d42938f8..4beab5a45 100644 --- a/pkg/recommend/advisor/resource_request.go +++ b/pkg/recommend/advisor/resource_request.go @@ -108,7 +108,7 @@ func (a *ResourceRequestAdvisor) Advise(proposed *types.ProposedRecommendation) } mericNamer := ResourceToContainerMetricNamer(namespace, pod.Name, c.Name, corev1.ResourceCPU) - klog.V(8).Infof("CPU query for resource request recommendation: %s", mericNamer.BuildUniqueKey()) + klog.V(6).Infof("CPU query for resource request recommendation: %s", mericNamer.BuildUniqueKey()) cpuConfig := makeCpuConfig(a.ConfigProperties) tsList, err := utils.QueryPredictedValuesOnce(a.Recommendation, p, fmt.Sprintf(callerFormat, a.Recommendation.UID), cpuConfig, mericNamer) @@ -122,7 +122,7 @@ func (a *ResourceRequestAdvisor) Advise(proposed *types.ProposedRecommendation) cr.Target[corev1.ResourceCPU] = resource.NewMilliQuantity(v, resource.DecimalSI).String() mericNamer = ResourceToContainerMetricNamer(namespace, pod.Name, c.Name, corev1.ResourceMemory) - klog.V(8).Infof("Memory query for resource request recommendation: %s", mericNamer.BuildUniqueKey()) + klog.V(6).Infof("Memory query for resource request recommendation: %s", mericNamer.BuildUniqueKey()) memConfig := makeMemConfig(a.ConfigProperties) tsList, err = utils.QueryPredictedValuesOnce(a.Recommendation, p, fmt.Sprintf(callerFormat, a.Recommendation.UID), memConfig, mericNamer) From 28f17819ddc9b4bd1df058b6bc586b7639c313ba Mon Sep 17 00:00:00 2001 From: zsnmwy Date: Sat, 2 Apr 2022 20:59:37 +0800 Subject: [PATCH 06/41] Support web docs by mkdocs Signed-off-by: zsnmwy --- .github/workflows/mkdocs-publish.yml | 42 +++++ .github/workflows/mkdocs.yml | 21 +++ .github/workflows/preview.yml | 27 ++++ README.md | 2 +- docs/CNAME | 1 + docs/CONTRIBUTING.md | 28 ++++ docs/assets/util.js | 17 ++ docs/code-standards.md | 4 +- docs/getting-started.md | 114 +++++++++++++ docs/getting-started.zh.md | 151 ++++++++++++++++++ docs/images/add_cluster.png | Bin 0 -> 314915 bytes docs/images/crane-dashboard.png | Bin 0 -> 256693 bytes docs/images/dashboard_nodeport.png | Bin 0 -> 156973 bytes docs/images/first_cluster.png | Bin 0 -> 236345 bytes docs/index.md | 78 +++++++++ docs/index.zh.md | 78 +++++++++ .../20220228-advanced-cpuset-manger.md | 2 +- docs/roadmaps/roadmap-1h-2022.md | 4 +- .../tutorials/analytics-and-recommendation.md | 104 ++++++++++-- ...ctive-hpa-to-scaling-with-effectiveness.md | 51 +++--- docs/tutorials/using-qos-ensurance.md | 53 +++--- mkdocs.yml | 73 +++++++++ overrides/main.html | 8 + 23 files changed, 797 insertions(+), 61 deletions(-) create mode 100644 .github/workflows/mkdocs-publish.yml create mode 100644 .github/workflows/mkdocs.yml create mode 100644 .github/workflows/preview.yml create mode 100644 docs/CNAME create mode 100644 docs/CONTRIBUTING.md create mode 100644 docs/assets/util.js create mode 100644 docs/getting-started.md create mode 100644 docs/getting-started.zh.md create mode 100644 docs/images/add_cluster.png create mode 100644 docs/images/crane-dashboard.png create mode 100644 docs/images/dashboard_nodeport.png create mode 100644 docs/images/first_cluster.png create mode 100644 docs/index.md create mode 100644 docs/index.zh.md create mode 100644 mkdocs.yml create mode 100644 overrides/main.html diff --git a/.github/workflows/mkdocs-publish.yml b/.github/workflows/mkdocs-publish.yml new file mode 100644 index 000000000..a900da4e0 --- /dev/null +++ b/.github/workflows/mkdocs-publish.yml @@ -0,0 +1,42 @@ +name: Publish branch +on: + push: + branches: + - "release-*" + +jobs: + upload: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - uses: actions/setup-python@v2 + with: + python-version: "3.9" + + - run: pip install mkdocs-material mkdocs-static-i18n mike + + - name: Set user + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + + - name: Extract branch name + shell: bash + run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" + id: extract_branch + + - name: Mike with updating aliases + if: ${{ github.event.created }} + run: | + echo ${{ steps.extract_branch.outputs.branch }} + mike deploy --push --force --update-aliases ${{ steps.extract_branch.outputs.branch }} latest --rebase + mike set-default --push --force latest + + - name: Mike + if: ${{ !github.event.created }} + run: | + echo ${{ steps.extract_branch.outputs.branch }} + mike deploy --force --push ${{ steps.extract_branch.outputs.branch }} diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml new file mode 100644 index 000000000..eed2ce56b --- /dev/null +++ b/.github/workflows/mkdocs.yml @@ -0,0 +1,21 @@ +name: mkdocs +on: + push: + branches: + - main +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-python@v2 + with: + python-version: 3.x + - name: Set user + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + - run: pip install mkdocs-material mkdocs-static-i18n mike + - run: mike deploy --force --push dev diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 000000000..51c46ed56 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,27 @@ +name: 🔂 Crane PR Docs Preview + +on: + pull_request: + # when using teardown: 'true', add default event types + closed event type + types: [opened, synchronize, reopened, closed] + +jobs: + preview: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-python@v2 + with: + python-version: "3.9" + + - run: pip install mkdocs-material mkdocs-static-i18n mike + + - uses: afc163/surge-preview@v1 + with: + surge_token: ${{ secrets.SURGE_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} + dist: site + teardown: 'true' + build: | + mkdocs build diff --git a/README.md b/README.md index 76a48d44c..0382ce7c4 100644 --- a/README.md +++ b/README.md @@ -198,4 +198,4 @@ Please see [this document](./docs/roadmaps/roadmap-1h-2022.md) to learn more. Contributors are welcomed to join Crane project. Please check [CONTRIBUTING](./CONTRIBUTING.md) about how to contribute to this project. ## Code of Conduct -Crane adopts [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). \ No newline at end of file +Crane adopts [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 000000000..61470dc8b --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +docs.gocrane.io diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 000000000..9d8162bde --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,28 @@ +# Contributing to Crane + +Welcome to Crane! This document is a guideline about how to contribute to Crane. + +## Become a contributor + +You can contribute to Crane in several ways. Here are some examples: + +* Contribute to the Crane codebase. +* Report bugs. +* Suggest enhancements. +* Write technical documentation and blog posts, for users and contributors. +* Organize meetups and user groups in your local area. +* Help others by answering questions about Crane. + +For more ways to contribute, check out the [Open Source Guides](https://opensource.guide/how-to-contribute/). + +### Report bugs + +Before submitting a new issue, try to make sure someone hasn't already reported the problem. +Look through the [existing issues](https://github.com/gocrane/crane/issues) for similar issues. + +Report a bug by submitting a [bug report](https://github.com/gocrane/crane/issues/new?assignees=&labels=kind%2Fbug&template=bug_report.md&title=). +Make sure that you provide as much information as possible on how to reproduce the bug. + +### Suggest enhancements + +If you have an idea to improve Crane, submit an [feature request](https://github.com/gocrane/crane/issues/new?assignees=&labels=kind%2Ffeature&template=feature_request.md&title=). \ No newline at end of file diff --git a/docs/assets/util.js b/docs/assets/util.js new file mode 100644 index 000000000..f0d31c739 --- /dev/null +++ b/docs/assets/util.js @@ -0,0 +1,17 @@ +setTimeout(function () { + const requestAnimationFrame = window.requestAnimationFrame; + const requestIdleCallback = window.requestIdleCallback; + requestIdleCallback(()=> { + requestAnimationFrame(()=> { + // Remove # when use markdown annotations + const mdAnnotations = document.querySelectorAll(".md-annotation") + for (let i = 0; i < mdAnnotations.length; i++) { + let tmp = mdAnnotations[i] + let parentChinldNodes = tmp.parentElement.childNodes + if (parentChinldNodes[0].data === '#'){ + parentChinldNodes[0].remove() + } + } + }) + }) +},1) diff --git a/docs/code-standards.md b/docs/code-standards.md index c9f47dca7..bb0570604 100644 --- a/docs/code-standards.md +++ b/docs/code-standards.md @@ -1,7 +1,7 @@ This doc describes the code standards and suggestion for crane project, mainly for new contributor of the project ### import need to be organized import should be categorized with blank line as system imports, community imports and crane apis and crane imports, like the following example -``` +```go import ( "reflect" "sync" @@ -81,4 +81,4 @@ type Interface interface { - Test-driven developing - Complex function that include condition decide should add unit test for it -### don't forget to run `make fmt` before you submit code \ No newline at end of file +### don't forget to run `make fmt` before you submit code diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 000000000..412fa7c13 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,114 @@ +# Getting Started + +## Installation + +**Prerequisites** + +- Kubernetes 1.18+ +- Helm 3.1.0 + +**Helm Installation** + +Please refer to Helm's [documentation](https://helm.sh/docs/intro/install/) for installation. + +**Installing prometheus and grafana with helm chart** + +!!! note + If you already deployed prometheus, grafana in your environment, then skip this step. + +Crane use prometheus to be the default metric provider. + +Using following command to install prometheus components: prometheus-server, node-exporter, kube-state-metrics. + +```bash +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm install prometheus -n crane-system --set pushgateway.enabled=false --set alertmanager.enabled=false --set server.persistentVolume.enabled=false -f https://raw.githubusercontent.com/gocrane/helm-charts/main/integration/prometheus/override_values.yaml --create-namespace prometheus-community/prometheus +``` + +Fadvisor use grafana to present cost estimates. Using following command to install a grafana. + +```bash +helm repo add grafana https://grafana.github.io/helm-charts +helm install grafana -f https://raw.githubusercontent.com/gocrane/helm-charts/main/integration/grafana/override_values.yaml -n crane-system --create-namespace grafana/grafana +``` + +**Deploying Crane and Fadvisor** + +```bash +helm repo add crane https://gocrane.github.io/helm-charts +helm install crane -n crane-system --create-namespace crane/crane +helm install fadvisor -n crane-system --create-namespace crane/fadvisor +``` + +**Verify Installation** + +Check deployments are all available by running: + +```bash +kubectl get deploy -n crane-system +``` + +The output is similar to: +```bash +NAME READY STATUS RESTARTS AGE +crane-agent-8h7df 1/1 Running 0 119m +crane-agent-8qf5n 1/1 Running 0 119m +crane-agent-h9h5d 1/1 Running 0 119m +craned-5c69c684d8-dxmhw 2/2 Running 0 20m +grafana-7fddd867b4-kdxv2 1/1 Running 0 41m +metric-adapter-94b6f75b-k8h7z 1/1 Running 0 119m +prometheus-kube-state-metrics-6dbc9cd6c9-dfmkw 1/1 Running 0 45m +prometheus-node-exporter-bfv74 1/1 Running 0 45m +prometheus-node-exporter-s6zps 1/1 Running 0 45m +prometheus-node-exporter-x5rnm 1/1 Running 0 45m +prometheus-server-5966b646fd-g9vxl 2/2 Running 0 45m +``` + +you can see [this](https://github.com/gocrane/helm-charts) to learn more. + +**Customize Installation** + +Deploy `Crane` by apply YAML declaration. + +```bash +git clone https://github.com/gocrane/crane.git +CRANE_LATEST_VERSION=$(curl -s https://api.github.com/repos/gocrane/crane/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")') +git checkout $CRANE_LATEST_VERSION +kubectl apply -f deploy/manifests +kubectl apply -f deploy/craned +kubectl apply -f deploy/metric-adapter +``` + +The following command will configure prometheus http address for crane if you want to customize it. Specify `CUSTOMIZE_PROMETHEUS` if you have existing prometheus server. + +```bash +export CUSTOMIZE_PROMETHEUS= +if [ $CUSTOMIZE_PROMETHEUS ]; then sed -i '' "s/http:\/\/prometheus-server.crane-system.svc.cluster.local:8080/${CUSTOMIZE_PROMETHEUS}/" deploy/craned/deployment.yaml ; fi +``` + +## Get your Kubernetes Cost Report + +Get the Grafana URL to visit by running these commands in the same shell: + +```bash +export POD_NAME=$(kubectl get pods --namespace crane-system -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana" -o jsonpath="{.items[0].metadata.name}") +kubectl --namespace crane-system port-forward $POD_NAME 3000 +``` + +visit [Cost Report](http://127.0.0.1:3000/dashboards) here with account(admin:admin). + +## Analytics and Recommendation + +Crane supports analytics and give recommend advise for your k8s cluster. + +Please follow [this guide](tutorials/analytics-and-recommendation.md) to learn more. + +## RoadMap +Please see [this document](roadmaps/roadmap-1h-2022.md) to learn more. + +## Contributing + +Contributors are welcomed to join Crane project. Please check [CONTRIBUTING](./CONTRIBUTING.md) about how to contribute to this project. + +## Code of Conduct +Crane adopts [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). diff --git a/docs/getting-started.zh.md b/docs/getting-started.zh.md new file mode 100644 index 000000000..fabc54870 --- /dev/null +++ b/docs/getting-started.zh.md @@ -0,0 +1,151 @@ +# 产品部署指南 + +!!! tip + 本页面来自 https://github.com/gocrane/crane/pull/243 @willemswang + +为了让您更快的部署 Crane ,本文档提供清晰的: + +* 部署环境要求 +* 具体安装步骤 + +Crane 安装时间在10分钟左右,具体时间也依赖集群规模以及硬件能力。目前安装已经非常成熟,如果您安装中遇到任何问题,可以采取如下几种方式: + +* 请首先检查后文的 F&Q +* 可以提出一个 [Issue](https://github.com/gocrane/crane/issues/new?assignees=&labels=kind%2Fbug&template=bug_report.md&title=),我们会认真对待每一个 [Issue](https://github.com/gocrane/crane/issues) + +## 部署环境要求 + +- Kubernetes 1.18+ +- Helm 3.1.0 + +## 安装流程 + +### 安装 Helm + +建议参考 Helm 官网[安装文档](https://helm.sh/docs/intro/install/)。 + +### 安装 Prometheus 和 Grafana + +使用 Helm 安装 Prometheus 和 Grafana。 + +> 注意:如果您已经在环境中部署了 Prometheus 和 Grafana,可以跳过该步骤。 + +Crane 使用 Prometheus 抓取集群工作负载对资源的使用情况。安装 Prometheus: + +```shell +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm install prometheus -n crane-system --set pushgateway.enabled=false --set alertmanager.enabled=false --set server.persistentVolume.enabled=false -f https://raw.githubusercontent.com/gocrane/helm-charts/main/integration/prometheus/override_values.yaml --create-namespace prometheus-community/prometheus +``` + +Crane 的 Fadvisor 使用 Grafana 展示成本预估。安装 Grafana: + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm install grafana -f https://raw.githubusercontent.com/gocrane/helm-charts/main/integration/grafana/override_values.yaml -n crane-system --create-namespace grafana/grafana +``` + +### 安装 Crane 和 Fadvisor + +```console +helm repo add crane https://gocrane.github.io/helm-charts +helm install crane -n crane-system --create-namespace crane/crane +helm install fadvisor -n crane-system --create-namespace crane/fadvisor +``` + + + +## 验证安装是否成功 + +使用如下命令检查安装的 Deployment 是否正常: + +```console +kubectl get deploy -n crane-system +``` + +结果类似如下: + +```shell +NAME READY UP-TO-DATE AVAILABLE AGE +craned 1/1 1 1 31m +fadvisor 1/1 1 1 41m +grafana 1/1 1 1 42m +metric-adapter 1/1 1 1 31m +prometheus-kube-state-metrics 1/1 1 1 43m +prometheus-server 1/1 1 1 43m +``` + +可以查看本篇[文档](https://github.com/gocrane/helm-charts/blob/main/charts/crane/README.md)获取更多有关 Crane Helm Chart 的信息。 + +## 成本展示 + +### 打开 Crane 控制台 + +注意:Crane 的控制台地址就是 Crane 的 URL 地址,可以将其添加到统一的控制台查看多个部署 Crane 的集群的信息。 + +利用 [Port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) 命令,可以在本地计算机的浏览器打开 Crane 控制台: + +``` +kubectl port-forward -n crane-system svc/craned 9090 +``` + +执行上述命令后,不要关闭命令行工具,在本地计算机的浏览器地址里输入 `localhost:9090`即可打开 Crane 的控制台: + +![](images/crane-dashboard.png) + + + +### 添加安装了 Crane 的集群 + +您可以点击上图中的“添加集群”的蓝色按钮,将 Crane 控制台的地址 `http://localhost:9090` 作为 Crane 的 URL,作为第一个集群添加到 Crane 控制台。 + +![](images/add_cluster.png) + +若您想添加其它集群,实现多集群的资源使用和成本分析。可以在别的集群中也安装完 Crane 之后,将 Crane 的 URL 添加进来。 + +## 自定义安装 + +通过 YAML 安装 `Crane` 。 + +```console +git checkout v0.2.0 +kubectl apply -f deploy/manifests +kubectl apply -f deploy/craned +kubectl apply -f deploy/metric-adapter +``` + +如果您想自定义 Crane 里配置 Prometheus 的 HTTP 地址,请参考以下的命令。如果您在集群里已存在一个 Prometheus,请将 Server 地址填于`CUSTOMIZE_PROMETHEUS` 。 + +```console +export CUSTOMIZE_PROMETHEUS= +if [ $CUSTOMIZE_PROMETHEUS ]; then sed -i '' "s/http:\/\/prometheus-server.crane-system.svc.cluster.local:8080/${CUSTOMIZE_PROMETHEUS}/" deploy/craned/deployment.yaml ; fi +``` + +## 安装常见问题 + +### 安装 Crane 报错 + +当您执行 `helm install crane -n crane-system --create-namespace crane/crane` 命令时,可能会遇到如下错误: + +```shell +Error: rendered manifests contain a resource that already exists. Unable to continue with install: APIService "v1beta1.custom.metrics.k8s.io" in namespace "" exists and cannot be imported into the current release: invalid ownership metadata; label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm"; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "crane"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "crane-system" +``` + +原因:集群安装过 custom metric 的 APIService,所以报错。可以把之前的删除再重新执行安装 Crane 的命令,删除方式:`kubectl delete apiservice v1beta1.custom.metrics.k8s.io`。 + +### 获取 Crane URL 的其它方式 + +#### NodePort 方式 + +您可以将 Crane 的 Service 的类型换成 NodePort 类型,这样可以直接通过集群任意节点 IP + 该服务里dashboard- service 端口号的方式,打开控制台。 + +具体操作:修改 crane-system 命名空间下名为 craned 的 Service,将其访问方式该为 NodePort 的方式,然后获取某一集群的节点 IP,以及相应的端口号,端口号如下所示: + +![](images/dashboard_nodeport.png) + +注意:若您的集群节点只有内网 IP,则访问该 IP 的计算机需要在同一内网。若集群节点拥有外网 IP,则没有相关问题。 + +#### LoadBalance 方式 + +若您使用的是公有云厂商的服务,您可以将 Crane 的 Service 的类型换成公网 LB 类型,这样可以直接通过 LB IP + 9090 端口号的方式,打开控制台。 + +具体操作:修改 crane-system 命名空间下名为 craned 的 Service,将其访问方式该为公网 LB 的方式。 diff --git a/docs/images/add_cluster.png b/docs/images/add_cluster.png new file mode 100644 index 0000000000000000000000000000000000000000..0c79a6b73af1791d23904791d4799f305c852fe1 GIT binary patch literal 314915 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�XOLA*tpxvn{KSzQR-G$j!I1V z@Hu(w|NW|3rz9Ms#;wCIBovZ0WqaYT6Bt%@C|galH@%>5X#j5{9C;QpaCq_0?vyUv zVW@aa`rzqzvbWfhHR~8Ck^)$RGa1_}1~m5NNgE8@ACqxBLEOAbx%ig{>U8z0F;vNATtU_}c$+4*%mH zdk^?AH~fzZ3L0#44~=g6Co68j4hkSQHA2UUp5D8*j#>m0xxQ&gC3FO{j0HfrIuFG zuFlr+aDFe8sS%$hzKnfMd;jQV3zMIC^SV9qpW5ym85>RqIYrL;a-GN zMYPhTx3VSBJ0J32hWMvINInZ=!%92^r z4gBIKXHU=K$Y?2w8(OYU{F$BDZgZ4p25lEBJs#95UV#u;%DEM!w8V1SN&!RAmV`-D zQUT%bFv=@Su;KARkr7lN6%eIJsKE+1=paaG1n9cW*&x61rKhG!$h!_Za776y==y^D zM~=!mSFl)H5usYb%q%Pjxp=T|C`swhy6zarFV z^>_JWh}xoM^kb@N&UrM_(0S7{$wouvXMUra36aDDMOr`@(|;|`kgJHaA;FlA4k^Y6 zvU=LQw$)YK%{TiYBb9t(6x_fkr`nTk?dnX~e?hJaMzNSfqMNJWDHp=`R*E=4D}kQ*`_Y2T6XJ%3TR^YGex z4*E*D-Zhcd5LXR%nNIHKxD5#dmaZVO{F+`T78<;mJzP!AS0-+#ErbClvp)%@Bb4kQ z-%fv*lRCMK%$zIaUq!f-R^*O75X=qxF)YAB+zz0?*!zGrXRSNw28yMyk5b!m_0?`d zPM&xRvJdgIv$LMyHdKY8+U`D`;sdmG%fH+a*R%K?XUw+$n6krmyQ95e!^m4e+-)3P zpLMyE(}!ehWeYV+hLr)ZD|y=d=(+E9dEhe}uHxCN2*#JBkY6**G0UYX7fTCh!aC=K z(uOUA5gq}TqeBwvZKDWE4ABX{mDTR@T!Krw`#AoZ*QA=f}?- zZdh!cb(B5-53M!(?))tEh9C||W`^z%*uSkHcQSHBSCoCE(&HUhen#<-JR#`Rft3ee z7C5=HgVw*zE+`Fnw(szzj97RUWKEV_wK^Zx?h8dX^D4dTJ7}yFwsDFR_~&WT^*>Eo zD$m-2AM;99yk2#XS9wZ}GJYqdWa6bTI|Tmg3G`)pGj`-t(bCK(^Mj{df}fw44_c`^ zgv9mF2RcyvjygAcy~}BXBRR$ku4=}(nd!AlOCXr&bT#p(&*phCiJ}jaX##4M1(Cm^ zYeVk7-I$tdd)xSFprz$%>+%#tht9sY`_k15U49v|YW*udik0^H^MkT|rne%a<662q zv5c0^)^L$j&-=4kiAK%wt8<9=r@tBFN~Vm% zz}DvsB+E}XkAwLzGil@wsoQRE2ulf_bbOGA`86rY-!hmv`Lf9u>W;X#;-W7Ifv7`n z{B}v-F};SByG{sU1UPjqKuHUESQ%KI1QY}J!@b>B7qJ+;dX0{Qj21M{>oDgok><*% z>=b5J`Z0%iyo0DDa~7(W0u7n3^P{Eez+=O;4irPNtE|cSmoIMKcVx}C1Y(&}%06c6 zta#RfEz1Nj$&}B91dm)pEpcoBR6^U7EYRXx9inN5^3@u*uA18Nvu70^i z3#aIG>=G++D@IW#xI2l$zWNe%NKwuVOEza|q6m^{p zAHIamy_RNy5{g^en}_IAjq_3~Xc8b^j1SCL#7y$_GI-IM@$?kqSt@?6BzDA0(#vw4 zb!E-)g|yM1hQX?dje{yY5g+#f-)q*+a*$8&l)Y3Z6#Q)|#Qop_fkP1G&-3)?;L@yl zCpO!f0$O55!RfXA$*%`r6S_{5sY>Z2QG&{f=<9xx{q$sGyCs}IM2NT+H? zbqJ~Tk|Yr_LD2Z5Cy!Xu={0*xRrrgKSm&}NDuh4scHUpV*rz{C&k6}~qxFY)V7P|4 zyz(Q~os@#zt2Zhzy&IsYwkOQTV#KR3*xk-v;j{kEjc6^u66oQ^&6sBSLha~9G-Cb7 zx(L(_?K$oJB2G=YQ;43`O3;9T^9CR%@gZWefSV@-*+hZdNH`JuMfa%t?afp+Key(U zdQeiSNZu@#4TH)KV*>~(#s#JB3FkO+=6Xz=hp-Fqgk81Pn;DXF+?m%2=YyBq z27WUWueLl4*n&5j@|to{ww6bAMr5)|*$>D(_?D`=UZ(h<4F<|Hlc4+}e3-`>yXdTW zyRaNI3+e1U7Zyn+gkTE!=2Q?(Vo3HdC(YN#-?T@L_^)vCuwzRiZA$Sv_Tq(+ zly~GxXTplgv?#r$ik$4T*g;bSMRJ@GUX_AhW&ns(DZM$@)P5LfvAgC`dKnj50<^tS z`)nqwCxYx!o?4(4vi1w9reMx^rnHejIv6p11Pj!@OIuoH@ineR*qFfz-2lDQYY50L&T?ZR5`!+r))aTVuQVewH!e|7tlQ?ts;5yKy%Z zvsyk~$=CUGlFujF0wXnf^gz1b1hbP`7DT!A)Ec4PL&2PngyJ*PtqY$i??U(AVAPtV z+cQ>6<}=i5vnGWhGf)1)6B~+uE?`nu$`Waj7(b~%$M*^E@zq&kE{mF0bD)$FXye00l;CN&S$VuZ+%;Q#Tavhr z=0f&^!m3?2Vx*AlO6$+g(?#-QYPlh;zW6vF4wZ@6m@ltKZ)zxTobL%WA)T`65LmuB zGXbJ=*oXIpoq>Xv_g;7yY?Hk$i5z^?3s%!ofZbJNPv6Y5FVEr65bprSZJBRdO?^Y# zIbzj`rlD)iiAL4hDHpqT{x(;&ek_aq%6ggKw7DG%h|W;T7R;$ZEf;KN$|KRl7==G% zC^ZsZAJ@F{1?+F%CV}=4u*z(7NYwLXf93}5#qm3CJKEY#5WAO9xH**e?F-wIN4)SP zB{F`&YW>rCn^IVoYaV^F(&J|6nHIi7=5u89=jn)tcRmL)CXe_}`kl|F1{aPA$V-If zUMe(656q16$vJ$^18QfU0bJmGjs&Bx`~_VS(PzWuMd`8G z7XY2%>r_=RXUwZ^`>cIn7}*g(5-Y2?D~2N5LE1OemEB}K{wXOvmm;p zIICfo#TC0nenazkwVl6HGd$gNGjgtIdG9QjakJ>OG*a1_`x_QDW1pbzOfCqb5Md~u z<)B%F_LOO-sy`U^Rd{%F4Z~#x=@rEesaQ9#Vtx;7tnRbnl5YBNPdzZ(EA?WoUKQo()-tlH=)G?#S|oT7D8?=ny74aQZR~ z81#e3Zw=&^Z(i*}@Dc5EtbHnuqTEb$r%;^QTK!$x%pVP`b$!x10zJ(FnR`&xiOr3_ z?3vv0UKyK>ZcOl+=}HX}Da*Rq8ID?NQFCNAW!fRw0{k%pISy+$Ep=%Rti6`8%vk+M z+--X<3f`6N0TA*IzCC4`TI`ABShA>Llx{pF5c)ShLvOOZ#VE@gWTy9(EakRrgb>qN zOTR0?8NIBwT2tb|A4{7M&&62jHu!OHoWAQ$9!AN{$39W#SkC{|ue1l%yFhqz`Qebq zY3b)4!o$xOG*m_0S3oh3Drm;_UijlHtDCv}y$3XMjfG#w+;rzq`ewLi?_Q5Ned4jc*nGcJwwN!6w(z4@2X59DzIoqvsy?SQ@|~m(#O9oY*C)R( z+*XO^@2IoGE-rS-Og zYhlLx%g@G^vtpS?%`nb64_KbV-_l{+?71hN&!^`;mo4TkcS`;ke154urW_xgE>YLY8V-xM;5ApE*JM@FI@k zye8Fu+tNR7!ZeqvVeTcks@ho9(vHHaqT=UDMCo_^3mM;H10_3ShWebMR{XFC%lrqw zPo>8#C)hjWe|>4MMQ$?J@n=r>CrtmwuzVhBf+P}}wlC=KYShJU_BE$6ls+kN?fpx3XTM-CpDGRr+4YU8 z0*V1->#``MglikUw5eS)+H1(d>$a8byD;$e-f|y{hWmjc&>g$gSaSwzNY|GGgPqB@ ztweY974`Wv*6NV`47M#Sej|Dblt-5hNQPDElQnl>N~4pOm*FaJut3FsNPT1?DxM{i znu{2;PlyX0gO7yx9AkbpiiUEsdR09mr6jdug?{bjwPF75MGo;9o5ZZ?0qg|9B8i7d zytnp45tY?;j??V!;65m)A0MiI55i$G5vw+;6LS(7abc-t)(tKETa2_8m(YYC2meIu zYZDE7*`P1{qj@%(yCq`ZIz1A{9<;pqQDUrqK0TN_BHOFA`rx4(*x*5oS%&n9^oysf zU)Jes?B~4y`1qMXm3K?vW9g`w*^zr}mpWtrROb=~pXSX*38LT)+%+iC?Jj?0rtx7I`? zsMng)<3{!K1I@V3+xgd&2UHyWw&IkEyTp*P_pcF&^HiHu%=dzVh-enkuatG4oH_!F zU-v0|Jgn!4N=J9%+7vox%_~++KJ+k45Y=9kjL873><|p)wk%NC`6l91t`8g?)UkYu zfUW8zDL-BEAupHC6SyFSO#-;>aArx*bdwX`%XY&PeWb3@lT|H`jHX^LC(-)jo@hG` zV&uKSF{_moe=&Mhh01a6blr1RnNC-X51|^~X`|uBFui9O-VnkeB>drJoXy>13{#EU zD?#A;G4o8zbA;P!u77SN#;0tL35K*&LX!}_Q8iBLQ0q6{+g;V~O+A8Y-uVoL2A8jc ztvBj&p~R>YVcA36wXL)p#GQ<}^|ljlzLc^bjrXiU_Mr-FObV!zBRY-8LWHRnl=D1Q z@PG=7xqkn+ozYZX-!&QgBpWR)K%X~G ztg1~FZf!$XeTTZyUp+8CxP(Q}xaaan9gV1BIxg4K$7DqB=)%OCc-Fi4x=|=|eNxK5 zIhnAXGz>!9OWh?PpRN6|5FMhb=9o)vR|)yOS@&LHw=X4VigCsR81n)rVpkN+5XENtbM>mN@d*#nmzGIEq(sTtdy zrJN)2AL^VcE}h5_5NXjgKC$gyggp0D_L~UBDE1~NmhQMO@P>$<6<#EHlE zn`1(6-#c^ka+FXq-_87%PyP4>GYh8Nh)jQ^%Cv|JS;`Q5cI;yt8j3AZ>`c74f9MQx zj#@o*ttM^R=iWfL>3W+ox2RTvIZ-OcdAS!lPbD<}-HE(TJuF(OmsQ*)#Hz0i!}T4u zk8+a=L6p-jp=c~J=^*l+cZtadbu7kSMt1pajyiRHe}d8(ON0tepJtY=)h-?sd4Cnr z!@=u&`5`B%+k!ev$6?Eho_n$u&1VgpiLNE4=?8P^FEIhPRTYbBQWR8w2X&Udjn9l? zD*JXdM94LI6=T$dM#cE)r-|3wwp4_*EB3+0ksHL~U`md_0PYxEBesSZ^j#6>e@zzF zH6O|j$%k$~Obci5F*PBlF1-eMhPeHzYgVF3X#d(c*_14m#~xkoh@ zL@zzy`=ix&Wm#j}qai5u$RJW461Nhrai}c1H$dk~7Q4KsHh1KW`$g3kqWJ`J-qZxN zwbeWbyuj4=6Ua1pM=s~+83s9g!OL6^-&2M{@a0ruRW-D!u&OYyx~cH#H<@hY{Z*2s z8rU%{AlM6(_*STM{apX0^@2+%7rpHW&S!b6v9P&SpFz(NUOxMEVw5nsH)H2^nTILU z>$g6tmWf(TC0LPkhk)115b#QX#e1o7b-R_Dw9_RSTva0_t{Jd%)AmKq&I3ggN8^m5 zQm1dG*{`I{kEn&O6D=ESaNg-%vtrb#fHsd4d6zn$lFbe8^vKSvCU&mS4KP-=_;SOR zeCTuy-Q{Lzc_`wrmi$0fM?N5>(=jF|$3o@VCb|$mxDX?~=M*uJF zPhiOZR)r1II`d&OS!^V#Z2>qLjCU-3y_>S>`YC4Z<+rb&Xqhe4d7W9|(@!nTgW4z0 zzd%SV>w?Ktja@|m%jC`fS_-&NhrH$fBiI`j(I2L!#! z^Sq!gk$4h!+a_2$u#NAFi3=;3$Xh%Y<(07f1<4X8@|qtlC7FsNtuya8$oUB5$*wkS zR1pt$vL#nP9m+Rbm?t$uoYa>^A`OTsNEl0NFDwtss+`U6R(6P z#Vw-(xx{^4(fu8sQL*-YK+gX`@IHy@BaBrOtiq}iQ#Y<4zUz+7Jm1vO^Dfw$4_}CO z12(WY(j4{oZFTLQ&5?f=pIxNGBG#N%Dk6r0eS*h|u{j#?PTr2`)fMl!ARV$hXqlPm z@fKPJRqS)zqshk(5+b|qWfswz3n&eX8=lJEV6bzx1jA68SldbI(X(?Ugk#{iQ4;Y zw+?@x+9nsiN|J5P$Jr1W@!K&HGJ7#7EAj>colW+Ypkt5z7~N-aLw5(U_sb{J!%F|U-@+| z>K$Raa12zi)?r`ZCREEAbUlwH0P@_|sr|DBd06c3(|;J@jEpj|@kTp$)fa=bw+?pp z44{1tJ!g#D5+)o_tTliC&k=LnkX!T#1__juSCD6^jwJxS%`D3}IX10zmNJ`n#m8Wf z37f2^?aQ|LY(2~Y5R6RN!d3jGb)tfEXSzY82wnjG)qV3cRXmGuii+FW?w#PLEW*LQW3r5xIa}eFy*wLiv@Cp-${4z>e5b{J4yCe6i<^gHz znh0;*U!=zh+LUmU)gpC8JrJXgKrYs#=|#l4H$gP8*B`Y^Nh36^xBBS{i!CdHSl4qu z>I~i1k^?fO*y=y~z@cjU$C?);!*@+?Z=A~lwcvQKd2>ya-Io@?%CO{w*x>-AT*Chm z-X?z)Wl>=N`x)7J#;<$pZc@kbZfZPW ztYeGIlEz<;??(rzJmcZF>6h*dBlkZgIWv;kXlWZuND{%^p5w19kkxDThCq(s4B@@L zg&eOW`i^xfOZB^{r4sUY?(VbRaLXWGq%F#B8w;(2dijMiM08wJL_W(~M={3l%67z?euRfA*ydMf7PvY zJ(!;f@p>koJL%|!VQxBJ#Ybt6$wJvB)ir8UcvB5V>YV7}C1Cj6e zo&0q528o=ZxVVL$50|1$x4C(L>m^9`K2hadc^)%%M`GK%`=+8X8MgCy2ox_e2G~D( z98Y==0NR*=n!W4Fk+M#5AX6O^b$*#5|A4&ew(O;0mh&OrsN$p8J7CM$b27GiBGzXr&_W3^)#7o*GfXw@lwTrc+~K}qt58!psZ7Zz1@2GsP| znHM%X4Y`RYc027z=UL9{-*`>WeGu;DW@|1hUD>nXkUEW1uD~LAB&fl;UZ(Rk&gc}n zYZ24Pi=o@0Q{x-wwXrV#X<0s&wO*#2{1EYlLM zZAzmyRpENJEgSu$#TdxRA2YcGM z+JF(Wem^|E=vJ{~&I{@^#&m;MpVZtQA}KFf#+Z3&F-fgO=cQb{Xc;ARL<)n8Ab){l z;`ShVy#k4-EWvIj-o}PqGN8aB>TrI-h%_F7dnmFpfS1sIjeJ!zg7h%rIQszvduB{9dWW zQTlfZikyf5!0|HlU4pCMxouf|4#4r;GvZL|r3nEv3Slh1+U0W*5Ap1Y+O~6asY45` za%H_vUb3HKmvyz~Jt3YZtZWtb`*M5ljiS@Daw<3=^A2O&58iU5r# zz@mplhgJL@*Hk+qRn#fli!072ERB#JFchf1)R>E3e(We!h@r(D}7%gAz#a+|zEAzCbR9Rzc zm)#3D@-UT9<_C_^$%~G=k`9<#W>kAR8U@kQ1*j}WQ={(&ev%Wx{Mw*TE6oY0wD~$I z^=3%{`F}{e>bR!2_djr;6I3oJiXxy07?dC#!4vLb&rRW`F>Xvu-9>GkG8V*DL>(nm+0oi!|WP8J496Jf}5d2s1N$=?!ZgzTe8` zrs}pol3>-v+fYGQ3Z=8+dk$_yBiIBq3caCw768D>+w6Jv_E9j{dV&JmI4liQ>H`!; z#j{aY(&VL{^F^Frc>ey@tt|k2FUh?@r6ny}6%M1CE5fq)n4Q73k_&TMsNN=4hvyyC zQPRzt+^(s~Jn<5!+0;GvO?!nqPuFPov$ZOVW*9yYxfrN-S<;(AU;;bUYlMXXvO`md}dO2a0idPBGrdUU8NNI*Xqq*2t5 zTgG}CWS1Ek>T@G^<{C_X>AZvtQXsySh`U}ZicvBu5S}%dEOV=MmPk+5MkZuTdPiEP z?E1LthUpc-?wo<4>-CtKIK7bGUfGhFq_;6qQ-TI{OImpB%tu$#oZ;$>TD^=}`7Ku4 zng={ZFc*&1md)z4IyT`Kj+=Z@NhwsMPBE)cZ~A8(lCkS|6~gJ=FY23}ku@xF&CxZq&L+Ir=3%6=xacIQza}D%poz zx>%a#g%N?oWKo~NAQlzNUinGY=);Il-P`$&zJan($pn(fx`BS5yyi~??BdL;sikMK z?-x$jb}G7HseepOq1ddni?he2+c{)E}pELTd#d1 zvv%s|_&2C|rr|AU+ROyfmRUAgmBB+Va&8;+rv_B#+xqW<`S6{U1hf&*I=6*UCf_#e zmi8+V^6}ZD6ExoWO%K>)p)WHQdf)0z)p$7SC_Q6;ih4;-5bu(}^Jy@3zW7BoCvw** zRi*t8Zx2L4%t9j1Y9$`83BBAYW1f6#S`3|OXcuTaUw56=M;XO0G&IV1X!{uaX#RLI zk)28-%k_e3+!v!qqw;DGYjca^ZylMcpPzHa%gM-)<8)s>)Q>VVcqs##$T*L2rZ%QB za)=dA>t{3wNk;pO4Mq4^y%pJm_CiaG<0p$E91Q(q;~%~u(2BcCLKZUX`^V&u#?soX z_+h&cW>2n@*Wq{pYx`TAr zI)70VQC`VKi&)q80!d$6eGE(|g zY6cWseBMkq5ZfjWA)hIq71oA`Q|_ok2rt6RihC})CJ!_x`$}ko_99&Ba1n4v%TwuJ@>a zoT*9DHPfoGa#Oh7JXs3vt5*{jG)U=R&ZO8D4+YN_bf%b6KP~t!xGvT9P4rs+93W9L zK* zi}#_d7a|3>rIcS**5iFxWK(dqLGly4gHXO8kP?+Q%S3&O1Olr{ZztokDW*fzh@{z3 zaO>7oS;?lj3j~*$F=!=gk1Ai5mG*InbNriu%bws`Ptq^kC*Ri<-3>Y6#vP{rz}#v@RxHpV5sgfkMj8hiGP0X)a$4GXpIOPgi78lPI1 zT&>nMd2sVo=UE~&<8@=!c$|2CVN!}Znhdebo@o@qAH>@ocETTQC{zU9);AN#p6=xJ`HFxkKQb)#3 z7xXh`gTyhX#@j~SGm@Bsd0)hr+b0w>i!Qv8tPRvgx8*Jf9f`W#c_l<*M;v*?E&l1K zX`*gs#f$3OlW9bJb4f=LYqjcgTL}ZS?qp!;2*v1Q^(dD}N6t)Hpsfm^DRL_j|WCs~iu3Js2)Zh#E>we`j$GrZ4DP4SUGP9ECY=a7-zK z18Okd6?^%mLwp%uyTQ#HX_e6%&6f;bMi%YtvDzsj^+Z2I24}!=1m{EC;nEG>8i2e& zfVLdM7+(lG#pq0n~bh^|3q{ z`6?~t&6TBxQJ=c!XNRPk{BLtsLX4mIO9T6vmLb4OUB<}+?p%VLYj)Oi-3$?nZd!*C zz~uA{f=+f;uwF^0c8GrHeNHK{QIi98nZezxED*0d8qd;x;n%)r>G8UQfKqQeM*w&@ zzK$7I#&Hbmq8ylwhSat$7JPw(vbGfiX2Rsf*Anri>j2c`PfJ+vsOKJn`$S zsoWC?Ek(H-AJ0}`y1KepXMM`t>9uJTh@yKv`LcOz2#KxIpr&F-2E9@MiB?QX3d7}n z>C&TN2^krE&`YNxfOpjQc~FMVQZL{PP=f_&b?dD8 zCcx$&>h7?f9*5=zyGsZg&%-yz&T%97hH38MY`fu&3G3DB>;z2EaY9&Nz1~o zTc!jhsm-%bs?dnmeWv!RI>?{dO6xtL@U5DjpnPw@i9WpY6ND#9OZw>)nsc$b} zmIa+6Uhr|LZ$3*-NKTVH2Kju2oKke&f%99HPa7J?;!CcZb&Y^8blfPLeXcA7TJdF` zF`GPjU?Kjq>10Nq=}$F~K{N@9Dk_=)_E`_*{rvd2O`Ym@$G5|TCvtX5yu+hJi`R&H z4#0AUzTQ}>AIx=HI71eI_voXIK|YU7w7%(gp+NnfGOv=^RYW2iukB~T93pS(;svt3 z)|~xSxm`bV5nyA4SbQ-L=x?#{@z%%v$gjRs9$687#0z>d$HAQ7v*a8(6*^RQK=bkz zn}x&nWln#ovz@RG-_-B$v!-lNhzU^eBmeUFrUNPTgE)EnQ$KerzN&x`a+T8mcotm! z%IU}oHfh!G{i|?*kl+*a{E~<|#Gx%wcHN3-{=0&Hw?2RQfXLzjY{+fse3_rw`_-S1 zdd7N&Ml4o$u4j(=op*1a*AaTaSWAPHUekz0tYMdRSkBBKkI>8x_-q*m;@XPCX@zv#F zRdM^O+6Azhp_Cj$=LDdFJb-yi&f$l@2R?%=nnURHuZW0o$^La{=0lhca6{me0a z`_3){&|BJ~AK=x2Z6B*4pnhMmlm^vlC-3t9V|<3-S{kW9LD$O;YAY0i8Do|f{(VVg z(Nh95+vqqme&3Y(p*%J$=a3$6<@ndM5;Jr26JRmiYg$Yk%?pDj0}JZo6Z4#Cf$ zt9cm9;M|~k=GsomfQJqRqA!fWz?Ze`GCh47C7K^n3JKF*g8-T-d^PRglfqw6gunbO zGs~Gd5p6KUWj#dy=dk*#`^L`Ww9u3eHPhm%_WMSIC-<%&WN@#N&T^UsPMtO~VOlwR zw0hTEZ0FVOtOiPlt{&}jd%YKi7CoqxoH%=09edE4$gVWQ6 z%zi^BFuyfG?3*9?sH?&c-s}@D?5wX$>;Qxo@ms!B*f`eH)s*I?^dSh#u z)iNz4did};R;YCM>>mez-{%8i;oW`)Vy0p}tnle?&hys<_M@ShhevtZAxN&h*tXw~ zs{BxMz_*1o8)*JT34U!QJW44d2y@W3s%v|s${L&Yu>+VSN^iu2=@(YYHAxG33sB? z*P;Q#Km$}C&^ZjZ%l`YT|NEvdF{x>4MnmZ|NWORD*03Hw)N=+_NX*`KgU_E9Y5wJX zfA#EfdqT&3570yKh-U|X_5c1wKz7_w$_EuA&O3#QfBEaL?i5fcu*>X9bbj9cYf`J4 zJ)wiht#p1vEuCu_#2Az62duDv+FI_~P8|qk_G@cv6N7}X>i4eU$j#2uaX{8bI&rS$ zm=Gucg}+t=3`Gb^CwwidF++exzhOM6I)tGE&l;A*BYFeWi=Gt*4CFJe!MQ*X2%1fg zzsvyHtoCs&NxP^l9i89ff)24Yywr{}Jo+FP*n9%dvla^|i_pp7gE-u%G~oaL@#!xe z+)bvp5b4rH-Zktl>dd#m=FiMiYk3U)*T9BhPA1~t?c~3{AhWRhlnKIFp1BsO zLD5557X?6y?YH^&%X)P5k6F*KqdK4O#H^+8z#|$1tj&u)&NYl3gq}JG_(ekN2G87< zSc}nO+4;V=9hVS-t3a&wsctrhB;2zH@g4u7~pv|0PDI&o)Z zJvDnoL5I|Aqq6f;&^v&ADS0iS_Fc}ehb)6=*f5tP2ZWG-Oj_A{Z&-qi(=$#*uTsz_ zv@mD>;4i~AQ2jz6Y@ubuZmzx|r@n=Cf^-NlK10&7?BXlNZfXn<*r|3rCreqhS@dHde`{Ci6=*M^zt4R8Zh~GzNF0v@$LuE>WOTS z)~b-6s%dCMf$x^gHjzHe&y3N=7^+7)k9ETKCv0j^q-n%{8ql@Qnb1>Y-85#@>loZ{ zf9#AeRY^9dyUYY%-mm$mcb_07Ot7vB%*cdV_h> zK_@roCGZa*E!g$S-Z<@w;Slr^_9N6z>BzISZs4G zJKXNpr#db0?lh8nccr@%p?kEVGu%L0O+fNhHgku__KDKVQ$~HdtKtusftIdiIKj;Ff{W;!{!1 zFI=(SCEdyHMF2b4H1C(?*KSQnH<$X}PxpC14R z?+E((;u;R0ji2c( zSmnwaRmuSBF(swn>XQi1Q#^sG_Z3K8Lilh2LGwHbxciiq*#0ZM0AL$$h5}8Ir93|ekS4#91|OyuYjRQCB_ww!S(85Wt4pt zHX#5Kh)?O4wNpZva4-;;_H5bvc9SYOVRSYON^b|+YoZ1?e=HZ|?to66&CY~BHQy}4 zL74;t4D-FnQ>4#g@QAX9?M<8}CIV)nV_JuFGOuC`twhA4IpR&8Dnf)__~scGSg7Zu z7q66g|KhNB1S*9u5pY$*Ak@EYDDYMJQRn|SlRJ>Eoe^jDXI});l`ug1U}pE4FmvLa zog!?fS{b2wA&v)S=PX+?axF){^egcS#Y0~f(B4>3H#htF)s|@Wc*%bD#pq(Tt+d%C zxVY$9naP*8ncUL^=@ESi5xdI5j!H{8j}X;l0M&l)j>J7bdQ|3vXSo$)hr+)Q9^T

Zk3*pIvY)+2^X(XeCg5J&Mfs_u&22Z46^o=y5QqZ3jO5+W)ZM} zh@JA%@fVkR6I158>yPEYugTdqc4(FyZa+M52ovq4LCy{hBWzgm+VTl^Y1a=<43)TD z8X#OfS!hF7!R%05B!RTo$rUtVw#PIaublUeF~`+1#+o)rv&+`%+)vJ+UTow=-)QhM z;PTVqPM2_^HqJU{GR10U+A=!@+vB9Ge&p4c$}x!5Mki}>)A_n4-8{DCxU*rEqPdd{^h&jfKZc>!Ab&76 z&!)e8rdXg37XxS~5`gCu#uJ+G3b@fYTflI%56RMes9r(q%b9=jsm1`l;Tn5-n-97| zx2~(zhkoDKT&oXru}ya?`c%i5TQ5!h2VD@0yOChxQ~__SB~hvw#lA(jDBb7&F^G!K)<=})gkLN zq8l*4HuP9AWR%b7PR-6cV#wlaZO<%(bGa}Rvph~VMbvXmyq)BiK_!Zuhpg3rve+$b z%@5JNd0>cbtTB!6ZN6ch{MF8d^Eug0Pfd(-R6P4}gXfV>3PMA3U>5OC!p_BL8BAlU zMYgz8{EuZiR4e=QSrsOTQ4e)8MH106=I7jLB+bk}oqgFA@9&oDEKchs%1z(}E;oeR5Y2UN)8g&92r`w8Q`&SS4nm~8P_s>>@%?lTIHzg<2PK3D_n zyoA*Fa9p2$)XNz@%v%H5n{;E6$RDgelpU$$?WcPx&aavr0fGxDIy?Q-pKJtd+sQ?l zGs737#PJv)$U{@%J{3*e!sa1aBzU^}YqUhBRn(VfSOeLD*^Z*h_D?!um?$zjHYBaL z%p`JsSd$Tcj8m2CNi5Gxw0mpegUo<#E<$GXYQxI+@<3XU>sI1~80gfEcEO!41GlhQ zW6i*Ia$*0c%nxJ=a#w(Qx;&2BZE=56icMc*sqXnvPpYk|d*>@44t&8R_ z#E<&8vsziEoSqPv*jLIEyEvNX9(RrXpc92qNz@RpktY{+{;AxwL9f?$?)@F>@FoHn zQYcAx*FD^+VXqVW%?t3rcb|BN8Xs9_bd>WceTfRFq=f;9Ug&7i0bdNU#8Z(^69Q%f zgh4(>6ebQ%FHWGbV;+sU+3+%-XT$Rm@u7}F_3j<St zZXS?p5XE(!lDHo;lRbYnH{mj;QwW%WY?pit*}e7ha!*pse5+kgGoV)u#gpHbzS-xL zQbcgEq|QDvs44HP`_j!dR$6Or!ScS*rE(R+HOn9-(m~z*ezy9K_zK`5NGpYL=*l}0 zsUgg)xLlUhCjq~Qx{0y1!``E~YmZ=l4KL07A>1AxAKGbG*fsc@tFYUJKNSf~E^0Tc z5+==~>lmUVMtQ9B{APM;);(U&V}RTu;u)*gRHmP(>tBfK;nA$U_{Q3y#6+WzjhzWg#vDq7lTVrW0jRhrUPQ-#@q}qmJP}%i<}m zosAIG-F=}##B0t={JoAw{&eECQ9LD?YY;M;?H9S^Mxgn?>OMP zB0$^X!kbjbMKFaA-hZ8lye6&@yKZUl=9ajbT)Qp%GS9Yj~Sw}l_n?bg!z{<2tRD^t;YaX|)SVFK!9-lUFFcAkitt?Fd6HeSVqMTPh=`>Em!T%LUkvv#w;eQ72HGau6# z4L@B_8Yg(_W`v+L|C|t0uKo>mGt(Tu>K-3|ep;B1B`x-sN%vX5JIoZ`uY%75NzS;= zNK|T*OR?|FXvZ@jc6Cd}?Jkn-u`?pIH<%r|0u$AqV&}@} z=2|S>IHs8`RF(ZlA|}!E(|lOwOLA<+zR&h8gl$emw(uVV5jQBi>>Z5EtZwfpr+a6Z zY{7{0WW$*J2{Dd|Ry6SJJr#F~0>rc3Uz1RH@?N|V{)4PIkBc?`0-NBDj8X9d6MS4} zqjzj`rnUFA$Gvz7;ts-(7Jkwg(WnZ8RJy`VEx$#-f?^1CY8q+d+YC**roE#nf$lJ_ zzG`nzcUoj}`>i<@aE@HD6MPP$h`ai4)k04USYAI2PrQO#D9_RTeA2Sza!G0}ZVoM5 zR2B4)wCxobG1_iiK$)CQDteSiJA@YKJpoTEONYK(J;wqSIHvHniLdO|WUp8=|$$Lgst(P5X&fMOhcodBN6P*IP96lbk{bQDr#={f(z_FJfe#5lhjs z{falskxp4cPTp0W9ai3}h|#1i!oqHHK=GvI>2EhWdh+zn2oWZqe)>Ja#^vpsD?dga zNW&H=iz+1v&%Zm(9SOZLTtgKyEN=90^WO_{umR|XcE1Y!Ej!xKXtRiJb`{IbsUFRJ zlgrUWpKz#kTMC_DnMJ#Rk86c;s`$F`2?gIc=g%5OzBSI?pDJ-!FePKxQH-s`*~4-b z3~wzx^C!`y#P^`>x?pX{Zfp7lHkO$6n;LcCwg>;dHFWfW7kKC{Gu3Ux$Z&TG&1H&z z%#2pr1j)4Rz@{NvBof}p-q#b7Z7wp+Ajh=(EUr@0ZaHw4+e>7fS?ax&E-s*oI2=HQ z>O8q&sMSO=?^msBT69vlQj{iL>r2xfR;`#fZ??b}bFBkX(EMTgBC-DG^WVln5J7x_ zF*9|K$gJ*zC1dJv;hYk#(%1cY02}hUZ^_+ok$w}Xmm0pX%Uc20GE$wQ> zl{bGQ$r`Rxq=CO)B(#cfY?wY2>N!8f3&}M-JhNi6nOLNqN41=WyyM=|e{2jpiQ4H^ z0&?`&iuE4JW;b`sxkLbeoJ0N)efu3~7vyR?1{#7-P;|2lw86ZSeu>_*n@)Y~d3#sV zg;B%&oWbDByD1W?eyA{ZJuualO_1xBQGw&`k0tF8(qfgy;G9=|VkISrI3E^Y5XN_1 zvHO~}&YK{oJ$%^ptSzy-DsgSpWAitDtoEWlGvrrClvVVNhhvE_NF%37qWx&GM&vt^ zxT_ZC&(VaAQe4;Mu>7T^ebx|*qWT1@oUrES9xhy%jOvLWr3`Ap_Ey0xtNUQrik9%? zIv~u?r@#24ZoK6BP)+Yn1=mTV0<(BQ_^XW&H38V`=SO|@ugZgAzP8?$$JsTkyYsK8 zVnE>_=jgqnNogOvs2}7!%E>$BbR&k_HLLjqK~)KVHo` z;GtrgTHIkVfFO%G8dgMjwFPd&nB@F?J-1ixn6mj~I$GH|BUIv199=G2KiE2CLIcgK z6PVzHmf|BmDu^tfjF#=NDxN3(SkYmLQRg9^r-xXw<=_8SDbIx<1pSkwuRo&ICA|y0 z*|o<$m|3<-D1EM8m>lEq!sz=d=CHLyXZjo{`+_t~V=C^B7WC{_Vb>*|=$1QY)iMl5 z==KJ-i`PDI3Uu9M6Vn`SZ&^G-Gbd4xl<>iDZm-WT5~Nu8KFa#KUI4>QD;P_gN8D0# zXlm1Lw&?a+5K~~nr+JRR+=VT?2D+De+c)DcsCuh-dJ|SiO8>jQM)mWCN+g$ugu6dO zJ3p|qybel?j$mZWdHgLgOuLNk5n>G5Jq_)x@0oV=mOefmaW_poM5g#6$jT(jO~$Sy z;^jeGO@T3YfwTF#5R1$VZN&`G5t6h@n90+UqlCj#Zmicso=*ENNi7?O8`>L#-1J2o zADJdq#+~da_lse81L|xkiN#T+;%}6Vs8Za6fD-x74 z94=X{)rZFS!wfwQ{-=3qN}00Kw3r z`+!*+Ny|T+++fEVJhZs(#gr8qTQ#gQLFORHu&4Vzv)61%U>trJNi=H|va=?ukO z-qk68sV14Inr3amLA`umq0=UQ3?93sAJBv^Czn;vLz*&m-y9^`7nx^Eym;_q9RY&4 zz0rI?88Ucm+wN}$sIP#2<`j8xQcxV*490ns308I{_o1+3FSZcn^pllFkAly*Gcv_g*mixOWKBgdV;?8;eSYi8iGfQ`;ZFf6d+VbE>06& zeI+YEP-bBwVlj4T!6L-f2ooK{ci~d@Lfup}WWkPa3-s-bAeOs4lAL7Ua|Tie0=7t0j`>LuEb+z6m6_vioa+Y zE3OisICdiTf~sh5;~=u9BP3Og$*%!b*U&DE5@=K_S+ulggpBe30Czd57FWiR7X>*{E|_?*#+gUt4K47nKXJh*?|z zC|sy2fl!$gxpRPH+jgTDYlBVP@lbKax~M9pSoEqEKlRyu>2ytpDEzPY$u1vZ8-H(7|LI9anlzd_SBLX198SrQa~NEUzm5mf8e zuEJ|=t@76`S2>VDVHO%99w2JQYhLxYyN zHl$uj_^&Vj^BLss1CWtuK|gv(^y}J*eQR6KXVZHSRK*CJxW*5e=1*+@*8|Zz4-g5_ z?X?r;zrPl6nYKk#GVBZjsPtbNNPJQx(21n|H>%{TbfRkUc>&X(8Ny+K(ZhX=X_)t z*8uHO)!}*J3lx34mhgHFihh`BACsB&;Vms|;0pVp&TnOblx~GPq96g&mK0TYAN1{cXhUTecwzx-GS!iG#!BxOJ*c2APBKQ)Z*EM$=7oWwWn@;W%k z6ypo~<)s#O8r4EWSgT}ogwZ)%eYA7$e;@2WC@dZQah4b` z^_PakJZ2d8lfL)I1=0Qz0H#KvB058R+L-?;nZNp)qEK4Q^K2WP-*HqsbPZ41Q4B(! zi-A@v)y?18B*C-G`XJ2m?)_Tyq3dgWkbAD^d+qQyRuiy?XWgLa)}o*5@ca*lv>#wv z`PL1xD6AO3f0T@Wd*Oh+EmlQP$mWyhdH?Ne|8e$aXJ|g~3UKU@!BBaLwGjOR_J$6^ zfyg{;->?>u$p*xv;(*>Ko&T}&@1}0G51^n1Jn8e4p|x0v4bZQoLqrDuS{~!iV8CQ| zbS*vZ{7`2ZfSGZ8E@ZWaMjIg43th(MS2FuCUAiH<#zR_W9cE{&<(N=sp+JCdpIegv zyV2Lt?}s?JB^j*A2LAzUFbhO_t8(yfY2#O6MeKp?n-e+7h}wg&3RqqHe@d#EkJC8c z`!+Z@?g+kia}5t-*%6{d54ivkwIQiGKlRhAzdbmquqBa`kioOk6313kxStfJ0D(o?J5obp2fo&XryOR6eE@2#Vo?)f!f|fmsveYX`z#S)W(^Zcnub$@pXu z_YW^Y@0EJcNpuWXF*#ey?P~<4J0B)oC-jvS6dDkHJ73>s+Fn0AY_4DBF;ls~iKEla zHadVuCmu@nno@2XzqjpBJ%C9z1d3Ga0r;v37#OY11v)ujbV*x*yZ`hV_wn;UK1;Ih zS~*On?b068S7Sl<12DTCnXwMS7CQTqNu+VtaJOZ$Ej>rMbl=-OsVCSWL&)S1)?XoZyg~}DTD?9H&yZ9%f_-F z@|k_F{mO5C-=BZ~u;UTP(r`)Bu0IzE0?X7y74m;iEYAZ{3H}QopY*95AJ2lc^y=}Ft_SJ><+n$O_0v=}V zsVv@a5{K#+$OX5~Q;)fqp64J0E)0U6-tlH-G?cVs<48kv1HjPQcS{nR(1~&lo`fol z%>dYj#{P9kLMowW?)|GfV+~VP1n(SkPVt)@z1u2(HDp8Gg~pBhX6gI^k=|?8v_f^6 zWI%K_i3C}9X2ue=Xq*Em_34L!D$j=D;YFl{&uj(OHpCdPKfu{EBzT8BqOm>VEZ9&n zekYb;pTBZAuE%)(R0BOOsB#5_*H>p&iraeo=tDl~}Q3kNS z0B_!WXa~T$!v&EG{e=2=k59*&z3k}#0uvAB+0M5{*MnmE81CUBr6b2jyVbs47dhXN z59k)XJ?f$#nnAa4M{x0g^P+qZp*(`ARc3t%+Jwn56iQ*i#_sccytTBue}uA9XOTT+<;wd!bWIk==8UG z6(`F&r+1Tr?Y$o73?jAAG1g}0mLw$fJ>OMFi!uPs^1R@`-ntBQj;-)%dL8WzOrf=X zjBmys|T0u31j#yzP!==rZ>8;?we()%p* zVv{=XKvvXs%Axn428(#TXSy=hnRVq=z$U&}JnNacJMhJauvX76Z?-pV@%eo7e4Au* zj{~<{c;qConjYfl4BZ^b7uI#3byep965owT0(2MQvT*$Kn6^Wi1?P(F~<6}m_yY_ zC@4JzCxyHwCbW4>+(vf#R~xlQ1t~cZ$YC;u0xL~TV(y@5ov&V0N6@~QEH<^k6I z#Q?X?KR1>NU%Dm(a1?Bnv#;4S8{;Gh!*$^kYVM{BJ(&8(_Z54%&e6Yf^vdWs2$Qe8 z@#%cqq-X(zKSk)pHA2;_i8B97=#n>um~21qPSc}2n(bKDko(rz+v|4d-6U|i4?k#) zJs^VDYW~udcX!bT7cU<+lEXOnl)5NKuG92sh2G}>EDAU@+TX?ICqIaqBKk}R;s{4aS8hzA{FU-M z_yUdUhwd+vsuZZu3hyt0rZxloLx%qEEDqJp>#F9zaXtiV?X7UNCx$B(UW_(BpcZPX z;!g>iAv}#Xu@dVXX?UN!)SVm&T+nR4Z9btxOc!O8C6$TYE^M^FE+Qt?zFA()5_35P&E_tde3!q^Tl#m0{69w}`W%%!d5pV|p?0PGKY0`ZfXPQJi!Qyn zmk%aKC0Uk&v5Wjyg||uCbhQ+ixa?yyqOWBYoC7X9Z=bXcm9oUgF=>UXgyt&Dv|lJF zE(lG8O{%6C<+t|(OyXj#@8ao-GH9V~Phr}UPxf{&ManiG_G|#~K4`WWFKd2vAqT`l zCT{ObfV=5l@~m&Y^uz1tPKEQ z&4@c(9?vhU9sq0;!DV^Q@tMgWkrIyQZ$YP4E|GfGMK6bNxRQ{jiyyX+jCU6_Ik26O z!R9sNV zR>^?XW*Vgwqljx8@EWZKbL>YzcmJk69J5kLaub$xXc$T{-eZ+p74X%^|nxzl`@Pe^y=DAK-6(LgB zFHM#`v?t0H=zPfT<9W4lX0J@C^OzCZOa{QT9hpT^z1^qk1mcIP=R0y-6nsL1MUab* z%7YhG{AXKD(Y!|yzB9VM+EF5=ik1cT)ntnc0-BL$b`9<4AU69_h|e;hoQg}+ZCAQD zcGh0!n*X2ruHyPvNqv;y^kt@=@@WS19KkgBEbadzPA-=Sp^zlt!SQctA<2N-P%sV; z9Erl%m0A&Ba>LXX>gO#Z$y9Q3MW<>2lHi4x)`C^Fx9uPKu6Cebyng~dX z9`!GXT(^F6p{p-WJoy?jY2swHTW6RVAUnnEBbqiD%yl>W6w6P&<@J`z3k9Ie6DNN$ zy4}F6&og_z0U~X#)%4B!&IX`xP4NvN!;BA?0RaS=7X5@Zx)$vdA5;~o(#jX%LpT7+ zUQR^?MWd!_XHe8-ON+S*5MQxe28bBbM+5{W35#x6NE^Q?@}-dcPNb z0Se>S%QaL6MvbUZa42>oexpaG?F~|7(4TcYZh%$oatdjX(@TJwae)xKd)pA09wG^_ z`gU*tMXY!ldwbej_4vTgnyi&X)~t~}{PLux>x$e}oEoIXO3Epw`7?Yi%ZZ<|PPO?$ zg~yE5f;=rhO>+D2Cym@qK`9^VTe_|hlMcoHppg}!tyjvXuq33#RM1>yh& zWU?jVA8BEO2%usjp9Vwg6o7#kDZ?jO`$O3T=PxQ44Hbmy-XleT z^2q-&+pwYzHw%&>i3*TBnwq$eME0idmUqkTj=HWm|M79j1fgh8?3STvn)upwXG}Iu z0E|(5*|pADa#*iEuFW;4IjdL-o7XNt^RrmU+;HnnR%}`OwjkXOswlTbAOO zureF;Ivq|5GyV+RsQPD9#WwRLFjLc5KRua%Shv2O=6M6A2$V^}PAs`R{VQ5BV2=YJ zc2C`>&fQlJ7%(R{y@JdixXFdl>>XWAY#r>GjKFkqnHQNH0{~?e{K;{AT0r4Wg-!Pf zeWZoHeo6Vls|%i7(t{z}O{&g1^7ai(9BP=%I>c!6=HlN2EJQB@P!gAgn!`5AmtrI8 za7fDc8oFqPQc^-_3UZP8@sld(!pLc|R*J>Z;jecGlZ7Z+Z2=J1#m7N)X`Tz6QajU+ zxcB!TprcncNf95kY6uv)GE@I&wHn&A`W)K0@|>N9d*p6Iod`6j~7W< znm7BZ7vIL^f2qFW&7JY#!`4zq+w{e8UlFuSXQA2Ip-^3lkcK~Ep%0A;7D>LD9OQE2P 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 v=ZPRH@8rV`XS4N|^e=io>>Hn2)6K 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

  • jn0D-5o{RGAeCM0hJy`?-_POnE{5ziZs-I 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 s{0;2zk+)j~4%jkKE$#zc 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

    xm&4abeqzu3zvCW=VJJ8idx-HrVG_{FEb$eS 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

    31|C-!-VlfX7lKby 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 + +--- + +Crane (FinOps Crane) is a cloud native open source project which manages cloud resources on Kubernetes stack, it is inspired by FinOps concepts. + +## Introduction + +The goal of Crane is to provide a one-stop-shop project to help Kubernetes users to save cloud resource usage with a rich set of functionalities: + +- **Time Series Prediction** based on monitoring data +- **Usage and Cost visibility** +- **Usage & Cost Optimization** including: + - R2 (Resource Re-allocation) + - R3 (Request & Replicas Recommendation) + - Effective Pod Autoscaling (Effective Horizontal & Vertical Pod Autoscaling) + - Cost Optimization +- **Enhanced QoS** based on Pod PriorityClass + +![Crane Overview](images/crane-overview.png) + +## Features +### Time Series Prediction + +TimeSeriesPrediction defines metric spec to predict kubernetes resources like Pod or Node. +The prediction module is the core component that other crane components relied on, like [EHPA](#effective-horizontalpodautoscaler) and [Analytics](#analytics). + +Please see [this document](tutorials/using-time-series-prediction.md) to learn more. + +### Effective HorizontalPodAutoscaler + +EffectiveHorizontalPodAutoscaler helps you manage application scaling in an easy way. It is compatible with native [HorizontalPodAutoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) but extends more features like prediction-driven autoscaling. + +Please see [this document](tutorials/using-effective-hpa-to-scaling-with-effectiveness.md) to learn more. + +### Analytics + +Analytics model analyzes the workload and provide recommendations about resource optimize. + +Two Recommendations are currently supported: + +- **ResourceRecommend**: Recommend container requests & limit resources based on historic metrics. +- **Effective HPARecommend**: Recommend which workloads are suitable for autoscaling and provide optimized configurations such as minReplicas, maxReplicas. + +### QoS Ensurance +Kubernetes is capable of starting multiple pods on same node, and as a result, some of the user applications may be impacted when there are resources(e.g. cpu) consumption competition. To mitigate this, Crane allows users defining PrioirtyClass for the pods and QoSEnsurancePolicy, and then detects disruption and ensure the high priority pods not being impacted by resource competition. + +Avoidance Actions: + +- **Disable Schedule**: disable scheduling by setting node taint and condition +- **Throttle**: throttle the low priority pods by squeezing cgroup settings +- **Evict**: evict low priority pods + +Please see [this document](tutorials/using-qos-ensurance.md) to learn more. + +## Repositories + +Crane is composed of the following components: + +- [craned](https://github.com/gocrane/crane/tree/main/cmd/craned) - main crane control plane. + - **Predictor** - Predicts resources metrics trends based on historical data. + - **AnalyticsController** - Analyzes resources and generate related recommendations. + - **RecommendationController** - Recommend Pod resource requests and autoscaler. + - **ClusterNodePredictionController** - Create Predictor for nodes. + - **EffectiveHPAController** - Effective HPA for horizontal scaling. + - **EffectiveHPAController** - Effective VPA for vertical scaling. +- [metric-adaptor](https://github.com/gocrane/crane/tree/main/cmd/metric-adapter) - Metric server for driving the scaling. +- [crane-agent](https://github.com/gocrane/crane/tree/main/cmd/crane-agent) - Ensure critical workloads SLO based on abnormally detection. +- [gocrane/api](https://github.com/gocrane/api) - This repository defines component-level APIs for the Crane platform. +- [gocrane/fadvisor](https://github.com/gocrane/fadvisor) - Financial advisor which collect resource prices from cloud API. + diff --git a/docs/index.zh.md b/docs/index.zh.md new file mode 100644 index 000000000..9c3aea1ee --- /dev/null +++ b/docs/index.zh.md @@ -0,0 +1,78 @@ +# Crane: Cloud Resource Analytics and Economics + +[![Go Report Card](https://goreportcard.com/badge/github.com/gocrane/crane)](https://goreportcard.com/report/github.com/gocrane/crane) +[![GoDoc](https://godoc.org/github.com/gocrane/crane?status.svg)](https://godoc.org/github.com/gocrane/crane) +[![License](https://img.shields.io/github/license/gocrane/crane)](https://www.apache.org/licenses/LICENSE-2.0.html) +![GoVersion](https://img.shields.io/github/go-mod/go-version/gocrane/crane) + +Crane logo + +--- + +Crane(FinOps Crane)是一个云原生开源项目,它管理Kubernetes上的云资源,其灵感来自FinOps理念。 + +## 介绍 + +The goal of Crane is to provide a one-stop-shop project to help Kubernetes users to save cloud resource usage with a rich set of functionalities: + +- **Time Series Prediction** based on monitoring data +- **Usage and Cost visibility** +- **Usage & Cost Optimization** including: + - R2 (Resource Re-allocation) + - R3 (Request & Replicas Recommendation) + - Effective Pod Autoscaling (Effective Horizontal & Vertical Pod Autoscaling) + - Cost Optimization +- **Enhanced QoS** based on Pod PriorityClass + +![Crane Overview](images/crane-overview.png) + +## Features +### Time Series Prediction + +TimeSeriesPrediction defines metric spec to predict kubernetes resources like Pod or Node. +The prediction module is the core component that other crane components relied on, like [EHPA](#effective-horizontalpodautoscaler) and [Analytics](#analytics). + +Please see [this document](tutorials/using-time-series-prediction.md) to learn more. + +### Effective HorizontalPodAutoscaler + +EffectiveHorizontalPodAutoscaler helps you manage application scaling in an easy way. It is compatible with native [HorizontalPodAutoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) but extends more features like prediction-driven autoscaling. + +Please see [this document](tutorials/using-effective-hpa-to-scaling-with-effectiveness.md) to learn more. + +### Analytics + +Analytics model analyzes the workload and provide recommendations about resource optimize. + +Two Recommendations are currently supported: + +- **ResourceRecommend**: Recommend container requests & limit resources based on historic metrics. +- **Effective HPARecommend**: Recommend which workloads are suitable for autoscaling and provide optimized configurations such as minReplicas, maxReplicas. + +### QoS Ensurance +Kubernetes is capable of starting multiple pods on same node, and as a result, some of the user applications may be impacted when there are resources(e.g. cpu) consumption competition. To mitigate this, Crane allows users defining PrioirtyClass for the pods and QoSEnsurancePolicy, and then detects disruption and ensure the high priority pods not being impacted by resource competition. + +Avoidance Actions: + +- **Disable Schedule**: disable scheduling by setting node taint and condition +- **Throttle**: throttle the low priority pods by squeezing cgroup settings +- **Evict**: evict low priority pods + +Please see [this document](tutorials/using-qos-ensurance.md) to learn more. + +## Repositories + +Crane is composed of the following components: + +- [craned](https://github.com/gocrane/crane/tree/main/cmd/craned) - main crane control plane. + - **Predictor** - Predicts resources metrics trends based on historical data. + - **AnalyticsController** - Analyzes resources and generate related recommendations. + - **RecommendationController** - Recommend Pod resource requests and autoscaler. + - **ClusterNodePredictionController** - Create Predictor for nodes. + - **EffectiveHPAController** - Effective HPA for horizontal scaling. + - **EffectiveHPAController** - Effective VPA for vertical scaling. +- [metric-adaptor](https://github.com/gocrane/crane/tree/main/cmd/metric-adapter) - Metric server for driving the scaling. +- [crane-agent](https://github.com/gocrane/crane/tree/main/cmd/crane-agent) - Ensure critical workloads SLO based on abnormally detection. +- [gocrane/api](https://github.com/gocrane/api) - This repository defines component-level APIs for the Crane platform. +- [gocrane/fadvisor](https://github.com/gocrane/fadvisor) - Financial advisor which collect resource prices from cloud API. + diff --git a/docs/proposals/20220228-advanced-cpuset-manger.md b/docs/proposals/20220228-advanced-cpuset-manger.md index a0578fb33..c60b576ae 100644 --- a/docs/proposals/20220228-advanced-cpuset-manger.md +++ b/docs/proposals/20220228-advanced-cpuset-manger.md @@ -73,7 +73,7 @@ Provide three polices for cpuset manager: - share: containers of this pod runs in theallocated CPUs , but other containers can also use. ### Advanced CPU Manager component -

    +![advanced_cpuset_manager.png](../images/advanced_cpuset_manager.png) - Crane-agent use podLister informs to sense the creation of pod. - Crane-agent allocate cpus when pod is binded, and loop in cycle to addContainer(change cpuset) until the containers are created diff --git a/docs/roadmaps/roadmap-1h-2022.md b/docs/roadmaps/roadmap-1h-2022.md index 358635c95..79f11fd43 100644 --- a/docs/roadmaps/roadmap-1h-2022.md +++ b/docs/roadmaps/roadmap-1h-2022.md @@ -11,7 +11,7 @@ Please let us know if you have urgent needs which are not presented in the plan. - Multiple Metric Adaptor support - Node QoS Ensurance for CPU - Operation Metrics about R3 and EPA applied ratio -### 0.3.0 [March] +### 0.3.0 [released] - UI with cost visibility and usage optimizations. - Request Recommendation adapts with Virtual Kubelet - Multiple Triggers for EPA @@ -29,4 +29,4 @@ Please let us know if you have urgent needs which are not presented in the plan. - Node & Pod QoS Ensurance for DiskIO and Network - Prediction with DiskIO, Network ### 0.6.0 [June] -- Scalability to support 3k TSP and 3k EPA \ No newline at end of file +- Scalability to support 3k TSP and 3k EPA diff --git a/docs/tutorials/analytics-and-recommendation.md b/docs/tutorials/analytics-and-recommendation.md index b8385448c..1a8dc1145 100644 --- a/docs/tutorials/analytics-and-recommendation.md +++ b/docs/tutorials/analytics-and-recommendation.md @@ -3,6 +3,7 @@ Analytics and Recommendation provide capacity that analyzes the workload in k8s cluster and provide recommendations about resource optimize. Two Recommendations are currently supported: + - **ResourceRecommend**: Recommend container requests & limit resources based on historic metrics. - **Effective HPARecommend**: Recommend which workloads are suitable for autoscaling and provide optimized configurations such as minReplicas, maxReplicas. @@ -10,14 +11,48 @@ Two Recommendations are currently supported: Create an **Resource** `Analytics` to give recommendation for deployment: `craned` and `metric-adapter` as a sample. -```console +```bash kubectl apply -f https://raw.githubusercontent.com/gocrane/crane/main/examples/analytics/analytics-resource.yaml kubectl get analytics -n crane-system ``` +```yaml title="analytics-resource.yaml" hl_lines="7 24 11-14 28-31" +apiVersion: analysis.crane.io/v1alpha1 +kind: Analytics +metadata: + name: craned-resource + namespace: crane-system +spec: + type: Resource # This can only be "Resource" or "HPA". + completionStrategy: + completionStrategyType: Periodical # This can only be "Once" or "Periodical". + periodSeconds: 86400 # analytics selected resources every 1 day + resourceSelectors: # defines all the resources to be select with + - kind: Deployment + apiVersion: apps/v1 + name: craned + +--- + +apiVersion: analysis.crane.io/v1alpha1 +kind: Analytics +metadata: + name: metric-adapter-resource + namespace: crane-system +spec: + type: Resource # This can only be "Resource" or "HPA". + completionStrategy: + completionStrategyType: Periodical # This can only be "Once" or "Periodical". + periodSeconds: 3600 # analytics selected resources every 1 hour + resourceSelectors: # defines all the resources to be select with + - kind: Deployment + apiVersion: apps/v1 + name: metric-adapter +``` + The output is: -```console +```bash NAME AGE craned-resource 15m metric-adapter-resource 15m @@ -25,13 +60,13 @@ metric-adapter-resource 15m You can get created recommendation from analytics status: -```console +```bash kubectl get analytics craned-resource -n crane-system -o yaml ``` The output is similar to: -```console +```yaml hl_lines="18-21" apiVersion: analysis.crane.io/v1alpha1 kind: Analytics metadata: @@ -57,13 +92,13 @@ status: The recommendation name presents on `status.recommendations[0].name`. Then you can get recommendation detail by running: -```console +```bash kubectl get recommend -n crane-system craned-resource-resource-j7shb -o yaml ``` The output is similar to: -```console +```yaml hl_lines="32-37" apiVersion: analysis.crane.io/v1alpha1 kind: Recommendation metadata: @@ -106,22 +141,58 @@ status: The `status.resourceRequest` is recommended by crane's recommendation engine. Something you should know about Resource recommendation: + * Resource Recommendation use historic prometheus metrics to calculate and propose. * We use **Percentile** algorithm to process metrics that also used by VPA. * If the workload is running for a long term like several weeks, the result will be more accurate. ## Analytics and Recommend HPA -Create an **HPA** `Analytics` to give recommendation for deployment: `craned` and `metric-adapter` as an sample. +Create an **HPA** `Analytics` to give recommendations for deployment: `craned` and `metric-adapter` as a sample. -```console +```bash kubectl apply -f https://raw.githubusercontent.com/gocrane/crane/main/examples/analytics/analytics-hpa.yaml kubectl get analytics -n crane-system ``` +```yaml title="analytics-hpa.yaml" hl_lines="7 24 11-14 28-31" +apiVersion: analysis.crane.io/v1alpha1 +kind: Analytics +metadata: + name: craned-hpa + namespace: crane-system +spec: + type: HPA # This can only be "Resource" or "HPA". + completionStrategy: + completionStrategyType: Periodical # This can only be "Once" or "Periodical". + periodSeconds: 600 # analytics selected resources every 10 minutes + resourceSelectors: # defines all the resources to be select with + - kind: Deployment + apiVersion: apps/v1 + name: craned + +--- + +apiVersion: analysis.crane.io/v1alpha1 +kind: Analytics +metadata: + name: metric-adapter-hpa + namespace: crane-system +spec: + type: HPA # This can only be "Resource" or "HPA". + completionStrategy: + completionStrategyType: Periodical # This can only be "Once" or "Periodical". + periodSeconds: 3600 # analytics selected resources every 1 hour + resourceSelectors: # defines all the resources to be select with + - kind: Deployment + apiVersion: apps/v1 + name: metric-adapter +``` + + The output is: -```console +```bash NAME AGE craned-hpa 5m52s craned-resource 18h @@ -132,13 +203,13 @@ metric-adapter-resource 18h You can get created recommendation from analytics status: -```console +```bash kubectl get analytics craned-hpa -n crane-system -o yaml ``` The output is similar to: -```console +```yaml hl_lines="21" apiVersion: analysis.crane.io/v1alpha1 kind: Analytics metadata: @@ -166,13 +237,13 @@ status: The recommendation name presents on `status.recommendations[0].name`. Then you can get recommendation detail by running: -```console -kubectl get recommend -n crane-system craned-resource-resource-j7shb -o yaml +```bash +kubectl get recommend -n crane-system craned-resource-resource-2f22w -o yaml ``` The output is similar to: -```console +```yaml hl_lines="26-29" apiVersion: analysis.crane.io/v1alpha1 kind: Recommendation metadata: @@ -209,12 +280,13 @@ status: The `status.resourceRequest` is recommended by crane's recommendation engine. The fail reason is demo workload don't have enough run time. Something you should know about HPA recommendation: + * HPA Recommendation use historic prometheus metrics to calculate, forecast and propose. * We use **DSP** algorithm to process metrics. -* We recommend using Effective HorizontalPodAutoscaler to execute autoscaling, you can see [this document](./docs/tutorials/using-time-series-prediction.md) to learn more. +* We recommend using Effective HorizontalPodAutoscaler to execute autoscaling, you can see [this document](using-time-series-prediction.md) to learn more. * The Workload need match following conditions: * Existing at least one ready pod * Ready pod ratio should larger that 50% * Must provide cpu request for pod spec * The workload should be running for at least **a week** to get enough metrics to forecast - * The workload's cpu load should be predictable, **too low** or **too unstable** workload often is unpredictable \ No newline at end of file + * The workload's cpu load should be predictable, **too low** or **too unstable** workload often is unpredictable diff --git a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md index 36c537fcd..7da8d8d16 100644 --- a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md +++ b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md @@ -1,46 +1,56 @@ # EffectiveHorizontalPodAutoscaler -EffectiveHorizontalPodAutoscaler helps you manage application scaling in an easy way. It is compatible with HorizontalPodAutoscaler but extends more features. -EffectiveHorizontalPodAutoscaler supports prediction-driven autoscaling. With this capability, user can forecast the incoming peak flow and scale up their application ahead, also user can know when the peak flow will end and scale down their application gracefully. +EffectiveHorizontalPodAutoscaler helps you manage application scaling in an easy way. + +It is compatible with HorizontalPodAutoscaler but extends more features. + +EffectiveHorizontalPodAutoscaler supports prediction-driven autoscaling. + +With this capability, user can forecast the incoming peak flow and scale up their application ahead, also user can know when the peak flow will end and scale down their application gracefully. Besides that, EffectiveHorizontalPodAutoscaler also defines several scale strategies to support different scaling scenarios. ## Features A EffectiveHorizontalPodAutoscaler sample yaml looks like below: + ```yaml apiVersion: autoscaling.crane.io/v1alpha1 kind: EffectiveHorizontalPodAutoscaler metadata: name: php-apache spec: - # ScaleTargetRef is the reference to the workload that should be scaled. - scaleTargetRef: + scaleTargetRef: #(1) apiVersion: apps/v1 kind: Deployment name: php-apache - minReplicas: 1 # MinReplicas is the lower limit replicas to the scale target which the autoscaler can scale down to. - maxReplicas: 10 # MaxReplicas is the upper limit replicas to the scale target which the autoscaler can scale up to. - scaleStrategy: Auto # ScaleStrategy indicates the strategy to scaling target, value can be "Auto" and "Preview". - # Metrics contains the specifications for which to use to calculate the desired replica count. - metrics: + minReplicas: 1 #(2) + maxReplicas: 10 #(3) + scaleStrategy: Auto #(4) + metrics: #(5) - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - # Prediction defines configurations for predict resources. - # If unspecified, defaults don't enable prediction. - prediction: - predictionWindowSeconds: 3600 # PredictionWindowSeconds is the time window to predict metrics in the future. + prediction: #(6) + predictionWindowSeconds: 3600 #(7) predictionAlgorithm: algorithmType: dsp dsp: sampleInterval: "60s" historyLength: "3d" +``` +1. ScaleTargetRef is the reference to the workload that should be scaled. +2. MinReplicas is the lower limit replicas to the scale target which the autoscaler can scale down to. +3. MaxReplicas is the upper limit replicas to the scale target which the autoscaler can scale up to. +4. ScaleStrategy indicates the strategy to scaling target, value can be "Auto" and "Preview". +5. Metrics contains the specifications for which to use to calculate the desired replica count. +6. Prediction defines configurations for predict resources.If unspecified, defaults don't enable prediction. +7. PredictionWindowSeconds is the time window to predict metrics in the future. -``` +### Params Description * spec.scaleTargetRef defines the reference to the workload that should be scaled. * spec.minReplicas is the lower limit replicas to the scale target which the autoscaler can scale down to. @@ -103,7 +113,8 @@ spec: type: Resource ``` -In this sample, the resource metric defined by user is converted into two metrics: prediction metric and origin metric . +In this sample, the resource metric defined by user is converted into two metrics: prediction metric and origin metric. + * **prediction metric** is custom metrics that provided by component MetricAdapter. Since custom metric doesn't support `targetAverageUtilization`, it's converted to `targetAverageValue` based on target pod cpu request. * **origin metric** is equivalent to user defined metrics in EffectiveHorizontalPodAutoscaler, to fall back to baseline user defined in case of some unexpected situation e.g. business traffic sudden growth. @@ -111,6 +122,7 @@ HorizontalPodAutoscaler will calculate on each metric, and propose new replicas #### Horizontal scaling process There are six steps of prediction and scaling process: + 1. EffectiveHPAController create HorizontalPodAutoscaler and TimeSeriesPrediction instance 2. PredictionCore get historic metric from prometheus and persist into TimeSeriesPrediction 3. HPAController read metrics from KubeApiServer @@ -119,20 +131,21 @@ There are six steps of prediction and scaling process: 6. HPAController scale target with Scale Api Below is the process flow. -
    +![crane-ehpa](../images/crane-ehpa.png) #### Use case Let's take one use case that using EffectiveHorizontalPodAutoscaler in production cluster. We did a profiling on the load history of one application in production and replayed it in staging environment. With the same application, we leverage both EffectiveHorizontalPodAutoscaler and HorizontalPodAutoscaler to manage the scale and compare the result. -From the red line in below chart, we can see its actual total cpu usage is high at ~8am, ~12pm, ~8pm and low in midnight. The green line shows the prediction cpu usage trend. -
    +From the red line in below chart, we can see its actual total cpu usage is high at ~8am, ~12pm, ~8pm and low in midnight. The green line shows the prediction cpu usage trend. +![craen-ehpa-metrics-chart](../images/crane-ehpa-metrics-chart.png) Below is the comparison result between EffectiveHorizontalPodAutoscaler and HorizontalPodAutoscaler. The red line is the replica number generated by HorizontalPodAutoscaler and the green line is the result from EffectiveHorizontalPodAutoscaler. -
    +![crane-ehpa-metrics-replicas-chart](../images/crane-ehpa-replicas-chart.png) We can see significant improvement with EffectiveHorizontalPodAutoscaler: + * Scale up in advance before peek flow * Scale down gracefully after peek flow * Fewer replicas changes than HorizontalPodAutoscaler diff --git a/docs/tutorials/using-qos-ensurance.md b/docs/tutorials/using-qos-ensurance.md index 5adaa5bfb..b423b40a8 100644 --- a/docs/tutorials/using-qos-ensurance.md +++ b/docs/tutorials/using-qos-ensurance.md @@ -2,15 +2,17 @@ QoS ensurance guarantees the stability of the pods running on Kubernetes. Disable schedule, throttle, evict will be applied to low priority pods when the higher priority pods is impacted by resource competition. -# Qos Ensurance Architecture +## Qos Ensurance Architecture Qos ensurance's architecture is shown as below. It contains three modules. + 1. state collector: collect metrics periodically 2. anomaly analyzer: analyze the node triggered anomaly used collected metrics 3. action executor: execute avoidance actions, include disable scheduling, throttle and eviction. -
    +![crane-qos-enurance](../images/crane-qos-ensurance.png) The main process: + 1. State collector synchronizes policies from kube-apiserver. 2. If the policies are changed, the state collector updates the collectors. 3. State collector collects metrics periodically. @@ -19,7 +21,7 @@ The main process: 6. Anomaly analyzer merges the analyzed results and notices the avoidance actions. 7. Action executor executes actions based on the analyzed results. -# Disable Scheduling +## Disable Scheduling The following AvoidanceAction and NodeQOSEnsurancePolicy can be defined. As a result, when the node CPU usage triggers the threshold, disable schedule action for the node will be executed. @@ -51,21 +53,28 @@ spec: localCacheTTLSeconds: 60 objectiveEnsurances: - name: "cpu-usage" - avoidanceThreshold: 2 # We consider the rule is triggered, when the threshold reached continued so many times - restoreThreshold: 2 # We consider the rule is restored, when the threshold not reached continued so many times - actionName: "disablescheduling" # Name of AvoidanceAction which be associated - strategy: "None" # Strategy for the action, you can set it "Preview" to not perform actually + avoidanceThreshold: 2 #(1) + restoreThreshold: 2 #(2) + actionName: "disablescheduling" #(3) + strategy: "None" #(4) metricRule: - name: "cpu_total_usage" # Name of metric - value: 4000 # Threshold of metric + name: "cpu_total_usage" #(5) + value: 4000 #(6) ``` +1. We consider the rule is triggered, when the threshold reached continued so many times +2. We consider the rule is restored, when the threshold not reached continued so many times +3. Name of AvoidanceAction which be associated +4. Strategy for the action, you can set it "Preview" to not perform actually +5. Name of metric +6. Threshold of metric + Please check the video to learn more about the scheduling disable actions. [![disable scheduling example video](../images/disablescheduling-example.png)](https://youtu.be/87bnz5LasbI "disable scheduling") -# Throttle +## Throttle The following AvoidanceAction and NodeQOSEnsurancePolicy can be defined. As a result, when the node CPU usage triggers the threshold, throttle action for the node will be executed. @@ -82,14 +91,14 @@ spec: coolDownSeconds: 300 throttle: cpuThrottle: - # The minimal ratio of the CPU quota, if the pod is throttled lower than this ratio, it will be set to this. - minCPURatio: 10 - # The step for throttle action. It will reduce this percentage of CPU quota in each avoidance triggered. - # It will increase this percentage of CPU quota in each restored. - stepCPURatio: 10 + minCPURatio: 10 #(1) + stepCPURatio: 10 #(2) description: "throttle low priority pods" ``` +1. The minimal ratio of the CPU quota, if the pod is throttled lower than this ratio, it will be set to this. +2. The step for throttle action. It will reduce this percentage of CPU quota in each avoidance triggered.It will increase this percentage of CPU quota in each restored. + ```yaml apiVersion: ensurance.crane.io/v1alpha1 kind: NodeQOSEnsurancePolicy @@ -113,7 +122,7 @@ spec: value: 6000 ``` -# Eviction +## Eviction The following YAML is another case, low priority pods on the node will be evicted, when the node CPU usage trigger the threshold. @@ -127,10 +136,12 @@ metadata: spec: coolDownSeconds: 300 eviction: - terminationGracePeriodSeconds: 30 # Duration in seconds the pod needs to terminate gracefully. + terminationGracePeriodSeconds: 30 #(1) description: "evict low priority pods" ``` +1. Duration in seconds the pod needs to terminate gracefully. + ```yaml apiVersion: ensurance.crane.io/v1alpha1 kind: NodeQOSEnsurancePolicy @@ -148,15 +159,17 @@ spec: avoidanceThreshold: 2 restoreThreshold: 2 actionName: "evict" - strategy: "Preview" # Strategy for the action, "Preview" to not perform actually + strategy: "Preview" #(1) metricRule: name: "cpu_total_usage" value: 6000 ``` -# Supported Metrics +1. Strategy for the action, "Preview" to not perform actually + +## Supported Metrics Name | Description ---------|------------- cpu_total_usage | node cpu usage -cpu_total_utilization | node cpu utilization \ No newline at end of file +cpu_total_utilization | node cpu utilization diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 000000000..b7be8c352 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,73 @@ +# yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json +site_name: Crane - Cloud Resource Analytics and Economics +theme: + name: material + custom_dir: overrides + language: en + features: + - toc.integrate + - content.code.annotate + - navigation.top + palette: + primary: blue + logo: images/crane.svg + favicon: images/crane.svg + font: + text: Work Sans +extra_javascript: + - assets/util.js +extra: + version: + provider: mike + default: latest +plugins: + - search + - i18n: + default_language: en + languages: + en: + name: English + build: true + zh: + name: 简体中文 + build: true + nav_translations: + zh: + Overview: 总览 + Getting Started: 从这里开始 + Tutorials: 教程 + Proposals: 提案 + Contributing: 贡献 + Code Standard: 代码标准 + Roadmap: 路线图 +markdown_extensions: + - codehilite + - admonition + - toc: + permalink: true + - pymdownx.highlight: + anchor_linenums: true + use_pygments: true + linenums: true + linenums_style: pymdownx-inline + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true +repo_url: https://github.com/gocrane/crane +repo_name: gocrane/crane +nav: + - Overview: index.md + - Getting Started: getting-started.md + - Tutorials: + - Analytics and Recommendation: tutorials/analytics-and-recommendation.md + - Using Effective HPA To Scaling With Effectiveness: tutorials/using-effective-hpa-to-scaling-with-effectiveness.md + - Using Qos Ensurance: tutorials/using-qos-ensurance.md + - Using Time Series Prediction: tutorials/using-time-series-prediction.md + - Proposals: + - Advanced CpuSet Manager: proposals/20220228-advanced-cpuset-manger.md + - Contributing: CONTRIBUTING.md + - Code Standard: code-standards.md + - Roadmap: + - 1H 2022: roadmaps/roadmap-1h-2022.md diff --git a/overrides/main.html b/overrides/main.html new file mode 100644 index 000000000..e4c38e21b --- /dev/null +++ b/overrides/main.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block outdated %} +You're not viewing the latest version. +
    + Click here to go to latest. + +{% endblock %} From c163040982735bfea9e6eaaafb53e21fa2581796 Mon Sep 17 00:00:00 2001 From: zsnmwy Date: Sat, 2 Apr 2022 21:00:14 +0800 Subject: [PATCH 07/41] fix GitHub action permissions Signed-off-by: zsnmwy --- .github/workflows/preview.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 51c46ed56..0ed14b2e0 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -8,6 +8,10 @@ on: jobs: preview: runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + contents: write steps: - uses: actions/checkout@v2 From 0d3386bf731d3a17739e599bc7a365bfd094f268 Mon Sep 17 00:00:00 2001 From: zsnmwy <35299017+zsnmwy@users.noreply.github.com> Date: Wed, 6 Apr 2022 16:57:47 +0800 Subject: [PATCH 08/41] Fix GitHub Actions PR Comment Signed-off-by: zsnmwy --- .github/workflows/preview.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 0ed14b2e0..816e096ab 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,7 +1,7 @@ name: 🔂 Crane PR Docs Preview on: - pull_request: + pull_request_target: # when using teardown: 'true', add default event types + closed event type types: [opened, synchronize, reopened, closed] @@ -14,6 +14,9 @@ jobs: contents: write steps: - uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} - uses: actions/setup-python@v2 with: @@ -21,6 +24,8 @@ jobs: - run: pip install mkdocs-material mkdocs-static-i18n mike + - run: git log --oneline --decorate --max-count=10 && ls -la + - uses: afc163/surge-preview@v1 with: surge_token: ${{ secrets.SURGE_TOKEN }} From a54f957fa50d7843c335fb2f0acfde9436e052b8 Mon Sep 17 00:00:00 2001 From: qmhu Date: Wed, 6 Apr 2022 15:45:12 +0800 Subject: [PATCH 09/41] fix typo --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0382ce7c4..fb62b8f79 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Crane is composed of the following components: - **RecommendationController** - Recommend Pod resource requests and autoscaler. - **ClusterNodePredictionController** - Create Predictor for nodes. - **EffectiveHPAController** - Effective HPA for horizontal scaling. - - **EffectiveHPAController** - Effective VPA for vertical scaling. + - **EffectiveVPAController** - Effective VPA for vertical scaling. - [metric-adaptor](cmd/metric-adapter). - Metric server for driving the scaling. - [crane-agent](cmd/crane-agent). - Ensure critical workloads SLO based on abnormally detection. - [gocrane/api](https://github.com/gocrane/api). This repository defines component-level APIs for the Crane platform. diff --git a/docs/index.md b/docs/index.md index 0e45649c6..74c50d6f6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -70,7 +70,7 @@ Crane is composed of the following components: - **RecommendationController** - Recommend Pod resource requests and autoscaler. - **ClusterNodePredictionController** - Create Predictor for nodes. - **EffectiveHPAController** - Effective HPA for horizontal scaling. - - **EffectiveHPAController** - Effective VPA for vertical scaling. + - **EffectiveVPAController** - Effective VPA for vertical scaling. - [metric-adaptor](https://github.com/gocrane/crane/tree/main/cmd/metric-adapter) - Metric server for driving the scaling. - [crane-agent](https://github.com/gocrane/crane/tree/main/cmd/crane-agent) - Ensure critical workloads SLO based on abnormally detection. - [gocrane/api](https://github.com/gocrane/api) - This repository defines component-level APIs for the Crane platform. From 6722fe95c4e284a97b3ab1f362b91056450fce10 Mon Sep 17 00:00:00 2001 From: qmhu Date: Thu, 7 Apr 2022 21:31:22 +0800 Subject: [PATCH 10/41] Add website to docs --- README.md | 165 ++---------------- docs/assets/util.css | 3 + docs/code-standards.md | 3 + docs/images/wechat.jpeg | Bin 0 -> 117200 bytes docs/index.md | 16 +- docs/index.zh.md | 27 +-- docs/{getting-started.md => installation.md} | 34 +--- ...tting-started.zh.md => installation.zh.md} | 7 - mkdocs.yml | 16 +- 9 files changed, 44 insertions(+), 227 deletions(-) create mode 100644 docs/assets/util.css create mode 100644 docs/images/wechat.jpeg rename docs/{getting-started.md => installation.md} (83%) rename docs/{getting-started.zh.md => installation.zh.md} (98%) diff --git a/README.md b/README.md index fb62b8f79..dcdbd4054 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,6 @@ Crane (FinOps Crane) is a cloud native open source project which manages cloud resources on Kubernetes stack, it is inspired by FinOps concepts. -- [Crane: Cloud Resource Analytics and Economics](#crane-cloud-resource-analytics-and-economics) - - [Introduction](#introduction) - - [Features](#features) - - [TimeSeriesPrediction](#Time-series-prediction) - - [Effective HorizontalPodAutoscaler](#effective-horizontalpodautoscaler) - - [Analytics](#analytics) - - [QoS Ensurance](#qos-ensurance) - - [Repositories](#repositories) - - [Getting Started](#getting-started) - - [Installation](#installation) - - [Get your Kubernetes Cost Report](#get-your-kubernetes-cost-report) - - [Analytics and Recommendation](#analytics-and-recommendation) - - [RoadMap](#roadmap) - - [Contributing](#Contributing) - - [Code of Conduct](#Code-of-Conduct) - ## Introduction The goal of Crane is to provide a one-stop-shop project to help Kubernetes users to save cloud resource usage with a rich set of functionalities: @@ -42,155 +26,28 @@ The goal of Crane is to provide a one-stop-shop project to help Kubernetes users Crane Overview -## Features -### Time Series Prediction - -TimeSeriesPrediction defines metric spec to predict kubernetes resources like Pod or Node. -The prediction module is the core component that other crane components relied on, like [EHPA](#effective-horizontalpodautoscaler) and [Analytics](#analytics). - -Please see [this document](./docs/tutorials/using-time-series-prediction.md) to learn more. - -### Effective HorizontalPodAutoscaler - -EffectiveHorizontalPodAutoscaler helps you manage application scaling in an easy way. It is compatible with native [HorizontalPodAutoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) but extends more features like prediction-driven autoscaling. - -Please see [this document](./docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md) to learn more. - -### Analytics - -Analytics model analyzes the workload and provide recommendations about resource optimize. - -Two Recommendations are currently supported: -- **ResourceRecommend**: Recommend container requests & limit resources based on historic metrics. -- **Effective HPARecommend**: Recommend which workloads are suitable for autoscaling and provide optimized configurations such as minReplicas, maxReplicas. - -### QoS Ensurance -Kubernetes is capable of starting multiple pods on same node, and as a result, some of the user applications may be impacted when there are resources(e.g. cpu) consumption competition. To mitigate this, Crane allows users defining PrioirtyClass for the pods and QoSEnsurancePolicy, and then detects disruption and ensure the high priority pods not being impacted by resource competition. - -Avoidance Actions: -- **Disable Schedule**: disable scheduling by setting node taint and condition -- **Throttle**: throttle the low priority pods by squeezing cgroup settings -- **Evict**: evict low priority pods - -Please see [this document](./docs/tutorials/using-qos-ensurance.md) to learn more. - -## Repositories - -Crane is composed of the following components: -- [craned](cmd/craned). - main crane control plane. - - **Predictor** - Predicts resources metrics trends based on historical data. - - **AnalyticsController** - Analyzes resources and generate related recommendations. - - **RecommendationController** - Recommend Pod resource requests and autoscaler. - - **ClusterNodePredictionController** - Create Predictor for nodes. - - **EffectiveHPAController** - Effective HPA for horizontal scaling. - - **EffectiveVPAController** - Effective VPA for vertical scaling. -- [metric-adaptor](cmd/metric-adapter). - Metric server for driving the scaling. -- [crane-agent](cmd/crane-agent). - Ensure critical workloads SLO based on abnormally detection. -- [gocrane/api](https://github.com/gocrane/api). This repository defines component-level APIs for the Crane platform. -- [gocrane/fadvisor](https://github.com/gocrane/fadvisor) Financial advisor which collect resource prices from cloud API. - ## Getting Started -### Installation - -**Prerequisites** - -- Kubernetes 1.18+ -- Helm 3.1.0 - -**Helm Installation** - -Please refer to Helm's [documentation](https://helm.sh/docs/intro/install/) for installation. +- [Introduction](https://docs.gocrane.io/getting-started/introduction) +- [Installation](https://docs.gocrane.io/getting-started/installation) +- [Tutorials](https://docs.gocrane.io/tutorials) -**Installing prometheus and grafana with helm chart** +## Documentation -> Note: -> If you already deployed prometheus, grafana in your environment, then skip this step. +Full documentation is available on the [Crane website](https://docs.gocrane.io). -Crane use prometheus to be the default metric provider. Using following command to install prometheus components: prometheus-server, node-exporter, kube-state-metrics. +## Community -```console -helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -helm install prometheus -n crane-system --set pushgateway.enabled=false --set alertmanager.enabled=false --set server.persistentVolume.enabled=false -f https://raw.githubusercontent.com/gocrane/helm-charts/main/integration/prometheus/override_values.yaml --create-namespace prometheus-community/prometheus -``` +- Wechat Group (Chinese): Add it and Reply "Crane",Robot will add you in Wechat group. -Fadvisor use grafana to present cost estimates. Using following command to install a grafana. +Wechat -```console -helm repo add grafana https://grafana.github.io/helm-charts -helm install grafana -f https://raw.githubusercontent.com/gocrane/helm-charts/main/integration/grafana/override_values.yaml -n crane-system --create-namespace grafana/grafana -``` +- Bi-weekly Community Call: [Meeting Notes](https://doc.weixin.qq.com/doc/w3_AHMAlwa_AFU7PT58rVhTFKXV0maR6?scode=AJEAIQdfAAo0gvbrCIAHMAlwa_AFU). -**Deploying Crane and Fadvisor** - -```console -helm repo add crane https://gocrane.github.io/helm-charts -helm install crane -n crane-system --create-namespace crane/crane -helm install fadvisor -n crane-system --create-namespace crane/fadvisor -``` - -**Verify Installation** - -Check deployments are all available by running: - -```console -kubectl get deploy -n crane-system -``` - -The output is similar to: -```console -NAME READY STATUS RESTARTS AGE -crane-agent-8h7df 1/1 Running 0 119m -crane-agent-8qf5n 1/1 Running 0 119m -crane-agent-h9h5d 1/1 Running 0 119m -craned-5c69c684d8-dxmhw 2/2 Running 0 20m -grafana-7fddd867b4-kdxv2 1/1 Running 0 41m -metric-adapter-94b6f75b-k8h7z 1/1 Running 0 119m -prometheus-kube-state-metrics-6dbc9cd6c9-dfmkw 1/1 Running 0 45m -prometheus-node-exporter-bfv74 1/1 Running 0 45m -prometheus-node-exporter-s6zps 1/1 Running 0 45m -prometheus-node-exporter-x5rnm 1/1 Running 0 45m -prometheus-server-5966b646fd-g9vxl 2/2 Running 0 45m -``` - -you can see [this](https://github.com/gocrane/helm-charts) to learn more. - -**Customize Installation** - -Deploy `Crane` by apply YAML declaration. - -```console -git checkout v0.2.0 -kubectl apply -f deploy/manifests -kubectl apply -f deploy/craned -kubectl apply -f deploy/metric-adapter -``` - -The following command will configure prometheus http address for crane if you want to customize it. Specify `CUSTOMIZE_PROMETHEUS` if you have existing prometheus server. - -```console -export CUSTOMIZE_PROMETHEUS= -if [ $CUSTOMIZE_PROMETHEUS ]; then sed -i '' "s/http:\/\/prometheus-server.crane-system.svc.cluster.local:8080/${CUSTOMIZE_PROMETHEUS}/" deploy/craned/deployment.yaml ; fi -``` - -### Get your Kubernetes Cost Report - -Get the Grafana URL to visit by running these commands in the same shell: - -```console -export POD_NAME=$(kubectl get pods --namespace crane-system -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana" -o jsonpath="{.items[0].metadata.name}") -kubectl --namespace crane-system port-forward $POD_NAME 3000 -``` - -visit [Cost Report](http://127.0.0.1:3000/dashboards) here with account(admin:admin). - -### Analytics and Recommendation - -Crane supports analytics and give recommend advise for your k8s cluster. - -Please follow [this guide](./docs/tutorials/analytics-and-recommendation.md) to learn more. +- Bi-weekly Chinese Community Call: [Video Records](https://www.wolai.com/33xC4HB1JXCCH1x8umfioS). ## RoadMap + Please see [this document](./docs/roadmaps/roadmap-1h-2022.md) to learn more. ## Contributing diff --git a/docs/assets/util.css b/docs/assets/util.css new file mode 100644 index 000000000..f273e7533 --- /dev/null +++ b/docs/assets/util.css @@ -0,0 +1,3 @@ +.md-nav__title { + display: none; +} \ No newline at end of file diff --git a/docs/code-standards.md b/docs/code-standards.md index bb0570604..9223c609b 100644 --- a/docs/code-standards.md +++ b/docs/code-standards.md @@ -1,4 +1,7 @@ +# Code standards + This doc describes the code standards and suggestion for crane project, mainly for new contributor of the project + ### import need to be organized import should be categorized with blank line as system imports, community imports and crane apis and crane imports, like the following example ```go diff --git a/docs/images/wechat.jpeg b/docs/images/wechat.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..d919b96c99b15cb4dff898fb2bebb5ae806f8fcb GIT binary patch literal 117200 zcmeFZ2UJtt+AbQTNf+r|=^bezHKGCnB2Bu0fOP4E4pC`J6_6qw={2A99_b>zOAWo3 zgc?E!cYS;R`<^q-IQNcw?ilx;{~u$AF;_B^l{x2|_0D&_^Ld`h&7YfP&>am`byW}^ z9tea7{DE%fK~F(M1O$Wx1Vn^{ghWI{#3Ym?B)4yq+@+u(rKGz{PfvH3mX?9}J}Uzw z2NNwV8y_17Cl?P74?U}ZFh94@eQqA^zZ<~=zDjbNgqnnenwyc9k^6u7aq|;IeVgDb z!6SS;PS7oCJbY@rn{E&XFit|ee>_0{@xZ%Yhhv=Sc@@@{iI`O!hAH-_YvwD$Z+LQ2oT$i&RU%f~Mu zC?)++=8>%2(`PEGYR}a*^j{em8X23I+Pt;3vv+WG^74lG`1<(=gocGjM1J}lm6-H3 zIVCmiTl)9>g2JNWlG3v3n%cVhhQ_Am&aUpB-o9V`zsDygr>1BA%+9T>uB~ruZf)=E zqK;2a&(1HVp?URJO9~~rIl6puwYtJ!KdTyx|9@O8a{ll{VXNGN*pf$^ShH^zZWT-{9Xq@NXaZw-5Z=2mb8?{}p{8Mh8!Yv9KeT z;Cqw+;m4>44t-2Tcq+8OyZ!AYB#4+*?un9R+wQq7*z2Ncr=L-jnk8 z{Qbc{%6q^C-q7l*fM|79`9a@fbRQGa{?{&~4+3VYm9JzM`PNM z37XpLVRa2B?L+=-F&s7ZDUDaEO@VyZUa|U@oAnj#gnmjhL=J9lw~wT|$ZtRh7H8*` z`X43e&`$b*s&c`8FVDBKuSjo2+A`wLLQPR4F&6w&#IZ*eE)bz#E(haM)GG4d*K@7i zDJ7FIM!&5#($>WFI-93G+UDlfTvL=%saYu*s92vl6csvK4p~+X=d3b>2g&C-XH!np zUh|IM_btiI*jQ|TfcjY3n5c{xJ*#TzZNGyY&RM>;+oht~5!YhN98BaXaQZb*dHd0F zXcUrzprB#t;h0R5ugqwZy)2*eM}G_{Ms1Z(iC_l4H*9%LlV$>9z(A0`75(n9e3J zR|^wd>sODD#2^R(&L9C<^BUKIYR{6dzyA$4B6bD)iOq1t3N7LI(B6Kj z9j4*U{Qj$!waU0-uMcNT9I*i=5f9s`BtyRIzD!c_t>6nL~WS|Tv)CL z)u@P>YG96@ZU$s=bPcgn1oj44WI%4GFF7*yGx3qrnZ$XV!g5DCj|c=0U2aVoP1ZnB z25UDUym##rYbj}QA_qKQIG$+0aD&dX?f3i)p^Scz(`e_kgKryZj@){xqh4`}C`*d& zM@_;(j)HO2>bz5@C)J3j`_(U`LW%|BNcCFk4kij`^>K8t_cx$zDyth1)a(WnRd@pm zcV5=U;QxUldT&6h<-_omEQlC}(iDnFxdAbQSF-AW+T1^DTN`;dAm#C^LY%#tv>OKB zG6?$XR2yyBj(-EnRgAp8cEbs#;^>M$P+>bNw6AO3P%yb0Py}QWzAf)~0}3(2I@@&I zfCyj;GOL*Q{;!KvoN zg)sQ3j&#mtofRdf%+S}5YqBOh@7l!Y;(EjthdVoIgcak&EHXGEn``h-G)iyZfIi5D zVrVQM7{NQwgkE(G8@!!sPd!z5$yNL^%da<6Z^A4fJWwq(m zI)(mmC|`^%$xhta8Y$VAG70sc_)V}XTCwm}X7S^qjN)sLjXun2VRz&2$@?#9ZS8r_ zk8ePceD^!`D+LqFsuC?{mOaR>6#ZHbpm(T|K} zu?TiblvtS5;!77LwQRp1LS&yoq6Ouw_HoKpVqHtr_4Vk!>rjyjuRrq(zh8KXo*lQ= zLnyN0UFex+Kh4hbY|63x@ptx3>9=RIUhI>RXC@qfz?Si2>55cVFI!&~K^wGge@NmQ z=mjmt*!$2@Hl9}*+e^mm70W*AS64l9ZUf_&`M(`;gPy zM$^kqU4tr0Nq0HxnY>f+UC(9qsW=GfNyWOgOX%F=$kvu_I*(g@v_{?c7u6TM4{-}d zQj&6Ckx}8Y(tJV<8_vetDdwbUsfHe}OHIV&4}(hA_RKj4dVK3mSw-lwN{>}{$PPU& zhP4$v!K7PW7U3xSpXq8J<~rVqo{?o_^d_n^Z%qA_&mKjo?l#_f4u3k}+*{8~6Y65- z+fpBk9SQFnPZm6m8P~3!B~zhW{1e24GR(JkgOD3qxpJE5S_Bsek;lZi2bVjc%cMjO z3i3lXU%8(NSA0I;BqMIU*snkI(272^>zNby z^j6&s2tI_P{kvxQuNvL4??@~BSbqn)Lg#w}>i+~?$%eo%WIH#Yivb`yav(?KX08cO zZ$MWYH=s@+U`BkN1VShw5YV6*SpNT^E&!Z!VS58g46k+rW7DGlV^r-qH=rOmTL0~J zj&$0ZBZtYvln%X39U3253XJbN1dPE0BJSo5h_td48$5YNA-6l|NI&{*#V_pR6Af2A z$&a$VPWjhuf%4GxymuKRHy~bxswjR~m6Gv)x#XBu=aCfNHkdqw*$jO+hYM_(txTC6 ze}pY0_PCdniKCmp0d>hc660)u%W=_Zl!S)%g>WLXTI=T?=A9cCLd9qLV=q{3WNrC! zE7RH^_+d7^BSf4<_oM~G{ z`*vy+>1`aO_& zcx}=^)5mFbuHf8*HwB@g9i>AKHUif7Szk;RoIB5qLD2 zG_O z?}n<=_n35f%%*MzBoEa_rBPjWcN(U}@0eEsQ$v3^@6*po_>VlkC1BFjKcf1aO;&?c zDtEDQ3szi6dSdtGH%O4=o;QYhOq!angDHvaBSxEGfnX#9o~K zTfu00Ip2_$i}`pn)i9`D(0j{NFP}y2yJGw~q=t9RtexwSTUP*+!gon}pu~@k>@lSc za7Wf<4GktqWd}ZWvLhv0um`Qlf)ij;Xd{%^Gvvc0f9DcY#E@b)?u`SNs!rZxP~y)m z*#mPJR!S^_3fol|e|5%i17fgbNn81$H^^hI>lJTT8(@rCpy#7vC3lc(g`rFrHnihI zMA)I#ZZ{yL9s;Yyhvh@i!?&rSH=vI|uC(f04#a{mWZyM@UCuw-Q^QJeL_oLMDu9%` z5su!FUj=WIg3)A>oB2Q<6@MhFjn-BYxdDyx-hggEgutur85878ce}#0^z3&OPgYM| zl$m6?)>|tgt>2)2dX7Ea$0ub{bAK2rr`))veLW0Qd$)e@I zoJ7uaC+EUVX*UZ{T2({QSC1{y6z)4a72}k|XsL0(%Q?2{+k;_G&@dExSD)_AUps$U zD6^G6KaLJJSTJ*4u!?^nvtXqTV?Wdq^WX+#@6LBh)Lw*AiWi0FS~}`1MBBH-blVEGI4Js!DA>0JT_aV0T40rH zlOt3r^oF5FS)peh7UihWUQA@D_kqHWXAj%Z;2`BG#WDXD=&Jg}f<2_nT9Wh?Kipre z58BV(tG>Verp&Oi#wR2rq$ss39+U(6V_~MayQB``_uOM21U(?u&n`ZxGBZWC*Q~j* z?h`Dtw>3JqM^amqU^&}5R=l+HbTFMH49H6y>Z^Gv1gZ-oIh0n>SykoUf? z4bPKU=2w%JLIFI12YVrH!!tNKnHcDH{x0-l5{~t0f!}su2w@#d?7cE-nyQkiX&dUQ zp-KA5lD3Q&cc$49U>{xiU4~s?hW^lw(agarR#&Nl_HIaKurt-FTO6c~4P2ujUW8b% zs3%YLn3MW^8@G!sG>H$%4G!>p1wk1YGHHmJkLy}ARQuqPhtoasB8t!AOvHHSp%BDb zlXEXS0gCUlv`^~<)(TQEe|zfg5@?r5E~&0pov%uf*r^M+&8e^6fH3@+;_EY+8xUJn z`AYF;2>8x6$l1`>XD+MeUD}AN^@*ARgb}}(n5|>^tq~YS7{cvvqE+GtH3%G1NJQ9c z8k;^RE+W0Vc6N4F31l^8aD%Ndm%_Q&oRQ?COP3$*PzErcIZAo zw~+fzHnPS+jj703FH91UJKA9pLEwoFuyj-6EyV}x@uN|fC%p_2H=v$?o_?1l+x2da zbKlI6G?>M87A&k;^~W3S2MgTja|qWB=xwEBrgU{Wba4Y)iTSqiDC`8tWCAlz;M*QK zY{DwV@kL*$(3plO>)@B9(Ea4CseMGPVa{-LNy#qHhmq@JAnMl`#mrPD7@Vgudj`|B zZ`lkE3j`{>p7DjYYUntZq8(S}Eosrc16uIdf?C^zO#|zK_rG-F9BKaWp)(C21i>A^u#2FBj^Wu z(gpG@{SJ;(a-hLmZ-EeAasx6&#_#|AO^)4Zq09UW__31x_x7}ZbqI{_g9Okav@;2* zeT~m^1N!+5j4lID4{{iYH9^z56a8D~)brc+ZInuOh?Vu5^rt$K?hm`+&^NS}@{JF~i4JrE;n#UOF+bBg^ zc{XdsqzAVy-xawhSOGe!^`S$dhxx+t1ic+wX3N_|E^`dRR{8~0Aw`w#>4;4PdU z@8~NtwP#J~OV3yBf9Y&I*Yg;bj7#3YFzjCxKQ`2I)=xk9a04=MZ8yCpk>xwBy6CeI zya9ztcBL{m)-#B)2y&~O6A3@w3q1_*fsxFFNc+_oFa2e%Qq;LXQ1{}Y;==mYPSmky zkf@bmW_ziqaYH%W0DZO{@U4oA@TCXl_hzE0kS|saB7^nK-)?6>0d3bFFn6*j(~iDa zkuW)VfbYecbfK-kFjIw|Bg*M$UT}~YvU-G%7eCL#wof0WM@wH)GO4f|2^H~g3BdDDa=~B(aH|qWA3&j2dh$GA2cmL=u zhshM|Nut%qM>RWbpZjpK7^B=Ev(dBoJLp%A%_2E-TPZ7Ku=F1XDg;}?YVP@{s@I0> z-r{hBWP2CUr3@@4Aj{9`ugWk?X927-8P@QtUO@y2K)uK0f1AAxxR2RSAPD_k+3SL? zyg={a-m3u-2>{zxfltFF*I*bt4lHRTa4BKhSAvn(M6fpKv0B!3z8UU4V(|tvm%Vla zx(x?zx3LRnST67m&Vg~_AG{VlLZYFTb;ei%?6HI6e>o<&;L4?$p3W&1^2V}U&%XW z973|xQ?E_c2<&ILYoOagW>7{2vQ;srT_1{qc@>_zT456Zh14?a;^lhJEK9yfrw9hojw@rUmsVNWjLXSr6R`%2Os6mVcFeA-3r51TvW6R zV(@3lt?|B8Pa@BQ<>(f_9yItIwq&`M%K5o<`br4g_r9VRRJ$VSJFc*#aK>>Ur(?gP z{m;m4~D$M@wIem@?5vc;O{=>(1e;`U?j4zkI;_RTV^O&WsjJi%P84!p@n7*fkCYm8|ZJhPke%v{jv9nrUNRdHEE4>KhtsdE>l%Ks?tNOQAG^51m|07oJ*Jvk5-J|vQBdBSf`XFhOwXh zag_5mRsH5zteiwwAwZfm84jY_u+Uu9en0JKQ{tq%XGG!oT{A}g?g3v4S5zOqHlbd@ zH0Mi!1DhAGQSM>pv>Cg$*nnxN=u7Xk(=}U#aiNzNI&^k#xAWb1l`cZ2)=Mh(>1b=j ze}dj7J$D{eB17x=MfRxsE0|TBF1)GR^pYh6-&}TjxlAt#@POmipl}6gNbdSEqGKrml6-EaKGfL@<4mms_zA# zKDvJGv?uVW8%je(>i6;-BSYrC_N#uxQoQjOhCHXU-JqAa%`ZqiGTF3FyiR5|pw04Z zGw}6O3#rmB5^dW{5$dL8GqD2>CWrbiG>psU)Q}viY-xmeDe~@6^!6&ZJ@`FuyDOT{ z&b9sipI@qm(*kzjiw<4PUoanZG~`?i-`VR>Fyz-x&XX>OYb{R?kzJe8ar4yGA#`w{ z0_*N2yn};ZzP8GIUbs7juL-7oodd&-tj@R4T)0+hul`cTKNhhtpKgXm1mv6>#nn3Y z-?#7}0TPLiIakubcFrmW9g~qsSm|r3Zv$n`er28~*i*&gwd}7Ds$1%ERTjOgvbfN% zU<_T*Qh?D+w(tat339r)_#WY*OF^vU^=h#r7G=pvDb%wfHl zZnWNC>3UdUOJlMy6N#@yC{Sb%C z?a8kp3^q`WsaAtZCqoP*uBL3j%YB8*vaY`$i=nIokg$l;$Wd=+b0xE;BinFs?h|>* z=hwsPd`#PtKdWe#XSz;S4!~Dly3wwAexUz6{Fp?>xnD1P|#I=WP8qaLh*BO zo#;#oF-~y}+=D|M?9A*TO)9448CZGm3J#Q+wZq0Z>{InHaZIZ}L>6H?0W~q`4is=KVpvRQzuvwUNk@uys`|Qq*gC+_9J^G=pMHF}x@%yb zxAmn3ZzpL!>2fMS!}QePQHN)rO`M*muN9C1-uoWKf9F3q(0_5E|9hWR`Fj8o_HQEg ze_HNIvvkkR?;v;j4BF{EM7zW71mD{~y2lP>J{6nY9T-H3<_D((o(grAsCHA9W*=OGI3gf-+~E ztupFkb!v^ur%t7LV;PazKiVxoda=suuaQrJna*=fwlnq z_jLl&+C&aBNzccBpO665O?cv+EORCQq%y!FjU3whM(>DSUjKkdT8@;pAnvnw~o2b1&xJ@YW3w(3W3 z%we}+Sxln#8=;+%@OC0gB8SJX%d#}~KZ~;93-#Tm%Ei5%{&sG2_5$2|edz!|AUw&~+bn~}<=b8ycaSWy-kPLmAfoZD~*jJq-eZR%tUvdKoJXLdW zABV=}YfJN7lgbil>k zjo?LM(M0%THC%*q;3{!hHqSYR66OBJ|NyoxmO(?{u;jmH)Z7`Onm0+c?}s zVYuIFceFE*Rp=sR=4^5uy7GM=x{c=rFby;RU>c%-01OA=2#!Duth@>g5!#ySRm~qrQE5|q)7nG5I^3oc6&hrtIBIORDzR%emi6QS{R!b zX{I8B5&PAEI$W`@9`*Lg=x1nX5{U^Xy|slrk&G%V2qK@Z6`0%8M7h^~`_gM6WKFs7 zQ4O*41uWQcoeN>e>GAP-K2$$FspK{GE&i13H3BOFV+O!kAGd#?xil74WQ5TvM49dr z>hksJri(jcrwXkWVz+-Jv-677Ih(XcTa=gXX(HEp(E$Gw2>}RiZ2(jTAOliFAIGV# zEBt5xp!GNA+`17gyK=FWUr;RFuDs8~V#)oq28px>M(x@jqqSF4!0X<%08>QzJn;i*7)T@Jsv}3NxzDFJC!M`ruBk?L5zoLIlQf0>*w8mb6Q|x2w5chU_NP z3<@fbu&C`>q@v_b9dUTm8+4k0B0~(571>&B! zwi4by+)P?K%s;mz>T-~k@pTBZul|S_B;6_(G|qG(^{&9t&KYVU%!T1xer1h8JWk23 zut4+0LTAy6%cZu7m4?_LlI0O{Wn11_!gWMj6X%@GNx~>w=KBX=d<%Lk^=Q@<#z4=Xk!Cxv-Ymydy)a_C@(S+Y@fLR(E$l5TzQd z(jT=}Nw=%SjAmcr9j!QX2zpBE2w}g@u@kA?BJ^s>yrZ^aa0cZ>! zGqelx1V@Ku7;8JWXq(SxFs^qYr366bq9*8^AeuL}z{LKWtHo<*W8)2Ic5mI>Va+RT zIH}dO^4JKPaJux{_(hpcNu?0D=LXcFz&%+%bJz5Bmj{_kBA*E@=8mTzSAQW4?u6mE z6D$R1YQ3{v1oA!=$JnX`B)-VVESko_PdV_i?LNnCvbjtnk3)O?7?L+!9X|<5y13QyqCKCloqT z?p)W;lxiukeV_rh9$>=$YFFJ_5C(DCx&eVUare->Gaby5i_ZYfoi9d~Y+vgsqdADE5_?B*bsqN3eZ)19I}bo?Dg@bZ;l+8e|>-b(MP_Es2TSUQ*ZqXgE4 zte~HG*+QZCID)n9UO*l~>lO;$nmYm(%*>%k`3~sGfj^L3Q&`0DeR7xH(TG_S0`uU4 zslXIp)*K9CjitS>;Ky=sI<)6}PXOUk0_1%X>^FK-hP9k3k7LlNzqvjc@*Nj!Oco1!h-wcPc{nF41N z1sw(txuQa=&j{ptxBt^Hy0kj{c$2!CkIAKU9R8N){Z9*JOBa+jNM%J!L~2M$6IyfM z?v`=G9rgZ>5shg8yf|7#jcamT0U+57Os=qsWFt+Z+AB-icip#3yt`A7IzycWa};}K zNxhfSJayR+Sg!L?@yAMtp|FJfu~S^bs-ju95mB(2PGf5jYE$MnT!mF^Sx7EwDVsi4 z-m}N?`|+u4@uyPx6ZO6F6B?%V8T%CgC1K}9PA9k({?T$0Ikui9ly>FVTgL}mE3cl zdGbJ+JGYs(vg-z{qc)3EtOWXB(vCaK`A6`2czm6IF@*%+3}kOfdU9P|VNbW^E^a(L znW_X7=L~B?AFb|1`@bR94trkc+ebqFjZJxRy7e%s>@tMC^>VjEW>bq55+J@_%=@Kc zaL^>Jh9*(HpEof|sOHzEOM{R3gmjy}YUlA? z?KCQ95(G6}<*#!3!>Z`Estit)DU60`qP?6q10;e1P@XY#6D$iqq51mol@PxMoWCRV zVg-&aJBiVa+QjvAKt~F^Z$QpA;H@?JVBa<3&q2xs3y!{))^TL->E;-}nK2DZ7@t-7 zc3JSYBZ~?kZ1MvP>}D$87~DZ?;CQ+u74M0kD?1b3c?91t%m)Q+oL{Av3Rq~`dE*4p z(N*Z)-(-q<&tK@MZ|256#Qy11YNgTlb6yRBuPDk~$-HY{ddXH$`Fi5x|aG06%juM!R3-i8|@kC~^k{qTC$3;aA59tbv!3IBKbKEwa`{*Clm7 zuk*G}$>opC^_;_~E&i$iSqu7@$sK+5s-ikCauwsoR~ZgKoH&yGdsXHuozRXbGq( z_}4iQsw)hz$o=ORfXdbDP5vIS5-a%DLdZI}Y89Myy$|4#D>i;DxCpkVINaC`h>W2J zar(d#0Bq;B#8o(Sx}YPC*T0lnKHY$F;*abQk*!u0em1XCU;Svh0jZ}w`1)JsvxHZo zeC9<}x^`UlgY1WKsuPQhcMK}4Z)5CQF<&RA29Q&>Lwf0Mqu!`LQO+qejsc;pKOXh^ z7Zkd+296t<`~sGqI-UR7D3Wx^e=3##?^fsc0CoqEHUBS{wEtf03|J1Rr2h#G{O7t| z{Qtje>pvvnD)++yHTXxsCH{q(fWAioGV%WkrB=9AvBF8m|6EQr&zDl;@{3tZRj>q+ zV06Cfeq5pXOD5wtq1(=nCSwZL=rhbx`8DM8YIUchM&Eyrs|5%_Mk(Mxm+!K&Xm>to zKJS1DJ0B#WQFGl7!w)^di@Oa@wwFtY>>fW8eDJlM&Py(ezsKZ0pu2Ym+%WpRu67hj z70Wwuh05(R?c?&XZMoL23)7c*_fIu_!QK{^Z=9g#RaT;V}sPx)WJO!E1k zV^u``5Xo(iVJfr+AYIdk*=*A=mz3QZwMkczc^=!S*;z_T%G->)R2wE!nNF%kx{iNJ zpQ!Ur#{iM8CGnq#lV<1(g72wBG0eiZbTva&Dd_R|zsKkUTLKIYz)zM83H&2>p zu%1TCl~y-O;1kfDk>DV36x9Np>L6W|o|M1zOCDllBA;^VOuu8k$YEOI#ayq%`~yVV2hsrZ$%4LDMTlBRNlXI z*i5|@L+XPko1gxgRKOSnsY>lcP(h9uO$U4nm1z^6;mjDm@(sNYyrOnOyq#3J`a%K{H%ewTn)16Q?^%7h6E0`kb_1@@Q;`@g zCpWRHCyI)8HVqpm8k9>J@ft{N>L4Q&UzF76(>CRU_91b-RsQ;25UBaL^6=4^R zGa>zr+JYw7US<2qu2*JcU>%1c}RRE}a;p#a`~Z; z&Dp85YZ+JQOP5t(>ODjA;Q1Pnjxok4tS^68ueVyI$fEhtLd9P{2m-d~X0QTC-1ng1 zLIn(DQuo;rmqLO>c&9j`jPTFaiTgO)rDNP0~x~Gi5=&*BKD=tVl56CTEbrZDrtGe9ylF|Nm*h?J5y$OFTH*uZ^lHjU1mZz9DvL#Pr~(~0j39>09}4|b|Uoy-P}KU zo>aHkWL=1<+JfujM-)uSyp*YKTc6p!x(n_6FbdwbZpP-r9wSr3D}$t0I=(CW&3xfY zllhD3@-w%`p_c!jF&wFV#veG6GhiAm<6n3U>&EzeV!2Wxt4*Ow`||6z5tqUZh#0DC zytc$yNg_M!qB^n^DY!JhxL4Xvp;Kt0dMC=W`Qq*T+?9!s9MvtqCj&oyW(?~w<>qRh zt1mQb-@SXY#@-rYu$99YL|AB|3|;*swk{(hStT;#`m+xPw{~2jMH>*ctx?@saDF)K zJrLMr6OQ-x#Q4X(kGGda!88Z2#k!xj%G<0mNgYwlryW#=sM|@@Tvq$`sxNzEuggaV z9KCFs@=ThfGTWw{9rgjX_GvVSi7-n{DG%+OdPCq|nc=kx+NFFuo#QjbIh-+Z%4N~u zg@xVgggB*dFi6uB7F=wql)FUNNWa68KA~ovMi#RLd*NllumX*+xR3J5o{LCN>BYMr zFVSC{2pT4m^Rl=BEh~x{P6Y80CBS;fG+iqx4KB)iu=h}ZSVQPoRgs6qbumXmv*r6t zq*b{)jV6lvKSB$!s>q@?ZxL@OmAR$4i!i6A@s|U(m*!tX05IxKknVUZFS4f;ZE0BJ z|Fu>*Ka`x`x}i}RNZ5x+mP^@N)Hy7io6v>J-&!44 zP9sKD&aWH^zA(tY+KM1JC-6GE)rzV8OT7Dupi!~N;+aJ;MApXkiKoX#`mC9%Es%&Z z?<=U3Di`ep(B~_554~s0e@rByE~`Lp2#>=0`>#+aI5Ee4DkpjK3GQM(y!74$Y+8z} zS^0@H$V@fL<1lPwdFw4}JfR?%^Am8krkqbWd=xzPtT#(?3Y{hP(vuV#^A?H`;(k1i4np#Pk zm@9j_BMy?&19^3{^K~WEk^Iw(3)kT&Gp9uPD;__>#fo}{q`BAk)eqJk3Z8gH=qWQ{ zqA(UjXD%%^e4_@E%tZDI|_Ck zc>Mt3te2~cs~7b zZzU{ZjyvK(&@kQOTkS57dg)5X6W5cfTehV8W zTZ!}Pt$In5kJUaW&sFY05!^Vb>!)1|=_5VSB8ICZ;2Q4%@L~&I-6qdp#33@k$_kHe z9PJ2MDcb6Gv3AqU7Vf$|6-bql7%(I49U{O|8e4{Tbiwu>hebT;knHt9(0zm%dbxe$ z%^&c=n9c>o+N);XYnzoHNM8!vJ9z|;FRxg#Fl+czXwKY0WY10LZ^?vN27%>JW7BP^ ztB}a}L##OW95$WP*z{M;gIasa!4RDX0mqBr&en^LY{E&bhX;f*L!?&g-G@I5k|59L z`0s-$g0nR(Xx$a2xD%u6GlH=5_Whf+d}d5e9=@s2iC^d1?;8;Bkgw{)00}|mKwtd1 zF%j;a^H2~^`3`~#>tEJU{&U>8*REb*7ZsD8A5B&2w2JMedq5mMocrhB?p*Hda;uIM`kk`sLO?oL$b*I+7OcLE?VKojJw zy#hqJ*YqT<;EEBiTbgtW1FpMkg1ga~)C)nIt*O0tW=;Ld4eBSXs7<;c+#aeV_dxCe z=f9-;B7Y+x9tIBvG8Xrs@M5oW>TlNDD?6(kVr}CHq;_GDSc#u+&z${vN=8xFI)gaw zeD+nM+|1CDjF|z-r>fq);118^r%$1z54u?c-!fx}SG>vcf*ww6e)U-I_eQUMG>P1a zx=i2oZEj5TH}g&u_W=}=>4-@FlGVLN`Cd6OI1Vo**kpi8?VHJfWe4;dyFbih3@eR{ zQh~e*r&{ zht}-?*uR3(5tmYG_=$kmXnH7c@!6*nqJ(;CD=fqOSQcQ0M4BI7yn zj>%Ru4WEV-OO)G^^Y;lObh<5vp~bjyScay`;$FkD6SOlD39P}>hReVQt(I67hy@AK zFm_qjN9tO26Vfbb;%fVZw#wf;H{j%yt{44u`7nNEQNrA)mx^GVKzNLyTSu()-Z7$h zrqUl4S2sdwxfBhha6lT*b|dzXOK-Pka+<-G8y4gb&cr8D*y%PNo%viqPxI%Jos9X* zj`JD&_p6RB*%w!jA}m-@DP__^dsijA$I}ub8;>jS9`Si*`}Zvi(coys!ob^NWl#hf zj*i+?Vq8RXbl+0svK)K2GKt&QPkEEd{{G}WBJW^F9Ywsn-b^r5=18Kr^u;o0R8>-> z`Qj(;{>*~!S@BCchbc?}>TY;_^B5)&F+CsWS!kLwo%ckt9kbi!ErwoO?u}f5ks+Mv z(^GQa)*0BE%#zj{le^~vlQ4owlsAs?Yi;5K153S^Aeb>a5(QO5S%w#no$e_Si$Ff%v_B-QMNPOklgF67tDMiks1|o*QKoN-qIal0(Y?TWJ zTswKc{yL6eWZWlilkd*vM0>5y^Y24k?1onv*YB2no_+9>IurIoTC+=rgG_-Z;G$Wz z+@7L40r=N48wkPYk2?4o>5iqg^)Ri;8hVfbd3mTM*KVrS8c@?Pr5vJU#o{EqwBN@O z#GCl6RM7F(hPD1MzZFCNDUI2_O&7+6p3L>D<@n!iTwNEI6bdxHp5BXk)6=U4B!c~t zKYl8Z%V?lrpVJ4K0Weu;&oR;2hd<$YvEc6#VvbLMT}%(zIp*$`s@{#E^=`w)2~XEf z6Y7^s3n0u`z*M-q>T6k?=IV8Be+j;{dUXZ<)&gRiT~PEu8`b-fbv#@m9GmMDz)eY2 zGx0VapSvj%48)$!@M3Mr*y#{_ zbLW8M;X>cl+zSTLw{EB8_79JWeRl(kJ4c8X(L!C-e-LTR zyUr2c28B)BAA{b0xSl)Cp$=j}Nx79d%g{JR-*$A(k*t5R{sYI}2(uWk)6%1gBq?2z zs@ZieuIm`|^9e5e>e6Qs$_S&FR4_+T>DOfcJ~V%6<~Z8N$#VZhU{``hQ7B%}ugR#~ zFzb17u-V?W_a@jNmejkDMB2IB`|MGafQboXd8r}m9o5?a^JR|Wdxq?dewb7FRH1@T zjE39l{S#u=t96|8x$%OE25r;M)2wq#0d3fNwaN9%U}ov-Lb);*kyNZKu-&lREWvjz)>UO&Gz)x`)POOPwS3ml3+(TC z==(IlYwsPnw=PHw#n+`IG}-&Dr~{m>TX4OOr%G&bwyihp@hE^)qDx~;)9n0`)$_Oe zSy=oa=wGvD?VmX7Up2ZtO4T9KdAE!?nV85iMKxa>V=bq*RpBDA zV3|Feu0E@fO4CS~8^_z~gy_k>SNB0=d8Y2URSet6Z(C18kq-fhf4g0kdAf$HF6`~nT=to87an7woQypnkLXhHgW^8U6>sKXwSc{w z>>Pk%qP`TkYeP}eYnI4w=p0;xqWujBA7F+5*87Kzbl-qZ#rMEy7QP!0oe2#i-2amU^|68j#S>XBtus8WpE_BokNU!?9=yVhe{Q?V6{ZH9z0OGOwAKL@$ zSD_fjvv@28kT68$Ux`Tr!-yZjhF+-wg6v$+bdgNcU#iyA>RuoFHV3VmQ8V!x7uskO zIC&qoQ3cpgwt}NuuCG6~Fn{VodYEEwJQ|SbF0?%oWpoE^xe|7Mhb?b4u9y1YCl~Hg z-ypj)b9XdfzW&tE=b(HnLR&5>%jrwC?u@t>Tuv(0Xg%m1{WFl2bk z^j0)SoPCYAHKW&(^z?|-V*9~7;yW}5U`eeN=R_19rP&lq^(M+=I$cWAB6N#xmV22T`Wn97!a776zj zepRsiD|XP>yg4c^$(q64aT<^`uWNsUKUT3Ga#pNY*yf4$)!J2s%AFx*Pr533HgIq` zD^AOr$Iq_@7n(R8Gn_~tt!-)Je@HC;t}!qLc*z3l!Pi}DRKj_4{oytB99Gr14tmE= zyK6XF%2#FxBK$(4Dna0p)dFj_Vp(LI7?yZh_TXL{GB$Q#QRu<3aNgyUFS5gmP>szX zH56svb99?%zAszPRQ)&CX^)CW+|Shp{kd8mfHlTi(OWBI7gWA01LYCA?`@-a?*({H z9X}Y@D;cko;XhuSojX{>87ie1FUUh^i}HnL%`H`IarRm(npA{-eJaeAu&~p4Kc?AR z1CDnahzXEFBT57dzm^_Ori?F!#~_;?S*Cz9Y5Na)A6E?ks&blB7){^9*zY?s^dMlm zw5R@#Ve%lywxNZ-kLVhQ$d^FYBsN|HQ ztF<&>e3h@^nj)a?*?AFYz8#6RLe2YWs+oheFQv(l9j~d*)UhuVFMne9wjOvP zq|b-}QArV2W1{vdzFxX1#{bKL>W2%i4}H2FKc$!16_G=!VXcobDp^+uM%@?H65(^} z_O5t}L}0Mfd82hZvs7D*+X34=FkuZ9s_x~PPo9sX=@J#!R@llMb0}*sl0Ukc@OkZ< zf4UZbZ43Jx^1x}jKe+f$A5X!uI?3_MRb;~CR-r$4z;GeCCV4>Y>a%=2dOK3$B1wxq zHcg<`1P6*9;IEKsgX<3f&)%=lQbE}o%$L98@J>ygz z^0af~Es{hJC0OF9PHv7Ps$uhuQNabK^4kL^-;}>U=TVlRyD02f*-q8=t6Ep*Y%sob zvWw_`&70b^DK<5Hh$SLGgCdn)Eu#fm+GOzFkSoklD?M1b01JCP{_bzt+{o72x~&A!&X0{2la?YZC!UHWI*{!5s-3d~(@!0|MdlkWh+klHjK5%jIv0p%JcvIl=r-g|X zqvJkyI^?-t{^u`MZ-4sCnqAw?+HLr9>EuU$({|ESRd+l+!kltrFQDk2GSocw!`?Ww zCi*DB>sthyvj*j=;=XaB-NjXJSn}M-p1Qauyyx;D2hx~038f?ab9HrUCT*3CGf%!+ zlH8iK{FI}c@Y+4hKA8^U)6Bo-C(Bm%=V@36dO>vGB%3<)WpsGGWItu6 z#ut0J{f6Dzu5N`^sY1gJm^xx7jsqJ3s3%x#&&dN}dv1G15*|Yx7CLD$jbBel1G1Ou z4hg$`Mnm3gE428E)e*6A70uUdv%p!7>36^`>qshlG2T@qSvRG&u^RG)&Kz*_aA3;u zYeOHJAj1wwi_3PWXqWh$SYyHpcy8U0__y3g@R8lv3)UdtluQTAU3tpBrqNU-&!E?8 znX7fb_L5DWLLx<4L&e2YDt|a9sxdpn1gYf`jNY8V1_GFNm~S=zAsLNyKBUHMIhHri zhG!8IJhp(2NmqWSCHdx17 zFXb?+I&st)`iY`KuQoSe*PN*~JYDuA30UNF9F~PbMV}I!n6xa^=oB&s?2hoz#(c1 zC@tZ{9lDGHsBG#p{aV01tUXtXXToyr%}Iw>J)(})B`tY;0(xzN`|J0tHbco;o#cJY zfKZ0gla)xX9{zCd)pXt}e_0dzl!(s*-nG#fXGJm4V(c3U}Lzpz9ClTAHiFefkK#; zA7`9GOTvH*xpB^?IodyrjUntWuhR6B;M;8%E%zqYDjSnHm9tM-(*QmD{DEr^I>N!e!1tWxpB9JF?4Qf zwui03yJG;r7l@+$TFvt3TN7*BM(G6E6S}{jCb}d9s$3p0N10GC-45!Y@G{$ewi}sMeg^+?W@m7&% z$COxUHFQlfZ#B0Y<*yHtq2N9POgr8xv!FOUTcNh1l;2T#Fa7xWKLS%9q19K_MgddN z{zAgKX(M0O_+vqAaHlVzT`R1BG8 z_m^B2R$N8Mgx6(n6@aAsJ8a6Y9IE8=82!zgH%o^m$5meq?{%EC6wU^=$++Pk2YxX> zV+0n~_N;#dXkA}*tTt-fVEN|fM}AK$ui4|;!%?-BY4KlJ*42!!2)n5!ee0qI;_p+Y z@!L0(>~Y(pxrS3M;&$}x5#wOGJcXhrwvnIDpdNDlI2Uui)u>{K&6h&004KD0lx!?T z$9SA9SGvR{ulb6PSA>)My>WBZX;E%zTE2C`!{pU>A2h<~AS!LBDg+3}#MI>j4L_Su z{amuomlZ1{9i0KW>Sz)gUE`1774@3b$hr_GcY8K+r)z0m3e-u9)EEokgbVj1TWO&6 zemGk{WwK^zu-YpVczff55v7ezqzcI&nE%F%Yu%i_nwbi9eodyGDyC)Z#y_1|xJE*= z>J?F~?7@BGtR}AQNcwm0`L7iM(p&pM+?`E^_kY0FxUnMoh9cOU**nF@!~~2-$0M*B zw0P$+p_18lXN%C-x(wh}qAa|U*ghrPH*@oFn5z8#WA$s?TBL3~bS)?HqC(0g=8{`Q zWok3Qewnvry=!<+#YiJfyZJIv0}vSgIQua!8Ws4ZX3jH&ae1!w-6vMEp=Z`swJyX; zcL>V&=St!E>S#)40#o7Fu;NnVflyY7`bYeCo&66KISE^R)?_K+%iS%!)7cgE^+9%1 z@igCgh=d3__!QML0)nQC_k6y2`j}J zY$o2>Kq=%$e%gr+&N~$cw)U-KGW|3CnCjz<672Y?dk5<5*q07QUVSxBL;R%c$Jys4 zq9I*IHL-KeVV_>xp+kpybz`Vr-K>Yc{3wYlrsyeMQ&()0vfPtGBD_lb@7h@;7a#jMWB z+y-*ZZ7&(3t*GV>_Z`RaKW1R`>6p+2Ad9Qr-|w1Q8d~+Bw!BB-oR*eOMzY&`su|s? zg&MvrpTx18!@hnR2(;ry`M4G++8=-&i-Aem6zfP8bgfs&sE*%NWEm>;c0MF|w}A~) zYuTm|>tWsf=72svop@j8BU=0_$;YnHY~)ZzhTfED*hSQCEJ;P!uBU&e6j{`&J#dsK zE-o~(?4!pwgAt|TWe-TK>21UC+e*Ee!&h48wtc+ND)H{|{Os-A_8w1lmeQ532O{#5 zZBh#KG$XTi__eYbx&X@Bz*BYO?x9S+M)+xZlWFZ)RuM}FQs8B7U0qGl^qSM~m6vsA z&9&_NOUu3^4E>H_L6P-Nq+Sv`v{t!2f45#@cYK8pze;-sXS}R< zBHrFSlI34d8gay+InwJ1nI{)NaX<-5J{ zH&OZJzQQjr7DD&erP!_EbT^W(uv)hF)^PJ)7eW-$4c!_ha?E5`xkJ9l=2d>LE<89n zJT1hsC5#v%i)r^GuLsP}VO7$_H;Tq%htB-(=PO`e^kYT(2tK0oSp}x(PwRIk+ z3-CE4Rx>Ta6xOJ%wK*zwRXLhFSz(00hZT7r6@PNdOC3)FShC(EZ?GX5|g zb~Od_S8$^<2Ce3~Q@x!M$H@HGOh&Ykq6zkM5KdPhTL=;gHI+6PtA`XyWgx$8_UVw0YGVuJJ>P-wP81M7n@g0Duib6tCfIuLGF60jKC$NEqSa^fF z5DbAGF33kStjP?|t;pmk>lUQTpO6bdTVDbJ2Oa#xrtti(Th_@gxw9a#RXqh=%YeO) zzKB2c*=V8d&X_d{*lLujt%GBVmHI;-PPd8A$^)?kIDdJsC30-s3i1xt(0!iH$;oL_ zt)ezTfAlBao)2k|uO;A)()u{K4kc94PpBBzX>5f|UNTeDlVwQh3W`!CPA)54^FNF0 za(vYJ7M}eE@L}h@CfS@Ea`t*guB2db`vj_)EZgQYb=<4!&##R7ra8BJ{&m#Ly*xCQ zU5iT2s*kzzw2W|d1bM$0%?4X~GT~^!#a8dl$7b+1EvD#KVvqPo8R}-MZgtc}&#M`G z{Il`*s+L2aW#lQX%M&}@{sbnP$#NqeMr3MKe)~qXScdVzTr%e|q>#O;+MVNb>X#8Q zAHPfrU@*1|;K#y9O1n$z<1G_P(Cis8mm0;*7k5Fm)!?u5w@YEJM}!;#fb=}vU)pXu9? z5=h)ljNabiRwEVr#yt_KwOMecS6z0!JTyudnzl2ZzLu-*wX~!sisyy%&GmLf6=DPU zD;PLQo`3pI7>*v70d_E=E1Pq#n`bJSl{wj_tFh2^=3tsHj%RUXiXJ@W9gdsx%$rGs zcQ_%7ZL*jRFEPCfsjBlUwf4iP#77GionJ;7q8{Jck(w?}@bw|eWmJJB?Q&L{wZ;vd zy4ffchuD+&4(ilG$5F!j(9Q&yz&`bf?X!(NqCijHiAokr={OU#DKfN$5&OOYy2ej$ zTXY{Z>*#FNf6fOz0g_G`Tg0&bs0$4;+hIFtfi+&4FJ;>|`TaNQdcxAd&5SbQTF^l# zB5-iXK&^CFuUh_Y69(T}%%l)5TjUlf$7!WHzQeRiJH5J)IH1$JlLoBN5Es@{3Gld8jbkXc3uj( zg|lt_chvi`b5zwz z0~vt)`{kYRpN3PSi$=z!PIm7b?iR-MEOXy{ZS9Ox86eRA8^B>6+5)aLJi;_{JgSka z*fC*q%dfocs#poi)jd<QdJwE`3QL+rgHJ`aBpvjOWy-@q!)AH774ZfRe$qrFN3 zKh5=|yyL4agwZ$0ly(pH6xC7`3HxtZ3MqKMGo$9yPFFK~%A4@{vI?=%N-^L0{8a{Z z$Q1I&K7a@w;~p(P_7mstf`lJt$rbe4Pf7VGQT?e|Gv*y{q2taOZ{l7*{wfrsBa3nvlDn=9=?1gvTKed z;NlNq=9~iS+7&I>rwA;{JA0h_dRvA+aUf3YEz>J6De5fO`%*FMT$C6}?`>UN@xV`2#d?z;T z;}J4h$n&4AOK`=mLBKP~!UEIwxV_Ndu>Qzt z1}}H#qwNNV<5a!)$|GgbdE9ffSp3R$skY(7kLcpt?aoBRO}Vie(x5s?8R27dx2P|> z)*~^ZUIW=!HopMskA<VW+$}(;9oaq$Glr!c%g6l|fE9Ao0xN!%-@L@_54R8++#uKPHGQ!;_^m3w z3$PqErHD9Lj`8Y3_b5~Gw>3?X?8(X`O~p@$JwGLY2!k)j1Mb*MDI|Iqo9(5h$3)St z$MRRH6_~tF?tyC1oR<9llSG{C$ZH+geS()?vsb8bB+*T37SZPm_-hn;^ICCyvQJQ+ zZ3wdT1P~3yioy^5+1HeS4B+IQJ)@S)oW+s&1LB4sS~~AnxFklk=UP1LVZJf1^lD-p zd2_y9+IN3{^97yQFTtX17Du{f#Uu19YdrL@RMc_D#iokBZ10pKw*p#WoGMF>D!qvI zC~%*r+DIQ8P#h%pvbrI3Gk*oU+KNFXb_f{Hy=t7GJ+#2TKr{-TZL?ipM{eOB0aIis zp78I~2#MQpeIkjQ%eiEGQtNSS@Gq*&BKXCsLcJ7#Yl!JrWF6>dbm(){kKB4;CT3$y z7TqPU6217mxdd}Mf2CNOGL{+ASxaB8%U0X)2OykuC;2d?D(i1szXO2_n~S5!+Fy4F zNZWJ)fg?OM@F6^OTrbS+!B6rhc!^Qs)|CCoa|l*h_EF#{381>XmjLWCfHXi>EU;?; ziy(2-s{aUj_9rr6l4I@xg|fy*Q@;Ma>5MgksYT@i&Bv|UxoF@#cw3&qUy4R4^0vvj zSwG+DibW_e1}IkhwX;Eqk(5PRZ`ci$+V6TIvzz$Q+8u6t`aYs1HK|TNZ0LU~=Qwjn z%3ZhJzvJ|fmg!P-3qgCfcn{+-b;e|_-e_FYJw!eI;2^>3c!fD;;pzq!_oPdwV+t;X zwvz!)sjT(Kc)C`8cwV_k&QBw00J}lL0-eJ)@dtpR_ax|9MpZEE_=7g`mT_N2zAvKXt0dJ>2e< zB+fTm1$Jzrr*8-$Cwd_Kvu3{aj^zhOM{F66+G=*zmPdir4GFH$<-EWS78JlWN;%_6 z0IqaTnFOWmHHf>Ng9fn)pInz8w%Cwa%hw^klDx99|3vA^}X9APm2EFq9 z1?kJTIeHh|tcS#)mu}I#e)HL(g+|c=zZ1Oloj12|qyBnGdR^=AG^5H2z0)(c8^l4t z@XB>DkkOeE)x&!8rwEc^AJTgW%9jVnbA-7(%T6NYq_qHVovh_Nq}(NU z;%~g~?Df>RM=5(i!l+S8vMgF*{+$%j50~8#{lnfVJqV`uHR(Zf(p{R5gVq#b8SY;x zlVAV!A{D5YypWyTmCDOsakP1f?`%dhf17$|rJ&Oy&-vlO2FqLS?(RQDnZ)w2Q=Jsy zisppss>^0+0}N`ipim`-qu!#V?9lT97o%D%19?0BL^a}&@7XnX4t400?gy-Hp`(mc zv~9c7)o}67`A3BT&v&P2+?1sa7Y6GZDFCnLnT(|7<@7JPRZxgn!sQhHSxxB62g}SQ zRKI=Si*muCt0vk%zo2;@3bOs6F}M}$bJ{4{0-{hP(a06qn3!x~%4j&=vWm)=I?b2v zc5TENA8u~Qp$CoVohnzIzlT)U!Ft>9`y7IoqHclIEl+^BVS4K?J~neLZPJJBAn!PwX57%4eQ_WU(;WD}Glk6x{ zcnKB+B)6LoU0~ap?6|- zckavO)}Png*HK5lfIk}$h24XH=M?u``fV6DUNaWmp&xEGF_yjMo= zz}-H?d%Sb~P4d-nR-M`ZM7N*U@&4QDU!i(6e6U!@UU#&3AP|L<0}Q7O2mZU>L*k_w9y zHS~~Ca2B!y5xC1AWY6dxhb_+>t~E+jV-J_1DLyJTjs=JpPb2z{2)B)_>u5LY3^nXe zs~4LZp1EMBzw1XoJ7ky*{3$tiCB32>UW1~CM*A0S83xpK1Ri`_K5+hGehTm%So&6+ zu9FcwyIqPjfmdV^rVu%|XwZAt%kD^tMO;f6Acjw)XRQjjM0We_Gm0n9UDN6<_N6Kd zX>zMG8@M(i_q(MhTM-L0x^uxsRTYpS!P<_Ooul zbhdvYJONvg?T7#AE&9JrwE2HZy7_8M-yo47Ae*#lU%a^IN< zDgb`1dtJHxGP}?JYf;f6$QIF51C%@ec>y&o?hI4@Uq`tXb?*P`f&a|fz#(7)Vt^Kh4*65Tp@3{_#-^& zo#NL4O@UICv9YvcIHk0hu`N%4B~&}Eqi#uvn*w7jeR67^i?k|yXPkLBK6ZXNw=Eng zsG*dT;+4W6JIOPz@R3l9 zr-U!_bO1fP5>TCP^e3-AZ_Lc8yCZGu(xMC(ZSo-!!~1B3x*FbL>U2)RCm=-jAnEit zxC)dh0)$N9B>!U6AzgR6-l{oO)t7&_<{}Cikvk$K@ve3&;bDEDV6sp%KZ=rG{kCS3 zO{bWWdVOi{txGkt(@N^>r@q>F7^s@cX+V4Fsp2)zM)B4E0pq7w|Kd1SLaJp&3YFq- z@3`xZH(Vw&rR*emnU^dzO@YZjY^p_CU5-Wfns>6|g9Nzgn1^(VH{(<2gI<@uGO@KK zRp}p&Tc#Cnx@mpLy1C$~9$X{Q=FJS|TT$G_OC+LRL4CYRM8&opGZf{kC#?Ib~RKG>~yze#MOG275f$H}KwBT0|sWrweq9 zxTo9hCExt*)RfC=)UW`&D$xNCxqliwi zO8<`YYZ9$Sm%Or(+W?D)wHc+d!9&ghudf0192pckd)n2trv6%4a}W6xNJ!z1x^@Fb zI0)pv2aqvr35e=4OyyzN{LV3~zFGa>?R1Xh`48K2L0(UsH##b~$MdyBpX4)T3)ho`vdQyb0}KietlF$4et)A%=oFG^V=dI5mee9JqXQt#q3Sjf+O&Diuw zA6iksGeL*$WKt&$4+nrTQTv{6Ov(pI%Y7@kD!LysnP!9K-I>KuMQ~{&$LIEMmj@#0 zU(-_wCidNBJdN`?!1-s{&Y5?{f%f!#baTY#qCa|%bEPlu)sjoL^;7lo45Yf(Yuo3I z;+cDO1SkT=jz$U_(KJ_(pB+mybyyR= z!(Xb7ftHm#Wry5SVzl=-gWAXiq$5wE2g3mPGZ-^^bLEUG1M^8yU6zy%92SlPjR)C- z{!YmJA6k*+vg!WzpOp``BR~r7PXe+UpkV>j<6z@r)pv#V*-#G1!t^=O~IDi6$ zX^rrpp$G)bb^yK-o=%+ zorxMm4}xC#C0X0-0O{P35=5BnQFT+F+{?+6__)mA~1{wx&BboL}j`tiylKB)t9Ah$pKcnEd6xtY>+Q003* z<2Jb8`SXV#*EQhW4a;gK0*DeL=3rFEwC>d1@_q4xF~bta&?oD+!d}%eMC_k>Y*TGl zmod-~D+-79SMNLZz@vEzTu+ZCf#8dd$meC*-~UhB_*|IZgRzhtgKca;VP_0Gq8z8- zpPvmBzDLwr`*p}3DK72>()-W*NuX)E7-FdRJ1Bq&j z`SBQcL9?+CK3m1*jD?~_n&mAI+1uq6V=W@Eb9%pLOC#K3x)I84l3|dtK&iM+2yK&G z33gy!K4V(V*wBfd{BPGPN_e53Zhb5V#kS-H$mA)+Rs!9m(1$!${|HJ=2!kqQpU+rj zwg5Wn4<+lNx#sg4MO*f1My&y+!!k`f*AnBN8aat)Td!M$5ZHS9UY66&e*|w7jb&+3 z7hQc|ei|HW0*{f$s`xFd4AJ-sg1rT#MweHKb9C#8mS|iK%hgkE`stnw_L|B#jjAc+ zdhJVArOc$1JK$Tjh=Jz1KgHU2Xb@B&>2(E?b$+%EvA~a{%8Hn7#KGkb>?ud%IZJ6N) zi`8eLl9zkUE>nr!sm?JTND{cH2wgRM0}Q;>U`iXi7H`ov9|~RGPfVL&A$F>ssb-A@bsuElPul&5}ND&e5$PaCx}E@BycwV^%H|GtB-ALev3X+%2R$U?*Kt( zex$o`vxcF^i)fNZRu-gfpS{YY^>p8FMidgA)g!pD&O_5;>H0%+WSW^8?)I~$IAud= z*k4@ixGK6V$ph7CIF;Dp=%)4rCL@vCrt;HF= zGV<1ktT^%UvId-VpdJu|86ZB6)3vd7wptxjXE+!dGFto=*0&oJ6&)bjuW!9hV$)6^ z8b?waS_NcZU~EWF)aHXZrtZ0##%VP->NBKXJ2cB{Zhm1TZ;1;W#@qB;nWP&J*h3rU zPt3o*pZ>c<{MTZlg~l$GwDzMZMv3i&T0^C9FmL%n=RVbH3o&Y=g$K=^kwSA@e~~-T zRdA4H@Y9|W@+CHNU3VNDm?LMgV!XpH&gL)V(j0gk&A)AC=0;~}uiY_*P1@YG&R-gZ zKL6M`p21OcVVb?~gTw}%>Wn6vh0Ar9W z@3GrN0NN5mbWQ)%M}F$Mu>#Q#7U6vGoJrBYcJz|?Mp3(1nyMHI&FQk#d9}*aBkR{s zl|q#?gP>cA+r}iT2*#O^T2uZmvYz{|3XB~7KfEUqpA{xZauqa2BidX3`Et1gDe%0RTgIi1iCGfGNw)86?y zv!@~NU5}k#kK;`5ceLfhs-yzn~wW{GU@rN zT*H)aM=K$@Ru_3L03~0;S7aeHj59QN-)fn4sF&5s`1VpiD%v$C=HbhbH?GrqNTw4U#x-}F%s=_e9|NaYMlIvebO zoSTo8;N;Oy#+$Td3Q-)0QpcDF4axJq0$dWDcDv@R3b}@_l4!+k=%imfzp0%>K=qPD zrIOf^#v|49@B=&1aWwn?2uS_xiXI&*8l!JlJc)T4D!>};)%M)yV*8S)6FvH=NirKQ z+u7wqvX$+^glUTi7}IC)tRK1knN)iUXr}7;kd3!f02YrR$V~_gr`d4r+~IhC#qO_N zhV>qz;!UF-e}b9dr?|mp_p$RjpKo@(se-O5BQCHbMNw;wYOZQ_8*Z~bUTNGY&8X-> zE1}4s^CMfSlvvTkjrPicPvIMR3TrZ6Vw22!{;-}fqhp3{sp+neG4PXR%kod}=kgv5 zWWNh|*~v*@afYiydP!t!RkN$x5u#=P8sRzPlXXM5TK*Of`*An=1Q040z!O(VOZ{aq zNAU%tZXW@(-R36`bWH8mfdoKSRP48*;ry@t?K`#{sk+Q9BZz-~^|o zT)7-R@#%hct`f-0%lziswA(s=m{D!GAIYyBu@q`$k9?k2`pF6p<}GJDzvf^tw_Eh7 zcvz~k3iT5seHL3ijPp`i6vGViiCV_KXxF6jnqKV}4$Q+4_rD&{^LBh1d2eWZSueV+ zKW+HW+l1u*N&G@=~k{~Ka4^J{TirBuu!7f{@BUh zRo+SL%vK@r<_+Bk&L9FNb$@14V(?{=X6cL4^!f2)#o)MNBk=E16~X?(rm_D@A266*niHhih=On)z1T#KW;xxOa5v z=%_b1igdGTgV1^$Q^8w$6&kC?S*z+!#c8uYuJAZ@-mPZ}voBp6jmcpBgHtWAORh;Z zmV-$vl(K0UeA*AY0|{}$)^;0#g6_wc?zVu&%V^%llH7~BaNO7rKIy;M&$qW~cuDL@k+&6e*Ch(-B8OuKN zl~*&O)46fft;Y|xwvVLWe^g{@+<7;OsI!7+oggtIpn4LnxSH{44MaM-=hecgF6-TS z{3+5eo0DMqi0k4=5y;kG_3o%@6J z4@38!A8zxw)xQrSMqsHQUg`H*!PYiSU3IoL9OY-7vc1MP{AEd#>9p*1F1-^RO%Hwf zT7^^o;+b}m<4p~X{4}dhoW4EGtg-#mM~FOzG9pImTEm$i1HipZn$L$4QMPoGMv}T$ z57s~X+abtsto*@E>N3CMsNE7pi>*F?xmhkc!^Qb*-VFPTnT8dLGeT>(qN{7U^mj`e z1Hyu1ks4e&Onip?Vz{ddX~;dlw-bJ#oZ-A#gE=m-d%2PoM6M|=G)WLgz)_uJ1Z4?Qs_iklH$jd&FC1%$~0PVXr||=NW9noDm{Jt zTlxWVa|&;c($7xT>EeQ=`oIP$CzmgchqgJf7i;r|IiFQ|AA=nU5Q zzBrkFhOP}e)wH^-X@DZjx_P8ge#}|1zu48l6o|tE;m2MvL=`HayuOuZ3wh+Hh=lvW z8tfJR5j4GHWIvYTXj^eNo^h3eulH{jO1cP$G9-5q6Z)C*$`%v9UCw=$#*Dm|aU(b{B=rj;j3v;n&HW2sM}XzELOs z9-0i^s-!A@@+C9Xb1!l(=u;2QyM$UkpC4{D#t3(@kb`vrjWN(P%vw>~SWarfCTAsW zz)jHpa0U1$bzYBo-IF4gcijiEj2qC4_{a$S%@g4fLZ()!oi^=4Ox`A~#Ln50l%0)r z{b*D=dsvkXff-nh=Fo34R>4-z(mhPJDV9x?r^x&{^%xAB=P?!Ssbpg{H2JfWIHib{u=MGOnzj zAkER!;b%9@zRn<)TQ%i&HslhISRbr^XNP!IbyS4b7}U_HeX zIOrNAEZ%?xaP`fXb{Jx(Tf;ImZ= zd!_^Yfgu4tPqHGp=fPhA#^?W-oWx(QwuO#OaaHo?Nb$Y}@F+LK`9%+WnB%a3xgO;? zk0(PC0X;JpM6YrbBp!j9E7{ifx)mqr+p)|skS^LBhw|8mY2_ER0PI{87y)@KGOYM& zyh(KR3*5a<)6AsMw3ki?C&_jpQF{CkJH2}Gx#|Jt5w|CPuC9jJPcVWu<*4!JQ@M8; zpzUtIB=ZtqqDfP+ZNpi%8ddp#MQDD`PSHeRQG`Nr>4metB_t$f%g++cePP`s@sFVP zOA#QUwObqJ?@ji}T}s@X?R7tC3SHyqNLyJE^S#pJ??6)T`VdAsV`4m4+PB+wz;!=@ zh5Jh2Z(T0zV?)q1I^#HP(oFx7eHtToFXCf@I#1HH6~_;E#v_aB)J*L4Vkk@dDUUL0 zVw#tQUaWl_N$1pUEUe8ovaem1Tc&H>$k}I6f}Fk5!-Vxr`~^d7Z1Q%*wlyQEVqrf7 ziiYkBS1U?hMXm$c-LZq+0o)B!4y^UD-0`%tQUw;e0EYgM73*(r9=5+~S8bSywwQhY zms+{0$21nS*m2@^!~Li5OD>oMQX)5)z%Ad>FC&%qwOc2aFaLL{$?)F!@|M>!74BVW z91&IpDD;KViAw9GZWxuvxjBYo2qhSPMqeBoLhh7!)Pqe#4N5l?hI-J8CId=$$-dr# zc-L~FHP9DbEF{bJ4a7bQKS{ImcAxLO%MdD8ihg`g7aV=}Ncs%Wyy1*m(06%rcgmSK zl^#_NL~SO>?R2@b9K>~{p8m!fjS@17JkK3TpWi9Fa`rXqb@Y>`UCVgp;a%_ezM+w? z(deRn%@e56(xz}u`1D-jyLPM}-^g$qL zNtNviDl>NbZGtYj$}l%&++B3z=0=bNM)dV+Yuo`2?;q(lw_~i?Ck*+J#F}bVqMJa?5UaX1sEab>87%&`tNPAt*Z>_nD z+h?Vsb0TurDVp{w2iGpM;9?!CovYA(RX$(7*ERU++fF#h%G5lcXQqhBr+@|-rRRn1IK(t~# z{yR`gtm)>w1|?mDbDNGET38Fo350!EoxrvEqr3_0M)O6?&x2c{@G@ZOd;siqe7KIf zU7(7-?ka{mn!qHTU@_43EX)~?^rgah1ZRk6%d!?J^?;l@P;mK?nG za4^d%7%%GFyTl6Y6F(&n4x{}`hf)MT|9NEaCO*y8r7~&cr4v3)UpUiGy=L6+T`@fM zLiyTya_Q7z6E%fPXa!QjI}zAeLd^u9@c_fH7J{ETsTseSz3m85&B^mmIGfXkfGb!l#V_;?vWtoReD#j_IzA@aZw~O;IvYGFV)zae!X00)2x)f(oUpg+|i*d zb#^h0uJBp1l8G`!l~Yrw_Gbuvw0^lfI=l1FY`4=Ax#5sY5&4z??WgIZ)GOi-&#L*% ztyMFw_mWypyE^`4>*1&J*_)7VeR&zM&-8Zhzg;y_;P$8SoPqu9DBzvS^8{)ZHSB+5 zC$p^ZZ%82ce+2nJSY_cB_RIm6z5`UVTC6tz2%bi+GnYt*5Z=>xxRGea zUqmvO{#WMiaoqLJbQP8_Fie)Ph8{=15aZ=$pZP1*I@zG}U8JKt;|6I6@0esHh3itBLAY9(-M{klVDwpgNo&*`j{ZG$0O8n^gt<`CwpQRp0&>R@)K$^(Z#H!keH!Cl+Co)S34fW;~}*Cg;~%Y#D@RzU$T2{p-9gI0-O#E;=8ozrZ>wfj{y&Jg&`yEq1B2@PlYV z{nF+a?Nd?^n9TLRIs(-j<&S=*z#Ntl@r`I`uie_AA+Li#s`{rFPBfpM?wB*Dht=k} zn9_8uBSMylAZHycH{{&?KGOw$ic?j-fMNz~10Bam`xYMPNo*>Oa)$@?iP}VHIx>YmfI%6jw!PSdxTZvn{ z*a8p|1PL@~?geSNqX*@|8%?2aKbdnC6bQ@YU3j)#D-z1`pTs^W_K7VofNAye<$AGC zlq)>bPpWto8;mJSm2_00jrF0Z7B7xN#K)+)bHCjveKhRI&o6{Dx8K3DU=yx8@Ep}m z6}8Db^(Q$s5vn2uK0(qM>kE3@oy!lfkS;x8ll|0%bMkqKQ%gH?5o?(TA4c;b_@V>z zHNqfS7CAOqig9_&EbZyr#}EGz*z3`;&b-%?Sn&CoL7mPi>2OwY4JgXB)tCtrQ^=%> zxc!gt>&3G7|5l|3Z1?<~T~u}1_#vOFm`qOgKd5{2cqrSye|V%QOWN#Z+9^qelrUOQ zq$w?;n9_nINwUvLwj!w%r7|L^ER$?4n6iYc?8}5KgDlx*7-QD6=QCQauIqPy??0Z` z^SkfY^T+r4n&~``IhN1o{r+snaeRcWbAH#?f5X$pzhkaJw9boc_o_j2(xj8)G)rM@ z@BH90@=+dKLCdb_YM|afz&m?3J!Io4#4Y=h=u`cPD*wTppf361j)kySJvi0mdKEn~ z)c$c0^X9sD{ytU@LyEgza#nv1KlkLS?Uq*=O$JgHXE$y%th&}{;CedkF%OOm^2(U( z%(&v=y70)C4ZVvDlxSJ?n_7|vqe(^4U6-OeD;2DbY2H#}RZ`^DN4+x>FG_aYa__k2 zTgTtbjy%=brn^5Y?j2`xXZ4~l4!!MjhD=oMRU2g4JyD;#UpCPC z`-{5|I9J%{4dh+i&zSv4HNsF$|3!?O26yWmaop+`drdpF>|)c7F7LoHH`Tthe|gfa z-|zK(Y_vqTzDSphnAaBLSi+4jcI-ecsY@dXXV>UG+0=Snaz5$!gN0Cr`dpQL$F<9V z$XWc+V$I7}n?CONYk|lF#$Ww%u8N2E?WGM)Mf+@=S2kwbUT^WbQXCt<>o0dp;x5BN z2LinqHCGKshG7NF#L!>kEf9z~49=JF@h7j8VO4K*EWy3f;1< zw8oBN7US9~S|#pKD7$QBg~PEEt$Fcj_<^J3YlUjty9r`8PI>g*Z}N2w{cag6rA?Ra z6d9M}rET$eP7-$=${tlJ^*}sbog}tuj;h{R+H*}LdLlzN;OUEl$=aRucM{`cnBU&` zEW#d*qOMZQS>E8^n^Qk_8qGoIdFVWseI6Q`M|9Oa);%mnhab0l&JC;5dSDgPasN`m zgBCHl4<=(l9+L4|>_aJ$cI|li!Fes!vL*A{Dps4%4?QH+`f_IHM4H*;hEKXL;S!#T zHVx%BHW!Dy*!=C!_LbdH*L|5I*cPrv-rf1LKK1|2tr`E{zOxFaw9Zk)@p12U#}^WC z7s=z&^$}2pJ7?~$a7(qa0t2zNtJa%Ws_HD2sx_9i!JNKUYmAv*8+X*w{;{a`>1+GK zF{@TNrX-9kI325f+i@B*!E)bD(FJpNRW7WrnUSPzA8rJNwj$>TO&k*=r_sV~_82&J zH>GYBbJ~Qf5DpfP!)weaU!Va4wGdEsh_of-?ESLY>ccGt$iw~9&HN2d=MueDIrnKm!{ zXxwJFz`$5mR~QX?HDkfP1Mr@(+V_9sf3vd#hKb7jjgT-65+ouyhVNOL>ZmQhjW>y8 zzxq(!^fropx`P`>8QcCHlWU1qmZ2t^Jg6{i$r;{64yn?*c1r5xK>fp8dB)A&*b}$E zZn9w?KA0+*M0T2j3jLm!0~)FUX9y* z#!mH4oTVbk!9im&NHNUkAC1BMnW7lspmFToep)aGv!lSz$b@ZV2auu@G}6!B3C}MS z9Q%ap>!V@EWQO!*#)vS~H850{zlVyYS5hXRadBI3K_K7uI$9q<})`qEcuv8 zx0B?1)58aEHk>^8!1B+vkQDv37FYlCTIB9C;dt*c2dWG%!(KGh*rckd8d+XyjS44g|SQ`kp z)-L#t`9nR0B08m>4CFtmCo6wnIAKr>_kXA~1OK1j*)qKCqj@kMuElklbu4k$*TYo9 zd#Z|^O~_BQi1>{b$bU8c4*#0|zwyXLIQ@o7!s-9r1dg^|h`%;~zh%PX7XMI#pE4(u zkKbwvyzn>NPKn2#aQzRot@{%)WJLKSp=$mG^`ielH-QSKx+0{4G9eY5_)k>uXItU| zX>oA$fL8!)gV4|*sA<6patrVvs?x|0Nj(XYs>xqz_j}|ZcyN|vE9YtD``*bl?FwA@tsyA_&*s-~952-pg>6WQ3g3 z0s{BDzb-y$#I^LHjLb6fz}lg0&(nKO-txg{*>wJw^9IL@{`u}d#~L%aH>>{G_-MxP z@bPlO2JdNW@n_@Jb$`r2u~1iqGw@&PDhLbIW<5%PXJ8u70=&LJYHAQVAbjo=o&H(` zsVOe`SChD5{%^$o2V4CyZ-Bpl{DR9*7W_%dieNiTv7m5irdV)lX>fVtzj^=XVt@R{ z-2HR>KiB&2k<#z7o#8G%p<%L2c%CuZ@m~@3Su9f<%g4Z;hHMb=--|Rw{K9peBK{xi z`db!%Oal-3Kj0|~%qQdz>j{M9m-U4IX-G`TNv2RvNdK~&p8ZK{>gQD(B4Hy`XKk!RG2iUH3VU{WflpknK|#x=*;W z&nSVq_0x*~P3zYvF>qJlFeS^C|B1kY>bD%{mcdfo=?>0a$}klI9n>6Z@6oLgbKL*+ zJLYi`b4`@s0~S|Fx=RF;>}Jv-h~HBHBgZ zkJTacHAu)}eN%VD3%&TZl~*=S2FMM?vEjHP{cI9n5=%4XuZIJ&DV)A!r1LPGJcwav z3`3i>uPOP69;<_W;ydOlY5b#*c{0%jNHLbb8-B-T>UR=k=CyaU;~pyi(ek~2wOq~l z`n%O1B|a7SIi zU-`N$eK7mYkU`XS!0xNj4B2j*sNoazKC_0kXV;!=+`+2L*UYWC^Cj&-XJ1Pi+nq(C z%Y=KhYRumgZRz~BdB=L!+|_TRo>fl^Ft`xD#cBmZx$9C8{jEiAgU9%V#jkFc#P2v# zHROO7K1rW?$hjLUcV^w7idy4@x=Xup+tB3P5rr*w+lq042~vrb@lT@N zeMnW89TQ|8A@*JPl12NY!K7{){f@DaE3D*O_(}6N`iVsU6a|zMsG4_)0~Cck(S#RF~b;>2wq6ceRsH;Kp$YUAW6Rt}O&RyaIdH zQvcQMGcqp~AWQfSE3ULwD|qy^zs9pq%3OU7Lirf*6;Kcs-k_|Z=J10H&aL<%gt1O$ z0v1_JhW=cyViisuYg$un*7=n74&WA%56Fx@r@K8<&ES zY&WBemWdTuvE12FkN6uH=}qb6oT8S>lk`=g27TVA^rLo*?v|mLnz7%qYG7$&Q;^RZ zIOYi|z)vxO4=55JmxoTnGRPa*(X>V8tcOiq4A%fT)q0o3a`Tk?#;}!^hZ!)4-n-Zh z=M0}vc7a${Y@~Mxg1{lEG4_ju6$@l&!L7NAaD6bV>2|dV#M*dqws)d68-FBruhNq! ziRPne8^6|n+8UITRX+Jxyl}62*+rx!mDc9Q~ic_I5*+8hDG|g@0jE2t^%bTu3JlhzAo$iX+m)4WmEp{CH+V{`HEjz zS%+&?VY?9edu~SYW`dEEWmVkvRKzoHGOEwKKnP5u#D)C142RN1hTnL_6({YpZ*Ny^ zSvgkK^}0LCY%pvnh_Nne!p2l6zX>w)r$B0LFFH9mHHazU_%Vp6DSV@hSMLOTdyg&< zE)nkopla_FQ2tmFCW$X41j-HKCDok1zx71}9!qjZyi;2d+6}{%NVS0~u(~*V-!B0i zzzHWRK;PWgCvIEx%f{eu1myGo-Fs$CWTVsarRykdlxf`%MSxJljZsvVb}Vd1{I1#PBgv z)OU=6j!dxLp*!9w15J~azFSH@ZjqIk)~8R@4wyKj-rd1=A@@r{9FOFf;`cT!H{afN`fDQ6Ko@k>hN4p0zV%U^8yg21znbbknCt z)1=p2$W)U#FYRw&gx!R;;>K1wVkgiJ?hHS7!U^J^pFMyJiDjg*U3dXfDNz41Sd5&g z<}4?%AXm;LyY&X(Ht4&9xj?>x8(IN>B-!K{&O|C~=qZBW6Q~C>Ba^4xuhc~LeP-U} zvPbvr!#=eaPZng!EsGwt2KvuBeUnbCBVY%(!xIx7VGSLnu5Rr#yfJ95~|aBu_mEjez-y>+WT7H z$ncWFY>~0H75*Wh2Y7IllyvaCF;chP3`Q9(Ikt!*U;5~RBP z6)$VB`i!HO#4Ce|o^s$jhB6Dx8O>0*PVLOp17g)fE>Y}*v7ikJ4=CJeR{7KlZeP?n z%Bd|mbd#%2VmU77gZ4U&d@ft;@YkK9o?~YRN3A>Pt#-@G_~9)C!FLP-`0>L1D5;ca zsN{7Q!f|?t0MkSc&WUBnhia$W?<{fkbzb<@)W~{k*`PH+wgM~dX8|t8jf)*zkp!7a zA2sqW_I!Hb$F8#Qk?bRbya)wamUG~8HHBM>ChL%P!K%PMSr%#NI0PWe_JY;(n8ejk z*FqIyixH;wH`3%+b#Yrp0d?s9r9!Ei^hZ<;@|-g(eTz<jQ+0e<=+Dt#a-I9e_rI<~D4D`%#iG0P5!T!=j*f4-8%efM(VBmVUgv0)SKn-smDaWM_WJT_ z1)L3r-%;s*hbP;I&T(--DP?HDYBI=87_Q&3fihZzMEaB!;e%PYSr>f^))w!3Rd~JE zbyI%%f@dGrmts6UI2DXy96e7Tr0TdL@{kzW-A>tTxCyB^%5cDq&yD5Oh{;^W^<1n0 z#dHD1JVeoyckL#Q)%CL5v*dsb1=5u zX5v_9*q&f<4&guFMM|+9o>Pk%bi7DFcDRSYbfm7*FOq$@SqJac+t4dt%C_lmwO2Em@IHtrL?2^;rW@;kt zTOTKDi*)!+hbD??c#thKfh@U-96%a7><8W#VStdB{TaK7*h&~%*$)&26*OxLw=l_> zI2ST!{zVyh0};p*7I7^_N3fqq(OpaaaM`v%t2>dQB|uac5~jV1iu{fl+sOxgIo6Ea zxinGCcZCN`yQ+EO=KQCk<2R_a*i0+KEltRf3XZv+ux08q?BJ*t1eKwoAgK?NbQr3` zz}hPgVR>R8RgVn(-yV&y8LtKow%8P&&%|-MCOBbn^@qOvB@6g%wOJvxL zRD5ZpQpWu=lNtXeI0`w zIU%VzXOQX>nSW{Jj_aq(4}B4H{^oa$_4pl|#QFrIPH}=+ctv6Al4pp=O_E!+P_u_A zg3ChJr9EH1U>(lfPzc0&0K`E69?Zi}3)d|4(_-iff}X%L78dj}bQd+0GNcT1m{@x5 zo1RBT>Is7orn*5+k;2!=H+u02HR4~BeZOOdjv-xNzu{O?h(O^E7_n+Hp;)G>6KS&a ztk($|5|l6RH;Jm$oXsA5wrsurjf`2_wwCqISf_VGy{n_u6g9I06W~}j1Yn{FP7>@q zRxNb@m$z0UUfsyW)9<6ZNTJBkA{q3u`nWx~Vu1Ss}*fz??L3%kV(C;$=oVE7}IE1myX zLV|#fe1P=C&lR2ecmw!vE_tw3R-JA+a;~n*p=U3E+H8 zlK23L#aQnAYzhzT8R|2a!s+}?FW+1qp~BW-t@lemDnGxFHhb&fU^r&fF)<%uJz|`G z-PsX#{+o|jl1>Pl)x$jqRcjN9AC)?ka;EzHd0@yHV+e1^nWBi427$xy8Pr+;@ zl7Iz%0B(o#cyxCFoD}^UM1Ph!|67Mpm^!!%b*5y=O{tLVoAFIoDJJ>+q;9N~oi!=u zW|XCW|Fp@=;`~E#z!NSM<{9ch`2gWADvo1V_hVUeA^209N=TU&puc5`JWPL)$ECuq zA3oG~%$IF4g1Ev(2{M^Ddje;^2gt9GOr{k^ksti~n*^CEN>muCDIZQ5dcyrO zxSmX}RFo2*j|RxEycP%ealv`8<8w4>OrD2OhX?=-TghbC6cUqWkPU0 z4t2P}F|0t!YG4B6_nL7ZH8aVA7%+~x!=v<42DMw4e>>6v{fzWq84MpLq<`%gxlJj? zR$%X)_>O5mgIqJ!7 zCJ#N0`j=7l|YFR)50&H$b0ZUP>9$KGQM5(M3a@(*-1? z=cU&Xlp>B^b}ltI!89p!667I0*7QCBu>zFNs;+SyKm7JPW@&X8Zjc459w*wPw93t7 z73TJn@RU0(w&G!RSc#zshq#%I_y2 zQ~=WcH|){68^XXHGPX-b5WEt-Gjfnd$?V|Y0)_)?G}-qKM)nuxcL*^*^;HJ88{yx= z!8kwb5xyE>A9yfjhFqUoJGJXJ_7uF$%Q4B6P;#0!&GUM1Au)N8qbQT@mAbW>9|q^7 zO5z#dgaoHTj}m%gAqL`v>TrTcKD$Z#jj*73^xOSd=E6GoLj(6AJIUjw=p(7L4Kp`S zxB7}0=5U=lH92$hw*a=iB?uN|i#%lbtWsq=bRB*a*>jW0+4g+xu1!Pg;}mqRKY|9l zA)(X2d>&wE&yhK9gjFJzvnEwk812dKsl_YrOF9ibpA0{K$Yt=I#&zdGSGJipgbmA` z!Hj(e$f?ATY26`0A2)vo7yCl`vtOE^crvh|Ui1s)tmL4@_AZadO`hwHmJ06A8x1uY zd^q~S*vr9Zi>0L~^DQlkA5E4IeDESOn2~+ z5-f9CBaS`~Pbb&nL-y?wFLsqSUE{JaB4wN6!eh@`HZ6TaE{X|ITz*x`W%>1|S0uI8 zzk_Y<&bsJ4fAPXRShr3aB+^0X4&3tX!t=zwApKc{xXs!kTm+I>CV_CZWThsY-;@Ni zhoh<0ApM(#FIggy#ABzgJBe^(Pd&B%wmv(?^U~zb6eq`%vqhNYsS4zHIJdM5q1k=w zV9m#Y3)OFiS#NP`N9e{|rU!P+xOcZxZP706?!$%#Aj|S41ePQyWUYmfT+~%2mMc9# zVlMy>bv^H}ZL2d_lqa(5)-Gu{hs$1ytgJ1m4oHvAx!^`v;1HiPLdk5EXQyw-#q-Ti z>ys`f$f*3B7g3lOIXwNjXPgTw?pth=r(9b1>Xlb-+#J41c(#c}jznBk^xcvWDvYtF z65}_9mwhB3rV|moYiV7M;@l70S7hBVZIGy{Bwq8Ijo~k)lLSHC2{Ix2%CyLHScQH| z!>DJ^*FHM;sq##x+C0tWU6fs>W)}H%@wY{29l2QkEj;ha)~Q%oq7eBhJvaYf06&<2 z`3C{PtL+fGK*l&~{(}ap`=|Dt{Tt&sVugi*tGFH;hN^&A3ZnKc=AFL=;bBL%JU<4% z09chKGy{lNsC}OQAOcJA6*N3Y@$XocKjE$+Jb#k}fjDwG0!Cm;gUDE)&;?NXw+o>2 zA6x)1551qEs+%;*$MJ|!F?Zg1loqM z(tQt;KfMY=O=JxTTr=FZa>|$EIzYW7dA^uo^+26*?7O zd8kPwApJ_A{CH5Z`l~vS&z`y3-fwA zg!YVKoGU7}!XN76`~vB3Sq==4c*Dj0HX|u6_PLjI&9#%)9=tA|AUh#guvfeamrLbe zErbLonKeZhjs6k5vjB?sK^Ay3b5b#eCLWjDqGIqEl4rMdZoNmVqHzKCFp#eNP0iV_t3#F zrWc&Qx-LY@2fM({J_>l-lxA~Gwvn&Tb|CZjG-O;Hl_{GZE64DzT5)4>>jMv+3TiDO z6VH#bp$fcY1X6p&Avi4+!Pt)aT^!|0n~hVhU}Zcgp>J9oTgHrHT_viooSZ%FmQjzt zI`frP2_e^%f9DDqw=!rjQ-rpSVxcbzJgXXp8_G+B4BUN~<}#OUPcwSHN;A6|Ng5I1*b3V|$ns-YiWtppoJAM8teooR$$bnIc8$ zdB}D}-{*qiw#Lf*D79FVqe@f)kIRLEM#$F1ofXyTL~=d((aJJB39tYY+Y82Je|)nD zhZX@6^yfViVeA|r>_n>w3;9dv_3!g+Oei`nM=N~B$DgqVg0 z+*d!BQm?;t;oL9PJ`P)@0zb5cZ(jCAY2vw=jgj}t0^VM}KD{@`H>snIkluK^QtFY0 zb!g}L^Um^z1W!;EcAi;2edN9;(KW|$d1juB<6lp99Z2k9DITx%OJ-bwx|4c_sUY|i zEK;iGJHnWOmpfV%L*eQ;iq<2vn}(`Lbv&qRV1%thF@D-0F3a_b@`reX>uTDuA!)Z; zHa+|lb(x|zJQnXf*g_|@E=Ee9hM`3e>Fd`tk~bappqF786VH*(`BwM*@bux)VXagf zb_9)XeqY*fnbQ_q-5c*K+TNW@isM8qv}z_~T0`BOGW>@ON|*piyKdgHDJ5P6GbK8& zAhn33!k4G#75lhe<{P_vs-z|str;oVIJ|V0e8$Xg27~<){2n%F;tKat5=$7X5~tcA z!`Afr{S6vvE~6gvbv`|lI@bJZ#@ztie!KTgl=b|%5R!-w1W8q%%G#W#T=Z8HEe3O3 z6T;Dxb6_P;lf!(eUkE=*X!{fi74!>3SNG8!9bn>8x!@6S^$ITtu0mF44?`R~hLS*( zYXRitOI@4qm%;gPVHtyOP8CEnci3vz%Dq0g1^-kB4A`F_C6olw`F!V*I5kn4EBhqw zYRC9M3esu64>UH6u?6+l9_34!@t%ZZ*hf%B86nC!b+Ezll^Lq1XO$q5*)FH+OV%GL z(`ft4d`|e@&ZkFJ;wOfoT=pkl;r_)})3&n9x=36;jtfSzc~KC$`X6qJ{6E~3;s4*e zDa}-{iUxm|FSHjfgH6=MT%B=D zwSiwPZRovLBVJFSx3*LZB=it;I!>6LlP*XDeNIjR!xDrw#P1`(tV#|ef)!B6E_i%+ zfa;@B7@zBYud(a)YkMn&_p&`@36Cd|axnhIJTUhv0J8Hq;Mc@LE#&9Psn{1;_?dJD z!~ei2<6kda4A^|98jU;?`%YzHL@BCO%beBgwX|WaW!vLxr*5cp9ZoK1A=Bzc`4saU%4x^{EWc6VG^VlM-@5aFa%uKVT)(HA_c}wKBAS z=4Fxbb2Hot`>m=vavuqi!K4o*RHK1L3qAieTd7a{^z#I%i(OT|<<<4?|A1tnAI~Np zEOLLVQN5-5D`AyYDVja4AAS?Hl% z1cT@YTi?LSS-tj?7Cg-Eh_I7?-E?l^W2$)QKzfPWjNuAQk2iNeqUhaZTi6gTJV(v_|5RYHaX1ece+|V!6fmTVB1V9b@*tcp-jWE8f`? zRR}YNnA}^?nRh3_Bjb>1B>rujH1FFXFh$l`4LA)LVKvSmGQ)6P+f1u6J=>u-{Q5kW zckY|5^Pc+U4v{x2<7^;J6x!Z|^zW+&pB!|js6dic4wGW#45YG&!knevW#cGQLkdJ> zN6@ui=Oz!otv_Dh(%#>i=C=9R`Gh{zLAz*z0kIS`CB!=w`Mit5w4v4{B|H-y_w5FW zi%99Zj`S|m98aTQz|x!mYfHig7Njv9cMTakz=!S&Gc~8!;;1QQHuBk$`W<7Ejv?N+ z3Pzi;V`cz#FK*+wlGL|WA;iypsKyR39zU631vC0ZyHpxkRzrtyT_H`BK|azytx$*j zl476r9kXC9{D;sDvIIb6LA>C19>(+*LVGhm@&}n`seP(tvx#fHve2Rp-!Xca_jEk} zy3g+*UXh@dN&e&t0r>L11mv?xtFTMNhnj6zGYoySRR-OqDkxbpl^1G(yigIez3X>q zFTlW|b97k5pB}W6QlG{&ciBFimG)s*^2z4FYsWm`6g5=Y7l!c29E_-UVdQ&Ym@&%$ zD)WR;2^PH&bSVIe9RP}+LQu5&l)d){PX7LC3MbP+Qj&mXf54(glBh3#q$* zH)G2BLPh%b*W>6*Axzi^=!o#poNM8<=y7Zv=ZQk=`8}8qzRWbKS|g?SfBAil zoS-S+5U3Zl2iyY#=K$6YbLqFPrwq@4xn-Oohw1_!s zEWLkNZ$~#&y_OY?au=+@Z3K;Go>3F6!qFb0@<Z zH{csTHdQxX`Rs%;`Jhw7TyBlHEMV&>{Vf_IDZ}^WJ5K$A?XO?3CG(ftXbNU9;k2Zg zct#RBPeU2K%mwyUW&e7W^2e*5Q=JPDc5dob-G96)|LfKIX_OGZWr=L{-RQ@fv-X); z?I*{Qs&rLS;y$O1vUgr2a3wz@o!f*{aHGG2DgOdwKNyCH;Wz)2liS#!S1a6$5Z1g1 zPNR%szg~8`W>asNMM2DF&5=d6i|rK@m2ViOS6^;fnd-_oQS`F%Nqec%xApU?MKNMN zw~R5wFd^fn@UOhl6(A%5hFYsLJ~@0drR|%Fc-_3Z7U$3-{5z47*jHdFceU_5S(~c) ztA9}|gUnwR*C7xY1vFelDJrZM+|W3uVJK&@=+it16t-wBdbw(Ui&hbq( zf134X)q<1j`ks>SP-u@(wd*+AS_*#~AgF%<;{rrHPjxxkn|S&g9z3}9)}AdA{2^d& zPtd1?Jwm=8hGMAKT~Xoj>liuVhrJ?>yl!wwx?%QgB}V$P);s3P*JfEB$%M~OeZdx3 zKvy~(9>i%pgBjFUXPo#DKdZjgf{qq=96w#BxO-n`WC;ep?DHWiU)!{FcDrUF9AUAa z51UNu$fGC5UDDR3L~UwYxTe_fo-7V#25kPjCc-X^q6^YyxR{`Q2Pm%#^KVqUyDc+c z6PCJu^U61xu&!g4d;p{43J7z_(fphFYs>q~|2lu*+8pPn>^+e9f->u(b)W~^?qZXt z<%>?S@TtF9xa;3vF+~^-X2SkkeIU-NC+(r5Z{3eOjw#xxF)mN_-)hBxmBz*Uyw9Iv za;>xywwN2wUngF_*tbU93+L#1l?~=x?&KJOPJYf;q&vTh*Q7s*CJ(kR%r0ouQ9khc z&8r)^1Ifo@P6RbX6J%s$oUu#^3P`9Y6i5if*~ilcatX8fTU=0HE5AmwzYn`PN$wZHNCVwa@6!yw&l{8Ly87lF;ti}dM$1NuKye~ zT80!AHnYRhoji#m3@JJ8odL%S7aQySwq~?_lZ#k<+jy12Y!M9IU>1MyW~!BvNs?edc7KqZBj&AAlqWtspRrvZidbPzGG^EBYS64HNWb%` zf0OWZcW&na={Kmw(HoO&#Y}1Z2Cy-?1$5MeP(5Ou>02+`n5q0o|dxfX5;?)q5-trF2^zdmZ|1Ma(SA!=F#;ty_#Py}NKm z9zY$vs?Mt~tmx3HHRl#7oa+p_*9>(3`?0^)66S(`mRc%Xq;-%pZ65{Ez;< zS1n<$crIGm<_CuRISTJkK}P<5mdjw5=Fgm?J!L}|mZNZhgAAw%B*F4^3#%TtuWio{ zon$>_pGqO%Pq{y{OM9`!gm<JL+JR0+FXwfzXQ;BR!hOmzYwf_SkaiM& z8w-jcsygLY|M_{Z_?4e&TLaY_r0X67j|Tc6s8}+_t8r23MdD_MNplMNrzKBnI5%ZsSGVJ>Pi zt#1)`eCO=3-vzjj$b&IN<=Tu1U)HId>}wxa?Yp(W;~g1V3Vk8e&aDPuhGR|&i}m{` zLKivCN)Q|-j1?m`Ts-RzySa1ps^Od$^?nAP?gl0DmmREKTGr<|EyCO7jJs~%cFaGE zrwl@@`4;>gsE3^HF{;zqkxAj-;z7{)BXro*Zrmb}lgz-OW|~m7vBC`yA}*GOCu-tVGDk6=;ezCPrm)MLPGi0jK#R!)RCxU zFZp2-WGz49;RhchT#Z3zRH>TgAef;E8Yp4bg|245-6eROkCO>8R58~WdFFgx^RfBe zPZCQHo>Fypd+?$wz;FjS8*+Q!F`Sh?QG$@=5G-+{UO|di@-3mm=b-t(Ollfj_pd@@=X9pFXwgN4jy zABo~f5P$&Y*N9mSgBmQ)phAQm>7Qp+k~1+{N>Bo8I@>dBDLt%s;Bi4C?bVUqaGHL| z*o_U*uU}Oib+g-pJ4p^VB@MOd`@32O7^JcQ$8UK*pK^<5kRPd+;~*YOT*7vtDGRhp z4%KdT)1cj(e&MQ!ZNeq46}d*l*xT+kZ@1rO`Uu(k@i(Q&E?eurj^8;{`&mpSG@%|j zgAa|%O?FDLIipK<^ITo5u<@K&?_#M3=QlWs40_OTxj6o4Ou z?{?`D#=SYlYByxX70VN5+fYmjXP!W1vB6xV+)(o?;XyvNS?JCjwK#3evSfU}_L^v4&xpPw<0c=kxeN&*+G zWG=OsO@2XC^BUYPNEGgroaq^$8Z&u#zDD!)u4U6WP7ll6-QrDUdkFLj(t;>{u{O9e z(q(F3zxRt1Qe*GG;lydX(q1kFcCx9MtqIkU2xPXCp2L zU#zihM0ux&I&Do==958P%&qh4)aOPV*KPofUo|=r!?2<6&s45_3+2d1O4}+V6n6`^ zp$v{FY!DW276lp0{;%_AVt~P07C`^KFtm*Vx!QwX)S<7=Yvv5TEZ=z5usV-Ej{8s$ zLs{P??KUx$zugM?TPOZ^%tqpIFY+HL+LKLWsQKt|X#BZT0scRXI3K@|U2jGoY*Ri+ zxx3?(BCoBU4QHK^rKtiM>!+CTd=i@k-X-OS%dzerpXTQa{{t9rSi7G!N%iL--EF@=@+6 zLcS+1{D zW%fJn7S>7}%$UlMr0VFX)O$$0=MQJ!**WF+i@7tm~ z&yDmUOHD+*<2&Yr3};nbm>@{VmsjmX>>$*vfK*sC;D!`c(Q9VM{8I^X#AeFaeh@g` z3{x78w)nZ*R*O-Vs3~}7d!DF8g1N(ov9>P$=;20wRk!I zNcb+zhrJ3>d!S2iKtM!dvX%>;X%ZE8qEcbSxs#dwVMFQ{>SeX2cdlQQWf90EKy864 zaRpcdr^?WXGf)ru^n@T)lepv!dmBNz)%r;;k`+gDSYtnrfB#+CrYdK1R3YMb>r`;B zf(4Pdp69m6=d}dEY(1VM^_t%j!2^xL`Cf^(KGHtUtXs{)*YGpF= znB1Gcz1wqG+LInzk{h=}Z=v4hFE$a8qpP+V+OL1dB5%g#jwIKkbJg)enN5(96|V0J zJgo1WXigJ8fYRej9~FdXAW(c+cLV)&36WbySX9}iIJBHv*4omvY5STLoR(SofjcNK zjbktG%ioW^nsJU~jBQaDHF~~c9ZFxdxqFKnyZ#jxA5>i4N|jexT$&gKW+q7~W)2nA@g2{>I*9aL*!B(CK+>s~h|i>`Yu~+nJ9C zNahiHoDWNFS$2WOsp^h1@}5}WPB3RHvrJwv!h*9O`sZ7?xw3dCAC$ZZdU3N}TV&jL zg+D%n_`!#GGl}p`z3cu}!wT2sJgLR!T9Py4+tj~CHw74cWEp_CWg~+{t^d8e zqx?H$-ue4nt1kyI`%1kiW!M(6Zkk+X$^hN*=9#5qq8m9YR^>@Y?Q#ADRGjC56AEl!m=CA<{HR&IL58Aw2&hnAo{GKhcl;UqI)47qmK=Ve z^A3&1+=U{6)ljU`qd5zr__f0A3z0@-ow68CEDVpdEeg6@hg-OxZ8|dxEHVR zJZe2#Tthykp07S3MV@~=1?qgK3 zWpi2f-mmg)3(B=>&^eK*sZtlm5S9;ftDQGJ3bpTGf%-X+w@;&Nsls)rj`44D319-2 zXT%B$zGITL#>GpKF|BVuD`3e25(UbWtx$?7RKO11CpGucLfSs%X?a;Tf4%eZt@o`9 zWzTqxAN_W+_jPuJw$E(jAE8;yTcmlUu5)~NZTF?qA!A}j_FD(PSjF8Njc?bpsw4=v zOsGJ44S4{^wDof3Ye$vhxyl)o(N6@vg%9bSt=VYzNcwXp%Dk0^OS0=1n@1c@5t)9j zGUrNj_SkA8PK4~F>QD%9L^zf!0P@+E0Y}7qq*;SeVbXxKTI1Nyhx{~X((>|^B2zLxCVr5v^Y)~*EUj0ShpGpj`2`9T)-mN9THJ(^?HcaR9ev?A;ZGxeeBfxIL4 z)gP~~oIg+W*>LH3gkFV}0AAmh4W;w95XOObd{*TOVhB>aNmxGi$fO=ccL`5W0b`X0 z9(#x~p2tyz<1O}dUg*f|=CkSXQw7OmH}6LFJ>y(8 z2sw*LFNQsb=WtzFRLamYh}ukTIRw2tN{`3&uaF-n=a3NxN~lf9m&sT|x!hacJx(W) z_3uxgxJ8_Nmf>1Pf=D&QsNcs`hx=(IyiXalIhfjJ-In^=@ub}~kxl%5(H5ib0tJ-` z4j3%bi@<3Q9fab1ESQFNjl4Dd1B|FBeZsS5cGQvkdoN4kHfY~GFvI1YLx7s-09TEC zo8lA|(Y}eUS)!0#AbKR`LuK01`yY2$>fUPBkAm9WL)2b}5-dl>Z##sIw~z!%jZH|g zDIbiEN4b5d0EDiD+DKGp%hCr+h>Pkb(yfXQQEft#oMhV?DwhQvt0 ziIi;=+5@62QuD|GHo}|~p5y_}og4e05Tr>0K{VhTI6pQv0)U2peGkVol+mmN5*v|8 z79L&w@Ew0LNoTMldo<`GR+Mj)SFdl7VtV{^)7-!8P3$G*&f}MJCB~GFP4BU^Y9mf( zi_oc7^g|&}?Y!(-j@(b3c{;{oL~_gG<$_V0h%WhenxS0Pz?@2xvf_>Owjw1U!g7clpUh@0=&5K)tW90FQS05YA zTD@~qk58Zx_6gIfFORPs_EQBK5Wa=xKR+(UZN=O0TiH3#v}Or~HRnFef(`}Na0z2S ztRa~q7qa`{s<H517n|-UECKY6`+Da8RS$5 z`h39VLSkD(6@8xsc~~94Ny0W_3o^Dho5T}~5-2o|x2?nNES!y0tf9aDj(G~XCTS;7 zPjm-<9+n%@hV(y4>j)x^nd`5`eOn}t2H75*c%T&WfMvDss>{eS$H&`iZ-&n7Zh%}= zR+0{PE+}HRP!T16Dx#e^Z#Pu@ng*f^pFE=pB$OqKkp(6@+pel@KY0P4kRWs0-8}l6 zBVT=BwAr2J8kFxzGuSg;61Pxya=o3m)AH+I)>hlE5*eTEJxE9*Ohdbazvt{tu$@OJ{s zalX_ABK_}rtgfQeFjQl@up~(w4Y6xVP{W)TpO%kj0cqUYsw*Hu`;RO|X^&b8-wLk0 zqEoLTgJYVo31<6{`XJ?Vgm5zpRI2qL+!+}E^;4cexSHq(;^J%ULY}aszCS19;&t^z zb`aFV`A-V6z_NBe%JL%Dt|N>vp{jwhjIpLwz|CWSNm81trKCH3 z!-F|aIbVF9eKAwh{+|yh!=+P5F>2EKHv3c9-EM<|O5I``j746oQ_P?ew%0lNgUoLG zS8fVXne!`4?bAn$JgMo53Hy#Z-1X5c!g0XyZN&=W3ufn!)36p+D8zJ!Ci*?-_sV!Z zDB%{)juyp{g8*J0h52N^UQ;*Y(`QrwUW-YuR zc6v*g(PnbckNuHksJjrJkOTW8M^SUl5LgNviKlM$z_)LKw(Z_1j<_At5en8c7sp!j z;%yc~^GZuslh<}@6OmgRUJLpP{9UqrB-X93y8)Jx^kRv`mj8#hHxGxhfB%P-N+rn_ zAyZLg&0fMJ2^Er1l<7`oOA@lXl&sN&5MrzeG1()GeaSNRv1A+jK4Tqb=DL6H>AvsJ z@;t}$$MYQD?{geE4l~VV-q-Rzm)H3^UuWN^*imomH-bmH#gOe-(`lJd5VAh&1DQJv zy63Df`9wp{=0FEiKJc&$KmqKT&A(nKZo6omLmEOQ&bXZeccIY@kXR%C^98Lm#TRLa zD^bAh>>v2&{}r(Rdhz@JZ>K(XHo3K5_=MkkyI{(AV~xyFh|wBjUb!C>7G*90gKb{| zhnUqc$eSW)K;8to=S`Lw(Hw6MDi74O^%Xq3z91&9_gYy%UGb?0RMiFK#u(_Qyo7ih zM=98>?8ZvNXRAnqdSL2ihp*-3fs2@~%I+kh%Rgnb}B+@1cX|#8P}ul$O5kaF5~A=1lbO-?h{0m)@3k$nhAg<|KA+dT!2Cug~cry^OjoN9lOZ*b}!Fet43@!{bORi}wLAPrz-BgEDw4 zJq((Rz7Kd(`Y8G?iIKo-4;;ZPK^Hp#h{^56u@(E|Xf>tbV?xG<_JZiF@BvVn=Gl=a z9WM^jf3)ozWlmb5w@F0^6tvy@VuH-__?2MJC1F4c*la|^|}MipO#rm zVlSuJe4WFNExDV(9eLfk=k~PVmxo4h3T;xSZ!r%cADMrY@{w3hd=#wrreC`1@JP`n zescsM;2Nw*DvX&x#VFijp2ZBQZw^xH2bs<9X{x+E+M;#Baf_Zk6LP~)tBQVr!jUyc z@)9PMzd#KNOGWJFf4s+KDQ+d^PWS!Sxyjabn_Oq%qU{&D8#xXvf^H>R7ye|50lFX$ zyO`HWf}tT~nZb3aJ}Dl?Jpj*V_TbONa}A(8R)Hj2Gh*O=MEP9dd zM{=s6K`lw(8^X@19e&sI`a>6UgZc@_32>*VAYM%ADhZ*Ey_%U>Gz*ovs}$r zgPa5MoZbPYGhS*1l7wxd87Z4I^x@X7uRSyj^-(aqFB)fQH+ax?zm@OaPtZhfy-pa{ z2N&_GF~7lzi;BTSwmlXN&raMFHEe<@zy!@Fqhf}m8+~|rT9yqg-=<~AeR%lwoVKBk zU4_s$&=+~`|2LuLSyja(dR~2R4LoJ=lbwtpWqBNZx0BE$8e|l$UfBznHJbd5e7kNx zI5<&fT2jgt$QwL)FYni--Rl$Fu1Oo|bN56e-lTl!J#K33r(3f2c>5zM{M}cmb|h?F z@Zps7og4#0$`$us+!7kbTLiz8Xuw&$ZN@IEURPZyjbFrFLV5y>=Lt5TeWE2SZk-lR zWk1}#>F#|V6awaMP*5oP$I3JFD$A*^hr@P-*u{!me)j&+Q4!Z1_T65*OqNtru(C;h%~$&b8E2S^aq6-A8$QZp%P~HdP`6_fEohP0-E|MLqB#2 zfx2m(@_w(+LpK1W)Zfnmh8>{GV7src@N5T9oCJy6%M#!L*MK={NZRkEJiY+lS}=)| zj^T^gT-D$fYh;R?_cTq1Y9+iFMKY-p7?f@Mc&m`xlIlF*IiJLKUVGrh1)|Vw@^#p^ z7{tn;{S7D_0XoOd?jcZ|0{wR0OMvI}#BHdmY_xXif%VQtS+$$x-Io#p0tWipU8OYs zEyNHDd~KBeU6VFguHuW-SLFbKqQxsMCMQP+u`kkhXu~c3R`6K zk2_YP3n=-nK762;0FnKug_cdqoU&{F&*%Qa7Y%5v=}g|Qr~qYXmiz(y#b5d~A!NY# zL|2!syz<)R_}T4s_1D}HSog})s)+QP%#Fu2un&%lF|S=GIsg_fh*tZrf$C$QG&*hA zE-s-s_Tj7L+%%3WZzi0$d?os6PE=JeZ9>&1*Y;=}m#)2&r$T3G_|>T=B0`lL%C(~d zGeo7pi3C=|ijGi|;*#(d$wXUP$YI@u8;2muV^j!geIIzts?u_2###Jb3_yc`snA(U z;O@D>`@IEs>LvB2Bjx43?UB*vDc!_k?V6A_xZMjQNRm`y{5Vz9)k!ERQf~J?ZsE|i zjWlM)rcgh+)t3SOqA7^Xmc3ZX%o>!p>DRN|Jf@bV9)7H9?fh`jcMr)YrBVb@fUE}( zliUKDY6~2Lflq7VK7tQ|BD8gb%obZ%7D1o7EqU0~Hk7>nnFULTu>~d5j9Pov+hyG{ zMebemeOE(_kG8-3c3${A)({(1dCCWmU;or7>W47u?D`Pz7Y!d_=*3lxhJQ z?PXL^W^tAV+u{V|CTlz>G`y?)g^fl&LHi{tkXY)@7U@B{O2rNt&HE!;+18>jvmi84 zMnEqeNOiLWI_#frE4v>nB{>oBi0%E?ee8XDn)Vj?~DEn0&w>@G5pTtFs5Q*~Q z;#W{p?eg`mie${v7ukt6#Jge^uuz3v%Lr00f)%vbD*tYBZa{Lo{6KJeT_$WKD49h6 z+$2x?54?=XsFa9G@jb4qwa-_X#x-W|Ks=o9?7e&cOvP&4ee{VNSsRmdI}k$zm{0&l zeaQ}@9W)^4pcn}v2>bs|5O1)*hQ^~RK^gcc*!qCg0jk`8A7K9b0BpsVlrbL*w?GXX zsj|p5)i!*;!_!IG8@{i30xh)7Fx8DhQXp5{VdRQEUfv+)sU>1}V2>%9pgeJy7sdg9 z+xglTX&_ODvm4zOkq5#Ah#ekJd$*V+U^zqr9Cqj+bGw|zQY&I=H74`MN0Jih;Nm#` zgKs&t=y^m;l+m8ht%ZAkV6n)Dnt` zM%kQ?3mE$~RTP%2PNARMXNZ2^Av{zuyu?Hd5ldrfMev=87$y2(MI;Sh`MyRjym5{b z`X2Ye=U$pr%{%R_ih6lqaX(c2En^V&+BHBcoG&}G=@ibm`j%03C$P?t@M`(s>&&36 zL>higO}>aZ=ZSS$+5Amk9WJr$Kx~Dr<6z#0d-r44GTrTge?^ zKBgDm203?|1#j{1YI6@OUdHcjZeEkMPKg(J%c=10a#m=B=dEKrOOqx_OOEn?@UDq= zm}2J5Ld&9B3{H-bc=OTM;>~)~d!Mm#nw+M-om;uPF?%!lXYQ6-=ox{5T$^WjdwRTz z8~U%V+{bR1#ewd+e`)rtRh|IgUgqkbOkIXM&$QtQgPH9-I}Ca24WUt;qlc!lWp5or z`gkMR)qd6~G;}@pbqG0p0RcQzE&I>|;JY8oz`NOD@#Of+h&&4aA{T}u0VvkhO*C=X zZx`55fp2iHh!dhrH^o~y?KxR7jDbtkbcoao51sKW#07-Tr?WyP;u76$a-fGiC*oc|-?O)UfA0AD9<70&{xftLWw|y0-&&U!^ zy$c3vWJPk1>a?L z8Lw+lNF_Mz&1=02&YP>8?57`%sNY-r#BN4p8P`_$)WOoVBf1pplrr1L??5|svq?&7 zqGWV4U)laJ*|iK(n*_5Endk4g~8 zd<#Xje-r}F^AOSom^P5TQ}zRt9XTGjgq(E*#(Ed9cswY>P964`|I3>ey(G`^5HC?u z_AJM|-k0oq6^)-d-5)(;vOI-638%wtoh5XX{0Y67E{ljz3Jtjwgif|m-=f&1Y zzMwd{<>B8@;(fxS&ZD)L`@b{bqm4%z6%CwVDvMR#pX+ciF=X&tPmT*8t>vz9qvJ1A)^8kFob*07Z?-&L(OeUQWiMkK&vU~HUZ#C8 z*Wlp12`q>9Q^|Jfwo0>lJPd;`p0-fdM9FePLE>r`v$ z%_;qE3O{YAuQ1bD&0_8P_Y-Y4@->vXC=uvdhu<7TdB%$Q_vQvRpRF2%o|m1Gl%o(O zZre86R~_7gfUz>h_aJ_6Mg-{>FKS&BxTsfFK%5yHb0IbEk~hE?*l-KqQT6OQwGfzDA&b*P}}; zi&I>G>n#@n?kE>@jT+*sYBd2Z?NY8`voq+9yo@%aK4Mea#5`$LQe$(^qnG4Dv--dW z?ZyKebQe_&I!WX@kPFp7xazSN(SUmwZeo;2IgEBc%Ply^Kiifow*382u~o5WpGo+a z??v9#=Dj(x34O>fqe%@Zuv0U#|agK0-;j$D^+|(@D6c?vGwAm(tmF ze(WD^F?|c-98HrR{NL=_Y};GOk9m2YD8(wARkarkId{M*$P3(nOK9(o1D^@iNTv>c~?&otY4`*?w#@4Opy%lMy4Pb6jUdR8g z#D$TWx#Do^bD2Z*xm}s#38G6SNb4x4L)yMj(2l7?jg)EkVnj{vNe$mrjMIYA7FIe( z-yM}aMzm9j#A)n3uKwYBYO#cHg1_U)8G?GR=z!F(ZQZRVSQzHXCaPKAy=0$^#Jzu^ zO*%+)Z+kiZ1vL^rH}-sVb=9uJh1>A{;s!hL&(O5xKds0XXQ@g6djaP7FKRPRhRD9P zgJEdsB~AXNp~vlETo0*&JX;^3V0UjlYR=C{b#m`)$Q)XvT`_!6r|Pl6`H02`qk z4Zo3S(EjT660$J}`PfKf$f%A6;V5w%?5|Y92#s`eqwY$P>vWvm=c-bZss_8m0}Mn}FpiS7jogeR zMZX=x26Nh&v4srWmHMiG>d>8i63xvbgb{6H@YG?bDC!Pw0(AuLBXHdFGK(D#7ct1I zew~9E2XqvyPBA?hK67`l+Kwf7S|>?^UncTcl_2{#RypOP&^T#@I1}b0Od)8KFd;4( zJ%xI=#_e;LEJO???Ry?y5}s%C22T1=FDV=L*MUf<9AN26CCcFiMExkM&f=H1kkH+C zObe)F%wQY@fCe*g5g2LBCHGO9yeT*l?s3M6K$I*Lf?n*?1NjEMpup z`1c{mB4@zU1wG`z_hf@EgBgg_hB}Cwz0EKY01^IOB(?orBuztZ!6;a~f{SWu0M38m z_xWpY<^orZ?89wsKn=dCEAX*wMxpdQ03@#9XvPmHYhx>~DuvwS?~+jg&U{}LbHsa> z?WM2e%Z6wP3d$dWI4tVv*%|0K05*@hr*2<)UjI&oNsM^{ zL$PrP!L2Lm0X&xskwFjoHJUN7vRMu^mbZU01z}a;7SO4LVZ~85p_-JquIc`LaU<3r z)}`No{%j9zngX^SwZji+C{=DaN(gd1-A5c?KE28?GXQ()Ok;18?+ok5j~B;j%zpt) zO;9t<_>TkP*0QMsMFImW&&<8HI2H1dTd~0+@DmI@>I;MqBhYsoNLgRgbr0o&LCj59;tV<2g-H9Qy1?D z`fcT*IK57UTT(FNflm(d-h3NbwSWSFeccQqK;@;>FJt4MxRd0vbM(%##XyHkIA`lfK z5L9X1Bz6f#z(pRMYj+aQbw6EMFQ(paec6DFedOe;UUZdb!Y$FkHM=F%%}A#*uSEWY zF{ey2EWD9}XR$T)5$((snpX>8u@RQMP_t(7aztLmviY%{f_zP`?!CuOOL23~s31va z-7|N&{Z{3)`Ht=I2N^|to?Dd~!l9a$5|wzw($A{pJj28;z=zA?yya*1i02L3rSi-q z?j~;qJ}abr-AmL`i3}G#cBW#VlIhK#nrA0DI(i0&K81@|6p7!y-j}W~9>yUyr}-jO zP3y#*hA@xPv2MzR5{gF$<}%W3(gA5T8W5LGuU}dT_#=9nXcDb^sB3qtftmnMuN%K{ zOwHyCnah0e=c4iEmqHs^{neOwh)W?`kCnI&_xaA{Z)RpA&D@5WOy-8`uo$ z<4%Wlxkqm)Z<2n-HcZ-Zb8K^&LwvZ&Ot)0H2JA1D77{xRZ6OGv+jJ}(X7*5h4pHDx zgZph+a3Cuo8&6^i3BcLzp$LpmdSC+!?<`8UEk2LAdpti)R(KjDL%mFd0J#6$bth6T z-*|}bz4@D@kUMn3dJ=nJ_T1=z>p0TS%X3_cQA?II-8wR|zw2s*R?U*&b1kny=j@HK z{$b`7R>JtkCm?jjgNgZ0;jA2X~93RsoX6l`ig1tMw( z73RqOG9NIrXy%sPtpm#Av2SzJ;IyXU>S?54*|hRlKd=5zw`H9#ZE2 zgl`pD@{~G<@tBasV24P^}h_Jg$&i)V(^!jNbJe7*H@{JSZs9;EG+4;2a-|u z;W}s)KpZem7?>rA$$R`egiVQxl48X8B0Dr7-{Ck^<;gO2 z{8yuh7wo_0JiDgJ7a(8s{Cu++mCv@!4HQ!Tc2XE5B2CxloLj<#i?dz6=Gi7;<_e}~ z6wl323dS94Q`}AY>>6VJv9qU|_ry0mi7-;M{c0Qq)V?q~RA5;_M>nMV3TS(wx6l4N z=IZ(Zg$a6H>qGw4UKK*O18KB#D$ED#(C`R&&6H-ab~Lg=>a=UYdqPLi%kJDuFK)=x zvKx3Thxc7MoFQI&f)L{uGG8u{J)>lVd)lB&mw3x{4PI5H+3zE$>c@qM<#IJ2oK`hX zd*oewdImPzMO*kR^kE?N?u7NP$9Eo}4b6<=-{jg~&d#`)_*mXp!9|d7{#V}QeQjdstb)~gHSbt57sdM=?^%Vo zoOF31mHM=vgEm-{ZjflARC{YPiqrF$a*ToN#kP|zviPo~-LI}&)R?ICM3`I#ZELcL zpj#dKcZ>z^?r2`?U+$96tHw4rbFDz=#^-g6tXaL2;pZilC9vdR`etZgX!}NrcGLN0K0#&+ z*#!j0%;2X8RV%U9z+QccUT8dqfgA3ENGFk?J@D}gK&F`hz1)DDGUo0uxD3q@9jJ>v z&z5JT>(Qlc9wjunEl|hcC4isKLKxfi(VHz2T)W{K>y0KxyEAB^G$Kqo*) zq~cUbbVUC!-bQ69?f}0i>MEE)E~`Iwg$y8Udnmi+V4TwiyZUC}3 zoeA)M4aiA8EjZ9yQU%}(uuhv@Q#f0YP9_4|HF_0YbPuuZAVXibvug0!Pf%t43O%yh zOc`8jx%-lZZS~U_kRaRVD?+^uqOJRkkCjkPD@4%DNLjkVWeHa$11_+{_2kjx)z8?P zm~0gf?stP28l(+z8F6BBIb_qRE8dOiyrq+B@xG%I; z$6u5il~F%)f4J#X$T`PSw1!37n8QE|@oLxv7#3X7QTMW#;MgJ&+_7|XKos;B*^`kN zW?N{Poxb1ny{PTRN-)h0Ve}`{b7=N*d5CORdYq9c h=X%OD-mn65JT(E4$d!)Z~_4YI=FFx5~&K)rJ;sA4BncCTDzuK7muiy8+eppHz zn8>hwZ=hoSk(on4Fx*UQ=+>iUT^n~*c?aD)96$$6hRN$ukJm-Xms`sOr7OOg$`b2} zli6DaUlizdXpLLMfY>eR;GDY)o3bPQKl86ls0syk^nJwduGFGfl7-f)cV3@;vH9*& z)Pbc1)Lk2usN%egYH#cD@mS`wJPB`a6wQh!W(aH9oE3`l-t zqp2+0aU*Z0H8;Mp2aL-2Igi85@RQQ}+M6L1hvfMZ5Btp$5mS@=!do%}zkI94)=HW$%nA>K%d>da4%FmKDl{7aNz!Rzg?rxTED8Ql;-R1OV#_3Q zJFD{1(-#7JI>!+MB}9uDVg>Kb(vIE-MYxhU&6$jY`4U`&4kL~&F>XTGqdju3*>8Gw zX9ITE`Hu2kX}Q@%R$Ts|LJE&}dj2FQDA8OJKs_#L+zG<1gzMi)MK7Pic9=$?2Ls0) z=qy73O&q0(A&b~+Mt9gtU}hX>UeC51OjRN!ertfnPL&t>^dLc5%tqlF36VUAV;Qods<#iPG1tskgyATZT>Q!~1!00aB3_o+0=h!Esa$=rdl!XW7sp<&CKq&LASZmC06re*DRX{ zmL|6X%si6}Lsq2oA9K$7+ng)-uHp(oW~cUu@uw9NhE`;OnqAI6A3E^YhyK1g$=<&` z%SR!1MwC+c?xQHp49YMX#vuY9C!IFmjP2XAwTb;)`k+$T?MB)-f3qPJH;q^MXymLD@vH zl>7@fAkI0QL%!Sz`l2ctfSK&R5)yCp_=zs z!jo!}s)TyrZCZ9?rnHTc8&3va`GmrU&ynf6v9Z{BO@q8AM$~5Y+sq{u&riSQyfeAc zW=lceq`FY|UU-L$f*SI(duqF<(3wl)V$}2QdD_=xFU@H=A3q67Ssg6JK5dva;39sj zui9a`>G8;a!$_!)jx1EVK@1#$?f{uLKZFG1_|(M_WTSt&3UYtzYEw-A($)U80rh{g z^+=yur8Kti%9jtZy?eR*5b%=bfr>niCRU>^4Ap4TbLg+&Xvxa9DR;`mGkW83Z#K8a zuii%W#~2bU-wo&oP}^#tW^V|f+A3)F8mRmO1~Hf?ltr_~MnU7>+35$6zdr%Az)n%# zk8;yaBnrdr{LkIf-e^v52Tq-De=f%SeFgQgQf`l10RU>S!2PdVn$9)2Ewp(xe}(HO zO#5Vt5McUevdhJ`DSF^VSK0IJe=>P6kp;GPOfaI zM%`yMV(;^pZ0==Y_av2L&$G-EYLuwEnP`7DVk6y+HgW}6eY3JM?Jz`P^iu{$FF zWCH)_{yKulrPmN~30&?s$hPd-9|WLb<&%s}CEbmy!c>tEX7zxj{%O#*>kvIO-ZtJrD!yTOZ) zJl|;EWzdJ0rLIgOfT6J*z2$0~7!XTX52@i23VhmXbAN@x&bzk5|Di#uLanOM?8CB? zRCeG^;ig$H5*05;B3^WOl)vf3dpQAGfvg}(- z15W$ns#=>@KJ=JO0;aLX36wJ~^dP@M-IXny1~Tmf?ZZRu@(X@u7X0))_Fz@b&vOV; zkUPRY;pCe7P(tkacBMmI%tJn+fYBMA34KR?#Gbmgfe#*C6|qGvvrkJjbww(Cz9Fu) zU>Fjv()XaQ{QJ>pr+dn~MWl92TU16;20!PyIMYu@eYEOUTt|mlQI-7_&m!l7>%EF6 zmnFUJZeJ-9Z2~R5Zz|c`Fb#vAw*1~-%%46|4P5b-cw30Zmj#@pJ>^|f+<2EdVGg~4 znY+`?olXUH9#uI1tAA$O=))WIhjQKVY~WnxyKLejUH6n zg>lSl7a8{J8Rm1v-^wlzJ-Wmk(0C8#A!CCi<8^zNzYeWv2%l`sOOgA2Cxc0>Dlwok znjY^`np=3WP1Be-Y zGWc6@pZ+T1!@&~h`Loki)Zm@C@p3D-ZoT6ltVCY)e|?XCLNRuhQDymj&vGRhnThp< z#U^Q5;Ss0M{q2bvNV;hBcH;LflUN0zw$Z_2_o4H{B{q%S3K-HaQTRDpu$BmE&BR|0?)qrUhsqi(E0`MKs z`VE)gwWt4jy>J1H>q9X3p8)pQFaod#fE#{vHc4?C_W2%8`5|-A7Gqtkl&`#UiVE1d zVc9A!6L&_mRU&<#*Y=nwX0BbS<+whmk(-g)X;>}y>vBZ$&+ko{60NF7<6b^QqiXVL zni;HA(W>nUf#|}<^pgSs>=XKOQ?6P7{rC_*EqU-0|Fw?3CAI|G+tA&v?CDm799|cv z*^|_6zJy`JXSsX4zOo0`x^>6aW z;KG^^$V>kre;oab{PC?_0uNaOJniV;K*wq92bvaD*UKP};KFJSams12)rF_TTYujb zblh~XbQqf0sx#oW;Wbmw!3w+;C|sR>yGRaOn0sG}@CUJh`;v@8)G{)^u@=t;SXV_Y zD9*VQFiP;wRPdp9@w#4!GL0nmBW>Qz)KgINi4x%NTYy}H38>2;YW(oDQww058$o2_ zaU`FY1J>&x`7P!8IDKVPJ>*+@&Cnjs@n4VM&FonN+E#fDveyT3NZfdaj|9}wK1yK) z8;$Eah(s=u&EbHT;1Rw9QR0}WEE5Bb)uTKR;Vogt!fse~7df(Fl#^ze?uM*aDeZCA zGjp_ew|x+%+K)FZz0E=4KwX6ZI}VgSlJ7$#aR*r37l~ZEs^{Yi-eydaV!V9@RC>VV z9`v{Y{UBq_asa!&?K=bfIv{Gbfo{A5xJ|PyK@)@@jVGDHuEVeY%4+kv+O&aW6Mjvo zJnu{i^56r$^m?A3G~>P^_QSLbK^66%|1a=SV1zx zWid*!tR9qU#2suV;)7mVn)Pu`E!Is9$_$^ll^yi+ow87m?>2Lh&qps18iljhLYu6h z*3^0Z9vD}SsKM;;028zOF++x{%XvwiO}u8XrdP>)=*qXc*!EsSU*t)>S1n$afW3B~ z2pIbx5zdlJMl%(?$W8 z_baX|bj^p_CL|qBNh@WFYoawrPFALSx(^K>ZZiL$dgs_z-5>wvGvTxM*(2 zbaBGRzWF!S+dcfuKWsF zh7VY0Vr^o|yv#zQxl}_QM@X_*)AxC}=18mz#N6B!H)QtOa>z}!*IQs5^9~l6*Sy^w zAu-9!F8GM4maO>6>5~Y(zcs`EOPNr(>zIJd?yqqh*dPb3uN?Avds~zJJ~=k+t~4RY zfEfFBX{i@R{qnY&o(D@EMu?JKr@3gBkQS{J^t>bMo2mLF;S=-B*%6%Fdc6mC)>T`w zm1@ew_t_=QQzf=L*T;^&eyS?#l9~TtxDtpjyu*FLCKS%<)y?hZyb-z&$xlVrDjnTX z_IDm)^A6ws!u9p!TLkUnCJp+{#V_iJi*Be zsQs%xLUYHEtKi9*y;|mm?7Pss5I3#P0X3_2or9)g8Nr2D{KV)WFY)Tz2|YW5Z)7el zdk1$($HvL4mwkU7HYqYcCjW}k7*4)k&)1GD1b|Be;TOzC5gwC4xS3uj8w3?9R`hO| zyOfoEUz^mF3~PQW!GzppjwH202ccP06zyO<=qdaxyarcvZ>liEN9#aiQv7y~H;8Nw z)sr${e-~g{GC>vm7s<66%}il6Q7H*@Hhk>%(E7$}E3eFkt9%%ZOUE-jC=;7KU`MT7 z1y&A(8Oelx%1qp(stxIFHRgyzawS}~Vc=(~a6e)PMd z-1PSsA;&+$pfNWe`P&-3M_>v~XL%W$6T1VVK4Qf#O_)T zx4hTmbrCWj@uh*sS~%@eQ~Gv&pHV0x2iA|GM>)!6$fBsub=(n!qe?M)f*kZj`6BJ7 zQC|^ka2JwWk^RWrODD>Qa%EmetyA>4lTlVo=pTsz302hM^6Q(R4jrKhMyyoR+B{v{ z&`Tf%6A3W@eAewaM!QM{JqR~x4yMuiXaRd-+T=o@NDy&v;p0R1hTQCol{kjaN8CK6 z{j2JM_n0HVs^*UKfXbr6OuZ(do(+`0J0Y^-rd9Q@=S?!Q7RkQApHp30Synu%kbY@o z2z_4Ax&Dmr;+K?=OaC8(mv#;7l#o3@953l`Z4K{;ORCuquTH=ecv;enRqc{_hk*n~ zYXR=zXAyL6o==D!>F@qM=tUDbuV>q;walN}@ZQW>KjH#HrTN)yuTCMKfbZ=ab6ZEG z>SUNhgSq`IY@9%|kS;4aR=_5AQDnK)z;u^UoM1%&h`IV*|EI@)@vH2O87eyeJ~ZX{ z(mI0fWtwEk)9R+w1H+T+=e6J`WiMXXwbuPy%bS?^Jgg5UD1@$QUsK_qIUh3U-!*Wz z`68mMRA{Eiz4nLhNvjJ_E(YiRXi(lOMJ%~>b@gtgA78F^y6ZS^*}&q1lh#hIoFOWP z_XDl}Rug0lmHdwwrOhp4ao|6ui9G7}vderKWFcbQt zv*LtM-u41Y*QcIK%YkUXsoIrhw<*?e-}g_Z=){dR`|CVCecR`Lk|PO!G*~ll9I-V~ z%Ux>Pd~aHZD(cCUsn4*U)a6~g`65FNx6?b3ak~P!x&;zuh@H~IWgt}-pquV~Z^P=L z!L;?RPsZp)YR&mVuvpxa>=3#<$>0C2n}L=?zPXbnNZ)Vc*4nI@$Jt*gm4F@_UN0%h zZ+e`plPz*bScrD(0@SN5FeLRS)5=&b*F-{kIpRRMk>pXb=BYauB^qAcLEO~x@q%oC z91ea8Pp3JMlh}J?mLz1hsUW(-y+$udAh&71f5pk*3RiG5t1~dHOzEU&cmrZe337{! zYw$(hgbKgnW|l``_#pCMztJk;ZU$jw2t(ZgD$AP*TQv9=D4_H)S_J5q;4T1BV7?$% zh@dv@h~bxBT2|+xWSxI@%GF-wCXXPe+u~jycgSWG!Y|?JbO&-SVXR`R4POtjYC1Yf zc2*{H=IczoIyS43bQq8>w_vYjkS@;>G7RsG0qQBIwB-aA6W~bSjU+ z^ZNaDjw$R~d>PLXTHLpN-!1S*KjhKArO%W#YF`juoYS)xt;Kl=&=jUCWlGWGQ1I}b zOn$GlBhR&4PqA9Mta?`!Xm20tF#fcI9_Yv#5?Z#*l z(xIlP++eH)!I7D`?>re zKfe`tzq78VG(H$Nj^}hs9gnK1b#*x15dX;m70c2=D08!GG=qYcgufRj`23NOHkOGM z@1|*h#+|0BHA$%x(`U7RLj031te!wp%~ne4Luuj5pC3mh*0JI36kDDN{2n6y`mVTZ z@rKbEJ#!vk)i+tbq^W>imH5eHy3(tFQZ1r1f5v}AqrVGRhd*K`+SL7Y!ry>as7k2Q z_IH$vFzwi~unN>IMq3eLG=3CBxdbf^a;h{jA^p87Ca$ybch?y;CN(|EKR>A3#PYq( zb)v>-;f)@V&189eXWO>laLG)`f{#=jFk(5_;Ml$p(9Y)lS+}<6xy_pX)~wr|UwsKy zkD2``&{&10Nw58K>lukV_hfDMDJNE$x{{5EY>k2CS{ZldVzh+X`wv`Bl+)K<`{IHQ zGTH3lbJpV2Ps_@e<^f7(_{GS1v#+jZpK>Jh&dU|N@E{EQk-v3Ky0FlYW}x)xSNaog z83*D3q9)obY;f^=sXvOZ;e~wMxZ-^XA2p(@sZ2*V}tSg7@jyx8L+{0CUTw==7bkO2u{?iRXL7p^kOVS@Se87&pN1XwzYBx3-A`FH# z02hf`Wdux>3zTC5^(368?%_L{1hOJ2qn?w!4h-xf&~Q5(IpMANa&>l;Sw;N165_d7=v@BQ$$#oe(J^k2sxTg!TOEjm{{Z?@@>s(ucXfWz6w>=eP z4#?;~nYPHbE)RYl(|N4=T4HsEs!zQ@ecS=c3^}M2_6`f}v7?b!Mf4-qqhWl3|Jv zgG$iawgWK6yfnMjE$X#37?OroCV-6kpebf;8=#MnIjBzWpt;HV%39(&YKE`i+wr)>wW7t&CC+|*k&;K4zTnQ1n=-w|tn7pb38@IZtG%O>J&W74Q zJ0~*+T!t0wagZ+It=_IJr}p*GOhg->NSAc{qd*CpXE+^yrn^`UIu-yi;kw{neS_pJ zhAd7~QBd%Khj!Kwt%MnSpI{#_GEG}m26Q=CZpZNn z`2!UP<|%v_V)a%Lh6=K-6wBOGfN1hxuW@&Q5+Q)7{e85j-N2>K!Vsa4Aaodc!K%f5 z^8^FySh~Lzm|NNV`AXeX%p}tPx!M9$V>+TWbg6Obz2gQ?TX3L)^b1RyHKVfGmkNej z?v3w!pZC_g6%(3zu2gvyNJAX;FB|*5(eB!9hAF!t6tti3I4c$lnZ&7_bDI28-Y({x z67F%(Y=iwN1DE)p`ne{SQ4^qR%+xH(oml0Xh$yBi#c*y3Lo;T=IUot_&^-2a$Q^e)J$deTBsPbSAr}AFj%Z zihPRH<5|3{nkhV+%)^)FpAw>Ja`SJ5>x5dt=2L3rslO?^0~VrGCGXLH#^7Pw&i}{U zJ3t>v27~XWU7@J{snKwU={!r0mm_0no(r@?iviRk#XcWAZuPDz2mny2pz6SwHUz=PVu%@Z z2H*ir{LMjqOaY1UhLDY}1_0d?fi^GYm z!d4z%^7&e_z0w}NIKZ>xG+4<`$3l}iAcMC6{8TX0T=i<@5{a-RKx#1{O-I={5>G@_ zTX8@8JfeRviG|{wJucaGlVuQjR2}K1N*1j}ADQESQZ6myAUPstd8A2Mc2>@$Qaa_s zO%|;&T;K?Bp6-rT<82qPRwbd=PX!tercIPGz=c|QFC&n-07F4Kg@na_jDi_k+G-G7 z4&K$o=2m&RU?43Z+oAn^%nA*n8T-5f^Od4a`~$6b$>mOYg&Kt zyKPKfi-~8tEM|$9gxBejcBbMvBwdeo70O`;CNJLC-SfO6NO4Xy-RFsy21xMMK!(Uu z1|XBRO9%^^E|4Vr*JL4lK0OZo}c`}vuahdvMp9A)QFtx1XPPs zvw0t0K`+oGOoza&OFqa%r4m!$kd9`VCxtSo7>16%5dS87n2E3<#U{rr_K+tLA-5qI zvK`S_$Bzlf-JAHM%={_wVl{q7H%_B}`PtHg9{a?>aps1JxV6*Y-Wm{G#3YHsk_V_! zJ}-0tGw^C&PmTkT%UnPIf^3^l;XjmfH8JqVV<%$lVmq7`p7ox>VfGb=fhJ^L|cv*SOl=}ELxO(>U}b~Vs}RA zz^(Jfy2p;stq!-SUgdphO=WJ=0)oRet5x!RvwEoR2bVP7zwqSWiF5l%?DEU|bj#Fo zJ!kjupG=;oCMxB-l0a^L|L9bt!S~hotLm2=w+W~uH#b>==1!oBL9!q~REl>6c%DY;KTXoNT zN6Z!IiI!Tn8QYzgOtVivr()cqE3@GuYbI^%QEc;7Pg3=QxYUh#ZJT>p@8gdhthyk| zTxpj_T26R<8uwoz7_CR(Lxjd8pYw}o_xtXC$);e0mQpbK6SgZOn`>lYDUEU6RGoqI{ zV%UD1-}Y4`u0Kg*R@_l0X@ZV>#^ycFyNYdBp$jr5ors{pq?5yMw{Py-3IksCIxr%O z0>G`O#NlLvvE3NP9*<${aV4#l7AqM=BkD zPw=}5{>B0wxqfg*v*Lv6%6+gd(n76AMPGQ9-Q3=#)Q{8XpDzbTVs~fXg}V@k9F~)d z{OW>MTNn7*PiaJpGI@^zyk}wt%$){E^BO^BY-L*jXllWJz{p53`6RsFzsFgTh$`Bm zMVtj)xa`w*LwnsYOCSdm3HS^5c;F?^kZ8ho$_!9pof&_yo>oX6l~A;Enu>&)1xYv{ zZ9Hww-0}Ygw`g4be+&V#kIKi}eVMe#ax$J}VNsMbHQ_QfvC7E&`C8>xuN3FZlE))X zuE-Lbop<6(?reAax3{&U^-mh!zf^K`^-Ar@0C6*m9?^$f1!bz=Uw_pA!zn^=xkKKO z#tBR{k>9=9ZelGClW**tZ;3rCoebs&9Qq#%0=h{XxIvd7Q^B(%(5|~too-6U3Eg`1 zy2fc}r#H&xMRly{%M8&;mw`6!4@FbymNWHVF`U2X7~M#gX|EGBJv;tsFPn25)x2B5 z4lN;BhSPCZDb`NL!9P0z+rm?9s|GYXgCOZFLr)|UsJuME|M=IefhZzWU^V=&!AC!7 z`2U=Agr@&QFo+ixlE5uwn1ZLQ8MiKf-(isoST&I~xD6oO!gVj^EppPj_iqVhf;m+k za0VU$9)k}%eGdUlBA5+h%vyIdXg~}k8ie?qbKnpS>Z(#Wz)@m%iy|(YFci3oeF>iC zn*b;j!oYz#;8A4(QpA8->;df@7Y3*yJKSE0t>@bUGHakWG#5GR4BS5xs1yG8s~sFU z72pL?_B45r61+CAi{V9*BBXQG8%~D#v_6zrd)7RP`7G{4eQpkROROl&!VaG*LfT`u zxt!T|fR5DeO0`qI>N#K`VKc2t9LcMh9>07=xxbmR{+QduwcfF;6u*m7aLc!^fcab073saerK7_Ose>607 zv0Y-AQAIsv8pzn^_P=Ks%rarsD0uQ?b&lC+kJLH)FZ9pQiK_+sNsgZ;{Ve=Z7kvgX ztHRce-QX$>urUEme1{>ZBUbtMDO6;SZPoQq^2TixDeKeSz0WL0n{AXaADBOlxeU(@ z;x4S(Esge1g2|@waLp|c3!S|rw7^i)Ku&ss!O*`cnWl3YwzL+?E6_AM`Y(Nr_eb0= z*5(jLx#r>y{$hQC`+jFnz49Ks*P|zui6s1@yW=>X!)EY1+1ZF5GJa+iuDMFjINuJd z7p;v}^u_1K05lUnG;&ye@G+;z`{qu#8+s9lx&i5}*-&fgbovuH1;Ot`B;TIAiy`PoM z;?wNEJ$mOxER%Y;xo}mv?BQsw{3FDeD)=DlWDC(mAaD&~wKquyn=X*&Bnn z{7}vw+#h>%Z3Jc0ZspB#ztHw5$i6$&Z!YpiR-0KU>0QyYn)Zz5tk67>4yOLT9WOq_$azT%&{RhPS^8aD&%j2Q! z`+r9&6`B;uI+a985>mF2l2A!P*``tnNrmi2gdz!{h>?;?OtL17T_sDxgv!2eGnO&y z)%lEio~P&cJLkO4>-?TS-1j}#J;pWP>$5NKw_@G?k@|6ZyTM(*{YrOTgy!mnqzM;h zA~G1scP1aZ(-yMv=9I~z!kD3-RK;^*%RKLX2#Cvl!f)}#?&B5vdlpAHQy7uBy(dC& zu7Yx7H!K>q8^t_r{`AEU>vDx^V^>GJDX(cPxlHW^&Hhk{@xv!w&T>odo%HE%Py3o4 zb-d7eo5O9@>%y45*+I5DSH2eS$OvmN4bElsb+(~deO4)Jb}tz8I}sYrGAbs+Hq|qmX}sHq)J!*g0FaFO1H#L-YvY4 z=_zV);*jpUThSwZx&3*u=CPkTKVI4AiLIH~mUkuHW`cE8r2u&9mLSjj)Go!aLp2^wx|Jn7dYfOjT$K4gDs07X1;jN z_X$I(njJb3sW*x}X=|8$MrHa`$(xe?4IhbL1S|n#Iu(+f zfA(7vQH(B;xrCc|=ZAh0y@GO8!<8{M$vPb_?CFAK-8ab+tFao4;_&But>O!l$;)%o zoW##i+;b$}J1Vl93I(nqg8cqTJ@Er)4Sfs=M*x8qVFEBeX^;;nUkW*KfuC za;M(5;(L|v?RVBN8RXoGWSx?9z)NY6Td_vCtX<-%HzCP{`oP9NxL%RaBuQ8d7J~kO zeyH+LYJ^P>FCiTyIZQKTQbfVoD6<;^ZjeV3CO8mPxIvX?ehB+06|D!pjLSUF-A-xZ z%s277li*B>;!KV^ao61b#4V&Gd2Eu%E>9r0bAK?0qYVjrkSzE z^lyZg6pww?x_o}06KNOVZ>)RJUt+(y>sva)w4cFpe1=(M>wft{t15ZPr<3eDC{w=E znBUbn*W|iVp=H0mutlBjpN_!)7}?pGcpCv1s{s3%1b8Zk#7;5?q$cG=kWOAW6yP0Cy zg)~1%IqQ3IOg4tOGTXR@Fr(_k1^HA*LY-gJQDcM+B|AP>=$43W=|MkOj0mDf?KZJY z*@vh~Rmo`m_mm%$-1xE4zUY#C|MIN{Hsn12w_Sv8P#*tqMj`E6;yyo>-trh3A>U1m zQy7MWuCxXzA5)_bOD`el_IAKxdxdvU5_b;Jrr$_xBwa65k96DN+rEn+uXS}Vv1yDI zM$=D`M}!U%w{H^7<@E9SpcZy~IiCJm4zWIHk{cdptzE$sM-2ohIy1vU5Xo_7V}g7r zt?^5GsNR#HH#9YB23t+82FpZq_4x~zq0f^#dKy{d_44HUtu=IBHAX+}G->!2VWA=w zosI~MTXyGNB;wQ91`nKQ8t(iauHy0$=R*o&A5@Imy@%N39T!`66dIr=RG55?h|6N* zh^qAi!Dk-s+!H*@B9lo@1yB#Xji1iZm4;yD?_U6PV%J_AhkpiIqlA9D4BC5F20aX6 z3HxVvApua69aN|qTrLOa)IVZ(r9?Og5QwnK! z=n;J;w^J}*=CvJV- z3KFpq(jwlQ-1S?}$tEA>O&JQr>NCTKO0H2Bs=9@CYx<-6`QubJTnC0jfeSuN{N(Y=IRjx?G*Fuk`2k&0u zbLV2CY0g?cB32beUpJe59?3w8S7oby%l(DI2;sYduGQ^QfPlkU+4xW!!o%JAk6B+W z^(gi{E8aAR(`<9*nU>|!+DT?663&^D1^$OUZ`u(A?$^bDOn}tKya`{m5+&)n4ks zDCE3^oDu5=g}y34ZFR!oo1i7PK!LjVt{kS3s_Qa^E9-sMTpr$NU?T2$i}%Wm`x$?{ zCoT!sS@;mTrSI?J$p;X%jYVxMmKu9UWuD-jyQhg>Vet9t$SWV}V0fM^h1tJu^r^f)NO~!*d}i{_mVV7E1%Dx4XO4u zN1`>iwQi{}-y-dJvz~78Nzk}PTtBX5DyWaP;hEUj>mDJ7I4g;3W*j*D(@>-Yut7iL zo=n4pTB~&>ySMLrdiiwtW1gX`fOy5hvM)&VdSwn(SK4;bPURvY3y>*2!g4nOn}8)r ziG(cuh^UR>E<;YWXwnS26n~+HVN7G<#2btp`(nE*-a!#(@+CmxgKCnZ(eiii45V)` zcwP9E09nu-4@ym%+hy>_^m<|n0@dwyHH$CXee(=s+bkZF?>9*^j$+V~5V~qPM~ZGh z9Fvx(Uju}WXKBv$@AYF&@45Nz-u0_{v&)Lmf#t*s;5uBgOFxFnAp3VE>MFv#hMx(0 zyBHqo7{hkWCY~Be)arJ~yZOX$)mEO`p`|H?#De{ElH}pA$)(u78F~hGmH~b|3+0}I z0USel+<3A7>rSSYnT>%&RPLeO>7l-sKfI*#8DU&b<~-u!2Ctq7)A#><807z4RN-;d z-sZT?o%g{0giq~?QJMC$L|vjNq}!kpH70#$V9)-O`>s>huJXLRR?8f{$xFR$ZApAZjf zD>N!Kjx(A#s;p+YQBos$MW29_QPwmV5;N`Oqx#3#CpckK%*xxURhPx;p0a znJp>9^&%8U&SUPpX|gBSuwL-O++9?Eq3T02I1FHtT^axp63m`mg|SPL3IKOt zI)3Y|@C!^OWM|-B z-q&M*bqxU)9HQz|tJc|new?MBWzP@K3ULArciWw@LrK6{9>yW!v{#>u?#v0ZLU9x* z771rz0a7mJQ^$adM#rPOx-mzLW4y*s5ya-kjZH%Awx#f&+7z#?V__(BS7B4#aRZ}K zHo7iYRTAH<0YQwuqJ!V5FViLa0r1+&B8k_=?#DL(SJ;MnFH}AZ@YMatw^q`~CT}?C zB=)7n7c#$JIFq2@bdCNRKXi)`vS9>IMOW!mkgNIh0B+tU2}>*O$gr@FUL;U1N! zxJZ;+zg24;yV?~$&B90Szvij^J>|mZ7L%>Y#RfaB&8w}KPv!9;kHW0&z(L9|CukBs zcY-{0VxIUFhr)lj)7!*a)(H+I{aJZE9r`p|-UE>mnoE?0pwk25*hgE49wd}A^9q62 z#`b%Mp`_`bFG2SNVvN3Q{D28pPGKm`y?hFP4#Y+jZ4Q3(8Wh#q%Npe~^8Mbk6xrLT zgh00Q3miT60O43ce06oq;gJf0&tt#W&SS?~d8n?FVcu>IR1KI~$Ot+1NNAg6h^6Mh zFfWC;5+S$ZhneFD0(7y3NC#o&WERk3i6Wu%JUi&rylg)?2 zMFN*bJqmk~x>|>1pd;d_aT$iX+3H&o{hz-3+FP%>-H>6B@5gnX!&FOPoFKA(E!Gfl zC+I5uCh&Zg(M=2~Q>A^HzEYM)3yhsJ9qt{v^vpE$g!$pUI-&Qa2-V4$V^O^eccgYG ziqs}uJ$c)5Bf}xOCg93Y*$ma84ilE5Kxu!OdZ|n{Xxgkb>wI4R&2taLE_iIuj7b%U z(RgeLb2gL)n5ZO;m_Rs90<<0X^4a&k?wfTs1>v{4eRr~lXj0e zC?kHW$UH7kk~WmWvb zHEiahRMk1B5z<$CL3zvdZJo-o@y9j8Q4^7VzO0Kl+b*x+L)N~J`WkNjLRk#r?=mgF zna`ppjVZ+108MJZBmdq~cD`D}RUe7766_g*0kjqZg`03Lq4QPvU_(lb`y~7| zPq$>nw9kC$k4_X5eHHV{K)U)X?-#!d>E90YOkR8Xroh5hrza>!ej~%BA>ax)6|Oz} z<5U(rZ|i9LsgvEMj19l~nYmo^_jgvz&r=Xc{iyK7+%&Fk%T1g-2Da>poK>Q@1t#1< z;9m4(vI!ETj^{q|2hLUyazBjh<{&WqMnM{(H#B0xHCfGIvfR03Mqmb>=uCsNIRJgI zX1)@n7HGPAr99@Biry>yz-xovbu%}$!JnTK39wAfI$sesk!~4@eEP{tl?!C6WLbH| z8Ydh}>6<(sx#fb(r*&csL!#@FKnY>f%9}F!2c<*~q1XxvwF33MM=!*MM_<_YVXw@B zi%okWmE7ADre>Y2U{2L8&6><*xE=g**hoENm2(OeJIPO}I!^id($S@_%QD5+@SOh4 zg~9MOd_Q3CBII7~OX=dsUgqcSe$$2*Kfl)vHhF4&d^{PWSA{)b&KY;8EE8&HJHHZC zsG_0qKF2=}%4|=5`f?x~Rm%mURbs3!F$6E40|r&3mq2O6ieN{MbF~QUqxoFML`DyK zofoejS+T@8-7v%0%{}H|_DEOj)|CvyXU)>%KS`Rf7^%eAQ3jI@M9}usaL$@(E`wv9 zC_5e}3{@5|u+93Y>jCiJ(Mj;Ph()BiO}LDFM#y5w_j?_h8}b2krj9E9qY+SGMFEsAzS{ryYy%L7nYxv2OBw}=hK_lq|Ritlx0L*xjd(}u#x|C2Dz;4eN%h|Q3*|ye_UQF=c$zT185&~mqmDqFcZR$8 z1wV_UG5>;6S%jPYYkc<;yZ(POzFS3wf^K+*MH8D-58|KrftaZVHPHq0ww=>q5tC`6 z>$KhrCP^+ato1ZEp`RU}W=c+yC@W#&o*H$E;Swt>3f|Jql!Azm zvXrY*d#UN5)b^sE!5Tm@%l%ifzrdmW3c8$Wsoi$3&pVr$E#&y!$9B7lU}^THH zU{|@OTa=Fp-G!yZT(=WXQRc2kF~gRW-QeUkY6(8YlOb_x7Cevc3av+O)f3o)IAm*T z3DpWAM@R8@bQXpt8Dm`lfTVNjBgT!uJ^jQil;6v6h0$5onr<}XaTYv*W!$Gki0BsB zLO1EV)x5Pe)-*aRX1L)nO+fkVT}Zxf1nxcCPCBZCffjvOFX>NUMf{xe-!DEZ@BXuv z$J>YRQb&w{hAbG$bcIFODx1z7WHpA!Mi=2c{`w5y?bsiL~=bcKq-f>TGNeh?uQyyU?j-IalZO|TE+wp z!n?1g+=XzkPkGtu$c9i5H3=MhDJ+6zb$b28c5GJZ$*h;7N+x8m4%!|>^j^5eUi|ug z%jHJ5pMg5hm-66}u2&BFs^DQN6QDjqdvYM`PQcQ|No;+GdY0l3zhluQ&Z2kD zyos{0_bbS{Y*UFzP7fC72kNID9LyjC;fpI$X#vu^i_67b(d+tcXtt_s%U6$3sz*t^ zy_;0sgM#y-fHA6B)TlxJI)^&ZSA>h`7Cs9La}PZ_=H7Y8#tgcYyciUUj24+Q11w!I`RB&I}4?;1P+Se?4!&LH_I2eGHZj4=pC6FN(Fom^~huMG~in zXj%4^n%Nx|EbjiU)wj7T{QR)k^vOI$`Ej3iLi+1We!K5Am$R!j83Q5PbH|%{rCl_2 z_>3HNPB273%`wF!`Z@le$ZoDSs=&#cM_|KF1bl*3luBRE7fQF!J-|Ce>^1vv`D5c` zbs?|A5zkcgtC1Q%5PU(>1(6PX4ev6(1OMTX8)#i7ckrYkK#RJW4otg+w`0C{WtMF0rpM;mH7xnYrgHu?PpHKv1O=U*ZWOeHx19G^z4jCa`}dF3w?Y118i7)l}J zIz%xjmk8NLgJAVxt);Sk71m zoiGG$$Wt;1=4Y$_I3?wqqju3}YY8sDP&NsSRkH!LrJJh|EyXa-Zrq^F-m);lLqGX9 z;Klm1qKQZr5?b=HIC1XdsU64g9cn}8XPk3aw$AV7Jd*{y*1EJmAIkN1|D&J19@*1X zt|Y^-Z$eD+at*R;@17seh`GD6Z7eIV_LHZkhc4f2ka{7UoY|!HKwi=^*(oB|vtB695H+u*D;lmRP1*rl^($`5tz_gUZLbm5rZsHlGgZlnuM1 zv+0t!PKJb`gSWTj?zG2ipUpO)uFubzOq{&dAL;y?kh=>DJP@MzX7PSVKCFsyylinw zSXHu~%Ymx+-B#aCL?2AdBz$P}5l2lq_hGv*h*1fSCJ+Xe%!hToOorQ%9ms^l<;(~C zoLnjzh#%*^mSbi%)7_8?3lhMG%&MdkPk#M{awOgHxe$^cQb1e+3%K`dNf%G(y+8?Y zP^oCri_K*UbT^g(Gzro7+>dT%nFkqL*XM1XJX1iC&Uc9SgW-sYBwal+$@d0ZhK@@zC#tB}x|LS9jZvxhO9XQN+!d6p?(AlWR z49ya(KfNVdJtj?d)u&x$Q*E7u4qPwH1wnYRZG^WcJFbl_54JxJxGz^60F$%oNq_R5 z?nBgj`OmGk89N()JafnJt9b0Jzlx-(BVqIz}RNrSY64V%K~Ej+yHx&awS`nB(%iZCqFlJiuz;zZqdT%QAmhrV{xV zMe~6^Jd_RiInh+~?H4f3Z)CBhg{QsjGyN=UFIx**($na1tI!11goJqI1{MBLo`>^$ zQ_*)vKF$+M;Y$U8W=L~2BLx=b|Eaj6Hs}=CmhZ#&UQWReE|PMKGe~`;n{y@|tV)O^ z6X?r-OsK_bSTWv`63eWIuU7dl^Xg`+S=L~f{M;CByBY7al|m1Z?nDa5&aKY_4|p&& zpp765@%a7x3}lHc>I@qk3$UsX7FkuKU{vc$1f-rch^myGl!V3?er|7{nomBa43Sw=56I0{Q(URUx*8XaK8yxh*yYfIYjKh{Ra53H~5j0 z%^1ON2YT;RJCRFTaaCcMtmi+@LLesP* zTyWR=(ybjg_OE5iW753`UkA8+hTriHU!U z%43!hh2&qC$#U0Oo#4_+ja|5p0o5R$>ND?gvzPHXGTyX2CS0LjOWFAj)!oh_vq*qX z7oUEk?GwFS+T}TK+fmoh0H)@y-TBs@`@-eZN>w@_kq!LE4|lr*Go$?L53ttg&p+^> ze~olt{vPRAnIA4SB7Hm0wyW@tj6~tDP2_W~q8IN1&#aDt8$#Ut* zrx$8jQ1k`PH45x-687)juPd#D%g}*rBKiOrU*Zbv+$rK`C(b^K13O$C!|?)5NvlC! z?t^4@c~0GlWm^Xj3NZy1x!z|gLA$}~`%&H`^3v+T>wA1HKj6BG3pvY_NYhYmg$D4G z0qF>9!4+$zi*mAQwx5hhS^R`M1oU6kqx!H9@S)pK2w=%l_DD2e_$hdVOiTN(< zwHBE5CEM;FQrqy}mpo!WqG9%4b2R?g)b-EJo3=1h6e8*M&rh9V@1SZoWX0u|P){AE zeiYt+dbLK-a@Z1O`TRn8nGPu}gap|ALb*D1&k2`8;b;<3o5M^vzU;Q6lTU{a&Gfmm zP@3oOzv1(mSLLAz`WdtAw_!#4%HzHus+svMm1VtjrMNf zhO=h4a%$NxX1ZCC49hVLZ8i7#yvMNlOejxTd{9YBwT(h}Gw8rl>QK>B)fW{)hx*NJ?sa@I`IZlsaTQz1B0%&fnt7)lZcf&>M&H@N^#Uf&*;QC5_Wk9SqjgTp@}h&`Meb_QJ~>Gp?cql0=?IA6g3?6o#NB=q1Fz%^Z4lC81YEil) zz2%G_P8lsd#n2^_YpD`03Y3yAAm)Mp)K zPM$E~wvPj3M|Z&gH+PodXS$;9Bj(HqkLRa;7R8J;cJ{WOQO$uTzVF4c;AiljoplIX ziEajTe%Q@XAwM_NqZxcPtuRn+8}{%qs-8g}cBpBvKAulc>N|C&tTAMicq2nmTrlv^o z3)f%fNB)-!c|1%{Sat+`{pU1eW|#ACMzeLl8O>Drs&pT7y`>n2at}C(NcQkl6b6p9 zT_m3<&9SgHu8;7rj~6ofBrzVWi+Rb@oU#E^OVWZeu&g3As%Gi7jXyC13b&CTZB6Xz zX%c1AFH~(AgD&#?+Zb-8pPGmF1sAt#vZ+ctauhTlrx?m?Y2odGj%y}b*ip<3#(=H? zlpe`M<)o-yi)kGBNREZs{mNxaF`tOd{|R3!4`p1@yuEijvp~CCu?cD;n~R7mYe*-% zql!TMOvY{B^_5JRElhatW%!PAOTWt17rbI{3Wt;0-jK4c#(nduv@K9JNI5+oMKoAd zTJ^2Gwly2_KKEom-aO9ppZKx*DUnp)2FHF`_BKa#r_W?+4gbb!yy*lyc6CIv@n z?1tXLQLdOrL%GX*3g$xaRajB4bvSaimSLJnhW<52$!l77Gkp0zO0MfHi=W<~%G*+A zz)3F?qW9P0);?>?L!-Zst#@%=>mB`;r$|8Pnq%yIpj@z*fcRsJ&ymJ3_1F|#{pDi+;V#*P zPY+&d9^2(5*HY>f9|RbhO;d9kW@OS@Q5BlbuC9U zDaUeqqXfOe$!6{O#+C)Sxp!=|W_I-+Iw_DyFRa7NXuuPot$hbRAj_Jt6g!aZWr9>H z1K}4qSpg~}{Btv;f>aSCmnz6(oFxq2B z{2?++n#_dy*q#UolZU~Rs`88wD9t2*4!#OiJJNM-2@+qW$5w>Iu(BTEb_1%(!|`KB zSj~JRu549oWfN0!2Wk2{iG9?QW_jOf&sDq553+?tkr%@EfB6!)5!px{Ob&QN=ZoU; zf?W9q6auQ%eNA&XnfAl(72h&)*a*4N-biq~J3tu6xOgZ47Ugz*fYPkN4l~s9jXeq>8GJ97ni_cC2%WbO{>6)Y9it?Fygh^0=F;) zwef_1yu>cPBxylUz?O=yaJ{Xwje01Hc&SXRxb&-<#Jim?S7f|s_3LsjoZ)v^y2ksZ zmMF!c?&lh+U2LDAXO-m*al2#>sfM=CcSFubTJNY^`WU6HFhL3dUvW$eoZp!)JZJrO zYy@WJ2>U3!93{=IJ1k&AzZ4aMpW6ov?C+qIkL^thfC^3XFsO0BAPA)MZ2Mg}NK?-5 z>x2Ki{+g0;cMco|&A8&Jz;TflF;vFTn_vz$Q`K!f43BAtsN!Ae^TevstAs4j!$M&#boh5!pzLwyg z{QLn6GYY=`dOsa)O1uu97LHvg=ZNDdF*fVRByz>$dtv%Q7#{p+ou^8`U`$#^Eb65F>oSU(|$z|K|%}HP( z{2{Wcv6Ss;Vo16}e9;AwTpJO}6YNDuhFs@y&+APA@FY|%ftYi^yRF>Zb0JH>8{?RrVDFN%zd`Z_0 zLutZ*ML$-;wdl|-{_OR>JV2HrTT@E9qxvYX;*A=JC&CAVw7+Y4J93ND))N1T?(pJgpn8VF<$0U)j0t(8 z&F{vRe{D*~Wjj|aSf|A=Ikf+~LOOA4p7+HsJ?A#nn?8{ruMxJmC`WKEs3o6FRt~JY zy0AQV`~@{GgPD}7;dd9GFrRH#YPEYPNGBMrmAQw1#~e~;VVG6FxL3rDApqX z=KDKq{_FY#H`mS`YOtg=e$8t*Hda%j;4}2|;_brDHN1KK+S;#3>^(#AE1GU8LAeo3 zAj7u?BC1N$O#I@e#p^_>$th+xBH;@f@I(*9a!CTW92xqv1+?Wjc(w94hyxj0!%@tx zzu#r~|NpMd@LB)%7yq}P#eEn2MNi`jP`kw&gSTM|rV?U-xGH2CSqf7gAGKc^?$ZJT zK3r*X=PKKrLZq?Rqt6g7d1)nF9agw^T_?XYC2Z7Af(7RJ;}$uDFoeWS89Yfve~yxX z?&^3SnzhmfzG!;}eO>h(huaXv230ZQZR`Y>D(3iEAGJud(UZOb|{`csxtmX($fa;49A-16pm=eSM$0_Ul?UFVr! z5-oUEew1quH`*3Bwtxx3=b499x~}|wsZd;`{mBlp%e5f`jkG}XL;LtzN>s(IP|PMo z!VQ9fKXT2DQPTXjWoO)Bt3MyVR^42OzmmW&A^AW+CCGVpg*Zo+ZUQG%4_W={2&h7& z@?+QG2a@RtNJSxrxr02E41a!H?wP5+4LE;J)=EM)`G|U?^)g_Y(`@ zfpM=uv6Uu}1o072gQub~^a|F&(`*^?WS(#Gs{Z4?5!bG6xpyXTNwt0Sq>U(h4-MSA zUgYqiSWB=RG4vuIOHQx>652M~2D|ZeY_&pPlb~bqjCFpo)B4e?o9$zgfaSMCq|Ohd zBgVQHfJJNAnK{Dc+#+=pLl!dCKUM0?f4}g8w@(~ud+YDEoM>K74#E#yZw9Oa7cS2R z>6qwLR62Bh+#{1r;MJLo99uv~N>cGT+ zmC*a6m6ohCplxs(MYpi+Wtaw3K$xEd{k<#I*ND{WlK0MiAosD}2}54!_jnNx5FcaD z;Th}L`yqh(2oZ$kmpL8=nL3RaqXFfa^9z-JRju347rtXnABhQJ|EP^1O5~@XC_U1Z z^1e2j9y)9ikEjM6zH9nn&0wfXtc{d#GsYTUb;Xf1C-)QIa{{JbO&W_ zV(1>dhFa*JQiZCwKNMTz*WAAQDe1tB_mbkHPh0MC?e=Tkgzb$Q2ylQ{!sjI-#|YszP&ek8>ML`d3~HLuO1qkr^dikJyTVDRf}`ME zd7~^KeMo4gQiYzPpz$_OV)N^FX9jNMY_1beySq$6mzJL1c->LZTP{$}=iZR109rfvecDa#WCt{*?`>+>^bMPJQl#@hI^exN)@o60DapRx=(+A_T5OijDCQufT}Sr+ z&lBXJ!1aF?AO&3ofAG7U(5~a(dYofoG*#p64xTYj=oaE5W*zpt62=3BH z>Z1S5MZ~b&mfkcpWfWh4_cWoykc{s8Unn-e6U|7Tw-$_PEFua9V&^Xu_}I=U`gssb z=y>pxz{M62&!+`yx&9|UMMs_UJV3z9xHltoE@^tTmCb&&wyp!);?FT`-)(3*<~)3C zo~AUJjqi)30Expb3Ajx)D%l4G`;6Kc>ZK;mEje(Ja!-h>0Y`lxngAL{U|PPr0WK3S ziT}%EW|H{xG?mu*={2j`>WfVfi87%VEGo8}XtgPULHg^BS=~XH8B0GoNC)Ie$tZtU z(5z(2d+f~W#jl=?>1zs|o9-yoFCZh*G96B$v;Og(MXq}{lsBTZ_Yt2{aheDK6>J{) z4*LKMI6^^`R})(eU$YL#7c|lArB<`kQeG?@dgSZu9AdpdVZ^F(arsKY%*WTpKW2Lc z9~}x@U+Q**^HOJvqm@VgEm4}C{%gafXR}WBis(f(TSlK~=6f|x%4@2|3SA;69(v+` zj#e1G;rzI79O~6Z*>k}o?0yVJGe!65GnelC}ooA{PJM}gS3ZGrxY$%B@k92d-JHEtne~;ki zueQ|Z5$WAB+W9{Qu6{`EiIZFYZbp-QngVF?mQcCfghoQ;c_*;+^GzY$bApTK1*@7W z(AwvPW27i%c0fK2&oK1JVuQa61Wv$-kx7fC<5K}IJ3l3^cSJU*-Fj)!g&4hIZ_lLz zEO}y?b04Wo1u?QqhFAfD!7ov|(!6$=X#rpHLM58%r$;TsLlQeX55B1-I=#LTWoCCm zUNvw*o0k?&osOJ;j}aJGFSzbloHu&mdUV%z6@yKk<_>n&a=megcT{=$mjGjpu+EvOxz)s3iCC5yY>+wpm^^pOMiM3riB!Efb!SbZjuGM@^MGrFmf&$KeE=cIs;}Y+$c}0G+Za;(rmmE`h>6B zIa#+Mn8B9G~Wz zCM$W~I65Ba=(`1X?7Zx!z4T3$+s2svTheFB&v?+XU)=}Y7{=9+7&~;fgTY(KHmZG&j>y9a&T{gBg!hw=&)63P`*}mYPEBc7=Regp^q`N`O9wv?FFemJ_fa4DNBhs;%z{ zVci?pmXuG8GhI~)#}7z#-H}~ei5cP*6C1U`IvK5zhD=}3fogyRSzzcZ@< z&H-6C+X3z&_BFIT(VTTs*F?Jh>jh@5Ei!7rR%S2Pqj~$E`1g{l3a=?13y*~3F9)1wB#iiw<+|0J zjY?f~n3^|}Q`uFmp0Ay&61SR(_^AHww}aj zX$^Okx(Ib9j!E4}iL7{a>z!?Vy86m(GM{}Dw@(qzT~>N_`|i%`B%^e@JlnRWCwCvj zH3PiB0q%FuF8rI4(!q&~D)3i{oRP2w|DiIY{uj#70N}h?kytLQ00v+Mnn3LrlU;xn z@Q0^b-|PA>SOJx>f4~Z4{bql%{>}bWqisKTsLY*{r>0PGiDf z7saU}U8I>EUaklUtW&c*?_d<&XnvY0=!98p5*e^%eHJ*&^U>@Tc-_7|7Z2(Wlz-Ll)E7GJ3=%M|I8mm*Eg*(+98v>E;rk2TSs89o zn;!gU!pp5Ej2+j#5>kglO2f8%5dlm6j7e0xd=Hmi!9$1T%2G~!cd1f1TrJdet-*%w zOCi*jEvFVl^trC3`^*}D$*a#RDk(|2@?o=C{hrlOa-U)neKSrwnckjuQJjiCrq{6H zDw?>t2+FcpaA^A+NlEw+45b+l^K93@;`czM0X0tQ6>i3k2xfqhgifg6S(aUg^(ns- zp%TVksS&I_>pR4kiG62Nai;jH{eDVdA?lB^yVwfD_$X=7b{!RZhn4{asWn;S$nPkX z^FE)I;uOE5q-S8cFwbnhQmf7yD3_V=c+}!riRn!KQt6F2tj{6_pR!_ui`t(M}l5V@zOsQxGT`H77yr+fV9;OiF+O#`x9`<6kIn1^|P> z7p~UL6d3!h8#udwj~4OBX1cGx$Lj;qPp&3Lq}5+fGvLqJ`>{!EYZ;VTLVdaHt$G*X zANQaR>Tkx{;f1xM-~x%4f%?iM!&WDCW``M1Owt;MsH>NFp%o2B2}6-*p|)x~ywk z>Sf%`dAE>30R;IdBqU5q^A`$AN2^eMq{{?`Yyp8L41P^FrfiEE4O>T8cL~0npAU(E6LgZMyYY{vIhZbv!fh>j$99ri@>p#;cM?ps>SENbj*1;kuOny z(!S`m%I+opR|QY~1d|*D;hh z=k7VNRxD)`skTsyzt8qMPMq$uPtBKhsCDwDMe^-^aRyrLKvXvkvtaAgls;l>^GZ}G zCVlIJ`;IDDw6YcP&i3}+f^DB0MK7Dmgx=Vzjau3aOewwC0t0r;ZTtk6H>wRx%)cqw z2fPzHyo{fkQT1?clDB$&Vn}DV{rK(MdLdU=YKGr*`Y9EmxqQ{yy&9J|HaHL%EpDNhi{8%$nr>T-TUz z(#d$&X3ZA1+esRxuN@_=XdSRvJ0-6!%#_36fs7aVLjE3?Un*lb_I-_iks@kcsp z1GQ#VEkTSxX28P1RdxdR3y1pA;mhh>NoOe0zZOY*H!95W_Q-|hMUZaUi6!*BQb6ycR*ilD;H zFT_xH)idKyM|&R(2wi!^HQ*zaOcIZ#Eb}RAxw3zM z+Rf9CJa%gtd(ixqTP0PW$!Bk%T1(5e26VjG(2PteJ@8E#%8B$jTiU(e2S$hDp(c^SP1*J(7k8)5zpQfF;xN$$9n98q)gS zaicTFA5(Vjj@mL+a29$2e48TsY_ zb(*Mb%^h^e2!s;G&cPWK?)aiMH}2%^!e4A+JOoZP5G5yaf#sdWe!`#Wz01VUMZw4+ z5gi=U2&?zuA7tJEXXv@GiGV{$+%jf^2Pto%HE_csUi+Ae|Z&G*3WRXjs?3 zuqxqK2r^$er3=N4R|=!BbED{hgqCU|Y;6ps8i2qAVO*N-gJL{5SN4Mw2_xtanjnMR zMw$~QYGQKM=R8?ydt_%MsQ!!dIHqJ= zPY1C8QAZlB2sN&v2eMC($6F{HT#6ssmUi*n0p&&mR@-nGO{Tq$-2mT`;e%pY_C~Q| zNrL!qyCFf<&vI{z>pd#Q*6dAIFo-dKG~u$j&{6n|vN^BJOgi;Yamoe??Map)|FQU8 zT9e|B*RN6uN3}jxo88YTm@{FDc%WIxgRiVBBc!?QV4u4OQqj-d^!*yZv%XIQk$U+8 z-#tJ)OE;hzeeG)sb7;>}WlXGo?$W;VXL9sx^sva;VF=? zhc+Z`_q)ySX}Z@E*ABhj63CSP5Z&N5&k51Jy)nVtNJrmmtF zR%u*$FDd9M#pc(ju9M{z=xNo_!BX|;QAmX+j=2qDZ~1xE)nTLi$1X_;qGbJ(SnHu~ z76BNz}K~xkAN|B-x3rG_X0qI0knn-UNnuv4(=|~HTh#*ypfJhJs9U{_e z#83o5Izg)RUP3QPd@JfXNB?{Nd(XS~KX=^m-gOLQBtEU@mPn(ORAmOFIMC)#Xms}n3t$7i%dLq2#HOYS zp8i;i4a2ITRo&cvLwn!L$49{ZK-#e&V0{!p-m(9WyyIU#6HNe>>I4e9l721U+fT0G zuX#jQbC_4?((Gql(Jd3IHDNzgk94w272!`MQPYB$JhQ zdy*Vo-W^3Tj_x>46k40d!lRn}?4L^E{g+Gi{dO;1n_(}d`Di0^7jWLQmu{iGu(fhk zgi5($NAV!@j1&(`=hlevQ`G!v+qC3B!!CNd^LVxo4%ru_qqx3I=ApT}CC|mVm?*1t zJ9T#QUN@OERNLuVspXtTHpbaVyslH>n_A&AwqUz!|3uSwEtQog6R#6KLE%CDC4>#) zypgL}>E3CzQnQiXrG2*PQ6OiIvZ~F`rz`i6lcRpwb*Ks0U+ezXA;~3dXr3YdO=Vxx z-zxiZkjwfD1MB=HK-M2+{XM}nGx7z>8~He*?X&-2ck@hJjgroK@_?Fb$Mq!aj?_Eg zKYuWN))1M-c6$=!WUV*^?f}M=4nW)XjM3(?P6YOhrvTuz4OBs5AB&IlF%-iFNTTA$ zLbujBG2hwyYnvutA<{ti-ctzi%vu7;NPw#c2~)61qol$y5(_c53c9Ikl!p`g=p|!! zK4s+&uT#_O%IaCeHwYHUR{bAl_y##tr%HSkorkbNZqW(R0D{bp$Y^xZU5%Rvc2Jp>(Qauzr%-wC7DH*LOnLDwT%kJlMWg;*9^ zOjxs9D<0$;Pu%U995mhsihv#t+({!#=?QGK1N7)!T?$yMSHFt^N!lw6@f7HNUR4XS z883KBEwwxnt~9H|sWV>EaZqOVD7wvbSai|oL@QM*GS3xuWDT}M1?n^wuKRggdrEFb zpgje;%(^_K*vs^r_djfE+rPJ6X3FawS_V9$f*e>4gX@wg(BMt_S9QsGEuizDme=>* zCzDtfM-T)eIO=3y0mX*m30*F{9`Z>Q&{Ezw4Q=m7hlS3&;w4DlPA$L_fEoS@=@qPp z9T6^vQd>LTl#b16D$-Rt`9@x#w72i3lc%>Ldoi#$rKqJADM$3G3nh>(@4o$y0(X3wK5Ujs7e&SgCV1JXn0o$$}2% zeq}Dl5+8ApWp+4~42Hfp2L-!qg<#ZHy{Oa{>Gt+p$$S?nxu1)o0Xz@ql0ffUx`F24 z^XxL~=#Hu5QYw!0J`8LyfZdLos)B8kB2VZqd{Wy(O(V00)&r8gwrPr++fE}7o-34!iU4mp z0B9X){&BdsG!%cuEfl(XpbSh;W!(zc>s~i=x%{>{O5RuTN(Z^?**K>o2GhEndW3^7 zt|*u7$yq$*@!+y3yTNs2D+r$|T9ox_Mch?=Vze@yf%syg`-0R4rI2J^8hRH#D}InM zZ%}ybzM0;m8Es#>YEY_gD-OtHPtrr9+XNwEtR%$xg76!7c^@J!qmv0MF(Y>4)3+%kxFThygQJ0JnA7cLDmB}f?Vex z!A9DFYD<7MWDPeG`SBY*PDTMNjO*trA}Wz_`FEJ9FO7c^gThzBcg}cT04rbl_mz(> z1%nap%>)J`H4Vr!=LZn10y<$yIGr+g6NrqB%({(Wns8o5jGN`7#X%syFH~(wPBXjmve2C0`O*~+@C0jhag^gvJ4Z5 z0%)i((%*fCLO2HK?C3S&EpRTH#5&N9 zp9=%Ja}~sN1w-6{U3D4C=LygRP}_*#neAUc{~)$`mSKYRUm=xRz)eAT5Av4A91hIO z+qtU=>UlG_lRn$82WVc9bKC7Tk&z+Hv?3@Tq4q37L{bWM;5f*j7*e?Cb$K->9+0ck zR8m~vkcucVF=;b5VJoqZvHq3p^mHN0im|G?7z62s@s>~C+N^7nZzU9Jd&UwJg)>G@ zstpZ9Y3`(N8X?>p&`LC_Q3eTvw4rQ#8+WMTGD-$i;NY1b`1r5?P0_Kbt9y$0#B4Mh zP`lhS{x@8NCphPiXT9cbbl5j%UC~-7lL6mVPs?#wib(ck3*{`H{aDvpym-cf=%Eov zBiW|!A1@rGZ*zN}RMr#x;Yg>Qqz^DB0=l@+Roig8QDVpJk$Ux%7fp_hTpC-hlW~@~ zBj#%JR2JOtaS`Jodf(Txv)Y%N-7~LWpV~Of&hF%4HwTy)K`0R{*m?MRb$f;C`n}l^ z*p4%RyTW-B6bK6YBLR!``?C8|);dF!DtLvfcnc-y4sBdbcx}O-7E*Ho(dFKLv;f z%LEv#j|5p2X_2w$Ce_Uwl7OX=Ap%=-*BIbLV8i@Cv8F2g{(Q=r#Xj@jjlj$3kn*ls zqP1q{s8&@cny*bo+dMX&a)v_q8Ysh40yAmZVoM{vr$fvYE;tV($@?v^($HJvgNMaI z3SJ2^*p&`W;Koa?FH36Fr+t{3y07)HlLa!LHHqlcBwe#%B)y03oJL2$hA)Du_Ed$c zg#8G7CT{RlSD|Q)Yj4y*JJ*L>0lkFslUld7u ztK86kDXRuvhr%;ri*(BhiOmJLwv;!`_vb=VmiKY&)*Uih3UKov`M}LdlpG-cY67Y* zgMNd#$9v#txD zK#BWw2atyd9Eqx5Xbv~<1*9sTwd@{`oez8Nnb$dz4ECH#MwLy($bpYitnYhAjx!sI z89!8Sd$e?wBFruE@K=b?E9(_H5*_p?05K1MAMXITvTWG(?9{MSrQwgO6;*aF^4%dd zxqcRE`f`-bO%myN8G7dnc}W8%2I2^#gMqNC2vRi;x=leg_|&4=;zR#Czy)%QnQ)XpZvPWRJ#_S-?HIB*c{*Wb$t{fKJL1mS^K!5u3- z3S~Tu&C{`CgT2+x$6W8lU6@7cvp@(191)6fL`g9HVOZoUq#d(F3j@ykBVQqh5v^1} zZG5Kyro9jB!tAOYaIHLt?ML)nf{q(763(!ayLy=1)o`F)T2x!_$>utElucdkQqmbe zZC0PdkrZUO-e)PU`;63G7Caccl&x&)C|rQC^QWPUvL)7%>$~j_eTtb9Bdal>ZZlXy zLU*b>h{4V_SGAWCsx~%?8SlMFr*A&(P;)xb@)|6p9G&S4BJ@Zv9bl&UgzNE(P zocVs2OD&TA6!NN?h8`ZS?DHR6PH)AKu9RI^EqyguZ+qBZvNYj?PkbCmr9J!kh(*BKXn&eFcJYy zUp-BXso>4olpoIPa2~kmB|VR3k7$fBeiVNjhxV<%&e;s%xDE=$Pm7c-VvUYYm)Vr} z59)&gpBECxdqN<&RiMJ>9KZ%jJdE_XSreS-3U*d{8enJxkB;ijI;;+Jjhv<6f_VRs zY(`x%%K}oUC$AFf10x9HesIL<4s_HgNed+7+7URR0U$)_oE2tc4jhK~y}Pks^Bu|~ z32(E@LOgkwuwRfhyk|$K{1*#psArB9g&EZ>H=lu|CoZcNdbPWuQbv3v_14puo>Y#) zc3Z9+LfaRFd14m3&&n$$fa=GMKy^;6;sD71DibjTBmvkX2_Q?t&x7{x+o0K! zyF0t85(t?jK|l9TllHY{FP^gCyDvM$3rSY3G&hJNQ~~B(HFDZBSk< z%bE-K7DDi`cbblPm@fSp`NRHQk6g zaX*NL-a)sCb5deqrqJDP{_jXE-8mIkQTmo0`UWX^DcC(P%ntMPPbCLJHa$k6)kx?p z2ws;2=`0DyI&HHTa(i!@DJ zZ}auXpUJ}dZMwevHb!&=3*hEm*}x)pk=Sp!`QIpcS-l-6%g|&y*WiU84dt3Y}bR>_JMb%ct z@SiI`x?lur+UvNPlJc4~BJpd4QHsM3|ArG0I%hoTocd2iLAs7KS zTWYB1o1^}zf^SFnR^cUFV(8yOv(>kKqeyC-We_1Mx#G*t(84&>J%sYXGh)%GS z!KxtUR%ix_rjc^VO-A`wpz9M7TcFr1Nxl#`B!9XrbkmZ5I|{Lk0Qs!AKzn(5L{n|goHEXk_D$6QIfn!7eSyFslOi4(o&5GpGPjW8?EsmfT;nb0N5t*Vs_tN z%z5M%s+oVyl>!hyUm?th7=*0}2DxN3=3!0{dO^HCv;_l_p8{0N^RJK$K)HOET(qU5 z{C2qyAQ})sm?l`Uz;}`5lUQybTG4;@E&(fYhhS^2{C_mTe3LSo#G?9JXPlDPfqegX z$}1qTQUqa#U`jG3mIjj$>QZi1?Eqr{{CXKHJeGHKljT1PkIF&@)gqg+Xz*t3dJT94c;MIFm*-~ z(7u?VN%E+G33dp`=C@H%-L!;lM`4yq))Z-D0( z`zKHNr(@3^r>^>Q#}KN6|%C3f3fAiz98}w-YN zB6={#3A?^R2KO)K3zKQ?txFsJkBx0}Urb15vJOtX8U}UE58UU=eR0uQ3x-`>%k>X8 zxEOC)t&V!DvlALyZ-UZLY0)ib4C!=9p-(Lhy}(&7WX^!hn#oAjV`O^}BrUs(+s4xO&DO8?!FyHK#J!N0g` z72z)SHnKmt5+V`USjaA%Iw^hTQD#NU4f8J<3i4gv)eNo^uNgYI7y02=#6j?0H1@ z87yvW!!&Qo*xqI1oc-mMKrY-7MLQn(Gf~c>r#fUlpf9go0b2HMaBIk){Uih5{$7jb zKdH_kXOZM{uq}==ky6MEG;U@F<+23-YhPYe<`Qb{vc;+()nepn>1I5rRdjUk*s!}? z-L0YjAx{qVssy5Ip5*2&v4^&a@)Lr6+heDzl0(5)DRjSoSZLf8m<*f}cVZid)T15C zE|8B1s4d-j({>10%`v0&8g%kjs0^$7)2%PUAKDEYPQ>ZD@4h`Yf7Dq@<>W<5HvjY9 zGaDxQCkN(=SA_B}>94L*wnvjlHdkB{%o?N^->^pMWlU7E(0e7I9s97uUF_t7olYky z{`CP#{}`b3`)9}@UUo=3WX57zjx%+4_Y22cH}bEH-$K9_3cTRF8izhEH&%$V4iT+Z z@ZG6JWzmhMamTo^9hJs9fpHy<$fN$+y0OzvI<}$NwHa3~UTLIiDnuFHO&XbNp}l|K z^DWT86C)&a+H%$uK7BbGf8dgpD=ijM4I1-gj=BirEC!DS;_hu+Q{q=czQ>H-?96^$8U@cw&2936Vg-j7 zqDL=a7rUyWdivm3&G$XoP3_xJ31b?GuGo$;m1<$FI-_k^4pRSa#SdR*PI~M7%KN0) zLHna@lW$J?m>(@s>_CRU--}!>y?+tf%@pDc;(pY|`h0jClx_!u4qZRkEnXTBnSv_|nzg&K1 z)AB>RO~TR^MK*P1)7-o}R4E=kc#CL}C;1jy2GO{WW(7{uwPb}(t1j|N%6Sxz~?(YB?G~1ckMS~AOW#H?E43#AmsZeuGBEDr@ zojW{aE>=ZgAO$WO$E0Y?Ut`R^hNEbZz zJf!eY*Vr-3st3FHXS^eCS}k5viq}!e8IiCN6|%UN55lFKpm1zgg(h#eaY2*16E8uT z#Ndm2?r2c(rqaya&GS&@%;OE+{J{@*V?WaMy-5d2w#j$1LlrIl{sr{cDo0bMN_40B z^Gf3~>q|^cw)#NS+HAKGe8!W()={c@UFMcfRO085Gb%!3Z5>2$kXT%iJc(t_MjsvU zda3mCq}~`b*lIo3s7^CT2D0G@yqYspo)Tn?}<{Tco z!&Z!QPoa+G-=SjtEWzE`4>!l%` z`%_NP5zZ2eB9x`hmX1iSi za_@%cjYa6{kIc*+tK?>?QD?KdK!2wM@9gR%UASU!Gs>*6uH&29pg%j_|UQJaUl@H zWN0`%POLF6cZT^nb&Kzbddd{qWVZ+tP7$0{3gdZ>dT?VUb7WGpVeej12Ks1x6Y8$E zv((jtfnm=rdFT=r9r;r?_|L78Sd<|b4ZcF!W%pG@bl(Q_wr^lB{$*@xzcWGszxM=7$n2aubYpzX4|HgROcHAe&C(YwJHy@|396mAN{kDI1tVYHL|Y zcD57oU8ItKOcFlsra^F84jt8=f8AdQe>rn!Az3&Nc#Vsai9MLbOxQ4p1T1GHuBrB7 zONiMLF@)_l-$gy8VX13t0yLWp3RN_fQf5!Rohl0?0=gf~7~gL5oi|`{yJWJFYeJyN zkoT3x8z8G;+pCq8f+B&bW$}d!IDX$msQU=;7gN;UdiK71|AsH7vs3cMez!)85w0r{ zy_JV~kE=elw~gJH$Y!q)xF3FMo7W6)c`pbR8hY&kL0oxm$e~+vO<#M;lPA3)_~Qu^ zA_xPbUJ$M27`|1ZUv@U(*5k6XG5*!hx;>tIT{)-|Rs3Xi#~#U6y5<8KWTE=VgmE$19(t=T}+iI-jeCpVMDz;RhhLF%E`cLD8)ejjHd zzB|*|iDi$5 zgD+?cf*0Jqc#@bbmAnp@-P~V!cg`6e`s{WwJFjlDeckB$P<*cKj!p#zRv9z8ll)L? zS=CCwz-g-PxUIX;n^x3P&NW~I>iur!d`p@AGfVNm|GPsF>rFUro+U1i`Dif6!f_RD zag)ZGro7ngc>3Ko^;A|<&GnVM(NXheje$pC9Xkd!;ALCFQ_4asPgC>w%^L6r@#UYt z^kwyUu%q_W@Ti6U`kVXXsTDNuWulbCe?8yqRuxp(`*04s_2E^O_C>wT^tucob&@`q0(aP!!xh{yEEE6g}-BOc$4pm8H< zfW6&8*~ul&Ip?|GBL+?4oCAWTfNNi^gGzQ_Tv6t{{zMQBTr}}c z*c{m4)GuS{?*wv|eEXk5Kq*jA&hqIEjgbhUf_*pCl=)^Zg67fB!}fC4GABLU%UNG3 z&xWrNJewKn7}!#Z=R?}HUp);SV9r#xyECeyv8kRG#A4X>(ZH=X^rPK9$eQCV5%D!* z%U*|PQ@%_&ul?ggVs2-GSvKOaqon3J9WIsMY&_^zw{N*9kC|rUXq&orU|Y==AnLS)0%^N4K|K!8eXe+XfTyB@g#;>O~aYI)%!Yu3Y;iN#6#VA zA&K(#-RfcD3&sz%#u@MzA|qYRy!767@S%1B%X|^U8%W*Ve z)i!O4dss!Yr#G6_S(@Gn$EXI+-9l-xPLvX_)_yUQU}JsRTN=B-UgFhWF2OqIV0D4# zEt6K%n7h^+fsnVZ9Ay=83s+VYKB?x&pIDY9<$PAnOK)aqPkR1Vf>!Ysiwo&Yr%emN zQ!rGXIcHymiRf2|-Y(cq8p9{zp50pF7rYLluEZD1n=(Gj9$HMv*zW3ao)@j`%;QeqWl4(tN+?p$if@pbFvRYMrd}2qLfb(`)@8Um>DIO$pYWoeub$|c3DYGSQoyJLRSqI==e+k{fgG><&F<2o%IEc6-2bFJGMa`M_gl6iH zG*QjWxsD_{QP^a!>dq8kEBD7kS7tegt6Uz;>ol3&B+cZ8RcI75#~VUctQ|9`-DJ0k z0o-Ad9dngi0rVM&*v#13zs_aMBkix7Pt3doUG$D>gt9crf3#)-L9#3X6{c?e`-Y(p zg-B@4Jf%Il8Mt^2Z|7QA;M(4)HgucSUOa0G@H?$yr}h|irNZB-W=Rabni1o>{nT^0 z4x@vXicl|qx!B+6oumCRTFi`Xr|bOLndY-T3!koHI9&>1jr&X! zXUTDAMZusFo-8V)4o~khxtk40M6MuU|0Vv=xKeigu=8a88(Fr$$mp4aPWX|dh7|(d=hN+hoYM`7lx%8(w{Y8Q!O=1=JVJ+6tm80vsqr4Jqsu0s zmR$zH`lfnhNZ`#|Ee$7SN%@wy)0)E=Nh8bFuP}InnlGrbr@FY!EQ;9JX9DL{^;<>7 za!ZVpiltcGMCHA1zExyvg3Fy(bySqUE{?k*ubT+=luV|`f2dt?uF`zFLvs&mWS-0Hnl<)V)rSuttgZ5V4;6Ia)JbvlqU z30Se;t!6;Ts{Ier=KkFOkn~Ud692c~XI(1uYfh#-m|ZoHSx6tJYA=)!)c>sZMZ?Bp zSboupM599~m(YV)_+2mYPistX_!N#G0C|&uepL26NWm z)v|amaf*WjEJ2I^F|5m9nah9IH2}9c50EF;&A%~l=U;Lf%m4Q8UvsL>|F3fV`nkg! JYYGAX{tvTa&HVrX literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index 74c50d6f6..44d815d80 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,17 +1,4 @@ -# Crane: Cloud Resource Analytics and Economics - -[![Go Report Card](https://goreportcard.com/badge/github.com/gocrane/crane)](https://goreportcard.com/report/github.com/gocrane/crane) -[![GoDoc](https://godoc.org/github.com/gocrane/crane?status.svg)](https://godoc.org/github.com/gocrane/crane) -[![License](https://img.shields.io/github/license/gocrane/crane)](https://www.apache.org/licenses/LICENSE-2.0.html) -![GoVersion](https://img.shields.io/github/go-mod/go-version/gocrane/crane) - -Crane logo - ---- - -Crane (FinOps Crane) is a cloud native open source project which manages cloud resources on Kubernetes stack, it is inspired by FinOps concepts. - -## Introduction +# Introduction The goal of Crane is to provide a one-stop-shop project to help Kubernetes users to save cloud resource usage with a rich set of functionalities: @@ -75,4 +62,3 @@ Crane is composed of the following components: - [crane-agent](https://github.com/gocrane/crane/tree/main/cmd/crane-agent) - Ensure critical workloads SLO based on abnormally detection. - [gocrane/api](https://github.com/gocrane/api) - This repository defines component-level APIs for the Crane platform. - [gocrane/fadvisor](https://github.com/gocrane/fadvisor) - Financial advisor which collect resource prices from cloud API. - diff --git a/docs/index.zh.md b/docs/index.zh.md index 9c3aea1ee..3ea987f38 100644 --- a/docs/index.zh.md +++ b/docs/index.zh.md @@ -1,17 +1,4 @@ -# Crane: Cloud Resource Analytics and Economics - -[![Go Report Card](https://goreportcard.com/badge/github.com/gocrane/crane)](https://goreportcard.com/report/github.com/gocrane/crane) -[![GoDoc](https://godoc.org/github.com/gocrane/crane?status.svg)](https://godoc.org/github.com/gocrane/crane) -[![License](https://img.shields.io/github/license/gocrane/crane)](https://www.apache.org/licenses/LICENSE-2.0.html) -![GoVersion](https://img.shields.io/github/go-mod/go-version/gocrane/crane) - -Crane logo - ---- - -Crane(FinOps Crane)是一个云原生开源项目,它管理Kubernetes上的云资源,其灵感来自FinOps理念。 - -## 介绍 +# 介绍 The goal of Crane is to provide a one-stop-shop project to help Kubernetes users to save cloud resource usage with a rich set of functionalities: @@ -65,12 +52,12 @@ Please see [this document](tutorials/using-qos-ensurance.md) to learn more. Crane is composed of the following components: - [craned](https://github.com/gocrane/crane/tree/main/cmd/craned) - main crane control plane. - - **Predictor** - Predicts resources metrics trends based on historical data. - - **AnalyticsController** - Analyzes resources and generate related recommendations. - - **RecommendationController** - Recommend Pod resource requests and autoscaler. - - **ClusterNodePredictionController** - Create Predictor for nodes. - - **EffectiveHPAController** - Effective HPA for horizontal scaling. - - **EffectiveHPAController** - Effective VPA for vertical scaling. + - **Predictor** - Predicts resources metrics trends based on historical data. + - **AnalyticsController** - Analyzes resources and generate related recommendations. + - **RecommendationController** - Recommend Pod resource requests and autoscaler. + - **ClusterNodePredictionController** - Create Predictor for nodes. + - **EffectiveHPAController** - Effective HPA for horizontal scaling. + - **EffectiveVPAController** - Effective VPA for vertical scaling. - [metric-adaptor](https://github.com/gocrane/crane/tree/main/cmd/metric-adapter) - Metric server for driving the scaling. - [crane-agent](https://github.com/gocrane/crane/tree/main/cmd/crane-agent) - Ensure critical workloads SLO based on abnormally detection. - [gocrane/api](https://github.com/gocrane/api) - This repository defines component-level APIs for the Crane platform. diff --git a/docs/getting-started.md b/docs/installation.md similarity index 83% rename from docs/getting-started.md rename to docs/installation.md index 412fa7c13..fef9c1ce0 100644 --- a/docs/getting-started.md +++ b/docs/installation.md @@ -1,17 +1,17 @@ -# Getting Started +# Installation -## Installation - -**Prerequisites** +## Prerequisites - Kubernetes 1.18+ - Helm 3.1.0 -**Helm Installation** +## Steps + +### Helm Installation Please refer to Helm's [documentation](https://helm.sh/docs/intro/install/) for installation. -**Installing prometheus and grafana with helm chart** +### Installing prometheus and grafana with helm chart !!! note If you already deployed prometheus, grafana in your environment, then skip this step. @@ -32,7 +32,7 @@ helm repo add grafana https://grafana.github.io/helm-charts helm install grafana -f https://raw.githubusercontent.com/gocrane/helm-charts/main/integration/grafana/override_values.yaml -n crane-system --create-namespace grafana/grafana ``` -**Deploying Crane and Fadvisor** +### Deploying Crane and Fadvisor ```bash helm repo add crane https://gocrane.github.io/helm-charts @@ -40,7 +40,7 @@ helm install crane -n crane-system --create-namespace crane/crane helm install fadvisor -n crane-system --create-namespace crane/fadvisor ``` -**Verify Installation** +### Verify Installation Check deployments are all available by running: @@ -66,7 +66,7 @@ prometheus-server-5966b646fd-g9vxl 2/2 Running 0 45 you can see [this](https://github.com/gocrane/helm-charts) to learn more. -**Customize Installation** +## Customize Installation Deploy `Crane` by apply YAML declaration. @@ -96,19 +96,3 @@ kubectl --namespace crane-system port-forward $POD_NAME 3000 ``` visit [Cost Report](http://127.0.0.1:3000/dashboards) here with account(admin:admin). - -## Analytics and Recommendation - -Crane supports analytics and give recommend advise for your k8s cluster. - -Please follow [this guide](tutorials/analytics-and-recommendation.md) to learn more. - -## RoadMap -Please see [this document](roadmaps/roadmap-1h-2022.md) to learn more. - -## Contributing - -Contributors are welcomed to join Crane project. Please check [CONTRIBUTING](./CONTRIBUTING.md) about how to contribute to this project. - -## Code of Conduct -Crane adopts [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). diff --git a/docs/getting-started.zh.md b/docs/installation.zh.md similarity index 98% rename from docs/getting-started.zh.md rename to docs/installation.zh.md index fabc54870..28e08bcc5 100644 --- a/docs/getting-started.zh.md +++ b/docs/installation.zh.md @@ -1,8 +1,5 @@ # 产品部署指南 -!!! tip - 本页面来自 https://github.com/gocrane/crane/pull/243 @willemswang - 为了让您更快的部署 Crane ,本文档提供清晰的: * 部署环境要求 @@ -52,8 +49,6 @@ helm install crane -n crane-system --create-namespace crane/crane helm install fadvisor -n crane-system --create-namespace crane/fadvisor ``` - - ## 验证安装是否成功 使用如下命令检查安装的 Deployment 是否正常: @@ -92,8 +87,6 @@ kubectl port-forward -n crane-system svc/craned 9090 ![](images/crane-dashboard.png) - - ### 添加安装了 Crane 的集群 您可以点击上图中的“添加集群”的蓝色按钮,将 Crane 控制台的地址 `http://localhost:9090` 作为 Crane 的 URL,作为第一个集群添加到 Crane 控制台。 diff --git a/mkdocs.yml b/mkdocs.yml index b7be8c352..065102d4c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,6 +16,8 @@ theme: text: Work Sans extra_javascript: - assets/util.js +extra_css: + - assets/util.css extra: version: provider: mike @@ -33,8 +35,9 @@ plugins: build: true nav_translations: zh: - Overview: 总览 Getting Started: 从这里开始 + Introduction: 介绍 + Installation: 安装 Tutorials: 教程 Proposals: 提案 Contributing: 贡献 @@ -58,13 +61,14 @@ markdown_extensions: repo_url: https://github.com/gocrane/crane repo_name: gocrane/crane nav: - - Overview: index.md - - Getting Started: getting-started.md + - Getting Started: + - Introduction: index.md + - Installation: installation.md - Tutorials: + - Effective HPA: tutorials/using-effective-hpa-to-scaling-with-effectiveness.md - Analytics and Recommendation: tutorials/analytics-and-recommendation.md - - Using Effective HPA To Scaling With Effectiveness: tutorials/using-effective-hpa-to-scaling-with-effectiveness.md - - Using Qos Ensurance: tutorials/using-qos-ensurance.md - - Using Time Series Prediction: tutorials/using-time-series-prediction.md + - Qos Ensurance: tutorials/using-qos-ensurance.md + - Time Series Prediction: tutorials/using-time-series-prediction.md - Proposals: - Advanced CpuSet Manager: proposals/20220228-advanced-cpuset-manger.md - Contributing: CONTRIBUTING.md From c7ba6f573ac81fc2cb109123ce2bb021e7fdc751 Mon Sep 17 00:00:00 2001 From: qmhu Date: Fri, 8 Apr 2022 11:17:41 +0800 Subject: [PATCH 11/41] update url --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dcdbd4054..dae503d80 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,9 @@ The goal of Crane is to provide a one-stop-shop project to help Kubernetes users ## Getting Started -- [Introduction](https://docs.gocrane.io/getting-started/introduction) -- [Installation](https://docs.gocrane.io/getting-started/installation) -- [Tutorials](https://docs.gocrane.io/tutorials) +- [Introduction](https://docs.gocrane.io) +- [Installation](https://docs.gocrane.io/dev/installation/) +- [Tutorials](https://docs.gocrane.io/dev/tutorials/using-effective-hpa-to-scaling-with-effectiveness/) ## Documentation From 4c789c8a8a8964006836c3d4d91089f29eddbfa5 Mon Sep 17 00:00:00 2001 From: qmhu Date: Fri, 8 Apr 2022 12:21:27 +0800 Subject: [PATCH 12/41] Update community call --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dae503d80..e6fd54b0e 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,10 @@ Full documentation is available on the [Crane website](https://docs.gocrane.io). Wechat -- Bi-weekly Community Call: [Meeting Notes](https://doc.weixin.qq.com/doc/w3_AHMAlwa_AFU7PT58rVhTFKXV0maR6?scode=AJEAIQdfAAo0gvbrCIAHMAlwa_AFU). - -- Bi-weekly Chinese Community Call: [Video Records](https://www.wolai.com/33xC4HB1JXCCH1x8umfioS). +- Bi-weekly Community Call(APAC, Chinese) + - [Meeting Link](https://meeting.tencent.com/dm/SjY20wCJHy5F) + - [Meeting Notes](https://doc.weixin.qq.com/doc/w3_AHMAlwa_AFU7PT58rVhTFKXV0maR6?scode=AJEAIQdfAAo0gvbrCIAHMAlwa_AFU) + - [Video Records](https://www.wolai.com/33xC4HB1JXCCH1x8umfioS) ## RoadMap From 5ea7cab6e12906f727218ef6884e9991e983cd6f Mon Sep 17 00:00:00 2001 From: zsnmwy Date: Fri, 8 Apr 2022 18:27:19 +0800 Subject: [PATCH 13/41] Remove docs tips && Set dev default make copies of docs for each alias Signed-off-by: zsnmwy --- .github/workflows/mkdocs-publish.yml | 3 +-- .github/workflows/mkdocs.yml | 1 + mkdocs.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mkdocs-publish.yml b/.github/workflows/mkdocs-publish.yml index a900da4e0..c2a526be2 100644 --- a/.github/workflows/mkdocs-publish.yml +++ b/.github/workflows/mkdocs-publish.yml @@ -32,8 +32,7 @@ jobs: if: ${{ github.event.created }} run: | echo ${{ steps.extract_branch.outputs.branch }} - mike deploy --push --force --update-aliases ${{ steps.extract_branch.outputs.branch }} latest --rebase - mike set-default --push --force latest + mike deploy --push --force --no-redirect --update-aliases ${{ steps.extract_branch.outputs.branch }} latest --rebase - name: Mike if: ${{ !github.event.created }} diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml index eed2ce56b..1bd49a85b 100644 --- a/.github/workflows/mkdocs.yml +++ b/.github/workflows/mkdocs.yml @@ -19,3 +19,4 @@ jobs: git config --local user.name "github-actions[bot]" - run: pip install mkdocs-material mkdocs-static-i18n mike - run: mike deploy --force --push dev + - run: mike set-default --push --force dev diff --git a/mkdocs.yml b/mkdocs.yml index 065102d4c..98206640d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,7 +2,7 @@ site_name: Crane - Cloud Resource Analytics and Economics theme: name: material - custom_dir: overrides +# custom_dir: overrides language: en features: - toc.integrate From b50c195f0cbae48e2d23b0d7710c96371e35f8ef Mon Sep 17 00:00:00 2001 From: patricklai Date: Thu, 7 Apr 2022 11:33:37 +0800 Subject: [PATCH 14/41] fix(web): fix edit cluster model click cancel, form data doest not clear; add logo; fix start scripts --- pkg/web/package.json | 2 +- pkg/web/public/logo.svg | 141 ++++++++++++++++++ pkg/web/public/runtime-env.js | 1 - .../src/components/layouts/DefaultLayout.tsx | 5 +- .../components/overview/EditClusterModal.tsx | 3 +- pkg/web/src/store/editClusterSlice.ts | 16 +- 6 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 pkg/web/public/logo.svg delete mode 100644 pkg/web/public/runtime-env.js diff --git a/pkg/web/package.json b/pkg/web/package.json index c1c479134..e9818f0ea 100644 --- a/pkg/web/package.json +++ b/pkg/web/package.json @@ -7,7 +7,7 @@ "node": ">=14.17.0" }, "scripts": { - "start": "NODE_ENV=development runtime-env-cra --config-name=./public/runtime-env.js && react-scripts start", + "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", diff --git a/pkg/web/public/logo.svg b/pkg/web/public/logo.svg new file mode 100644 index 000000000..dfbfae831 --- /dev/null +++ b/pkg/web/public/logo.svg @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pkg/web/public/runtime-env.js b/pkg/web/public/runtime-env.js deleted file mode 100644 index 9d2e5333e..000000000 --- a/pkg/web/public/runtime-env.js +++ /dev/null @@ -1 +0,0 @@ -window.__RUNTIME_CONFIG__ = {"CLUSTER_ID":"cls-j3vgaeae","CRANE_URL":"http://localhost:3333"}; \ No newline at end of file diff --git a/pkg/web/src/components/layouts/DefaultLayout.tsx b/pkg/web/src/components/layouts/DefaultLayout.tsx index 1053500df..389c373ca 100644 --- a/pkg/web/src/components/layouts/DefaultLayout.tsx +++ b/pkg/web/src/components/layouts/DefaultLayout.tsx @@ -7,7 +7,7 @@ import { SupportLanguages } from '../../i18n'; import { ContentHeader } from '../common/ContentHeader'; import { SideMenu } from '../common/SideMenu'; -const { Header, Content, Footer, Aside } = Layout; +const { Header, Content, Aside } = Layout; const { HeadMenu } = Menu; export function DefaultLayout({ content }: { content: React.ReactNode }) { @@ -18,7 +18,7 @@ export function DefaultLayout({ content }: { content: React.ReactNode }) {
    {'Crane Dashboard'} + logo } operations={
    {content}
    -
    Copyright @ 2019-2020 Tencent. All Rights Reserved
    diff --git a/pkg/web/src/components/overview/EditClusterModal.tsx b/pkg/web/src/components/overview/EditClusterModal.tsx index 59a62bc62..0915be806 100644 --- a/pkg/web/src/components/overview/EditClusterModal.tsx +++ b/pkg/web/src/components/overview/EditClusterModal.tsx @@ -15,7 +15,6 @@ type Validation = { error: boolean; msg: string }; export const EditClusterModal = React.memo(() => { const { t } = useTranslation(); const dispatch = useDispatch(); - const editingClusterId = useSelector(state => state.editCluster.editingClusterId); const mode = useSelector(state => state.editCluster.mode); const visible = useSelector(state => state.editCluster.modalVisible); @@ -194,7 +193,7 @@ export const EditClusterModal = React.memo(() => { }} >
    {t('请输入一个可访问的CRANE Endpoint,以获得新集群的相关成本数据')}
    -
    + cluster.id !== action.payload.id); }, resetCluster: state => { - state.clusters = initialEditClusterState.clusters; + state.clusters = [{ ...defaultCluster, id: v4() }]; }, modalVisible: (state, action: PayloadAction) => { state.modalVisible = action.payload; From 845848e780df464d52296f9bca26d6bdd8460b0e Mon Sep 17 00:00:00 2001 From: devinyan Date: Thu, 24 Mar 2022 13:43:46 +0800 Subject: [PATCH 15/41] update the video for disable scheduling --- docs/tutorials/using-qos-ensurance.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/tutorials/using-qos-ensurance.md b/docs/tutorials/using-qos-ensurance.md index 5adaa5bfb..a51a46e5d 100644 --- a/docs/tutorials/using-qos-ensurance.md +++ b/docs/tutorials/using-qos-ensurance.md @@ -62,8 +62,7 @@ spec: Please check the video to learn more about the scheduling disable actions. -[![disable scheduling example video](../images/disablescheduling-example.png)](https://youtu.be/87bnz5LasbI "disable scheduling") - +[![disable scheduling example video](https://asciinema.org/a/480735.svg)](https://asciinema.org/a/480735) # Throttle From 98a159b632faa9feb1937075d40f9308b14f1f27 Mon Sep 17 00:00:00 2001 From: qmhu Date: Mon, 11 Apr 2022 17:56:21 +0800 Subject: [PATCH 16/41] Update roadmap-1h-2022.md --- docs/roadmaps/roadmap-1h-2022.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/roadmaps/roadmap-1h-2022.md b/docs/roadmaps/roadmap-1h-2022.md index 79f11fd43..aba63646a 100644 --- a/docs/roadmaps/roadmap-1h-2022.md +++ b/docs/roadmaps/roadmap-1h-2022.md @@ -20,13 +20,13 @@ Please let us know if you have urgent needs which are not presented in the plan. - Scalability to support 1K TSP and 1K EPA ### 0.4.0 [April] - EVPA support -- Application Portrait -- Descheduler and Dynamic Scheduler -- SLO based Application QoS for CPU and Mem +- Dynamic Scheduler - UI to support EPA. ### 0.5.0 [May] - HPC open source - Node & Pod QoS Ensurance for DiskIO and Network - Prediction with DiskIO, Network ### 0.6.0 [June] -- Scalability to support 3k TSP and 3k EPA +- Scalability to support 3k TSP and 3k EPA +- Application Portrait +- SLO based Application QoS for CPU and Mem From 1a7cba42508ec51e4b9b8f8210619f87e160218b Mon Sep 17 00:00:00 2001 From: zsnmwy Date: Mon, 11 Apr 2022 21:02:58 +0800 Subject: [PATCH 17/41] perf(workflows): Optimize CI --- .github/workflows/go.yml | 176 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 3 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 36ad7b47f..8773306ad 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,7 +5,71 @@ on: [pull_request] jobs: - build: + cover: + runs-on: ubuntu-latest + steps: + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.17 + + # Get values for cache paths to be used in later steps + - id: go-cache-paths + run: | + echo "::set-output name=go-build::$(go env GOCACHE)" + echo "::set-output name=go-mod::$(go env GOMODCACHE)" + + - name: Checkout + uses: actions/checkout@v2 + + # Cache go build cache, used to speedup go test + - name: Go Build Cache + uses: actions/cache@v2 + with: + path: ${{ steps.go-cache-paths.outputs.go-build }} + key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} + + # Cache go mod cache, used to speedup builds + - name: Go Mod Cache + uses: actions/cache@v2 + with: + path: ${{ steps.go-cache-paths.outputs.go-mod }} + key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} + + - name: Go Lint Cache + uses: actions/cache@v2 + with: + path: | + ~/.cache/golangci-lint + key: ${{ runner.os }}-go-lint-${{ hashFiles('**/go.sum') }} + + - name: Generate + run: make generate + + - name: Fmt + run: make fmt + + - name: Vet + run: make vet + + - name: Cover + run: go test -coverprofile coverage.out -covermode=atomic ./... -v + + - name: Convert cover report + run: | + go tool cover -o coverage.html -html=coverage.out + sed -i 's/black/whitesmoke/g' coverage.html + + - name: Upload a Build Artifact + uses: actions/upload-artifact@v3.0.0 + with: + # Artifact name + name: coverage.html # optional, default is artifact + # A file, directory or wildcard pattern that describes what to upload + path: coverage.html + retention-days: 5 + + craned: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -15,5 +79,111 @@ jobs: with: go-version: 1.17 - - name: Build - run: make all \ No newline at end of file + # Get values for cache paths to be used in later steps + - id: go-cache-paths + run: | + echo "::set-output name=go-build::$(go env GOCACHE)" + echo "::set-output name=go-mod::$(go env GOMODCACHE)" + + # Cache go build cache, used to speedup go test + - name: Go Build Cache + uses: actions/cache@v2 + with: + path: ${{ steps.go-cache-paths.outputs.go-build }} + key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} + + # Cache go mod cache, used to speedup builds + - name: Go Mod Cache + uses: actions/cache@v2 + with: + path: ${{ steps.go-cache-paths.outputs.go-mod }} + key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} + + - name: Build Craned + run: make craned + + crane-agent: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.17 + + # Get values for cache paths to be used in later steps + - id: go-cache-paths + run: | + echo "::set-output name=go-build::$(go env GOCACHE)" + echo "::set-output name=go-mod::$(go env GOMODCACHE)" + + # Cache go build cache, used to speedup go test + - name: Go Build Cache + uses: actions/cache@v2 + with: + path: ${{ steps.go-cache-paths.outputs.go-build }} + key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} + + # Cache go mod cache, used to speedup builds + - name: Go Mod Cache + uses: actions/cache@v2 + with: + path: ${{ steps.go-cache-paths.outputs.go-mod }} + key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} + + - name: Build Crane Agent + run: make crane-agent + + metric-adapter: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.17 + + # Get values for cache paths to be used in later steps + - id: go-cache-paths + run: | + echo "::set-output name=go-build::$(go env GOCACHE)" + echo "::set-output name=go-mod::$(go env GOMODCACHE)" + + # Cache go build cache, used to speedup go test + - name: Go Build Cache + uses: actions/cache@v2 + with: + path: ${{ steps.go-cache-paths.outputs.go-build }} + key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }} + + # Cache go mod cache, used to speedup builds + - name: Go Mod Cache + uses: actions/cache@v2 + with: + path: ${{ steps.go-cache-paths.outputs.go-mod }} + key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} + + - name: Build Metric Adapter + run: make metric-adapter + + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Go environment + uses: actions/setup-go@v3.0.0 + with: + # The Go version to download (if necessary) and use. Supports semver spec and ranges. + go-version: 1.17 # optional + + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: v1.45.2 + + # Optional: golangci-lint command line arguments. + args: --timeout 30m --disable-all -E deadcode -E unused -E varcheck -E ineffassign -E goimports -E gofmt -E misspell -E unparam -E unconvert -E govet -E errcheck -E structcheck From 95c319db21eef72f4a0bf2db147048c706fcd654 Mon Sep 17 00:00:00 2001 From: qmhu Date: Tue, 12 Apr 2022 22:25:57 +0800 Subject: [PATCH 18/41] HPA Observer Controller --- cmd/craned/app/manager.go | 6 +- .../ehpa/effective_hpa_controller.go | 2 +- pkg/controller/ehpa/hpa_event_handler.go | 64 +++++++++++++++++++ ...ntroller.go => hpa_observer_controller.go} | 32 +++++++--- .../evpa/effective_vpa_controller.go | 2 +- pkg/metrics/autoscaling.go | 21 ++++-- 6 files changed, 108 insertions(+), 19 deletions(-) create mode 100644 pkg/controller/ehpa/hpa_event_handler.go rename pkg/controller/ehpa/{hpa_replicas_controller.go => hpa_observer_controller.go} (51%) diff --git a/cmd/craned/app/manager.go b/cmd/craned/app/manager.go index f5bba5017..fe3ea1af6 100644 --- a/cmd/craned/app/manager.go +++ b/cmd/craned/app/manager.go @@ -212,7 +212,7 @@ func initializationControllers(ctx context.Context, mgr ctrl.Manager, opts *opti Client: mgr.GetClient(), } if err := podOOMRecorder.SetupWithManager(mgr); err != nil { - klog.Exit(err, "unable to create controller", "controller", "PodOOMRecorder") + klog.Exit(err, "Unable to create controller", "PodOOMRecorder") } go func() { if err := podOOMRecorder.Run(ctx.Done()); err != nil { @@ -242,13 +242,13 @@ func initializationControllers(ctx context.Context, mgr ctrl.Manager, opts *opti klog.Exit(err, "unable to create controller", "controller", "SubstituteController") } - if err := (&ehpa.HPAReplicasController{ + if err := (&ehpa.HPAObserverController{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), RestMapper: mgr.GetRESTMapper(), Recorder: mgr.GetEventRecorderFor("hpareplicas-controller"), }).SetupWithManager(mgr); err != nil { - klog.Exit(err, "unable to create controller", "controller", "HPAReplicasController") + klog.Exit(err, "unable to create controller", "controller", "HPAObserverController") } if err := (&evpa.EffectiveVPAController{ diff --git a/pkg/controller/ehpa/effective_hpa_controller.go b/pkg/controller/ehpa/effective_hpa_controller.go index e11b0a2f4..0552ab0ad 100644 --- a/pkg/controller/ehpa/effective_hpa_controller.go +++ b/pkg/controller/ehpa/effective_hpa_controller.go @@ -184,7 +184,7 @@ func setCondition(status *autoscalingapi.EffectiveHorizontalPodAutoscalerStatus, func RecordMetrics(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) { if ehpa.Status.ExpectReplicas != nil { labels := map[string]string{ - "identity": klog.KObj(ehpa).String(), + "resourceName": klog.KObj(ehpa).String(), "strategy": string(ehpa.Spec.ScaleStrategy), } metrics.EHPAReplicas.With(labels).Set(float64(*ehpa.Status.ExpectReplicas)) diff --git a/pkg/controller/ehpa/hpa_event_handler.go b/pkg/controller/ehpa/hpa_event_handler.go new file mode 100644 index 000000000..dd9d8fcf0 --- /dev/null +++ b/pkg/controller/ehpa/hpa_event_handler.go @@ -0,0 +1,64 @@ +package ehpa + +import ( + "fmt" + "strings" + + autoscalingv2 "k8s.io/api/autoscaling/v2beta2" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + + "github.com/gocrane/crane/pkg/metrics" +) + +type hpaEventHandler struct { + enqueueHandler handler.EnqueueRequestForObject +} + +func (h *hpaEventHandler) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) { + pod := evt.Object.(*autoscalingv2.HorizontalPodAutoscaler) + if pod.DeletionTimestamp != nil { + h.Delete(event.DeleteEvent{Object: evt.Object}, q) + return + } + + h.enqueueHandler.Create(evt, q) +} + +func (h *hpaEventHandler) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + h.enqueueHandler.Delete(evt, q) +} + +func (h *hpaEventHandler) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) { + newHpa := evt.ObjectNew.(*autoscalingv2.HorizontalPodAutoscaler) + oldHpa := evt.ObjectOld.(*autoscalingv2.HorizontalPodAutoscaler) + if oldHpa.Status.DesiredReplicas != newHpa.Status.DesiredReplicas { + for _, cond := range newHpa.Status.Conditions { + if cond.Reason == "SucceededRescale" || cond.Reason == "SucceededOverloadRescale" { + scaleType := "hpa" + if strings.HasPrefix("ehpa-", newHpa.Name) { + scaleType = "ehpa" + } + + direction := "Down" + if newHpa.Status.DesiredReplicas > oldHpa.Status.DesiredReplicas { + direction = "Up" + } + + labels := map[string]string{ + "resourceName": fmt.Sprintf("%s/%s", newHpa.Namespace, newHpa.Name), + "type": scaleType, + "direction": direction, + } + metrics.HPAScaleCount.With(labels).Add(1) + + break + } + } + } + h.enqueueHandler.Update(evt, q) +} + +func (h *hpaEventHandler) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) { +} diff --git a/pkg/controller/ehpa/hpa_replicas_controller.go b/pkg/controller/ehpa/hpa_observer_controller.go similarity index 51% rename from pkg/controller/ehpa/hpa_replicas_controller.go rename to pkg/controller/ehpa/hpa_observer_controller.go index ab1b4ed59..8e03b355a 100644 --- a/pkg/controller/ehpa/hpa_replicas_controller.go +++ b/pkg/controller/ehpa/hpa_observer_controller.go @@ -10,19 +10,22 @@ import ( "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/source" "github.com/gocrane/crane/pkg/metrics" ) -// HPAReplicasController is responsible for monitor and export replicas for hpa -type HPAReplicasController struct { +// HPAObserverController is responsible for observer metrics for hpa +type HPAObserverController struct { client.Client Scheme *runtime.Scheme RestMapper meta.RESTMapper Recorder record.EventRecorder } -func (c *HPAReplicasController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { +func (c *HPAObserverController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { klog.V(8).Infof("Got hpa %s", req.NamespacedName) hpa := &autoscalingv2.HorizontalPodAutoscaler{} @@ -31,15 +34,28 @@ func (c *HPAReplicasController) Reconcile(ctx context.Context, req ctrl.Request) } labels := map[string]string{ - "identity": klog.KObj(hpa).String(), + "resourceName": klog.KObj(hpa).String(), } metrics.HPAReplicas.With(labels).Set(float64(hpa.Status.DesiredReplicas)) return ctrl.Result{}, nil } -func (c *HPAReplicasController) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&autoscalingv2.HorizontalPodAutoscaler{}). - Complete(c) +func (c *HPAObserverController) SetupWithManager(mgr ctrl.Manager) error { + // Create a new controller + controller, err := controller.New("broadcastjob-controller", mgr, controller.Options{ + Reconciler: c}) + if err != nil { + return err + } + + // Watch for changes to HPA + err = controller.Watch(&source.Kind{Type: &autoscalingv2.HorizontalPodAutoscaler{}}, &hpaEventHandler{ + enqueueHandler: handler.EnqueueRequestForObject{}, + }) + if err != nil { + return err + } + + return nil } diff --git a/pkg/controller/evpa/effective_vpa_controller.go b/pkg/controller/evpa/effective_vpa_controller.go index 9494eef16..60f186e71 100644 --- a/pkg/controller/evpa/effective_vpa_controller.go +++ b/pkg/controller/evpa/effective_vpa_controller.go @@ -124,7 +124,7 @@ func (c *EffectiveVPAController) SetupWithManager(mgr ctrl.Manager) error { func recordMetric(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, status *autoscalingapi.EffectiveVerticalPodAutoscalerStatus, podTemplate *v1.PodTemplateSpec) { labels := map[string]string{ - "target": fmt.Sprintf("%s/%s", evpa.Namespace, evpa.Spec.TargetRef.Name), + "resourceName": fmt.Sprintf("%s/%s", evpa.Namespace, evpa.Spec.TargetRef.Name), } for _, container := range status.Recommendation.ContainerRecommendations { diff --git a/pkg/metrics/autoscaling.go b/pkg/metrics/autoscaling.go index d5a1b5944..288156ae0 100644 --- a/pkg/metrics/autoscaling.go +++ b/pkg/metrics/autoscaling.go @@ -13,7 +13,7 @@ var ( Name: "hpa_replicas", Help: "Replicas for HPA", }, - []string{"identity"}, + []string{"resourceName"}, ) EHPAReplicas = prometheus.NewGaugeVec( prometheus.GaugeOpts{ @@ -22,7 +22,16 @@ var ( Name: "effective_hpa_replicas", Help: "Replicas for Effective HPA", }, - []string{"identity", "strategy"}, + []string{"resourceName", "strategy"}, + ) + HPAScaleCount = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "crane", + Subsystem: "autoscaling", + Name: "hpa_scale_count", + Help: "Scale count for HPA", + }, + []string{"resourceName", "type", "direction"}, ) OOMCount = prometheus.NewCounterVec( prometheus.CounterOpts{ @@ -44,7 +53,7 @@ var ( Help: "The cpu scale up for Effective VPA", }, []string{ - "target", + "resourceName", }, ) EVPACpuScaleDownMilliCores = prometheus.NewGaugeVec( @@ -55,7 +64,7 @@ var ( Help: "The cpu scale down for Effective VPA", }, []string{ - "target", + "resourceName", }, ) EVPAMemoryScaleUpMB = prometheus.NewGaugeVec( @@ -66,7 +75,7 @@ var ( Help: "The memory scale up for Effective VPA", }, []string{ - "target", + "resourceName", }, ) EVPAMemoryScaleDownMB = prometheus.NewGaugeVec( @@ -77,7 +86,7 @@ var ( Help: "The memory scale down for Effective VPA", }, []string{ - "target", + "resourceName", }, ) ) From 744b537982df7ed3ff91b150536f371a6fb8c379 Mon Sep 17 00:00:00 2001 From: kitianFresh <1549722424@qq.com> Date: Wed, 13 Apr 2022 20:57:39 +0800 Subject: [PATCH 19/41] update crane ehpa arch --- docs/images/crane-ehpa.png | Bin 79583 -> 79358 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/crane-ehpa.png b/docs/images/crane-ehpa.png index 027cb20ef4c9634dcf7eee2dfd22cccce79b4ea1..6fdb52ff482e41f13242051bdef4f34065acb70f 100644 GIT binary patch literal 79358 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

    5dmnTJsoCbHgHb$s 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�Ky3BpjQ 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

    !?&X2SgAlrA3hJ)4 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 Date: Wed, 13 Apr 2022 22:36:22 +0800 Subject: [PATCH 20/41] add zh doc for ehpa --- ...ctive-hpa-to-scaling-with-effectiveness.md | 9 - ...ve-hpa-to-scaling-with-effectiveness.zh.md | 192 ++++++++++++++++++ 2 files changed, 192 insertions(+), 9 deletions(-) create mode 100644 docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.zh.md diff --git a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md index 7da8d8d16..b6b827f05 100644 --- a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md +++ b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md @@ -50,15 +50,6 @@ spec: 6. Prediction defines configurations for predict resources.If unspecified, defaults don't enable prediction. 7. PredictionWindowSeconds is the time window to predict metrics in the future. -### Params Description - -* spec.scaleTargetRef defines the reference to the workload that should be scaled. -* spec.minReplicas is the lower limit replicas to the scale target which the autoscaler can scale down to. -* spec.maxReplicas is the upper limit replicas to the scale target which the autoscaler can scale up to. -* spec.scaleStrategy indicates the strategy to scaling target, value can be "Auto" and "Preview". -* spec.metrics contains the specifications for which to use to calculate the desired replica count. Please refer to the details: -* spec.prediction defines configurations for predict resources.If unspecified, defaults don't enable prediction. - ### Prediction-driven autoscaling Most of online applications follow regular pattern. We can predict future trend of hours or days. DSP is a time series prediction algorithm that applicable for application metrics prediction. diff --git a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.zh.md b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.zh.md new file mode 100644 index 000000000..28cf1d45a --- /dev/null +++ b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.zh.md @@ -0,0 +1,192 @@ +# EffectiveHorizontalPodAutoscaler + +EffectiveHorizontalPodAutoscaler(简称 EHPA)是 Crane 提供的弹性伸缩产品,它基于社区 HPA 做底层的弹性控制,支持更丰富的弹性触发策略(预测,观测,周期),让弹性更加高效,并保障了服务的质量。 + +- 提前扩容,保证服务质量:通过算法预测未来的流量洪峰提前扩容,避免扩容不及时导致的雪崩和服务稳定性故障。 +- 减少无效缩容:通过预测未来可减少不必要的缩容,稳定工作负载的资源使用率,消除突刺误判。 +- 支持 Cron 配置:支持 Cron-based 弹性配置,应对大促等异常流量洪峰。 +- 兼容社区:使用社区 HPA 作为弹性控制的执行层,能力完全兼容社区。 + +## 产品功能 + +一个简单的 EHPA yaml 文件如下: + +```yaml +apiVersion: autoscaling.crane.io/v1alpha1 +kind: EffectiveHorizontalPodAutoscaler +metadata: + name: php-apache +spec: + scaleTargetRef: #(1) + apiVersion: apps/v1 + kind: Deployment + name: php-apache + minReplicas: 1 #(2) + maxReplicas: 10 #(3) + scaleStrategy: Auto #(4) + metrics: #(5) + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 50 + prediction: #(6) + predictionWindowSeconds: 3600 #(7) + predictionAlgorithm: + algorithmType: dsp + dsp: + sampleInterval: "60s" + historyLength: "3d" +``` + +1. ScaleTargetRef 配置你希望弹性的工作负载。 +2. MinReplicas 指定了自动缩容的最小值。 +3. MaxReplicas 指定了自动扩容的最大值。 +4. ScaleStrategy 定义了弹性的策略,值可以是 "Auto" and "Preview". +5. Metrics 定义了弹性阈值配置。 +6. Prediction 定义了预测算法配置。 +7. PredictionWindowSeconds 指定往后预测多久的数据。 + +### 基于预测的弹性 + +大多数在线应用的负载都有周期性的特征。我们可以根据按天或者按周的趋势预测未来的负载。EHPA 使用 DSP 算法来预测应用未来的时间序列数据。 + +以下是一个开启了预测能力的 EHPA 模版例子: +```yaml +apiVersion: autoscaling.crane.io/v1alpha1 +kind: EffectiveHorizontalPodAutoscaler +spec: + prediction: + predictionWindowSeconds: 3600 + predictionAlgorithm: + algorithmType: dsp + dsp: + sampleInterval: "60s" + historyLength: "3d" + +``` + +#### 监控数据兜底 + +在使用预测算法预测时,你可能会担心预测数据不准带来一定的风险,EHPA 在计算副本数时,不仅会按预测数据计算,同时也会考虑实际监控数据来兜底,提升了弹性的安全性。 +实现的原理是当你在 EHPA 中定义 `spec.metrics` 并且开启弹性预测时,EffectiveHPAController 会在创建底层管理的 HPA 时按策略自动生成多条 Metric Spec。 + +例如,当用户在 EHPA 的 yaml 里定义如下 Metric Spec: +```yaml +apiVersion: autoscaling.crane.io/v1alpha1 +kind: EffectiveHorizontalPodAutoscaler +spec: + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 50 +``` + +它会自动转换成两条 HPA 的阈值配置: +```yaml +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +spec: + metrics: + - pods: + metricName: pod_cpu_usage + selector: + matchLabels: + autoscaling.crane.io/effective-hpa-uid: f9b92249-eab9-4671-afe0-17925e5987b8 + targetAverageValue: 100m + type: Pods + - resource: + name: cpu + targetAverageUtilization: 50 + type: Resource +``` + +在上面这个例子中,用户在 EHPA 创建的 Metric 阈值配置会自动转换成底层 HPA 上的两条 Metric 阈值配置:预测 Metric 阈值和实际监控 Metric 阈值 + +* **预测 Metric 阈值** 是一个 custom metric。值通过 Crane 的 MetricAdapter 提供。 +* **实际监控 Metric 阈值**是一个 resource metric,它和用户在 EHPA 上定义的一样。这样 HPA 会根据应用实际监控的 Metric 计算副本数。 + +HPA 在配置了多个弹性 Metric 阈值时,在计算副本数时会分别计算每条 Metric 对应的副本数,并选择**最大**的那个副本数作为最终的推荐弹性结果。 + +#### 水平弹性的执行流程 + +1. EffectiveHPAController 创建 HorizontalPodAutoscaler 和 TimeSeriesPrediction 对象 +2. PredictionCore 从 prometheus 获取历史 metric 通过预测算法计算,将结果记录到 TimeSeriesPrediction +3. HPAController 通过 metric client 从 KubeApiServer 读取 metric 数据 +4. KubeApiServer 将请求路由到 Crane 的 MetricAdapter。 +5. HPAController 计算所有的 Metric 返回的结果得到最终的弹性副本推荐。 +6. HPAController 调用 scale API 对目标应用扩/缩容。 + +整体流程图如下: +![crane-ehpa](../images/crane-ehpa.png) + +#### 用户案例 +我们通过一个生产环境的客户案例来介绍 EHPA 的落地效果。 + +我们将生产上的数据在预发环境重放,对比使用 EHPA 和社区的 HPA 的弹性效果。 + +下图的红线是应用在一天内的实际 CPU 使用量曲线,我们可以看到在8点,12点,晚上8点时是使用高峰。绿线是 EHPA 预测的 CPU 使用量。 +![craen-ehpa-metrics-chart](../images/crane-ehpa-metrics-chart.png) + +下图是对应的自动弹性的副本数曲线,红线是社区 HPA 的副本数曲线,绿线是 EHPA 的副本数曲线。 +![crane-ehpa-metrics-replicas-chart](../images/crane-ehpa-replicas-chart.png) + +可以看到 EHPA 具有以下优势: + +* 在流量洪峰来临前扩容。 +* 当流量先降后立刻升时不做无效缩容。 +* 相比 HPA 更少的弹性次数却更高效。 + +### ScaleStrategy 弹性策略 +EHPA 提供了两种弹性策略:`Auto` 和 `Preview`。用户可以随时切换它并立即生效。 + +#### Auto +Auto 策略下 EHPA 会自动执行弹性行为。默认 EHPA 的策略是 Auto。在这个模式下 EHPA 会创建一个社区的 HPA 对象并自动接管它的生命周期。我们不建议用户修改或者控制这个底层的 HPA 对象,当 EHPA 被删除时,底层的 HPA 对象也会一并删除。 + +#### Preview +Preview 策略提供了一种让 EHPA 不自动执行弹性的能力。所以你可以通过 EHPA 的 desiredReplicas 字段观测 EHPA 计算出的副本数。用户可以随时在两个模式间切换,当用户切换到 Preview 模式时,用户可以通过 `spec.specificReplicas` 调整应用的副本数,如果 `spec.specificReplicas` 为空,则不会对应用执行弹性,但是依然会执行副本数的计算。 + +以下是一个配置成 Preview 模式的 EHPA 模版例子: +```yaml +apiVersion: autoscaling.crane.io/v1alpha1 +kind: EffectiveHorizontalPodAutoscaler +spec: + scaleStrategy: Preview # ScaleStrategy indicate the strategy to scaling target, value can be "Auto" and "Preview". + specificReplicas: 5 # SpecificReplicas specify the target replicas. +status: + expectReplicas: 4 # expectReplicas is the calculated replicas that based on prediction metrics or spec.specificReplicas. + currentReplicas: 4 # currentReplicas is actual replicas from target +``` + +### HorizontalPodAutoscaler 社区兼容 +EHPA 从设计之出就希望和社区的 HPA 兼容,因为我们不希望重新造一个类似 HPA 的轮子,HPA 在不断演进的过程已经解决了很多通用的问题,EHPA 希望在 HPA 的基础上提供更高阶的 CRD,EHPA 的功能是社区 HPA 的超集。 + +EHPA 也会持续跟进支持 HPA 的新功能。 + +### EffectiveHorizontalPodAutoscaler status +EHPA 的 Status 包括了自身的 Status 同时也汇聚了底层 HPA 的部分 Status。 + +以下是一个 EHPA 的 Status yaml例子: +```yaml +apiVersion: autoscaling.crane.io/v1alpha1 +kind: EffectiveHorizontalPodAutoscaler +status: + conditions: + - lastTransitionTime: "2021-11-30T08:18:59Z" + message: the HPA controller was able to get the target's current scale + reason: SucceededGetScale + status: "True" + type: AbleToScale + - lastTransitionTime: "2021-11-30T08:18:59Z" + message: Effective HPA is ready + reason: EffectiveHorizontalPodAutoscalerReady + status: "True" + type: Ready + currentReplicas: 1 + expectReplicas: 0 + +``` From 3dc83d6a72beebb0c05975bf6e8dd149a7ad4ac0 Mon Sep 17 00:00:00 2001 From: lbbniu Date: Fri, 15 Apr 2022 11:18:14 +0800 Subject: [PATCH 21/41] Fix ehpa document yaml field --- ...fective-hpa-to-scaling-with-effectiveness.md | 17 +++++++++++------ ...tive-hpa-to-scaling-with-effectiveness.zh.md | 17 +++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md index b6b827f05..a429b4373 100644 --- a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md +++ b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.md @@ -92,15 +92,20 @@ kind: HorizontalPodAutoscaler spec: metrics: - pods: - metricName: pod_cpu_usage - selector: - matchLabels: - autoscaling.crane.io/effective-hpa-uid: f9b92249-eab9-4671-afe0-17925e5987b8 - targetAverageValue: 100m + metric: + name: crane_pod_cpu_usage + selector: + matchLabels: + autoscaling.crane.io/effective-hpa-uid: f9b92249-eab9-4671-afe0-17925e5987b8 + target: + type: AverageValue + averageValue: 100m type: Pods - resource: name: cpu - targetAverageUtilization: 50 + target: + type: Utilization + averageUtilization: 50 type: Resource ``` diff --git a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.zh.md b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.zh.md index 28cf1d45a..0995937fd 100644 --- a/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.zh.md +++ b/docs/tutorials/using-effective-hpa-to-scaling-with-effectiveness.zh.md @@ -93,15 +93,20 @@ kind: HorizontalPodAutoscaler spec: metrics: - pods: - metricName: pod_cpu_usage - selector: - matchLabels: - autoscaling.crane.io/effective-hpa-uid: f9b92249-eab9-4671-afe0-17925e5987b8 - targetAverageValue: 100m + metric: + name: crane_pod_cpu_usage + selector: + matchLabels: + autoscaling.crane.io/effective-hpa-uid: f9b92249-eab9-4671-afe0-17925e5987b8 + target: + type: AverageValue + averageValue: 100m type: Pods - resource: name: cpu - targetAverageUtilization: 50 + target: + type: Utilization + averageUtilization: 50 type: Resource ``` From 6cbda7c7dbe9b9277e0998fe1f9bf325709bf1f3 Mon Sep 17 00:00:00 2001 From: qmhu Date: Fri, 15 Apr 2022 11:42:50 +0800 Subject: [PATCH 22/41] fix typo --- cmd/craned/app/manager.go | 2 +- pkg/controller/ehpa/hpa_event_handler.go | 4 +++- pkg/controller/ehpa/hpa_observer_controller.go | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmd/craned/app/manager.go b/cmd/craned/app/manager.go index fe3ea1af6..109498970 100644 --- a/cmd/craned/app/manager.go +++ b/cmd/craned/app/manager.go @@ -246,7 +246,7 @@ func initializationControllers(ctx context.Context, mgr ctrl.Manager, opts *opti Client: mgr.GetClient(), Scheme: mgr.GetScheme(), RestMapper: mgr.GetRESTMapper(), - Recorder: mgr.GetEventRecorderFor("hpareplicas-controller"), + Recorder: mgr.GetEventRecorderFor("hpa-observer-controller"), }).SetupWithManager(mgr); err != nil { klog.Exit(err, "unable to create controller", "controller", "HPAObserverController") } diff --git a/pkg/controller/ehpa/hpa_event_handler.go b/pkg/controller/ehpa/hpa_event_handler.go index dd9d8fcf0..51c9ec58a 100644 --- a/pkg/controller/ehpa/hpa_event_handler.go +++ b/pkg/controller/ehpa/hpa_event_handler.go @@ -6,6 +6,7 @@ import ( autoscalingv2 "k8s.io/api/autoscaling/v2beta2" "k8s.io/client-go/util/workqueue" + "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" @@ -33,6 +34,7 @@ func (h *hpaEventHandler) Delete(evt event.DeleteEvent, q workqueue.RateLimiting func (h *hpaEventHandler) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) { newHpa := evt.ObjectNew.(*autoscalingv2.HorizontalPodAutoscaler) oldHpa := evt.ObjectOld.(*autoscalingv2.HorizontalPodAutoscaler) + klog.V(6).Infof("hpa %s OnUpdate", klog.KObj(newHpa)) if oldHpa.Status.DesiredReplicas != newHpa.Status.DesiredReplicas { for _, cond := range newHpa.Status.Conditions { if cond.Reason == "SucceededRescale" || cond.Reason == "SucceededOverloadRescale" { @@ -51,7 +53,7 @@ func (h *hpaEventHandler) Update(evt event.UpdateEvent, q workqueue.RateLimiting "type": scaleType, "direction": direction, } - metrics.HPAScaleCount.With(labels).Add(1) + metrics.HPAScaleCount.With(labels).Inc() break } diff --git a/pkg/controller/ehpa/hpa_observer_controller.go b/pkg/controller/ehpa/hpa_observer_controller.go index 8e03b355a..08918b8a3 100644 --- a/pkg/controller/ehpa/hpa_observer_controller.go +++ b/pkg/controller/ehpa/hpa_observer_controller.go @@ -43,7 +43,7 @@ func (c *HPAObserverController) Reconcile(ctx context.Context, req ctrl.Request) func (c *HPAObserverController) SetupWithManager(mgr ctrl.Manager) error { // Create a new controller - controller, err := controller.New("broadcastjob-controller", mgr, controller.Options{ + controller, err := controller.New("hpa-observer-controller", mgr, controller.Options{ Reconciler: c}) if err != nil { return err From ad013844a4dd06b8732cb45ca4a0d9e22ebd3e44 Mon Sep 17 00:00:00 2001 From: kitianFresh <1549722424@qq.com> Date: Fri, 15 Apr 2022 12:25:51 +0800 Subject: [PATCH 23/41] init query builder providers in main --- cmd/craned/app/manager.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/craned/app/manager.go b/cmd/craned/app/manager.go index fe3ea1af6..67c269ff2 100644 --- a/cmd/craned/app/manager.go +++ b/cmd/craned/app/manager.go @@ -39,6 +39,8 @@ import ( "github.com/gocrane/crane/pkg/providers/metricserver" "github.com/gocrane/crane/pkg/providers/mock" "github.com/gocrane/crane/pkg/providers/prom" + _ "github.com/gocrane/crane/pkg/querybuilder-providers/metricserver" + _ "github.com/gocrane/crane/pkg/querybuilder-providers/prometheus" "github.com/gocrane/crane/pkg/recommend" "github.com/gocrane/crane/pkg/server" serverconfig "github.com/gocrane/crane/pkg/server/config" From 50f33313dfb7036ccbfec9020e29b122043213b1 Mon Sep 17 00:00:00 2001 From: qmhu Date: Fri, 15 Apr 2022 13:19:08 +0800 Subject: [PATCH 24/41] hpa scale metric config --- deploy/craned/service.yaml | 4 ++++ pkg/metrics/autoscaling.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/deploy/craned/service.yaml b/deploy/craned/service.yaml index cd26b1a73..85f7ecadf 100644 --- a/deploy/craned/service.yaml +++ b/deploy/craned/service.yaml @@ -18,5 +18,9 @@ spec: protocol: TCP targetPort: 9090 name: dashboard-service + - name: metrics-http + port: 8080 + protocol: TCP + targetPort: 8080 selector: app: craned diff --git a/pkg/metrics/autoscaling.go b/pkg/metrics/autoscaling.go index 288156ae0..c9e5e5d5b 100644 --- a/pkg/metrics/autoscaling.go +++ b/pkg/metrics/autoscaling.go @@ -93,7 +93,7 @@ var ( func init() { // Register custom metrics with the global prometheus registry - metrics.Registry.MustRegister(HPAReplicas, EHPAReplicas, OOMCount, EVPACpuScaleUpMilliCores, EVPACpuScaleDownMilliCores, EVPAMemoryScaleDownMB, EVPAMemoryScaleUpMB) + metrics.Registry.MustRegister(HPAReplicas, EHPAReplicas, OOMCount, HPAScaleCount, EVPACpuScaleUpMilliCores, EVPACpuScaleDownMilliCores, EVPAMemoryScaleDownMB, EVPAMemoryScaleUpMB) } From df21260daeee989d43fff418e82b9e12ae5835b6 Mon Sep 17 00:00:00 2001 From: kitianFresh <1549722424@qq.com> Date: Fri, 15 Apr 2022 16:22:52 +0800 Subject: [PATCH 25/41] use workload name not the pod name to query the containers of workload --- pkg/controller/ehpa/effective_hpa_controller.go | 2 +- pkg/metricquery/type.go | 5 +++++ pkg/querybuilder-providers/prometheus/builder.go | 4 ++-- pkg/querybuilder-providers/prometheus/builder_test.go | 8 ++++---- pkg/recommend/advisor/resource_request.go | 8 ++++---- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/pkg/controller/ehpa/effective_hpa_controller.go b/pkg/controller/ehpa/effective_hpa_controller.go index 0552ab0ad..d73393828 100644 --- a/pkg/controller/ehpa/effective_hpa_controller.go +++ b/pkg/controller/ehpa/effective_hpa_controller.go @@ -185,7 +185,7 @@ func RecordMetrics(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) { if ehpa.Status.ExpectReplicas != nil { labels := map[string]string{ "resourceName": klog.KObj(ehpa).String(), - "strategy": string(ehpa.Spec.ScaleStrategy), + "strategy": string(ehpa.Spec.ScaleStrategy), } metrics.EHPAReplicas.With(labels).Set(float64(*ehpa.Status.ExpectReplicas)) } diff --git a/pkg/metricquery/type.go b/pkg/metricquery/type.go index 747eba17d..acbbae3c6 100644 --- a/pkg/metricquery/type.go +++ b/pkg/metricquery/type.go @@ -59,6 +59,9 @@ type WorkloadNamerInfo struct { type ContainerNamerInfo struct { Namespace string + WorkloadName string + Kind string + APIVersion string PodName string ContainerName string Selector labels.Selector @@ -162,10 +165,12 @@ func (m *Metric) keyByContainer() string { string(m.Type), strings.ToLower(m.MetricName), m.Container.Namespace, + m.Container.WorkloadName, m.Container.PodName, m.Container.ContainerName, selectorStr}, "-") } + func (m *Metric) keyByPod() string { selectorStr := "" if m.Pod.Selector != nil { diff --git a/pkg/querybuilder-providers/prometheus/builder.go b/pkg/querybuilder-providers/prometheus/builder.go index 67c371beb..5e35b773b 100644 --- a/pkg/querybuilder-providers/prometheus/builder.go +++ b/pkg/querybuilder-providers/prometheus/builder.go @@ -92,11 +92,11 @@ func (b *builder) containerQuery(metric *metricquery.Metric) (*metricquery.Query switch strings.ToLower(metric.MetricName) { case v1.ResourceCPU.String(): return promQuery(&metricquery.PrometheusQuery{ - Query: fmt.Sprintf(ContainerCpuUsageExprTemplate, metric.Container.Namespace, metric.Container.PodName, metric.Container.ContainerName, "3m"), + Query: fmt.Sprintf(ContainerCpuUsageExprTemplate, metric.Container.Namespace, metric.Container.WorkloadName, metric.Container.ContainerName, "3m"), }), nil case v1.ResourceMemory.String(): return promQuery(&metricquery.PrometheusQuery{ - Query: fmt.Sprintf(ContainerMemUsageExprTemplate, metric.Container.Namespace, metric.Container.PodName, metric.Container.ContainerName), + Query: fmt.Sprintf(ContainerMemUsageExprTemplate, metric.Container.Namespace, metric.Container.WorkloadName, metric.Container.ContainerName), }), nil default: return nil, fmt.Errorf("metric type %v do not support resource metric %v. only support %v now", metric.Type, metric.MetricName, supportedResources.List()) diff --git a/pkg/querybuilder-providers/prometheus/builder_test.go b/pkg/querybuilder-providers/prometheus/builder_test.go index 46f3e8939..8e159d9df 100644 --- a/pkg/querybuilder-providers/prometheus/builder_test.go +++ b/pkg/querybuilder-providers/prometheus/builder_test.go @@ -69,11 +69,11 @@ func TestBuildQuery(t *testing.T) { Type: metricquery.ContainerMetricType, Container: &metricquery.ContainerNamerInfo{ Namespace: "default", - PodName: "pod-xxx", + WorkloadName: "workload", ContainerName: "container", }, }, - want: fmt.Sprintf(ContainerCpuUsageExprTemplate, "default", "pod-xxx", "container", "3m"), + want: fmt.Sprintf(ContainerCpuUsageExprTemplate, "default", "workload", "container", "3m"), }, { desc: "tc4-container-mem", @@ -82,11 +82,11 @@ func TestBuildQuery(t *testing.T) { Type: metricquery.ContainerMetricType, Container: &metricquery.ContainerNamerInfo{ Namespace: "default", - PodName: "pod-xxx", + WorkloadName: "workload", ContainerName: "container", }, }, - want: fmt.Sprintf(ContainerMemUsageExprTemplate, "default", "pod-xxx", "container"), + want: fmt.Sprintf(ContainerMemUsageExprTemplate, "default", "workload", "container"), }, { desc: "tc5-node-cpu", diff --git a/pkg/recommend/advisor/resource_request.go b/pkg/recommend/advisor/resource_request.go index 4beab5a45..834eb6ae0 100644 --- a/pkg/recommend/advisor/resource_request.go +++ b/pkg/recommend/advisor/resource_request.go @@ -107,7 +107,7 @@ func (a *ResourceRequestAdvisor) Advise(proposed *types.ProposedRecommendation) Target: map[corev1.ResourceName]string{}, } - mericNamer := ResourceToContainerMetricNamer(namespace, pod.Name, c.Name, corev1.ResourceCPU) + mericNamer := ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceCPU) klog.V(6).Infof("CPU query for resource request recommendation: %s", mericNamer.BuildUniqueKey()) cpuConfig := makeCpuConfig(a.ConfigProperties) tsList, err := utils.QueryPredictedValuesOnce(a.Recommendation, p, @@ -121,7 +121,7 @@ func (a *ResourceRequestAdvisor) Advise(proposed *types.ProposedRecommendation) v := int64(tsList[0].Samples[0].Value * 1000) cr.Target[corev1.ResourceCPU] = resource.NewMilliQuantity(v, resource.DecimalSI).String() - mericNamer = ResourceToContainerMetricNamer(namespace, pod.Name, c.Name, corev1.ResourceMemory) + mericNamer = ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceMemory) klog.V(6).Infof("Memory query for resource request recommendation: %s", mericNamer.BuildUniqueKey()) memConfig := makeMemConfig(a.ConfigProperties) tsList, err = utils.QueryPredictedValuesOnce(a.Recommendation, p, @@ -146,7 +146,7 @@ func (a *ResourceRequestAdvisor) Name() string { return "ResourceRequestAdvisor" } -func ResourceToContainerMetricNamer(namespace, podname, containername string, resourceName corev1.ResourceName) metricnaming.MetricNamer { +func ResourceToContainerMetricNamer(namespace, workloadname, containername string, resourceName corev1.ResourceName) metricnaming.MetricNamer { // container return &metricnaming.GeneralMetricNamer{ Metric: &metricquery.Metric{ @@ -154,7 +154,7 @@ func ResourceToContainerMetricNamer(namespace, podname, containername string, re MetricName: resourceName.String(), Container: &metricquery.ContainerNamerInfo{ Namespace: namespace, - PodName: podname, + WorkloadName: workloadname, ContainerName: containername, Selector: labels.Everything(), }, From 09796aaa2a58b7ac79098a306242db728a7ad15d Mon Sep 17 00:00:00 2001 From: lbbniu Date: Sun, 17 Apr 2022 12:19:41 +0800 Subject: [PATCH 26/41] Fix /grafana/api/live/ws 400 in nginx --- deploy/craned/deployment.yaml | 101 ++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/deploy/craned/deployment.yaml b/deploy/craned/deployment.yaml index 0999d3b3f..036141cd2 100644 --- a/deploy/craned/deployment.yaml +++ b/deploy/craned/deployment.yaml @@ -155,7 +155,12 @@ data: text/xml text/x-component text/x-cross-domain-policy; - + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + upstream cluster { server craned.crane-system:8082; } @@ -164,7 +169,6 @@ data: server grafana.crane-system:8082; } - server { server_name _; large_client_header_buffers 4 32k; @@ -177,51 +181,52 @@ data: root /usr/share/nginx/html/; include /etc/nginx/mime.types; try_files $uri $uri/ /index.html; - - location /grafana { - proxy_connect_timeout 180; - proxy_send_timeout 180; - proxy_read_timeout 180; - proxy_pass http://grafana; - proxy_redirect off; - rewrite /grafana/(.*) /$1 break; - proxy_http_version 1.1; - proxy_set_header Connection ""; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - location /api/v1/cluster { - proxy_connect_timeout 180; - proxy_send_timeout 180; - proxy_read_timeout 180; - proxy_pass http://cluster; - proxy_redirect off; - proxy_http_version 1.1; - proxy_set_header Connection ""; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - location /api/v1/namespaces { - proxy_connect_timeout 180; - proxy_send_timeout 180; - proxy_read_timeout 180; - proxy_pass http://cluster; - proxy_redirect off; - proxy_http_version 1.1; - proxy_set_header Connection ""; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - location /api { - proxy_connect_timeout 180; - proxy_send_timeout 180; - proxy_read_timeout 180; - proxy_pass http://cluster; - proxy_redirect off; - proxy_http_version 1.1; - proxy_set_header Connection ""; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } + } + location /grafana { + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_pass http://grafana; + proxy_redirect off; + rewrite /grafana/(.*) /$1 break; + proxy_http_version 1.1; + proxy_set_header Host $http_host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + location /api/v1/cluster { + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_pass http://cluster; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + location /api/v1/namespaces { + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_pass http://cluster; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + location /api { + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_pass http://cluster; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } From a0915bb46747d1c45af755a468fada70b98ab783 Mon Sep 17 00:00:00 2001 From: kitianFresh <1549722424@qq.com> Date: Sat, 9 Apr 2022 18:38:50 +0800 Subject: [PATCH 27/41] refine cron metrics priority for ehpa when working with other hpa metrics together, remove the cron impact when it is not active --- .../ehpa/effective_hpa_controller.go | 2 +- pkg/controller/ehpa/hpa.go | 4 +-- pkg/controller/ehpa/predict.go | 8 ----- .../external_metric_provider.go | 32 +++++++++++++++++-- pkg/utils/ehpa.go | 11 +++++++ 5 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 pkg/utils/ehpa.go diff --git a/pkg/controller/ehpa/effective_hpa_controller.go b/pkg/controller/ehpa/effective_hpa_controller.go index d73393828..a487e392c 100644 --- a/pkg/controller/ehpa/effective_hpa_controller.go +++ b/pkg/controller/ehpa/effective_hpa_controller.go @@ -76,7 +76,7 @@ func (c *EffectiveHPAController) Reconcile(ctx context.Context, req ctrl.Request } // reconcile prediction if enabled - if IsPredictionEnabled(ehpa) { + if utils.IsEHPAPredictionEnabled(ehpa) { prediction, err := c.ReconcilePredication(ctx, ehpa) if err != nil { setCondition(newStatus, autoscalingapi.Ready, metav1.ConditionFalse, "FailedReconcilePrediction", err.Error()) diff --git a/pkg/controller/ehpa/hpa.go b/pkg/controller/ehpa/hpa.go index a375bc2c1..c597074d1 100644 --- a/pkg/controller/ehpa/hpa.go +++ b/pkg/controller/ehpa/hpa.go @@ -180,7 +180,7 @@ func (c *EffectiveHPAController) GetHPAMetrics(ctx context.Context, ehpa *autosc metrics = append(metrics, *copyMetric) } - if IsPredictionEnabled(ehpa) { + if utils.IsEHPAPredictionEnabled(ehpa) { var customMetricsForPrediction []autoscalingv2.MetricSpec for _, metric := range metrics { @@ -243,7 +243,7 @@ func (c *EffectiveHPAController) GetHPAMetrics(ctx context.Context, ehpa *autosc } // Construct cron external metrics for cron scale - if IsCronEnabled(ehpa) { + if utils.IsEHPACronEnabled(ehpa) { metrics = append(metrics, GetCronMetricSpecsForHPA(ehpa)...) } diff --git a/pkg/controller/ehpa/predict.go b/pkg/controller/ehpa/predict.go index b88a95f4e..cb4d3fc69 100644 --- a/pkg/controller/ehpa/predict.go +++ b/pkg/controller/ehpa/predict.go @@ -154,14 +154,6 @@ func (c *EffectiveHPAController) NewPredictionObject(ehpa *autoscalingapi.Effect return prediction, nil } -func IsPredictionEnabled(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) bool { - return ehpa.Spec.Prediction != nil && ehpa.Spec.Prediction.PredictionWindowSeconds != nil && ehpa.Spec.Prediction.PredictionAlgorithm != nil -} - -func IsCronEnabled(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) bool { - return len(ehpa.Spec.Crons) > 0 -} - func setPredictionCondition(status *autoscalingapi.EffectiveHorizontalPodAutoscalerStatus, conditions []metav1.Condition) { for _, cond := range conditions { if cond.Type == string(predictionapi.TimeSeriesPredictionConditionReady) { diff --git a/pkg/metricprovider/external_metric_provider.go b/pkg/metricprovider/external_metric_provider.go index fbf70e2c8..22e6b4412 100644 --- a/pkg/metricprovider/external_metric_provider.go +++ b/pkg/metricprovider/external_metric_provider.go @@ -19,7 +19,9 @@ import ( autoscalingapi "github.com/gocrane/api/autoscaling/v1alpha1" + "github.com/gocrane/crane/pkg/known" "github.com/gocrane/crane/pkg/utils" + autoscalingv2 "k8s.io/api/autoscaling/v2beta2" ) var _ provider.ExternalMetricsProvider = &ExternalMetricProvider{} @@ -73,14 +75,40 @@ func (p *ExternalMetricProvider) GetExternalMetric(ctx context.Context, namespac return nil, fmt.Errorf("%v", errs) } replicas := DefaultCronTargetMetricValue - // No active cron now, then return current workload replicas to keep the original replicas if len(activeScalers) == 0 { + // No active cron now, there are two cases: + // 1. no other hpa metrics work with cron together, then return current workload replicas to keep the original desired replicas + // 2. other hpa metrics work with cron together, then return min value to remove the cron impact for other metrics. + // when cron is working with other metrics together, it should not return workload's original desired replicas, + // because there maybe other metrics want to trigger the workload to scale in. + // hpa controller select max replicas computed by all metrics(this is hpa default policy in hard code), cron will impact the hpa. + // so we should remove the cron effect when cron is not active, it should return min value. scale, _, err := utils.GetScale(ctx, p.restMapper, p.scaler, namespace, ehpa.Spec.ScaleTargetRef) if err != nil { klog.Errorf("Failed to get scale: %v", err) return nil, err } - replicas = scale.Status.Replicas + // no other hpa metrics work with cron together, keep the workload desired replicas + replicas = scale.Spec.Replicas + + if !utils.IsEHPAPredictionEnabled(&ehpa) { + hpaList := &autoscalingv2.HorizontalPodAutoscalerList{} + opts := []client.ListOption{ + client.MatchingLabels(map[string]string{known.EffectiveHorizontalPodAutoscalerUidLabel: string(ehpa.UID)}), + } + err := p.client.List(ctx, hpaList, opts...) + if err != nil { + return nil, err + } + // other hpa metrics work with cron together + // excludes the cron metric itself + if len(hpaList.Items) >= 0 && len(hpaList.Items[0].Spec.Metrics) > 1 { + replicas = DefaultCronTargetMetricValue + } + } else { + // other hpa metrics work with cron together + replicas = DefaultCronTargetMetricValue + } } else { // Has active ones. Basically, there should not be more then one active cron at the same time period, it is not a best practice. // we use the largest targetReplicas specified in cron spec. diff --git a/pkg/utils/ehpa.go b/pkg/utils/ehpa.go new file mode 100644 index 000000000..486106312 --- /dev/null +++ b/pkg/utils/ehpa.go @@ -0,0 +1,11 @@ +package utils + +import autoscalingapi "github.com/gocrane/api/autoscaling/v1alpha1" + +func IsEHPAPredictionEnabled(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) bool { + return ehpa.Spec.Prediction != nil && ehpa.Spec.Prediction.PredictionWindowSeconds != nil && ehpa.Spec.Prediction.PredictionAlgorithm != nil +} + +func IsEHPACronEnabled(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) bool { + return len(ehpa.Spec.Crons) > 0 +} From 495762f16b8473abfcdba4599956b43e60f8a9b1 Mon Sep 17 00:00:00 2001 From: lbbniu Date: Wed, 20 Apr 2022 11:00:59 +0800 Subject: [PATCH 28/41] Optimize docs preview github action trigger rule --- .github/workflows/preview.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 816e096ab..dce97ba6e 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -4,6 +4,9 @@ on: pull_request_target: # when using teardown: 'true', add default event types + closed event type types: [opened, synchronize, reopened, closed] + paths: + - 'docs/**' + - '*.md' jobs: preview: From ed8543cb58ae28c96d3f48b8642b3cbc0bdf2a09 Mon Sep 17 00:00:00 2001 From: qmhu Date: Thu, 14 Apr 2022 20:11:18 +0800 Subject: [PATCH 29/41] percentile estimator --- cmd/craned/app/manager.go | 1 + pkg/autoscaling/estimator/estimator.go | 14 +- pkg/autoscaling/estimator/percentile.go | 182 ++++++++++++++++++ pkg/controller/evpa/config.go | 8 +- pkg/controller/evpa/container_policy.go | 94 +++++---- .../evpa/effective_vpa_controller.go | 60 ++++-- pkg/known/finalizer.go | 5 + pkg/recommend/advisor/resource_request.go | 17 +- pkg/utils/prediction.go | 9 + pkg/utils/slice.go | 20 ++ pkg/utils/string.go | 9 - 11 files changed, 343 insertions(+), 76 deletions(-) create mode 100644 pkg/autoscaling/estimator/percentile.go create mode 100644 pkg/known/finalizer.go create mode 100644 pkg/utils/slice.go diff --git a/cmd/craned/app/manager.go b/cmd/craned/app/manager.go index ec8472abf..f8ba3c739 100644 --- a/cmd/craned/app/manager.go +++ b/cmd/craned/app/manager.go @@ -258,6 +258,7 @@ func initializationControllers(ctx context.Context, mgr ctrl.Manager, opts *opti Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor("effective-vpa-controller"), OOMRecorder: podOOMRecorder, + Predictor: predictorMgr.GetPredictor(predictionapi.AlgorithmTypePercentile), }).SetupWithManager(mgr); err != nil { klog.Exit(err, "unable to create controller", "controller", "EffectiveVPAController") } diff --git a/pkg/autoscaling/estimator/estimator.go b/pkg/autoscaling/estimator/estimator.go index 50be773a3..6ae8308d0 100644 --- a/pkg/autoscaling/estimator/estimator.go +++ b/pkg/autoscaling/estimator/estimator.go @@ -10,6 +10,7 @@ import ( autoscalingapi "github.com/gocrane/api/autoscaling/v1alpha1" "github.com/gocrane/crane/pkg/oom" + "github.com/gocrane/crane/pkg/prediction" ) // ResourceEstimatorManager controls how to get or delete estimators for EffectiveVPA @@ -29,19 +30,20 @@ type estimatorManager struct { estimatorMap map[string]ResourceEstimator } -func NewResourceEstimatorManager(client client.Client, oomRecorder oom.Recorder) ResourceEstimatorManager { +func NewResourceEstimatorManager(client client.Client, oomRecorder oom.Recorder, predictor prediction.Interface) ResourceEstimatorManager { resourceEstimatorManager := &estimatorManager{ estimatorMap: make(map[string]ResourceEstimator), } - resourceEstimatorManager.buildEstimators(client, oomRecorder) + resourceEstimatorManager.buildEstimators(client, oomRecorder, predictor) return resourceEstimatorManager } -func (m *estimatorManager) buildEstimators(client client.Client, oomRecorder oom.Recorder) { - proportionalEstimator := &ProportionalResourceEstimator{ - Client: client, +func (m *estimatorManager) buildEstimators(client client.Client, oomRecorder oom.Recorder, predictor prediction.Interface) { + percentileEstimator := &PercentileResourceEstimator{ + Predictor: predictor, + Client: client, } - m.registerEstimator("Proportional", proportionalEstimator) + m.registerEstimator("Percentile", percentileEstimator) oomEstimator := &OOMResourceEstimator{ OOMRecorder: oomRecorder, } diff --git a/pkg/autoscaling/estimator/percentile.go b/pkg/autoscaling/estimator/percentile.go new file mode 100644 index 000000000..cd202599b --- /dev/null +++ b/pkg/autoscaling/estimator/percentile.go @@ -0,0 +1,182 @@ +package estimator + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client" + + autoscalingapi "github.com/gocrane/api/autoscaling/v1alpha1" + predictionapi "github.com/gocrane/api/prediction/v1alpha1" + + "github.com/gocrane/crane/pkg/metricnaming" + "github.com/gocrane/crane/pkg/metricquery" + "github.com/gocrane/crane/pkg/prediction" + predictionconfig "github.com/gocrane/crane/pkg/prediction/config" + "github.com/gocrane/crane/pkg/utils" +) + +const callerFormat = "EVPACaller-%s-%s-%s" + +type PercentileResourceEstimator struct { + Predictor prediction.Interface + Client client.Client +} + +func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, config map[string]string, containerName string, currRes *corev1.ResourceRequirements) (corev1.ResourceList, error) { + recommendResource := corev1.ResourceList{} + + cpuMetricNamer := &metricnaming.GeneralMetricNamer{ + Metric: &metricquery.Metric{ + Type: metricquery.ContainerMetricType, + MetricName: corev1.ResourceCPU.String(), + Container: &metricquery.ContainerNamerInfo{ + Namespace: evpa.Namespace, + WorkloadName: evpa.Spec.TargetRef.Name, + ContainerName: containerName, + Selector: labels.Everything(), + }, + }, + } + + cpuConfig := getCpuConfig(config) + tsList, err := utils.QueryPredictedValues(e.Predictor, fmt.Sprintf(callerFormat, string(evpa.UID), containerName, corev1.ResourceCPU), cpuConfig, cpuMetricNamer) + if err != nil { + return nil, err + } + + if len(tsList) < 1 || len(tsList[0].Samples) < 1 { + return nil, fmt.Errorf("no value retured for queryExpr: %s", cpuMetricNamer.BuildUniqueKey()) + } + + cpuValue := int64(tsList[0].Samples[0].Value * 1000) + recommendResource[corev1.ResourceCPU] = *resource.NewMilliQuantity(cpuValue, resource.DecimalSI) + + memoryMetricNamer := &metricnaming.GeneralMetricNamer{ + Metric: &metricquery.Metric{ + Type: metricquery.ContainerMetricType, + MetricName: corev1.ResourceMemory.String(), + Container: &metricquery.ContainerNamerInfo{ + Namespace: evpa.Namespace, + WorkloadName: evpa.Spec.TargetRef.Name, + ContainerName: containerName, + Selector: labels.Everything(), + }, + }, + } + + memConfig := getMemConfig(config) + tsList, err = utils.QueryPredictedValues(e.Predictor, fmt.Sprintf(callerFormat, string(evpa.UID), containerName, corev1.ResourceMemory), memConfig, memoryMetricNamer) + if err != nil { + return nil, err + } + + if len(tsList) < 1 || len(tsList[0].Samples) < 1 { + return nil, fmt.Errorf("no value retured for queryExpr: %s", memoryMetricNamer.BuildUniqueKey()) + } + + memValue := int64(tsList[0].Samples[0].Value) + recommendResource[corev1.ResourceMemory] = *resource.NewQuantity(memValue, resource.BinarySI) + + return recommendResource, nil +} + +func (e *PercentileResourceEstimator) DeleteEstimation(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler) { + for _, containerPolicy := range evpa.Spec.ResourcePolicy.ContainerPolicies { + cpuMetricNamer := &metricnaming.GeneralMetricNamer{ + Metric: &metricquery.Metric{ + Type: metricquery.ContainerMetricType, + MetricName: corev1.ResourceCPU.String(), + Container: &metricquery.ContainerNamerInfo{ + Namespace: evpa.Namespace, + WorkloadName: evpa.Spec.TargetRef.Name, + ContainerName: containerPolicy.ContainerName, + Selector: labels.Everything(), + }, + }, + } + err := e.Predictor.DeleteQuery(cpuMetricNamer, fmt.Sprintf(callerFormat, string(evpa.UID), containerPolicy.ContainerName, corev1.ResourceCPU)) + if err != nil { + klog.ErrorS(err, "Failed to delete query.", "queryExpr", cpuMetricNamer.BuildUniqueKey()) + } + + memoryMetricNamer := &metricnaming.GeneralMetricNamer{ + Metric: &metricquery.Metric{ + Type: metricquery.ContainerMetricType, + MetricName: corev1.ResourceMemory.String(), + Container: &metricquery.ContainerNamerInfo{ + Namespace: evpa.Namespace, + WorkloadName: evpa.Spec.TargetRef.Name, + ContainerName: containerPolicy.ContainerName, + Selector: labels.Everything(), + }, + }, + } + err = e.Predictor.DeleteQuery(memoryMetricNamer, fmt.Sprintf(callerFormat, string(evpa.UID), containerPolicy.ContainerName, corev1.ResourceMemory)) + if err != nil { + klog.ErrorS(err, "Failed to delete query.", "queryExpr", memoryMetricNamer.BuildUniqueKey()) + } + } + return +} + +func getCpuConfig(config map[string]string) *predictionconfig.Config { + sampleInterval, exists := config["cpu-sample-interval"] + if !exists { + sampleInterval = "1m" + } + percentile, exists := config["cpu-request-percentile"] + if !exists { + percentile = "0.99" + } + marginFraction, exists := config["cpu-request-margin-fraction"] + if !exists { + marginFraction = "0.15" + } + + return &predictionconfig.Config{ + Percentile: &predictionapi.Percentile{ + Aggregated: true, + SampleInterval: sampleInterval, + MarginFraction: marginFraction, + Percentile: percentile, + Histogram: predictionapi.HistogramConfig{ + HalfLife: "24h", + BucketSize: "0.1", + MaxValue: "100", + }, + }, + } +} + +func getMemConfig(props map[string]string) *predictionconfig.Config { + sampleInterval, exists := props["mem-sample-interval"] + if !exists { + sampleInterval = "1m" + } + percentile, exists := props["mem-request-percentile"] + if !exists { + percentile = "0.99" + } + marginFraction, exists := props["mem-request-margin-fraction"] + if !exists { + marginFraction = "0.15" + } + + return &predictionconfig.Config{ + Percentile: &predictionapi.Percentile{ + Aggregated: true, + SampleInterval: sampleInterval, + MarginFraction: marginFraction, + Percentile: percentile, + Histogram: predictionapi.HistogramConfig{ + HalfLife: "48h", + BucketSize: "104857600", + MaxValue: "104857600000", + }, + }, + } +} diff --git a/pkg/controller/evpa/config.go b/pkg/controller/evpa/config.go index b836f624b..275876128 100644 --- a/pkg/controller/evpa/config.go +++ b/pkg/controller/evpa/config.go @@ -40,6 +40,10 @@ const ( DefaultEVPARsyncPeriod = time.Second * 60 ) +const ( + EffectiveVPAConditionTypeReady = "Ready" +) + var ( DefaultControlledResources = []autoscalingapi.ResourceName{autoscalingapi.ResourceName("cpu"), autoscalingapi.ResourceName("memory")} @@ -48,10 +52,6 @@ var ( Type: "Percentile", Config: map[string]string{}, }, - { - Type: "Proportional", - Config: map[string]string{}, - }, { Type: "OOM", Config: map[string]string{}, diff --git a/pkg/controller/evpa/container_policy.go b/pkg/controller/evpa/container_policy.go index f7f20a019..b44388a3f 100644 --- a/pkg/controller/evpa/container_policy.go +++ b/pkg/controller/evpa/container_policy.go @@ -1,7 +1,6 @@ package evpa import ( - "context" "fmt" "math" "sort" @@ -25,8 +24,8 @@ const ( ScaleDown ScaleDirection = "ScaleDown" ) -func (c *EffectiveVPAController) ReconcileContainerPolicies(ctx context.Context, evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, podTemplate *corev1.PodTemplateSpec, resourceEstimators []estimator.ResourceEstimatorInstance) (currentEstimatorStatus []autoscalingapi.ResourceEstimatorStatus, recommendation *vpatypes.RecommendedPodResources, err error) { - recommendation = &vpatypes.RecommendedPodResources{} +func (c *EffectiveVPAController) ReconcileContainerPolicies(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, podTemplate *corev1.PodTemplateSpec, resourceEstimators []estimator.ResourceEstimatorInstance) (currentEstimatorStatus []autoscalingapi.ResourceEstimatorStatus, recommendation *vpatypes.RecommendedPodResources, err error) { + recommendation = evpa.Status.Recommendation rankedEstimators := RankEstimators(resourceEstimators) for _, containerPolicy := range evpa.Spec.ResourcePolicy.ContainerPolicies { @@ -45,7 +44,8 @@ func (c *EffectiveVPAController) ReconcileContainerPolicies(ctx context.Context, } // loop estimator and get final estimated resource for container - recommendResourceContainer := GetEstimatedResourceForContainer(evpa, containerPolicy, resourceRequirement, rankedEstimators, currentEstimatorStatus) + recommendResourceContainer, currentStatus := GetEstimatedResourceForContainer(evpa, containerPolicy, resourceRequirement, rankedEstimators, currentEstimatorStatus) + currentEstimatorStatus = currentStatus if IsResourceListEmpty(recommendResourceContainer) { klog.V(4).Infof("Container %s recommend resource is empty, skip scaling. ", containerPolicy.ContainerName) continue @@ -75,7 +75,10 @@ func (c *EffectiveVPAController) ReconcileContainerPolicies(ctx context.Context, return } -func UpdateCurrentEstimatorStatus(estimator estimator.ResourceEstimatorInstance, containerName string, resourceList corev1.ResourceList, currentEstimatorStatus []autoscalingapi.ResourceEstimatorStatus) { +func UpdateCurrentEstimatorStatus(estimator estimator.ResourceEstimatorInstance, containerName string, resourceList corev1.ResourceList, currentEstimatorStatus []autoscalingapi.ResourceEstimatorStatus) []autoscalingapi.ResourceEstimatorStatus { + var newStatus []autoscalingapi.ResourceEstimatorStatus + + found := false for _, currentStatus := range currentEstimatorStatus { if currentStatus.Type == estimator.GetSpec().Type { currentStatus.LastUpdateTime = metav1.Now() @@ -83,28 +86,31 @@ func UpdateCurrentEstimatorStatus(estimator estimator.ResourceEstimatorInstance, if containerRecommend.ContainerName == containerName { containerRecommend.Target = resourceList // todo: lowBound and UpperBound and uncappedTarget - return + found = true } } - return } + newStatus = append(newStatus, currentStatus) } - currentStatus := autoscalingapi.ResourceEstimatorStatus{ - Type: estimator.GetSpec().Type, - LastUpdateTime: metav1.Now(), - Recommendation: &vpatypes.RecommendedPodResources{ - ContainerRecommendations: []vpatypes.RecommendedContainerResources{ - { - ContainerName: containerName, - Target: resourceList, + if !found { + currentStatus := autoscalingapi.ResourceEstimatorStatus{ + Type: estimator.GetSpec().Type, + LastUpdateTime: metav1.Now(), + Recommendation: &vpatypes.RecommendedPodResources{ + ContainerRecommendations: []vpatypes.RecommendedContainerResources{ + { + ContainerName: containerName, + Target: resourceList, + }, }, }, - }, + } + newStatus = append(newStatus, currentStatus) // nolint:ineffassign } - currentEstimatorStatus = append(currentEstimatorStatus, currentStatus) // nolint:ineffassign + return newStatus } // CheckContainerScalingCondition check the conditions for container with scale direction @@ -157,10 +163,42 @@ func (c *EffectiveVPAController) CheckContainerScalingCondition(evpa *autoscalin return true, "" } +func (c *EffectiveVPAController) CleanLastScaleTime(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler) { + for _, containerPolicy := range evpa.Spec.ResourcePolicy.ContainerPolicies { + c.DeleteLastScaleTime(evpa.Namespace, evpa.Spec.TargetRef.Name, containerPolicy.ContainerName, string(ScaleUp)) + c.DeleteLastScaleTime(evpa.Namespace, evpa.Spec.TargetRef.Name, containerPolicy.ContainerName, string(ScaleDown)) + } +} + +func (c *EffectiveVPAController) GetLastScaleTime(namespace string, workload string, container string, direction string) metav1.Time { + c.mu.Lock() + defer c.mu.Unlock() + + return c.lastScaleTime[GetScaleEventKey(namespace, workload, container, direction)] +} + +func (c *EffectiveVPAController) DeleteLastScaleTime(namespace string, workload string, container string, direction string) { + c.mu.Lock() + defer c.mu.Unlock() + + delete(c.lastScaleTime, GetScaleEventKey(namespace, workload, container, direction)) +} + +// GetScaleEventKey concat information for scale event key +func GetScaleEventKey(namespace string, workload string, container string, direction string) string { + return namespace + "-" + workload + "-" + container + "-" + direction +} + // UpdateRecommendStatus update recommend resource func UpdateRecommendStatus(recommendation *vpatypes.RecommendedPodResources, containerName string, recommendResource corev1.ResourceList) { - currentTargetResource := GetContainerTargetResource(recommendation, containerName) - ResourceWithTolerance(recommendResource, currentTargetResource) + for i := range recommendation.ContainerRecommendations { + if recommendation.ContainerRecommendations[i].ContainerName == containerName { + ResourceWithTolerance(recommendResource, recommendation.ContainerRecommendations[i].Target) + recommendation.ContainerRecommendations[i].Target = recommendResource + + return + } + } containerRecommendation := vpatypes.RecommendedContainerResources{ ContainerName: containerName, @@ -172,22 +210,10 @@ func UpdateRecommendStatus(recommendation *vpatypes.RecommendedPodResources, con return } -// GetScaleEventKey concat information for scale event key -func GetScaleEventKey(namespace string, workload string, container string, direction string) string { - return namespace + "-" + workload + "-" + container + "-" + direction -} - -func (c *EffectiveVPAController) GetLastScaleTime(namespace string, workload string, container string, direction string) metav1.Time { - c.mu.Lock() - defer c.mu.Unlock() - - return c.lastScaleTime[GetScaleEventKey(namespace, workload, container, direction)] -} - // GetEstimatedResourceForContainer iterate resources based on the result from estimator // If priority is equal, use the larger resource value // If priority is larger, use the larger estimator's value if value is not Zero -func GetEstimatedResourceForContainer(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, containerPolicy autoscalingapi.ContainerResourcePolicy, containerResource *corev1.ResourceRequirements, rankedEstimators []ResourceEstimatorInstanceRanked, currentEstimatorStatus []autoscalingapi.ResourceEstimatorStatus) corev1.ResourceList { +func GetEstimatedResourceForContainer(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, containerPolicy autoscalingapi.ContainerResourcePolicy, containerResource *corev1.ResourceRequirements, rankedEstimators []ResourceEstimatorInstanceRanked, currentEstimatorStatus []autoscalingapi.ResourceEstimatorStatus) (corev1.ResourceList, []autoscalingapi.ResourceEstimatorStatus) { var resourcePrePriorityList []corev1.ResourceList for _, estimatorList := range rankedEstimators { resourcePrePriority := corev1.ResourceList{} @@ -204,7 +230,7 @@ func GetEstimatedResourceForContainer(evpa *autoscalingapi.EffectiveVerticalPodA } klog.V(4).Infof("Get recommended resource %v from estimator %s", resourcesEstimated, estimator.GetSpec().Type) - UpdateCurrentEstimatorStatus(estimator, containerPolicy.ContainerName, resourcesEstimated, currentEstimatorStatus) + currentEstimatorStatus = UpdateCurrentEstimatorStatus(estimator, containerPolicy.ContainerName, resourcesEstimated, currentEstimatorStatus) // Use larger resources if priority is the same CalculateResourceByValue(resourcePrePriority, resourcesEstimated) @@ -216,7 +242,7 @@ func GetEstimatedResourceForContainer(evpa *autoscalingapi.EffectiveVerticalPodA } // Use the highest priority value - return CalculateResourceByPriority(resourcePrePriorityList) + return CalculateResourceByPriority(resourcePrePriorityList), currentEstimatorStatus } func CalculateResourceByValue(resourceByValue corev1.ResourceList, resourcesEstimated corev1.ResourceList) { diff --git a/pkg/controller/evpa/effective_vpa_controller.go b/pkg/controller/evpa/effective_vpa_controller.go index 60f186e71..35fb709be 100644 --- a/pkg/controller/evpa/effective_vpa_controller.go +++ b/pkg/controller/evpa/effective_vpa_controller.go @@ -18,8 +18,10 @@ import ( autoscalingapi "github.com/gocrane/api/autoscaling/v1alpha1" "github.com/gocrane/crane/pkg/autoscaling/estimator" + "github.com/gocrane/crane/pkg/known" "github.com/gocrane/crane/pkg/metrics" "github.com/gocrane/crane/pkg/oom" + "github.com/gocrane/crane/pkg/prediction" "github.com/gocrane/crane/pkg/utils" ) @@ -31,6 +33,7 @@ type EffectiveVPAController struct { OOMRecorder oom.Recorder EstimatorManager estimator.ResourceEstimatorManager lastScaleTime map[string]metav1.Time + Predictor prediction.Interface mu sync.Mutex } @@ -47,41 +50,69 @@ func (c *EffectiveVPAController) Reconcile(ctx context.Context, req ctrl.Request err = defaultingEVPA(evpa) if err != nil { - c.Recorder.Event(evpa, v1.EventTypeNormal, "FailedValidation", err.Error()) + c.Recorder.Event(evpa, v1.EventTypeWarning, "FailedValidation", err.Error()) msg := fmt.Sprintf("Validation EffectiveVerticalPodAutoscaler failed, evpa %s error %v", klog.KObj(evpa), err) klog.Error(msg) - setCondition(newStatus, metav1.ConditionFalse, "FailedValidation", msg) + setCondition(newStatus, EffectiveVPAConditionTypeReady, metav1.ConditionFalse, "FailedValidation", msg) c.UpdateStatus(ctx, evpa, newStatus) return ctrl.Result{}, err } podTemplate, err := utils.GetPodTemplate(ctx, evpa.Namespace, evpa.Spec.TargetRef.Name, evpa.Spec.TargetRef.Kind, evpa.Spec.TargetRef.APIVersion, c.Client) if err != nil { - c.Recorder.Event(evpa, v1.EventTypeNormal, "FailedGetPodTemplate", err.Error()) + c.Recorder.Event(evpa, v1.EventTypeWarning, "FailedGetPodTemplate", err.Error()) klog.Errorf("Failed to get pod template, evpa %s", klog.KObj(evpa)) - setCondition(newStatus, metav1.ConditionFalse, "FailedGetPodTemplate", "Failed to get pod template") + setCondition(newStatus, EffectiveVPAConditionTypeReady, metav1.ConditionFalse, "FailedGetPodTemplate", "Failed to get pod template") c.UpdateStatus(ctx, evpa, newStatus) return ctrl.Result{}, err } estimators := c.EstimatorManager.GetEstimators(evpa) if err != nil { - c.Recorder.Event(evpa, v1.EventTypeNormal, "FailedGetEstimators", err.Error()) + c.Recorder.Event(evpa, v1.EventTypeWarning, "FailedGetEstimators", err.Error()) klog.Errorf("Failed to get estimators, evpa %s", klog.KObj(evpa)) - setCondition(newStatus, metav1.ConditionFalse, "FailedGetEstimators", "Failed to get estimators") + setCondition(newStatus, EffectiveVPAConditionTypeReady, metav1.ConditionFalse, "FailedGetEstimators", "Failed to get estimators") c.UpdateStatus(ctx, evpa, newStatus) return ctrl.Result{}, err } + if evpa.DeletionTimestamp != nil { + c.EstimatorManager.DeleteEstimators(evpa) // release estimators + c.CleanLastScaleTime(evpa) // clean last scale time + + evpaCopy := evpa.DeepCopy() + evpaCopy.Finalizers = utils.RemoveString(evpaCopy.Finalizers, known.AutoscalingFinalizer) + err = c.Client.Update(ctx, evpaCopy) + if err != nil { + c.Recorder.Event(evpa, v1.EventTypeWarning, "FailedRemoveFinalizers", err.Error()) + klog.Errorf("Failed to remove finalizers, evpa %s", klog.KObj(evpa)) + setCondition(newStatus, EffectiveVPAConditionTypeReady, metav1.ConditionFalse, "FailedRemoveFinalizers", "Failed to remove finalizers") + c.UpdateStatus(ctx, evpa, newStatus) + return ctrl.Result{}, err + } + c.Recorder.Event(evpa, v1.EventTypeNormal, "RemoveFinalizers", err.Error()) + } else if !utils.ContainsString(evpa.Finalizers, known.AutoscalingFinalizer) { + evpa.Finalizers = append(evpa.Finalizers, known.AutoscalingFinalizer) + err = c.Client.Update(ctx, evpa) + if err != nil { + c.Recorder.Event(evpa, v1.EventTypeWarning, "FailedAddFinalizers", err.Error()) + klog.Errorf("Failed to add finalizers, evpa %s", klog.KObj(evpa)) + setCondition(newStatus, EffectiveVPAConditionTypeReady, metav1.ConditionFalse, "FailedAddFinalizers", "Failed to add finalizers") + c.UpdateStatus(ctx, evpa, newStatus) + return ctrl.Result{}, err + } + c.Recorder.Event(evpa, v1.EventTypeNormal, "AddFinalizers", "Add finalizers successful.") + } + if evpa.Spec.ResourcePolicy == nil { return ctrl.Result{}, nil } - currentEstimatorStatus, recommend, err := c.ReconcileContainerPolicies(ctx, evpa, podTemplate, estimators) + currentEstimatorStatus, recommend, err := c.ReconcileContainerPolicies(evpa, podTemplate, estimators) if err != nil { - c.Recorder.Event(evpa, v1.EventTypeNormal, "FailedReconcileContainerPolicies", err.Error()) + c.Recorder.Event(evpa, v1.EventTypeWarning, "FailedReconcileContainerPolicies", err.Error()) klog.Errorf("Failed to reconcile container policies, evpa %s", klog.KObj(evpa)) - setCondition(newStatus, metav1.ConditionFalse, "FailedGetEstimators", "Failed to get estimators") + setCondition(newStatus, EffectiveVPAConditionTypeReady, metav1.ConditionFalse, "FailedGetEstimators", "Failed to get estimators") c.UpdateStatus(ctx, evpa, newStatus) return ctrl.Result{}, err } @@ -90,9 +121,9 @@ func (c *EffectiveVPAController) Reconcile(ctx context.Context, req ctrl.Request newStatus.CurrentEstimators = currentEstimatorStatus recordMetric(evpa, newStatus, podTemplate) - - setCondition(newStatus, metav1.ConditionTrue, "EffectiveVerticalPodAutoscalerReady", "Effective VPA is ready") + setCondition(newStatus, EffectiveVPAConditionTypeReady, metav1.ConditionTrue, "EffectiveVerticalPodAutoscaler", "EffectiveVerticalPodAutoscaler is ready") c.UpdateStatus(ctx, evpa, newStatus) + return ctrl.Result{ RequeueAfter: DefaultEVPARsyncPeriod, }, nil @@ -115,7 +146,7 @@ func (c *EffectiveVPAController) UpdateStatus(ctx context.Context, evpa *autosca } func (c *EffectiveVPAController) SetupWithManager(mgr ctrl.Manager) error { - estimatorManager := estimator.NewResourceEstimatorManager(mgr.GetClient(), c.OOMRecorder) + estimatorManager := estimator.NewResourceEstimatorManager(mgr.GetClient(), c.OOMRecorder, c.Predictor) c.EstimatorManager = estimatorManager return ctrl.NewControllerManagedBy(mgr). For(&autoscalingapi.EffectiveVerticalPodAutoscaler{}). @@ -164,9 +195,10 @@ func recordMetric(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, status *a } } -func setCondition(status *autoscalingapi.EffectiveVerticalPodAutoscalerStatus, conditionStatus metav1.ConditionStatus, reason string, message string) { +// nolint:unparam +func setCondition(status *autoscalingapi.EffectiveVerticalPodAutoscalerStatus, conditionType string, conditionStatus metav1.ConditionStatus, reason string, message string) { for i := range status.Conditions { - if status.Conditions[i].Type == "Ready" { + if status.Conditions[i].Type == conditionType { status.Conditions[i].Status = conditionStatus status.Conditions[i].Reason = reason status.Conditions[i].Message = message diff --git a/pkg/known/finalizer.go b/pkg/known/finalizer.go new file mode 100644 index 000000000..89cd4901f --- /dev/null +++ b/pkg/known/finalizer.go @@ -0,0 +1,5 @@ +package known + +const ( + AutoscalingFinalizer = "autoscaling.crane.io/finalizer" +) diff --git a/pkg/recommend/advisor/resource_request.go b/pkg/recommend/advisor/resource_request.go index 834eb6ae0..24265dacf 100644 --- a/pkg/recommend/advisor/resource_request.go +++ b/pkg/recommend/advisor/resource_request.go @@ -100,37 +100,36 @@ func (a *ResourceRequestAdvisor) Advise(proposed *types.ProposedRecommendation) pod := a.Pods[0] namespace := pod.Namespace - var queryExpr string for _, c := range pod.Spec.Containers { cr := types.ContainerRecommendation{ ContainerName: c.Name, Target: map[corev1.ResourceName]string{}, } - mericNamer := ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceCPU) - klog.V(6).Infof("CPU query for resource request recommendation: %s", mericNamer.BuildUniqueKey()) + metricNamer := ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceCPU) + klog.V(6).Infof("CPU query for resource request recommendation: %s", metricNamer.BuildUniqueKey()) cpuConfig := makeCpuConfig(a.ConfigProperties) tsList, err := utils.QueryPredictedValuesOnce(a.Recommendation, p, - fmt.Sprintf(callerFormat, a.Recommendation.UID), cpuConfig, mericNamer) + fmt.Sprintf(callerFormat, a.Recommendation.UID), cpuConfig, metricNamer) if err != nil { return err } if len(tsList) < 1 || len(tsList[0].Samples) < 1 { - return fmt.Errorf("no value retured for queryExpr: %s", queryExpr) + return fmt.Errorf("no value retured for queryExpr: %s", metricNamer.BuildUniqueKey()) } v := int64(tsList[0].Samples[0].Value * 1000) cr.Target[corev1.ResourceCPU] = resource.NewMilliQuantity(v, resource.DecimalSI).String() - mericNamer = ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceMemory) - klog.V(6).Infof("Memory query for resource request recommendation: %s", mericNamer.BuildUniqueKey()) + metricNamer = ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceMemory) + klog.V(6).Infof("Memory query for resource request recommendation: %s", metricNamer.BuildUniqueKey()) memConfig := makeMemConfig(a.ConfigProperties) tsList, err = utils.QueryPredictedValuesOnce(a.Recommendation, p, - fmt.Sprintf(callerFormat, a.Recommendation.UID), memConfig, mericNamer) + fmt.Sprintf(callerFormat, a.Recommendation.UID), memConfig, metricNamer) if err != nil { return err } if len(tsList) < 1 || len(tsList[0].Samples) < 1 { - return fmt.Errorf("no value retured for queryExpr: %s", queryExpr) + return fmt.Errorf("no value retured for queryExpr: %s", metricNamer.BuildUniqueKey()) } v = int64(tsList[0].Samples[0].Value) cr.Target[corev1.ResourceMemory] = resource.NewQuantity(v, resource.BinarySI).String() diff --git a/pkg/utils/prediction.go b/pkg/utils/prediction.go index 134cdb310..83dc79efb 100644 --- a/pkg/utils/prediction.go +++ b/pkg/utils/prediction.go @@ -30,6 +30,15 @@ func QueryPredictedTimeSeriesOnce(predictor prediction.Interface, caller string, return predictor.QueryPredictedTimeSeries(context.TODO(), namer, startTime, endTime) } +func QueryPredictedValues(predictor prediction.Interface, caller string, pConfig *config.Config, namer metricnaming.MetricNamer) ([]*common.TimeSeries, error) { + err := predictor.WithQuery(namer, caller, *pConfig) + if err != nil { + return nil, err + } + + return predictor.QueryRealtimePredictedValues(context.TODO(), namer) +} + func QueryPredictedValuesOnce(recommendation *v1alpha1.Recommendation, predictor prediction.Interface, caller string, pConfig *config.Config, namer metricnaming.MetricNamer) ([]*common.TimeSeries, error) { return predictor.QueryRealtimePredictedValuesOnce(context.TODO(), namer, *pConfig) } diff --git a/pkg/utils/slice.go b/pkg/utils/slice.go new file mode 100644 index 000000000..f35a3a841 --- /dev/null +++ b/pkg/utils/slice.go @@ -0,0 +1,20 @@ +package utils + +func ContainsString(slice []string, str string) bool { + for _, s := range slice { + if s == str { + return true + } + } + return false +} + +func RemoveString(slice []string, str string) []string { + var newSlice []string + for _, item := range slice { + if item != str { + newSlice = append(newSlice, item) + } + } + return newSlice +} diff --git a/pkg/utils/string.go b/pkg/utils/string.go index 591115c4f..a190e4f25 100644 --- a/pkg/utils/string.go +++ b/pkg/utils/string.go @@ -2,15 +2,6 @@ package utils import "strconv" -func ContainsString(slice []string, str string) bool { - for _, s := range slice { - if s == str { - return true - } - } - return false -} - func ParseFloat(str string, defaultValue float64) (float64, error) { if len(str) == 0 { return defaultValue, nil From aa85501b2bc21939cbeefa5b33f27e5a72629c93 Mon Sep 17 00:00:00 2001 From: shijieqin Date: Fri, 25 Mar 2022 12:37:57 +0800 Subject: [PATCH 30/41] crane-agent only create tsp Change the units of ext-cpu --- cmd/crane-agent/app/agent.go | 2 +- cmd/crane-agent/app/options/option.go | 18 +-- examples/noderesource-tsp-template.yaml | 2 +- pkg/agent/agent.go | 112 ++++++++++++------ pkg/ensurance/cm/advanced_cpu_manager.go | 10 +- .../cadvisor/cadvisor_unsupported.go | 5 +- pkg/ensurance/collector/collector.go | 1 - pkg/ensurance/collector/nodelocal/cpu.go | 6 +- pkg/resource/node_resource_manager.go | 33 ++++-- pkg/utils/pod.go | 2 +- pkg/utils/string.go | 2 +- 11 files changed, 122 insertions(+), 71 deletions(-) diff --git a/cmd/crane-agent/app/agent.go b/cmd/crane-agent/app/agent.go index 6dd1c682d..1daeaa1b6 100644 --- a/cmd/crane-agent/app/agent.go +++ b/cmd/crane-agent/app/agent.go @@ -100,7 +100,7 @@ func Run(ctx context.Context, opts *options.Options) error { tspInformer := craneInformerFactory.Prediction().V1alpha1().TimeSeriesPredictions() newAgent, err := agent.NewAgent(ctx, hostname, opts.RuntimeEndpoint, kubeClient, craneClient, - podInformer, nodeInformer, nepInformer, actionInformer, tspInformer, opts.NodeResourceOptions, opts.Ifaces, healthCheck, opts.CollectInterval) + podInformer, nodeInformer, nepInformer, actionInformer, tspInformer, opts.NodeResourceReserved, opts.Ifaces, healthCheck, opts.CollectInterval) if err != nil { return err diff --git a/cmd/crane-agent/app/options/option.go b/cmd/crane-agent/app/options/option.go index d657cf9c9..a222fd456 100644 --- a/cmd/crane-agent/app/options/option.go +++ b/cmd/crane-agent/app/options/option.go @@ -4,6 +4,7 @@ import ( "time" "github.com/spf13/pflag" + cliflag "k8s.io/component-base/cli/flag" ) // Options hold the command-line options about crane manager @@ -21,21 +22,13 @@ type Options struct { // MaxInactivity is the maximum time from last recorded activity before automatic restart MaxInactivity time.Duration // Ifaces is the network devices to collect metric - Ifaces []string - //NodeResourceOptions is the options of nodeResource - NodeResourceOptions NodeResourceOptions -} - -type NodeResourceOptions struct { - ReserveCpuPercentStr string - ReserveMemoryPercentStr string + Ifaces []string + NodeResourceReserved map[string]string } // NewOptions builds an empty options. func NewOptions() *Options { - return &Options{ - NodeResourceOptions: NodeResourceOptions{}, - } + return &Options{} } // Complete completes all the required options. @@ -56,7 +49,6 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) { flags.StringVar(&o.BindAddr, "bind-address", "0.0.0.0:8081", "The address the agent binds to for metrics, health-check and pprof, default: 0.0.0.0:8081.") flags.DurationVar(&o.CollectInterval, "collect-interval", 10*time.Second, "Period for the state collector to collect metrics, default: 10s") flags.StringArrayVar(&o.Ifaces, "ifaces", []string{"eth0"}, "The network devices to collect metric, use comma to separated, default: eth0") - flags.StringVar(&o.NodeResourceOptions.ReserveCpuPercentStr, "reserve-cpu-percent", "", "reserve cpu percentage of node.") - flags.StringVar(&o.NodeResourceOptions.ReserveMemoryPercentStr, "reserve-memory-percent", "", "reserve memory percentage of node.") + flags.Var(cliflag.NewMapStringString(&o.NodeResourceReserved), "node-resource-reserved", "A set of ResourceName=Percent (e.g. cpu=40%,memory=40%)") flags.DurationVar(&o.MaxInactivity, "max-inactivity", 5*time.Minute, "Maximum time from last recorded activity before automatic restart, default: 5min") } diff --git a/examples/noderesource-tsp-template.yaml b/examples/noderesource-tsp-template.yaml index cf47619bd..f8ffdfe9c 100644 --- a/examples/noderesource-tsp-template.yaml +++ b/examples/noderesource-tsp-template.yaml @@ -17,7 +17,7 @@ data: resourceIdentifier: cpu type: ExpressionQuery expressionQuery: - expression: 'node_cpu_cannot_be_reclaimed_seconds{node=~"({{nodename}})(:\\d+)?"}' + expression: 'node_cpu_cannot_be_reclaimed_seconds{node=~"({{ .metadata.name }})(:\\d+)?"}' predictionWindowSeconds: 180 kind: ConfigMap metadata: diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 3051f1fbf..b8eda041d 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -1,13 +1,17 @@ package agent import ( + "bytes" "context" + "encoding/json" "fmt" + "html/template" "net/http" - "strings" + "reflect" "time" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/uuid" @@ -28,7 +32,6 @@ import ( "github.com/gocrane/api/pkg/generated/informers/externalversions/ensurance/v1alpha1" predictionv1 "github.com/gocrane/api/pkg/generated/informers/externalversions/prediction/v1alpha1" v1alpha12 "github.com/gocrane/api/prediction/v1alpha1" - "github.com/gocrane/crane/cmd/crane-agent/app/options" "github.com/gocrane/crane/pkg/ensurance/analyzer" "github.com/gocrane/crane/pkg/ensurance/cm" "github.com/gocrane/crane/pkg/ensurance/collector" @@ -58,7 +61,7 @@ func NewAgent(ctx context.Context, nepInformer v1alpha1.NodeQOSEnsurancePolicyInformer, actionInformer v1alpha1.AvoidanceActionInformer, tspInformer predictionv1.TimeSeriesPredictionInformer, - nodeResourceOptions options.NodeResourceOptions, + nodeResourceReserved map[string]string, ifaces []string, healthCheck *metrics.HealthCheck, CollectInterval time.Duration, @@ -88,7 +91,14 @@ func NewAgent(ctx context.Context, avoidanceManager := executor.NewActionExecutor(kubeClient, nodeName, podInformer, nodeInformer, noticeCh, runtimeEndpoint) managers = appendManagerIfNotNil(managers, avoidanceManager) if nodeResource := utilfeature.DefaultFeatureGate.Enabled(features.CraneNodeResource); nodeResource { - nodeResourceManager := resource.NewNodeResourceManager(kubeClient, nodeName, nodeResourceOptions.ReserveCpuPercentStr, nodeResourceOptions.ReserveMemoryPercentStr, agent.CreateNodeResourceTsp(), nodeInformer, tspInformer, stateCollector.NodeResourceChann) + tspName, err := agent.CreateNodeResourceTsp() + if err != nil { + return agent, err + } + nodeResourceManager, err := resource.NewNodeResourceManager(kubeClient, nodeName, nodeResourceReserved, tspName, nodeInformer, tspInformer, stateCollector.NodeResourceChann) + if err != nil { + return agent, err + } managers = appendManagerIfNotNil(managers, nodeResourceManager) } @@ -127,61 +137,96 @@ func (a *Agent) Run(healthCheck *metrics.HealthCheck, enableProfiling bool, bind }() <-a.ctx.Done() - - _ = a.DeleteNodeResourceTsp() } func getAgentName(nodeName string) string { return nodeName + "." + string(uuid.NewUUID()) } -func (a *Agent) CreateNodeResourceTsp() string { +func (a *Agent) CreateNodeResourceTsp() (string, error) { tsp, err := a.craneClient.PredictionV1alpha1().TimeSeriesPredictions(resource.TspNamespace).Get(context.TODO(), a.GenerateNodeResourceTspName(), metav1.GetOptions{}) - if err == nil { - klog.V(4).Infof("Found old tsp %s in namespace %s", a.GenerateNodeResourceTspName(), resource.TspNamespace) - err := a.DeleteNodeResourceTsp() - if err != nil { - klog.Exitf("Delete old tsp %s with error: %v", a.GenerateNodeResourceTspName(), err) + if err != nil { + if !errors.IsNotFound(err) { + klog.Errorf("Failed to get noderesource tsp : %v", err) + return "", err } } config, err := a.kubeClient.CoreV1().ConfigMaps(resource.TspNamespace).Get(context.TODO(), "noderesource-tsp-template", metav1.GetOptions{}) if err != nil { - klog.Exitf("Get noderesource tsp configmap noderesource-tsp-template with error: %v", err) + klog.Errorf("Failed to get noderesource tsp configmap : %v", err) } if config == nil { - klog.Exitf("Can't get noderesource tsp configmap noderesource-tsp-template") + klog.Errorf("Can't get noderesource tsp configmap noderesource-tsp-template") } - spec := v1alpha12.TimeSeriesPredictionSpec{} - err = yaml.Unmarshal([]byte(strings.Replace(config.Data["spec"], "{{nodename}}", a.nodeName, -1)), &spec) + n, err := a.kubeClient.CoreV1().Nodes().Get(context.TODO(), a.nodeName, metav1.GetOptions{}) if err != nil { - klog.Exitf("Convert spec template error: %v", err) + klog.Errorf("Failed to get node : %v", err) + return "", err } - n, err := a.kubeClient.CoreV1().Nodes().Get(context.TODO(), a.nodeName, metav1.GetOptions{}) + spec := v1alpha12.TimeSeriesPredictionSpec{} + tpl, err := template.New("").Parse(config.Data["spec"]) if err != nil { - klog.Exitf("Get node error: %v", err) + klog.Errorf("Failed to convert spec template : %v", err) + return "", err + } + var buf bytes.Buffer + //The k8s object is converted here to a json object in order to use lowercase letters in the template to take the node field, + //just like {{ .metadata.name }} + raw, _ := json.Marshal(n) + var data interface{} + _ = json.Unmarshal(raw, &data) + + err = tpl.Execute(&buf, data) + if err != nil { + klog.Errorf("Failed to convert spec template : %v", err) + return "", err + } + err = yaml.Unmarshal(buf.Bytes(), &spec) + if err != nil { + klog.Errorf("Failed to convert spec template : %v", err) + return "", err } - tsp = &v1alpha12.TimeSeriesPrediction{} - - tsp.Name = a.GenerateNodeResourceTspName() - tsp.Namespace = resource.TspNamespace gvk, _ := apiutil.GVKForObject(n, scheme.Scheme) spec.TargetRef = v1.ObjectReference{ Kind: gvk.Kind, APIVersion: gvk.GroupVersion().String(), Name: a.nodeName, } - tsp.Spec = spec - _ = controllerutil.SetControllerReference(n, tsp, scheme.Scheme) - _, err = a.craneClient.PredictionV1alpha1().TimeSeriesPredictions(tsp.Namespace).Create(context.TODO(), tsp, metav1.CreateOptions{}) - if err != nil { - klog.Exitf("Create noderesource tsp %s with error: %v", a.GenerateNodeResourceTspName(), err) + + if tsp != nil { + klog.V(4).Infof("Discover the presence of old noderesource tsp and try to contrast the changes: %s", a.GenerateNodeResourceTspName()) + if reflect.DeepEqual(tsp.Spec, spec) { + return a.GenerateNodeResourceTspName(), nil + } + klog.V(4).Infof("Discover the presence of old noderesource tsp and the Tsp rules have been changed: %s", a.GenerateNodeResourceTspName()) + tsp.Spec = spec + _, err := a.craneClient.PredictionV1alpha1().TimeSeriesPredictions(tsp.Namespace).Update(context.TODO(), tsp, metav1.UpdateOptions{}) + if err != nil { + klog.Errorf("Failed to update noderesource tsp %s : %v", a.GenerateNodeResourceTspName(), err) + return "", err + } + klog.V(4).Infof("The noderesource tsp is updated successfully: %s", a.GenerateNodeResourceTspName()) + } else { + klog.V(4).Infof("The noderesource tsp does not exist, try to create a new one: %s", a.GenerateNodeResourceTspName()) + tsp = &v1alpha12.TimeSeriesPrediction{} + tsp.Name = a.GenerateNodeResourceTspName() + tsp.Namespace = resource.TspNamespace + tsp.Spec = spec + _ = controllerutil.SetControllerReference(n, tsp, scheme.Scheme) + _, err = a.craneClient.PredictionV1alpha1().TimeSeriesPredictions(tsp.Namespace).Create(context.TODO(), tsp, metav1.CreateOptions{}) + if err != nil { + klog.Errorf("Failed to create noderesource tsp %s : %v", a.GenerateNodeResourceTspName(), err) + return "", err + } + klog.V(4).Infof("The noderesource tsp is created successfully: %s", a.GenerateNodeResourceTspName()) } - return a.GenerateNodeResourceTspName() + + return a.GenerateNodeResourceTspName(), nil } func (a *Agent) DeleteNodeResourceTsp() error { @@ -193,14 +238,7 @@ func (a *Agent) DeleteNodeResourceTsp() error { } func (a *Agent) GenerateNodeResourceTspName() string { - return fmt.Sprintf("noderesource-%s", a.name) -} - -func appendManagerIfNotNil(managers []manager.Manager, m manager.Manager) []manager.Manager { - if m != nil { - return append(managers, m) - } - return managers + return fmt.Sprintf("noderesource-%s", a.nodeName) } func appendManagerIfNotNil(managers []manager.Manager, m manager.Manager) []manager.Manager { diff --git a/pkg/ensurance/cm/advanced_cpu_manager.go b/pkg/ensurance/cm/advanced_cpu_manager.go index c6911ae9a..1c8e8fb08 100644 --- a/pkg/ensurance/cm/advanced_cpu_manager.go +++ b/pkg/ensurance/cm/advanced_cpu_manager.go @@ -67,6 +67,8 @@ type AdvancedCpuManager struct { // stateFileDirectory holds the directory where the state file for checkpoints is held. stateFileDirectory string + exclusiveCPUSet cpuset.CPUSet + cadvisor.Manager } @@ -255,6 +257,8 @@ func (m *AdvancedCpuManager) syncState(doAllocate bool) { } } } + + m.exclusiveCPUSet = m.getExclusiveCpu() } func (m *AdvancedCpuManager) policyRemoveContainerByRef(podUID string, containerName string) error { @@ -299,7 +303,7 @@ func (m *AdvancedCpuManager) getSharedCpu() cpuset.CPUSet { return sharedCPUSet } -func (m *AdvancedCpuManager) GetExclusiveCpu() cpuset.CPUSet { +func (m *AdvancedCpuManager) getExclusiveCpu() cpuset.CPUSet { exclusiveCPUSet := cpuset.NewCPUSet() for _, pod := range m.activepods() { for _, container := range pod.Spec.Containers { @@ -313,6 +317,10 @@ func (m *AdvancedCpuManager) GetExclusiveCpu() cpuset.CPUSet { return exclusiveCPUSet } +func (m *AdvancedCpuManager) GetExclusiveCpu() cpuset.CPUSet { + return m.exclusiveCPUSet +} + func (m *AdvancedCpuManager) activepods() []*v1.Pod { allPods, _ := m.podLister.List(labels.Everything()) activePods := make([]*v1.Pod, 0, len(allPods)) diff --git a/pkg/ensurance/collector/cadvisor/cadvisor_unsupported.go b/pkg/ensurance/collector/cadvisor/cadvisor_unsupported.go index b53cfce86..9b20d808e 100644 --- a/pkg/ensurance/collector/cadvisor/cadvisor_unsupported.go +++ b/pkg/ensurance/collector/cadvisor/cadvisor_unsupported.go @@ -4,6 +4,8 @@ package cadvisor import ( + "errors" + info "github.com/google/cadvisor/info/v1" cadvisorapiv2 "github.com/google/cadvisor/info/v2" corelisters "k8s.io/client-go/listers/core/v1" @@ -11,13 +13,14 @@ import ( "github.com/gocrane/crane/pkg/common" "github.com/gocrane/crane/pkg/ensurance/collector/types" ) + var errUnsupported = errors.New("cAdvisor is unsupported in this build") type CadvisorCollectorUnsupport struct { Manager Manager } -type CadvisorManagerUnsupport struct {} +type CadvisorManagerUnsupport struct{} func NewCadvisorManager() Manager { return &CadvisorManagerUnsupport{} diff --git a/pkg/ensurance/collector/collector.go b/pkg/ensurance/collector/collector.go index 98e2ebcac..3024caac7 100644 --- a/pkg/ensurance/collector/collector.go +++ b/pkg/ensurance/collector/collector.go @@ -42,7 +42,6 @@ func NewStateCollector(nodeName string, nepLister ensuranceListers.NodeQOSEnsura analyzerChann := make(chan map[string][]common.TimeSeries) nodeResourceChann := make(chan map[string][]common.TimeSeries) podResourceChann := make(chan map[string][]common.TimeSeries) - c := cadvisor.NewCadvisorManager() return &StateCollector{ nodeName: nodeName, nepLister: nepLister, diff --git a/pkg/ensurance/collector/nodelocal/cpu.go b/pkg/ensurance/collector/nodelocal/cpu.go index 1b350bd5a..8fa7446c1 100644 --- a/pkg/ensurance/collector/nodelocal/cpu.go +++ b/pkg/ensurance/collector/nodelocal/cpu.go @@ -11,6 +11,7 @@ import ( "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/load" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "github.com/gocrane/crane/pkg/common" "github.com/gocrane/crane/pkg/ensurance/collector/types" @@ -85,7 +86,10 @@ func collectCPU(nodeLocalContext *nodeLocalContext) (map[string][]common.TimeSer usagePercent := calculateBusy(nodeState.latestCpuState.stat, currentCpuState.stat) usageCore := usagePercent * float64(nodeState.cpuCoreNumbers) * 1000 / types.MaxPercentage - cpuSet := nodeLocalContext.exclusiveCPUSet() + cpuSet := cpuset.NewCPUSet() + if nodeLocalContext.exclusiveCPUSet != nil { + cpuSet = nodeLocalContext.exclusiveCPUSet() + } var exclusiveCPUIdle float64 = 0 for cpuId, stat := range currentCpuState.perStat { diff --git a/pkg/resource/node_resource_manager.go b/pkg/resource/node_resource_manager.go index 3870365c1..e6e7d31d7 100644 --- a/pkg/resource/node_resource_manager.go +++ b/pkg/resource/node_resource_manager.go @@ -60,7 +60,7 @@ type NodeResourceManager struct { tspLister predictionlisters.TimeSeriesPredictionLister tspSynced cache.InformerSynced - recorder record.EventRecorder + recorder record.EventRecorder stateChann chan map[string][]common.TimeSeries @@ -73,11 +73,16 @@ type NodeResourceManager struct { tspName string } -func NewNodeResourceManager(client clientset.Interface, nodeName string, reserveCpuPercentStr string, - reserveMemoryPercentStr string, tspName string, nodeInformer coreinformers.NodeInformer, - tspInformer predictionv1.TimeSeriesPredictionInformer, stateChann chan map[string][]common.TimeSeries) *NodeResourceManager { - reserveCpuPercent, _ := utils.ParsePercentage(reserveCpuPercentStr) - reserveMemoryPercent, _ := utils.ParsePercentage(reserveMemoryPercentStr) +func NewNodeResourceManager(client clientset.Interface, nodeName string, op map[string]string, tspName string, nodeInformer coreinformers.NodeInformer, + tspInformer predictionv1.TimeSeriesPredictionInformer, stateChann chan map[string][]common.TimeSeries) (*NodeResourceManager, error) { + reserveCpuPercent, err := utils.ParsePercentage(op[v1.ResourceCPU.String()]) + if err != nil { + return nil, err + } + reserveMemoryPercent, err := utils.ParsePercentage(op[v1.ResourceMemory.String()]) + if err != nil { + return nil, err + } eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartStructuredLogging(0) @@ -99,7 +104,7 @@ func NewNodeResourceManager(client clientset.Interface, nodeName string, reserve }, tspName: tspName, } - return o + return o, nil } func (o *NodeResourceManager) Name() string { @@ -153,7 +158,7 @@ func (o *NodeResourceManager) UpdateNodeResource() { if !equality.Semantic.DeepEqual(&node.Status, &nodeCopy.Status) { // Update Node status extend-resource info // TODO fix: strategic merge patch kubernetes - if _, err := o.client.CoreV1().Nodes().Update(context.TODO(), nodeCopy, metav1.UpdateOptions{}); err != nil { + if _, err := o.client.CoreV1().Nodes().UpdateStatus(context.TODO(), nodeCopy, metav1.UpdateOptions{}); err != nil { klog.Errorf("Failed to update node %s's status extend-resource, %v", nodeCopy.Name, err) return } @@ -188,7 +193,7 @@ func (o *NodeResourceManager) FindTargetNode(tsp *predictionapi.TimeSeriesPredic return false, nil } -func (o *NodeResourceManager) BuildNodeStatus(node *v1.Node) map[v1.ResourceName]string{ +func (o *NodeResourceManager) BuildNodeStatus(node *v1.Node) map[v1.ResourceName]string { tspCanNotBeReclaimedResource := o.GetCanNotBeReclaimedResourceFromTsp(node) localCanNotBeReclaimedResource := o.GetCanNotBeReclaimedResourceFromLocal() reserveCpuPercent := o.reserveResource.CpuPercent @@ -205,14 +210,14 @@ func (o *NodeResourceManager) BuildNodeStatus(node *v1.Node) map[v1.ResourceName maxUsage = localCanNotBeReclaimedResource[resourceName] resourceFrom = "local" } + var nextRecommendation float64 switch resourceName { case v1.ResourceCPU: - // cpu need to be scaled to m as ext resource cannot be decimal if reserveCpuPercent != nil { - nextRecommendation = (float64(node.Status.Allocatable.Cpu().Value())**reserveCpuPercent - maxUsage) * 1000 + nextRecommendation = float64(node.Status.Allocatable.Cpu().Value()) - float64(node.Status.Allocatable.Cpu().Value())*(*reserveCpuPercent) - maxUsage/1000 } else { - nextRecommendation = (float64(node.Status.Allocatable.Cpu().Value()) - maxUsage) * 1000 + nextRecommendation = float64(node.Status.Allocatable.Cpu().Value()) - maxUsage/1000 } case v1.ResourceMemory: // unit of memory in prometheus is in Ki, need to be converted to byte @@ -313,7 +318,7 @@ func (o *NodeResourceManager) GetCpuCoreCanNotBeReclaimedFromLocal() float64 { var extResContainerCpuUsageTotal float64 = 0 extResContainerCpuUsageTotalTimeSeries, ok := o.state[string(types.MetricNameExtResContainerCpuTotalUsage)] if ok { - extResContainerCpuUsageTotal = extResContainerCpuUsageTotalTimeSeries[0].Samples[0].Value + extResContainerCpuUsageTotal = extResContainerCpuUsageTotalTimeSeries[0].Samples[0].Value * 1000 } else { klog.V(1).Infof("Can't get %s from NodeResourceManager local state", types.MetricNameExtResContainerCpuTotalUsage) } @@ -326,6 +331,8 @@ func (o *NodeResourceManager) GetCpuCoreCanNotBeReclaimedFromLocal() float64 { klog.V(1).Infof("Can't get %s from NodeResourceManager local state", types.MetricNameExclusiveCPUIdle) } + klog.V(6).Infof("nodeCpuUsageTotal: %s, exclusiveCPUIdle: %s, extResContainerCpuUsageTotal: %s", nodeCpuUsageTotal, exclusiveCPUIdle, extResContainerCpuUsageTotal) + // 1. Exclusive tethered CPU cannot be reclaimed even if the free part is free, so add the exclusive CPUIdle to the CanNotBeReclaimed CPU // 2. The CPU used by extRes-container needs to be reclaimed, otherwise it will be double-counted due to the allotted mechanism of k8s, so the extResContainerCpuUsageTotal is subtracted from the CanNotBeReclaimedCpu return nodeCpuUsageTotal + exclusiveCPUIdle - extResContainerCpuUsageTotal diff --git a/pkg/utils/pod.go b/pkg/utils/pod.go index c08758e36..836f7a8b4 100644 --- a/pkg/utils/pod.go +++ b/pkg/utils/pod.go @@ -159,7 +159,7 @@ func GetContainerNameFromPod(pod *v1.Pod, containerId string) string { } func GetContainerFromPod(pod *v1.Pod, containerName string) *v1.Container { - if containerName == ""{ + if containerName == "" { return nil } for _, v := range pod.Spec.Containers { diff --git a/pkg/utils/string.go b/pkg/utils/string.go index 5ec868f56..9010814be 100644 --- a/pkg/utils/string.go +++ b/pkg/utils/string.go @@ -31,4 +31,4 @@ func ParsePercentage(input string) (float64, error) { return 0, err } return value / 100, nil -} \ No newline at end of file +} From ffeb399684876fca5826d1804af8ddcd2d9753ad Mon Sep 17 00:00:00 2001 From: kitianFresh <1549722424@qq.com> Date: Thu, 21 Apr 2022 19:38:07 +0800 Subject: [PATCH 31/41] support init mode for metric model, and init by realtime provider is async until the data is accumlulating enough --- pkg/autoscaling/estimator/percentile.go | 43 ++++++- .../evpa/effective_vpa_controller.go | 3 + pkg/controller/timeseriesprediction/config.go | 55 +++++---- pkg/metricnaming/naming.go | 16 ++- pkg/metricquery/type.go | 18 +-- pkg/prediction/config/types.go | 13 +++ pkg/prediction/dsp/prediction.go | 4 + pkg/prediction/generic.go | 4 + pkg/prediction/interface.go | 3 + pkg/prediction/percentile/aggregate_signal.go | 7 ++ .../percentile/aggregate_signals.go | 57 ++++++++- pkg/prediction/percentile/config.go | 19 ++- pkg/prediction/percentile/prediction.go | 110 ++++++++++-------- pkg/providers/prom/prometheus.go | 4 +- pkg/recommend/advisor/ehpa.go | 13 ++- pkg/recommend/advisor/resource_request.go | 27 +++-- 16 files changed, 286 insertions(+), 110 deletions(-) diff --git a/pkg/autoscaling/estimator/percentile.go b/pkg/autoscaling/estimator/percentile.go index cd202599b..1751ba4b8 100644 --- a/pkg/autoscaling/estimator/percentile.go +++ b/pkg/autoscaling/estimator/percentile.go @@ -19,7 +19,7 @@ import ( "github.com/gocrane/crane/pkg/utils" ) -const callerFormat = "EVPACaller-%s-%s-%s" +const callerFormat = "EVPACaller-%s-%s" type PercentileResourceEstimator struct { Predictor prediction.Interface @@ -29,7 +29,9 @@ type PercentileResourceEstimator struct { func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, config map[string]string, containerName string, currRes *corev1.ResourceRequirements) (corev1.ResourceList, error) { recommendResource := corev1.ResourceList{} + caller := fmt.Sprintf(callerFormat, klog.KObj(evpa), string(evpa.UID)) cpuMetricNamer := &metricnaming.GeneralMetricNamer{ + CallerName: caller, Metric: &metricquery.Metric{ Type: metricquery.ContainerMetricType, MetricName: corev1.ResourceCPU.String(), @@ -43,7 +45,7 @@ func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi } cpuConfig := getCpuConfig(config) - tsList, err := utils.QueryPredictedValues(e.Predictor, fmt.Sprintf(callerFormat, string(evpa.UID), containerName, corev1.ResourceCPU), cpuConfig, cpuMetricNamer) + tsList, err := utils.QueryPredictedValues(e.Predictor, caller, cpuConfig, cpuMetricNamer) if err != nil { return nil, err } @@ -56,6 +58,7 @@ func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi recommendResource[corev1.ResourceCPU] = *resource.NewMilliQuantity(cpuValue, resource.DecimalSI) memoryMetricNamer := &metricnaming.GeneralMetricNamer{ + CallerName: caller, Metric: &metricquery.Metric{ Type: metricquery.ContainerMetricType, MetricName: corev1.ResourceMemory.String(), @@ -69,7 +72,7 @@ func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi } memConfig := getMemConfig(config) - tsList, err = utils.QueryPredictedValues(e.Predictor, fmt.Sprintf(callerFormat, string(evpa.UID), containerName, corev1.ResourceMemory), memConfig, memoryMetricNamer) + tsList, err = utils.QueryPredictedValues(e.Predictor, caller, memConfig, memoryMetricNamer) if err != nil { return nil, err } @@ -86,7 +89,9 @@ func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi func (e *PercentileResourceEstimator) DeleteEstimation(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler) { for _, containerPolicy := range evpa.Spec.ResourcePolicy.ContainerPolicies { + caller := fmt.Sprintf(callerFormat, klog.KObj(evpa), string(evpa.UID)) cpuMetricNamer := &metricnaming.GeneralMetricNamer{ + CallerName: caller, Metric: &metricquery.Metric{ Type: metricquery.ContainerMetricType, MetricName: corev1.ResourceCPU.String(), @@ -98,12 +103,12 @@ func (e *PercentileResourceEstimator) DeleteEstimation(evpa *autoscalingapi.Effe }, }, } - err := e.Predictor.DeleteQuery(cpuMetricNamer, fmt.Sprintf(callerFormat, string(evpa.UID), containerPolicy.ContainerName, corev1.ResourceCPU)) + err := e.Predictor.DeleteQuery(cpuMetricNamer, caller) if err != nil { klog.ErrorS(err, "Failed to delete query.", "queryExpr", cpuMetricNamer.BuildUniqueKey()) } - memoryMetricNamer := &metricnaming.GeneralMetricNamer{ + CallerName: caller, Metric: &metricquery.Metric{ Type: metricquery.ContainerMetricType, MetricName: corev1.ResourceMemory.String(), @@ -115,7 +120,7 @@ func (e *PercentileResourceEstimator) DeleteEstimation(evpa *autoscalingapi.Effe }, }, } - err = e.Predictor.DeleteQuery(memoryMetricNamer, fmt.Sprintf(callerFormat, string(evpa.UID), containerPolicy.ContainerName, corev1.ResourceMemory)) + err = e.Predictor.DeleteQuery(memoryMetricNamer, caller) if err != nil { klog.ErrorS(err, "Failed to delete query.", "queryExpr", memoryMetricNamer.BuildUniqueKey()) } @@ -137,9 +142,22 @@ func getCpuConfig(config map[string]string) *predictionconfig.Config { marginFraction = "0.15" } + initModeStr, exists := config["cpu-model-init-mode"] + initMode := predictionconfig.ModelInitModeLazyTraining + if !exists { + initMode = predictionconfig.ModelInitMode(initModeStr) + } + + historyLength, exists := config["cpu-model-history-length"] + if !exists { + historyLength = "24h" + } + return &predictionconfig.Config{ + InitMode: &initMode, Percentile: &predictionapi.Percentile{ Aggregated: true, + HistoryLength: historyLength, SampleInterval: sampleInterval, MarginFraction: marginFraction, Percentile: percentile, @@ -166,9 +184,22 @@ func getMemConfig(props map[string]string) *predictionconfig.Config { marginFraction = "0.15" } + initModeStr, exists := props["mem-model-init-mode"] + initMode := predictionconfig.ModelInitModeLazyTraining + if !exists { + initMode = predictionconfig.ModelInitMode(initModeStr) + } + + historyLength, exists := props["mem-model-history-length"] + if !exists { + historyLength = "48h" + } + return &predictionconfig.Config{ + InitMode: &initMode, Percentile: &predictionapi.Percentile{ Aggregated: true, + HistoryLength: historyLength, SampleInterval: sampleInterval, MarginFraction: marginFraction, Percentile: percentile, diff --git a/pkg/controller/evpa/effective_vpa_controller.go b/pkg/controller/evpa/effective_vpa_controller.go index 35fb709be..4640efd4a 100644 --- a/pkg/controller/evpa/effective_vpa_controller.go +++ b/pkg/controller/evpa/effective_vpa_controller.go @@ -158,6 +158,9 @@ func recordMetric(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, status *a "resourceName": fmt.Sprintf("%s/%s", evpa.Namespace, evpa.Spec.TargetRef.Name), } + if status.Recommendation == nil { + return + } for _, container := range status.Recommendation.ContainerRecommendations { resourceRequirement, found := utils.GetResourceByPodTemplate(podTemplate, container.ContainerName) if !found { diff --git a/pkg/controller/timeseriesprediction/config.go b/pkg/controller/timeseriesprediction/config.go index bcfdd0a8f..1aa8fc2f3 100644 --- a/pkg/controller/timeseriesprediction/config.go +++ b/pkg/controller/timeseriesprediction/config.go @@ -63,18 +63,21 @@ func (c *MetricContext) GetMetricNamer(conf *predictionapi.PredictionMetric) met return nil } if conf.ExpressionQuery != nil { - namer.Metric = &metricquery.Metric{ - Type: metricquery.PromQLMetricType, - MetricName: conf.ResourceIdentifier, - Prom: &metricquery.PromNamerInfo{ - QueryExpr: conf.ExpressionQuery.Expression, - Selector: labels.Nothing(), + namer = metricnaming.GeneralMetricNamer{ + CallerName: c.GetCaller(), + Metric: &metricquery.Metric{ + Type: metricquery.PromQLMetricType, + MetricName: conf.ResourceIdentifier, + Prom: &metricquery.PromNamerInfo{ + QueryExpr: conf.ExpressionQuery.Expression, + Selector: labels.Nothing(), + }, }, } klog.InfoS("GetQueryStr", "tsp", klog.KObj(c.SeriesPrediction), "queryExpr", conf.ExpressionQuery.Expression) } if conf.ResourceQuery != nil { - namer = c.ResourceToMetricNamer(conf.ResourceQuery) + namer = c.ResourceToMetricNamer(conf.ResourceQuery, c.GetCaller()) klog.InfoS("GetQueryStr", "tsp", klog.KObj(c.SeriesPrediction), "resourceQuery", conf.ResourceQuery) } return &namer @@ -139,30 +142,36 @@ func metricSelectorToQueryExpr(m *predictionapi.MetricQuery) string { return fmt.Sprintf("%s{%s}", m.MetricName, strings.Join(conditions, ",")) } -func (c *MetricContext) ResourceToMetricNamer(resourceName *corev1.ResourceName) metricnaming.GeneralMetricNamer { +func (c *MetricContext) ResourceToMetricNamer(resourceName *corev1.ResourceName, caller string) metricnaming.GeneralMetricNamer { var namer metricnaming.GeneralMetricNamer // Node if strings.ToLower(c.TargetKind) == strings.ToLower(predconf.TargetKindNode) { - namer.Metric = &metricquery.Metric{ - Type: metricquery.NodeMetricType, - MetricName: resourceName.String(), - Node: &metricquery.NodeNamerInfo{ - Name: c.Name, - Selector: labels.Everything(), + namer = metricnaming.GeneralMetricNamer{ + CallerName: caller, + Metric: &metricquery.Metric{ + Type: metricquery.NodeMetricType, + MetricName: resourceName.String(), + Node: &metricquery.NodeNamerInfo{ + Name: c.Name, + Selector: labels.Everything(), + }, }, } } else { // workload - namer.Metric = &metricquery.Metric{ - Type: metricquery.WorkloadMetricType, - MetricName: resourceName.String(), - Workload: &metricquery.WorkloadNamerInfo{ - Namespace: c.Namespace, - Kind: c.TargetKind, - APIVersion: c.APIVersion, - Name: c.Name, - Selector: c.Selector, + namer = metricnaming.GeneralMetricNamer{ + CallerName: caller, + Metric: &metricquery.Metric{ + Type: metricquery.WorkloadMetricType, + MetricName: resourceName.String(), + Workload: &metricquery.WorkloadNamerInfo{ + Namespace: c.Namespace, + Kind: c.TargetKind, + APIVersion: c.APIVersion, + Name: c.Name, + Selector: c.Selector, + }, }, } } diff --git a/pkg/metricnaming/naming.go b/pkg/metricnaming/naming.go index 38dc19492..a93165811 100644 --- a/pkg/metricnaming/naming.go +++ b/pkg/metricnaming/naming.go @@ -5,7 +5,7 @@ import ( "github.com/gocrane/crane/pkg/querybuilder" ) -// MetricNamer is an interface. it is the bridge between predictor and different data sources and other component. +// MetricNamer is an interface. it is the bridge between predictor and different data sources and other component such as caller. type MetricNamer interface { // Used for datasource provider, data source provider call QueryBuilder QueryBuilder() querybuilder.QueryBuilder @@ -13,10 +13,20 @@ type MetricNamer interface { BuildUniqueKey() string Validate() error + + // Means the caller of this MetricNamer, different caller maybe use the same metric + Caller() string } +var _ MetricNamer = &GeneralMetricNamer{} + type GeneralMetricNamer struct { - Metric *metricquery.Metric + Metric *metricquery.Metric + CallerName string +} + +func (gmn *GeneralMetricNamer) Caller() string { + return gmn.CallerName } func (gmn *GeneralMetricNamer) QueryBuilder() querybuilder.QueryBuilder { @@ -24,7 +34,7 @@ func (gmn *GeneralMetricNamer) QueryBuilder() querybuilder.QueryBuilder { } func (gmn *GeneralMetricNamer) BuildUniqueKey() string { - return gmn.Metric.BuildUniqueKey() + return gmn.CallerName + "/" + gmn.Metric.BuildUniqueKey() } func (gmn *GeneralMetricNamer) Validate() error { diff --git a/pkg/metricquery/type.go b/pkg/metricquery/type.go index acbbae3c6..e5f24adae 100644 --- a/pkg/metricquery/type.go +++ b/pkg/metricquery/type.go @@ -27,10 +27,10 @@ const ( var ( NotMatchWorkloadError = fmt.Errorf("metric type %v, but no WorkloadNamerInfo provided", WorkloadMetricType) - NotMatchContainerError = fmt.Errorf("metric type %v, but no WorkloadNamerInfo provided", ContainerMetricType) - NotMatchPodError = fmt.Errorf("metric type %v, but no WorkloadNamerInfo provided", PodMetricType) - NotMatchNodeError = fmt.Errorf("metric type %v, but no WorkloadNamerInfo provided", NodeMetricType) - NotMatchPromError = fmt.Errorf("metric type %v, but no WorkloadNamerInfo provided", PromQLMetricType) + NotMatchContainerError = fmt.Errorf("metric type %v, but no ContainerNamerInfo provided", ContainerMetricType) + NotMatchPodError = fmt.Errorf("metric type %v, but no PodNamerInfo provided", PodMetricType) + NotMatchNodeError = fmt.Errorf("metric type %v, but no NodeNamerInfo provided", NodeMetricType) + NotMatchPromError = fmt.Errorf("metric type %v, but no PromNamerInfo provided", PromQLMetricType) ) type Metric struct { @@ -153,7 +153,7 @@ func (m *Metric) keyByWorkload() string { m.Workload.APIVersion, m.Workload.Namespace, m.Workload.Name, - selectorStr}, "-") + selectorStr}, "_") } func (m *Metric) keyByContainer() string { @@ -168,7 +168,7 @@ func (m *Metric) keyByContainer() string { m.Container.WorkloadName, m.Container.PodName, m.Container.ContainerName, - selectorStr}, "-") + selectorStr}, "_") } func (m *Metric) keyByPod() string { @@ -181,7 +181,7 @@ func (m *Metric) keyByPod() string { strings.ToLower(m.MetricName), m.Pod.Namespace, m.Pod.Name, - selectorStr}, "-") + selectorStr}, "_") } func (m *Metric) keyByNode() string { selectorStr := "" @@ -192,7 +192,7 @@ func (m *Metric) keyByNode() string { string(m.Type), strings.ToLower(m.MetricName), m.Node.Name, - selectorStr}, "-") + selectorStr}, "_") } func (m *Metric) keyByPromQL() string { @@ -205,7 +205,7 @@ func (m *Metric) keyByPromQL() string { m.Prom.Namespace, strings.ToLower(m.MetricName), m.Prom.QueryExpr, - selectorStr}, "-") + selectorStr}, "_") } // Query is used to do query for different data source. you can extends it with your data source query diff --git a/pkg/prediction/config/types.go b/pkg/prediction/config/types.go index dc2e4c825..2782bd87a 100644 --- a/pkg/prediction/config/types.go +++ b/pkg/prediction/config/types.go @@ -10,7 +10,20 @@ type AlgorithmModelConfig struct { UpdateInterval time.Duration } +type ModelInitMode string + +const ( + // means recover or init the algorithm model directly from history datasource, this process may block because it is time consuming for data fetching & model gen + ModelInitModeHistory ModelInitMode = "history" + // means recover or init the algorithm model from real time datasource async, predictor can not do predicting before the data is accumulating to window length + // this is more safe to do some data accumulating and make the prediction data is robust. + ModelInitModeLazyTraining ModelInitMode = "lazytraining" + // means recover or init the model from a checkpoint, it can be restored directly and immediately to do predict. + ModelInitModeCheckpoint ModelInitMode = "checkpoint" +) + type Config struct { + InitMode *ModelInitMode DSP *v1alpha1.DSP Percentile *v1alpha1.Percentile } diff --git a/pkg/prediction/dsp/prediction.go b/pkg/prediction/dsp/prediction.go index bb72c259e..f4d9085b9 100644 --- a/pkg/prediction/dsp/prediction.go +++ b/pkg/prediction/dsp/prediction.go @@ -35,6 +35,10 @@ type periodicSignalPrediction struct { modelConfig config.AlgorithmModelConfig } +func (p *periodicSignalPrediction) QueryPredictionStatus(ctx context.Context, metricNamer metricnaming.MetricNamer) (prediction.Status, error) { + panic("implement me") +} + func NewPrediction(realtimeProvider providers.RealTime, historyProvider providers.History, mc config.AlgorithmModelConfig) prediction.Interface { withCh, delCh := make(chan prediction.QueryExprWithCaller), make(chan prediction.QueryExprWithCaller) return &periodicSignalPrediction{ diff --git a/pkg/prediction/generic.go b/pkg/prediction/generic.go index 5169f12f3..79e420efe 100644 --- a/pkg/prediction/generic.go +++ b/pkg/prediction/generic.go @@ -26,6 +26,10 @@ const ( StatusNotStarted Status = "NotStarted" StatusUnknown Status = "Unknown" StatusDeleted Status = "Deleted" + // StatusInitializing means the prediction model is accumulating data until it satisfy the user specified time window such as 12h or 3d or 1w when use some real time data provider + // if support recover from checkpoint, then it maybe faster + StatusInitializing Status = "Initializing" + StatusExpired Status = "Expired" ) type WithMetricEvent struct { diff --git a/pkg/prediction/interface.go b/pkg/prediction/interface.go index f2b724007..01ac99ebe 100644 --- a/pkg/prediction/interface.go +++ b/pkg/prediction/interface.go @@ -19,6 +19,9 @@ type Interface interface { DeleteQuery(metricNamer metricnaming.MetricNamer, caller string) error + // QueryPredictionStatus return the metricNamer prediction status. it is predictable only when it is ready + QueryPredictionStatus(ctx context.Context, metricNamer metricnaming.MetricNamer) (Status, error) + // QueryRealtimePredictedValues returns predicted values based on the specified query expression QueryRealtimePredictedValues(ctx context.Context, metricNamer metricnaming.MetricNamer) ([]*common.TimeSeries, error) diff --git a/pkg/prediction/percentile/aggregate_signal.go b/pkg/prediction/percentile/aggregate_signal.go index f58856cd8..8e3427b51 100644 --- a/pkg/prediction/percentile/aggregate_signal.go +++ b/pkg/prediction/percentile/aggregate_signal.go @@ -15,6 +15,7 @@ type aggregateSignal struct { lastSampleTime time.Time minSampleWeight float64 totalSamplesCount int + sampleInterval time.Duration creationTime time.Time labels []common.Label } @@ -30,10 +31,16 @@ func (a *aggregateSignal) addSample(sampleTime time.Time, sampleValue float64) { a.totalSamplesCount++ } +// largest is 290 years, so it can not be overflow +func (a *aggregateSignal) GetAggregationWindowLength() time.Duration { + return time.Duration(a.totalSamplesCount) * a.sampleInterval +} + func newAggregateSignal(c *internalConfig) *aggregateSignal { return &aggregateSignal{ histogram: vpa.NewHistogram(c.histogramOptions), minSampleWeight: c.minSampleWeight, creationTime: time.Now(), + sampleInterval: c.sampleInterval, } } diff --git a/pkg/prediction/percentile/aggregate_signals.go b/pkg/prediction/percentile/aggregate_signals.go index 545360a78..e0a50ad97 100644 --- a/pkg/prediction/percentile/aggregate_signals.go +++ b/pkg/prediction/percentile/aggregate_signals.go @@ -13,6 +13,11 @@ type aggregateSignals struct { callerMap map[string] /*expr*/ map[string] /*caller*/ struct{} signalMap map[string] /*expr*/ map[string] /*key*/ *aggregateSignal statusMap map[string] /*expr*/ prediction.Status + /** + todo: later we should split the predictor to another service as a common service, maybe an AI like system + different caller has different config. this is inevitable because we provide different features in one craned, both use underlying prediction + now we can not control the param of different callers. if we use only one config, then evpa & tsp & recommendation will interference and override with each other + */ configMap map[string] /*expr*/ *internalConfig } @@ -32,7 +37,7 @@ func (a *aggregateSignals) Add(qc prediction.QueryExprWithCaller) bool { QueryExpr := qc.MetricNamer.BuildUniqueKey() if qc.Config.Percentile != nil { - cfg, err := makeInternalConfig(qc.Config.Percentile) + cfg, err := makeInternalConfig(qc.Config.Percentile, qc.Config.InitMode) if err != nil { klog.ErrorS(err, "Failed to make internal config.", "queryExpr", QueryExpr) } else { @@ -44,7 +49,7 @@ func (a *aggregateSignals) Add(qc prediction.QueryExprWithCaller) bool { a.callerMap[QueryExpr] = map[string]struct{}{} } - if status, exists := a.statusMap[QueryExpr]; !exists || status == prediction.StatusDeleted { + if _, exists := a.statusMap[QueryExpr]; !exists { a.statusMap[QueryExpr] = prediction.StatusNotStarted } @@ -79,7 +84,7 @@ func (a *aggregateSignals) Delete(qc prediction.QueryExprWithCaller) bool /*need delete(a.callerMap, QueryExpr) delete(a.signalMap, QueryExpr) delete(a.configMap, QueryExpr) - a.statusMap[QueryExpr] = prediction.StatusDeleted + delete(a.statusMap, QueryExpr) return true } @@ -89,9 +94,6 @@ func (a *aggregateSignals) GetConfig(queryExpr string) *internalConfig { if a.configMap[queryExpr] != nil { return a.configMap[queryExpr] } - if a.statusMap[queryExpr] != prediction.StatusReady { - return nil - } return &defaultInternalConfig } @@ -107,6 +109,28 @@ func (a *aggregateSignals) SetSignal(queryExpr string, key string, signal *aggre a.statusMap[queryExpr] = prediction.StatusReady } +func (a *aggregateSignals) SetSignalWithStatus(id, key string, signal *aggregateSignal, status prediction.Status) { + a.mutex.Lock() + defer a.mutex.Unlock() + + if _, exists := a.signalMap[id]; !exists { + return + } + + a.signalMap[id][key] = signal + a.statusMap[id] = status +} + +func (a *aggregateSignals) SetSignalStatus(id, key string, status prediction.Status) { + a.mutex.Lock() + defer a.mutex.Unlock() + + if _, exists := a.signalMap[id]; !exists { + return + } + a.statusMap[id] = status +} + func (a *aggregateSignals) GetSignal(queryExpr string, key string) *aggregateSignal { a.mutex.RLock() defer a.mutex.RUnlock() @@ -146,6 +170,27 @@ func (a *aggregateSignals) SetSignals(queryExpr string, signals map[string]*aggr a.statusMap[queryExpr] = prediction.StatusReady } +func (a *aggregateSignals) SetSignalsWithStatus(queryExpr string, signals map[string]*aggregateSignal, status prediction.Status) { + a.mutex.Lock() + defer a.mutex.Unlock() + if _, exists := a.signalMap[queryExpr]; !exists { + return + } + for k, v := range signals { + a.signalMap[queryExpr][k] = v + } + a.statusMap[queryExpr] = status +} + +func (a *aggregateSignals) SetSignalsStatus(queryExpr string, status prediction.Status) { + a.mutex.Lock() + defer a.mutex.Unlock() + if _, exists := a.signalMap[queryExpr]; !exists { + return + } + a.statusMap[queryExpr] = status +} + func (a *aggregateSignals) GetSignals(queryExpr string) (map[string]*aggregateSignal, prediction.Status) { a.mutex.RLock() defer a.mutex.RUnlock() diff --git a/pkg/prediction/percentile/config.go b/pkg/prediction/percentile/config.go index cf86aa428..591fc333a 100644 --- a/pkg/prediction/percentile/config.go +++ b/pkg/prediction/percentile/config.go @@ -9,6 +9,7 @@ import ( "github.com/gocrane/api/prediction/v1alpha1" + "github.com/gocrane/crane/pkg/prediction/config" "github.com/gocrane/crane/pkg/utils" ) @@ -25,6 +26,7 @@ var defaultInternalConfig = internalConfig{ marginFraction: defaultMarginFraction, percentile: defaultPercentile, histogramOptions: defaultHistogramOptions, + historyLength: time.Hour * 24 * 7, } type internalConfig struct { @@ -36,6 +38,7 @@ type internalConfig struct { minSampleWeight float64 marginFraction float64 percentile float64 + initMode config.ModelInitMode } func (c *internalConfig) String() string { @@ -43,11 +46,17 @@ func (c *internalConfig) String() string { c.aggregated, c.historyLength, c.sampleInterval, c.histogramDecayHalfLife, c.minSampleWeight, c.marginFraction, c.percentile) } -func makeInternalConfig(p *v1alpha1.Percentile) (*internalConfig, error) { +// todo: later better to refine the algorithm params to a map not a struct to get more extendability, +// if not, we add some param is very difficult because it will modify crane api +func makeInternalConfig(p *v1alpha1.Percentile, initMode *config.ModelInitMode) (*internalConfig, error) { sampleInterval, err := utils.ParseDuration(p.SampleInterval) if err != nil { return nil, err } + historyLength, err := utils.ParseDuration(p.HistoryLength) + if err != nil { + return nil, err + } halfLife, err := utils.ParseDuration(p.Histogram.HalfLife) if err != nil { @@ -122,9 +131,15 @@ func makeInternalConfig(p *v1alpha1.Percentile) (*internalConfig, error) { return nil, err } + // default use history + mode := config.ModelInitModeHistory + if initMode != nil { + mode = *initMode + } c := &internalConfig{ + initMode: mode, aggregated: p.Aggregated, - historyLength: time.Hour * 24 * 7, + historyLength: historyLength, sampleInterval: sampleInterval, histogramOptions: options, histogramDecayHalfLife: halfLife, diff --git a/pkg/prediction/percentile/prediction.go b/pkg/prediction/percentile/prediction.go index 9e5119b5b..c4062fb41 100644 --- a/pkg/prediction/percentile/prediction.go +++ b/pkg/prediction/percentile/prediction.go @@ -23,6 +23,11 @@ type percentilePrediction struct { stopChMap sync.Map } +func (p *percentilePrediction) QueryPredictionStatus(ctx context.Context, metricNamer metricnaming.MetricNamer) (prediction.Status, error) { + _, status := p.a.GetSignals(metricNamer.BuildUniqueKey()) + return status, nil +} + func (p *percentilePrediction) QueryPredictedTimeSeries(ctx context.Context, namer metricnaming.MetricNamer, startTime time.Time, endTime time.Time) ([]*common.TimeSeries, error) { var predictedTimeSeriesList []*common.TimeSeries queryExpr := namer.BuildUniqueKey() @@ -59,8 +64,8 @@ func (p *percentilePrediction) getPredictedValues(ctx context.Context, namer met queryExpr := namer.BuildUniqueKey() for { signals, status := p.a.GetSignals(queryExpr) - if status == prediction.StatusDeleted { - klog.V(4).InfoS("Aggregated has been deleted.", "queryExpr", queryExpr) + if status == prediction.StatusUnknown { + klog.V(4).InfoS("Aggregated has been deleted and unknown", "queryExpr", queryExpr) return predictedTimeSeriesList } if signals != nil && status == prediction.StatusReady { @@ -112,6 +117,11 @@ func (p *percentilePrediction) getPredictedValues(ctx context.Context, namer met } func (p *percentilePrediction) QueryRealtimePredictedValues(ctx context.Context, namer metricnaming.MetricNamer) ([]*common.TimeSeries, error) { + queryExpr := namer.BuildUniqueKey() + _, status := p.a.GetSignals(queryExpr) + if status != prediction.StatusReady { + return nil, fmt.Errorf("metric %v model status is %v, must be ready", queryExpr, status) + } return p.getPredictedValues(ctx, namer), nil } @@ -175,7 +185,7 @@ func (p *percentilePrediction) process(namer metricnaming.MetricNamer, config co var historyTimeSeriesList []*common.TimeSeries var err error queryExpr := namer.BuildUniqueKey() - cfg, err := makeInternalConfig(config.Percentile) + cfg, err := makeInternalConfig(config.Percentile, config.InitMode) if err != nil { return nil, err } @@ -276,14 +286,31 @@ func (p *percentilePrediction) Run(stopCh <-chan struct{}) { // todo: Do not block this management go routine here to do some time consuming operation. // We just init the signal and setting the status // we start the real time model updating directly. but there is a window time for each metricNamer in the algorithm config to ready status - if err := p.init(qc.MetricNamer); err != nil { - klog.ErrorS(err, "Failed to init percentilePrediction.") + c := p.a.GetConfig(QueryExpr) + if c == nil { + c = &defaultInternalConfig + } + + var initError error + switch c.initMode { + case config.ModelInitModeLazyTraining: + p.initByRealTimeProvider(qc.MetricNamer) + case config.ModelInitModeCheckpoint: + initError = p.initByCheckPoint(qc.MetricNamer) + case config.ModelInitModeHistory: + fallthrough + default: + // blocking + initError = p.initFromHistory(qc.MetricNamer) + } + + if initError != nil { + klog.ErrorS(initError, "Failed to init percentilePrediction.") continue } - // bug here: - // 1. first, judge the metric is already started, if so, we do not start the updating model routine again. - // 2. same query, but different config means different series analysis, but here GetConfig always return same config. + // note: same query, but different config means different series analysis, GetConfig always return same config. + // this is our default policy, one metric only has one config at a time. go func(namer metricnaming.MetricNamer) { queryExpr := namer.BuildUniqueKey() if c := p.a.GetConfig(queryExpr); c != nil { @@ -353,51 +380,26 @@ func (p *percentilePrediction) queryHistoryTimeSeries(namer metricnaming.MetricN // So, we can set a waiting time for the model trained completed. Because percentile is only used for request resource & resource estimation. // Because of the scenes, we do not need it give a result fastly after service start, we can tolerate it has some days delaying for collecting more data. // nolint:unused -func (p *percentilePrediction) initByRealTimeProvider(namer metricnaming.MetricNamer) error { +func (p *percentilePrediction) initByRealTimeProvider(namer metricnaming.MetricNamer) { queryExpr := namer.BuildUniqueKey() cfg := p.a.GetConfig(queryExpr) - latestTimeSeriesList, err := p.GetRealtimeProvider().QueryLatestTimeSeries(namer) - if err != nil { - klog.ErrorS(err, "Failed to get latest time series.") - return err - } if cfg.aggregated { signal := newAggregateSignal(cfg) - for _, ts := range latestTimeSeriesList { - for _, s := range ts.Samples { - t := time.Unix(s.Timestamp, 0) - signal.addSample(t, s.Value) - } - } - p.a.SetSignal(queryExpr, "__all__", signal) + + p.a.SetSignalWithStatus(queryExpr, "__all__", signal, prediction.StatusInitializing) } else { signals := map[string]*aggregateSignal{} - for _, ts := range latestTimeSeriesList { - if len(ts.Samples) < 1 { - continue - } - key := prediction.AggregateSignalKey(ts.Labels) - signal := newAggregateSignal(cfg) - for _, s := range ts.Samples { - t := time.Unix(s.Timestamp, 0) - signal.addSample(t, s.Value) - } - signal.labels = ts.Labels - signals[key] = signal - } - p.a.SetSignals(queryExpr, signals) + p.a.SetSignalsWithStatus(queryExpr, signals, prediction.StatusInitializing) } - - return nil } // todo: // nolint:unused func (p *percentilePrediction) initByCheckPoint(namer metricnaming.MetricNamer) error { - return nil + return fmt.Errorf("Do not support checkpoint now") } -func (p *percentilePrediction) init(namer metricnaming.MetricNamer) error { +func (p *percentilePrediction) initFromHistory(namer metricnaming.MetricNamer) error { queryExpr := namer.BuildUniqueKey() cfg := p.a.GetConfig(queryExpr) // Query history data for prediction @@ -449,11 +451,6 @@ func (p *percentilePrediction) addSamples(namer metricnaming.MetricNamer) { queryExpr := namer.BuildUniqueKey() c := p.a.GetConfig(queryExpr) - if _, status := p.a.GetSignals(queryExpr); status != prediction.StatusReady { - klog.InfoS("Aggregate signals not ready.", "queryExpr", queryExpr, "status", status) - return - } - if c.aggregated { key := "__all__" signal := p.a.GetSignal(queryExpr, key) @@ -468,7 +465,17 @@ func (p *percentilePrediction) addSamples(namer metricnaming.MetricNamer) { sample := ts.Samples[len(ts.Samples)-1] sampleTime := time.Unix(sample.Timestamp, 0) signal.addSample(sampleTime, sample.Value) - klog.V(6).InfoS("Sample added.", "sampleValue", sample.Value, "sampleTime", sampleTime, "queryExpr", queryExpr) + + // current time is reach the window length of percentile need to accumulating data, the model is ready to do predict + // all type need the aggregation window length is accumulating enough data. + // History: if the container is newly, then there maybe has not enough history data, so we need accumulating to make the confidence more reliable + // LazyTraining: directly accumulating data from real time metric provider until the data is enough + // Checkpoint: directly recover the model from a checkpoint, and then updating the model until accumulated data is enough + if signal.GetAggregationWindowLength() >= c.historyLength { + p.a.SetSignalStatus(queryExpr, key, prediction.StatusReady) + } + + klog.V(6).InfoS("Sample added.", "sampleValue", sample.Value, "sampleTime", sampleTime, "queryExpr", queryExpr, "history", c.historyLength, "aggregationWindowLength", signal.GetAggregationWindowLength()) } } else { // todo: find a way to remove the labels key, although we do not really use it now. @@ -485,11 +492,22 @@ func (p *percentilePrediction) addSamples(namer metricnaming.MetricNamer) { } sample := ts.Samples[len(ts.Samples)-1] sampleTime := time.Unix(sample.Timestamp, 0) + signal.addSample(sampleTime, sample.Value) if len(signal.labels) == 0 { signal.labels = ts.Labels } - klog.V(6).InfoS("Sample added.", "sampleValue", sample.Value, "sampleTime", sampleTime, "queryExpr", queryExpr, "key", key) + + // current time is reach the window length of percentile need to accumulating data, the model is ready to do predict + // all type need the aggregation window length is accumulating enough data. + // History: if the container is newly, then there maybe has not enough history data, so we need accumulating to make the confidence more reliable + // LazyTraining: directly accumulating data from real time metric provider until the data is enough + // Checkpoint: directly recover the model from a checkpoint, and then updating the model until accumulated data is enough + if signal.GetAggregationWindowLength() >= c.historyLength { + p.a.SetSignalStatus(queryExpr, key, prediction.StatusReady) + } + + klog.V(6).InfoS("Sample added.", "sampleValue", sample.Value, "sampleTime", sampleTime, "queryExpr", queryExpr, "key", key, "history", c.historyLength, "aggregationWindowLength", signal.GetAggregationWindowLength()) } } } diff --git a/pkg/providers/prom/prometheus.go b/pkg/providers/prom/prometheus.go index 00f0f72ca..7a34720d3 100644 --- a/pkg/providers/prom/prometheus.go +++ b/pkg/providers/prom/prometheus.go @@ -37,7 +37,7 @@ func (p *prom) QueryTimeSeries(namer metricnaming.MetricNamer, startTime time.Ti klog.Errorf("Failed to BuildQuery: %v", err) return nil, err } - klog.V(6).Infof("QueryTimeSeries metricNamer %v, timeout: %v", namer.BuildUniqueKey(), p.config.Timeout) + klog.V(6).Infof("QueryTimeSeries metricNamer %v, timeout: %v, query: %v", namer.BuildUniqueKey(), p.config.Timeout, promQuery.Prometheus.Query) timeoutCtx, cancelFunc := gocontext.WithTimeout(gocontext.Background(), p.config.Timeout) defer cancelFunc() timeSeries, err := p.ctx.QueryRangeSync(timeoutCtx, promQuery.Prometheus.Query, startTime, endTime, step) @@ -59,7 +59,7 @@ func (p *prom) QueryLatestTimeSeries(namer metricnaming.MetricNamer) ([]*common. //end := time.Now() // avoid no data latest. multiply 2 //start := end.Add(-step * 2) - klog.V(6).Infof("QueryLatestTimeSeries metricNamer %v, timeout: %v", namer.BuildUniqueKey(), p.config.Timeout) + klog.V(6).Infof("QueryLatestTimeSeries metricNamer %v, timeout: %v, query: %v", namer.BuildUniqueKey(), p.config.Timeout, promQuery.Prometheus.Query) timeoutCtx, cancelFunc := gocontext.WithTimeout(gocontext.Background(), p.config.Timeout) defer cancelFunc() timeSeries, err := p.ctx.QuerySync(timeoutCtx, promQuery.Prometheus.Query) diff --git a/pkg/recommend/advisor/ehpa.go b/pkg/recommend/advisor/ehpa.go index d686bc7d7..0d90aa37d 100644 --- a/pkg/recommend/advisor/ehpa.go +++ b/pkg/recommend/advisor/ehpa.go @@ -47,7 +47,8 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { if err != nil { return err } - metricNamer := ResourceToWorkloadMetricNamer(target, &resourceCpu, labelSelector) + caller := fmt.Sprintf(callerFormat, klog.KObj(a.Recommendation), a.Recommendation.UID) + metricNamer := ResourceToWorkloadMetricNamer(target, &resourceCpu, labelSelector, caller) if err := metricNamer.Validate(); err != nil { return err } @@ -62,7 +63,7 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { } cpuConfig := getPredictionCpuConfig() - tsListPrediction, err := utils.QueryPredictedTimeSeriesOnce(p, fmt.Sprintf(callerFormat, a.Recommendation.UID), + tsListPrediction, err := utils.QueryPredictedTimeSeriesOnce(p, caller, getPredictionCpuConfig(), metricNamer, timeNow, @@ -265,11 +266,12 @@ func (a *EHPAAdvisor) proposeTargetUtilization() (int32, int64, error) { var cpuUsage float64 // use percentile algo to get the 99 percentile cpu usage for this target for _, container := range a.PodTemplate.Spec.Containers { - metricNamer := ResourceToContainerMetricNamer(a.Recommendation.Spec.TargetRef.Namespace, a.Recommendation.Spec.TargetRef.Name, container.Name, corev1.ResourceCPU) + caller := fmt.Sprintf(callerFormat, klog.KObj(a.Recommendation), a.Recommendation.UID) + metricNamer := ResourceToContainerMetricNamer(a.Recommendation.Spec.TargetRef.Namespace, a.Recommendation.Spec.TargetRef.Name, container.Name, corev1.ResourceCPU, caller) cpuConfig := makeCpuConfig(a.ConfigProperties) tsList, err := utils.QueryPredictedValuesOnce(a.Recommendation, percentilePredictor, - fmt.Sprintf(callerFormat, a.Recommendation.UID), + caller, cpuConfig, metricNamer) if err != nil { @@ -389,9 +391,10 @@ func GetTargetLabelSelector(target *corev1.ObjectReference, scale *v1.Scale, ds } } -func ResourceToWorkloadMetricNamer(target *corev1.ObjectReference, resourceName *corev1.ResourceName, workloadLabelSelector labels.Selector) metricnaming.MetricNamer { +func ResourceToWorkloadMetricNamer(target *corev1.ObjectReference, resourceName *corev1.ResourceName, workloadLabelSelector labels.Selector, caller string) metricnaming.MetricNamer { // workload return &metricnaming.GeneralMetricNamer{ + CallerName: caller, Metric: &metricquery.Metric{ Type: metricquery.WorkloadMetricType, MetricName: resourceName.String(), diff --git a/pkg/recommend/advisor/resource_request.go b/pkg/recommend/advisor/resource_request.go index 24265dacf..c5022b418 100644 --- a/pkg/recommend/advisor/resource_request.go +++ b/pkg/recommend/advisor/resource_request.go @@ -17,7 +17,7 @@ import ( "github.com/gocrane/crane/pkg/utils" ) -const callerFormat = "RecommendationCaller-%s" +const callerFormat = "RecommendationCaller-%s-%s" const ( DefaultNamespace = "default" @@ -41,9 +41,14 @@ func makeCpuConfig(props map[string]string) *config.Config { marginFraction = "0.15" } + historyLength, exists := props["resource.cpu-model-history-length"] + if !exists { + historyLength = "168h" + } return &config.Config{ Percentile: &predictionapi.Percentile{ Aggregated: true, + HistoryLength: historyLength, SampleInterval: sampleInterval, MarginFraction: marginFraction, Percentile: percentile, @@ -70,9 +75,15 @@ func makeMemConfig(props map[string]string) *config.Config { marginFraction = "0.15" } + historyLength, exists := props["resource.mem-model-history-length"] + if !exists { + historyLength = "168h" + } + return &config.Config{ Percentile: &predictionapi.Percentile{ Aggregated: true, + HistoryLength: historyLength, SampleInterval: sampleInterval, MarginFraction: marginFraction, Percentile: percentile, @@ -106,11 +117,11 @@ func (a *ResourceRequestAdvisor) Advise(proposed *types.ProposedRecommendation) Target: map[corev1.ResourceName]string{}, } - metricNamer := ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceCPU) + caller := fmt.Sprintf(callerFormat, klog.KObj(a.Recommendation), a.Recommendation.UID) + metricNamer := ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceCPU, caller) klog.V(6).Infof("CPU query for resource request recommendation: %s", metricNamer.BuildUniqueKey()) cpuConfig := makeCpuConfig(a.ConfigProperties) - tsList, err := utils.QueryPredictedValuesOnce(a.Recommendation, p, - fmt.Sprintf(callerFormat, a.Recommendation.UID), cpuConfig, metricNamer) + tsList, err := utils.QueryPredictedValuesOnce(a.Recommendation, p, caller, cpuConfig, metricNamer) if err != nil { return err } @@ -120,11 +131,10 @@ func (a *ResourceRequestAdvisor) Advise(proposed *types.ProposedRecommendation) v := int64(tsList[0].Samples[0].Value * 1000) cr.Target[corev1.ResourceCPU] = resource.NewMilliQuantity(v, resource.DecimalSI).String() - metricNamer = ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceMemory) + metricNamer = ResourceToContainerMetricNamer(namespace, a.Recommendation.Spec.TargetRef.Name, c.Name, corev1.ResourceMemory, caller) klog.V(6).Infof("Memory query for resource request recommendation: %s", metricNamer.BuildUniqueKey()) memConfig := makeMemConfig(a.ConfigProperties) - tsList, err = utils.QueryPredictedValuesOnce(a.Recommendation, p, - fmt.Sprintf(callerFormat, a.Recommendation.UID), memConfig, metricNamer) + tsList, err = utils.QueryPredictedValuesOnce(a.Recommendation, p, caller, memConfig, metricNamer) if err != nil { return err } @@ -145,9 +155,10 @@ func (a *ResourceRequestAdvisor) Name() string { return "ResourceRequestAdvisor" } -func ResourceToContainerMetricNamer(namespace, workloadname, containername string, resourceName corev1.ResourceName) metricnaming.MetricNamer { +func ResourceToContainerMetricNamer(namespace, workloadname, containername string, resourceName corev1.ResourceName, caller string) metricnaming.MetricNamer { // container return &metricnaming.GeneralMetricNamer{ + CallerName: caller, Metric: &metricquery.Metric{ Type: metricquery.ContainerMetricType, MetricName: resourceName.String(), From be59025302f1901e996f11470446482b1d6ed25a Mon Sep 17 00:00:00 2001 From: lbbniu Date: Wed, 13 Apr 2022 13:01:06 +0800 Subject: [PATCH 32/41] Fix golangci-lint code static check --- .github/workflows/go.yml | 3 -- .golangci.yaml | 29 +++++++++++++++++++ Makefile | 16 +--------- pkg/autoscaling/estimator/oom.go | 4 +-- .../analytics/analytics_controller.go | 11 ++++--- pkg/controller/ehpa/hpa.go | 2 +- .../evpa/effective_vpa_controller.go | 6 ++-- pkg/controller/recommendation/updater.go | 8 ++--- pkg/controller/timeseriesprediction/config.go | 11 ++++--- pkg/controller/timeseriesprediction/status.go | 5 +--- pkg/ensurance/executor/schedule.go | 2 +- pkg/ensurance/runtime/container.go | 2 +- pkg/metricprovider/custom_metric_provider.go | 10 +++---- pkg/metricprovider/remote.go | 10 +++---- pkg/metrics/ensuarance.go | 4 +-- pkg/metrics/health.go | 4 +-- pkg/metrics/tsp_metric_collector.go | 4 +-- pkg/prediction/config/config.go | 4 +-- pkg/prediction/dsp/estimators_test.go | 3 +- pkg/prediction/dsp/frequency_spectrum_test.go | 2 +- pkg/prediction/dsp/signal.go | 2 +- pkg/prediction/percentile/prediction.go | 6 ++-- .../metricserver/rest_metric_client.go | 12 +++----- pkg/recommend/advisor/ehpa.go | 6 ++-- pkg/recommend/inspector/workload.go | 10 +++---- pkg/recommend/inspector/workload_pods.go | 6 ++-- pkg/resource/pod_resource_manger.go | 7 +++-- pkg/utils/pod.go | 2 +- pkg/utils/pod_template.go | 6 ++-- pkg/utils/target/fetcher.go | 4 +-- pkg/webhooks/analytics/validating.go | 4 +-- pkg/webhooks/prediction/validating.go | 2 +- pkg/webhooks/recommendation/validating.go | 4 +-- 33 files changed, 107 insertions(+), 104 deletions(-) create mode 100644 .golangci.yaml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 8773306ad..f7f9111e1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -184,6 +184,3 @@ jobs: with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version version: v1.45.2 - - # Optional: golangci-lint command line arguments. - args: --timeout 30m --disable-all -E deadcode -E unused -E varcheck -E ineffassign -E goimports -E gofmt -E misspell -E unparam -E unconvert -E govet -E errcheck -E structcheck diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 000000000..a91cbaacb --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,29 @@ +run: + timeout: 30m + +linters: + disable-all: true + enable: + - deadcode + - unused + - varcheck + - ineffassign + - goimports + - gofmt + - misspell + - unparam + - unconvert + - govet + - errcheck + - structcheck + - staticcheck + +linters-settings: + staticcheck: + go: "1.17" + checks: [ + "all", + "-SA1019", # TODO(fix) Using a deprecated function, variable, constant or field + ] + unused: + go: "1.17" diff --git a/Makefile b/Makefile index 3a7add299..f5e303822 100644 --- a/Makefile +++ b/Makefile @@ -87,21 +87,7 @@ tidy: .PHONY: lint lint: golangci-lint ## Run golang lint against code - @$(GOLANG_LINT) run \ - --timeout 30m \ - --disable-all \ - -E deadcode \ - -E unused \ - -E varcheck \ - -E ineffassign \ - -E goimports \ - -E gofmt \ - -E misspell \ - -E unparam \ - -E unconvert \ - -E govet \ - -E errcheck \ - -E structcheck + @$(GOLANG_LINT) run ./... .PHONY: test test: fmt vet lint ## Run tests. diff --git a/pkg/autoscaling/estimator/oom.go b/pkg/autoscaling/estimator/oom.go index 2868d0a3d..d6f227a14 100644 --- a/pkg/autoscaling/estimator/oom.go +++ b/pkg/autoscaling/estimator/oom.go @@ -34,7 +34,7 @@ func (e *OOMResourceEstimator) GetResourceEstimation(evpa *autoscalingapi.Effect } // ignore too old oom events - if oomRecord != nil && time.Now().Sub(oomRecord.OOMAt) <= (time.Hour*24*7) { + if oomRecord != nil && time.Since(oomRecord.OOMAt) <= (time.Hour*24*7) { memoryOOM := oomRecord.Memory.Value() recommendResource := corev1.ResourceList{} var memoryNeeded recommendermodel.ResourceAmount @@ -47,7 +47,7 @@ func (e *OOMResourceEstimator) GetResourceEstimation(evpa *autoscalingapi.Effect } else { oomBumpUpRatio, err := strconv.ParseFloat(bumpUpRatio, 64) if err != nil { - return nil, fmt.Errorf("Parse bumpUpRatio failed: %v. ", err) + return nil, fmt.Errorf("parse bumpUpRatio failed: %v. ", err) } memoryNeeded = recommendermodel.ScaleResource(recommendermodel.ResourceAmount(memoryOOM), oomBumpUpRatio) } diff --git a/pkg/controller/analytics/analytics_controller.go b/pkg/controller/analytics/analytics_controller.go index 6cb9af091..eaf4bd7a9 100644 --- a/pkg/controller/analytics/analytics_controller.go +++ b/pkg/controller/analytics/analytics_controller.go @@ -7,7 +7,6 @@ import ( "time" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" @@ -111,7 +110,7 @@ func (c *Controller) DoAnalytics(ctx context.Context, analytics *analysisv1alph1 identities, err := c.GetIdentities(ctx, analytics) if err != nil { - c.Recorder.Event(analytics, v1.EventTypeNormal, "FailedSelectResource", err.Error()) + c.Recorder.Event(analytics, corev1.EventTypeNormal, "FailedSelectResource", err.Error()) msg := fmt.Sprintf("Failed to get idenitities, Analytics %s error %v", klog.KObj(analytics), err) klog.Errorf(msg) setReadyCondition(newStatus, metav1.ConditionFalse, "FailedSelectResource", msg) @@ -126,7 +125,7 @@ func (c *Controller) DoAnalytics(ctx context.Context, analytics *analysisv1alph1 recommendations, err = c.recommLister.Recommendations(analytics.Namespace).List(labels.Everything()) } if err != nil { - c.Recorder.Event(analytics, v1.EventTypeNormal, "FailedSelectResource", err.Error()) + c.Recorder.Event(analytics, corev1.EventTypeNormal, "FailedSelectResource", err.Error()) msg := fmt.Sprintf("Failed to get recomendations, Analytics %s error %v", klog.KObj(analytics), err) klog.Errorf(msg) setReadyCondition(newStatus, metav1.ConditionFalse, "FailedSelectResource", msg) @@ -176,7 +175,7 @@ func (c *Controller) DoAnalytics(ctx context.Context, analytics *analysisv1alph1 rCopy := r.DeepCopy() rCopy.OwnerReferences = append(rCopy.OwnerReferences, *newOwnerRef(analytics)) if err = c.Update(ctx, rCopy); err != nil { - c.Recorder.Event(analytics, v1.EventTypeNormal, "FailedUpdateRecommendation", err.Error()) + c.Recorder.Event(analytics, corev1.EventTypeNormal, "FailedUpdateRecommendation", err.Error()) msg := fmt.Sprintf("Failed to update ownerReferences for recommendation %s, Analytics %s error %v", klog.KObj(rCopy), klog.KObj(analytics), err) klog.Errorf(msg) setReadyCondition(newStatus, metav1.ConditionFalse, "FailedUpdateRecommendation", msg) @@ -187,7 +186,7 @@ func (c *Controller) DoAnalytics(ctx context.Context, analytics *analysisv1alph1 } } else { if err = c.CreateRecommendation(ctx, analytics, id, &refs); err != nil { - c.Recorder.Event(analytics, v1.EventTypeNormal, "FailedCreateRecommendation", err.Error()) + c.Recorder.Event(analytics, corev1.EventTypeNormal, "FailedCreateRecommendation", err.Error()) msg := fmt.Sprintf("Failed to create recommendation, Analytics %s error %v", klog.KObj(analytics), err) klog.Errorf(msg) setReadyCondition(newStatus, metav1.ConditionFalse, "FailedCreateRecommendation", msg) @@ -361,7 +360,7 @@ func (c *Controller) UpdateStatus(ctx context.Context, analytics *analysisv1alph analytics.Status = *newStatus err := c.Update(ctx, analytics) if err != nil { - c.Recorder.Event(analytics, v1.EventTypeNormal, "FailedUpdateStatus", err.Error()) + c.Recorder.Event(analytics, corev1.EventTypeNormal, "FailedUpdateStatus", err.Error()) klog.Errorf("Failed to update status, Analytics %s error %v", klog.KObj(analytics), err) return } diff --git a/pkg/controller/ehpa/hpa.go b/pkg/controller/ehpa/hpa.go index c597074d1..88864ec8a 100644 --- a/pkg/controller/ehpa/hpa.go +++ b/pkg/controller/ehpa/hpa.go @@ -220,7 +220,7 @@ func (c *EffectiveHPAController) GetHPAMetrics(ctx context.Context, ehpa *autosc } if len(pods) == 0 { - return nil, fmt.Errorf("No pods returns from scale object. ") + return nil, fmt.Errorf("no pods returns from scale object. ") } requests, err := utils.CalculatePodRequests(pods, metric.Resource.Name) diff --git a/pkg/controller/evpa/effective_vpa_controller.go b/pkg/controller/evpa/effective_vpa_controller.go index 4640efd4a..6056ff2d8 100644 --- a/pkg/controller/evpa/effective_vpa_controller.go +++ b/pkg/controller/evpa/effective_vpa_controller.go @@ -240,16 +240,16 @@ func defaultingEVPA(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler) error { for _, estimatorCurr := range evpa.Spec.ResourceEstimators { if estimatorCurr.Type == "" { - return fmt.Errorf("Estimator type cannot be empty. ") + return fmt.Errorf("estimator type cannot be empty. ") } } if evpa.Spec.ResourcePolicy == nil || len(evpa.Spec.ResourcePolicy.ContainerPolicies) == 0 { - return fmt.Errorf("Resource policy or container policy cannot be empty. ") + return fmt.Errorf("resource policy or container policy cannot be empty. ") } for index, containerPolicy := range evpa.Spec.ResourcePolicy.ContainerPolicies { if containerPolicy.ContainerName == "" { - return fmt.Errorf("Container name cannot be empty. ") + return fmt.Errorf("container name cannot be empty. ") } // scale up diff --git a/pkg/controller/recommendation/updater.go b/pkg/controller/recommendation/updater.go index 4ad26f1f0..5dd79b8f0 100644 --- a/pkg/controller/recommendation/updater.go +++ b/pkg/controller/recommendation/updater.go @@ -48,7 +48,7 @@ func (c *Controller) UpdateRecommendation(ctx context.Context, recommendation *a unstructed.SetKind(recommendation.Spec.TargetRef.Kind) err := c.Client.Get(ctx, client.ObjectKey{Name: recommendation.Spec.TargetRef.Name, Namespace: recommendation.Spec.TargetRef.Namespace}, unstructed) if err != nil { - return fmt.Errorf("Get target object failed: %v. ", err) + return fmt.Errorf("get target object failed: %v. ", err) } if recommendation.Spec.AdoptionType == analysisapi.AdoptionTypeStatusAndAnnotation || recommendation.Spec.AdoptionType == analysisapi.AdoptionTypeAuto { @@ -67,7 +67,7 @@ func (c *Controller) UpdateRecommendation(ctx context.Context, recommendation *a unstructed.SetAnnotations(annotation) err = c.Client.Update(ctx, unstructed) if err != nil { - return fmt.Errorf("Update target annotation failed: %v. ", err) + return fmt.Errorf("update target annotation failed: %v. ", err) } } @@ -76,7 +76,7 @@ func (c *Controller) UpdateRecommendation(ctx context.Context, recommendation *a if proposed.EffectiveHPA != nil { ehpa, err := utils.GetEHPAFromScaleTarget(ctx, c.Client, recommendation.Spec.TargetRef.Namespace, recommendation.Spec.TargetRef) if err != nil { - return fmt.Errorf("Get EHPA from target failed: %v. ", err) + return fmt.Errorf("get EHPA from target failed: %v. ", err) } if ehpa == nil { ehpa = &autoscalingapi.EffectiveHorizontalPodAutoscaler{ @@ -127,7 +127,7 @@ func (c *Controller) UpdateRecommendation(ctx context.Context, recommendation *a if proposed.ResourceRequest != nil { evpa, err := utils.GetEVPAFromScaleTarget(ctx, c.Client, recommendation.Spec.TargetRef.Namespace, recommendation.Spec.TargetRef) if err != nil { - return fmt.Errorf("Get EVPA from target failed: %v. ", err) + return fmt.Errorf("get EVPA from target failed: %v. ", err) } if evpa == nil { off := vpatypes.UpdateModeOff diff --git a/pkg/controller/timeseriesprediction/config.go b/pkg/controller/timeseriesprediction/config.go index 1aa8fc2f3..a3872f021 100644 --- a/pkg/controller/timeseriesprediction/config.go +++ b/pkg/controller/timeseriesprediction/config.go @@ -38,10 +38,11 @@ func NewMetricContext(fetcher target.SelectorFetcher, seriesPrediction *predicti predictorMgr: predictorMgr, fetcher: fetcher, } - if strings.ToLower(c.TargetKind) != strings.ToLower(predconf.TargetKindNode) && seriesPrediction.Spec.TargetRef.Namespace != "" { + if !strings.EqualFold(c.TargetKind, predconf.TargetKindNode) && seriesPrediction.Spec.TargetRef.Namespace != "" { c.Namespace = seriesPrediction.Spec.TargetRef.Namespace } - if strings.ToLower(c.TargetKind) != strings.ToLower(predconf.TargetKindNode) { + + if !strings.EqualFold(c.TargetKind, predconf.TargetKindNode) { selector, err := c.fetcher.Fetch(&seriesPrediction.Spec.TargetRef) if err != nil { return nil, err @@ -132,9 +133,7 @@ func metricSelectorToQueryExpr(m *predictionapi.MetricQuery) string { conditions := make([]string, 0, len(m.QueryConditions)) for _, cond := range m.QueryConditions { values := make([]string, 0, len(cond.Value)) - for _, val := range cond.Value { - values = append(values, val) - } + values = append(values, cond.Value...) sort.Strings(values) conditions = append(conditions, fmt.Sprintf("%s%s[%s]", cond.Key, cond.Operator, strings.Join(values, ","))) } @@ -146,7 +145,7 @@ func (c *MetricContext) ResourceToMetricNamer(resourceName *corev1.ResourceName, var namer metricnaming.GeneralMetricNamer // Node - if strings.ToLower(c.TargetKind) == strings.ToLower(predconf.TargetKindNode) { + if strings.EqualFold(c.TargetKind, predconf.TargetKindNode) { namer = metricnaming.GeneralMetricNamer{ CallerName: caller, Metric: &metricquery.Metric{ diff --git a/pkg/controller/timeseriesprediction/status.go b/pkg/controller/timeseriesprediction/status.go index ce1d649d4..e9cb25663 100644 --- a/pkg/controller/timeseriesprediction/status.go +++ b/pkg/controller/timeseriesprediction/status.go @@ -229,8 +229,5 @@ func IsWindowInSamples(start, end time.Time, samples []predictionapi.Sample) boo //startTs := start.Truncate(1 * time.Minute).Unix() endTs := end.Truncate(1 * time.Minute).Unix() // only check the end, start not check, because start is always from now to predict - if endTs <= samples[n-1].Timestamp { - return true - } - return false + return endTs <= samples[n-1].Timestamp } diff --git a/pkg/ensurance/executor/schedule.go b/pkg/ensurance/executor/schedule.go index 0e2d1a8f8..9d5781b5d 100644 --- a/pkg/ensurance/executor/schedule.go +++ b/pkg/ensurance/executor/schedule.go @@ -93,7 +93,7 @@ func (b *ScheduleExecutor) Restore(ctx *ExecuteContext) error { func (p *ComparablePod) Less(p2 ComparablePod) bool { if comparePodQos(p.Status.QOSClass, p2.Status.QOSClass) == 1 { - + return false } return *p.Spec.Priority < *p2.Spec.Priority diff --git a/pkg/ensurance/runtime/container.go b/pkg/ensurance/runtime/container.go index c4e183227..73e151b65 100644 --- a/pkg/ensurance/runtime/container.go +++ b/pkg/ensurance/runtime/container.go @@ -98,7 +98,7 @@ func UpdateContainerResources(client pb.RuntimeServiceClient, containerId string // copied from kubernetes-sigs/cri-tools/cmd/crictl/container.go func RemoveContainer(client pb.RuntimeServiceClient, ContainerId string) error { if ContainerId == "" { - return fmt.Errorf("ID cannot be empty") + return fmt.Errorf("id cannot be empty") } request := &pb.RemoveContainerRequest{ diff --git a/pkg/metricprovider/custom_metric_provider.go b/pkg/metricprovider/custom_metric_provider.go index 3081a17fb..806058b3c 100644 --- a/pkg/metricprovider/custom_metric_provider.go +++ b/pkg/metricprovider/custom_metric_provider.go @@ -89,7 +89,7 @@ func (p *CustomMetricProvider) GetMetricBySelector(ctx context.Context, namespac readyPods := GetReadyPods(pods) if len(readyPods) == 0 { - return nil, fmt.Errorf("Failed to get ready pods. ") + return nil, fmt.Errorf("failed to get ready pods. ") } isPredicting := false @@ -130,7 +130,7 @@ func (p *CustomMetricProvider) GetMetricBySelector(ctx context.Context, namespac valueFloat, err := strconv.ParseFloat(v.Value, 32) if err != nil { - return nil, fmt.Errorf("Failed to parse value to float: %v ", err) + return nil, fmt.Errorf("failed to parse value to float: %v ", err) } if valueFloat > largestMetricValue.value { largestMetricValue.value = valueFloat @@ -223,9 +223,9 @@ func (p *CustomMetricProvider) GetPrediction(ctx context.Context, namespace stri } err = p.client.List(ctx, predictionList, opts...) if err != nil { - return nil, fmt.Errorf("Failed to get TimeSeriesPrediction when get custom metric ") + return nil, fmt.Errorf("failed to get TimeSeriesPrediction when get custom metric ") } else if len(predictionList.Items) != 1 { - return nil, fmt.Errorf("Only one TimeSeriesPrediction should match the selector %s ", metricSelector.String()) + return nil, fmt.Errorf("only one TimeSeriesPrediction should match the selector %s ", metricSelector.String()) } return &predictionList.Items[0], nil @@ -245,7 +245,7 @@ func (p *CustomMetricProvider) GetPods(ctx context.Context, namespace string, se } err = p.client.List(ctx, podList, opts...) if err != nil || len(podList.Items) == 0 { - return nil, fmt.Errorf("Failed to get pods when get custom metric ") + return nil, fmt.Errorf("failed to get pods when get custom metric ") } return podList.Items, nil diff --git a/pkg/metricprovider/remote.go b/pkg/metricprovider/remote.go index 1d281745f..223b2a59f 100644 --- a/pkg/metricprovider/remote.go +++ b/pkg/metricprovider/remote.go @@ -38,7 +38,7 @@ func NewRemoteAdapter(namespace string, name string, port int, config *rest.Conf discoveryClientSet, err := discovery.NewDiscoveryClientForConfig(metricConfig) if err != nil { - return nil, fmt.Errorf("Failed to create discovery client: %v ", err) + return nil, fmt.Errorf("failed to create discovery client: %v ", err) } apiVersionsGetter := cmClient.NewAvailableAPIsGetter(discoveryClientSet) @@ -94,7 +94,7 @@ func (p *RemoteAdapter) GetMetricByName(ctx context.Context, name types.Namespac kind, err := utils.KindForResource(info.GroupResource.Resource, p.restMapper) if err != nil { - return nil, fmt.Errorf("Failed to get kind for resource %s: %v ", info.GroupResource.Resource, err) + return nil, fmt.Errorf("failed to get kind for resource %s: %v ", info.GroupResource.Resource, err) } var object *v1beta2.MetricValue @@ -115,7 +115,7 @@ func (p *RemoteAdapter) GetMetricByName(ctx context.Context, name types.Namespac } if err != nil { - return nil, fmt.Errorf("Failed to get metric by name from remote: %v ", err) + return nil, fmt.Errorf("failed to get metric by name from remote: %v ", err) } return &custom_metrics.MetricValue{ @@ -142,7 +142,7 @@ func (p *RemoteAdapter) GetMetricBySelector(ctx context.Context, namespace strin kind, err := utils.KindForResource(info.GroupResource.Resource, p.restMapper) if err != nil { - return nil, fmt.Errorf("Failed to get kind for resource %s: %v ", info.GroupResource.Resource, err) + return nil, fmt.Errorf("failed to get kind for resource %s: %v ", info.GroupResource.Resource, err) } var objects *v1beta2.MetricValueList @@ -168,7 +168,7 @@ func (p *RemoteAdapter) GetMetricBySelector(ctx context.Context, namespace strin ) } if err != nil { - return nil, fmt.Errorf("Failed to get metric by selector from remote: %v ", err) + return nil, fmt.Errorf("failed to get metric by selector from remote: %v ", err) } values := make([]custom_metrics.MetricValue, len(objects.Items)) for i, v := range objects.Items { diff --git a/pkg/metrics/ensuarance.go b/pkg/metrics/ensuarance.go index 27c333e92..0fb4a925f 100644 --- a/pkg/metrics/ensuarance.go +++ b/pkg/metrics/ensuarance.go @@ -201,12 +201,12 @@ func RegisterCraneAgent() { // UpdateDurationFromStart records the duration of the step identified by the // label using start time func UpdateDurationFromStart(module string, stepName StepLabel, start time.Time) { - duration := time.Now().Sub(start) + duration := time.Since(start) UpdateDuration(module, stepName, duration) } func UpdateDurationFromStartWithSubComponent(module string, subComponent string, stepName StepLabel, start time.Time) { - duration := time.Now().Sub(start) + duration := time.Since(start) UpdateDurationWithSubComponent(module, subComponent, stepName, duration) } diff --git a/pkg/metrics/health.go b/pkg/metrics/health.go index a141b5a08..8cc143e40 100644 --- a/pkg/metrics/health.go +++ b/pkg/metrics/health.go @@ -72,7 +72,7 @@ func (hc *HealthCheck) ServeHTTP(w http.ResponseWriter, r *http.Request) { if now.After(lastActivity.Add(hc.activityTimeout)) { w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte(fmt.Sprintf("Error: last activity more %v ago", time.Now().Sub(lastActivity).String()))); err != nil { + if _, err := w.Write([]byte(fmt.Sprintf("Error: last activity more %v ago", time.Since(lastActivity).String()))); err != nil { klog.Errorf("Http write failed: %v", err) return } @@ -83,7 +83,7 @@ func (hc *HealthCheck) ServeHTTP(w http.ResponseWriter, r *http.Request) { if now.After(lastConfigUpdated.Add(hc.activityTimeout)) { w.WriteHeader(http.StatusInternalServerError) - if _, err := w.Write([]byte(fmt.Sprintf("Error: last config update more %v ago", time.Now().Sub(lastConfigUpdated).String()))); err != nil { + if _, err := w.Write([]byte(fmt.Sprintf("Error: last config update more %v ago", time.Since(lastConfigUpdated).String()))); err != nil { klog.Errorf("Http write failed: %v", err) return } diff --git a/pkg/metrics/tsp_metric_collector.go b/pkg/metrics/tsp_metric_collector.go index 13b5e9c79..9d03e9a29 100644 --- a/pkg/metrics/tsp_metric_collector.go +++ b/pkg/metrics/tsp_metric_collector.go @@ -153,9 +153,7 @@ func metricSelectorToQueryExpr(m *predictionapi.MetricQuery) string { conditions := make([]string, 0, len(m.QueryConditions)) for _, cond := range m.QueryConditions { values := make([]string, 0, len(cond.Value)) - for _, val := range cond.Value { - values = append(values, val) - } + values = append(values, cond.Value...) sort.Strings(values) conditions = append(conditions, fmt.Sprintf("%s%s[%s]", cond.Key, cond.Operator, strings.Join(values, ","))) } diff --git a/pkg/prediction/config/config.go b/pkg/prediction/config/config.go index e7ebdb48c..7c906d18e 100644 --- a/pkg/prediction/config/config.go +++ b/pkg/prediction/config/config.go @@ -14,9 +14,7 @@ func metricSelectorToQueryExpr(m *predictionapi.MetricQuery) string { conditions := make([]string, 0, len(m.QueryConditions)) for _, cond := range m.QueryConditions { values := make([]string, 0, len(cond.Value)) - for _, val := range cond.Value { - values = append(values, val) - } + values = append(values, cond.Value...) sort.Strings(values) conditions = append(conditions, fmt.Sprintf("%s%s[%s]", cond.Key, cond.Operator, strings.Join(values, ","))) } diff --git a/pkg/prediction/dsp/estimators_test.go b/pkg/prediction/dsp/estimators_test.go index 0685e32ba..f0a7f923b 100644 --- a/pkg/prediction/dsp/estimators_test.go +++ b/pkg/prediction/dsp/estimators_test.go @@ -47,7 +47,7 @@ func TestFftEstimator_GetEstimation(t *testing.T) { charts.WithInitializationOpts(opts.Initialization{Width: "3000px", Theme: types.ThemeWonderland})) line.SetXAxis(x) - var colors []string = []string{"black", "blue", "green"} + var colors = []string{"black", "blue", "green"} for i := 0; i < 3; i++ { y := make([]opts.LineData, 0) @@ -65,6 +65,7 @@ func TestFftEstimator_GetEstimation(t *testing.T) { http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { if err := components.NewPage().AddCharts(line).Render(w); err != nil { // nothing to do + t.Error(err) } }) fmt.Println("Open your browser and access 'http://localhost:7001'") diff --git a/pkg/prediction/dsp/frequency_spectrum_test.go b/pkg/prediction/dsp/frequency_spectrum_test.go index b401d1254..934f63535 100644 --- a/pkg/prediction/dsp/frequency_spectrum_test.go +++ b/pkg/prediction/dsp/frequency_spectrum_test.go @@ -63,7 +63,7 @@ func TestSignal_Period(t *testing.T) { assert.NoError(t, err) assert.InEpsilon(t, expected[i], normalized.Frequencies()[0], epsilon) - lines = append(lines, s.Plot()) + lines = append(lines, s.Plot()) //nolint // SA4010: this result of append is never used, except maybe in other appends } /* diff --git a/pkg/prediction/dsp/signal.go b/pkg/prediction/dsp/signal.go index 739fd4367..7705dc2e8 100644 --- a/pkg/prediction/dsp/signal.go +++ b/pkg/prediction/dsp/signal.go @@ -135,7 +135,7 @@ func (s *Signal) Filter(threshold float64) *Signal { var frequencies []float64 for k := range X { // Calculate which frequencies the spectrum contains - frequencies = append(frequencies, float64(k)*s.SampleRate/sampleLength) + frequencies = append(frequencies, float64(k)*s.SampleRate/sampleLength) //nolint // SA4010: this result of append is never used, except maybe in other appends } for k := range X { diff --git a/pkg/prediction/percentile/prediction.go b/pkg/prediction/percentile/prediction.go index c4062fb41..0079e9501 100644 --- a/pkg/prediction/percentile/prediction.go +++ b/pkg/prediction/percentile/prediction.go @@ -125,7 +125,7 @@ func (p *percentilePrediction) QueryRealtimePredictedValues(ctx context.Context, return p.getPredictedValues(ctx, namer), nil } -// once task, it is only called once then caller will delete the query after call, but this query maybe used by other callers, +// QueryRealtimePredictedValuesOnce once task, it is only called once then caller will delete the query after call, but this query maybe used by other callers, // so when there has already registered this namer query, we get the estimated value from the model directly. // when there is no this namer query in state, we fetch history data to recover the histogram model then get the estimated value by a stateless function as data processing way. func (p *percentilePrediction) QueryRealtimePredictedValuesOnce(ctx context.Context, namer metricnaming.MetricNamer, config config.Config) ([]*common.TimeSeries, error) { @@ -144,7 +144,7 @@ func (p *percentilePrediction) QueryRealtimePredictedValuesOnce(ctx context.Cont key := "__all__" signal := signals[key] if signal == nil { - return nil, fmt.Errorf("No signal key %v found", key) + return nil, fmt.Errorf("no signal key %v found", key) } sample := common.Sample{ Value: estimator.GetEstimation(signal.histogram), @@ -231,7 +231,7 @@ func (p *percentilePrediction) process(namer metricnaming.MetricNamer, config co if cfg.aggregated { signal := signals[keyAll] if signal == nil { - return nil, fmt.Errorf("No signal key %v found", keyAll) + return nil, fmt.Errorf("no signal key %v found", keyAll) } sample := common.Sample{ Value: estimator.GetEstimation(signal.histogram), diff --git a/pkg/providers/metricserver/rest_metric_client.go b/pkg/providers/metricserver/rest_metric_client.go index 6affbad00..acc8af287 100644 --- a/pkg/providers/metricserver/rest_metric_client.go +++ b/pkg/providers/metricserver/rest_metric_client.go @@ -141,8 +141,7 @@ func (c *resourceMetricsClient) workloadMetric(metric *metricquery.Metric) (Reso return nil, time.Time{}, fmt.Errorf("no metrics returned from resource metrics API") } - var res ResourceMetricInfo - res = getWorkloadMetrics(v1.ResourceName(metric.MetricName), metrics.Items) + res := getWorkloadMetrics(v1.ResourceName(metric.MetricName), metrics.Items) timestamp := metrics.Items[0].Timestamp.Time return res, timestamp, nil } @@ -159,8 +158,7 @@ func (c *resourceMetricsClient) containerMetric(metric *metricquery.Metric) (Res return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err) } - var res ResourceMetricInfo - res = getContainerMetrics(v1.ResourceName(metric.MetricName), podMetrics, container.ContainerName) + res := getContainerMetrics(v1.ResourceName(metric.MetricName), podMetrics, container.ContainerName) if err != nil { return nil, time.Time{}, err } @@ -179,8 +177,7 @@ func (c *resourceMetricsClient) podMetric(metric *metricquery.Metric) (ResourceM return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err) } - var res ResourceMetricInfo - res = getPodMetrics(v1.ResourceName(metric.MetricName), podMetrics) + res := getPodMetrics(v1.ResourceName(metric.MetricName), podMetrics) timestamp := podMetrics.Timestamp.Time return res, timestamp, nil } @@ -196,8 +193,7 @@ func (c *resourceMetricsClient) nodeMetric(metric *metricquery.Metric) (Resource return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err) } - var res ResourceMetricInfo - res = getNodeMetrics(v1.ResourceName(metric.MetricName), metrics) + res := getNodeMetrics(v1.ResourceName(metric.MetricName), metrics) if err != nil { return nil, time.Time{}, err } diff --git a/pkg/recommend/advisor/ehpa.go b/pkg/recommend/advisor/ehpa.go index 0d90aa37d..01035a3fd 100644 --- a/pkg/recommend/advisor/ehpa.go +++ b/pkg/recommend/advisor/ehpa.go @@ -182,7 +182,7 @@ func (a *EHPAAdvisor) checkMinCpuUsageThreshold(cpuMax float64) error { klog.V(4).Infof("EHPAAdvisor checkMinCpuUsageThreshold, cpuMax %f threshold %f", cpuMax, minCpuUsageThreshold) if cpuMax < minCpuUsageThreshold { - return fmt.Errorf("Target cpuusage %f is under ehpa.min-cpu-usage-threshold %f. ", cpuMax, minCpuUsageThreshold) + return fmt.Errorf("target cpuusage %f is under ehpa.min-cpu-usage-threshold %f. ", cpuMax, minCpuUsageThreshold) } return nil @@ -236,12 +236,12 @@ func (a *EHPAAdvisor) checkFluctuation(medianMin, medianMax float64) error { } if medianMin == 0 { - return fmt.Errorf("Mean cpu usage is zero. ") + return fmt.Errorf("mean cpu usage is zero. ") } fluctuation := medianMax / medianMin if fluctuation < fluctuationThreshold { - return fmt.Errorf("Target cpu fluctuation %f is under ehpa.fluctuation-threshold %f. ", fluctuation, fluctuationThreshold) + return fmt.Errorf("target cpu fluctuation %f is under ehpa.fluctuation-threshold %f. ", fluctuation, fluctuationThreshold) } return nil diff --git a/pkg/recommend/inspector/workload.go b/pkg/recommend/inspector/workload.go index 2bf34a9d8..b34361fbc 100644 --- a/pkg/recommend/inspector/workload.go +++ b/pkg/recommend/inspector/workload.go @@ -28,24 +28,24 @@ func (i *WorkloadInspector) Inspect() error { } if i.Context.Deployment != nil && *i.Context.Deployment.Spec.Replicas < int32(deploymentMinReplicas) { - return fmt.Errorf("Deployment replicas %d should be larger than %d ", *i.Context.Deployment.Spec.Replicas, int32(deploymentMinReplicas)) + return fmt.Errorf("deployment replicas %d should be larger than %d ", *i.Context.Deployment.Spec.Replicas, int32(deploymentMinReplicas)) } if i.Context.StatefulSet != nil && *i.Context.StatefulSet.Spec.Replicas < int32(statefulsetMinReplicas) { - return fmt.Errorf("StatefulSet replicas %d should be larger than %d ", *i.Context.StatefulSet.Spec.Replicas, int32(statefulsetMinReplicas)) + return fmt.Errorf("statefulSet replicas %d should be larger than %d ", *i.Context.StatefulSet.Spec.Replicas, int32(statefulsetMinReplicas)) } if i.Context.Scale != nil && i.Context.Scale.Spec.Replicas < int32(workloadMinReplicas) { - return fmt.Errorf("Workload replicas %d should be larger than %d ", i.Context.Scale.Spec.Replicas, int32(workloadMinReplicas)) + return fmt.Errorf("workload replicas %d should be larger than %d ", i.Context.Scale.Spec.Replicas, int32(workloadMinReplicas)) } for _, container := range i.Context.PodTemplate.Spec.Containers { if container.Resources.Requests.Cpu() == nil { - return fmt.Errorf("Container %s resource cpu request is empty ", container.Name) + return fmt.Errorf("container %s resource cpu request is empty ", container.Name) } if container.Resources.Limits.Cpu() == nil { - return fmt.Errorf("Container %s resource cpu limit is empty ", container.Name) + return fmt.Errorf("container %s resource cpu limit is empty ", container.Name) } } diff --git a/pkg/recommend/inspector/workload_pods.go b/pkg/recommend/inspector/workload_pods.go index ac6ba104d..7981fdc3f 100644 --- a/pkg/recommend/inspector/workload_pods.go +++ b/pkg/recommend/inspector/workload_pods.go @@ -18,7 +18,7 @@ type WorkloadPodsInspector struct { func (i *WorkloadPodsInspector) Inspect() error { if len(i.Pods) == 0 { - return fmt.Errorf("Existing pods should be larger than 0 ") + return fmt.Errorf("existing pods should be larger than 0 ") } podMinReadySeconds, err := strconv.ParseInt(i.Context.ConfigProperties["ehpa.pod-min-ready-seconds"], 10, 32) @@ -39,12 +39,12 @@ func (i *WorkloadPodsInspector) Inspect() error { } if readyPods == 0 { - return fmt.Errorf("Pod available number must larger than zero. ") + return fmt.Errorf("pod available number must larger than zero. ") } availableRatio := float64(readyPods) / float64(len(i.Pods)) if availableRatio < podAvailableRatio { - return fmt.Errorf("Pod available ratio is %.3f less than %.3f ", availableRatio, podAvailableRatio) + return fmt.Errorf("pod available ratio is %.3f less than %.3f ", availableRatio, podAvailableRatio) } i.Context.ReadyPodNumber = readyPods diff --git a/pkg/resource/pod_resource_manger.go b/pkg/resource/pod_resource_manger.go index 6b8e136e3..0a5afc3ee 100644 --- a/pkg/resource/pod_resource_manger.go +++ b/pkg/resource/pod_resource_manger.go @@ -125,12 +125,12 @@ func (o *PodResourceManager) reconcilePod(obj interface{}) { if !ok { tombstone, ok := obj.(cache.DeletedFinalStateUnknown) if !ok { - utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) return } pod, ok = tombstone.Obj.(*v1.Pod) if !ok { - utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a pod %#v", obj)) + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a pod %#v", obj)) return } } @@ -164,6 +164,9 @@ func (o *PodResourceManager) updatePodExtResToCgroup(pod *v1.Pod) { // If container's quota is -1, pod resource manager will convert limit to quota containerCPUQuota, err := executor.GetUsageById(containerCPUQuotas, containerId) + if err != nil { + klog.Error(err) + } if !utils.AlmostEqual(containerCPUQuota.Value, -1.0) && !utils.AlmostEqual(containerCPUQuota.Value, 0) { continue } diff --git a/pkg/utils/pod.go b/pkg/utils/pod.go index 836f7a8b4..123aa84a7 100644 --- a/pkg/utils/pod.go +++ b/pkg/utils/pod.go @@ -72,7 +72,7 @@ func GetPodCondition(status *v1.PodStatus, conditionType v1.PodConditionType) (i // EvictPodWithGracePeriod evict pod with grace period func EvictPodWithGracePeriod(client clientset.Interface, pod *v1.Pod, gracePeriodSeconds *int32) error { if kubelettypes.IsCriticalPod(pod) { - return fmt.Errorf("Eviction manager: cannot evict a critical pod(%s)", klog.KObj(pod)) + return fmt.Errorf("eviction manager: cannot evict a critical pod(%s)", klog.KObj(pod)) } var grace = GetInt64withDefault(pod.Spec.TerminationGracePeriodSeconds, known.DefaultDeletionGracePeriodSeconds) diff --git a/pkg/utils/pod_template.go b/pkg/utils/pod_template.go index 242d28241..f0f6800ce 100644 --- a/pkg/utils/pod_template.go +++ b/pkg/utils/pod_template.go @@ -46,17 +46,17 @@ func GetPodTemplate(context context.Context, namespace string, name string, kind template, found, err := unstructured.NestedMap(unstructed.Object, "spec", "template") if !found || err != nil { - return nil, fmt.Errorf("Get template from unstructed object %s failed. ", klog.KObj(unstructed)) + return nil, fmt.Errorf("get template from unstructed object %s failed. ", klog.KObj(unstructed)) } templateBytes, err := json.Marshal(template) if err != nil { - return nil, fmt.Errorf("Marshal unstructed object failed: %v. ", err) + return nil, fmt.Errorf("marshal unstructed object failed: %v. ", err) } err = json.Unmarshal(templateBytes, templateSpec) if err != nil { - return nil, fmt.Errorf("Unmarshal template bytes failed: %v. ", err) + return nil, fmt.Errorf("unmarshal template bytes failed: %v. ", err) } } diff --git a/pkg/utils/target/fetcher.go b/pkg/utils/target/fetcher.go index 172d1cf45..e1983888e 100644 --- a/pkg/utils/target/fetcher.go +++ b/pkg/utils/target/fetcher.go @@ -71,7 +71,7 @@ func (f *targetSelectorFetcher) Fetch(target *corev1.ObjectReference) (labels.Se selector, err := f.getLabelSelectorFromScale(groupKind, target.Namespace, target.Name) if err != nil { - return nil, fmt.Errorf("Unhandled targetRef %+v, error: %v", *target, err) + return nil, fmt.Errorf("unhandled targetRef %+v, error: %v", *target, err) } return selector, nil } @@ -144,7 +144,7 @@ func (f *targetSelectorFetcher) getLabelSelectorFromScale(groupKind schema.Group scale, err := f.ScaleClient.Scales(namespace).Get(context.TODO(), groupResource, name, metav1.GetOptions{}) if err == nil { if scale.Status.Selector == "" { - return nil, fmt.Errorf("Resource %s/%s has an empty selector for scale sub-resource", namespace, name) + return nil, fmt.Errorf("resource %s/%s has an empty selector for scale sub-resource", namespace, name) } selector, err := labels.Parse(scale.Status.Selector) if err != nil { diff --git a/pkg/webhooks/analytics/validating.go b/pkg/webhooks/analytics/validating.go index 3f0305993..a90953dff 100644 --- a/pkg/webhooks/analytics/validating.go +++ b/pkg/webhooks/analytics/validating.go @@ -21,7 +21,7 @@ type ValidationAdmission struct { func (p *ValidationAdmission) Default(ctx context.Context, req runtime.Object) error { analytics, ok := req.(*analysisv1alph1.Analytics) if !ok { - return fmt.Errorf("Failed to convert req to Analytics. ") + return fmt.Errorf("failed to convert req to Analytics. ") } Default(analytics) @@ -32,7 +32,7 @@ func (p *ValidationAdmission) Default(ctx context.Context, req runtime.Object) e func (p *ValidationAdmission) ValidateCreate(ctx context.Context, req runtime.Object) error { analytics, ok := req.(*analysisv1alph1.Analytics) if !ok { - return fmt.Errorf("Failed to convert req to Analytics. ") + return fmt.Errorf("failed to convert req to Analytics. ") } klog.V(4).Info("validate create object %s", klog.KObj(analytics)) diff --git a/pkg/webhooks/prediction/validating.go b/pkg/webhooks/prediction/validating.go index 967428cd0..bf843d8fc 100644 --- a/pkg/webhooks/prediction/validating.go +++ b/pkg/webhooks/prediction/validating.go @@ -23,7 +23,7 @@ func (p *ValidationAdmission) ValidateCreate(ctx context.Context, req runtime.Ob tsp, ok := req.(*predictionapi.TimeSeriesPrediction) if ok { if tsp.Spec.TargetRef.Name == "" { - return fmt.Errorf("Need TargetRef.Name") + return fmt.Errorf("need TargetRef.Name") } if tsp.Spec.PredictionWindowSeconds < 3600 { return fmt.Errorf("PredictionWindowSeconds at least 3600") diff --git a/pkg/webhooks/recommendation/validating.go b/pkg/webhooks/recommendation/validating.go index e0d0bcaaf..36903f7c8 100644 --- a/pkg/webhooks/recommendation/validating.go +++ b/pkg/webhooks/recommendation/validating.go @@ -21,7 +21,7 @@ type ValidationAdmission struct { func (p *ValidationAdmission) Default(ctx context.Context, req runtime.Object) error { recommendation, ok := req.(*analysisv1alph1.Recommendation) if !ok { - return fmt.Errorf("Failed to convert req to Recommendation. ") + return fmt.Errorf("failed to convert req to Recommendation. ") } Default(recommendation) @@ -32,7 +32,7 @@ func (p *ValidationAdmission) Default(ctx context.Context, req runtime.Object) e func (p *ValidationAdmission) ValidateCreate(ctx context.Context, req runtime.Object) error { recommendation, ok := req.(*analysisv1alph1.Recommendation) if !ok { - return fmt.Errorf("Failed to convert req to Recommendation. ") + return fmt.Errorf("failed to convert req to Recommendation. ") } klog.V(4).Info("validate create object %s", klog.KObj(recommendation)) From 37c788261f7d1279bc0a27d42787e4509f0b1f42 Mon Sep 17 00:00:00 2001 From: qmhu Date: Mon, 25 Apr 2022 21:22:21 +0800 Subject: [PATCH 33/41] add predictable for hpa recommendation --- pkg/recommend/advisor/ehpa.go | 37 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/pkg/recommend/advisor/ehpa.go b/pkg/recommend/advisor/ehpa.go index d686bc7d7..863fc5294 100644 --- a/pkg/recommend/advisor/ehpa.go +++ b/pkg/recommend/advisor/ehpa.go @@ -37,6 +37,11 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { return fmt.Errorf("predictor %v not found", predictionapi.AlgorithmTypeDSP) } + predictableEnabled, err := strconv.ParseBool(a.Context.ConfigProperties["ehpa.predictable"]) + if err != nil { + predictableEnabled = false + } + resourceCpu := corev1.ResourceCPU target := a.Recommendation.Spec.TargetRef.DeepCopy() if len(target.Namespace) == 0 { @@ -61,6 +66,7 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { return fmt.Errorf("EHPAAdvisor query historic metrics data is unexpected, List length is %d ", len(tsList)) } + predictable := true cpuConfig := getPredictionCpuConfig() tsListPrediction, err := utils.QueryPredictedTimeSeriesOnce(p, fmt.Sprintf(callerFormat, a.Recommendation.UID), getPredictionCpuConfig(), @@ -68,11 +74,17 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { timeNow, timeNow.Add(time.Hour*24*7)) if err != nil { - return fmt.Errorf("EHPAAdvisor query predicted time series failed: %v ", err) + klog.Warningf("EHPAAdvisor query predicted time series failed: %v ", err) + predictable = false } if len(tsListPrediction) != 1 { - return fmt.Errorf("EHPAAdvisor prediction metrics data is unexpected, List length is %d ", len(tsListPrediction)) + klog.Warningf("EHPAAdvisor prediction metrics data is unexpected, List length is %d ", len(tsListPrediction)) + predictable = false + } + + if predictableEnabled && !predictable { + return fmt.Errorf("EHPAAdvisor cannot predict target: %v ", err) } var cpuMax float64 @@ -85,10 +97,12 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { } } - for _, sample := range tsListPrediction[0].Samples { - cpuUsages = append(cpuUsages, sample.Value) - if sample.Value > cpuMax { - cpuMax = sample.Value + if predictable && predictableEnabled { + for _, sample := range tsListPrediction[0].Samples { + cpuUsages = append(cpuUsages, sample.Value) + if sample.Value > cpuMax { + cpuMax = sample.Value + } } } @@ -97,7 +111,7 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { return fmt.Errorf("EHPAAdvisor checkMinCpuUsageThreshold failed: %v", err) } - medianMin, medianMax, err := a.minMaxMedians(tsListPrediction) + medianMin, medianMax, err := a.minMaxMedians(tsList) if err != nil { return fmt.Errorf("EHPAAdvisor minMaxMedians failed: %v", err) } @@ -138,18 +152,21 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { }, }, }, - Prediction: &autoscalingapi.Prediction{ + } + + if predictable { + proposedEHPA.Prediction = &autoscalingapi.Prediction{ PredictionWindowSeconds: &defaultPredictionWindow, PredictionAlgorithm: &autoscalingapi.PredictionAlgorithm{ AlgorithmType: predictionapi.AlgorithmTypeDSP, DSP: cpuConfig.DSP, }, - }, + } } referenceHpa, err := strconv.ParseBool(a.Context.ConfigProperties["ehpa.reference-hpa"]) if err != nil { - return err + referenceHpa = false } // get metric spec from existing hpa and use them From ef13266cacec5edbb7c029bbe652f65916a15f35 Mon Sep 17 00:00:00 2001 From: qmhu Date: Mon, 25 Apr 2022 23:17:21 +0800 Subject: [PATCH 34/41] Update ehpa.go --- pkg/recommend/advisor/ehpa.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/recommend/advisor/ehpa.go b/pkg/recommend/advisor/ehpa.go index d7036d88b..8af654d60 100644 --- a/pkg/recommend/advisor/ehpa.go +++ b/pkg/recommend/advisor/ehpa.go @@ -98,7 +98,7 @@ func (a *EHPAAdvisor) Advise(proposed *types.ProposedRecommendation) error { } } - if predictable && predictableEnabled { + if predictable { for _, sample := range tsListPrediction[0].Samples { cpuUsages = append(cpuUsages, sample.Value) if sample.Value > cpuMax { From 59deb960f58a260391128c1e51f1f190217cc334 Mon Sep 17 00:00:00 2001 From: kitianFresh <1549722424@qq.com> Date: Tue, 26 Apr 2022 12:40:28 +0800 Subject: [PATCH 35/41] add workload selector for evpa --- cmd/craned/app/manager.go | 14 +-- pkg/autoscaling/estimator/estimator.go | 12 ++- pkg/autoscaling/estimator/percentile.go | 94 ++++++++++++++----- pkg/controller/evpa/container_policy.go | 10 +- .../evpa/effective_vpa_controller.go | 4 +- pkg/metricquery/type.go | 8 +- pkg/prediction/dsp/prediction.go | 19 ++-- pkg/prediction/generic.go | 16 +--- pkg/prediction/percentile/prediction.go | 17 +++- .../metricserver/rest_metric_client.go | 83 ++++++++-------- .../metricserver/builder_test.go | 8 +- 11 files changed, 175 insertions(+), 110 deletions(-) diff --git a/cmd/craned/app/manager.go b/cmd/craned/app/manager.go index f8ba3c739..4350c0c58 100644 --- a/cmd/craned/app/manager.go +++ b/cmd/craned/app/manager.go @@ -210,6 +210,8 @@ func initializationControllers(ctx context.Context, mgr ctrl.Manager, opts *opti scaleKindResolver, ) + targetSelectorFetcher := target.NewSelectorFetcher(mgr.GetScheme(), mgr.GetRESTMapper(), scaleClient, mgr.GetClient()) + podOOMRecorder := &oom.PodOOMRecorder{ Client: mgr.GetClient(), } @@ -254,17 +256,17 @@ func initializationControllers(ctx context.Context, mgr ctrl.Manager, opts *opti } if err := (&evpa.EffectiveVPAController{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Recorder: mgr.GetEventRecorderFor("effective-vpa-controller"), - OOMRecorder: podOOMRecorder, - Predictor: predictorMgr.GetPredictor(predictionapi.AlgorithmTypePercentile), + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Recorder: mgr.GetEventRecorderFor("effective-vpa-controller"), + OOMRecorder: podOOMRecorder, + Predictor: predictorMgr.GetPredictor(predictionapi.AlgorithmTypePercentile), + TargetFetcher: targetSelectorFetcher, }).SetupWithManager(mgr); err != nil { klog.Exit(err, "unable to create controller", "controller", "EffectiveVPAController") } } - targetSelectorFetcher := target.NewSelectorFetcher(mgr.GetScheme(), mgr.GetRESTMapper(), scaleClient, mgr.GetClient()) // TspController if utilfeature.DefaultFeatureGate.Enabled(features.CraneTimeSeriesPrediction) { tspController := timeseriesprediction.NewController( diff --git a/pkg/autoscaling/estimator/estimator.go b/pkg/autoscaling/estimator/estimator.go index 6ae8308d0..5269b3f38 100644 --- a/pkg/autoscaling/estimator/estimator.go +++ b/pkg/autoscaling/estimator/estimator.go @@ -11,6 +11,7 @@ import ( "github.com/gocrane/crane/pkg/oom" "github.com/gocrane/crane/pkg/prediction" + "github.com/gocrane/crane/pkg/utils/target" ) // ResourceEstimatorManager controls how to get or delete estimators for EffectiveVPA @@ -30,18 +31,19 @@ type estimatorManager struct { estimatorMap map[string]ResourceEstimator } -func NewResourceEstimatorManager(client client.Client, oomRecorder oom.Recorder, predictor prediction.Interface) ResourceEstimatorManager { +func NewResourceEstimatorManager(client client.Client, fetcher target.SelectorFetcher, oomRecorder oom.Recorder, predictor prediction.Interface) ResourceEstimatorManager { resourceEstimatorManager := &estimatorManager{ estimatorMap: make(map[string]ResourceEstimator), } - resourceEstimatorManager.buildEstimators(client, oomRecorder, predictor) + resourceEstimatorManager.buildEstimators(client, fetcher, oomRecorder, predictor) return resourceEstimatorManager } -func (m *estimatorManager) buildEstimators(client client.Client, oomRecorder oom.Recorder, predictor prediction.Interface) { +func (m *estimatorManager) buildEstimators(client client.Client, fetcher target.SelectorFetcher, oomRecorder oom.Recorder, predictor prediction.Interface) { percentileEstimator := &PercentileResourceEstimator{ - Predictor: predictor, - Client: client, + Predictor: predictor, + Client: client, + TargetFetcher: fetcher, } m.registerEstimator("Percentile", percentileEstimator) oomEstimator := &OOMResourceEstimator{ diff --git a/pkg/autoscaling/estimator/percentile.go b/pkg/autoscaling/estimator/percentile.go index 1751ba4b8..dd6e98378 100644 --- a/pkg/autoscaling/estimator/percentile.go +++ b/pkg/autoscaling/estimator/percentile.go @@ -1,11 +1,11 @@ package estimator import ( + "context" "fmt" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/labels" "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/client" @@ -16,19 +16,29 @@ import ( "github.com/gocrane/crane/pkg/metricquery" "github.com/gocrane/crane/pkg/prediction" predictionconfig "github.com/gocrane/crane/pkg/prediction/config" - "github.com/gocrane/crane/pkg/utils" + "github.com/gocrane/crane/pkg/utils/target" ) const callerFormat = "EVPACaller-%s-%s" type PercentileResourceEstimator struct { - Predictor prediction.Interface - Client client.Client + Predictor prediction.Interface + Client client.Client + TargetFetcher target.SelectorFetcher } func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler, config map[string]string, containerName string, currRes *corev1.ResourceRequirements) (corev1.ResourceList, error) { recommendResource := corev1.ResourceList{} + selector, err := e.TargetFetcher.Fetch(&corev1.ObjectReference{ + APIVersion: evpa.Spec.TargetRef.APIVersion, + Kind: evpa.Spec.TargetRef.Kind, + Name: evpa.Spec.TargetRef.Name, + Namespace: evpa.Namespace, + }) + if err != nil { + klog.ErrorS(err, "Failed to fetch evpa target workload selector.", "evpa", klog.KObj(evpa)) + } caller := fmt.Sprintf(callerFormat, klog.KObj(evpa), string(evpa.UID)) cpuMetricNamer := &metricnaming.GeneralMetricNamer{ CallerName: caller, @@ -39,23 +49,12 @@ func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi Namespace: evpa.Namespace, WorkloadName: evpa.Spec.TargetRef.Name, ContainerName: containerName, - Selector: labels.Everything(), + Selector: selector, }, }, } cpuConfig := getCpuConfig(config) - tsList, err := utils.QueryPredictedValues(e.Predictor, caller, cpuConfig, cpuMetricNamer) - if err != nil { - return nil, err - } - - if len(tsList) < 1 || len(tsList[0].Samples) < 1 { - return nil, fmt.Errorf("no value retured for queryExpr: %s", cpuMetricNamer.BuildUniqueKey()) - } - - cpuValue := int64(tsList[0].Samples[0].Value * 1000) - recommendResource[corev1.ResourceCPU] = *resource.NewMilliQuantity(cpuValue, resource.DecimalSI) memoryMetricNamer := &metricnaming.GeneralMetricNamer{ CallerName: caller, @@ -66,28 +65,71 @@ func (e *PercentileResourceEstimator) GetResourceEstimation(evpa *autoscalingapi Namespace: evpa.Namespace, WorkloadName: evpa.Spec.TargetRef.Name, ContainerName: containerName, - Selector: labels.Everything(), + Selector: selector, }, }, } - memConfig := getMemConfig(config) - tsList, err = utils.QueryPredictedValues(e.Predictor, caller, memConfig, memoryMetricNamer) + + var errs []error + // first register cpu & memory, or the memory will be not registered before the cpu prediction succeed + err1 := e.Predictor.WithQuery(cpuMetricNamer, caller, *cpuConfig) + if err1 != nil { + errs = append(errs, err1) + } + err2 := e.Predictor.WithQuery(memoryMetricNamer, caller, *memConfig) + if err2 != nil { + errs = append(errs, err2) + } + if len(errs) > 0 { + return nil, fmt.Errorf("failed to register metricNamer: %v", errs) + } + + var predictErrs []error + var noValueErrs []error + tsList, err := e.Predictor.QueryRealtimePredictedValues(context.TODO(), cpuMetricNamer) + if err != nil { + predictErrs = append(predictErrs, err) + } + + if len(tsList) > 1 && len(tsList[0].Samples) > 1 { + cpuValue := int64(tsList[0].Samples[0].Value * 1000) + recommendResource[corev1.ResourceCPU] = *resource.NewMilliQuantity(cpuValue, resource.DecimalSI) + } else { + noValueErrs = append(noValueErrs, fmt.Errorf("no value retured for queryExpr: %s", cpuMetricNamer.BuildUniqueKey())) + } + + tsList, err = e.Predictor.QueryRealtimePredictedValues(context.TODO(), memoryMetricNamer) if err != nil { - return nil, err + predictErrs = append(predictErrs, err) } - if len(tsList) < 1 || len(tsList[0].Samples) < 1 { - return nil, fmt.Errorf("no value retured for queryExpr: %s", memoryMetricNamer.BuildUniqueKey()) + if len(tsList) > 1 && len(tsList[0].Samples) > 1 { + memValue := int64(tsList[0].Samples[0].Value) + recommendResource[corev1.ResourceMemory] = *resource.NewQuantity(memValue, resource.BinarySI) + } else { + noValueErrs = append(noValueErrs, fmt.Errorf("no value retured for queryExpr: %s", memoryMetricNamer.BuildUniqueKey())) } - memValue := int64(tsList[0].Samples[0].Value) - recommendResource[corev1.ResourceMemory] = *resource.NewQuantity(memValue, resource.BinarySI) + // all failed + if len(recommendResource) == 0 { + return recommendResource, fmt.Errorf("all resource predicted failed, predictErrs: %v, noValueErrs: %v", predictErrs, noValueErrs) + } + // at least one succeed return recommendResource, nil } func (e *PercentileResourceEstimator) DeleteEstimation(evpa *autoscalingapi.EffectiveVerticalPodAutoscaler) { + selector, err := e.TargetFetcher.Fetch(&corev1.ObjectReference{ + APIVersion: evpa.Spec.TargetRef.APIVersion, + Kind: evpa.Spec.TargetRef.Kind, + Name: evpa.Spec.TargetRef.Name, + Namespace: evpa.Namespace, + }) + if err != nil { + klog.ErrorS(err, "Failed to fetch evpa target workload selector.", "evpa", klog.KObj(evpa)) + } for _, containerPolicy := range evpa.Spec.ResourcePolicy.ContainerPolicies { caller := fmt.Sprintf(callerFormat, klog.KObj(evpa), string(evpa.UID)) cpuMetricNamer := &metricnaming.GeneralMetricNamer{ @@ -99,7 +141,7 @@ func (e *PercentileResourceEstimator) DeleteEstimation(evpa *autoscalingapi.Effe Namespace: evpa.Namespace, WorkloadName: evpa.Spec.TargetRef.Name, ContainerName: containerPolicy.ContainerName, - Selector: labels.Everything(), + Selector: selector, }, }, } @@ -116,7 +158,7 @@ func (e *PercentileResourceEstimator) DeleteEstimation(evpa *autoscalingapi.Effe Namespace: evpa.Namespace, WorkloadName: evpa.Spec.TargetRef.Name, ContainerName: containerPolicy.ContainerName, - Selector: labels.Everything(), + Selector: selector, }, }, } diff --git a/pkg/controller/evpa/container_policy.go b/pkg/controller/evpa/container_policy.go index b44388a3f..61ad2bc1a 100644 --- a/pkg/controller/evpa/container_policy.go +++ b/pkg/controller/evpa/container_policy.go @@ -191,11 +191,17 @@ func GetScaleEventKey(namespace string, workload string, container string, direc // UpdateRecommendStatus update recommend resource func UpdateRecommendStatus(recommendation *vpatypes.RecommendedPodResources, containerName string, recommendResource corev1.ResourceList) { + if recommendation == nil { + recommendation = &vpatypes.RecommendedPodResources{ + ContainerRecommendations: make([]vpatypes.RecommendedContainerResources, 0), + } + } for i := range recommendation.ContainerRecommendations { if recommendation.ContainerRecommendations[i].ContainerName == containerName { ResourceWithTolerance(recommendResource, recommendation.ContainerRecommendations[i].Target) - recommendation.ContainerRecommendations[i].Target = recommendResource - + for resource, quantity := range recommendResource { + recommendation.ContainerRecommendations[i].Target[resource] = quantity + } return } } diff --git a/pkg/controller/evpa/effective_vpa_controller.go b/pkg/controller/evpa/effective_vpa_controller.go index 6056ff2d8..d8e59c802 100644 --- a/pkg/controller/evpa/effective_vpa_controller.go +++ b/pkg/controller/evpa/effective_vpa_controller.go @@ -23,6 +23,7 @@ import ( "github.com/gocrane/crane/pkg/oom" "github.com/gocrane/crane/pkg/prediction" "github.com/gocrane/crane/pkg/utils" + "github.com/gocrane/crane/pkg/utils/target" ) // EffectiveVPAController is responsible for scaling workload's replica based on EffectiveVerticalPodAutoscaler spec @@ -34,6 +35,7 @@ type EffectiveVPAController struct { EstimatorManager estimator.ResourceEstimatorManager lastScaleTime map[string]metav1.Time Predictor prediction.Interface + TargetFetcher target.SelectorFetcher mu sync.Mutex } @@ -146,7 +148,7 @@ func (c *EffectiveVPAController) UpdateStatus(ctx context.Context, evpa *autosca } func (c *EffectiveVPAController) SetupWithManager(mgr ctrl.Manager) error { - estimatorManager := estimator.NewResourceEstimatorManager(mgr.GetClient(), c.OOMRecorder, c.Predictor) + estimatorManager := estimator.NewResourceEstimatorManager(mgr.GetClient(), c.TargetFetcher, c.OOMRecorder, c.Predictor) c.EstimatorManager = estimatorManager return ctrl.NewControllerManagedBy(mgr). For(&autoscalingapi.EffectiveVerticalPodAutoscaler{}). diff --git a/pkg/metricquery/type.go b/pkg/metricquery/type.go index e5f24adae..bc75dc2a1 100644 --- a/pkg/metricquery/type.go +++ b/pkg/metricquery/type.go @@ -54,7 +54,8 @@ type WorkloadNamerInfo struct { Kind string Name string APIVersion string - Selector labels.Selector + // used to fetch workload pods and containers, when use metric server, it is required + Selector labels.Selector } type ContainerNamerInfo struct { @@ -62,9 +63,9 @@ type ContainerNamerInfo struct { WorkloadName string Kind string APIVersion string - PodName string ContainerName string - Selector labels.Selector + // used to fetch workload pods and containers, when use metric server, it is required + Selector labels.Selector } type PodNamerInfo struct { @@ -166,7 +167,6 @@ func (m *Metric) keyByContainer() string { strings.ToLower(m.MetricName), m.Container.Namespace, m.Container.WorkloadName, - m.Container.PodName, m.Container.ContainerName, selectorStr}, "_") } diff --git a/pkg/prediction/dsp/prediction.go b/pkg/prediction/dsp/prediction.go index f4d9085b9..1aa86d587 100644 --- a/pkg/prediction/dsp/prediction.go +++ b/pkg/prediction/dsp/prediction.go @@ -30,9 +30,11 @@ const ( type periodicSignalPrediction struct { prediction.GenericPrediction - a aggregateSignals - stopChMap sync.Map - modelConfig config.AlgorithmModelConfig + a aggregateSignals + stopChMap sync.Map + // record the query routine already started + queryRoutines sync.Map + modelConfig config.AlgorithmModelConfig } func (p *periodicSignalPrediction) QueryPredictionStatus(ctx context.Context, metricNamer metricnaming.MetricNamer) (prediction.Status, error) { @@ -45,6 +47,7 @@ func NewPrediction(realtimeProvider providers.RealTime, historyProvider provider GenericPrediction: prediction.NewGenericPrediction(realtimeProvider, historyProvider, withCh, delCh), a: newAggregateSignals(), stopChMap: sync.Map{}, + queryRoutines: sync.Map{}, modelConfig: mc, } } @@ -159,11 +162,13 @@ func (p *periodicSignalPrediction) Run(stopCh <-chan struct{}) { for { // Waiting for a WithQuery request qc := <-p.WithCh - if !p.a.Add(qc) { + // update if the query config updated, idempotent + p.a.Add(qc) + QueryExpr := qc.MetricNamer.BuildUniqueKey() + + if _, ok := p.queryRoutines.Load(QueryExpr); ok { continue } - - QueryExpr := qc.MetricNamer.BuildUniqueKey() if _, ok := p.stopChMap.Load(QueryExpr); ok { continue } @@ -171,6 +176,7 @@ func (p *periodicSignalPrediction) Run(stopCh <-chan struct{}) { go func(namer metricnaming.MetricNamer) { queryExpr := namer.BuildUniqueKey() + p.queryRoutines.Store(queryExpr, struct{}{}) ticker := time.NewTicker(p.modelConfig.UpdateInterval) defer ticker.Stop() @@ -184,6 +190,7 @@ func (p *periodicSignalPrediction) Run(stopCh <-chan struct{}) { select { case <-predStopCh: + p.queryRoutines.Delete(queryExpr) klog.V(4).InfoS("Prediction routine stopped.", "queryExpr", queryExpr) return case <-ticker.C: diff --git a/pkg/prediction/generic.go b/pkg/prediction/generic.go index 79e420efe..aa105b2f3 100644 --- a/pkg/prediction/generic.go +++ b/pkg/prediction/generic.go @@ -40,8 +40,6 @@ type WithMetricEvent struct { type GenericPrediction struct { historyProvider providers.History realtimeProvider providers.RealTime - metricsMap map[string][]common.QueryCondition - querySet map[string]struct{} WithCh chan QueryExprWithCaller DelCh chan QueryExprWithCaller mutex sync.Mutex @@ -52,8 +50,6 @@ func NewGenericPrediction(realtimeProvider providers.RealTime, historyProvider p WithCh: withCh, DelCh: delCh, mutex: sync.Mutex{}, - metricsMap: map[string][]common.QueryCondition{}, - querySet: map[string]struct{}{}, realtimeProvider: realtimeProvider, historyProvider: historyProvider, } @@ -81,11 +77,8 @@ func (p *GenericPrediction) WithQuery(namer metricnaming.MetricNamer, caller str Config: config, } - if _, exists := p.querySet[q.String()]; !exists { - p.querySet[q.String()] = struct{}{} - klog.V(4).InfoS("Put tuple{query,caller,config} into with channel.", "query", q.MetricNamer.BuildUniqueKey(), "caller", q.Caller) - p.WithCh <- q - } + klog.V(4).InfoS("Put tuple{query,caller,config} into with channel.", "query", q.MetricNamer.BuildUniqueKey(), "caller", q.Caller) + p.WithCh <- q return nil } @@ -103,10 +96,7 @@ func (p *GenericPrediction) DeleteQuery(namer metricnaming.MetricNamer, caller s Caller: caller, } - if _, exists := p.querySet[q.String()]; exists { - delete(p.querySet, q.String()) - p.DelCh <- q - } + p.DelCh <- q return nil } diff --git a/pkg/prediction/percentile/prediction.go b/pkg/prediction/percentile/prediction.go index 0079e9501..b665d7bb5 100644 --- a/pkg/prediction/percentile/prediction.go +++ b/pkg/prediction/percentile/prediction.go @@ -19,8 +19,10 @@ var _ prediction.Interface = &percentilePrediction{} type percentilePrediction struct { prediction.GenericPrediction - a aggregateSignals - stopChMap sync.Map + a aggregateSignals + // record the query routine already started + queryRoutines sync.Map + stopChMap sync.Map } func (p *percentilePrediction) QueryPredictionStatus(ctx context.Context, metricNamer metricnaming.MetricNamer) (prediction.Status, error) { @@ -265,6 +267,7 @@ func NewPrediction(realtimeProvider providers.RealTime, historyProvider provider return &percentilePrediction{ GenericPrediction: prediction.NewGenericPrediction(realtimeProvider, historyProvider, withCh, delCh), a: newAggregateSignals(), + queryRoutines: sync.Map{}, stopChMap: sync.Map{}, } } @@ -273,11 +276,15 @@ func (p *percentilePrediction) Run(stopCh <-chan struct{}) { go func() { for { qc := <-p.WithCh - if !p.a.Add(qc) { + // update if the query config updated, idempotent + p.a.Add(qc) + + QueryExpr := qc.MetricNamer.BuildUniqueKey() + + if _, ok := p.queryRoutines.Load(QueryExpr); ok { continue } - QueryExpr := qc.MetricNamer.BuildUniqueKey() if _, ok := p.stopChMap.Load(QueryExpr); ok { continue } @@ -313,6 +320,7 @@ func (p *percentilePrediction) Run(stopCh <-chan struct{}) { // this is our default policy, one metric only has one config at a time. go func(namer metricnaming.MetricNamer) { queryExpr := namer.BuildUniqueKey() + p.queryRoutines.Store(queryExpr, struct{}{}) if c := p.a.GetConfig(queryExpr); c != nil { ticker := time.NewTicker(c.sampleInterval) defer ticker.Stop() @@ -324,6 +332,7 @@ func (p *percentilePrediction) Run(stopCh <-chan struct{}) { p.addSamples(namer) select { case <-predStopCh: + p.queryRoutines.Delete(queryExpr) klog.V(4).InfoS("Prediction routine stopped.", "queryExpr", queryExpr) return case <-ticker.C: diff --git a/pkg/providers/metricserver/rest_metric_client.go b/pkg/providers/metricserver/rest_metric_client.go index acc8af287..65379437a 100644 --- a/pkg/providers/metricserver/rest_metric_client.go +++ b/pkg/providers/metricserver/rest_metric_client.go @@ -132,7 +132,8 @@ func (c *resourceMetricsClient) workloadMetric(metric *metricquery.Metric) (Reso if workload.Selector != nil { selector = workload.Selector.String() } - metrics, err := c.client.PodMetricses(workload.Namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: selector}) + // use resourceVersion=0 to avoid traffic for apiserver to etcd + metrics, err := c.client.PodMetricses(workload.Namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: selector, ResourceVersion: "0"}) if err != nil { return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err) } @@ -141,8 +142,7 @@ func (c *resourceMetricsClient) workloadMetric(metric *metricquery.Metric) (Reso return nil, time.Time{}, fmt.Errorf("no metrics returned from resource metrics API") } - res := getWorkloadMetrics(v1.ResourceName(metric.MetricName), metrics.Items) - timestamp := metrics.Items[0].Timestamp.Time + res, timestamp := getWorkloadMetrics(v1.ResourceName(metric.MetricName), metrics.Items) return res, timestamp, nil } @@ -153,16 +153,23 @@ func (c *resourceMetricsClient) containerMetric(metric *metricquery.Metric) (Res return nil, time.Time{}, fmt.Errorf("metric ContainerNamerInfo is null") } - podMetrics, err := c.client.PodMetricses(container.Namespace).Get(context.TODO(), container.PodName, metav1.GetOptions{}) + selector := "" + if container.Selector != nil { + selector = container.Selector.String() + } + // now if we use workloadName info only, then we should first fetch workload pods by kube client, then use PodMetricses to get pods metrics + // each metric model's addSample will trigger this two listing. + // so we give the workload label selector directly to get pod metricses, use resourceVersion=0 to avoid traffic for apiserver to etcd + podMetrics, err := c.client.PodMetricses(container.Namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: selector, ResourceVersion: "0"}) if err != nil { return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err) } - res := getContainerMetrics(v1.ResourceName(metric.MetricName), podMetrics, container.ContainerName) - if err != nil { - return nil, time.Time{}, err + if len(podMetrics.Items) == 0 { + return nil, time.Time{}, fmt.Errorf("no metrics returned from resource metrics API") } - timestamp := podMetrics.Timestamp.Time + + res, timestamp := getContainerMetrics(v1.ResourceName(metric.MetricName), podMetrics.Items, container.ContainerName) return res, timestamp, nil } @@ -172,13 +179,12 @@ func (c *resourceMetricsClient) podMetric(metric *metricquery.Metric) (ResourceM return nil, time.Time{}, fmt.Errorf("metric PodNamerInfo is null") } - podMetrics, err := c.client.PodMetricses(pod.Namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{}) + podMetrics, err := c.client.PodMetricses(pod.Namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{ResourceVersion: "0"}) if err != nil { return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err) } - res := getPodMetrics(v1.ResourceName(metric.MetricName), podMetrics) - timestamp := podMetrics.Timestamp.Time + res, timestamp := getPodMetrics(v1.ResourceName(metric.MetricName), podMetrics) return res, timestamp, nil } @@ -193,40 +199,39 @@ func (c *resourceMetricsClient) nodeMetric(metric *metricquery.Metric) (Resource return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from resource metrics API: %v", err) } - res := getNodeMetrics(v1.ResourceName(metric.MetricName), metrics) - if err != nil { - return nil, time.Time{}, err - } - timestamp := metrics.Timestamp.Time + res, timestamp := getNodeMetrics(v1.ResourceName(metric.MetricName), metrics) return res, timestamp, nil } -func getContainerMetrics(resource v1.ResourceName, podMetric *metricsapi.PodMetrics, container string) ResourceMetricInfo { +func getContainerMetrics(resource v1.ResourceName, podMetricsList []metricsapi.PodMetrics, container string) (ResourceMetricInfo, time.Time) { res := make(ResourceMetricInfo, 0) var total int64 var timestamp metav1.Time var window metav1.Duration - timestamp = podMetric.Timestamp - window = podMetric.Window - for _, containerMetric := range podMetric.Containers { - if containerMetric.Name != container { - continue - } - if usage, ok := containerMetric.Usage[resource]; ok { - total += usage.MilliValue() + + for _, podMetric := range podMetricsList { + timestamp = podMetric.Timestamp + window = podMetric.Window + for _, containerMetric := range podMetric.Containers { + if containerMetric.Name != container { + continue + } + if usage, ok := containerMetric.Usage[resource]; ok { + total += usage.MilliValue() + } + // now workload has no labels for promql + res = append(res, ResourceMetric{ + Timestamp: timestamp.Time, + Window: window.Duration, + Value: float64(total) / 1000., + Labels: []common.Label{}, + }) } } - // now workload has no labels for promql - res = append(res, ResourceMetric{ - Timestamp: timestamp.Time, - Window: window.Duration, - Value: float64(total) / 1000., - Labels: []common.Label{}, - }) - return res + return res, timestamp.Time } -func getPodMetrics(resource v1.ResourceName, podMetric *metricsapi.PodMetrics) ResourceMetricInfo { +func getPodMetrics(resource v1.ResourceName, podMetric *metricsapi.PodMetrics) (ResourceMetricInfo, time.Time) { res := make(ResourceMetricInfo, 0) var total int64 var timestamp metav1.Time @@ -245,10 +250,10 @@ func getPodMetrics(resource v1.ResourceName, podMetric *metricsapi.PodMetrics) R Value: float64(total) / 1000., Labels: []common.Label{}, }) - return res + return res, timestamp.Time } -func getWorkloadMetrics(resource v1.ResourceName, podMetrics []metricsapi.PodMetrics) ResourceMetricInfo { +func getWorkloadMetrics(resource v1.ResourceName, podMetrics []metricsapi.PodMetrics) (ResourceMetricInfo, time.Time) { res := make(ResourceMetricInfo, 0) var total int64 var timestamp metav1.Time @@ -269,10 +274,10 @@ func getWorkloadMetrics(resource v1.ResourceName, podMetrics []metricsapi.PodMet Value: float64(total) / 1000., Labels: []common.Label{}, }) - return res + return res, timestamp.Time } -func getNodeMetrics(resource v1.ResourceName, nodeMetric *metricsapi.NodeMetrics) ResourceMetricInfo { +func getNodeMetrics(resource v1.ResourceName, nodeMetric *metricsapi.NodeMetrics) (ResourceMetricInfo, time.Time) { res := make(ResourceMetricInfo, 0) var total int64 var timestamp metav1.Time @@ -290,7 +295,7 @@ func getNodeMetrics(resource v1.ResourceName, nodeMetric *metricsapi.NodeMetrics Value: float64(total) / 1000., Labels: []common.Label{}, }) - return res + return res, timestamp.Time } func (cm *customMetricsClient) GetObjectMetric(metric *metricquery.Metric) (*customapi.MetricValue, time.Time, error) { diff --git a/pkg/querybuilder-providers/metricserver/builder_test.go b/pkg/querybuilder-providers/metricserver/builder_test.go index 56073e5d8..45211f601 100644 --- a/pkg/querybuilder-providers/metricserver/builder_test.go +++ b/pkg/querybuilder-providers/metricserver/builder_test.go @@ -90,7 +90,7 @@ func TestBuildQuery(t *testing.T) { Type: metricquery.ContainerMetricType, Container: &metricquery.ContainerNamerInfo{ Namespace: "default", - PodName: "pod-xxx", + WorkloadName: "workload-xxx", ContainerName: "container", }, }, @@ -100,7 +100,7 @@ func TestBuildQuery(t *testing.T) { Type: metricquery.ContainerMetricType, Container: &metricquery.ContainerNamerInfo{ Namespace: "default", - PodName: "pod-xxx", + WorkloadName: "workload-xxx", ContainerName: "container", }, }, @@ -113,7 +113,7 @@ func TestBuildQuery(t *testing.T) { Type: metricquery.ContainerMetricType, Container: &metricquery.ContainerNamerInfo{ Namespace: "default", - PodName: "pod-xxx", + WorkloadName: "workload-xxx", ContainerName: "container", }, }, @@ -123,7 +123,7 @@ func TestBuildQuery(t *testing.T) { Type: metricquery.ContainerMetricType, Container: &metricquery.ContainerNamerInfo{ Namespace: "default", - PodName: "pod-xxx", + WorkloadName: "workload-xxx", ContainerName: "container", }, }, From 257d09181451bd53a4c1d69d70f63fd1578caeb5 Mon Sep 17 00:00:00 2001 From: zsnmwy <35299017+zsnmwy@users.noreply.github.com> Date: Wed, 27 Apr 2022 14:46:08 +0800 Subject: [PATCH 36/41] fix(docs): fix Algorithm list --- docs/tutorials/using-time-series-prediction.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/using-time-series-prediction.md b/docs/tutorials/using-time-series-prediction.md index 50556ed6f..2f18c6e81 100644 --- a/docs/tutorials/using-time-series-prediction.md +++ b/docs/tutorials/using-time-series-prediction.md @@ -97,10 +97,11 @@ Now we only support prometheus as data source. We define the `MetricType` to ort ### Algorithm `Algorithm` define the algorithm type and params to do predict for the metric. Now there are two kinds of algorithms: + - `dsp` is an algorithm to forcasting a time series, it is based on FFT(Fast Fourier Transform), it is good at predicting some time series with seasonality and periods. - `percentile` is an algorithm to estimate a time series, and find a recommended value to represent the past time series, it is based on exponentially-decaying weights historgram statistics. it is used to estimate a time series, it is not good at to predict a time sequences, although the percentile can output a time series predicted data, but it is all the same value. so if you want to predict a time sequences, dsp is a better choice. #### dsp params -#### percentile params \ No newline at end of file +#### percentile params From 1a1d89bbd78dc99ff933974e6de37101420c5414 Mon Sep 17 00:00:00 2001 From: lbbniu Date: Thu, 28 Apr 2022 14:45:50 +0800 Subject: [PATCH 37/41] Fixed Crane dashboard discount modification invalid --- pkg/web/src/hooks/useGrafanaQueyStr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/web/src/hooks/useGrafanaQueyStr.ts b/pkg/web/src/hooks/useGrafanaQueyStr.ts index 2acd4a755..f0774e58e 100644 --- a/pkg/web/src/hooks/useGrafanaQueyStr.ts +++ b/pkg/web/src/hooks/useGrafanaQueyStr.ts @@ -30,7 +30,7 @@ export const useGrafanaQueryStr = ({ panelId }: { panelId: string }) => { ); if (discount) { - query = { ...query, ['var-discount']: discount }; + query = { ...query, ['var-Discount']: discount }; } if (isNeedSelectNamespace && selectedNamespace) { From 11c77d4478e26059fe5fbe87e45a1e47e6a3f7ea Mon Sep 17 00:00:00 2001 From: zsnmwy Date: Thu, 28 Apr 2022 11:27:21 +0800 Subject: [PATCH 38/41] feat(workflows): build images and upload to coding Signed-off-by: zsnmwy --- .github/workflows/build-images.yml | 219 +++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 .github/workflows/build-images.yml diff --git a/.github/workflows/build-images.yml b/.github/workflows/build-images.yml new file mode 100644 index 000000000..da9e928a8 --- /dev/null +++ b/.github/workflows/build-images.yml @@ -0,0 +1,219 @@ +name: build-images + +on: + pull_request_target: + types: [ opened, synchronize, reopened ] + +jobs: + build-craned: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + - id: git-versions + run: | + echo "::set-output name=git-version::$(git describe --tags --always)" + - id: build-name-image + run: | + echo "::set-output name=build-name-image::craned" + - id: build-name-file + run: | + echo "::set-output name=build-name-file::$(echo "${{steps.build-name-image.outputs.build-name-image}}" | tr '/' '-')" + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Build and export + run: | + make image-craned + + - name: Login to Coding Container Registry + uses: docker/login-action@v1 + with: + registry: finops-docker.pkg.coding.net + username: ${{ secrets.CODING_USERNAME }} + password: ${{ secrets.CODING_PASSWORD }} + + - name: Push image + run: | + IMAGE_NAME=${{steps.build-name-image.outputs.build-name-image}} + IMAGE_ID=finops-docker.pkg.coding.net/gocrane/crane/$IMAGE_NAME + + # Change all uppercase to lowercase + IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') + VERSION=${{steps.git-versions.outputs.git-version}} + echo IMAGE_ID=$IMAGE_ID + echo VERSION=$VERSION + docker tag gocrane/$IMAGE_NAME:$VERSION $IMAGE_ID:pr-${{github.event.number}}-$VERSION + docker push $IMAGE_ID:pr-${{github.event.number}}-$VERSION + + build-metric-adapter: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + - id: git-versions + run: | + echo "::set-output name=git-version::$(git describe --tags --always)" + - id: build-name-image + run: | + echo "::set-output name=build-name-image::metric-adapter" + - id: build-name-file + run: | + echo "::set-output name=build-name-file::$(echo "${{steps.build-name-image.outputs.build-name-image}}" | tr '/' '-')" + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Build and export + run: | + make image-metric-adapter + + - name: Login to Coding Container Registry + uses: docker/login-action@v1 + with: + registry: finops-docker.pkg.coding.net + username: ${{ secrets.CODING_USERNAME }} + password: ${{ secrets.CODING_PASSWORD }} + + - name: Push image + run: | + IMAGE_NAME=${{steps.build-name-image.outputs.build-name-image}} + IMAGE_ID=finops-docker.pkg.coding.net/gocrane/crane/$IMAGE_NAME + + # Change all uppercase to lowercase + IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') + VERSION=${{steps.git-versions.outputs.git-version}} + echo IMAGE_ID=$IMAGE_ID + echo VERSION=$VERSION + docker tag gocrane/$IMAGE_NAME:$VERSION $IMAGE_ID:pr-${{github.event.number}}-$VERSION + docker push $IMAGE_ID:pr-${{github.event.number}}-$VERSION + + build-crane-agent: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + - id: git-versions + run: | + echo "::set-output name=git-version::$(git describe --tags --always)" + - id: build-name-image + run: | + echo "::set-output name=build-name-image::crane-agent" + - id: build-name-file + run: | + echo "::set-output name=build-name-file::$(echo "${{steps.build-name-image.outputs.build-name-image}}" | tr '/' '-')" + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Build and export + run: | + make image-crane-agent + + - name: Login to Coding Container Registry + uses: docker/login-action@v1 + with: + registry: finops-docker.pkg.coding.net + username: ${{ secrets.CODING_USERNAME }} + password: ${{ secrets.CODING_PASSWORD }} + + - name: Push image + run: | + IMAGE_NAME=${{steps.build-name-image.outputs.build-name-image}} + IMAGE_ID=finops-docker.pkg.coding.net/gocrane/crane/$IMAGE_NAME + + # Change all uppercase to lowercase + IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') + VERSION=${{steps.git-versions.outputs.git-version}} + echo IMAGE_ID=$IMAGE_ID + echo VERSION=$VERSION + docker tag gocrane/$IMAGE_NAME:$VERSION $IMAGE_ID:pr-${{github.event.number}}-$VERSION + docker push $IMAGE_ID:pr-${{github.event.number}}-$VERSION + + build-dashboard: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + - id: git-versions + run: | + echo "::set-output name=git-version::$(git describe --tags --always)" + - id: build-name-image + run: | + echo "::set-output name=build-name-image::dashboard" + - id: build-name-file + run: | + echo "::set-output name=build-name-file::$(echo "${{steps.build-name-image.outputs.build-name-image}}" | tr '/' '-')" + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Build and export + run: | + make image-dashboard + + - name: Login to Coding Container Registry + uses: docker/login-action@v1 + with: + registry: finops-docker.pkg.coding.net + username: ${{ secrets.CODING_USERNAME }} + password: ${{ secrets.CODING_PASSWORD }} + + - name: Push image + run: | + IMAGE_NAME=${{steps.build-name-image.outputs.build-name-image}} + IMAGE_ID=finops-docker.pkg.coding.net/gocrane/crane/$IMAGE_NAME + + # Change all uppercase to lowercase + IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') + VERSION=${{steps.git-versions.outputs.git-version}} + echo IMAGE_ID=$IMAGE_ID + echo VERSION=$VERSION + docker tag gocrane/$IMAGE_NAME:$VERSION $IMAGE_ID:pr-${{github.event.number}}-$VERSION + docker push $IMAGE_ID:pr-${{github.event.number}}-$VERSION + + post-comment: + runs-on: ubuntu-latest + needs: + - build-craned + - build-metric-adapter + - build-crane-agent + - build-dashboard + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + - id: git-versions + run: | + echo "::set-output name=git-version::$(git describe --tags --always)" + - id: image-tags + run: | + echo "::set-output name=image-tags::pr-${{github.event.number}}-${{steps.git-versions.outputs.git-version}}" + - name: maintain-comment + uses: actions-cool/maintain-one-comment@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + body: | + 🎉 Successfully Build Images. + + Overview: https://finops.coding.net/public-artifacts/gocrane/crane/packages + + | Image | Pull Command | + | --------------------------------------------- | --------------------------------------------------------- | + | crane-agent:${{steps.image-tags.outputs.image-tags}} | docker pull finops-docker.pkg.coding.net/gocrane/crane/crane-agent:${{steps.image-tags.outputs.image-tags}} | + | dashboard:${{steps.image-tags.outputs.image-tags}} | docker pull finops-docker.pkg.coding.net/gocrane/crane/dashboard:${{steps.image-tags.outputs.image-tags}} | + | metric-adapter:${{steps.image-tags.outputs.image-tags}} | docker pull finops-docker.pkg.coding.net/gocrane/crane/metric-adapter:${{steps.image-tags.outputs.image-tags}} | + | craned:${{steps.image-tags.outputs.image-tags}} | docker pull finops-docker.pkg.coding.net/gocrane/crane/craned:${{steps.image-tags.outputs.image-tags}} | + + body-include: '' From 06caad79334a123467734eef56b368062d7cca4c Mon Sep 17 00:00:00 2001 From: lukeqiu Date: Fri, 29 Apr 2022 11:06:36 +0800 Subject: [PATCH 39/41] add docs for crane-scheduler --- README.md | 1 + docs/images/dynamic-scheduler-plugin.png | Bin 0 -> 238067 bytes docs/index.md | 8 + docs/index.zh.md | 6 + docs/installation.md | 5 + docs/installation.zh.md | 5 + docs/tutorials/dynamic-scheduler-plugin.md | 32 +++ ...heduling-pods-based-on-actual-node-load.md | 213 ++++++++++++++++++ mkdocs.yml | 1 + 9 files changed, 271 insertions(+) create mode 100644 docs/images/dynamic-scheduler-plugin.png create mode 100644 docs/tutorials/dynamic-scheduler-plugin.md create mode 100644 docs/tutorials/scheduling-pods-based-on-actual-node-load.md diff --git a/README.md b/README.md index e6fd54b0e..6d8156ebc 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ The goal of Crane is to provide a one-stop-shop project to help Kubernetes users - Effective Pod Autoscaling (Effective Horizontal & Vertical Pod Autoscaling) - Cost Optimization - **Enhanced QoS** based on Pod PriorityClass +- **Load-aware Scheduling** Crane Overview diff --git a/docs/images/dynamic-scheduler-plugin.png b/docs/images/dynamic-scheduler-plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..43f5eb64497cb9948e490400500b416e80104bb0 GIT binary patch literal 238067 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
    Q=ZbTg&)o(W^uwwtU|w$e$tN^XxHrV9B5qUPA zu^#O)HIK>b>R;o=_=wPO7%z8lL*~wu!G3gATYCUjRS43~y^obYyzmw7;)!A9h;h2i z-=Cb=iiw`1L5Vy!?_r5Iz}kkPHEW zC|b};tJ~)gskuM{k>n0gEZud4j?*a!M4G+nHfkSlKUyS#>l50GN2nnD>!1$2vAvTc zH+82SO84&Fd@6exw^Z@jaa<{mQ$@=}=h+IkU4C=OIKEdXQPJ=-^rd2=#jRv44iPr4 znN+EV8PuwaOjXE!lVl)0G_8KO;?m$=>7$#e4hvO331^h%k1!Yr~~D~x{#L5RqO9n$DC65nW^$$e1AKE1gRctYa1PDfW^ zul3eTtbw^V4JKnZw6g9_a1r+FksEzv0$U4qFgH=zXe&3T)Brt`RX2*WeSS;X#Cx-t z)b3+BC*{SuQ01IFf|6fc-Y5l?vn3C)PM5j0cLddQZFg*f*^nboqVDxTL$ezl4a->NIwHF@0BP6ellRDBgD_103$9;a z(PS39r&IoNn044@N|7O0L9j#k# z96Ggt61AwpJAfFnKI@iC`HSe3=es)MeWFxkNz1P2d-*Lc38-xyGen^pYlnDgYAw(` zJqHW65n55j%L)6FfdH9-;l=!CKF;bSTznvg{;p)N=;&7YnndHxy{+%t!Ja)_$ew3L z^F5^0vV7kO5J|#CEoN2jor~j-9%#T2T@*|b@?Z_QKUgB4hY4O3lT1anGClT}9VCu; zWobr|=ZaqUm6vAe`DX);@tCRTw;MX;u?ntL--v2p(D`jJ0H9e?O)=OqlCj3jJAACh z=9N6`LpcSYc_*FYO3C96`}ysS07e_Es-EEr#JY9kYmdoAOs=b(p-z};C(CDNH67}3 zlj*$Ip1F%|?wlwld%(Vs-iy;1`@Q)Xs1BQO%MJ?qK1jEOwp)z8E#Gr`>@8jluDQfggMSu zwc{>sJwb8%bJFLbRJpyZ+hZ)BZRVm_qvmbuoa={JbYq@3D$=4rbr-<~dhz)L&Da#= ze24JS8&hJJf^SU=UU#V*GCbwKJ=8zt2qZdbk8e?P6YcSGcigaeSP!ZSbVVRF2D=nb zhR&OMd79i>XXHG!+!ay1El(kTT^TRWJUoky2|`!q|S}92VkId{ET8|+MFkdM8it?iwaf=j(BE%B-j!Fhg;Zf@NK zj@a zY4esscShky5`K3qA_#~fB+I1x?=2wBA!Q0eJDH%s2iVt$^|sS)E`v+muOLt{bG!Mt ziK&;m?3y*9W~SL9M~?jHz1R;XAN-B)8T`CLY3`Tlnq?rS+(fhCGib(^=ULIDtnXci zvn<69S(hHsNfXoYmh0#UJM%PhBHNcF4{lPv@#&OC9x6XLUp8W{>@`H(Qm18b!xDN& z!+1d&hk{u7$?D+yT?ucVRB`yJx+gt0^&0?qLd+6)mLLUoC30n}k2ojotW@xJdGcg! zP93sc7TZ~^I`k3z#4g>#iO#6?oVaUa+Hwu9G#n8=8uA&7Fi^FOUwfk)fB!D%+6-6x zCbj^QDZ_1-I2v)STXa~SsLHzPvD&AG%^ww49@fBQ`)@j5^v-Y4-UWw70l*D zZudk(vz-CGNrl&92O9wTt6;m@t+lt>3)HE{@0OethMUt~b06~`?O!$`Ri&pEgkg}= znw8Kwpb_9L;k>toTXHsj8d5!v*6KkXa~oPzxPunpI;}ld3^a0TS=<1BLa+_{>_jnT zQYFQkSLe>L^$eAQa5soNxJ!QkuTzT+IIxzW*dy+qo<<*JuDpn@0Y}KL!<``8rP>)eW1)k^&t_EQ6~zds>Sws+ZA^v%sd02uqz`-> zy|K7{Tdcq<^i7;x_YO#`E-Po*aKRpu! zdJk^GQ{FhLG8{Vq!XQ4D-uJZyHaDfPg= zQx+3`%~iTfMk8kWy3I`c&dRsGz_*AT8I2lAd$VD6zuL{YtipLCn?C zPp&O9uG}GFE^Y&Jz9t1aeF6D;i6H)vQcUTyPYUt3{!OoRAfC*;tn%KJSCRMtp1Plp2@P&@D{GEg%MS?n+;tw`vlFc15s%*KGkvOSP*oxKsD5sOE zWqn_|(=iXHJ*N>{0 zGChNZy>ar=t9y_f&o=LG36alpOBe|WOm1}3dIQa#b$4LrS2^@4gLbttH!!AWqo8l~ z$T{}IW&FfeZPGkXj-k8y-gFl@v0c&DSi&cF>ZP2IeTnY982e&kmetcJ##$&)cHlc* zPu!|UAjTd6$qCok5z@*0d%4D^^ej4vQzpiVp6H@B4d(H>u9Z5b2TQ;gw!A1dyzGl6BnhHmOP8gXzQ&H4$VMq?8~C* zHD&IPqnIvhWUZ4qaCR;LuLqcT(d^Jsfbq_7C4vHQyY1^>c=Jg!!I5SIh$Yb3nJZYM zTa`P{gRVs2xcf^LrHw4=;9CxKT#Hyrj@h7arB1E^?l?iMazZx7m4K5dHyAivd2ycZ zhNzPdV)SMRF42!-LIU@Xj`0X&>KQcN-uWbxz#%V~H$@KG>_dd6E6~GywnA=``kWtP zX2(ovdz?pmbW2iiCO$pW*Z-#UnS+r(fU(3&ffY)Yitg^aCutXfHKidP<^kV?|&LCk8L_|#zL zxFk|h{=C{SNY>Vf>pzM7jj<-DC~D{bVyOOyACrvs846nNUt{`d*#3vl|1f~?B4z;G zu(dQ@I5@cf?H|pzfm*@xoC|CJt1tO&YUu%A#iB4smFm~O{BM5!|6c50r}BR%_HUv2 zKT-VGW#aq4JND;w`9J0H=WZPOKjraXmB(17Q}ogQ){Fr_#@W1LWE;9>8&j6|DC3$4PSSI>TW4*z=khXSB4<)q2=fd7Vg zzy5rI&yZr&ZoL@So&Uu2sreZQecyLqIW0?-_SdqN>86-iQeWhKi?Sdf)Auj&`)_}Q z>jI>ZeTbbQE_gGuG(Iz>jidV5hE9X6n9Be53F#oNf$rmFXaC#p_|N|V3^gstcZ^tn z`L8Ycy-gOvj$hzMEEH~~2mXf-Xfo`luO73W{ueFk?_WO3QeE>cKTougvP{M|feqin zau}HZ!!nXeXhH-C<6@rw-*-*&rrCB~eB$Z0^JGgsEc%@0O{yjN9V~u=vPm-g(m3iC zIx9m;REu@EJQ-IjM^71kF5_jL?Ck8?aO~*Q6V`6)-}KQ_fCKt(v1jI!I0$-l)3&+) zNF4u{{|8Wc#L0e)NBCBqi(dNh;tXQZvWBv!=d2xgJZl1A8@Wa)hM3N+jY#B2b5j&X zxr}?-cIt_W;-=RpTD#qT)aw0wCfpjnz3nMx)y^em+s#+(Ff0qqXt*o}u%pj}%lsf5 z2WZFuLc5823)^3pNQR0raY0IqVi6-l5ZP-E;(P|4QjLrLgNeN3CKYkb=j_Y%=anKQ zU@K2!a%ej46@&|2xl8WyiQ48arUWAcL;XkMH{v9XQ_R=Z~Y=eqLVfkeWGSehl5-gcZK#GGlFO?2G^%-RNQ}JmiNb_OJ3D{4aY!AM|VqGHAg>H^7NpggVM4v3&%OSlzns-z>G*w9H?-Lx$vAey zb$)m$wXF~wi?VF>7`-poa8S#+_#MM# zSI%e8)?K*%MLhkXW}npaP$JJz>@|z~%e%l-Xsv1fG36gFQ_>JX?eLKd5>xys-F#kf zcn0G&_5_JezK#sZ?>P_B?J^uJ6d{-XV1-orM6&@N(4GX?A9?V!sV%48Q8cVTXFXkZ+~P%?e8~D z5~pd1BMUkAeeuAfm-?d5Ss8`7oa9*;uv!0CcmrOyFTM_YOGv%wc&q|+(~Q2F{B+vu zj^dx(^#aCYsp0A%UoWR91!zUIycbHp#QH%^k^9Q`F_(rQ4$HO}iCV8cx`RCi=+LFV zJL8%?d|Q84A}aA3n~nJFe93X&z3n_(?gI%JWajPJ?SyXrqwq964kUH0Rx6Yzu59=w zNrmb96WMh_%Ub_FRf#SK&J-s3s9)OY6Ks4^O3mb;3uK5vwr z)gVJi-khcS);Ia!%>Kw;wPYr;Bt)D-s>r_9E?mx`v+k)AD@e8$)a` za?5sKF|H^%c`WLH+*FAMq*<6x#U9W9E1fz8^4?HPjNaykL?21yx_e7{`JSH#xDKLL zcbTlFHY(PIp7_&dOldOy@VxaRTOadF_v3r;! zWIz_GTDgXiu{OAy=Fdp@KPda*PgoySxfkwFS^<%=-thdaFL7d*E*iSrwDZdZ!SAzg zD&{NLT-te>^G&j~y@RX5{z!`}@1O?ApS;qpq{Ur!)5i z9T=0JQ*K|0Toib7Ke-S|aX9w~XAo?pEndN@`ECzLYPi0I=Crs}qJ{-7=xQRO3Up2$ z6Z|y({vmW3OYRp-kcqatCKlZ?Pj+W;79L%zzK#iR6`c-W>J#=}u(3L33Nenkx175) zI(21fUcO!O51mrZr}^m7>6s0HIrj+8{)gHQYooeSAKR9qGWv5{cr$2Nnn+DCbPK@^ zecXX-&B6sSkP#lyZ(F%I(;}hx&?DenN!M=bSZ6htvFn_FsP?DDHHCOLN)gKvS#lG> zFS&q{^FmhoI6z7%`g>6XpYZ`Dxqu<*zVq0AHZ7tE(ExAu@%qhWQJzG`QPPskLCc2KHfd@cify#) zEOhbaKlIQKWn|AbV-3R^_>^DF^_?EsrRWaw>=A2Aj!L%T3o{`9yg>BjBzBIoFCUi8vHA#cgxJ{udVj z7+3hsAvfMeP_jEZnf6+ zw;qTrS>-?dQ>y_Bhd)2n5d>9JQ)|zGrlqB!o_>A*-0m;JK^uk=?pvEA0R5PpwD|DxvJD z;atdSuA4;e4NsjpU-EHGHBO;_{mIx$#s!)Y{>*%jo@=9`>G?WwEa?-M$DY^ zvO==Is$?e?4TNVebo(X?_wm={&wS{r;F|tZ<5r*RC>p2nO4+_7H!}EL+b3rhj9b$L zL&PugyVzd3Nkc539d3;1$1#m0c19l?uJHKT0&;NXAE`hKT|vfu*dXJXTKlMVm52WJlpea(J>9=9@nI=HAVzymFxE%YE`aL(~6YiF(PT;6cV+1@N| zSx}cN`-71e?nt$$>bkcErDI&>x&L)9G4ukAV~j#DTI@?SFnt6Lgb`IZ(K8QP1QmvT zVxWKQT+vOlFRxCtGeE&$u&$=289*0a01Owq+@x{C=faQA6{)@8AQyrEo@M&AgUol7 zZg>nc&aJU!If?s?0)i+jwy72^+U6AlltIOU+*VLxqK&}63=k=6H>pqXqh*r#Cwxvq%3tcx`wy8&Tr zzdd{XbDHie7hUm+qii!R_m0pFcrbPAuYAd;4Y9!8p}armx}xD@>6gE4kYsn+XJx7Q zTG-W&8C2sS+xZJFkip2brw(DsypfL5tK0H4txZB^WyNd9hSY6sP zNO0pFsvW8`Kkd)HhP+^)q|$9WFbun0@A_c4E5c_(=5^j*LM@!GhAz{sFDXxURTQnP z+REjHaCcMw`EusFACw+H{?yagNB1UH&MmLFEeCq|Ktywh5bBSX+v<{qNY(U0-|5;S0ekEs>x zA*JZ8t;g+`NRG;DUamRiGMe`&?@zV}%A7C2(*E(;qwA_>U*BJBFRI)h^2VZVVzS89 zb*(x$I2bw z$BO{ygt1fcUdnPI(nKU|85Zfx^;^V&T9C_B)vVnal7g@D9oN~ZLZ8#mX?2`G$ngG< zQn)Ic=5m5tg96cFZ)ZzAGA1TQ75@8f-QK@j78hoJ&p_;8ghS-LiwWSZNs-fmY>@-d z((9eU@BcC_`k@9|Rsl7@_>@b|*0-%ZUH0D_@QwQTqI*3^8G6n@vOSR5dSKbNnzVju zW2%%KW%dFV+RAhqQ0%V)xc8RXI2eSoaj$`tX& zZF%kLp?x&Mtuoo(?smq0Q~&&5Y*`k*;R6A$K02TL^(IQZU}}Y(2_8c5k`8V>p2$<0 zrNJXdYE+4za_CBbXEVgSB{3wOE0&pmG4o?a5akVHB~g98E$yw}nJ+(?uMR}~DhL1( zx8Jf2q}~gs(z72Zs&8&-0TTw1lFoQl^Ir5J#vfpfBQZUwMe7L)AH7Z+P>bX5wk}xPo+LcKoHg zQl7)4;zT5-!v0C5pkn_zyc? zW^;oBDZXSEUkjykt2+5S?%-s9o=vB|*<{nZ-tO-1wAV4Ukd^QCl0JLh(=yr#!t6h> z16-U9(7eHPfxmcJ4^d^E>|pTJ3(9gt0BWTMeRYLakO!)dKrkVc#n!hXX-81z=MTef z++X+|I2jO1Ne*@K3S-GJ$<$@|9zNG3@0CtBLpPc+B#H7EakKnd{-S$BRBc zFg+^U@aMtLUePo#ICHH40`MNdE$ucGgubf$7zxN5zQ381-%<#_w}gtO8e@XvaPFTPBmVn*{HSbCVv&e_N5GPXm=k;aeNC?a^CRvmcJ>_4~g) zTMVeekvbdXa0R%ydYhOp8)^#OqVzBF^rq^Nw<8$}A871!-%oFM8cZ8t3Us3-|A{`E zF2I4Hh5-}`jl5*{dIXqv)ej66vuTMGDFsUSr9*`|WPYG#rGTUBGT)-FrRIwNhTTfM zfz&Y@ghE!4-slLLjdU&gH}*C}t&v;yKiy5hnmqlq?}o&uxrdgbm#C9%WCosV2q~IE zg5ScJt?~R5mj`7i8fs>W@sb9TRc27SDO{F$OIMbD$sg>`@JuSu9H)fs2Y--@rs!yo zo+%j6;3&YtT|VRp_y!MJF8p*_XZe8JG%GDo@{hW$xv#-vDKT0#YN?TTjb^QU7XQ_) zEcW^zD=d6r8Oez*Xy5mSuAR#i=?X}8|E@z#v=~hKX7Z2OS5{J45s;9Okim}llu+lt zwqiDbRA|6IFjkMZ3R`6BF`& zA85Hyn4VKWyv$U^(4Cq3kx~p2Cu^`ld_tdj(AfCXUgS|3IO&CIwyX%aSy-e2BS+i6 zrVtPaM4rFn4}%V8UZ<6cLQ>+Lw5g2U$fvC%EO8;REhj6BusZwluIbJ!~VFZHcQT#p44 zwm~;w;%pcp1~BqA5eo7pxzW4gemp;R9Ikq5Cf0^Az4}1JqlJ=Qpm`KGHM`a0bY#07 zHXEdp@#lfFN>v{#tu#TcVJn&dZF1i@?OAW?3$)Z3Q@68*ZabC3-fi5HWl7TQ51W4L za^5h|;Wpa7_2nb38*a8&@;BGDweN8kg5snfS5ndjLrPK7dR1GwvAIv@u0;GD(i7_a z>y{m&y2pN6#wk_Id=!}ER@t34umjvW!0nE=Y8%wk(lTddWo^F#GZr5E3GZzL04cJO z6&3$I?&K~zd>1T~uD@)n2OR~RJf#ZpY!$ig_G!sn1}?o9qq#^i@NA4hm&{K|0KQsj z`)G;1d+kV>If{Ek9|Ccu4TJWNBq#)@TmTdpqVDNQj>%r1S^zO1y zJA=FJw`|DXAgpp8)0y%Nty=Wtf+e+byVe&t0{`MA5L zNeEXpD#&_%$=ZC>h1($W^rfOs+(Upn2Br-#$z4>TXg}IZS?QB(h5%3nUSrST_%1#Y z@I*%b1}4M>{NqQ!KhOuAzWO=3P{gP{rcmP^AiF{aB~8cH-?A{wJe@pnb^tH!F5roY zpJ9mkojyv9Rhpfxv$wvduUUN71NJV>{Ke36@tyu#JuTpcnPWEyE^e+8=!o8yqm_io z{qC^?;MHUaPq%Q{Se#&To&ElzxP8&-$|)v>?H!qY#LVW-P)TT4T?pvHcj^}te3cWN zd|9gFrAG#bIEJKR_1UWV{?J#cMo9$)9RMWz+?&m@YuOt0n4ay5U;i zixUTaqtcoE{SWZF8UAAlfH8i4vTQ3x&R%KcvRE(|LHbFyyvj(rmLVNG3ohuYx|nsJ0Rn``S%6 zGa1h)tcEubXU*&6LWyly%H-)kT*RZPkCenVY&NRziY@DCYfFo5lzWt1$d8x~W?_!{ z?x4y20}=n%puwTTG%dz*Fk9v?`yqn(C2?wQl?-lVIX)Jc%Aijg%%Zv7o&u<^+3vpw ze;?4~2PN{78;*|C=S27Pz6D%6n_2w*wJD=)ySnGGbrFsy?7|+`3&fYgI30?s-ivi+ zzbpC2FXf%4zOSMZub>R->~gB|EGu5OF)ZFFFW#KuI>UXSHJhXlQ<1MZG+B%Og7IOV zaKT1ZNeY8|=yi;!P~;?W&e~&SA6f!H_`5uplh@it0L`8V`b#qc&B>Q( z`k>HQn^ZED2vr|D%{ePHcBPFx)8&f)FyC4EspOxcZeA;DmZ825<}IcUB=r*D&{18A zK|<=^u-<5-x;*d$-}AOnA6-x>KK$u75x-IeXftxM`uTb!*lZ-}IoLt7G8w6L1L_hF zf8%VM!3iLX=l>v!W2gAgMW3UIxjwVgacM@;M4`te{DQBPT0cC{I`Qj$Unnt98H7l6 z20;a$02o5o)RgDwWLFMUwjl?4^-%bMT}Rcb9&;1p zVXNNK+o6RY>>`en0)2K;b{!TOd%qQlsCeBi{UzqWt-Y6&lXJxun6YpJUc9roO`JcX zwm+mAv_T(d_5eLZgTop_7Ak$+gL^2pCH_C6RGxetQi_<}Sf$S~4k&!S(jypZ2(X{P?kTkexAP?ch_@!hnI!XFANdf1FM#ydokZ zrLwA!6H2@Unt()?Pr=;s=bp-y68f#_VXL`e)6)NBh&pt}YJBjnqJ4n`f~#YrAY7S@ ztE~LXV)k9SMd$!<9mdxe-R<61yO2tAZS;*JHXbeSSg+igvtINS=Sv; z_5b}dLxW1GBuYpbWsh)GlI(0kW$(!5;;LvF5hYof*?V7?hMB#`y_CJ~wXTbc`+L2S zKHtahkNy+y`@XMp&htE<&vRap6Z2ob{Y{tPFWjbu(zD)c(Z~_$=C%@0Szz7zUv%os zTRxu=tKIAKra8guDi5OBv%^N^_q$HGK_$9$^lj&K$#` z+dVO%)s$uSy;UH2y--k={JVWdu^?%^m@gS#DTGt*+1AGXGU}s3{HGmJIHvX__C5~+ z4prl~a7^W=B2^;B50xbJ{^l+~nMwgH2KxD^z&<8JWRnvI^~=xy%4N6r8-{Y$+gGCI zy0cb%e}gGhpNtAWU%tgDS?m^)`sYMXYitK1DSEdf*0p}wEZ+2edL8z*B< zIj^oEPIU_W{MTTCy;j`u)zZ9m1|SNH`T*7QDRK-?y*RzGzC39FI8db;g!8TTy#V_&L4opl{HSF#zHM1GAfJNv!$>?4RLf63BUxy1qKPxOk?{-xng z$|EDI!vi?`&*pUo&q$?-AXUtLdl52z_Tbjm8yLg_0d8u347Fb2r_j)Aq5pe|pK^6C zKkbxrHg$5k7O1UL`l$@67QheZ-s?0irXO~wHddo{-Hl_ACdi4N$KuleVn2i}gPPhP zZ;{{};E(5>Eq=an>2J&WxUn#l65$$ehw7F>g&shC{89f`AMC&QWTAU_AbR+d2`h`# z@vdYI&Iga!ee)YPCMFNESa6k4ejce}^q8f)C8_YLTRNEeJ`XEW>i!t+jCXl;(qb-b|mZ7g#aY1umNHl#@J>p;ES~wcc zT<#!LWlvgN8nB%<>hrlAuPzI>UjmJjt?d)~<$W8DX|kWWF|&}jsoF5(50@6VQ;a{c_(*Vj+V8tN8IpBWrJRe8xkEr6#_e4yPP1dGe`EAmaO&mTU6@|5Bx z@!h>RP-fI)Z%Yk{A#Ul<>NtPuOuiu6Vy0cp@QnET_bP+D_}^E(le=CWKP};$2I#fA z2cOO74e}npShtvjIuJn{<4jrq>pFMu?8b#B8;Dx^g;K`-a33*2aF3=^QI%OyqvU%` z3BS(i1V`B}lcuGaB|UG}f2bMx7UJL(c%wn~Z)C9@qLkk1Zyi{8;o^#ghxA2hWH|1`A1-ec;NGBMVO7{AfjT;!+l)SdtkazKxuF}a| zao!yst|Ui`d4pU(y?VnFu{$Tv(->j~yNJ#4R6GB(?9!87^l-=k+W#AQ#cYp3;%>VT zQVl4ZIjor*mGIQYE73lgw`CGjx*}Lh*KdHv94MY=j=@@Sq5vo`GtrseS){v% zeJ{8=kFH~NZj`jDh7o7`wX|<6razBRmHqdu{rsTi|Mu;sjjgQ^U^*4=FJJ%yfOIF> zewWP3${}$q^#N+LhkJrL?w|)Y5k#;FOP<*!CeYUe`9+Q)*M|71i&9nF zj8?IS`7RfWhiA+u%z!S?r`NUR;obdEhcf*FdEKYsf{6%KN&#;`Hbe0HQ)D+)a2|9k z+8!eT6GHg=lXtSmayU=6#LQBzuIH##4Gw`MlGc-HiaL@oQMhdFTs7lu}Aa z0Db7t+g~(Euc|-W;Bv`4DC{g9qqf#20_PjgeavcA#8IzBgj5ZAl{UGWET8vs?d)_- z8h!F#CbL6sq`J6So206tcTw1o`cl(CJ8JAOF@xW@KUt?aBXY5P_J2ysUGh&~9dH=r zyL`$R4YqjywM_u}HI$WuPOPN%6YuVRnw8>eg%}4VVI-PnX6MQ4c@a8b`_yCFA>vZ0 zV;R*ghhz2R2p>4H|Kpq5fuuZ=CDnSWsccAC=L?S3?fPO+n@RYAo)%cWthTlQkN8RT zD}P^9n=%>iyMe-mgR74Q53bhu+85Q3dS&`jrI(}ZBWulQo}UsMcc|5ktK4=S3+kQ! z5l1>#KURfRS?|!DjVAS1JN}1CXQ1I&h#uao6+hRyR2F!YCEp8&?8TPPX2)MVxzd}e z%E~q60DKm*le;Ma#?}q7$kvWC`@a4B2e5*kci#@#Vz$GO?Q7-XzhQ$u5c%KyHO5{- zW&ad($ifs8s)%dP5Gm&z?21LJbXfWl4zCXgRV?JCWS@| zWRzcMe^fB$GLp zE*F0PJ!32W|5^|_VKIE(mnPDMH3l!5OKS1H4Ga}iixzY5X^kE4&Fg5|CKs4<7{YyVMZL!F(>wkyr%DMOJv}QeEv-dHg*^)8IE1~vDRBSC=mt(d1Ox#m z7YA|bd{K-eB_(F6A4dPt>0!K2GS{WNkU*h)ILhyzE@3soRx#3^n(6*W=UH&UGuRg@ zX>{2bR(!Z@5aMqF_`QYNe`=indnWu~rw%cmI;F3np)n+tnU!<~`F>*4cZ%XNJ{E#q!+gN0W@6>EG>)G5); z73_y-(!G)ItFAx=JgymIuB_pAvMGT&?{>fVqY7W$6ZKC!;=PGOc04BM4!n9a`ir~w zXXqQA|NIf}i}7cOjGt2j%?IBI8+uMBt7ucYdDO^|^5qX6FqrdupRk*wHg@s*+DIoj; zLJIW4_v~|r!#EUg#!Q^vec=jB;J{7)(A?z=p*OfNXvn`0D{i<}bslImrev%awQwpr zF_H>H-L>*Hcrz`#f11KBsCk>ch){|#OI2EXZJ0ZC-F!xoTEJ{o7s5sQqu;zTe+O8B zrX;6sT>bC)1#F8e&E?XZgbUlan3I(yW=*Fo`VCRf&8MLP$!k<8Hs*xf-kjS-&7qc{ zejn$(=kf1LFr@U^&L{$i;_k>Adn>D_x6*!m$Y-QeTWUyMdZIX7X0g_1eN@q+`a z(f(a`^9~7#;PUJSMJ1Rr`wJUSZH^5>tX>`yOyzGa2cS?uf8_aA>+8BX_gOAMU0+aW zki@>@Uc?%rV7Z0RKWl9KB>9UMFF?mRoaN7{{Aui0BNO(q`TQZS?~Xf##q z3|)zC^GRfJzi6^mEUhqvSTjA$TV}Ph`vCLO-4Wmq#IC-D>jVgn3e`jQyPbN6IbWH)x{S3$fZ(Av;%!5pylv3>CVWd zU8!m3xa;x9pTT<`cLqZGquHLULz1&`=JTBzOfYZ1vtkPsBnRdb72^u#q11S(WXpopEZw|s z-+23H8LMS>0~-`CNOi7Wx=gnNg@KF^BDMZr7>i~W9xidH=%$lQl>ryt!d7WFH^(QH z6_>+2Idf52KSe4lTZ9aTNBsZ9o~-TO%Mzh3p43|^Lyl%fz`UQ+(bd{mHdHJ-;)ofX54y2%in+9T_S_)i$;BX z6=<_)W}1RNz*O*I@l~JC+Dq)WOV3ZXWx@f5q4Sa+cm=%85(xM^^DW?Ra$LH6VDC4< z^1;beEWS3rPb`3Y!QYV6O+Y@T|9F>ZRQQUu0x@I!rrR|8?&$|1SwPM%A6&Sxv0+a@#XmjC&D+3iC2mATf2CBl z;IA-sw-|ughEplt`%waf3-yQilnB`()Y_7#!9uvhU_o^3QHhqn!kcLnEKb@LOR(W} zn7RgFJ{xqR=0L4A)8m>xO5RQt>_Uy7uiWA!KJ4VTwdhu+B*<~G?@R2VdE|7zY;0_1 z)rm!KA-fQJWJ1&yBdk6Xek@9C=M0A)fQp9S-DCfX22D~%b+(()Y)2u59nr2iMN1^r zwH!!x2~8ew0z#Zi%#D6f~15TKf_D;ksq`+-fLu#cj$pjWl_JY zQnabB?v~PxVGfH>cU?%@HuMiyxuZQzmVJDth)4u)1i|iqQJ$-{6Ot9 zFFJ{J_rHuK9Y83Ei_bYr+#ze$_xK%F2eh3`KApm<+<~+9A8R`*4Nb-Nk%noupZQ$p z{Yojr;F2$2z5#iMDes(HPZgl@e^Dil@BB(Deo!n1=#L%QFU0xA@m9mi_bd^wp_g1UD1c(I__ zCf;?JH{^CqmIGkJPd|J9RfAzS=w6+))YrDqS6Kn<ijundIAD^u>(A$~u8t)? zaB`$B6E4M>dSD0AFaV780``07Wx<@NHVCbX_Ehh|!=K@fhZRI~=};BLK-l4ad4XqV zBMd(1YI~{rFKc^%9LWWUgWjtSx%4927t@Y$9XV}zYm%Xl>G`*# zYmooo5Wu31%2O32St($2$ybGJhC#kbq$V?u6Or0M!T*!~5PakwaqCJSOmhA9*_h^lF$!Qpl zE4;n*NjYOPuzwFfA}$@;EEBAsN@TA=+}R2|TJZbOEKknZ+e^JFi!@^&t6!Z^VVlp! zVeIMB|KkBN4X$oWxRq5^C4J#Yk5eT;hb>{1?R2Jq4Y|3?hD-%RM6vql*?(b^M0+`H zZeUR(rmkZq74rUsX){p;GKE%bTDb9r%+W6}1N+nwzRO2_uUq_$^55j(Oqp2p4zXS) z0KQeS;^E>bC7$YbhsCG{1$DBjiKRjbFfpz8u{hY}-9oJ=&u5l53=9vTvz-28HDtq+ ze-eji&I>1*7#aIY9Y<}qHt_0Ao%u)*MG>zK?_?%NK>z=5^$+8JGXAka1O#?N&dal3 z=-!7^RVw-ozo+f|VkA$!_sQ;7`b7>(EeDiA7H`*W`cwMDo0~s$ZoZN_H6?j@7}638 zm7Gu-se{?MBHwa!BnX}=H;aN zKiIcugXcX;d)wfw2WT|ArJt6dOPml^(f?x755@`UmVbV|)Dv*g{$TE#JI%D}*&Xzs z5((sSBxT`q`&+keeLI`1M~vjrJFeleD-S~YoQ99UZePft0J7g*iO>5i5I9SKj)MT@ z(f?L&7;kj_qklQBUAtp zylWeOQWwN*0i>in-N;eoN{3=h)E2OWbf^Vz?mUX=ClCWsB99CA!9+b+Xv7jYj~ZUf zIj3{C6>Aev#bj*6+Er>NDRO*-=@Q6TJ4Z2rim|Jtz`9sCNB_V#pV?1&nuneN*2w3`WQnTOixemCIyi(GgUsbV0B0Br_{X0w&x3pr2!=V z390OVlU#SdR=0qg$a=m%okLh)^I~w9?73gOcfHtjb%&LPs_$EayXSY^Ph+JpqCv%c z5p#CIXcjBKNzO=>Or{TKoz|2z`SgYOWDj|%MGa=B(FdJ8|6#}wD@>Ppd6n1hmxgmH zJNe@uPa|ibTEMHD%N98|w&!un1aIn*mDmmrZyO}9+g?e<*puVg{a|NlGchZL=&c`y zEdn{#Jv+<*M*bcvqK4|H2w*UpL0*f|ah3fLFx>}S3eMs!d*73jUOW)L=J3(kB_YA* zX&;MitYYKgKzoUIqk;x5a3X#K|0>nvQ)&+ld736_A3U_ULp5VXEiLs}0l+JjCyz4M zO}N8v?0hd}TmZaagT$pEbR}>nJ~5HqWZ>Q{AYQJMkKQph2mW>HD-vzR!+^6m(`UgB z2QCtwev;@qWH^gxo32)eOEZ}Y%kg+r~uQfH~J0dme=MKH|afz<*S3tUemn5 z*ZyL~o-J$t6g%DC@r2*6e03Om_44H>k)wtvAGp$MI=;-zOptg#7VgSI3@YIGKM^>$ z%SnHN85tRMG^RWRwjv|o-EsT*@pb&sDuCc4$BrCV$cb5M|1b#B@#h05n>y8^j?Tbj z9SW@h2pkch4!r`{{YFv8jVpPd6Mtty34NDH?dDh|*3nMN|$02gogEJTtJV~e< z^cg?lQcQbI)9_fHY%Mu?RohZ9MaT{NzO_pF@8(+1IUCD|G+HFF|~(r=D#v>a#SrT?gXEke$OhcAhp*ven*m0AuNmo{2TKq+1vq?g`6-C;Z;|%rrl) zJn7+e)5o+u>dBcBlEfh-BwcJhGCzcYk+2-ZG~qe}gSlo0^c+tKi?jbf z7bfC8D5Um)<)_V3HEa2JojrTp1+7Pn^ci<41OZQ5c>ZnvX-t7E@)Xb4 z;AJiQ&d>=vY_3dl%44VdGg!VQLvHxbKLwoVS9WdLris<5%gghXUes#CGm6 z7XLLw5B2BI(5xFDp%l;tCCih2k`$>;3FF0XJ3cBGS@(VK-Tlk){dj=>j~kiD$-NLf z@i4P#v%FxnyQ}L`B`@Pn<_g^c=+BIFx^rjY5EQ#?vy>@sQW6!Gx$n zFxh;ZO-;h4*l?jf38BqjBugK6}L$dJ%Gga&qLVHupMJ0$S)z85cGa z4$KoOe#XC;!gl7P*(M?T>iP$m?ST!O0NvCR!C6068k4IyM)^fLl0P8Dee#==dV>e_ zjg8~@ZplmT!l?Q)f0N~j5jUfLD%q{7;->+3_8pULg_$kI#%?E@o|yj`X*Z`V=ME*U zKb_xv5i$_}n_ZG(^R-=HRyUgGRns0U1If?xVrVAlh&h|90n-~5sS4)mv`R@I%@{;n%dft>NR?KD;i`E#>dB1NL_Wd(Ho_rb*&E3 zw5)16nYzC#Tk!g&8#5Uu9<=ZN8uG%}fM*g6-8n3qqi1Fiw}vp@#m0hrEVq}oLZl&Y1`uP!WuHORRB3}^2qYr;{$`WhZ$;WzAjG0f-@JXN(G~$F z`YyV{fVB!Vi@=2~bH$SeSRtdDD$8rvM7HzkfLRd?pqdF#qf1 z7y=Z`U7s#)U^pWhj>q=*8djvX@X ziZ{7rgp%OXayxTfCa!hoqn!3`VWD9gVQPCWP%a`^KnDZDsH-{g zMy}mcVBy=XV^FD=VgfyZv-Z1L4}}E9wj`0O+LVb-}R=`5J&4CW$*4W|y_&U)i+kUw>RC3`kgFVlM7cUut0XU{sm$4lTT`vU@l0p-bu5-DywYBke zHO~$zhZNcLy3*U=T+oJ&daEyaL7xsaTh!w0tYKTr$h=$oT5D%+)P z>0`+X74Q6|NdaKHeNt?FEIeGoB<^gy7O^nXzOn%+6Z@7WmbRbh8wY2^^+HSq`2i~5#9J{7<6=a7*B5ZUASI1#LH$UyO>xO3XdW!O; zYi;8UwZ!(#us?W1=RhHffBl+nGS;_}%oD8ZUmb5Wg*non-vy&$0AM69yifybxTkw3 zuu38;^h&bmuVMN(R>#-?g|*T;7qh5#pXnFd9S%r<#ijP z!mi%6Qw8(oA3{Tu?^IU5GBf^pdOyT%$9RoeRD2?E3 zohXT(7`K67r!S+T?Iy}@{5i5K& z@2yGN5?TP6Lr*A5sB*J7e6#yIaJ7OmwsH)(t4BCI4vrnkO_UEwQl+p`xDQ;L!rvH2 z&T!iSmjz_3@Z9Zw*%&gQp4vuVo5{v?X*{hO3^Iu2oIq;3lAcsq#XW~zBI9lL+B4Eg z5;xHV12E(BF8}F&{J?j}(9y2Xh>t6i4Eh=SQoYg^IYlq45w7kD;?IvyJ^dp1LZT)Q zRPS_+mCER|%*?z!@xoNxWeUAh18NEmBcOh}l7GJ$;}&AouP?V;r;qZ_1Csui$c&{* zGS$VEcDv|o9lyxvi}>E=6RiczBb=$03W^tV3@b!Jn}>_5U(qmIgKNclp7L;O+XMyH zUW;V3iTYID&pg6pzgd}6r#tW)J|D=ein8MwuN90u>);z|d%42Bam6Q%zBfnBR& zd5(}!-_u#+m!6By9Zlx*9Y=R3FxVLG{TTt1* zq%k{)k*BJAUOE^PVztC|klF25afk#-H-0Led$nv3I~Nv6L30;I1_!nvs%yZ#&U7`_ zUF(0h3ILzGA69GDXdDQ+;o4uZ3fA}Eu}Hd#HOFLNmJeBe%PpdMNr+>F+N|2!hlB> zo^FhQODWsOt|HYw`Sz3N-Y*t+KNY~xGB;NT?Qv&%-T2N;|S`^iUn1ta5LVO+oL zrk6F!>~n(sKHkgUV-)jSRPL(9VXm%hr}OLI1yd|~8$F)&mq=(UwH8xt?B)wc1?+8nF+TIj_^KbR0%^SOI_&W0$F)5U*x0RUX~(h%yX zPcQEz@n6V3hK%_aezCer4qm?N?2*sf{;^Tk5h&gxTkscP=O} ziS0Qhzsi&OKq!LOP-AfX+^#t9qysC+5$4)C1hfpO)Au9P z%SNoz&muMwT}u^u8}!CY5#FBKQWDtn8a}wbir!g0vyIjl%rgB`MeouUmy6lY3~u|~ z33@ib@6~%JK)?{J_fb3X4T-t6b*@1_;EK+;)myC(GrczQ#69xh8?E!?^1af0F$|IX zQ?ui?4BEm(UX`Z*<8l)poyX_hyEx0ZawlsB;yJVo5f?;Vx7Eio`>}jb@rQL#K~t}G zU_4V?FwnZE4R|pgQ3i3w#L(@%S6~TsHokUp7*`(t%9%?{)vgP_O|387XC)9hMlqiYF=-RC@S+2)z1c6lgVP z|8}lmboj>QYE{8?;F!E2929?Qryv!cvP2j6uc8)g)tFWHhIXJyzWC9dfsck$?u0Un zId>by_)nu*%`J0q$n|p0EiY)pYr0%E632ST~d#v_N2m6 z03XVZD|q)r=lJJ3n+!*<)MAg^?>I<@V@9@kw0h;Zl;Fu~m`|rvlRKQTmnMZdZks8i zy&F7x4sueJu2Y;rZpnh*NgSGT z3-#f$d8JK-=Pp&nSxICE7USD+j^j_CZB?RD!_YEY*_sQL1MwoYC+^1072{pkuqS^PYKI=efG5PAjCnZ1@i zO$ZeQ3mNWC-v3Sb7 zRwBP{sgXUym>`9HtPQ?|%e=fEsYksfIJ@p^znMc%r4t6>8B?0eYW7`e>V}xn#O~x_ zjqQHJM8nSTWlwtbg~}?1HsS)HWIXRb=y_04kXKWMUpP0ouCg$hlR3@C^2(t4$if>D z1LHmGuH%Q+UHfzt_mdVkY_aTju(d|$J5!I|cK@WQxxA$?=r$^Mh6nzxkoZsqf$@qe zFR%aFEg9CvjBL}qDqgKR;*Jn;I<@*CoRjTt8)&3-k7xak`zBPJ94?spbsF8_j(LC& zIB)&R&|x9clUXq|e2M#-l3+s_nc23}ChPr8g!&cs2!(mAhlsG)lPgmMjp&m+33}U` z^Y~TOt<^X;I+YF?%o*YX2L~-5n18cdMsYaJFv zg`f_Td@^O^w>|q*v#YsdWB_R@pa(+@-lCeEb}RJ3mEx4?zG%QI{6mpAm;RNC8=bZ4 z1uI#Y!Vb_K_FnfUgK9k^;U9K84m!x1TbRFi#$*L|1Skuyw(7AVCAe#%DAT(Ik zE;fDZCg3WUsn27T`&dI6TMr%@ccG{T9@l9K+44*9-1b{=9lz&p=C|;-1P{;m<*{4R zK5!u2M}M$1$#=tH*z`sHu1`ID&*DIO-;Ii!k(Rfz4^g?=_cI!rB1O;l6#E{|Z^$rU zdjRAwS|%E>rh?$w{9~4S zac&wFZQwmdq@P?!MOiLT!`3L!K*bQhq(; zMfxoi3hlS5HYpx?76HVFe&Ny70iaitpR``BQf%2WVD{;GS$$muSi^H&>QHXtb4M1U z!8(D8u}yxLhF!HCu>!VR^;>xSOiguTw}R#_M}UW+l1Zwnaho6`YOwet!`q_&p9Z!- zH-$lBB~veQpH`(;woGJ0x`$&quGtt@T8}{@N$hSO$WdGxc)t_L@9d)vpgN$XaH#%hE~ zHuk|CEy0{3>Wvw`hQR@+YVk-*6CBa)OVd&3i$4Np=7Zn8b{ZT)&mx;0n>zAhS7qLr zc?_Oza%~2y|3Cj;v>N>5wKb(rwI*Ct*$D{d`T6XGk{mQ|VyX;(UTG*qveug-py5}r zk|@pEs`Et^8*jnsNR=dUK3fHA@DP2u#ff#NZpwC9keaWw6qHqK{b7OOiAe znu2=(T0MoM2cJnekrQF?p|STC8F6vDN+;^mPaQi#iLqHQvuMlu)mq&~7Qpk{$9e~% zk#l^Km_-Y(SyZ$w30%p`?j}7h((SPt$?SZwmZeC;7&FB$xP{9@v!I@6Wq5aw2fx@v zy39!Fh@|T@-3e5*E{J@iExtX=rTmGpw{N;ArHa^eADyq|rD@KS^ZT}5IGW=NlSqg}*4b312s@x!O&-Q`k9_RdrTPr#P_|r`$svf{)+Z-tKbzucz#df|g z4pj4;Hz^MQUlT;&wNtG~eXPn+(&`}0mHWoyXeyRjK35$CilS!FDLnKO(~!OQY*2`= zxhVQ{ZxG6|!M8wD^f0mk`7VS0=)H12OUJjdFw#)8$o!2MH1oI*3o&DhtL{|d2iWc*;!ae zB>zkTzgm|)?ro)gtXk`aVRrxVtvK4DO8YW_H$@M4E4jrbd?iJ8Y)?*8J<$f|1qlyoxUJ#Qw#DJu{ymff`sxz|i@O z^40k=mkhh6PLf^59979wXzROLm|f@TDg1dp?vR#Q@z2pbV>vex!fbN#x@=lW>%v{a zJJ(O-E5l^@pe+!KJ&~~9!mXYV>$z_nAqRJdlT4pgM-L;v(>|8g+*^V(DBiTU1p*3c zVKVr^(^z7@sqU1QE_^tfNSEhBk97!?JQG|+|8{jNhoryTiRH_WX!LhR{KCDmPxo*r zzEl2naz2Z6#{v{WLSex?yui(Y#92{l_~qikWu!;5hrr z*#NsQVFYvgi%mhv@NKpm9(bYYXJrIxQ~ zc8If4jox;v#qV0xoU1{`svUrKHK`gRR^g1sssc819Fdrng;YzE)a~b26kRfI;B3S+ zy@obco~Gt+Mq)ik1sm7Fwqq{KHeWtHB9N5@%LdX@Ti%qtR)f0^o}ZocC0Sf9af0(5 z#S>vzPxo+1?1mm2q&$>eYTNF?^2x$yd`Su4=jJLVCXZ9W<$%`301SRiAEQ>DDWh@& zn6m|`ME~t1cyOZ4lzl^*=NQ4xq^NTXt&18wtd&wF-wh||Cz!V4={9_9TtEQ0kq>5~=anQ|J#5@g|c1t$Dps^4cS>C-I%p&QJIfRd8m?Z{n zH>!@m@Vu@6rQ1%m(4yb+)U}c(jt*rO9r)$uPzGIAOisNDk zqEVggBjM?bswek-`pZYBeC?)|gGrM&&8%D{agM!OFo=zYuxE?usE8#Wf%90A^Ff&-26~g zV>8RGi1F=nFPu70d&*EuyS?8&tJ_;<^3?)oQ;nyyz99)RBp6;g*H_$+DP?z0k#=!w zqhg=;{}}>Nm3l*7P!=uYjOVB$5t8E$x)>CMSM{73B7jj7${kzZZr@(-N=6`V-W`_b z8mQhnpUp+c!%HO&e11tRd4**i-;uPE?u=-B{TiVE_+(pj0kP(0?^J+!DU1tF(-x%b zur$2s+BzMODmtPhy6v1rsLhBLZEyV~E+=}`*L1oIrx^ zT{Q?H`taM9-Ye&z65C=(j6%VH->U6`1Dkr=tMk|?!g~V$+DgSQ*3zUajPJA9xN$fM zL#Cz=$32a;iMOOGYcS~f*PsIPNLApdJhkC;?#op<^2D3pSU+Zs2;e&hRk{;RmKHeS zoOF{3PcZ~ac+DS)K|4Fp}aG!%-ZnQO%3-`Kg)DEg9z=*7M&-k)B3o z_d4Qc?`EJ`%#TKH@3$}9`D{5h1fH{Hx4ex;Ks9tjroYsnGm5pEJ0j$?WmTOH9YIx%~+8u zm===E{Y0bQ6&Vcgs$vI-IYvBp5^b*8j!y_{e4n^Qt;`TMh?V${Vfa z1h*8g2d&o6FwB**+n&Zddl6n3xa+Jd0bj;GWFu#G1vSVOkwx&pdF2?W2*e?A zDEsJd-Kp0@V``NYOvd6GT5Xb+R;E;ziWPgC1nz@^RCZQ_<dp+Drsv{B8vlDrj1BX&q`}sfPh`0TJdt|Iw2#>+b~#Z zt*6!vO>te&ND(lw3Z;V*7=-h{PU8)%GC@KkYDMZZ_6%XH;vU>L8z+fpF-jv&e4V3r z+08;m@eVT?Nwt>b*mpCh?^_eFg!CaGfnqH-C$_=6^1~_jaXTt zEz&_HqKnI0x6Rjw`SDf9dCQESl%DrwT{51GgRA3YU!83QTqyOYw7f;sFqO)-*{#u8 z>ecDcZ70Eq8m*?j;u~|~hg*D>aN2-j4)Tl;b^hy~-gxru{87?o21)hyy`>Hd0Yc6T z^z|U;Ba;vbWqYh%hIkIl#Ft2-xntM5ZKqFdK{WbBy2~%cbJm=RapiI;)#lJ*0**BP zFK4;-Op9!TltZ}WL^v+C-lt+XXvRy^O%k(&#!2J1va}yB`y6C;(A#NX8R~B!RLzXS zpCf|se?SrOpuKT5GJ#$Ky&f9xGxc5lhRfIU=;u0; ziH50Fb%RU}sIamu=Jd1Qb!E<_58JcdEOl+TW!A{`DX8SFD~ zY6llPA}mtQr`cg6hj4$_xMGy*-Cp@#-i$Nf7$cI4h9fFly*X3fNJ>aNZj|Sw6p)3H z34Idpg0E2w46$*S@Y9*U=I|J%-!!Xrf;)^YZfEN-=%g_^gnn*p^LpE>Tyt-mK<9fP z+?-eCb{MjRALIJ`s_{I)poEPly_c3sdv(WaAOE(?$zD8oZ{`h$LkFw)QkRD-d~!u!SYR{(UoNXw{N*~sTA9#a>(or&Por>?-#jAfx9rOt(KqdU!fi{&ZUA!9->#Q8`Yh zB-vNa1mt0IT{gjB<53>&vwUh-?!z|@Bm^21lkVg<>Wm=l7iK0Ny3MF$1d z4$?t81tv!F3wzOky`w= zODwA+k$jIe!{Jsd$n182U*UC|*6NH^H(m>tF?&zfWz z2V+lLn#%_v&SM17H}ucyn_czgF=4iQE5@o9?`vccY+z1-m4TAS zbHdw~Lxz=c?Rl4wzOzNi5)qr@Vh6p}S*g~J$jn|G99S>!u$e^-`|_sAy)z1tJp-4- zRHc*hHn9sviGPG5y{VUK^7m)=Or!iFCy-N%T0LA%8**;Dm=2r-UCI@7g4eJ_q}2Mh^6;S5A0{fA86V-{Q4VY8%MiJ8*B4PWJ^W+E_K}-Ixl5`j_DBcz0rUJP z)5!T81M>#wHzoWV)rmHL6wr1k>B}=Iu3t1N;latyD85K72?1xRPwUK~0TiyE@tuzxFKi%eZRqvi-xz!7BHvB(($OqTIPRhKMDY z<(tXC!es|$_g4Qj&Bk=zQVe*}c*Tk!!5)PKTO)6%o<&*&n zi-h7IPm39i;i1->p20%IT-2{8qm1dK##xDtCfW#;XfT-6DCQo`DRE5XFW|je=O*&V zIR4CHWe)|@x=0re`!+e}v?~-aZ% zyvN^R^&D``-tlKo#U2n`b!iRC*gI5Undhcp6?d*G$x+3et>=r}n?IlCg`xw#l(S4C{drrDquJZb)ktlhh81-v+JEvpZvHkN=Atk>0iGm>GEJ41KTi@UhZwMsfz|yH0{W<{Fh#%--(l!`w8A%7@5)^fP zFg7i6c+@dot*)+cO0q5KEwC=)a~P>Bzcs*h`+W0NX(?J^^}V?=@M85rSM<%)w}dra zN1yEO@VnJQd-!nrxI6GJz88R;Hi$V!U^kMii!jR)STzgWa7N3lZ?x|ee|AGXbR;HL=jw*b}L(WL_IITWj_9A9H8XRL<&0&H(~_K6z~Baw<~!wMAC`u+361%jy$KFA@Hp>^dj zYf5N2m}dK8&#Aw+4anC0Ti__54jZQ5(19yx$vB795Vu_1X1g=tGlBk;yH25gXy|k` z_`&Fdwal#FZ z-(8^V-VzSRjL~0Nj;+|;FA2jXu2Z6@!!rrw_glQ;TV8Yd2v3Rag8O!=C6ezd zhDs@Y<`=<7{jomcRyaG|C#6o$x9Uot?wmLgPG;~$;a5Fx&E#7hw)Mm8iEXbr#lzV@ znDQMPJI*g_{_W?Xr&SD;zuq={pgb#fqIK*?+sNH6$HM7X$0$|(WD8AJ7P?W+5gD$y z^408gLoF1+<2Br1))2RmW!T-7PV(v1vly)Z*u9p#d;sga}?tHLnzfXeA|3 zwjLB-c*ow~SM)2~_uPI%L7?DBVqW~}lQ`v2tk!quKQu(-UWkv?IW3Jtz!fURgr%y! zrY6z2MR);@K*W#LuB9I>kNa2ClW}&Pp5yTbv!W-DUk~g}n!ne~Bp2%&dwcY5mfGhJ z={KUo>Yu#eVcovO!$M->}oL{?58Q>|*$ z^-QvHAjG!sTiWR{zN^ezEi@9z=iDTWXi{*MG*`=^qhDuxIn!oux#}C2M-|mx5O&Ez z`8D-h?F4!1b0Qudo=Y)gU37Uf;)%ENw(m+) z&_hp6sK$@w`qWD)G5J6Oh}L0xd5ckWXWMDHeIV)250ygg+ruC8=}t4KSrbuy@FjW9 zBKKLoiRJ^R2#M+IiHN|!K(#;GU*whHweIN|`w!}Zo8lJCIlG>2i~5gFY0UWO3_3bE zB(<~i&8(@~+vjs$j_8L8USs2PK9U!mAjtx$Z9R(`dT1#(C)*TL>W(@7nnNpamCxi#j``&$e4G|Wo2&yU;I;3 zV#XY^uH>mx(}wmIjP=Y?NxPzL%GUikjABQFeP@K|Q^n+FaC;9v6SRCnG2YW%mRaCf z!JUY*j}CELfnJA=AznW6lufXDHE9Yp{y#0*a?*P;yq@iLyJ6J|$nhUaMl2*0sG6Xv zmA+pBCjuBRvPpk_#>gKmSRc#j(a5JoUnh6S>fCJ{kgw!1vZbd>l1jY+F8%-Apt^=f z5%2vf)Z;(9DCdBcds%}QyGD96x;gn0^$KT^g+)C-ZC01ez<$j1KJY0N~Fvh&~J{-4k7*4|tTlQS8R(<@^e z(@7B274y?I0WDU;hI73n9x{9w`-dK9$ZkYu$`54wXA1n_Bz-D!nJY!%d}!O__7yKS zHBHP%{*eBgeLnA~a0*XDRd23q{gj--F{Yu8JldxPP&vu#ab{_D2vJ|1Z z=D#Z7f260c)$UI{va6(9|0M{ig?n`ZdM2&bv~0W#+&!4Ar!QSC zSjuU|9Eqz6%X~SBOqJ4t>w5O6-rmk~PtG*5yWB&&v!b#4YG3GL1olNoy2yd9#^>;$ z8?GZ4mygIKDpsT(*87RXnujCpeDz(|Oy6Dg3t@JI{Avi=t4>|jbMmoU<)WCxY}T~M zTtr~ZMqY!M(fm}ZIU8% zk+iZw0eaY$F}_u`e8{x_+SzSZS@FYfC$~RcBGdhm(=|cKWQ$;620wk}*UPVGNai;7 znyzIP6&pxIVn@bFrA$nRh5R}euhLnR!T#cfOGKHOnaMqm?J_AJHXjxh7qinF^`wi$0=HAjkWxWtq6rx#0WwJH|Xaao#q)N?|s5zi$FL%0V+zpxUYeDlRke|5D zxB91`4t7+Gtp9z}lB3;ZXF(3Y0J7cT_k2!)w+(~^-oaT$rmFHkxV1iv?0EOAqz;BQ zfL(n*OHcMDg31UhBc}(OJt25mj_5y|!k~5<#xhZU5F4?b*m#>Y5jEZE zp<6utmFsOZ`Qit}&|Hfv$$s+t^5oH5ok*aB&BPUXl|N!JTO&#+-hK4!hdg_XL%4)7 zq@gE>_!)26tvN0Ed`(Hdn`oIH)2CD*$sL{&Gy8XIfS}c(y~5HzJW$iJ^yJ0tOc?hF zTl7*dGG)f@E98`bxhe%4;A#wLYqzKn{aOdlnm<{i%MKS|sfNAc1QGOw*= zz+a@^AiD5FwfNJ!@Tjoy3xlJD+{&-5j83IxH3#sf204Phg_V$m;WTsuc)?d`oZug273VY z?%hpBLH~d#B@rr$9phf?0%&e1;`Z3%WwjS%1o1h?z+gL8>RH;q8L<>4up4tHxlO7b z{@=f(ik>9FbH(JUk{8fHGY^>G`DUOlRTUBw_6$TQSZ&~ICGLGlLuY3OXG7gHg z*{`yF&DUl6!NVj7oWyL`b5jQ|zwt@L3ubTijS^x3h0U?Ho3knMQVuLH08cb&G(o&Eh^&U0SW#L9~~-XWiJx@ovZ;wMk|a=ZbtyH(9?d&fds`9#!Ga+FOvCyA^TMuV^U4PNg$YDhMKpHfF&cyA%;_$Q>nP{e+n4!`{Y*DuyKyCw7T z&<`G%noV;_zLG-Mk%Wl&*0sh0w>F1O>pZ{`rAgr?_iEvJzqf#Y^fX zihB$eNMjCL$XGG}^7MAS5iKzhLE>tO>BOBmutKxY57Y%fx94tjtO#216KhJKDNne2 z-<}j>?)I2Bdo++-?B7W~QbY`_ZDR+h-tB}6zua2r`P3i)?gY>+d-c8Eu=J0-#2Z1# zDmloXFhpLzD6anooE`aDq6-%;*b;lwLQ9mB@k(-Hu6Y|wOY!0wDq=)p7X7Vy0JPe2lUUHu^=344mt_an!pq(5?ugYSm`b3 zlrDnesy%|StVY>26>2{l^?VW6h99-sZb_l<&SRs-g8~c|u~e zmXI^;ra)`O;kDc<@w){#7M-2&=OxyM^UY?#EfD{9EQtwRsqeHrtj&cxy&L*d?FuYW zFHq~`$HMG*!}wc}WcNb~I`ozCIPU!4lWXjNC8@eJpOs?y>&KYVxqX&Rg5ryUVK%rv zPuq7(o}2h(O*^-Jg;N=Z{qttCphF(|!9n(0s~KcEi{96;kY8|kd}Tj&FW-U!m7@OV zpP52Gr1+S_r_$2h9x2SdKJDBzsFhZJwhG#cW<_v#E-qciK`cRP5up^Fu#P;F7R$i` zv);i$^R~9OCN0P_4@U}H4FtRzbOwN92&An$fjJg8d}TOM6#?x z_O9INfJt^dyteitY$41m?2)_q_60}Cw>BV*0_~S|tbg!UF)iIWdwd-9z!Aq;Gt=-D z<38Xmvo9XS#T_OpPzMrF0O2(sQob-Z4`_Q>v5+F?oW~J987h^x?N4+D=tz7S$!7NQ zs{f7uj52tQBxZ(Rqu7Cb*|^c+d{fmtL!N<`2U~r(a}xl!6SJ~MDOSuaNX`B@_JoT)K%eif#AJK9yp{JW!x zeb3n2Lx0?PXyM1l^FRS{1#cWV>40ydy0mw{Wlbeol)seDCS>EydXkC9R!***$8jjF zNqdDNv5Bbhs|WTBmVSsfWbEFr8o z-kMF`_GV~*9oSQOU>xb3Ir}1weXt65)+s4)0FB_G5KXfE(iVM(opV(p zWw)XrYeaOnx8T`D@MC+-3^i}Ubh;NSlDL1?YI+u*kc5oW$KdMt{C1UdRZW%=RF_Ue zb^qpiu)NxvVAUEp6?9;=@H;zp*AzdU?P*Ofi3|R2k440X5zk@b za7n&Jcwc?TF=nTMPDcM}k&YMNlX!pA06~@~(lMv-Mo3aQPlkpsmf|z} z?C!VYM+q-$!W3`fjEVvy&^^EO9nSJaTGn7qaFTgGtS%b~_rIF6G4PL7+TX|-%8HH3 zzjj^1BQpQ|e;Wm@pfi7kb!az9st^?2&6xS zN&t~oXN&}=+UzpFvzkd*ynseN*3|PsWRO(2Oc67^dlE!m1DT1`3q&L7VMB`}9lCuJ zHUqJtEf$Fyo5yYwNJIc-XS7W>Q5nYZr^$jY$Q~l~x6-n~&CH=})~Mx69PEU%W%vNR z#xWKGsx?epG1^5{{P8W&^vMDxD^Sk_zmL7 zh)W%8BSC_+h%T(4Y>@hD^hCMr<{9a=8eaHlAUQeNST9nvsh(v{BBLYV z(Ls!;tx=9MOQU(0Db=e;|J;SrL;5*!^HVB!dOTLg@8Pv4dyOl0H<3%$g9S}xWn~Z! zn`v;W^&wGsQ}e{`dP`h`Ztm&Ey9b?L{I>3I=^^#58D+tJLY+(k2E<1LG*G>{HtGfG z80=sn_m*5%Nl{VJb8OX^M-gha??ZUM97Q(m9H)Mx9RE)zj>`5wv-%m9AlE+ZQ(Sf#7P#9r*H3RJwNt99T)%e z6hHmEqM~|-Q)UJyj3R^k6kFCHFz`EPO3S{iC5%VVfBzVgyp=+GG*VtZy5&z!I4+Qe zIIy^pljZY~BOJ9g6J;rXkzbRSUe6DaL|jl<$Xc&vjzoTu5YIEEd{XIJs2nB2b1AD% zI)aUQv)*mA!lhD9^?UOQHdU#g<`s!A%Zc*=$*;G1Fz$Mu2U|6YSAtlrBSFC+ZRH9n z8}AEB>Fh`8k4?D4D#Fq`0vr~)zkfYwo4=zLkF4@Q3r3I~*#2he{GFs2Y;tnxB8AYT^nim%f<$2PIsU z*{$x2l#1(TPJ0Nl73+eio$LCIB_P?1FpvCYL$|d9Ew*=KXEzAmG* z6+wxQ9gZ<;%}^Jq*K7Jb2Bb z%rYfF62zjkdHO@?g8URq?jw<4t*rHS zn=FrV(K=*>U1<22o=LQ-)uohc-je+n2N}f1l+FONb@JII(ipzBVlvn9Co=ciWSR(R}ZNY88elM(e@5CEh%~1W-4Ms6=~cZmkCyb3%VGGyD>J55I6~+ z44cSY{F5EkuK02aCP_&#{UD0(&!;%6cH~5l^ag67rPAH}+H=a&CS{i&!<|)R7^SZ1 z6~SSrRm`JnFFdj8!7kf!qGdmN^7p+EPTVZAF!3X9I?v2kPXy)^7|Ys!0l^?Xlw z3qE}eK73fw{3fj9VU1nlS}(0w*N(B#cymeSUi^7?jG6yXe5Yz3>vG7Gwun7WTit%= z*=xarTG&DH;8bOPpDo6lZ!ouTD^`W!^9PidQ;eEeEYD-I1xBLEoLp#979dG*(N{mdo%awk)^z3bL1krh*sa?hoFyn4g~ z>+~x@9{sR4cE4G;>0-374WstwG$#&!x?{)q&n6&7s5&o)S@k*r-lOj3 zL6^qOXqp)%hsvfKv}vK&j&@&>C*%jFnLBUozk>4R+n@0CGTmBmY{793`7Y($0Pf)@ z;qU(fDTE|>XGP3R_r#0Hlx{ub_ZhrU+;^AzZHq?7b^!_HW+g=A{(b)hERT|-k;d9n zTeXlzr0J{wX{pO5G+jRONM(s7TMWDBl_joZMWxxL7*k0 zY@}$}bDv@QVZ^$Cf1MtqKF-&u#`fj(xq;@m4$*Km)daz@f^RlrN|RWeq((Gl*DmfO zTl&5m%gx^Sx4cS1srV6^v8EKh9MX-bmD2b)J=NAT;VqpH+X^iy*A%*ETWNOYC4B+> znr6HO3I)nUQh(tgxhYYHr|Bn2mmfXbQ4VB{VoFB;GH>y(VW76uyq;snuit$qa|Tgt zHS}0%E81a7ccU}nhGqM_*RhzXT_$P_O}ccIP@?%80r`0GJ^1{QTj>?Gg6xXu+E5oK zvU+xK?X-$G4YgaTov$^jDza|%?wbhrY3A)_&Enx%&)v~*;Q*dUIZ*!+GmKn<88}zWO>aJF14^%GFY?U>TfFS85kbjI#`Ipo1Uj3ENzbrgLkNAZFk7c_A@0yv49vNSF^Upyo zuDl&6#YcV}efX=img*QLF~DK2uCCavI_{{L{?4Zt{Atdh&6&o3uatiQO@SfQjGPwX ze6Q^KHbx$NWX=5?RoChB1||!x{ZO(0lZ9tTeF`>Oy?f82R0fBtT8{{N(Hhj}Uzre) z(z#Nn0#&T5SjDfy*@h)>^yDfks9Pg_^G_=&&Q9R(HsP*JX+WTC(k{K~#+={3%aGpJ=YDC62Vx+zhQ8s zXP0}V!6BWl-p@JQiOkinelFhjHR^R7agnzl^{)?2iyItcZzAab^qH zUOkECAm#}EQujcIw>u)Xze^EW9V%vt?awu1V$tF)34JQ>5i-paOv@41biOK!&*NN? z)?Dt2*6TtLm&)kZmF;`IK|4-P=~~q^XAgW0KVs&2{J{jyHhPu0k&B+<3EV?J!hN6f zjeE0LT+*QU8H^`#?n_4{cHzwKS=8B}#IltG=S%P0Y|2a42O11-uKVZnnW&i2Jr`u} z;P-!qLdOa07Jk5F@MV1`MVGP1vyz66$ZuzR3ih=hwA4Fvz)p~Jgn7xKZ0MY4-E68n z>dU@@guNOJjbrhd_Y_JT@xYIdVeoLJ9hb>!_|ORahf39UiwJgo?XGk3xqn+;c(1x` z(M*L$l%3WOW3HlMYc*K#ouwAOrT!YuO0Kr>&zzO7r$n-oCp5freH zw&kQsd`5bC`P;!?kNkC7XPGQ4>E5Sy)I8O7fPp)jjlh7$rj$8%iXb^@%0n{&8P2_} zyTi&#FbPinI5{tA^urvzti_sjb<`SP!N^m(9=kj1?=Rzr?^0z<)*!#hz`uU2T9PX0 zU@>TJtgA3^p8mnC5uvo=o3mbn7yWtLnQq40J_-1zofwJNmZ+o@71F{72*nk+XNL@a zWQIPa463~uH;>*1HIZ&HLfI5ZOOFhqwz8pj!wSbE=<1ILx#E`5sGsp-#+#>meqWy; z&_;j}i}!&E+0bek#+7Aepq7@FlE+RzFf?A`KK;lYf`V@YL0~`kWP$|Ri#Cc9flt4z z2Lh_vBuJ6MCrgAr{W|ZB5T^Rbp~{5$aP9Ws{_aLF6maKTz_$HZjNVc5UtpV&cNt?mm>r%Pg ze5JhEw;t5r$!@SHP}BRea4=WJZb9u7S3V8%D5W!-U(7;vu#f8Y&2Tk45O-ff$D;TK z2$}EE19zP&Ra)1ygIOtSMTy40iU&#{Lg%GM+K=$`k#V0MuaQ-mizi^rugV+!tyzS8 z@tXNq&K*6)q)Q`g!)F*bv%p%*?F-^@YRxqguvZLMfi@=mc?(ibfTpDIRDPnRm0il? ztJP>(X7b)`S54A^J#%xp^hCiV@^faj(nOM#n@I*Oj$Bl6f+XvMgM%3$?&9&qu$^@8 z3g33wnAuHvh+pTXA5f}gW2{|;T8%(Ajpqamr?g@C2k)B2S%#nM%g1>8NsCB6-hNvE}> z9IGnrUQ~hnvLN0_Mr}xB@3+p}Wt0~pj#$1sg_WdG=&KFo)(5?cVV1Ymf2~uG%6Mzk zEQ`SAh2roVdlC|cbGPz-J;r-cO8vF}YVsL3dg|ZzD#Mog*Sfx?svd-w z{7Z%@&+-#@3!-HuJbDznos7C7dh?8U5-_e9{yB(;hQ7)Iq4}bq;iHeJIo)^WIZm%2 z4IqF=4EZYk#pQQ#4|{v;Dk6{gk~mL#JtpGXvbmCkJ%u6Qb|zp!3Psa430mU=Q?Y!J z!wtp*5=%br4b9u)q+&dSwj+OGZLK2AtgbGGAy@qQZQ2R7Q7>IXn;<_z-#V9)gigFA zB~pK#I`{6cdwT9L-)F9S0`#ORGw)3z)`TqUM`ht!%Gh0xZm-ynTgoj4_YG@`Hb*aD zOcP(E+(20_?ki+lr1^@#ZUH7B)qu#gdN@ut=$Y#9sn(=u=03XALG2<-Z8{2a$p53u zSiN$xt^HyHp_J9nxayzz9Yr$;$Ao>0#*}XYWS=wn;FIcPpJ4Sm(|a-*{=`y4`XYvE zMHah(pJFd>3Vu+S3Q-5sYV+PJTQ&{QIEX)yc~x8P z%7zaK)$ieHd$Q95XYab((Nd3_$?$O5#!0<#&7PvN*I^eUX1%qdNJ`bRVqn64`{I&= zK2en<-e3-5YNpZZ2JDUWQeG4x_@- z8vkkoc`7|oq}B(c*ou%kA^PtYI4sO*>FKdK~bT?K7B^7Gf*Yq>pPX%~s?}xtjg; zx}>4bPf3>88aE|HH6QKO{Q|SD^|I_A?z^+E=yz7sQPv@f)YwM#cX$on(%u=5-S%(Q z9V>Bl9%XN&<6}vpT{h@~tH}TkW@75hjzc*QoWs|39O8zu;|^=DzKOZ~$$l6pbQ05Q z^Y%q3SJUg#CU^Y6F*tz}3$aq_?rdb(E*0J|>ZNnzy!)1t%-s6(?$46Z({+FZ(had& zwnP^;p}HyXr7G7%TH(8Er0-I%1aUR@;>^NQ-#0$(R;S)0!kWf((JaUJD^s0uRVYZ- z;?+QrU}`bdEmiJwWj2@`g<1VUkEQbU!8h8NVAx(QJ+*jKN_%lpQDmKafZ{~HJBlmz zR!zLSSWWx}>l;dPuAxZUyNplHPpUWD=bLt@P<{O_Wt4&`^Ds|`FH}_B@oDI;>U(g- zv~bs;(EL%PnhGwS>W^4fnJ3E}mDZ9(mn09r<(GL>62CngvJCec<6r=HP~F4mSB^i9 zyHB>K1LP0opOw|1^;g06b&Q#5>~XYTyJDAPd& zp}kjDg-v>L_b!{#`^j-A4v?$Q@iQumfc{!O1%n9wjQ2R>3f#kz0w8lEIpI% zSeQkCmJz3ETKK!K3#SFy%JytW)3PaFh>7fOKDv3^vY&j``jL>x+Wg#{yqyECqVAKc ziD0G8D^*iL5>+UhQv|yQ$K>yJ3zO_pr^iXE$qXnF>CM{oW$ByM>N~|+*$`3gKm{nq z_40;-I06x+B0619gkH}Z!Ac^Z`tn616$Ifz&wCgBO<(1*#aluk5PyW??Hse(&8^(y zldzilJZ(JkO0EBI*2?^&mlS(eX`N`)Oug{YvYbcK+ecO}3?44Q=n=ek-3aOmS}s6& zCp?Bsi}1_U%rA{(WtkR7XjhaRuw1%hyZ$E5fEMuDi|sTESAdaBwg2AhgO4YEl7#JB z?Ac`(dC&N$81gp-QH7pfoVLFy{dq71p?qveo7Xgz9@eo4zv&YUb1U`n3=D4$HF~X>AX6FiN_EO2 z$wTM%m}uH}J-AUNzIV(7SvlLWgx9?x#J--M45zd}QGHCc0cG?>oqe7mTtC_3wKJ83 z#KuWtV@87GIaRtBE5Htu0??Pa83U5WHqtr%*!=oA+y4#}2(q-}Dmdiw!7#R#z zw6wGya!~8Z^q&4E5P9e035D!j|C_kj^RVrL93ufXbn;W~f%jBE>bk7uRB1wCI5y5Iut` z!IW=IXr(s!)fojC&S+H`bx7{MKKMG@7IJMjL|&kew)~uL!#B5V@-E}we}4D{KRRc4 z$x;^eFhgL(rZl6|jlV`A@~whT%G&R5Iz_mW{UR2hnPqre&l~rEccU8v z`vK+dGu*^&J-mHmtesFY>Q$dc6V+mIMxm92$8(*sVyn%hmCHtCMEtBTb2doate35} zdoAtqW*h$Ob{FG|;Th=N|{|Ci?5MK}t_{sTbuo5ubjJ;_SF+4|pUig0aP% z3|L@bp*;qYJA>U9TP$(>)mCL5SP^26jtsZ7v0=AB>e;|1Am&&AqUsq*disqnZ9)co zP7qB)nSi-uabqq&&Q6q8GOa#~t|RZ+^i$<)q0I3lXW8r0^{9OdGp3)jzW!_`z;rYJ z>AF#%XLL?3?MeNMeYqw3K|xYRWOufUNesv6u{aXjF}G`bL$_@zTJFV4U;fQ;MjjVr zkmPzaSE-#Ue=E-8(WDzZ&Z9oJwe@b_5LDwow=~tDLB6wGQ1)T8Dvi|hA({+{PEuq%ui7A?>s@jnP-AAOfj zuRFSUm7PJ&jEIuS$A9k)Quw+$GU=?}Ho>CAn-fEYe!x<@2guTZ#>c#n9{Gt`jc{sS z2wRxY*vt(kzINGNbF&@_68wYfD;e7PpJRSMVERi}fMTxZ+!Pb&iAT!gT_iPn;EIY2 z{OWw}GfR1jmZuG68nCnIFO;1uuYvtgG6~7-xP4oCJnq?%KGAKDKaVB88zL5bV0Zsj zgULCrqd|Yi092s95@IZ0A&L>s1wzNd&+2m7+D&HioNpX1HBR80k zf9LS9C7`%A@!>&jEgyuGY=RqR>CZ^^G#hA6sKkg1N1!sc-^%qRYFzbW4co8aYWov( zW6aoX8y@Ev2neh3uONaFep(`UE>xsZsUSK?EZ~5zQT1x+sOpG z$v?8UdE2^BwrVG(*l=^vlzwl!QUt{Q)!?m+zjpGzX-_ zX`iYufe~`pS~guI_KlC%f>$*#!(fvh?sUXR^odJIq#J!^SqTg+8Sn0B%K^N~n&pW6 zGwMix?a3QN1H>GPNO%Iqjb7UrmxVN@Br+oBU_VK+3om*4iE)9O-C^)G!V4jlKY8Zj z`RFN7Voen$Qt8Gupi$f1arzbz1+S3zH~rsJ8X;F}fJamfDy_>Y9sRPa2q>kC*wpLA z*clVQ=d`YcDrRcxLEBWe74lr8qQoqBjV*?Aucwv z?J-UMWRg7nfc>uYYbCOa#oGW-<%LZaf=kG_-&eowYA^T>lAeGQ5a(6rKICMna;B`( z-u_{T+wNT|?Xug4vRZ-^pZQatzxfPPQQx`%`uo&2zqMq_6?<)@oKra;ZDdLAm9CKv%QmvB3xl2L@w(Jy{rf zdtrs~-~7+8eI0i!Bqb#;t;ET_VeWW79~?jiJK4>8QrUT~J{(_0=OGRtr88_<*E8J7 zn84}c^E{}s#LlS>g@)@zIes`rOf5U!#(W>5Cf92w{Z|mDpb(vJB^xv>p4ygxdlpYO zZZA|}3qC1^F)zP+D`@=}olY|`oQ%5hB>Qrg>?SY-itwk%g|qXlH}n7pa{jA_327bS zi}CKTCjrIo8IXMe`6Wu)&pUY=O+iT7cZUkbZ~w<)dqAO9ggJE5QQ?md@y;d+^PMP$TPcgg4dv>+_`{4?gdpMRXj*73F-;`zM0EWZ{1{AaCgI@H{_P$ro zBbogV&ctrj6xh@K)l&v?0HU+6i@)L+l|GXYoMSWD@By8lB&OMmiIH$(%ij)7K3ze8 z#RysugBfayo+Z5LU5XOBTAzf4yXp!FGI?8fr6~b{7g0#L)7W@h(_*gf0y>hVQ)Dks z4Lt_9du(g;XV5aln^?D|*hrN3f%Qg^Mh`?e4XK3U#tHfOxC_>$)uXqU?Z5ZA`Ndpr zMEFCl!V78(%-nMGwE2-88N0q+bNZbUNV)u7dzv3aVgFoPxZvN9-CN97J-5`%D9>Vn z6dt)!cMf0yN{CAFSn+xS9|0bKzDZoROLbXUdCQHuIQMPA?e9UT4D8Zx2IyoSQ1wI1 zJwOZ7#$kBzwSY$kBv^O;;|oBD1+81wE#5`tiwfmyq{U2F(my}Gx58K!K%$sABB_Hf zNeR((Ui$4B_nU-fCt%089*iT5c1L2vk$GfFrDX}WoubEn?gWu9Reyn5a9gb85Foys z%hs#83Z_B=g0!5*y~>ACFdxA8EHeD@W=fzs$(rnlu=J;Ia)Qc_As!R!%Uhs&Xu^Hi z3yLL7TTyKhd0VKZnW+3rgjPtf@vETDVg0VxLom|@bdmVJ;P^m%mi#RlI#Duv5M<%C zPc8I=@pCQ>elGN;Nt#kLL3eN&lBmV=Zi|J9W-)O7+~F}l%w4v4A&&pVL1@iv=`}D4Ho;`NO;hx4Jgk(k(q>v(@ADzHqqD3=)_^=HW@=5PD z-*t(ijHO?Y$w8Npi{jn~^*4Qx?W!%cInXz2g#K`i@uOmQ@lhvS_wc9DKQe0<|Kl-O zARL!nDTe}7cx?%r`Ey~o^c7w2(PPtliAqhxpz=Rn@5Eh%Vp}tyW&{sEZjqV>G+-q? zH{D|E%*%3hP!cvi4Z;!&f0&&iaav=EXSEHzn@uO;zH>{WDk+Ih`PUg}h5ZyC<>wlj zij(WN0D#{n3$l?XWP;VM!+Nb;I4;crdMfe$L!kvHQ;-;gx>r+9yg0&U^W_|RpGj)Z zJ@wBnY>_)}{G@>7Wmmjp(tm*@TK;cH>VSYQ*Y_VQx~kmL_Bfbx`5hmoKa5BBaac}I zY#pk3_?UBzmLXm8xnARk5(aXXcoWy+m43QARv>^rD$gFo72lzq$CqizM!)4j z1J*%5=+P~}d76Zo(f>0_@vbDVvdhLsMRWLeU1zqhS#>l|_Y7TO`WrEJGl0$w$ECqX z4w6xT`(-CKYIhoLGg@Kn2C4uwwh# zzbIiEaf{vzf#TufnGlngKR+_|_Vk!Er)piKO8MbOrVB(}EHd%9j;84K9_1jh`3j;B zfYZ?v`&y7tuGsjV6UF}GB=p%Qm{0^5VbL%}NeoINcU_yZBg3X*Tz9n|`l_0XHo=el zo$8%EZh}x%F|@_h6u<+s`qzzSG!UbGPY!WKbR}lPtL@9MHON6KZwMzl&?R7mnEt1e zpxyKqz+xi%Y4eq@;rs7AAMmyf<*y_e^!?X5jc_56r!EFKdR^qIv_-Q}>a=rThBg(t zcwes-^m9iPW?yxg?vs50sp;FZfZtsIjP5POp8{TVXMTIB$YrtUCmshP25i@}#(T>& ze$a*{0Jl7{(32j#EX4RNg;mkY2`(fxP}j;gYEFq4i<0uhn7P1AeOZ=z?asMA?9ndW zn;3jXigslKkudwVHxC)B;LfMaY{wPY!CTL9Pse`1*VZqO`DRLfk&}^*#0o zlwI4o@A&q%giv%olmRuqaYqT2+iAZO{6a(?~nuj3AZ!MAdQ2EdJ?G$0d36*1J% zP_zA=l<$2jJt0@teGWa89dXS?YxCPINVh5}t}isHE`dk{;X+*S0n@tqo3gSrYwz)sq9fd}qph-yP#ZU`_RNFWJ`px_V7o(E8PvxBXw#5>;jiq2;-muv z|FIZwCaB;Y&=N-Q6M7jgL}y;lgf!Q6H5z$LSqg z=Qy1MuAye5Ki3zXI|CZ>z*ouN#-31IyVpS-M0neA3enuJHCa2YCZiGH`p?Lp-F+Wd z-x078c!L)*@~W;23O#np=R#9V3y9DQ4Dqb4`2&Ztc&r8Puymx{S;+{9-=c_mv13sB##~vILHgCM9g9hqCeqFFmsS zda~)UHln#8&KR>W7ofYj-N?Ui)g0zm4{aeb5cN zC#-5Dce390ZLJnHeE5szq()+Z3vx8_YGD8MJNQ1Q zZ#*6IMD9mg&({($-ZjTeE(W#xus829@qw<2$C*aptk}lGf-`$}rFj~;4UuA#S`8R5 z?Cet^-)ON2#2J316z_SdQDu&>*=l!T?efN0{8S@fLEO;>UqGPiX6j{$XLWBA7BxU= z`lr%UV0VgKx6Fr%taR5EJ=MIDrnR#L4U>jXSh`f z&n@R-NC%7}ZW+q_&R+S!NAEbox43;NTXX@l&i& z8e8eF`@B@TtkD-cSpgC|1)>i6w#`AysM%I`FUOjKQ2J z@~BI3<5MI}hKL3>vIV;B!j88}Z_T0|8Z$0p(R*`7t>ttKsF9<~7&}*<)Gj0!zd9~e z0^GM1djk({P$-J6E270OwA~)~SQkzS2t;pVt3hGg3XpPL#2$;G)H{qR?RI5yl&1GL zC{w{eNR~xofA?l5MiIbt|2F2n@FMS?l{_M>WqnOozG5NV=NaZwEx*C<`Sc&2rzHT{ji1y2ZXkcQ%xH)vxYhv}zls#Pcm5>te@eTh4(bO6f4%<8vXkpt~a4>i9m6?@w?$m&9ZYVKQYTlkw|@A%G-HFl6r z_eQy5za$VnDuTQD1@eKB5~mAZqe>9z8>HJ4`GNGbH-#TUiyloNIO zbfLn04}y^+ssjyz!KtbVh)Va~tE5Mw%}>@&qf?3B-$|?o(Bo^{m*}0`V%rzZOVA}9 z+XLV4pmFD~8qd00d{XFyiob97xTILXwK>PeR~Twg`X*OvL)UNG!LyU5aNKbRUKLC@ zh3?~Ma%uTpsHW3F$zpDxY5#3n$YinWjstw7cKZFhB0}6Qfj;aRJvniVl@^#*fj24` z0Rg$bf0EEfA@EO*^Is-l=-nb|G2(8ClS#9E;nvDJu)9i>`ty;$aT38Ld}B!pF-ZTU zXtRgXM)2KN$jzR>y2rbBezAWFZCRz+OjmO9$S_B?G^Pa^CU3JYY_N;hAr7yT*3V4X z1KM%(v;d7wvYn2&$cu&WCmd%gYxg(}+6A`qkz%{xNmk`p5|i zPt%2BwpRt%tO*(m+l|JbYb&6SXfbhvV%VH+TH`RfzkN4!T=OtS!I+~eD_SBulRm|L zKDHM%5#IAe%ZRcyC>TXd{UF|I(Yvz2Oxh?Fcvpnrw=o)Y%uaC|OZohv?PL9x{m=*w>=i{E26gMGQ zJ;<;sBhy`M)OO0nX+{-}2V?Xa;bBfL=YXsyF~;*vQwE6z-{P_qBZ>)+Z`KCct$Q_L za!)9G6uz)_ee({xb3xG4OqV2g>UQwyXPt6y!rU+9Kb;ZTQrP;TB$FLatmZK-^}@IA zT1M1LZo`ibc@A5h{%=hoi|j*WH~K%?xlPtCV%w#vz%3!?m10_oCi#4$zF)}wC2*-- zD9k8WfrCQ|bBlk7c6UjU1!~{wQ_9X1*isN$P(rs>6)3(0f6@=6tBVE>DF6+x-9%;tmSi3ir=>+}vG*zY#_&@in zWMgzz;TJYIDH3c9uTUK^C5C98<*EC!q#%w$nv7YUK2^ib+QLtB0HY}x8+aE&N3SbZ&n_-k-xJk!# zn)0oB{qYiiNc-#I+oDJv;(xzg;1m%b)-I>J+ z2Iuf)9MDT*njEXhFIeo30Uw@rWrV%vrpxztqbh1Xv-s73O9kBgUp?dA@c**AisAn? z)%CQ>fLOk+*rR1o(~0%Jc2SrICztPvd?yZz95XDpE*XTb94R^VkLL-rfc)Q$0z>!) zl!(Jt$eITBltz}y_5ApHPO3xMgApV;X@9qvf>vCf9 z5M-lFv{n|Ry+LO;H8~k>PQzx@J+gevg#I>j-!d2wC3*A)>IyM8b#9ybS`^#fgLKk7 z8yC+jx%`rR7{U*PfR(Pw7e1`M?CVU`kHK$=5n5KE0;FE6lP3^8uk02gR9y z4shk)zc9>V6vP#8@WwOJl)K@rlG3+dHulaPQT%Nzp=R;Ic5&9W0{WFUvGBE%&9R?7 z?$z@)e?K=5QxpD(EB&V7^iw`Lr<1jU{Wk3WJ-q{odY0M9BYuuW*B2Ag$+V<^hw<~J zYLYpiy|fb$Zfg+}ORdR5r&?Q=D-S{5bFg1RW~own-QX~k0}T4vnbY-SIF)JILiuEfGSi-H189X z3Z#CLB@7H(^aSYjNA?hq(k>Y((~T%BFGnwz8e(KZ@pf~CnP+y1x^9End#|?g>oKAl z0hrzOP-1UmV`JJ%*Wz&mB!veW*V;npj|L?z(EaM(vENuikW(NuRquX|HrR5ufDr2c zGP3_7YeV60{!NXpa6Iq@GAC0-IM+JPyt{u0{89_Vf_QqPjC4o-s3MJ=mDg=*6uKA+ z9lfOUznlJ5!BNk3nf`Qx@FFS%y!f?^mDLk4q}9A5tbkwk9Rq1(^jl&jwBP2`aE?|% zT3X9x#z$5iAq+|lP)J4RS1qD)=3Tw1OA;uf|D&Nq>pLx4#^h z4~|k_vBH$B2C5uJJAesVkdK>)Btr5ZUJ#u{I=ghkhU~=8obgwX%av?*BFa4=fp8`s zeSBS{b`TWhMY@M&d=D?v&vI+c5u{4M@&3O18s&JlUmj2(9Jlovl|Q{Id{Uo;?``JE zs6JJM5GCqjtMk}Y^a4C#uiX!Mc5~*Ta;rDheqW)!qPP182Q{hoe4_v(qAH;DVExR2 zr}yi6)mb)IVAC8_07ZX6q;miC+rxlf?lczoKV@1g+ncs9MloTR=Y_y#zEJkZyfXFA zh&;*DEl|wtI6S928S{;Y!!uCu>xG9y#KHGr@5ExP>8anycFLMBVmzd~Z}|iVL{l8Z zl=e_Np(M33H345Dx%WC#Ea z$*IJVDM(Y~H(r_+!y*QPV3NR#?SEBMe!$-T62pp2p4hbKrN@tr<%+KeR}@s+l^#UJ zKiUK?utE+fAQS|1U_mxp zWH}GWINt%BVLKH9V~vNd^y7dO#(|f8IcO~5x~j@E=?yOZcw$IT)rrSrNXfOUeuPjR z9N}SpUyvW_FR{1p6D41SiZ$+M@$^guUHsj${1*{82mDWeB-nq8d7V%&>|6)0|5Yhe zluIb%ft_pvz4m%HAG{(s`?pf9#Hz|XZC*1`dXvW{2l=1kzcYZgc)(UF%UB^Tu!wor zJ^l-`oGMT&GQ^_x^;Qqvduz(<@qk-%p*Cgxb`nY}iuw1EUR4tylSxrOBzt}^b)CVu z4P;fnM&@ogs0g&RwTgdJb{qEl@ohiq;VpGi(00uFnssfjz{@m-_h@!(V-^*p3}Z!E zbqzk)*yVS;xWCzaT;@JwMKAIgx$f}#vL&ve} zC(ca}A7xkGInTc(aZZjo(*XKCj#24;1w|!ER%O*Dl>&^LPw{IS*&WN8P-m6VPYa+s z)tF|8B^1f*mf|NCNCuqdAeqr4v?hT{hwk(Usr0a~JofSMS`$+Jlc<7CURINu%K_9# zi!Om8qzfPobT>MurVCu~S;l=l74{er+xd()1Byy&VjX{%6Qf1l2jsNGX2HmpmjwK_ zo}HHGsk&HV8asG#9W7lN~3uC@*&({VnTet+z>d8z7f=yIN0h8zbdICNzZ~82m=X|@_8YR1nY1aGa;X9GqOfMRALzbd8%iYb!}VN_yyOI zL5I!lEcqsJdpAj%GMrhnT_i#e>f)a2?qwYq^l5mdtx{C3n);X@7Bq5y?3j(I@Gh9M ztoX7H9ek_`a^twL;nm40uX4*)BlCPawjm+O`)OUb_q!hl?V%pe|0Ape7>K!`fCuP@ znZFzf&Cx($!^8!fD)ZadflwyqZ9^yrRSjlVS2>+>8)DIB;00*GYgU@+! zxoOBW^eq3EzfF%``cbxxzt}ZKuA&&~sm*nfM(cnK4knwrl%ti$@@Vsc3DtZ=kVDi{ zXul1S5LQa#${N#qDsS+wKfh9&{R|}K@P2>wXE$^y@0Zc}rgsqxV%|r^KuKt1nK&2C z<&@NYH%q}RV7OI!%mVNaF4FiBz?HOdr4wya$s0ddW+T3;tfDlX&i)-k3*gsN0(&}W+M0b&9>UjUM*fz4U>`XBGB&W}Q z!*X~XLA>N5V~biI1z?-xknsm#_RS-Mj4P<$1+~1<$ZT+aiJ)=`E?G+5>2KKb@F*gA z?_7-VL>X~n}t6()x-;2e0xuqT`{&aeUGoJWVQE)Cv=Qa5i0pNYxfZCDH&iqx; zQ^!YGbs!J~35dSd-Iv5x68qQ=Wx;2dKy{ddjN2aL{@JPm#8-fFKo{{uU{R}m!?`Ja zz=17I>gr0p7LlxWe5pOf<>LWEi6o1_p|!$nXd;Fz;x)VJPJdQ*?rmy%HC{}cCFldh4wSz21| z20?D~S_vdaD^sB;8&~482Uz@Hb1oV3Q5llWI3H_^_~?^F>D5b@jlZzzIR2?ChrN!L zmkFO49IR{O=|rFtxZP(YDZ3RO8*F(gNGh)`-XaZDTFT$)&GM$aiI+-NB_n`TatZD) zM`t})qOnQUYo0^GTL&i|v>5?tqq-sqeE!r6f)2-B#f_bZ9VT0mVhAD&)bP#8Je90~Q*-76^?K7x@pB)j#y_L{9mgs#<4!ao?4f#dM&-Qu~F`|D>Md>HGd@AaRG zq`hM4=f6khl7HhY`^(<}^6B-nMz%&G_9EEvdXEu#Tx-8TM%=zTzX$KP5jq!qcXijQ zKm|hC?i~A+TY)yzxE7~Nb<^w?tpLh60uAX*U+_lTmR~Gn({4s17B$}JjU^6^1_xA9 z4q3S638cNe(%FSm`n!a`0 zTH;Wi>wBwe!(rf}X8ZXl54&$AqvKCnWBIijA%L6b>qtb20{t*PyNjK{S>tq6-A9$d z4T5!!?|b1L8(ED&G^+-)+2=#ozQca0xa=1%iy`c6GeGmRxryQ=E>l%;*vuiJhhn%! z?bexF&*ume=7qQuvFdY|PBIiw^D2cOT?5wybS|(YBiYfH;mQ=LQ3ACp1f?*7uHzEP z#Zo|%0m_e)#;QhU1~aQ@``p9S1~n2D*c&cpt?I(U!eyugKGJJrHz0?$Yt3Q6se>T~ z9@uWR(&bTRlf_2}=Li+kxGKOq;9Z}aCvE9j@4^O)0-5JF97Pe{<5h1(B)+JV%7HS3z(1q+WYgfEVgGp@S$9J%e*>+PRa9S?ojz)x6V zE7FseC3?+Ni8qno3B5L(B!-NN-lNlI%<+b)*4d#ZHF`61pyLLh)SK_fX(s?xb}P*z z_q1-TN`yXhm&ZKnF)dGqPNKQu@Re<{wWbdQc@>bVv6%uI4e0DU@a3$i_AV0WKoHt| z3I5di>NNq2PwRM)QN@{$)D`0#BthmL=&D2!_Qay-Kv$wS64KHZ{#ZXKgMQO1`;S-NQsCZn_nLye{|yW>U)ZM+>0$ zc=S$0vcvqFwEP!s1~%8Ap4BbM;)DZTayywx0JJ|x2g>WGBfl+$43|XjgnuI>u(>hc zKdt+`1Q^O}-dPexW6MVL&`#zH&wofgQsM-ivD}=`kQ*{DeiD>yWX}bGwu{OPrI^tr zURfC7MW|(gxIs{}9P5A1;~$4hs7Ksd*#6n+V%xFTjH0^TakVs82i z)@7||31SFq+h-S$yC{-!#D6q|<^z3`PS&#hv#Z$}X|@EKo(acP`*gL--qx2^zuZ~? z$t~;RjOlv=O4ES+(^r50F0Sy<&LU{~#@1Hvx}GFkZm_h9U3Ozg(Bdei*mhWovXvgzC)j!-5sg(HxMRIh?7G@iBLhU-?h#F1?E~`q4!>9l7YH<)q9)7Y z)q}A?-x_{lyU9qNA|Jm;Se|r1M(jCeysFix+O;DlR@2z}AVTC!`Qo4w&f*|>LDPW3?KW?BcB4k z2Hc=Bk#)FcJ<0by{Y+wrABB<(zu=;a|Om%i3 zyP~*V&`w6)TYO2<4}S&9o3BoGRj8bhZb+|HY=WXjt*OAV;>qiHmq%VA6e3?beKPlI zVq9kAq4yUT=kOZGG+F*(oa}q^^_ho8d`c%$Nn_%1J!1&|`qvu)cr<&*%S4oK!o9$N zMV?_-HS{Bw;O<57U&5^fKEX326 zo-Dm)%a47|mSP(VZ>F^0{@}bHAxv-qkN*aziE57RU*^=m;R`{X@cWDH?x+G}Oe1u< zp>d_@ho2WCx$#AczD>BtH6AXY%hh|fT zDZ?aYDs3miyI<^j-kH)B05wA>swLy`3uq$?%K&BkL^M&9mB!A)2+1nf%*QH$8cHUw zMD9t>c1EyIfn3K6)6OHaQ{=ui`#qbcf!w{XknDyQ6{| zVRyP}iY47VlwV~TAHq_%KWU(TM;y(CP<}B}pN>%+^E(XZj)2Vg$PGW}I>F=aw`DZcVpLXjXgMsQT^ z;Yj9|6NI+=BhQ#+8L@wj$NmFZr=z7`?Oi_noiK^oQV1J6{jXDAIgkMCQ$0M^&t&T! z{EV4O#xucP8YtNc(U{!Evl=J$g^!u62 zm91vd7l-qdw;uzc28Jk=Pa2wb93lQ|Eyk)-Xr-y#glLT(3$ha9NzEvk4;MSN_rEeZ zm^I_RMkgtg8cKKP*)GZtYS(eW0u*lVd=QTAP`IalaVzSmNw8eE*l7IeM_un#i{d^5 zVWFRb?zq=nh4Yj-&rt%2F4#d~D$9{eHV>w-S3d*&?Jnx(d&YZ9KU$w&rfjY#FBR<_ z_2I>CV0wq;QGNVbM{aySPgw1A*m-9C$9Z~S(batKbL{A<%z7=Fa5<{dw$V99CC^Tt zn{Q5z2vd#uU*j!0Y9=CUPsq76qBAisPDktVRIJIxAa^v>5TD-D8l1>Fr-%3RihcF4=QuKIn zi28n(BE8~zrG@$8$M4$0k7y3=w`S<@?Mh7)_+5W&^x^v*W41ibmai~~l73p`Jszt7 zroY0kKb}7Jf6W>zt9V_tS$Rid_Xl(R*Q1G|W_T1lp5Bk_ z$i9Zh({0_0Cw-UNDC_vi-4#J??JuIMl>MvPyimS%{2{tlzq5g`RgD0te@yY$0P!|7fmb;ePn%kRwV2j{|}Z6_spIe9w!X#7WWRr zlovVmGW!dBVA+NIy=0(a8CSm?RNUMp@20wmzEhL@x~F0(w5oRn9@<6RruKY^;Su}2 zB&N_4YV#&9?H#mti}!g9^=IB|dX-+kVjI7W97xvi9dG+ThQ5EQ&U5o~%kiLd#otY3;i{jVr~{QF9Q6+w`g98btLoNW zl*{@e9oZ|uvd-p1tFnWvu!|B1&{qf_c6+d$gF;y-F`$n5Q*y+{2QZOGD~{qp|D=QE zO}BHZ*CpEsuoyzpDom`65P<$gJbU|=Z!qS$ieC^RKw+jgJ-NLw<9Ci+Ae#4=-(xv+ z(?D!cH=zRmUNEp0{E6X~%!_}xOoEc*zFhO80-|OL&g8>&E8r{j_S z*f~}r+c&lSb2jx|UphsQ$sB|>x?3-a(H%UD&4j?^cNjugA+smXTCFW7=_vKfMjiCy z167rFq5Cqh;xCrz_@fA}?}W}B-%qDCQI>6bG4x=1_G?T?4_V5bkVriRqnq!hajihX zG@*?4X?@*nrJU%LX~%KK_kpRnCQ;EqZRGbByptMHsI8J8{G%%N%If3WlkksfiJ@K8 zGV0#LdUH)j&Cq-|zdK{PT3QiPJvBOYIEwEX)axAf$1y(?KHtppelMag7QU1^>Asnh z9kQn{*R#4X);C}TWR}TtCF$kAt z80!AK9KUwF#e%6hbTPYDqStK2uN9Nlt ztu0LMS10PlX>_6Xl)y|2xs!dPDkLkE{sG^S{b3^&7V?xZW|B+)ZEJ(#7GyGnFckUi z>0eSL#D$@(Bes*f`3$1YccH_9mW<_I_FlJevFE^Oy5uk-#qCG51|7Hs2zaU+d`fMNZwsO$p)e!Y z@W~Wy+0^thj=#@pBu|#rX(Luv(4o)qtI?_h6jj|18-J_ zeB;_t!Qiqv82b8{(hw=4AsMz~!aHYoNJ33wuC>RAZEBpDmsKjrotx-v4k^+KPY%+z z)4<}yJD8%>6y7UJ^ppB=O+MJzU}w!s(p0?oW7X{{$<}v2AKvxZEa;Zi4q`iW1fqDD zr#*#*=o8j7l_S~9wR*N?`mhl9@Yd8o4*7t5pp3#v#_rtJ_ji+33FG||{|bPtyN-YO zZ`J=IA|tB$+}QGqAER8nl{%@k5gj`Br8tp-Fzio{)It%iby3B%cFIKTO|yji@ij~t z0zb-^UEA(y?D$;Ize9vD9#SfKl~rc5JV|`BoUz^vnQ;$Q75?HRyyu6?0!iYdurfb3 z>KrvV0`abut+7baO@B;{nz9%S1TwnY>=l5X%k)Lk}iV7tca`XB|-sYABjjA*$ zJJCx~$*Dc=dGx?YuGa`C{J*nlD_CM6n5XQSU^K#qF4~NKuq}W24Wx+feu>&nwFc$} zJw5YI?Q_xlmA8Q@8uLn-nd$|(NPqKT0fl8*OQJE-Edizw6f|I${_^vqd1@#O3rR13Kv zOuNRUk{8!KoYlsd^V7-V#z5a@On2?%8YR*08$16^K>-8#EWt}-3sq_qXw;xk`j@3EAkJyDH^*jUK${Fda_HB=U!Ar+@vpF6jS*wTSZ8mmzgY$=ea#wTa3wiCi6 zd#~5XJh02P4h;gHJjBRDQ7N~;!yOO>{q{^REI+gw=*elO=Pjm-W zvzY7hTVCU`{&HN+xL|`@OVN|@UXs(FAkUoH&zk)?@|esoR03@kR`mtQ< z0hZgJLmvGcX((LYJ5y|nU5=TYG_V0OOqei{gwHFB@QqrpADi$2OIF{gR|8g$paXr< zm7OX#W_tNMZKvJwla2^y2n9@jET1uOwU#4RmA|c!(*V0(Q?ZrekY8GD>N9!3WBAH} zLGtCQ%D3ByD;68!joL9L=vb#tuiPIF5#bbqn#qBMn=9QhB;9cm<20K^q8tFW{YvSda7uaEq5ZX>ItrtUjPJ~=RaV~o92qJc&q z<@vpcnLjM(v6-|pKL>t5y^}~Ww}0&#)QMtr-;p;y24<1&AFt_ibX|30ssU2l7vZc= zA&afdQnXOe|2ysybVgBP_z7g|xl3Hjp#3g}cQYg%z~v_Ae*0 zZLEZ!pQ+{AqvD}?rzE<~E3_ETov5Pdg8JscN+0dDQ>0Nb*7$K{(47HU%Xx2DQl8Jv z`6A&Zl+Qr$M~4+=?V6ul5Vb@2E#6j<(wrg4s{HL}+r<}5z)q6$h@WgAxU75M{aKxV zE|kBB-q7^_xLZKp_za`RM=lrO6g76KaWMKPbT~5BM0tB`R*Y3n z8B=`3hTBo9yl!+PiZ!*Y>|PLUUVWk$s#H8EAV``)K%P56W zMPmB2W;bSyeB`KZ=-pv*h3%@0z!K}_S`NQ#fBMQQE%TM&v5lnW^ll848wEl20-Bku zf9U%d4eK-xMcVib@&SXAJVS};DpIq)`u|(h3;tpR?%dzfFq`afjG!mXG;;pIVZ>o; z=3L@6we2D8I!GSoxVGdoSYqwEx0L2aW+C)sh0Gia#Fe&G3!=^;g|iP59Md1CZD)U2 z_-e7n-pV2JL+z^*2BRQT>WMpEoyjamE-V?rGQ>GrY2#mdN>F$}% zucvo!wq>XxM|?dnJSI~)HoREr+hx09p=3lSjd;F$fQ`K|A2Qcv`Nx+X88>l@8o4Dg z59iz7GZuz3g+&5Yl~~<)G*-*it0$oRZT59P55acM(e@uoTW$rNyIeFhQp zk|a-og_~J!$mhtdG0EqN5*z^z(%9g?{pLFOn9LOq(oR32jyaj-vgAEE!;{DH9tX;e z)T$KNf}@~ol0UHJ3mJ9`gYY& z#p9+-5~>RRIQNk#r5!Nx&LJoKYxC-$6Rt!Q)b04pm23D?U)%XlrKR7K?EG2frT}SB z$W0eOxg8l?dth%QO_^=#As;;>_-*T2uyX|0%c{`XA(T_D9d2jg<0cNZfn4RcNne?h zI5ZY(FpuB-Dl!vNzw2DAzg1Idyn~d7Qo^PRAv11S(Cr9~h)rY&;zuo0Xo!;KjW(NV zX1kFFaCwLoe#6B2Kx*x9wUbG0}TDj!d9aV|DjHJ?P*Z$t7Cz+x&@RWmV_SQPPoQ69Lym2TRLH5<`bu4{zL=B zYa6}k;6tCl?wxR;aVIfEOCS@rp9&q>nV@DsvcCfL1D>ypIwje`iu;~J zXDSL2?F?C1w|uxZ7A`i1oUHUf&VD!Ojt%V1vo6C9oHPEp>jBC393~0;8znxnN3VUymy>wM-_;zbb~Vl`sJT3i%120H0C7Z^DT~*Dp{8ohB&)$KfE)cr z<)AG8)=H|4EV5?SwQ(;99uZZUvu5A|ttlMVD|FpA$$-hzjI3|zEWlEpk>CiS!!AcM zQpCgOr+LMfT*bzibqb1oFWHiy2EBcTRHP}SPm>UoD$+fyA3S3v`M<8t)nq=YBYvZU zA8T2cN}@Ywxn~b#FHZ9dpjy)S#`(oydP5U=jDZf`MHCXqP%yQ5%-eSk^{5dgGDPa5 zXDSi>cty2a^9)fGXYxRfkw}3aznDYwr7iRHS=9HRG_2;XY!k0Qzja~mys-lRdUztG zd&n9Is|9C32b0j_mkovwU0KU5JUMa){)$RoWTZsQu;w43a@5LuSew&D`6f!B;_K0< zZS4-kqr&uDwM|{kDDFU;mJgT6Iw6yp*nLHv$ScFKHoQ9ZiN?suG?J-a86@A|och?U zYh&`A2Lqz9qr<~rCA*T~szMhmay^?7ZoypZy^V4@4!IJp9X2q>pM`zHlAbTPL?z;3 zJCf@YL!LfsY3}noj5pm>jA_B`Dvq!UZ&4Xz~ym7qKwWbJBYjSvG)}i^iVLpN2 zVxP_%FVJ`slAHfRaZxVy2PZ!4H%rSQ5?Dx&AbVqQ$@HuTyZgU%sJ(9FS*H zc~~K*)m5?96p!ClQJ`C=ly(+Z(__rCpk%$sxge{cydKCX&2{}rTEh!2z5up(Q7j9+ zhml0YB6U^xUTJ_VbLIP>kf9xh0EICV?I1>5%PB@yS^Jq9p|nJsyjlqX{aP%l5I4YW zJRmgr<)JnVMjcbQr9HJ@mek{xwuB~ayHH&uH!@Z4k$%qAV_ANVa|O63vpENwfhe@hb*zU!-pf%hA;yJp7imzh z(PAjp)^K#L)NP;0{&)4mFZj!EB1}eF8eFIJuB~(B&~gK3tp_Gyh`p4I6&}cyeAIk? z25MP2QZBaj{Y&Lj$~j~AwI5CHQ{{_4;SKKHNBY7?-i$Zd&Y7_ik+NK9#l;{f3Xjyi zXRO6NCr$Gm0(?RS{a~+G!Ppcw332Z|rtj;2XPa<&-hzkDrne?2cQQ}Ti9b=HF+EC{ z7)Df0h2A3-?2!~z9nwLkX|KO#rLktIRo+z4t%#r0WBQH2&R z46I@%n*%>0a66(gk0OgBa~;A*XiQe~u{AodIR{0)?%_(u`dl?gwntmhB3x%$(ND8J zCop87B(Tp|Z*r_iMhoUH$mh|}VrWu4b12*<_Z&J>;3>9Hgv<4RO=DA&`Vgh5VHdyhPSsHXkc>ji^qe_YjSw@JN>bgmOoEUZ@@6B(a^D>2NI?6r5l2ZXC$= zzi-)laWb|uox74d#c)n&;`8NcnjOc>glPIH5z7IMQqtZX!ZGPktpBlc`rh;i8|MRE>GQfT|+Va<8;P|(na%~oNOyf3V13VYpJ(}*hAqQn0r`tz!9rR<5~ z;ylJ%OsiZR?92BYYMHAPA6_^;0=|5d>YA}8H>!&gf+n;5C4x`r-={tmyyM{F;zHeg z`#fRwtO%(-zp>sA=yaUun6|HV@X_cOQy zeq>qm6jgg0@qKgw*`9XxTeht@YCmWmBwjcU)!3AWCCA7UhBPvwo@uTbg`1?9|ErK1o-a?$Ne*`2ePaa1!3j(qO%;V zgFRpGF>9ug(hkCE2$zrr*eh18=L~<|>)$PNjRo1Y+ElODtSa1vUB_>($ehAODJB2a zn@5bl_6%XnP5gyTL_{<^{RQzOz33CMqF7kovx{+rZFL1P<^!b9hE0=i5pss+#G^;yD4$cq?`Loaf<|@l~yzF7=_y6bz!nse%kea+^b+Af6fob5f+b zRZ=wQnQ-tw-ay^L_pJQnMr-GiY>3|w^IIuuVowT8a^h&c{3B}Kv0n7YaQgQzwvT0O zJ2&L*&_}VGlqYf*>3ggoJB%-ZbNl^pKUC+{JW-|Ol45iFBuop=AXc&`!55s!D_^LJ z?>jvLZB*)|h8fCj+%Hr*@~&P;(-d@`U+#=hVP^jwic&q}npH$NO$GrA`6pkLx_Yjm z;*Fi{elELT4kvx#OLY1j_j6ftw*-jn`X1R4Pz%d_k?z?CKE9}$`Q{(3(KfgK@vq+i zKHlE|s6hdcYH0%0_WL8RP(3{8>OR;LDcb~q>3K$U{Z3yaPEh#we*>eY&dTDoSP~L2 z0o_~anM=WD%I`PM!U^G30)XmN{XG78;nQ8@_zF&=*E1BPvJBOBBqHdRAy=JB_(hEd zD1X%P8b==7M^*p%#(2H>5~R=#&zH9;nVmnWV*Y1GeZ9#Ort$Ps*eJ{fYNlv>{=HK7 z)?vH17Z?Ex9!Uy!4j9@?Kx}W)t~f3d_Y?w=>o{;@@4oD&QYMC9k`KP|!ezBLSn)}# zFIYBeBj7{)s9cEt_aVc+8=F?Q9aL7d-|NlavN@ctZ1vPeeJ(O5Y+g3Y8CG#0&nD_2 z*Lo^BH8YDwMY#85;6Ga+LdMZlG>yB)!cKZwns7ANoX@b<6o3Tf2@hg7f^LCuNtOft z_QZ!v^ns2C%UQ$O5FlShPRS!A&VP>Z`NX~+I?~M6%zrk3;6SKN=c9K#Scsk0ew;C+ ziO&u917Fn6eOpT+(TJ+P)#T6#KbL7CdEwumk#as0jt;LarX`qL@-~qo%T%q0!-5+1 zm;0Zu-)DQWA?CdNop1;IxL^fNCT1z9#Jpn?jY2Swut%_~U0&2LF_TSS1X8D9Pt*x_ zx?;2^_5HUM4J>|h4J#di?R^o)V-xX31-)b(SBBUo6liix}@P}3T}}O zNjc7VO)Dt6RknE?1rtLqIxyuDh=t zUz%X}Y4ZEAqko=Bw$UVK1n^gVc z8i!5mOO|Y(twf*ivv~h!TBX!SG8+_1v!1+8<>su1^#XW%xscw$u$j|u86@XO$sd&4 zpci$udP@+c+J9(VS5Z=O@9Uk1ubkZOoz0T@%lE=n;G(5P<6i!ci@pM=-kq3?spxT` zn9v~2rvzI`q*m92$;mk}XMBT44nKIkpows6dT&pIyzN`Fpf?#l5qh2s3L-p~1(D?z z`9E87EAcyQAO0dnqI?i-;svRl5p>>HqtA+k>Sg?1=de5}H~d}ISGkudRB3ZS zPjWD|F78=j*mvRg^Ow@7`x$1av~km`bku@`(KfcmR*5nrxL}v(z{El3m$G*;iZyUwLddbK9$P+RUwM@HLHdv7-9r~?TOW~`j!kYz@yaXo=1O+$6f`kY@{W@9LxSm|1g4Ta_^ZQ>M zmEX_7tV?sxyvxV8=D06duF{Dml!`TmpL(J?W5sREz8`0$1&WCBWRdF>g(ZAm2Dw%F z8o*=XaQ*4{V3@`JnquRvQ%EO_#Mk#M$@vOx12Y)qjVP%qAm8(d<5yK6(5aea4t=EQ z)ERxOlP(ORlp3ijtrAMqtpJLDkME!DRg|CaG4HsRQ6x1}@x1%cc0Ep((}wAuZMl%q z{Taa(5rUg1sP%$DC(lqQ)ZgD{YTU}Aqoe1~yjm}R`{a*D@ZF`$&dDjMuo=^xMq1yX zQ3K^QkJ0QXAi$U`8M!P^z^uA7=J%a#sqIehntwcr?;y?5=&y={#2$q07JH)w0NJDL zWj@{Xy+HdcuB_P&I%X>-G0v0F|Z8v4J%C0s!!34(RV{6fL5%?sn_d-w=}9$%VE(diMS8>z|2EPdxH_ zS4<|=eie$Zhqz3+=JO*6ts zRn>W0^wq7M_Xs;WOzb*0a`-YM>YjP~IJn^akkv+wUKd^nzuC2j7jen_GOow*94`Bp zZz{P}tHgiTB*8}2ZGH79kdi`&Hf3tY`06~rm}pLLEW~}s4)MQ+kx-oGK2hHHPtAua zGm;e{gi{h3FJ)tc$Z2nH*DB%suG+@P^6GqCdC`XtAGAa>nO6WJoAs+FKBf|91lPG3 zM9bUt6bUAyFWLnLk9%+l-%xDd9%&zc_cPM1gECOH4NxkdstJp6FdkbBkp$84tLkUK zH5hWx>Qj~WGjY4GePl9gTtjRxS%|oAjMqIyZw?*br>ST;>|eEz9m}>YTR)4^$qg?s zv=vO%)=A)6?o&ESe-(tJnq|c0H|!s(9o|odU~#*lF5NY&t(4cBvjTinJ!Za%meyZh zifX4Vy{C%}RI>|<2MaBis_+lAx&I09hy$NYh9uMv42Zk8q%@V77Zm&zeQo+;%@3_$%-0=Vx! zdv6AW0zseS;xP|5El~`zL7iFFwBE55ifm=tTUMovgr9xyK z%$B`}5Z9TxvBDkw`C4n(D_D9IyZ*%RF!d2wY(V-{(0q69@~%2VPGDt@v8ZWH>Sio_ za7Um&J7_%+T~=8s{MCdnDxz!{YQQHq;FkWy*&>oll};~LV(n9W9`{M%fhA@yRbr6C zU4ti3X*0~S<_^MjcK1n@v6~GOmgglXg5QjTtB)CEdW9d1RgZkIJqTv~FbOPVsB)rh za=Bd@P-xU5I6VM%fKcCgLuc~TtNuNb3)vyeu2pIZI+&`YtAhr)~X}2$0d!W zRh(LxUnvs?Ro>++*P_vAcM2=F&nBLZh|IC!06;Iu*EUNdJ&)|f1q9y=FE?r1SS0I6 z$WO9BM1IO7=5PG=I;yo2f;sSSWnjf}`~n4T%tu#G{exc9C=vEC2|O`8XuD-}oWuNY zywwf$HVzxT$n^Avp|i`58sd{%bb2w2mE9)i*B6~SxCXe4V$e@eIp5NA=4CdR+OjPw z#^!Dw(c(HxN7zL(#Sz_21V|s^T+eU4uCF~n%+S24hB|lDZhA6-ij+m2(N8|U zHiTkh?tR;*Zu|&Sl)YDdZkLG? zP%#IYlg)sj>y5}Z(1`*whwj>otf#n`43Wl7xv;PQ=kN%e6MS#cLMOop3(*@=gszti z4?WSzq%4q2Mx28lFE3>Yhc@KTC?PmAn74yh882-WRZU|8w0I?PChNqi>0tYI2vS`; zIYL7!T6vsoLcA|Ge8M_ROIY$Fq4+&XJeBgujakX)jTpzz2k~Ma_I0Y8MGrMquIFKe z+_Fp^Z1)SaIy0Y+RBL-|ELeHtUG0W(xCR4N;TO3FL9A!m5ZXMQy|Dg%K_)YbCrfTQ zv)Wovw)+G7B@MDXv1^fwqD+eWF74FUx=;&Da}C#C9G}j^YwTw>R7yS1Tn>M&=*B$?esaooYFcYj8f`b;V|J zEsVPv37C6$e>2r;yI%Mp`mgx%P&Wz`l74+lmhU{FLJv~>evc!AuY`t3DvH185Ax6xzxng7qN@mNMm>xqe;@e6y$o@N;8i z8~T;QQ0y}dCkaL^;T0fyq#%eEloKf*I;Qss+Z{vIJ5rcQKv3}BeN4~31XP2>bofb5 z861@T!%?7ruVnme{p+U-U*;F-&B$*YtE8D!r+#TOQ}Cx%vUSSyJACS_bXT;KaHSy3 z@wKxrd*W#D8~oX-!Pgc+_h&uS$UeT8M#-qlQ&4;p5lTs=WE2z{{R=)^3m*|~v=Fzfs|v=56kLmrNt&L>eWQ0W&u#EH4Hx(`MbZtD~aY{6Vf%Dd}bgPz+E&5JVd3kS=KqM7moVq#1gM8F=>@)UWrq*89(0cX_X8_SxsN zKlwb*PV>>)6GttihE?73g2oTTF9{yG&T67IW`~+B1c3m+uqZc%daJ|?BErF zk8%V})svWRLrAPYNvQiOl6dI3AIyz*3Gau(gSpHMPC0e3G`L{V($RfjWCcA>|YWbF7HHZBWyFvHDU64 z``?(w!wbED#sWdo&Yd7H)P$d(Z*6ER-&`84`2m57ch*%zVa!KErup-)nMBgrz3<0o zFI-DcQoJ0>>{~+`y6xY4N#J(g;m=D*`Grloe74Ul3C}*F8CjX$UP}4#1u3F?Aor}f zV=?1~+h}CXgL6#r4Qyr-i=3nUfnU4IjVXD$eJsUpOG7z{KwjrXiHkfi>$#!w6;fiTi`cRZaUSA>&(6_kgbV*v0rlZV;R^!#rkAbicSwFz0c zrX^-tu(lhNn>lRownu_*>07oSIq1ycqYLVDR6HB9UnEeBRrDPgVElTh8#7qWLDf6M z^Dt$~5zrPb$tW0$a;1U>Lb3rmJwxorJe}prl!v>^-<{k&TM308d^e%FwEk8-@=*oc z=dfEYYGs;vkY(eB!Iv0Q)y;``A(!c?tTl7FrwHfJh(2_8)imCG;pAZM*OKf(x*}zw z5B+QT9Ej^FzPybb1>p>`-|wBT(4|6ut9R_tLpPi!L_8e1t?_U~cH=NHI4@W1lB}%4 z-jt7EGe_Kk>*^l-LlU=F8vE2N_woGAF(-qf_Amo@*7DTPWrsoqI^Uli3oZ|cpU7mc zfm+jxph+T$ZJUg6jNnU9*goiBjv;EBNt4F*$EtTX$ez4%ns6*yhx)xzYLY0|F{+)M zZ_{-XmO44uXX`Z_q#3of~d_dt>kRL%7Slazi&h zeV6j&Hqd#`Gm{>~UkJ!eLPxE9PE1En7~ogsbcI5G=pbw=QRI(VS{*?_^Q7h-s{mkVI&`4azsfww6^-Y{8 zZJA>1-k_${?%RY?6~S<(ey1t8!F1@T1X?H#hsDD#1Lf!(LOK~4`F<@ut-|z@*!nJ= zx9#jF*P<$WN{dD=lU`6_1RnLcGg49CgE9Q%xiQW1Oo{_4!7?Gd9622}ko|G7kh4`if?@LO-lf&?EL%oT z3V>#nQg0GAsg);Hbyg5;&SH?`JF1JJUD{n66HzaXnQpf#G@0@3zv&lp_cE=UlD&rW zyNE2Fkm=~$rxPd}l@BBDxpEyvzHV6gBswdu=#@SSx2~#lR7-iHKz>1Gcm;WwtEKYZ z*DY@`eMa4YXqYkXpy}6$3c~lXkne?0Cs;}RS8S$8>8CeeG)QIGAG{TDH!(8(z^}S~^a?Z-Ri)<@5(Cf_H95FS7*0 zZ$a1}%AV>Bt=+eir5~3SMkDVpRd_)y%fY3B(LS1x-MHf;WZ+sKf^t}G6$q9X%CBsZ zp-3<8&AiCp+!zh#2wfKrnWk7fUKhuL8`zX2Q9X*N9cTV-k9RWl{T`X)sSn7LWPaJ( z*aVyVs%>4T1#ejg+P&RKhU?gN%wNw9(jH@&_pSY38xzCN{3Pm)=aZ*6<#_~Wat--MzZ&pvf~qe{LS8ua4B*SZRe zWIQ0Gk)heZSM%CP-*hQ)v4)+uC6U{io$_s)uMXN*=TVvUD#aEauSYLGP93nSy79Bf zV8bv=Cz2!kh~vd|1_Nd`Zz7|6OD-WlD%_R_ChI>vdpd9 z4QDpk@T+rEHi&M{FK~5Z9Q`%;Av*wcE)whn1~i_oIsMTBz$OE(l9CfNH2atjXSAZ* z^1(#UJat0m14&3o$i@Vb23$b)nzAXhEyX0B+WaC#M1Ru<$hL`@0vzlOZB@!eFQ>nG zi5n0>=D9V*jcs^;o^{Z#v-Nog?(60!cAUbkqp6-?%kI1sJ?XLhq`5rRty;fb1axRg zUn*e^28w24c1?XK&Y>5Rj;y~7mpgPGCH_*$y{a7FVgA~$Ee5H%ti#-B|KX6I^K>&PeOc$M+~4N zIs>)p$L-#Ig}-U%9$uTtzs8h&@L1Ri44GBiKOhn8p4z5K?3i)*bFtlQl?=rtm&0_Q zLGm6%^I+{)q(~XVxxusv<#$lNtWMsA6nKUfXTyC9x-B?O5Y+jYLWmS_p8et8v>(JL-_bny)TrJtfsb0DTJn0~ zmoVMS1{>?zsi=@Esu`Bnfh^DScr zGflI8N?SN!FZ!*DITt3+e>vA_!3SoN}5uUsZy8c2e<1rly&DtmFI?Jty+_ zsMnr8q-}WNXBdeeW6xu5HLCOR8{bZzU&5y}|D2=wp~4sSiEp+Cx3+tqSkn61M3sqc zX(}rX?95KQosCQtimsM^MuOAs*1I87wz^i` zA5ultFBn7!Ebs>-i0e15mHz{t@Ru~lxnTr%xywPxE#E5zrm6HI0bliv3X>G8KaUFz zy>s-JiKN`@lJ9*ge-366P}h%H8Q3UUZ7qprX56!8tOo-FASKKTg*Q@|d_x?sm9ppq zrpXXG332f>jIR8Uo8>Ypd9X2xHAr6000@IUMoo&vi!SgVz|-7pTm)$=9JFiLY3nh; z%+Yv1r&vQX0S%RDRoyg+u3lz*kxfOysUz$T=9eGhXp%%^_m}>F-?Zkk$4;4$hwYF~ zs!GeSN(zuP=&U;8BUQ^t@d?lO(B>nZ0@v^Tls!SJI}-yBBX=lbc2Voy>@|5>WDZG; z3$Bfw-FXCs3&8uZpHR3)_OC2oIeA$*73=N+s@lB)mUc%q_7>G2M6-> z?f2HF2;}%|y1+GR_P^Rr5F;s5|F;6MXJpi^pLZzqlSH-HU48-AfxV{T*Q%3WNBKUbS*QxuwipR zcH3<7(dH|O%~<_{Km`e*RwlJ)%Uaa(OIw5N&)4yT^9}nK9eSOF#dUpzdjJ6{w2nP- zz3-bmzCu4y7kUiw%R#$s$w=S{LNNt)Y;=0Va)>3w@fcBm$S>$54<$b z=g1DenXsA)KjU`clk;?5#R{Fr3V&{WOJ2*O!S|^oik)X8x#s4zu6}a;N1DtRjFzjy z7^?>>XZkCutQdLS53x0YW--7;)Q%l;I*IlpUDZCx{G@xho^biuI6VMO{Lo6)U*RHA zne)EY^ly<15s#9yJ&*@2HzB~>UN+u#ZrNY@+x?sCoAqr)0C_!Tj2FU|l6{>OpZxBm zti-5Yo_+Po!2uPanwZ;le@R?|M}gU(>6hFn55Sq$+$ehPt51)jQTy{r4)V%sYA_YS zZq6a%!_2a>+gYQl%LD9JTbSU_Dp;T2wjE%6oj4!rf(*XXY~3u=x3xTQ)V!oJD8od> zTEwh-^$Jx&>m?@U#q^XkMkdZ*damNpvuQ3r@))G$T$(vFU(l5}d`OcHDJJFI^pJjs z_!1S0TJA#RNNCl_$M)=yaB|+5=vqy+uevcN4xxyzm|qT+KKwKjVc+ZCpRjW9AU;@I z+AYmSqwrpYU-9CZ`dax64bb%{g@XpN+~}OqAVN&ou&B!YaL1xLeyt{dd|k+3jAx7N zW|<+;{up_4u)f=Zf%Hz6!}eOVBUPz^T-g-n3&Z&vxm>!6N0mK0QT0ZiLe#1C2F-BL zbl%Z!j86FQfW>g|hQZe=3J61T8iy2jTkHeU-xW3XjiCkg79r8?@o3NEIZN3P=JQKL z6BhrF&f@6JdRD3JKdEyiOf1KHraKBZYOm=8=zy^Rd!dS1(T<4&Fqc@2jT`L_# zYy>BG^-m0Wkv+a&%b-uZkk-J^DSAcWi@0%Ix$gvDl@XZt2cMiUne<{w0ie{z~3UFvr_ z@TvKkv+lMy=gHU1UUa@ceS+?F+^16r7f@q6^s^kf9 z4+oVBY^!3wRk&bx`99r#6NPDIDxA3dfnsq_S!P=O`VWD{{AK8NBt_?&!UYH1y2a)> zb@CqhtD_Z70_9!ipdBt1HeO^(b3o`VZvb>7g z1*BYkXUCSmSWb23(;nA6rUBzD@WPjWs>~%L-^glJrS1K+~}8big1~=K!d2h)~4On96Lqswtwx_K>J$K06CU zBsNJ&A|)fl{@moX98!(#Q$;|?$yz@j&jWLaA`0z3Q&W#_tyiq9kJ#CkRCfb(&{Bh* zR~I#T+Q&R5?2V2O23IjiKfji$FH{dWG=@ln+!F6;86%@Jv!n>L;>^JJ9IJrhUFlO=+^~aJ=jA zbZdVnQPhj)$~9SJc0_n-eMh=5-~ndXN@KEZ*$f`$sD!C+cL^KR?-ec8#4Pn6Eip7E zi>nNxIIre)!6)-$KuXA1YuSe=Q@F7tYtXwC28L8EfN@W~Qs6D3;aXGuOJuWTd(aOv z7*OQ*xIcY%)U~L3S#|KuNbJW?;sfOq$44k@zq&)M1QTxq5vPb|{$982D{e{)R@#G! z`4?)dEie!3w|f*e!tpLW_3aU24;P}k=kYj!cdS-p9t(YlVoS#H7-JCG^f3|ATRc?k zt!TYFk)XzLFgDk(ZB*vqI|HsTw<9mo1}Np?x%3{jo&bTD((*uBT5$WJSUYF+9)ny(3514YDfcI>L5JsTzu_?= zV*BdG9w1ZDF;L(gwUFTv<=e0Sqwc=tHN3_|do_tl{^ctkzOqaBNv#FFJ4#kdE;}zq zmk)l{R%5C*$HL_7T~}8hov+&6c4nf(OfJdqXKbWt8|v5-cEq=vDc( z@sGzl+HT)#g*pJ%5u{HfFhH;x4vpyr=rZK%0WX;(1ixo@k1{jL8b>@jGAl6HwO3gi zhd%@=P^(lWQwP~9xmud-3>rU>9D+=NVjuZI{l4T%j`)lyc$^*#$(H9BgoQnUzwp2E zL!F>hY^!v&#>{)Y=bqF#SR?s+Rln4B%&ZtF-oFLj0zj{O>PAoS=~}cT<=}wX_o`kQ z&An0ea8#ih`;-wv^wdz%P|LUQ?a0{*w;r9t{v75Jx;JyNfEVVeo^-Lhv=Tc74ag^h zDzz}mQ8%lQUom`*H8S5^QWs=+=XA|qaszZs*b~L9{!OHyCDS{A z(tD_Coe(>^i3Ml&+iKSN&o$wagjR|UyeS-i4`+7hfyBZB7xdM-~UJ{-Zw zZbRuACyX-NZT(C7fXjN9`-|g)&z2BEYb5T@W)iL(i9GpLfyeRI+YC%{kEFy=J$&7I z1tc%Pw3?zorI#p-T8QU_w*oc7A00T8ej9fmKy`I}xM$xOeCgQ>Yqg>7QS!A{HnKW{vGivjE_DvcU3cKngy~XC%m_&Eybo z6o~xRIAB|ked+y{ zmuZLf2ycL+w7T9oPHcGd3Th+EgJt7)wk0_L19O53iMTB$kxjPanIVXRE1A3n1Bi!qx3pQQpN)YD8`Vuc6dqr(R&wS_Jv?bVCpA4AQUapct|=Z)fRW&QS$1Rs(H zYF`+*PN?^m8j<73D;a-%XSLcDe&)_luKt6OjGGezN@My0=wNl*a~pr5M5{Olud`lZ z5|6}3_lZhYQ@A)@h7DxWL~|KE2H3T75TS7i@Z>|g6f`z$%*AW@`ltL)pHXCBsAR<* zO$Y?#I0&}56kRXjYAUAef=@hPsD!jMp^6pz(6*F11u9C)kJ;I*Jx(%bUrPcLCxwkE zH_9_!zlIOq^?wI7`7OYotQKcjc#J}v0NYrxjV<@#M!FzB%hLhQq=J>l0=sYHn1}TX zYT@m+ePIxYC*v@MUNsn2!TFwAWo2sy5aziE5aRf)OxK7Lor?f2D5E=;Z<4eKtS|S*BmezRCJo~a9X4#34AFNROZCaoDJ{O=A_a8y!t8s=q!X# z7C9XP5skuxJ+$GzyV zuVyD-fMQmhn{%+b8lX-#R5<6e3pny-sVJJ)FY*KHnM&wFp#9AvWVtpI7#-Qoz%MP_ zn9?z_F@X)rNF|8$lYaz3mTS^$UdtLPjbn>1g$o%;COT5ubc5tg7at$FPbKl!gIJOpXcR1Nb zxn#>d3&x!&jTb$aA%X?us6S(VhD>^ZR;xL+Bou7Y^6k_LWceK3ZwEiX@b&34}4iXK~ zyrm%h5Ej(MqJJwWa7hY8wBXFCWtG(8=G2FkbR3dUvIPVyb*!qN<Mjvm`&0z+9?ySlB&9aP(f^AA|%)W?gJpZa?2Q0pU?K1USB0++_lyl z&x-#3T?V>+ubJ_>%-GvK;ISNGneDHlzG$hm|9LLfJ|&%SBEO-SGm{=W)a*aUz`sh2 z6cTc>E7Qkc3ZTa28yo0cJ1C`@C>k?#z&yicsI`Du?AAC#b6 zE5@I4Dd}`#wI2fVDfXb$b23faz)fo~Ni@Z(kL7vnc)8#45x?s~*GrjwcO8&D?=IyQ zj0n_iTmW}}ymbAD^8(zpc(dUpJZkK?l=dGlP<**7vIdYn2l+dFu)q@5}`9ykYD>hq(SUAhCcT}6^ilp@P{4J$)qo`PZ)F5bvdePU^#R|FKZ$=u1uJ0j#!k%3=j4 zdIjyitP9uyK`@{jQff|s0F;-{kt;!(zDw6Zo6xWjkX>HYg99=mZS{)}`>44a$v`f{ zpnYL%ZlItP4}gC4lR;isN~M~-a9errQlllcbwH5RT1oIZ2*mZ{OX<*F)S z;KL1q^SbrL021G4He5D^;tC1m|G0tM`E>r@@0UD{bCKG*#EWRcI!V_#4zic&5tXN@ zH*YQM4nM$r2pc&>dNp*!Io>OM$|Q_)o#Pf@e8mBD-#}`P)d-7#o!7v2tt5mNz&=%8 zYqEXl$ApNba>c;2<43QF^>b?P{{&lN1EY*lw&+Y0`z&%?!*I)MbG9K}(+==*GA?pP zEk2zHw*=%-wmZOA%P&}rK=X#bHtTen$?+#9YShkZ`PJvDOP~!h@f`+JBl)zDbXl)` zok)g>dRj8s4mYx^!nOVG|G>d5<(bx3PM$M&v(RJz>F)Q>700S30G?95no&G&#Z5))nk%~1WYu zh=>H;F=i7#zrKvX3!u3Yh9wC>6afg==)Mvay`{se1qvxyT!^0XOA%vQjXcxu0_Kw% zJp#A^9r!iX$HNIi@n$C}^bb9#sBmAr$G%#dT43YR<|lDzF9K4^KU6i4mB)rwXp#;J zPmF~2Crb%kVnRj9Uj>B7n}#)?G`}zbwW};*C>*DyTHpA0xit)3sX3WrJV&7(55B#F zfbkO}HT)(tbi_Y0A!6O?AWGNG(+YxDxo%(je_sT?9s;b#O`Y@XzxgSE(9cuCeK!t4bJapc5bvMpFU` zp3qgJN{%V1Sjy$S&Z}iyr=JnwlglMP-isn2Kv4F(eOZu`4u0PI?v-TwdaK>g%<@Wc zS?BPJ`eP&asfkYZ=!|X%(0D2UAIlox++Q;L+*c#NDdHk!5SYru2OXVlTyV9$#z6>+ zDj`U2K>~SB)8`2I!)iexX6N8M-xEd<6nn$P`78~FNHM#|b?5g(gwD>*4Cg_M<-$I1wB zJWDyE=C{+4YkYVvADVJj5&{>x=1v{-uLEM@OlI{$R<53g{2s_(J&j~;qZ5+qQw`K7 zuEINt0VF6stuD)*(&-v8*^kIR4=@vjTQ=K69EDyUY0B&v9rU z`GW@U67NGWD?o(3`@|?{m%-#@P^Q`qD@*M3%(dv2JfI%uHS^}#1zhEO2FwjKZAl%efWHGxqw z%>Z4L_Zj1Gk4y$nwcnID9nytDzndqelzCzV!=w8ha*}ayb~*gIKs>Xo zM-&btoQ`Xmh`Fyp^=da+*LE?ZUpg`xz_muchfpcB$Th!Ydp$yNYaI;e$)Pm1b}qm5k*^d6NvG?B0v;r^D#%>z2v(%&_J{_9Yj@NV82^=*uVGkiR5U- z;OJ3Q>+}a|D52X!ejftW(1zOynZ*3EV-TDXm0qqM5uY)u9YzS zA^r=BxX{WyDF-Z#)J{&5SJCmkw&(!7!POU;jYpIBQ-crZLY^Ml|0Z)C*+4US2u#OfqVx>(=qV+S9)Y(Oavr*{ zr=4`BP=*V%t*il~E=T|Y9KnXgWj1}ui3^nbKWg{#vsRV^22Sv+3%n`g;_H)UCzXWv zjBy;~u18Dktg%NCm;xgOeGylsf@faF3>;(|Uve2Ry71iYvx5ajbc=!n7XhWk2s-|( z$Cf>JA%_A5I_y8_eXxC+T>ZqtLFGjJi+_3p&2_Ndk5^7J+16}Vima3-)~=jsC(=@^ zwq}9hmr_90E|`4f@&g{#E|soEIAEEhe;8IR4|tCHAdKI`jk}*>Q*^AE+672_i|F#J zMBfov?|Vz|A>PL&H9=tN`JX)eKBua_zAb1LoRdjcsKc|ponitUg#B1m|MQD9dOY-$ zc@956ISq`AP%1J%h0EYq16FWAl^Hu0dZ{X!3X|WLG1LDN4$_!X zaMks>RiRiA@YRUHcR5!pdH$auOi#=jpf8Si;a0Fj5+=uh$^%q&s6BYm0sa}mvwF5y zQ!5`j6<|gmdH4gMSpalUa)RkaD0LyOitp!NV!oNI-4H(Z ze-1uWVwYXUiN0I?9F-*45BZ{*YdRv7p!8~>!*yRdl2d;*Um;GRvTinlN|OSlRO}fD zz$d8jTG0tixrXfz?!jU$9|RdiZo?>xRHU2X>6(4@Cvj9$-h_-D7+yG7kwsq&-`}VL zncpTmabkpaFY_8m@9LR9lt)kqqJGIx2}UjE$k#DgLo#Jqpx*-b+I6Pl_H}LH-N{;t zai*e@H<}D7$D~i->tSCHM2CZWnRFpk_JFu8B`wkgKq`_A6spq{8XE`Kv!ie4tpeVw z29mh@rrCGE(pgDOVi>s-_zbXmKyLhtMse$(!yrlT0ns&~-pQr&3);3uRdek80AN?C z{Ue--D;cM*ZqSgfbOx{oSDpwN6@yl?>gH<7X<%-*VF!klK)n^nH;A&W1a`lzx`E&E z*WhO99arYLhJp8f!r+H7F2PJ6`Gj;II{VKOgS=DZcNO%mHfPauFi$^vZoGR~DfPlq zKVU;ABtzvio6O{Pur=$2e~6o43!RBS)g8$!Yrx-Gr!k#_kzR2C)t`3Ndxhoq3ASs@AJwQ?#k;xtVilqw`!GI2#%7s=2-o={P>?2wZW>cxc08o3ie!9fT689n$f{o&y>OR z5&ilWEayr0O z4t~yI=AD&2M2vtSa@Wcg|JI6CddZzHg{wWMv{zq?TQS8S+}|Xlze8sD$$J^UI$|`1{)+{^6rRqh?^Y zt#_`MUJsZL)6L}Wg9jBK&yP4R{0IQ_`th$GBcTJUOklLn`F5YN1>{xu!SH@X$5KnL3#c_D>D3`$@yxuy|JsbiZ?Exyyc%lU zq+b>WqX0<)=yZNbkX`uKi>W>gAY%?26$=v>25KO|RQLe(+z{6kI^259)3jUg@N$9e zJWcPa`Dopq6*k(KV)^$Fg5P@yI5I0j+N2~bf*-sY6pikli}%4WR&Rf9vUjxe9tW^5 z@=Z;s>cp2alb4qSohU|ipI)MGH{prqyQ7VOF{yUR%A7BYjfjYOaH^W1**)c zN%rNCm{6F}fr^iDI~-RCFUmc{KjOeJo*UdV^wVQBVV$VR9_u{cV?#&YjMXTZrm4hE z3hXb%y}C;K2h#+YvZ{CKyP>l3@y0z=C_ zWU>aL(8y?ktd{drp*qVWkS$6*q}P2i@zNv}5Owcerxlv|GiG8Ur1nOfVfdiEi7Pou z0;*8~8i!|m6}|1ivJ`J!a$pU0&SLC1vHPXcGnb%4Jq-F0(IKRV|3oJ6r-=;>C3wR? zEOI7~TYqdb5Qt2^D-0#-rg((GwyRC+YpoiRhg{Vau6kWR7?Tae*G%(QSdZh~dBtzC zofgc;k}gvLB7fyz!2>Zh`43Rcfqo(3vM2o5!4CCgADS6JxnJgTDx|MLp92lO%Ef$k zrEb^!XiS&7Un}n>Y{+!O=3AY*qT=hHjgpceWmW@+^tIFqbcX)7;8KeBsuIm$NJ}=6 z+?>sY3t> zK`wlhR8qPiXGkLj4AQPyxk<#PkEJ)ava<4No+XyVIRo`ue!gb-?_mag`QFD@{bZkf z>lmPji4eHMctDqPkVN*n!$S{6JAfJ?aNm%)S=#Hf6O5RYg4$U?mw}~tVz{Q`B8`wS z5Gi8(%=J`T+YT|)m22Qc*#YU6fQ*k3=OSkGxqE8rarsZ<4yb1gPc9!tSbpyAMpKA*?1j2_)4}c@CWOe6io7?ceK7o`g}}wEniumrIIIZ zo2_7s^dfHEty13p{u#6T)>`0-Mju6Bf;`A(@5B20`xP5U?;L)(_u{PVBl%Hv4lrQk zT-;OWj(<;*r3v*{%I2;Aqv$a!ojkR)I8d7-t2*e9DC75;mcU8fpG$XUTjV({v$)J- zqYNre1IDhK?zDa_o*sH2`1DaESH^ad->`Rm3-9rW&0(^WrK%s~ab{&W+u;@eGs&d;u-NF+S zb$!+_s&^DgE&}~dFPf{3lf3~Y|@Oi zbk$n{sBMYC=VEBLWeF!6G_}?CqSaF~0za(3dWd6VV*?_^2j1HW_SvCBnZIm=O&UA- z+Js!iUx4p904&c!sWJ4Q69fL#IRKDSUa|%}Ar%8H5{P;YTw%y;-GUntXz@x0;2u0c zmFPEhmIGO}#5a?JnNIdPvPD_4Jd3D zAu|c$8qmW6Z5%IkF9(bk)JQ6LzuT({ISUR5E)FV=pE4I}pO9F76@0cweK?UX@oD-V zvhQbJ9DHw>u5K#^S_hPp0AxsZ5&#L{mdD=!l1xINm?|hQAGlw;;K^lM`W1*MoF#Ck zk*L~}1?cGU8ZRI|H8qWQ4+j*v@4)6oSyc3}oIL8!X(+}WN%R`gqdg*N^L$u-EL%@U7fB0$he$*NYFhkKpux+re7)X zua}E_9K@ygRb-h1wT92JcirT_i-KUc3tbobD-tc8Z3h{DF>`}^$pn1xY z)A0S~1X08Rd0@ohyL{b8U})dwp{wTe?CtNS(=}L;^@`CE(C-6Ez_okXR7!rO(oh;G zFD;qcVZF^S--Po$l*X2FL$yF1DlLitovG(IeI(#ph~zhrOuh2NBcc5_azy6)XYll8 z$;t;075Vrq@}~t}_w%SfBIr&8APMV(F;Gps`7`HS#pTnR$jF=YQ$=IYUw;Ih{nLnDF}v?NERN-9e29J}M% zj==kjpISm7MR4ziE3CGWxIGhNErT}9;(Awm)o@MRT8L7;2si%)ha~qr^(PY>5{QDb z(I3AxV8BnFf$+& z0s0PgU*SF$^P8>^*Q6t18!@9dS0;e$*KbeR`DbeBYj25ZzP@@BKGti6*)6W6D zS~%&#Sha_o3bVeVqLKxqU1R#ZYtcmoq+D6|ey3c%Ac{q+C@uXv-+% zs_KlaF>rmh5TFW%t5pkj@sOk(kSm9W0nHi!<{t$DP*2YyY7(v6TMIJ(=$ChsF6`8y zMjHw1ZGiZz68=glt=LEJq4nQQpcF<`4GlBdQ0gG{`%Gl502_6tT3tD~H}VT8zZIMG zd9-N)uB$>r*(hZr64pO&483;bdn^S5&;{jQ#{Q9!1T-Qrw%P;zKleA2(blDaDO52U zz+g|}K=L>1>%$%IJ$`s7xpnXJ{T0rEqqmQz!z!?fEyQxCncTyNqV)%VK%N(pSoq2I z@`oCwmuhp+Lp+j2;xCfPiV)K5ZD`unf4?ZPQo!>tB^CVF&_bLKuv%UK(&jAu?kUzZ zoymZBb(M3Aa!kY^1TKMeZW;G*buyvE2$Dv>?3Z9S8XX!A#+cY|I!W+|aTfrf(&;}V zYY1LbuXGoJY=(p!2Eq_XOMIb%otgy`2f$Q$~t&H^An zEx1T0VSn7H{pLg52>P+J_hu|^$bVn+jBrU&qvCZSkKuKtdbUr^OCn{~CQTCmO_3V6 z?TQLD?(6O=X5@;dma4pbTXk&BK|S9UcwA(v$-3nvty98flbpsIhYwmmSUCstT>=P0a!UgPXZD0BNn_kTf z&jBxa`ZVm2&0qfQzhBYc-^h5kNy7fdpbGc==&Aa+I?op|-imLJ?P)3K3q20qd%ZS} zdHm4BsoALl97hq?w$y^3;z2*&juV-O{M>|iGf@8oy;gb^UFWz(4MX>sd;V#l+#y`3 zdSm-FS<4#KTJj_dYipe8lx`pWi^sBAK5?~J9HIBe-D^f7qM^Tlb4}9Nh&Z_PBs+yZ z3S<=L>688Ibom<``qsP8P&bdpz^d-_x-Dk5<+pRC*WUJwEL*8qd;?m|;D5e-DT~*Q z-xH%DqifCkig4WrJ)C4-*XZ&$gq;dNl)I`#|R{Oiu&(9f+QwclqB^F)mz9^ z2kLfrcQ+}so$T$KKhig5b*6rQ?HYCpCJy$^_loHMiKqC{4Z9cWHy(Gbc%?Gi8#COX zv(4bF?LF_{X*9Adifuh)g*3!4Cs{l`u0CwDNP6g~<3ADTBuiPV^0zVZ7Pe(Sr@Xmxg9(R18{k;P_w{YFe=#Hikk?>X^n&5YfvYR3Pf}us`_t5?%g< zWXkeA{x?JahPt67(;HCce{zt(UO15t6;*dGFt4Q_>I=lRCD#=l&+u)1p7S8-qd>jw zM1uq=0(Ndv-?dq3e0PiU>4X=5oRNBKa=7`D(o&_>IQB_V6rS^|747d1k#fuTJN?9t z)ysb=X-pA-=EOb8061H1ZEgPo=R0_5dAYa#hRj%(J$sGw9Js}g`Np$Tu>MQ*g#}gP z+yA-N2S4&=;ZhMY&g)pP^>E)W>1eQcl+fi&lb=P=Relpwo0qa3@fON8CfQecEESh- z(_&vJP+{_i(+*hYxpk5GzJXY)c$7R^tP6i%d9yuXqB zTIhV}G!%I-;4#vMOyX@hh28QTCSYUxJtG}Dp-w~JcU#yC_;R%iIO(2&wgdeJ3}=_= zh~d<~+lb$%CmDk>L@G_#@K3y_^{Nuv*}WHrxwRu0N>tjPU;dLu)H%}nlX0TZZZKD) zQ*0X~OZ_t4ABO(b@reWZ^FXP7f3rf|;j!Psuato=H6aJ%z6g!X{iClQF%$w~4y6b- z!NfnuWrO7Xwt$~)Z2j>}DOaGiyU+NLY2q>ZnI&>}bt8s@7tHch35ka&+7_*CZMTYd zaeMVv^MHVXjq(nzQFrmeoJi;kxj3yNy#87OWJ-*<0}e~Yr!N@Y@(^`ZxHE%9 ztTL6jpuiQ?3@^eI#X^_Q;Gz=HUvFnP86Hi(`P7l*1+@#DF6*FHj=AG}_+yw84`V9P zzh2ceRGU5-!z=ch$rI?g=;hQ~(3_~eEoYD*G)3pYO?U8l>5Rn0u{LkbQC6_K+{}qR zGO8I%ePwi+?s13%R#;lPD1a__^-1BwF%GIc@-gCe*sWW$AY}uWZU}f+WQ15c ze=V}^oH+>0^O*6rjG+KSBVEbi16tn|JZl^xG5301XH2c(wM;!s&u@yZ9NGGl!^b*H7T$wDn-JTsb=2=b%V_#fWH^23&_cQDmbY?1EdQde5F{8&j6@;lAQsgkfgVU$=3OpjzpH_tx4(z4|p82 z<#hyUD9iiMHZoWH81f!~!W!5fqr&7)1^LHuzoE2C>-neZxqgazG`MXPwp`_UP02kH ze{1e(ws!yMOy?2bPCVp@A$uj}I&I;7+@R#~-mI?hmLZuLkXI!pIBl_#8p)ij=;6Gw zu)tFAfw=F%o0Jw%(AP|0@rsex!Es=<>HF)AuZ&?%{*tA*G8gFV z#T}krMb9-Vb;kMXZ!W?8tVP+X^fz`z(GI^Fb2)hr-Pdka0~s5{VLiou=65sfx&!g! zy*71q&!8>iM=V3BwT;TZ$cn$Iqj5mJQ_>m>tym%G`r{UGIJhD#9;evp9o**1>J0H4Nw_u{{3SCdxSN`OL&&87}Wb6 zLQY;WqJp5~z!)(0)6@c?W3y6UPp?K&5civOEz5m1eZqo=l{`xtCTNf_Fo2V1gQHUM z+saP1*`I9h%f5EHeY1%3-u;qZ%c53}xbm9#-5#GN6-6J~C}uABmL>9r{4Y;txO-iU z<3SUz(JvuvzVZdf5{~Y*>~0jeAh_I=gvs`*t*~mCsaf?@5oL0V=ikGG9h-`blj9Se zSjPP~4f!|g1@sZ?Vh-PZ#uti=1P^6Xxe~F`%Jewo4brSelKMkz^!cf&sp#)_yPlL^ z4plh&h1ih?2ZxjyZ2Gja5ZQk=y^w%qIkA{5JKn`6w{r27$9p^dmB(vxot&=Ik#E_= zqiRPh;#R5r$aEy?6aBKi;O#l3yJy3wEiyQ22B^iBHLMG^PH>U|4~cLT4F6~Wz&ah4 z_&kn0vmr0pwn{W6YV1D|6yg^?pxIO+q2OcK44v_<@`GN7KRQr-4~&-?j^Di#GE7z5 zt?N+W#P_u|95@!UwW`;xumjk_@jOW=jE+f;OqsWKeaJmW_~6| zPkb%l8VM!)z5h;^Oxf49GZ8(C_I53lUGq0;_sh0l!!?$|oE)@fD<0o{WP9C$`wIVu zalWygd%Wgt?~4y&9e0i5>ULg~cVFQ*N!c%1cHlP)J>DuFNynC3lFm3FjCrjW(Pi8~ ze{+%GJrJ6?=Vxt+nVX1ZXzI@#cOlB4?VYt~8ml~%lzC|1RDCqZnL5b+;NY;mpa8w{ z!L1;_!*`OZB5s4(?~|!P&#m8i$}GjBc#oK?Jl>^V?Ut*f^R1Efxjv~L7@xN2e0HC_ z2M-!3E+aas-_dq^#_vxSBO~EA6Z{_30JUlpk}II6U-8UN=R4V)6G%T|T{^`CS~Tv5 zj9JjzIXIwrNHWGJPlMl4^*?p>@SNl{7})*ei<2o~!^PW`2#=vtf$d^(KQ)jZ(oae3 zh``aEcOs=9!X&hRck5zJ%waRDmcrA4>Q+J+c-&y|?2yCw3vfiDDt>5cF ztx^o#$k-`Z9=A^b7_u_;#G2iPF!jNnb60$~=EI_U&bxuA@dP&06vkZ0mAsYl8qVg_ z>|F7v`+A9K<2eUqtPdw=09MYeNBxh6H}F(__mh1T4)|-B759xBWs3_6xbnh2q_(sU z%u{MS50pzvaNs>P?f^V)XKkCq$<~}B-J9fY|5fEB5Q_?pa~#?LQS~tbJ%o8tn@=H* z4hYMrJ@PZ!lOAzN{GD3>!;s-q!upGx!w=9kn+oV2)*_dw=QaMpd^i`c=MAmgq6 zv#7Bn4^&L6c;#f_sroH(#GQdv&rE8!j}xBNHt>vL!D%{MKp9m=DVj7z2;CW=6%%f`jtft?m-?B$MNxd99K=N;~M4pl6tU+BIn$^bN7 zi*fJ=*j^zETaH$3qiVU9q+Pl?TcX(8(feDe;xykux}il1N*Vbs*ZpbGfi!DCVvS1&t+x`e+2yLOOfePxaX^Dpx zpfK^Cp)oub*N~Vg=>7gD7h+?*wex;^a<8o}Ls_}g^Kd%DD2}H3@LWq`wQVc1J$ItA z-`2U4N*|Q4NxT}-@aj*Kb#13DL{WG zyJ3ZcUyh3B+w+bxML~*sh452@xP^IYBp1C3F3Qc-)$_E|T!qfzW%8lS)n^1NxtL00 z9DFHhV^z(wE&rjAoeE$%=X+F>+vY`A-@ww~FuNX(t8ym*p(2VZ`TFFb&%d1Hqs(x9 z30EGKJ;D3jN39L{3KCK0mU^A)t6j2(>!t)MbJm4VLVy;9=U#Mf?}6*+Mn>)Xt)NhG z&E1-!M#8mT%J;Q>URUj8{R)RaC3(y>uSZ|)%jCxkp-rf@HvAp%0&)mgKKX&yyPAio zFCMG~-ur4H(uC|r2F=?;U4IaRTo*lJ$erZyyC4O zRa`BV=FI$jmw3iVH zPJ)8@ci!XeOOO7FsZTC+gqD4O&CA2q<1x{yH#u-QmVTS?i(~IcMi!{)zokQX#Z~AUrQUfB`VqI zJ99~LXW~%W6PLSa^w1KI)O%7EF!DIIP7e2#VbwrdS~@;FJbZw9)mlzyD7+tfmPYu7 zEeHz*fYJTxDiuqD{r+p9K3p*d88(Yqah1^yqgR`^993aDp5G#n)pq{9FDHNkYrXNF zU&@TIO10}5y3w1${uamaneCsm89lUF>FBBPht@)+7 zO{u=CiFeznSNDyWgd*pfKMgCY8x_oQ1H}qffFMxMS{BC@@NPQNmVO_JlX@!Nxa&3K zBFlNn=Jt?nZ2y3@<1gTHoA7lG4BRv}sUWyha8`Ps~H|NLV zm>qU-pWL61l{^zkR~vL5^y@$HlWXs!7Y~G4y);v;nDbkz^r~*_=zCq}PF0K{oH> z3v{<%dBu#xmDc{KTXDj5ff(CsYUS9jCb-&&Fz7&t^!oETTo!?J#e!wpZY4!W3+u*# zInuNdH$s5`asdG}aS@88`%?hnObK;0HOqB1$CI;SM8wMUI!V2=0f=F0)UK)8D7J<< z)wdIGqDzTZ4A07IUJgC*!^gb$P?-M~ia~wQkEVH1H~MiWNKKMun&k}eveSMY%c7_Q z$|x2s(pCs^qVMx~*F#5{ZNokbz#K9kxvl88lGs>-<8m3`=I)R%?T`7!vEAC?9xb%8- z9>0CZX0Z}iW6=<{vDD)N(w~US(53<1*rlPqzDa1kh<oLP-Qnjm*oELqItuN0G z#6g$L6GOA>(NZ!Uz|lCrq`q)5cC)Z>@xJ9GJ*17yz05SYy8Wjtg6B7ud=7rohCl>2 zHO8Sy@0bQ>d0!Eob-cnxyB1RdS9uZ3M2CpcAx^>9`oqiSmz%`J%S)#Ogxx^xm8X3QQTj zS<7&Y)KtYKmsaimIPu2k1p;mV>|e@jw~b5Nn)^$?NR!gMqwM25Jw+eqy=O{Mh%q^T zTuso@Q2D*9A1s=j0QQ9iWb`z3E-EcT0OT$;Ir)9deRkiu5^Lx7go`NtcYxIJqYbL0 z>#Z*JS5n65a))ry-?h!=BLne#`J%`mkXyDf>g%X8|7pM?5Y0!QpjQ z&ObZFZlN*J#$)wo{CujW(AUStIlRr#eKnqYlopsWSkJC@7AMh?SIlu|+gTE~@!n$l z6L0vO7AY-FQdK_>=U>!7>1~X>$@3yoY?{R9Vib>USz0uuca4rwn$54!|KtD}JV9Gt zpq3J+z&sHz26uP&2BAtrgDKYe!L;+#k;34t?{~;b{=Lv&u$~T%3(o^^{6kqek5E2s zwsUGyOzKD$LQ&qrT(=MU1}5PBy!(UaQ>eI7`O$qN9u5I!$t9Whcb4j!BEra(EB#=+ zSXbDERZmIJ9uCQ0W%80&2@4wTZM+)(QJ_*YzDZTmu?6ml3I;IFS}|Tek=%zX;o;#a zfXy=#hs#~sBKed}r1Kv6W^?dEUb7hskE$mfqak6z_FWJ}8TGP#lOnHgC%3qbRvAr$ z6;KCxb-Ccq^y=0`u5p0%VHW8wFL&(P;f8Yl0Tn+c5lph`h5F)>lIymeVQd&`df%01 z;kLJrnVHYj^(-9_^g*}a`c-z5++$y_hT4E;!dM2phj;B*0VR5&Fi#^>baA#XXL7D3 zMz_|~`x^Ep=F-;Ky<`5{&Vj`tuEG;e&|2#`{f&l+Syc77KH_+3h1Fy?LnC+a`H zNgsi{$-O(e7N;2(Zz8M4{}5QLA^)E(Wh#$1;7qm{`Q_!8I8C{ua~CBpQhya(>~5t)NIq|x=2G)}uNk$hD`XGpFI&d&#_z~w{*^~d4_P^gT-NCfQOFwiq>pJ!V_f=aX zxU!5DBTLh=70g8vEQ|MOk%5e|93%NR842b~5v^K0|-^V!CtCDudsja-dk z4@wTF=u*EC1($HS#BI(}DufV-sQWCXmA@0T((TH@ky-=2IM zwz;NM3XsfTg-uCU`2Q8P|8wJ>YGM2|EmsGU2ySi`@kB4%PWVy-w%%IaTV;VzEMGZa zkV!rart~m`si~>?(bV3kfWWb@FALO|d)%v9Vno&2qCpkusU2|2BGEgsvj1Mm|7RD# zAtD}7uMS}^LuXEVE<_){sa3FxtcQ;S||B)80 z8wk#gC^t2XZ{9#1c`c5449&tN^961mLsG0v=~BI`ygmF1ekqZ6NFeV;YJRmuJG%L- z`G>DlQa(!l0C{yg#q(Ap_UDI3M^QneGk|*Q9lzKqJ1UdkT@3%T>rAqgP|Eqj0w_$Z z^BZw>%}<8Gzpno2j-R8+Chlkc4$OhmxoSbz|=9=jD~Z4OREm! zXHZvP$wZ^@ZfomGKN*I za>rWE`U)SqU`6sX9wA_LN3y20tAcM(P{XG-%>m0sXn5+xMfI>8)f&`IKL1)g&KX z#)drrw0Ae~KY@c1#EgicdvFu`%d7J0IlbWD1$pw*f3kMAMaT~j9#;?;9wxrNTAdRV zc<_Qc5{*Nb5JL#x7`Qs~8&_}b)llIFAo`Z21KA2A?mXEyR(LDJeC}dUbW(`r}qg8zaeWu^Q0S5F<&S&SI<(VN#47|#wE z(@IOdTRDDj50=44FUTAb*#AE2d=u}uqL{*`v=<@d{XNb+V3BvaWYp$Ws8ZM6^OL3X z1ADwO<E$G4ud)p6zE5xh~eR3yRQjdxg{mNEjODiGkzuUc_Y9U zQ?LHB(z>^+zpc=P+jY>R^M%OW2PIa>6ZTzM1^ZF-qsV}k&uJ7vHg@(#xlj5Gpm3Yv zeURQyrEa0ZRHp4RpY|LgM0&WvjUMnL12xA44rs!hX(`Zyxpa(0j_FW5U6zJ zF$z|LH=3p{>t?CYd`Biv`E9@9nh0rG1O6aE>Z9|e%)-z^!keD8l@N)Ld1 zsmk#^!QC^3C_cZy#xSCNkmsj;msR;ORLROzaTiOGafZFW$?l(C8;+gjx zBz!&6Go_jqxD|ESnmu-l`@r5I*a%{cmr6~J8ejtg<(bsg->b13l7+wwHXUl~Z0I35 zl{p2T++Q=%`sbLDM8$1_78+)raS&Q-DpSN14ft9v$!I0|^JPJq-c@ zKmOEFa6@CqFo~6vj`_Nx{=pa0T=aS5ek3goL_HKH72)EAZ(k4z-1_Pp5=$ah05c^G zzd7(6S#XoafAZ{ZFCS}vMN-PAv;%THvpgovM+OG0E?v5m*>4@~69>$Wv?3_BN?aZ} z&IAGX^or9F4iY)!zkp^`q19&enX8SV zJ7kZtkWR4E*D);5x#;$w&n=goZ}40nmkm-HnM9(R!6YN z9%njAda{cU$6skJPfEuFWnW%%amNV{(yzCYHy0E*87fumBLnH9PRAH;+W0q5lY7zX z4p=dKX8U2()K321C8!gy<3;Nm?8H-K}z(tWe}K6 z^sk%t)EI;EDKb@q1a1zW?lbs=8b7zb2X1Ac%qgj4#>wVLd>4B8Y|pwOM5v>l$u*k; zF6_x?ipRvcr0fK}j&5!R?eB9Kx>sgtC=*v%iT^N|K=903^Lisd{q7XF@i2_PPyf}mT_u*pG89M)PW zpD(q4JL^;)wG3ac*r?f%<6F+)c99zzjp0If{k9;K!|%QGNK~q{E}+U82)5_87rl zGn%rni7XM-d@uzx91DmfwbyPZc}>Qq78Mm$ywWKzwRUg02Yr%jP+r(9+YOk>dX#`Z z)Bn^h`llpw*wdGdj4s~v?s`#Wc35dMEntHrQ_;+D(@sicAHEsgU_~CA05?P^tVFp| z7OtlFEFL5k2EfU=b+~{|q|3}b zXy>>k%R7yk1tbbxGTAjXqul=6KdH2DRoC8oPt)DsKP9VMo2(e2TFu@QR7%?$Td-9= z$-Un!g9eK%*;(`9v^k~J ztRH5W>q&WKQ0HD|<<#08cIk-q`BC18#2Xj`kPGi-=fhT3U4v&HZ7%lHrL}@(YSPirY)Dmf6g@6u{1VF$3@=F^&pM95qeUmloSyyeWfv^;v9-O!9B zASOp}ocOCnbZw|}tNC-9F@m*(xaPmRc5zM!t3H=Ghws%Mi@5yjQU8snyYnClgkQ7< z^ww9-iurA?KaCJed=GlBB>kN_0W4SWEl}NV-76h@D59X#BJn~ z+}3;%Dpih01`wZ#Ug)ePM zNmlDl0DN=1LS`L#N}g$f{9jS0@`cBh4WVC83wD?vrJ9m_P&y`PCYZP2c%EFJ0 zIsT|#8`T0$EIerx2!Hh?#)R{>IeF%Fd)vYN0|V30Wj=5q zV1B8i%;@^7>lQ%x{eXSjJ_^7CzppHi-b^|{VIICpioxi@%0(fPqCz-BWb|y70t-eb zzkg97>)RvH)u`A4QDiBsDqhwHxAp>G*w2$TB{bx%+i1=PrQV#|9P@DNxH!eV+rsK! z^>Fu?y0hse@aay#4j>IKJaCD)g70y6b)Ard^Dnd}Tv2$x2PT`JI zlEksrm*UA2npi@7!*YzltG$qj?xpPN4RpEr7AOd`F+nK>IqF!U>*P?N6x z`0Jq>7u&+VnJXdq2HnQh|FJ4_ zkH{S?Kp&nls;O$y@4D;@>I@{Iy-`crd^OVMd!b@k|J;1mfsdt2w3nq(Y_HK#juy6~J~==?x5i70TEZ&>85}AJxNJQ;ZCyO1B8O5^#*0wW z-}*#)bQ-#1UNdz_wF%^Url>!&3pbExq`({k>f)W%nDU)T8zV|D1(woq8xi-EP6`DN z-||{n0WJe0MJIH5R1eunXgZF~@hp+G9}W_V_R_`w6v|gy;!_3)UTV>kpmhqeb;1wA zDfh=qXfO|$?k>sl)l%HpKzou2m*KT_i50&}tJW-kY4GbqA%e*fEp;G>%kwABq4;ZC zDXMpN{9HD^$HaqvLT@VVR9T{+)A*G9Zh4GI6O_TCPg{MAq|b3B*sQFasNp`$1{CJg z-;!z8sI;Ftpu-SZtNPr4@Fh4PQRYRxo7v~_Ipu?sU;I0I-Sjq#E#`=l?H5iWdqb*I z^9r1U3Qelc0WQwthvCXb1l0$S;fb-Xt}n#gk()weMfh;t{+1uk-+fX5b7^`ig}=0} zW_-<`>ZMN0#`evHE)$mh5+`Pse*TacRd^sxZuw+f@h!o1)x6V9s(KqNo>LI0>o_12 zj)aM+KTVYPRO_hS?9KD0^vlc=LH9lk38V-51tprU7E8;rorWWtV{ZrUn9_P@=Xm~( zs}&HoSs}OyH@&rGgSqrkpY<;ft8Z8AtS#4s^r^D$#$|q6Hb9QbFV<0w>c7g#)qO?+ zV*u%W1VWQxmiZSCL~PDCZvCi?sH>s#Q{|L^{6iPDyE1ac`^#UvNQiMPg@P@WKa1GW zfk!9FA90_)$~5S!kY4zuSwYchRZ0q2gG)WltY*hT`P8vIAM?#60G_%Ioj;x5(W@T;-Mr@Ho?s`;U(G~^FF!N>H$EdjDD5!$B>9nUb!&62ce zT}1UC^`6Tq^^PF!3f@HNxtHvqT)VDklx}xKYpekuS8OLcAcIPHdHfZuM7fBhZ8)IC zJZDliNwqu+5J~nflr_uRsPwy6fl^uS{SH@q#!N0 zjfeI2_ggYRntF2_!Uge99RdZrpBD0#Wh<1=PP?t-`1RH*6%f6nY1S3>9t2arbhZxo z;YkK2z;8ela!bqavb;<)hL}@+Uae^UkoLx{7s@0Us*Zb8arV8sg&|KK7xP*5<47VF zl@+Y1ZkobF*5`}#2Mg*6-`VV4@(^-{NjBA5smIx!(&l@3Gh*4Ns;RTSM~QavT^x+ZBaUP6oc&ZJ0@<_=o` zy48}Is^)5;M;g~LVa-}MK?cv0REy7B`egUtHZakZ)a_8RO{mX;96hRcl1 zceXt-xGsGrsvJ>I8+(1_SFbijkVA19*Qwl^&6IurmW2{JR$c-U$olN8bmM`e-=7NK zMY)Xt>`^Hgnf`Ujkr3}KK2ED(rUUc5d5&BocY|tAEAMB2`}3Xdy$*@LOgsWLqM1s8j9fKZFl~J#T>*Kvx7jvJx2?Fcc2-3iQ)Q zdSDz&xKzx2`lhl$CJBsC3I^p+K=1Q^JD4djL1ZHRtfqPZy^y-kS>>k=O4BcG!6nUi zNc8-Az>ywN{W_lc>`6=@(e>m>Bg5)6UVlSbooYLUz)=j}PIAuUGGpPx5jJGSsePCO z5Pf9w=5*-mddv?z^A?$g2WY*&yjQk>KY#>5n#y*@gARGeF1eyJuwI5sHeBAjaq;%E zuwj|01edCDsE572l_6SORlb7XooK_Lo78+H-S!7&vqLJ?H}6@2XcFTB$PW%vvl!gS zs0j!hVd?BAE2bT~%>Lw>%N`A!mM^n%E1J(3Rup^lbTflagzEuY*R=1Y{%#2&uO|IL zoi5Nb#e@eet!s5uhdg6p#SG61iR+Tg(`fTq&91h`c!x@nXz`nQ<#p8tZiebf4i4$L zyOY5~IyC>Z-uAO0Hx>fv;)b%cPKC78Ndv}>wL1#7Cb{GC?1C?CvLT0NAp;TxkoRwH zkwyCvj5_)sRU^5UVX0E4BS5yZe27tZlnA9!HM0=9z%waEvm_BJVHyC;)gl!sYQk81 z>yjMw5hWxto}Cn*-@1Tr6}N^c7+Ricd$REth>i}*qUH3FRrjq!U>V}Fv{p>CT8CuN z=5ieF_|DGwv_iuMMY)wxVJoBCm`2Py;jdQDDo}&mQo6cJ-|9EK3iJrByPFXG;)zopN{%8 z*7i2Eg73B9)z^~%kwLQKq9i-+CKt=_hY6&+O9`FM5cEl;ztrhs{#8?>6Vq~LqI!I* z(R^Lgu=Jm2qhP8}vWHepMU6$XU(-i0xcnR`6>&-jd(`%kL~q5o412496SS^!s`*X4 z$n%`piWRTT<(Z77wKb4ZchPH!TZE2F6XE?nKb&hSa-YEcT#8Q8T^}L|S>$Ok!8$C&{&7}z$mE#DtPAey1(&yf8E;{=iTi>bjdl*_Yr1H`XR;5Md^`^@bz;M-&Dj&=H@HJGp&h zd>_L@zmd~jZ-mvGhu&a4a~_x1__7&3nLo)ps@705FHuE~7y;%HA{_nc>}mW@l;@X! zQ1IkHPSOGJ0xvNZ2KxK{)AATWIxE{Z)vKxge4!3uWuLpdza2|0q}do#tJWJ20+X~L z5od^EXsWDSC55Lc5s`7^J-Elp;h_5r8v>aDFkW6Lw_s-nuYm{fN_g2GIsN)1;4|o= zt*A#_ey*q6L2|>6N!|80gwhC=smZbt>_3l=z(9YU6Wx$UDd3CWO z2lWnGe7wSbepHE-gWH&&JI5dBpKxgw=uo-a9pvPwJKo-!b8Y+ED{05Xa&U2;w7AaA zR;;r0O!b-j%gXAE_$*XQmx$zTx~{C$%)W9TvTmqtm|HPv$tMy&>U<$l&Veoe1v?1Z zM;%5fuZ_1IK2v-6g7QHUdgD<<0H}yY7IXk#xU1`M5_8jSz)<(JAmR|IuY@G)7x@e){ShLPdRb)@ zD={IYIeNa|;2W`QMRP6##hYGs@LF?msq?oRqD!dPZlI1?r_k$WTNDUc(Y!fE^+aW% zXq4^E2XXRqKhjw-9CN5mFY#gWI$v1+DR_Q)FGc%R2%BSkx`fpVgwDz@&SVhanFCvZ zfuk)DN`D*F3rZQBSu0b8flv69LYIv-Fh%bV&w{DxtXMV-*($fa_#QO{JEnf)xbE=k z4On{%D>luZN?WVnob&V2mD$-cc=IBKqzF{}82J`4JxUC4NT4+=K0BK>P6lK zBG(8y$d30oO9ho<%y>6;s(f>b3@yN{!@`WwpS$@I2KTbMeGeYM`DXonFNL$#8!B2nXjlPDbtW&j&G>4tZJVr0lPzlcUNc zN38a{J$rh9Y%~|RwfPl8Y@OyOKT8GdNcgPUi7G$MiWe5^G)n7fv}3rN$-P2;cmjpO zSJe|+3rf^-77LGc$yYg&U(DNRv3|u_oV!H6ZWqqP&N2yF(+k*dDk1dls=bAb0N&V` zbb==demaE5zxP(+0FWM*({(yk*8`m|{3#<*0%ARWS8LlXKF#E13FjS0ZeeJTE&3Vg z$U(oatgLtuj(H3_^GjY(!>^5aetR-WN}1qR;z5Wml$=zX8@MhJ1ku(-LMkdYbKnZ4 zhIzOHJyNyb+0a`d2M>K0+AH)KM;Y3VJvg35VQc>z2PdeB;Jh~o5+T=OpNgzGv4eC7 zfD(c9>6QzrkX2Dp5mvay_d3D3fs<5IGY31KU^n@a4kRb}zMhjLo5X#U^o~zV2uq+e zL?q$$brsOCI!)umz{NsV`zeow>a|qJro1gS4cUzF`<{Io_O##IW5_yfBmPO7sRYf(NiB)PKoa3m5Yx2<`tM~n7t_V< z-XoR$Hc1JGBO=&3Qt9ynM;S%KskV#a0x^&I?*QEX z?8w~=xU+*u;TY#Si&omMIuMSRRSd!{iI82Eu(S#ooz|*siT2GA;7T>n@3;^%C41K_ z7h7ZkE<1*QwNO09GfFOH3EnV%YpCfS|GB0=%W-{9Al&>dF;L-ETk5qvg$;6`Ckf{r z)njLc&o|iMWIlL@F;3I_^>Ryt+BgN|JIsn}06-4z$G`TAg#dGH@hOte9CsvV)@8C) zd~L+T$fS_v#@xJ^K6MB)NH1Ox4gV{}LO~r2E#t|9{4|)XF?pCuAzvEpP~g@wBdu!$ ztA+=upXEW3qg+89&}K}R68_O8pMw&MakVVBDrZpC^~d|gh7@Rce!qvl zMFz^2=+iFDHSweoHI3ngTz!Eh!j%FHAr)3_dIg2 zPY@~;uLhM9aQLdEZxQlx0U8gIAFmDA{~k=Fb;THB8`h}QfK~FXumbRACQ{pc z&U?25!;!i!lb1ZOYP1WWh&&99I{)MdBc*ws@(`|=9p(9&z4c~alantEClrzb;03zB z@9F;Iv38W^hmWe{V=NK4nnHP1vXcjYdKF>YdU)$O4?-1J!_CWxB1>#~SwP>HwE^3) zx6x}uwX$XHDnojfHK5vY8ep*oT4Ov>CourO$O$c5SzYb3qV8SL!K8qI55U~yWMxk< zrGt0J-2V;mBp)Uni!e4DeXA8U?jgkI^14=T9|+8G)3}P^t*#UDj`I7_>RYcaEsyc1k@!aCE>)5WD|W_C8yyS8M0F-)?3F_3eEyYJVTPHD(@5X|Z(@|KVd z&HhHiDJacFIT8c7xMQ`N6RzQEZnGxtRST7j%SLF#ZVd)bH0dKV)R+n6paN_R*Zmdo z4s4d2#|gdrp+qaE%K+hQ5D<{Lm|zTD$`5jpAFhFF(#wRKslbTs zZ7q<|9%$5c!CRn9KA08{xk1!ySts48=>t^)#|HylE$-STuWgupAW1V2oB~uoMnCzh z&TvK6#eFCPT`~edz4gEZ5RQjBUE(C7doZt6tN74Sz@gYoddrJQ095=>m@y})mw9)i ztKp}=S8uHqKppR>N-dG-#N*6b9*kw!=1Wp&nzdpU|T5a)wGPNs{VNjlp=UiMQp z1m{*oWu;1Fpg<;DMBHYSV_>&sukX^XFSk=tJ?m|4;q|4kb3Bwz!P!uXRSkl zH~nV3=2SGuhl{=h^7GuaFV;2zWPL-s2hB*8`rmu{0bv~0mMbaOP>+Vqa;d2s9hA$s zO+vXp!UZ_gs1+kA`#w4eBXUYi^=y-gl;-4#dl2ekwpzypnaM|VMgZ&5zo2Msdk;6J zQYY}@G^p5|hJd_5idM2J6v{$|TGk(X*S`#As@?{UwzZ?-}HW7W&KtKCvWn&ocZj@0J$-}DOvK5#12gJkNBMM zBxZ@yShc+}4mvVNH%s5G7_wJp23$OKHE+#xyWOk0Q&l8^;-s2hlmegw4Io;KwF1~C2Ngj_Z((3LA=W^{StWWRmR@2iIbOUu@EU*6ZO*-G{XhjFJw0a+uU~%z?TNto3wYuW z6fqbN$lVDeC;PD1C=IFRF5R&;;0S?iF0a*_<=Ve@y2L>Rnu*onj}^@B$*I7cH2W$} zCB|HInFJW+m+}c=3>a>JJ^3E+#rzNZ!9*8Pmmh?u4*uS7bT9^ytq+|lf^tp&Te0lI;Z+Y2iS-RCuoB8Sd#9pfS4SeVQepRk{WCCvqVDFKAXTo0GH@zZIT0UL2nN z58?4UZwr#!3^dGZh`vh+tMT1_1Ly@oTPEZJoA-^2B-aH2cwhCOkC_I|4p&@$^G=Ca_p7{y=YiGGodtdS^_2KP6TtTZgf61q+`M zcu~LK``Q=RV|^O&wNxwS@}qHr|ZmCO5Q2knLm7)!FtAM@L4MsdZ(2y+-I__|+Q3tSH#`Zj6~ zqFmjtj{!Xb=|s$c&KG@*{0u6{z--5YDzc>i&URCxJWV*_Gf;lYL!2b@{;$IMaI=ng zT$f;Xc(AT=H#d1$O9B zt4hO_E~~9OG$#wWsB>=nke_gmox?$LS|xw(HPU0O+A)vQfoi8%^~D`6wUv>hGK0BA z47j#ut8RURcdljp)enA;>85_?U5-|I&Z~ghzpH!((49>z-sMTg-e^Mu-?ku*{ka0X z9pDT?mj=xp{@A!v>WF$8R4RnaDZeq8YQA9WAfd2!*G!VW+EkLBRiDKSJB~0vc+^4? z9+s~cvK+tXR8v46QV&3+g(x#8EbXQ@c*gR+lY|=2W^UwLr-6Ki=@acLm?EGN~IISz1~`^%?!2 zHxHy?8&1(k1@F#_U7=}NhOL}m*%kl-+%h|rx(&$$qbE-j()Jn0c^o>Gt<*eC*CWAe4rHRX#N+( z2WQg2SYE1Z4RrK*@II%5Cv=n0`2w_uoUK{aFY3(QnsCt)Wc&H8Ccrz{90qLS%Zt^F6q zV4!}b=Aj!uf)2$Rxw^&LqtR5l!irYPQ@|IVoIqIwOr0Azw#T5s}s94QeI#nKKG#;}&dvUi4!#IWByZ#_; zFz=zvnENX2-1*qS?zBVGKevOQO!~CYv@>mhl|c0UWp9wX|#TVQ3eKbty|&gD6b*r;019?uu8PvS`>=UUaV0d0O$ zeeJY%4SLa-z%88p*pHkJ*g18v@zcR|a)-kA3!+WO$NN;PiJ`ehu_Yd8fd%${7SBAa zoOw{c4u)j1sd5C7Z}6kH0l2d2^`W^F7v1-W zPMG9DXCmM$3LpCbOX#{K@M^;TBOZ8a#tdKv7a*blkpR8h=HJ&pgyn9(*o{11d6_G#z1F@!b^yR73}NxCDC#~_LtOpum+R@zNl6`rmhhb~Q$sG= zD388%P~_eg2w^*%9tMOr+Brr0Pb+|ci(zgt3wYa$R1m}KBo0*Dm#!Js-b?n{EN_p5 zaBQ!vlns2%%X8iv2+fq9Qg=96(Pu>XdFQ)$2bi58>`0G(R??k5W!>7IlFz-OCA)QS zD>Bv#qz;^1(bZEhi_!o&S@2u*oPMAT#6v**!qo6L`(Z9_C2*JsA)V~&=^;ww)L_N z?)uO<_5qv!7ka+Z%@JDO;yD8PA#|xN(GRER`GwoX^*yF8*p5fA4zaS}H{EExQnIR6 zYU=CL7;e}58KwEc2zoo)|1{e6%au(v+eZR>s)72Hx+T8r{8Xl5zjuF-@K7JhN(4)Ftk1&@hYw~ceE8y z01xd3@Hp)WpEh;eynpv_m6wb5CJZUy=H_+-e>ksrH|Hg=e_vQZVcfHW;pCs*KPB~L z%o?7HdCiw#J8BADJ1v$Q^@eM^i0$m^OwQaCerBfCa)|Lb?x;OC8cl7k4k`*+P4*M}%<8YisdKc?RQ9y4hfV z3k|XNgGt0}uT)9dx>24qLV%^n-IwPD)d?AXI4~C8Z_Bu=w8nf_r|dLq&y>XOEJtq= zx>uXee9jHM7nzWHFkbj=w4f&Ca=d`p8;-h(=*oBOx(8jvqmULzb~pQs@lDOM>ssx& z>P`I!$(qH~9W5h&+6iG8?DCvsOlqI4VSmL+-%4%%hq+Z>;x95R4zUQ)Ouc=}wV@_f z($agW|HTJTNTEvum*UH1(JXq8-D}XaS2#`1+vbjA~eO`moo8DnF?G0p{MXPimx8&?i z#NbMCgH2Aacj@x1sE=(ry;cTHJ)jDY6bb-W=??RciJv2>~ z#?&i$e*POB^1o(9civ4^XDT>KC)i%D+M6YSkix9-_8QlC5LZT#`p-j%U*iI2&*~Km zvKFV=YIxXhhE?NSZBvG7fF5Jyx`NxR-R{Da-04r%&s#FY&pJ|z-W;W&n00(OSG#_F zsfBlBA*Zxsd+{O4-Ow!)d)2&i4@~d?2~rY~Rjhfq6N#6-3Q6(!+G7(}x>I*S^h2HG zyQkcL`yyRO%05^e{;cB73Z1FW7f1V4`xgBiJL6?MbH_!=MNp?^*NIKBt! zXG+fukXReB4`N{XkV{deY{&olN{g^mXC1HBnrys%zrASs>P~}$#{z`2XZ5QLBlU3Q zs^Iy)-0zaXd0Ec+h^|bNu@7*U6S)k_vb2}mN=3rT6%WME^MzhWOEjq zV^vvMX)715&u9$Dw^D_b+3@<|k82Ji#-9SAet5?7uOO4|0m?YG`qr01TA)COwDJvV zFv2IFwj6sq53SI9rssO{nthfaMF*5^+Uxj=n?cQ+GeJV-oBc1NVsDxgG}U}+H}>#0 zz;FpZ?<^GMEqk3e@74THTD_}nYk|0ad_fFKd$!6+wND7v?lLzbX;`a-Z0wgq8|P@D zL6!!23_Y7cg`vUid=1j`Biaj6n2eSuU0#fAlPcaZwm|HP@1rQO`jD6ekHk`b8wNw~ zB!<40CbM`qZg=8+&d~^*!XhlQ<&6FUn}O%+wZg(V+5Enk^LYWAv4o8z9|F(8cOAXE zhfN#a)-0#aIjupZ{blw(l`aC2+;%t3-s<_$;k3C9;8v6RLlzTQZUDV$4blTC&Wn2# zhQIXyU1@+k#R6;PO2?geLr3hdcgnQ5N>J#SAHzB;h%>ei#v47-Nra;4R* zFMX;u=y6<2DZiz7EY>Xt-HTet^w)*K?z+-0f$XA*05(8esSFB=c$Ul0CkUP-hO@ec zw=~khTg=VVOkx&vbbmR%pxAw+vu&qiAjhe8Yy9eH#~`mv8(v?!|4fv9Q}oFjPwpQ& zw3QQo2uAJcHm9>d^N-AUZ_Y!=Ryc=jL$$%;0zqc;PUC2yNlMqD{Wb(K`Z7ED<_lRA z0slyknDvdWysEnDj)7<%qB$~g$@B9wTHKbT)Jw;B1~Dgd{3=z1p#^Hq`*m%<<7KA1 z>G1jpl#{~i-hBrN6L%o2WRMV*;@yJz zDH?Qjb$tnX`(ew7=Op|rxOLyBHOSD&e?z47XMmkUlmGHa`rXARjxUpZ*Kz}INc6>A z#A0ET+!GEp>8GKLznkC!1LOzBJ&-t0z5DXc%^4aT-U@R$^6~1Y_&>tQev8Rzr{;%o znnnhiFAUJmBCzXoRyCsS){HR3Te7S4zz6{v!rKSZBzs8ID64I;k^yyZnl)6Bo9)WPNwV%^;R?u+9_ z(1E--na0+{L?4;)_qI#>c=!@#&=Mx7`Qzo~SjQ2;=nW~OTjqr&gAcZC-{K=jd6|;( zUbU`;JEThw9aBeg?fgpekJ^yhYqn#eO94ICq`PZapEm<3_wt?1 zxvcKvq}D$TNKnY7xS+p6WROokiRD_?<=JLS31qkrJ#t(2M_JEHxA*e8dcfm#mX=OE z=3zIRuNfDo8PUImTT!XLP#44;A=~4BdWF_1v2^d#(q9J9OF7|*r=P3$nK(X3u#sfU zuu?{qCR!ZBI~v{HTJFw>5m3pNUmWQ3(6iTGi)|mCbIZKn5X6i|QpDVmPrjJA7h$NM zr;Op#B+1B2E2a4@XsaIj>zkWG?f;hwy`!*V}P*@L}QX%;dvL&O#f4+MU=#_obqK2G1s$)UIUQ zQ6h#-dhYdiAhe;|^)%&>RThd1bJ<1J&MWvc3S;QS`fO9*?bF`ywfPy@g;~VyxW;FwUB_%+@0UM!F)k#bY zS(#TkL8D46a5zeN9JOUqC8?P>)PcjX2cG&P{-i6dixl;9uA{7I^{d#(ALkmoFu#tR zcV|8;{BC~6G7Z8oj2XJ3d!3R2c*(6^R3CYgHjwt2={q0$QSn87xm=R5grD4GLxHh@ zu^h3(BD~q@YVE$GCmrHd`i(%8>L6ES^^Bbk^m0Sl{f2gN8ff-xEP<{>id}PiW%r}S zrDkm-Tk$!2@xnclQgsFlmF+i@mIBm{IGBN_m~C}muU-EOHQB8MJ>M-J)Jihf(fJ{7 zL8|J_vi0XvUPiu}@T%E7@8U({_0~;#LdnXIKvJtzPr{&2(XrN0vYtNAs@@<6#qr4^ z4UtGL4Ej9r)aQ$kL1?gba{|k?kyH@71-M#s-?aKg3~@0wD`6?*%-K5K zE1Nw56lFx}dd1_y#dlN+zB{;fIl{T*@fxH~_A=y%oOeAGwTQvPZYe<2rUs>)RspK5 zrdKz2)0E)p_cM8mXt=b`@)k#5W=sVgK7CUTsgYk_n3X35CM7EA^PW*q2eRn(+Z2x~wN0DR|$&5;IY}w$*Pc{h1fX!QM5de8$4i=X0vWOQp>~=K%yai=I^a(yu`IpJw7I$mrtl zJSXNWI~~DUAi!X`1vzoy?Q81DM4056yVe4Sye5-8%-6XT?JKkV&kgf^73CkW%|Xxz zejJ5|S!~!-NJ%Vt-7R*&^`iok0*r>^$}Ia{_ZgA2(TbL$2YAn$3SC#76Iz7v@rg1u z%er9YR>@R835d!z&DBx=sEwi&;~+_I^va_p&sT1XYkzbSg;91yG}$52H`uhkX_k%Z z_lP4u-8YZReziZfzgcFRR#|MXHH;nUoT$pH*)Wg^l=NGId^? zc8(&t@B>%pY)#PBuiUvmcJWNo@4-S;E)kdj-L_YAaQd8)Pm;1KT;PPZbo{MK9l9YW z!EeSB%_??-nAG@u0fuvfUAe&eYxgrtG+qVCH3P_U zc1{lu|6n)t+Jp6C?PyD@ani1c`&kveV04Y#+NT`1 zMp<6u(J8GkRL_IMbsaj7Yhs7krMw_5Y*%PnkqwA3^uv%QR26NXHg>zS#M1Z&U7Vk; zdAEGn_07)6tkUb-e$$#VV0IWUs5nxkN>w&(f{3KDJ+o)GwoHy>=3+T(#Rx{!OzC~v z&0R>lO!xGIck+D0hQs|w)TWDe6!yKvF7Z~a-=DSH*<--Wo{FOUK69<2oQ>VtHZTcu z#IjNplU<4rkt~Q(G4G9Lv)UV}QyDjfg4XB5 zaF=gVR8gRnzT5h|osLg6dCZgw3VFDjbEw%kmM1Fx?sfyMZGc9F6L;^;JkeTt)^uF( zel7|(5a3Ub4uosX@r+uV!-P0{zYt|5O*HkpD+utvm6DW5J}=PrXg=aQ3z*}KO*g805{rD>tS!g`EzP8^O3I z3P&wRl$eU5XRH6^ zCnyUTIzgvxP^kP64^bDhzLt!b1Owp%c<$rIc8KC88_Z~Pk^e1__NOTSN2C7v6N>c= zh{?HBUKJ}Uq<4S;wO-)V-?kEvi>Kd69% zScIe;wLC$vP2ZCK1{wd4D};Z*2Pu3!a$b(RvSh#G$xXMik!^ z{w+K7f1H+72wcv&*nC{9MvHuFb5nYWmPa29ivr8gwzJy)ZJ@%xofvok76Zju#>mcR ztGJfK4G6|BhdSpHMqG1%+z|{6Gk?-@3gv?fQGcUo$o&Ug{F8o1D)q1b7-J!ZqC_*! zUvIMVY|_0Enh4-+0R`w9`fe-;e&`R~X2$GV_??-yGnM+eK7W5U(7?omu$j8dwH8^8bs0u(ru{vKrf zmsLUk)D@&$@0@?cND>4iXjOl`IuDFS0FKk!U|AyIG=*1#r=^BYd{r4b{a(UABxb=M z{%A@i>t*0o{FiZ8!>Gq>dI$ob*^Ce^w#TburBAM$bx^6+Aaox293Du8NU#t?p74T@lo9TE0uKTu`1c=#br{3PFZ4OuoM&!) zW^J9@>8*?%O$gS? z#p~2QcCExpeCVB`t!-s<9atRzjP)GJxjtvTz*K_nj}~C4el+;1`xJ$p|9&z5xwFDl zxS@JLOeT`0!DQ#>lo_}svD0!H1aI#E2D*1jQ{dQpM$J;>o?l+q5SW+eHh$j!Xbv>B z=kcvpSHlZTyKj5KPeLHrOK@9)|C>}tcf^E;LQ>2Y&e($InZn1#Zt_*F(o|i}%@NZ} z(Nw|x^6DiEovX)^U6a##WwfRz;R|&%M=p4C0EJ9dW;W1+$-&I^I`xcMuP7D(7Klz; zxO*G}5s-eoufMs_U$khNQ%t5_YW=Pnt&~JY&BFZRv4@ApKtQk;>Gc?}SbkvX0r{~E z#ZHxb-m2L*#vOt}GT)2f)QdlL`m~JYy3Yxe83k#d0HW)`onyE3REVmN^t9o4_*k`V*N$brMT2731#e>ggr zB6L&AGxEDLgskzJ!3fPnPj7F;E*3k|H%gBO>Ac36YlZn3=W~n-Apl*4fWB?Cv!85d z&Mb)Bv=b8(y8)qNuN#QUG0IwU1NRgs;pK8HQxX*VdRkZ^cu0x)nR&V{Xi(8)zRx(P zRcxU_|D*9khL?(oFizyW&%QN2o{{1%GivFX1Sl1$w#AESd6k`sd__c+;v}{_P?GZ` zqZ~>g?+rFRtLSj)ck zk8%w{;VQQir2*w`-s%rLmH`+Q{Xw~Y(e0~y2F0=WluRaQGwBn6 zq!Y)4JmZG&g@r5%@S#qte_{u;vadbP=QbTvqF1)EXEZN^#U!SS1sN+f`4m0Ca6C>t!=58!^A2VS%|sJGfX6&iAdp3F22 zsDSXF>9NP&^>u$ZS)ZDr8=G8Jd0qmy7vS-sz9KK|d1~zVO^(sL$G1+Cf5d5C9c_ne z#~zPBnd&+u9t^VIn*ERkj1*}#|I_Mmd%CEzr%#=d7Mr+?2gxD@+<8XD{&+=~e4ezc zm#$VEJX8bRCNG}w2{F4LieV-eOz^~hptz#h)5VWhac?1cb{QZJdvUi>UJaHtNGJC6 z0VgH9=38KXW0aymkw>H=C_#QH8h_>Z<8@uLo@@+pOZ$%5ELIaCQulLQ__4me{sGM6 zlv@o-&U*!y1Nf`xrAqSg2Cp9qdx+6t<}euPTMej2zc@`2g#1hifktxxW}5xLdi-{p zu9Kql^Im3r-+^!kL9q2f24hU6R+)k9&}eqBM*sUc=3|c}djqTiT6%66jg)6~N}Y%q zMTaocs-f%c>1z9|~RfmRLq6HccS}H)Lb9BOd2j}81!xL}dNdEaF`Eg6Y6Bi&M zc~$_q8JYZuK9G5B9FX?Y3$CD`;1_^AdGe%{1(+s}3MU{~Fel8AJs#rb6RP`_V5Qwm zO+R9VZ`RRk_&NG{o?}r=0wQ+l-GcP7vPybUVf4qhq#dR3aXN*MYsC%floJ@|EGr#< zBC7tgS|*vskjsp@?eoVk#KZ=~gcV$4og57~LsM z(gIe}e!g*z>e##HLO`T8c>vUt7H4N+t+&^F&?CvBk*hB$48-hok-8G0T|5r{(D1S! zFZmdGeN)rxQeFbduF!y)ZG(OQxPXK;jMVS~M4|yC>@A_nvD`@TR%f&^gc*V@TaY5{ zr!rcg5&3w8xv+jysSQhyiSQt;IQ?-}%Kl#r<8P-=Lh|&dM%vB^C{s)Uqb@9?AS)9C9 z-WI^Svl1O(HxX=l1R(^E#6({fh)K$q8U16$#1q~WaWxRml8l8yw^SH9)q^7L+tX+f z^4$j7p7(sW5OiMcs9U&Z}M`41GAvfOh5zO2w=T@EX|u( z6`}5R-?PA*Mg-tmV6HAMk1B?l6IFoB-vo!zoJdza_ArT8AX3&!P~jUxS4nG-QlrL> z8y0hwzR9Wny$4<9N+*4Y1TZf;oJ}Ly{hM8yE_}R*HdbDQqREqu*74}Y?n$xpgVN^XH0 zVN>qDcdYomy#=HXh=2I|9HWKF&##D@`xeV~MS&rp#?Fx!@S-rlj&x5Oavp!6>Wero zdu=!5MKG+KPJ}~^1n!2)Lk+4BC7gqNL9F3_fW#NBhcf_Ak1b1*TA0HWG5)al{4$PL zIz9qslb)hIUZVh|4Z(tD>Ch2b;%{|v!K*6QC<&Nrf+=X6!{N+8J}y19J$pRIxu9xl zYOZMMIaZwoUb#3LMD5ZVb%l0@HyPoHxBya-Y=7{v0>r3zSrH7d?3?63eJ4C$6Z{-2 zE3hs+_yl~O{gkTMvD@f~gK$>uf z<+1y?9#aii>k;gBI_dTDYCz}E(T4o0GwW6VyPt6$0F0W`a{+iLEI|02!=D1x`k%l5ue6e70?}AW5WA%|ABxpx-qJ@~q#scUZ2z00kM4dc-nS7!<`g#Di z^;54Wz&S{%vFE`l*jB=)Ra5!@Cc2S?C=>Lzgkq1Kko9qrb02a%u3ei=R`Or6nS#4brhuNM%0e)n>Z>o2b^~PtUMJ6nSL-f?lHZIk8;Z z?-nD4_o418ahdtWocfb%0k29%Zqjx+*0u_y_;Ucgb!~Y5gWdc3=wA+99IK-CKzxKz zcAWjLSsW&?*m5huSc2*L^WEtj z?26De!UY=k32sz9z@0ZOXYT%X?F90y*1aqTj9TI|X`+qt`Xe8-iI-Pe1meF22XcxR zi>_DuxHOg7brL{H00lbgAY|6X<9j1bt`}>J0UqY<3gqSa2+$A}i;IqT^ zN(4~rhbADFXw*_u_=jM5m*7Qb@VX$8wD54JXhDfYj!^8f$BzR(PHc_l!|?NtdspF! z27kFrrG`MgR0_3rjqc zod#Up3V(}4qR5G8w-5YpxMxYsuWQT}!t}E=SWTiU-=HV)X=Kl0 z_T5t~vD)~ry_zaAPN(dTIA2b%y%a^kB8+G;!5)ska*L3j&Ua#1!DQr2*&>u5&AVwe zi|Vv|l~PUof!(tZ!fH;h`R**G6*dejNP$Y+*eVxx@k+=`% z1^WFa=2>$R37(XtwPB?0?iUlwgcTw$f(P5<`&yku8Yk`)**u{9;JB0S5tF^s(Kux- z;9;q>I}Mor1w}gDR@O4o)oE=`E{9fE)zN7pO$4Xe%=QuUGFJ4f+q?7%b{)GV3(qy zZm{B@SZmyJ?$By~mN%gyW6u5CjD1PA0#&7z2HL9V@XqEd?qxHVN4s}=QrIrJ1wUF8 zEyg7$;I3!Bh?4dqlA4M8X{pvsjGV{X_3rAq=r7zfY!To#k>_Jk?NM4hxYOGj+G<46 z+WjoMv{+08i#NzpU_RMIKI1k`v#&CA+T!Vb&awF~3A~UG}8s^FL<+^i!RA=1*ROax{`OUp2Z_c@=^$?y!Hq z7VibwMbZsQxnAj9T~UUakE-u=1Wel1PHnU{^I(<3sR|OGQ+ce^Hr?OZH?=aPWtF8> zqjlXBNjKSL+q|*qZ&2c~WA1$D?*eoW4mt!9RP0Wubpno;3ywWw#~{X1AF)z(I2O|o z2jpVLUqf-EwRc2RRIgsNcydV2i^R8jKe9O^tU^akM?h4qLHt|slkA{|)dPJG$_fD& zbdY=rFh4CTSZ~2=Z924C)E@*7v(|p@`ypAk{9O(^f!*RIt``Cj2B%kjs+C0Iq7g$`H`?^FzHHv?cM}1b;A*`khG$ODd9k%X zBy$kk^!FzX7ALwGiC zwm-U$`}RMf(?vB#wBlhBOl0JTjb?EG;^BDh{8>(vXgCR@04VPZF^q9C#o9)PvbpF>g=7aPbp&^9My*20Yump*O0FA=b)BoR-8gF;q*Oxi|~uK?V`84$zV`j#7{k!QU6+7)fSpw zW9rBL_O+KmIf z9N)TQZ@;SDMYYH}{hgrH-(Uh$-Z#_NF+a;&;vq~lik)^!Z7)e!GoP94-|?GxVxUbz z69h$k}}JfGOKNiCw{XnUHnF`-`~Lr|Y&Fj;sTgd98X7kki&5 zK_ksT@x@~I^(?bbo{2>mALgXwTb^)R5F|7YN&@+bzj%d_D-G`Uj(bIPucn%e5el7a+6OElG4+5^9l<|l<7#k_SOjITk^>{fZ1TUvvURa7t zyXD=gkvlY9tu110#6=pdjA&81Avd~~S}x6zwUyfc$hB@ytED?>CdV1{gqx94nSi`! z_%~Z~=uTj~hrwZnhXB#FOeYDhha(x(!SUc(u~ATr2PLqJfVZ$G%{+fXe|`E3fnAO; z3wkj?lt66yOW)R4ox>vI*uF#m{_p6APb>pZ?2T9K6lX5A8{sWI3^JNoZlC`7{`{g} z!#ALBEB64C(=ymk+1fwr5cDueXj-ecOqy9NV7`6ukzwMM7K}nW)_}43vxsh#{ca|A zeNsF3a9%M5BbOK?uglcRYI!}jMT5ZZwdYith-ofg5i<_7e&I61Va`8^HpD@SI#oxt z8*)EK)As~woXAt%CZ~ry3gt&my_O#4&*9G8tTXlIPSU^yy*n*;(iU9D_$U^wAK+H_ zp^e(Ub(nTIV+hxAd&fYnFB8${zOfwNGD?M7mnt6khE;K`kRS>Q&cD)JuZBPec$Tqc zSBQ?VPYe6aU8)}!K6Sznck$Hbt2yEF6k74;sESHI9Y6Djr6q`l3ik!)d> zdQs8UHTr5aUXf?G~=x*sM#RZtr$KIDAh9z~|dct=sYsJgTXkvC}dP@7_mI9hpSg1V#YvWdU5vTestBb?Gd3>V4=r=}mtIFP&^MBZ%*WPEwE0Rn?;FAg zd|^ey8U3+NJPZ2c1yZ?i?g(k)%GK#rgVZ^WO-`QW^KzZRROba(`)OSHFYknP?P4$V}fGuqI@PqHSE+ma1@u`f%rK`6DB* zVbxffxFa6d$3|3zkMnEzj-tOl|H`aywY|$1lVtwMGFx9{SuJFX?1{oMYeIr$!T2Nzio#oc`K1k>4vl z^mn05yt;lmjZ#gtBUF;a<6rhdV-Vuf2(9j?ze%62^6yrLkG=D@&at6^0bx6x&Xjt`@XBy8~l~DboV=(cZ3iOGYLi|gVjv$ zFh1{_#~~{P7`5J8|6#|6njQn}b+yq4l+CTZ(U)^mWMvl5M+JfR%&8PkksCHsxih&| zJ(J>}Q4Oa$*ejnkU_gJe2|bDnz!N!8fLY9Q%K3G$??}4r_nbs#qBbAw6R}lG>dcXi#pP zds9T+4rWeTc^@7^x9YOuAN6OmIErbszq4P|>Yp+9*urp2BJEX-O>m1`&#E?DLqN-A zgkH1PX+?c=NY`I|g*2S>{n;zwmbNslU)lJ9rsi3@D3WKu^;!1U1L<`$98ULjVd8;o=J z6S4U2pPmrzoRko}P@$SU@C>1*eOr8OomXY1kkz}paJEu|(T$r*##)yBzOK&F>$S4yv4y_%6eXrKr*MX{rN2e-@%E7AQk@9 zC2Uv}-aN5*Cf4vAjsa2G6oNBdKV8U_1!8Z^D08yS)QzBj{#1tX>b3ZGbB#wnwS5AM zqM3?O@UZ=|Mi%SXx*V_ll2+QmVO6yuwKT=|(HT*1$hy2dykhz9fL{6C~5-5^O-x8au zOJfQWtB>LeN#08g!z`OsH;5Yj9V}Wg6eWGB*QJIMwp$hr!l(U>h)N9YhobQ>epy|W zl9`I2lftHu4^rU~&s40%W{z;46Jd9k>Df}kJ0GHP9Rsuuj+WmbQYUJNMm`CV@T=Q) z+t=D^x6pa(iNw+mtljZTo;4U@2O3L2&tvVS?GxIyeyn)J6Z#xjp5YQRiNqVDbg}Sp z(dEj?_hZg`u`uk??m*8BwdZ&RAZ)+q6OLf=waE+(%ESa(iFll^&X&L`LuOe8drDScdE*n#ERC^9;cdWK?TpREy}65i*{tLWq9KxR#+>s@yph&;)*3A zkJX{|1G$le_Gfi_n?V-zdz}5WG*cBGYuR?VU}j{eE_T(tzrs~XoTQ=1`t5jRr%6J1 z`?sBXrNbNHErH1KOD>}#Blo#w>TepnC1}GMySK*bh$KX_nO9l{RaZA{;c@E)x5+Z} zmONXMmRn7#bgCk)@itf0ix6pbov)~9DlI0yedOT+%yKtFHEVA0oT(6s5|>!u&YhFP zB?s(oXV?D57xJlaw~roM9-mAEuXCUUeY74*dputG)IJhwLgd4VH~xuWg+@nr@1QSv zdt5GP+&{EW0y4?kTmg$5JAesV0o~MC)e$_y`eMxw>G6i0T085G^$3MWF|%0F#8(if z_lOLN!z|M+yUCQfO-(sl*Zx2&XPCT4Bw+W3%+`jsj8TCjErG0Y*M!?_kG7S_R-JBuqw|X!o(17Uh6y3(W+@Cwomnwhv)+_jgFd+Q&0U*d_Fkbl&3$hj)*Ut zzRhs=@ae%`=2Gj9IJZDhHWoNe?FF)5BcY7)IB$cTb5pytGmH@$~ol_kgXv5ZzD z38Br4Ug+J}aYZf5 z+a#tElK!}eYV31tpmVg7cfDEY3;}VZ$S@2(Q}a8#RrIfj>LK-f-MMz_B5pb7#gxZ9OGq{wK1&+h~(4{`|JdYK(@7}KT^6BFH{>XbP69Mj-Xc26t4^)f}P zRnk_l5I0X>Tm-v@$hX)FH7B^M>O|?+oQue@wA*7Sx8dNKq$PrjJ_gs)%QbcK*q_fE z_>K@MDbRw}kkswZPy@v5F4u)N=^?a)s{Q#Lu=KHL@RzE^eF9KM-ibMD4; z2~(185rx_kLwiFk#aio~hV#8&o)ObUEoFo~Nf^fze-xR^vKP{w4e&QqwgeO$Cf{cMqL4N<}Hv8Uc8C&9nCd(E-ta1ZO^V3mO^S?&+*@z}IQ zbYBa+5dnAOcUi5Ynvp2Gq1L|P(3`Dew!gbEI~Ael#qA5f7-!$3F)Jgn`;h#s5Mg*K zVHYD9Y(#w5;dkZ$MOI9?i9O^D>kS7Rv=sI-qgsR4SnI?$dc<_&6c*iVw$ljIFY2Tt zHMm_8ni>KNbB1k|?Lqn((*NGs~($uIRU3%a(X z&BqbZI46u@9L|;#Lou@Y*4A9?;Hj`I%m?mHW>DZs)<2WtjnN<=y?Avci${)`WrBWd_tK5F76IF%bI$q&}tSJD8IBX@qCso&_T_ zJW7T&pOOf*(*3!FZb}{cqbB3&c^{#h*^f!w4g*`Z>)vth?KpNWCusf@&!2D~z0Ghv z{wFTQRts_6TDp%!4hNIGc)Ji}WMocbt+D&mHlGTmi4U^qDoyUc>0Hw5Y1O<6Td6Yi z?pK!gGcBlV)E@~nnfJfB8)gK;>TC>U3cs?qUDrvecZx0hqe1kDx=XF4B(K6Uk3Aja z(s+R*VU?DrTKG2KeWmn z5NW%a1uXa={jCTToW3-OjISm0Nbg)}m{dTP0fsg6C{+yD&{wk6q!)af}>h!L4j zHCo-P*Cx}5dNpsq@XLaFsBiHdMp%LGOHr9bep~^CP`^LU^#8f7WGZzSv)-)U$rDFb zV*^s>R{mil)#lXEpD4&+0!bsD9hnZy!6tQ@?(t zsEShe65uJuNmeE_dATG2ne0J$f|1Jr)R-6t4Er8i!+>(21eXN<@tL&6I#{L@7pYfo zmt0iefD$MJCs{45?)MV0KdW!oB zf3ElMpZlw@Au$Ud^bK`3g|Q8k1zzga1XV;@phVVO;k^U+tTL$FQNyphcKkAf5K!eW zN7i*gZk2WFf}qoizOzWq43wY+SGYqx<#-gH_(N;_%Teg?nY2cJPBpXFVuD`qwjwl3 zt;hHhzRiL^fBmLfJO^Yw|NAHZI*e!abztR7o_41{)DnY*f~qqsP)lqySBxfS?6?N# zf-z*|d+|Hd{nr&uNl@y~1t8dPcC8+I;_rUcWInx;ppSv~^YRC%EGH1Bbxyn!|MjE4 zpAeo5ht<+F=WK3ls8~8w8A8bVSU%<$zQ`_zV(tPLkA~PQC{ z+xZz~vAUx}k$zMtDey;iD3RAfwPfdH@p%wZ39o(s@YpR?%M;$IM~AVgwRO$L zmE1qdjvMHmGyr{wczoWZADLFdSqDJ>!GE>_pM?(pETAy!Io#^}zTujG?ht!8A(5Q0 zwfK*GnfTEFUoei3PKP3GF& zzcsJGy$SceO903N{!{WUD%)t?@2hh4z^n}x%+^Tk-r9Xp>)rXuBrYtRV^%JLqmuD( zV3$%5)W-ssJG9#D`Hyll!Hpy3g;5;6&+_1dp3pR=nAlr76xdZRluo$=;oN*Kx4DWf zbG7Z*=T}+j==r%o_}zc0>glkD%xrC>lp-p2rq`Ryy*t-loHWBOiOmuPi^aFa3UGQ@ z)_qUbcs=sQZZ}gyr`Ln-*X3qWZfBh2Oy(3{b;4K=McYm9*%;R&it={P(8tOk(*^BCViJg1&qKEM$?pz7Cb3R!} ziTCzcf7JOUZzy4Wbdd*qb4R#!;Xz^mv<7)9@SOt+Tb{ z5fcjgz@4EuT?SMLzHOLEBg=vr)EV>;x_(BA3aNt1Q*{b00zO>bHrdUFzX@J70m=ip zsd2+nK)1-n>Fe+e=v*~i^XF7(TV5<^86^0Pd8=~baKc0ce2 zf{LvK#v;uAXSt)yDd_z$N&CB=ZG^V9Kq&mKx}KceLDj$n$NCF5@)|nX9Y;dj#O5>I zW|QP1boB|Z;g!JyY#NkRGF509$|_cA{v%+6l7Ve0@FO^T7ZlnBdT>b&o2-#}2 zc&!?xF3V;4kO@AvQ-cyE`bM0vtBht3XViXHgP*@Mb?M;t5!r`Hee`#T&3h(G#QJTv z2DTQcL+Y0Ei8$p`+oLz?@s|ErH1y26q3f4Dmu@Q^R@adanhuPL;y6Ln@G5bu6}Jrb zU$6zuKUdRtp*iU=esWWs?!0Yr?sqM90-Vus&HPR)_Yre2CSTAX)f;3j*dEH8I@UQTYqKIKg>JR+RVEjHxgsCH^0~%u^l(JL;DNk3F{>C`0K$O ztB~zWcEF{G=Ct>iP|0YGiW9HK9Q{crE2Ha3p^XSNs+h{>suT0=7$c_v_m3%As2BZj z79rTVi6H$(@R&fC$;sM zsY4Z9Pf@qE=~)ytg^vZYIf9d_@umTDhdT@92i3z!a7ifSM!C@QYA0Y->qGP6{${(3 zl@rx%xGt@Z=!9UFsNURWBwi4LM>CBE9hg97jRHm?-Rm+-O; zS9y47f=BI4_}#rU>1tl%vT``C6_o?;!vAi`{GkUM{U*t!b>uH{7$oBH*$pM#HTbIn zwPGblXf^2(KVPC+VkBdUOZIWcrO`vhBP{g}rOqWj7iHlu5 zH*svD*HG`fmt*tDY@Xog9chMYg1K`mSRxlz?V5+S3~LD4zIR7tH-;B2$IM<6mN;6^R1VcR zywx{-e>Mc@zRCgm@X8!^nR`hD@;Zz>8;F5o_Qj!c$GNbycNtKoyZ7tSyI$*{*~tt% zthGUBXa)I~JL!ZniF}J%3v-C}`2=P5jl>wogf(%|n<`PL_;6Co)_kI(q~vWUpE;0UoX$#0uHM+6O($^&3xh(B9Ig1=OCX?vwwUjUBqG7?ph8 zgDLN46L)guWB?PZWtcNb)5ru9$ zN8{wI39L}LEXJ^>kI9`bTVE|QZ+?|n0xi4Cn4e#Vv-&z+Y&vFMI0tHOe%@SKB{_Wp z3^XtU9f`?v1#RS}$-wrj&ZQp-?O*(lQHAqY71LcJK5Co+wU0bxb+i63cd}eY|B#WBzfQq*r7tHQykJoKFZVm&*8nxisIC8;Uu0npIwy?*UWeQOx z^rB9R#pqMIC!|tpPo1*|lQ>iW=~N{1{+46{XJU-e`&6%Gg~M0+HYnfx?V;_1ZV1&i zmck=xc?%!S-$DyyHCo0LBjh67*OPW^HuHzV^+)aV%%M!y=C}w^LlB)#CkvffJlxPm z8|~)2#tOT4AB;NW=_nII07aM*i1GdFz_=e0m7w(ibZvMM&#r3}eE)7?_W1&p_G=@q zxdPG0sb|w2jyU@^L`wR-pi_H6d&;8g<|K+J@8y1=S{6SQ|A#q79JBnmhKkSRrRmAM zr?%gdJR2SCA*v&mds#1D;Q1sd3czULQW(zC{54vOVh?z`%Lo+b7Z>BwIvppSnbrCI z&PEEoIQ*AxfijguP5!DySBF&B60ulaAvXoTYOiFu-S5eAoQ;PL886&_VTcP3X zID}hr>a^F)XLAm%kZiQwE9VZmqxJ(?_LWWE=~S!3uWFrC^sX?R;a%Sw)qhi&)5S>` zw|oL6vRuK77%a^@shRG}dl}TIgC-4Liqxe(TS^piP}qUsW(6^*B`z9EG$sF={wmCY z7g@LuI4*xhS2%0)S8dYqvmY_hwKI1*utjT}a=pe;KJg3}Tk^LTAB1#owm7f-JS)Y6 z;V08l!LfYDGYG?{xpY`9_LW&@Elb1G%fZ0OBiEOj^KLRsRhZW2tZICG#p-GdlB zvH}^nCspKdIu0U`tL1UAR6RbZP>rp)*e3JcoMJRsw;Cw!ml!rvipey zPQd|p+D$a}ij7fAC4)!>9O%x6xkscl4`YWd=kpJa04VAnzF+dfNN2eSqA9;pVsk@6 z4yOW?v~PnvV4-(4c(q#zR>MY+CRU#`q)FDiBHbetH8V#O1*TZ+2&gbbRT9dB-h8V^ zOd?0?{dI4kamR1es}EaMwcb0c)t}?)D1o&=D?c{m7N(wzz{eV)+|eCrtzE#$0{24= z39DHeX`Zgm3YG}RxeD(7JME8N#&HK}9`z8lUhr8cu8Lzf@K`QJ%;GeI-_(4oZ|hA} z8UVbWeChx#{>h;E^HWGIoe~69VzmJp<~*fI=F&VQtBOhybX&!WMABgFHhdl=llR z>D6l}c@7u&0krV1o-Hs=4ip%P6?dD$cHU$-bSiVvzm2x5+{uOIoY=RJK><~oQq)i0 zpTAKw@uN^CW^)M`@tn4Ig3re9_{n=8=yVgBI6^`}mu3vKu@iSO|3MG>>5x^aHb0o$ z?ZNkr(*i0Fk9t|*sRVaAZVetx7u5pB8u)o)%eCMtA+!HT;IdvEPHCmuNr@bJbk%Qv zVemzXou@8Wh+Kj{t$c&6><`08b@{h$7+&50Y^TeZzX76J+8wI%X(GF4Pxd#_ zfQL|JWVRk(yTr+8bFC|`U;x*IjU||8_>19iKNJ>uTDT*`L@yn6X|a=D&+kLOFA?!p zL1#JR^W7)+`qAROS0|_gOOUuwwtB99MJj>?o`?tRA9144KiZ$b@C^Pc)vxJCT^nG^ zRXBZx!-3Ha9x5>ju1KTRfw=79+{7i7XNQ&NnUpz z;ofGb-;}c&OeY#B1kWjFt!r81`DYq?)Otd4sz$I|%T#@85?W}tJb7>8YN40aSAdGV zhWC^2ZyZ5tDuZ&#-`Q{X*luuGc>ae!N{H`w!n+TINrs#$tG3)$Ues#r;XG~Sv6s(} zrc|IFoG)FdT)xkiuazgd96u8;M`KmiAKUBuBCQp{j3a?3`>Se02%Kv-%hnh zu#)!gGATCyOh*XA5nY)e5Sya@NYztw{{>TSjytam=||k)A9mTz-_u7xTIsHE0hl(! z;40dxS0T7K_=$JOaRhlIyv}D7P4LrSUxGo^p=0zZEBIg0hp z{XosC?=>#QG*s$huL)dl2)*pVrEj?Wk{yVBR&IK+jU-rBOav8T`)6>Gh$*=qMM-lqu;(gER4-l(pJCc7` z7qD~o+);#;9C(;W4wtl9l?3&9BHuwntkT{S1JH64 zpzni5p&l2<{*4)#rL4PAPErLk{}=;#^I8yuVPAPSbXpOMTRYJhWnQpjiLKm90lw4X5qcD* zYVHCB#mZDZ?cz))2k12FU?Oj<3jL#b z->w)AZW9!YG3W2p<(Lat4Ff0Dge0p6$YG%*S>1s36kQqnP9yQgWR+r1 zu_@x!1KeL^K)q(lV3A_7h8g>{FsFOqA-l}#ILG0r!^nrl=sf;nkbMF@Lz-ZS(FO~G zP7OE212_V)bz;Vn^9eTGqvn~7TyL3i_2Up zpyfD)^@r2{N8wdTW5cz9y#LqUmp?+exBoMZGFr%zHcW&_(Sk}bv}etdEEy$)EG1-{ zG1?cAvag-8$CP~^rKDsj`>w3n_p!|Iz3!psIj3~KpFiMvemYOM-}n7~U(4%yUCZ0# z_<^e(C+2izC_DKsHv?gWv{$tqmN>UwkH+7aDmL_k!CYw%740w>Euici%uiw%=zx{n z_DwtVq8rZMpQBwCn;GJ}9#`U;=!zCucUM6C7%n0*|6bTZIZdo*rC@t#Tk7MTX$LoM z-1z;>%BSwEdy!P}vP)}z(REX9;8CtT*nJ=bPmA9l{s32SHu)Vn#9m~c!I;Z%?W2%o z-w%|9c*isYC%U6NM-=~dm?qJ9`r>E~fX7O}H)(na(u{H$R+XI`%!F?0WRxnqZArj0 zZ)fX52P;i<=63Wa5e{bek?D6Z5%g1y13kxXEYipB2-RMr60&RmwU*nyW%(9y_@mAyCQ z`2Oi&dSE0^4HU7CD7KVHQbLIy`~v;WS4(zSz-X->-ycY-Ay;|dH&y-5t3UpDsl8OT zTX}-;qcWl_#1Ue%Y0W$X0oNwYyn(%E8yJvN8pF*@@NRLnbs-o_z0X}|AFLGF$a2Af z5yT`KWT;KPvJvQCH!dlka$jfL(-{^316#q=%Ydmr38r3E#ql5XB)qdF&o)GhJA{fQ zlc$fi;V%vuBwxIDnUJQ`!0027hIyVpny>XGf=^s+l~m&2+Z<*tmu*SkF-^Cy_2FV9 zmq}u*66d}KtVnA0EwwNZARc7b_s&w?Qjv&yjka|Yc}<|t*bMwdNIQYRruX+Cx416s zSx!P4x2=;mxux_an3RK&`B6XxA$>Dnq;NPWs!>X`41IvaLa%}ao1X7jTr$FFuZ7`>F)Wxu1RY0rnbw;Z-6=kBm+b2MC^Xjv;_sT;ELohx-JRP2nm zMlak_&?2$yCAb(X;Azr|bQa1R{!3vMaI<``%?G-rG-dj|qz81OK87Z59~s2?wQ^hY zF=oe=a_yt`r+kgRyaBA4cW3J({zJj$q31xMjK{lnB`~-j{jE})+o+I?F(2S+s};Od z4dn-@`-1I6^u)*YHJslywKtNVpFJ%|u#2yfSx;rB_`w#9Iu-YDR z4oc{w$b9-NmEC+y4jgCrdvZ*SXn8L{HtI*;z0aR_bb!6vmVraRIF5C>81D5l<^9*u z$5$M|cy<s(T?&W5bh_+a=`+(p3K(5QAO^A|8vK=!cqg&S>%l6k5&rFj zv#&wYH4S=bRp{^T*_YkDHWYaWe_uy>48AdOZO=!-2;nbjodiE5=3^Wb6Um0_F8gQb zQ`H@fD#}i@ojDvC!a^9WjEG)6|4reVJufoachuwFl%HLbH@^47on)Y{A!4X@&}Apq zItzJw75D^&pEegY5h+osLJib z5kuJ}X#?ZFat3!WZnITs)#Y>F1iq3f?R?X@Y1o{y;E$sj^X_ZvEmbMw+mEKin|ovkOJPf0?jW zWi5%|DR#i|tTZyFkZ%WvV)rgl9_8W>q1+j){u&EbQ;v;w*y_V+G4qh`^h&t)NbBO! zbyd1$wYWX5eB_v^+!I|NW^_!hRGeKShY~V5c^UH1HOOc;uLS-7rivE~h79*Um+?#d zCr$^IN_x@+3nWqEkP|CZtlSFkc`eH$$|c9m!vS$N=R~jtPB}Kd1!s zK58|!#wx!n{TVJd{Cf(PWHG_6hMr^;!nL>#O$@yz$b)wSFN`nMcKo%(1}LxMK<*O3 zB3|_A@5|2B)2^~D;2I04aTx=H(y4b?aGC1G=a0`h2CsO7)O6q?MVOfh(!1*8?xC*G z`GelTjp6~6H{2l>S#@UCgHyEHD>mYM;_8p?v7|DqHjf-+^n}4#5S%ra#gNoG^PrwzOC;Y+=v_W3@%q=|Vj= z6_oGrl3XJgdtrW#?yP~Q3GVlw*8@GwhP#W#B+1_&EMI&LC2Uv7g`EumqVG$75ri>^ z-X03}8r!QD#tKcay-TZX$#Weu_^kSV!q++8=;W*}+q*u|7Ak9Rg7y`P9%@9WY-%L> zYas6BwYBpy5K!rF2V`vJUj6I%&uh1t%@*V1EQGH;-h4A~U2qU^%G!k%tWfZa> zM4rBd+ruKbZ3iKB!#p|J?K(Yq#N@dwWxDjokC=$b`N^5-&5DsbfkAS(QqO1_S+JrD zJ0*1{lJ!+xnw2j9rM0d{A|p&)Kj_yp;1E!u`!9`km5OymW(qJ9K!lQBH!!663h5IQ zg*Ch$GRgAl(nimPO0XP57J^#%Tr)wF*8)4Ap0A3@@J8V1oQbO9bFZvBjlIWdlEIZ3zC7arY@^Z`z!izNM8h0H{`y)9=jGSe}C^wah+s>H~F z)2yjVSos(b!pEl9H@)*Ry)K#6;Y%BPIW?bw-~^VIs)pX*ga&c6Zi+kX~asW>WO%ejI6oq#qt5{YjTtWY0*KkjvF4`8rJ1D5YACj!mE zopl8Vnq0VdWK1RFQ6`d=irj;~peBy0c#tKQ{8_wNh=cje zNIfETPsKp%bl9}XP|i@k+mGh!-fNYIkJ&{i86QAP6v|0=3LSs+0zd7CKPj0z>^aY_ z?)CKx+7cQ1w8xL{7w-;ryh0p!yQ7FLYBX0#MM&@Ftw`c}#nk)V2B!sm1oPdzDS!?^ z?_tW5VBuw&7nI;C8QrcAT7R#oe1pQ-9K^(1)yoZL3JDYzS=nzT&7i;AKZP>ZOLZYTKO@Lm}+t-bcp z!yd88u5e_zf`Niv0Z?h!g?~4zl$3Bva;GT)y8E)hEb{VsULRVALKN z{hNRXV9uszlq}bVdTpfWa~B0d`L##*-?Xn)+2WC_y8Of*_<@EJDbQQ+Y|QS$mr*W_ zeYZH?1gu@fUGHJ~!;1V`%)rWDLeF=8pK!9q_6aD|Y9-J0lGjK+KSx~s2)=JEcnz=E z{kP!={((R$6d{qjvSiY+BGLlkY#R)*UH*Z(5W0kZCxC*7NSxOtP{s@^K+2*?PJ3Zd?dd#HwU6ngSF10zMrq@je!-J!qW2%t8 zY5pCv3^w5J%V*=T$@=i&E0=5XE`0c7l4yRacb0JeJ4qBx@cCkHG8#<&_3y#vjp^3Y zt*qkP{rh+x?mqN+{~Tp83uizEi;N@)1SLRbUiz_S%E= z@k({|%m`7;pR#(e<)=~p0|T+&z9Jocsd+fGCijLXNS=iF*!JYRbOD*wfE{tQY}zYF z9|!{*B8r-O+Qs&6)`PX@LF9bkysS-AT@zQV7cw9*QPRjeSy^`Z`jTOzs~?4@*{^?Z zO@}<#IN-k!c`Nf@ITmESk@o?hA%xhyJ_vHy!9i+&&3(Z%{RI*Vutxjrh)cYqhV&&> zq@muYsqK<|@5UX}Ay^?gCq7Sfbu!`k;1|uDS+l92E}Ut+o#|ECa%?*qXTFT7Y&laf znn@IU0*6Bhoxp7tHV#7HJcPNPhv_dfkc%)Z!j4obOpI0SkBYYmj(3e{)RyfH7;3>| zpUq{SiIgNyW2OvP#}%>jl*ip2ot>rv!F!5jXb{Dh;^${-yFLgIx$pCLuv(7$u%Kse zA9QK>6(w;5rr^YP2Btfe6|aH1G1B9e+CGAnPMyol{6=ad|S; z0(+z4oZUZN8#Risk+s8&bf?kV+9K(Bxn?>K`UlA9lBol6W`=knT|zr3Ea zh5qf1Krp+2{KFV67bRmX%F}(>hHa(4LVZ>VgEsrhNi*^7Ive~Cohn1#g|Kq#iN{Ph zPwskk4?#cQizhbc0;Lsxe8d{f+N6tnHI#of|F@}&QddZ{ z70&XXg{ zlZWn>%OW|le;RGJXrXyC5=xTujD$e)mL`TO9XWG=2 z*_p>;bWKe0g3I+6^I;=k(mI_&UryhMj_(O*bsEi^DD>a2l*)v`_UtAdN{6(zyb*zuBb3EBmcBu})kjI3-(u49M8yT!NL;nQlL ze5P&3>~ymTSx+a+?e2L>?qH38Wt6(!S5d8jowFOdX;hx#@}9CXHG{^{?yyOxm2O?b7+1EY#r5DX~l25#xWI&Q#JQvf516jGNA2N9BfIbUlC0YsN)wQ!t7*47HMetNKU0PG2Ks2FV}_fry-fIE7gC_X zqS?7$0pH!-eR$yQ*TyhQcS)n%OZjs%R+Ym$-S_S_{sgb2#qaL^8(0|EzzV21+#pQ* zY!{G^^2NX1Bz|(-u3|3|+$nPw_Z=0#7aA7k{&Ft+_3JNZJkDu831t*Buzo&*rK~WG zvvzIgn%6!nc|QN;Iv6HiT>d%5ygXRtP00M=S54~J>NS+`}_M-6&1*9l{c*u{YfH79Klwq z4Gj!P$9=z?6@iQXMxUD{UMm=HRObx%8kNbSP>NIPU0T|$xYx%#=jgGWMVeGEmAY_Hv;Zd7|vSmqY82hH8g(YKx zY7PlZb)_j4+Xj~}%Uk@qqU}DG?v0I&)@fZMlUMT(DW~OA=mWL`Dj4Vm2^;#jIgE)^ z4jb$4U%ZTQHvcfSx5a(hj@6*|YsQK3%yD*{D7G~PM z1)CcL%(bl@0gdYr;}iG@C)*KVM5LCBljFVzBrZ@kAP12VsA(au#Kgp|(b2C%Bkb${ z((ZE|`F?Z^^5wE*JcUs3*ljyADuojy$L~e^?~=1hAFH*?k#Ur*W8LMAl$mmZI1PG5 zk-i-ihG1TLEl=m0PObdW}CnkBDTqbxz3`gW(Q@D4lsL0?-@ zoUuR1PD<4^iQhN$B-;y5E!m!cUIND9Vtf($V6y5h1%^OA)WQ|phPKD+E*t`m!U6|Z z-Kl9>c9lrd?wbVz6LLKt5ZBy_Q5b;q*%0^2w(G^3->;H`skv;|xAq78aJ8573k_Ew zwx~6SxGPfP6qLtd_|a>&Dl44MsB)&9A8mA_PesOmi0 z6KlHZy~}pF%aJy$WSuNsU-j+x4P-UsIl)4CX>M+AZA#IeQmzoP^5kE@3C3hG5p^M=a}GgHX=&ANQ0x&u(H!x`i8C++l)dQ^ z-!Eksh*A_xpyE25u3Y&N8XlewrgKP{hcYoSA=4A!zOa+Zu#<-Eak7glFp8d}QX3UQ zGjnqdjf9R}?OOj|6`;I3ksY-OeM|^cAoy9;+TTy?8Qa#L03SREetDH_b7VxE-R%R( z4UnWH^|5e{!u45~5~fY@!j!(SrUi__%8@DVLsg5b3AkSzKXI-)t8pN{hU!hEJ$HsS z%;x<1=NOK&cj4=l0>gfHf*u6}=-sNeZ{77;^IU7yngfmTN&(5G4k%q-;P7~M3tzL$AHx1|(FH2F|V zcg&0F8yR=x%ulsHdGdrI{0f0Wz>e`Uzsb*fbzs}VZ~q;LlcrfaZamZ;Q#Or3a=*W-|}ED&V5Nm~~;!03m8|I2~q>@5+<;X8%PaFzOx!29EK#SCGT_wTiS#S`dy{@>vx+PXvC$Rt@S$o`m`ghJ4z=H{6zU)L)De0R{Q>>gww11mp;`M&yG#Rd}3v17{0Qcaht>@z**Y zcm!x7hU&0=Mz|+H9L~ga#z>KJXOkQXKFwbk+mRvRyqMiZuM>Nfl~qpzm};Gte>B|b zWw&Oc?Ms;8Wx~zTzo|X8_tz91vI$m*gehSWZ&xRYIIy|HM=4E=K9_=FG`zd4+0P8W zn-O+P>Y~fy&W-4v=@$Z_l6bs=qsI>{D*5(dlO+s-gc=s~a$LDWvXXkHLXwA`Y}N~( z@ZReVLK_;NK`9YZe6MX@P&VTr)O6Sc3}7oQDmo^&dT4j!Zh!lP8d?9xRo-!|tdpvy zFD8Bhguh8sfjOEmH{GqE4WWrjb%=wtb>iw-Q*k`Q1gtt9sYD3!KQxQ6F+U*pZQ$F( zXZ{RY23o^%-KLZ2hf}rtQVtqoAGH$a-8cEFoc#)H_B@=(jKVSf-)$<+SPX@kjQR^- zgH{sn36MJBxkZnK?!SAl8nnNXTrnL72#$_5FEk(cwC1t8FYfs(EQ!Vs_a$4hwQO)1 z8XA%n6%{SL!!BTUUHgt8&Nv*L#8{QX<=;#WGfIf_1nX8Sr7iU$SYNx=PoGYu(_jvEzl=cWh%u$b)%u?>Fy{JEoL zdws;4wQ#d0c)-?!+I&lGB^u2+s4Ps;)+`QY$3v{AuR|9phm&vbDAJ{L}}9V5kx*n{0b@%%i{%(VkCzZA)lR zw2+1(rLwXz{jZ3~)@wyZ>d-ppT~O_VkEcf6$BUag~;wA+< zsK#f0M%o8ZNR&1j-cF4;j}w+zlV+flF%T8CSN~@{-n??AjRKmj2Vl1C;b_4xl#ijU2+NM*Gr9;!B_jI_N@+i2A z<}52)F%tJFSZo~Pm0+KA_O9c5E3y|Dimt6bRCe|7gBC5h&XxIh0xK;!j3#V*_I7}Y)ep*?D@xjemq*#M-~OpAx`?jYPfnj$`c>| zj&<70?5@LtAN{P2eU@KcU2SG!^1QyWG33YV7`Im?B_&<6Llj$869m->plkG*N7VghZGm%QO1dt!jTLU5`6KKT%!qMt~#Te+B__GGd3mg zM!^GK$%gxsp;k&n;g=ZaVwE>J0Agt6^ECA_DrMe1nAJtqcq^S$4^2!8Op z^RU$An6`-z++({OwNVcsa4>k9I`+43`tMS*uvFHU15)tnW;=ZV&$xp%8jum#C)yNX z@%<*vtZcx8p-7PdC~yp_@e@&+tr@L^#uAw|uTRI-Kpa+SW^bPY5iZ{a-c-2B{1Mpy z6@@#05fH|T?HnBAn?CI8h1-_ed5b3w2=t5g1l%X+S!TD~q~(LR8WHMQxX~{#5T`U( z9)8FwJtHFolsX5n?a^;B!Z3^0TuWUM40=uUN4n&$^pqlcTe9 zy&Dn}0g>29)i~ULLxu}Gd>l}Wf=lMnpVIN4orHDJXf$0!syO?EM?o84KxJvlO&Ve5 zN6h51UH~`6ROIFIIImBSn$GGI2!tfg zp@+w#quW%|@^jUb!62=HkGS&ixzUmmaTp|G!-WIfh(t($M8r=6+!%mPq59jiyQ5m2 z=0me(GZu|Kj)LYqC?_v(b92T_VW+e0I7mZRPfzSefkS7(NqB<_UoX;BUqXdB0-qGb zcoHy=1J_+u8(sqtnPkBF;yzxrK7>8p{#;8_(`9n0cuf}^gf_c5qpcL$GSxS-7uJp5Rp!EI z@%qKV6`)vb*k(El{coN`)7R}=uLeR&BC=^mRmXP)RN#|7=xKc^f0`FA!uUJmbd-{N z%0#Y9YHq;EOIJ-y4qqA-f7FORwiQC2zur_W6x07ryb*IaBL)r{ijC8Bo@?$G*P;T3 z?mdn1ySMXisdRnX_58U<3?SXk$99059*C0CIekqTP111(TgAhYJFR~RWDvcp=f-LldFzys9 zMI`mXnPf`pTv4f)BNELS>I&h(L@AMWfd<_YU67LryX`b*ehst`%uL;)nOSrff7`Kw z)d1IZj#6&Uamt*`BuC%VKH9r{pA)>1@oiKsNI{<+sy1uQ0+Go?n&(A6WX~1~mq=Ac zdV0|LpUv{(4*a++ z9F;W)r_^Vct_N7ISY4XpU#NfxfYfQ`XZi0}xrwuOdsBe;=CxOX^D_Q{SRVn@>LuI~ ztkui{DA(?!eACA}7MMxli@wrYQzHEf=L|vIjH{a)ZDeDpmCY^MRldd1AY!Z?RA0pV zy1M2d-d8Cg;Ohr~8Vg)V`b+_K>SwvrqnZ~L+si%jGeiQzB#jQPvDg@?pz3cE#~hU z?=p7)F#;=E_tT30ZUR4_ZKD8oZL~Y-DH7KczKR}n<5<{l zSFXiMVMu-P)1AQvm6P#ZviD+0Y7mqebD*Z1v5G0QaG%~Q&Uwk7)v?T<+S}W^02C)q z%2D?02fXFJ4)%1c=hCL7;0D@%n@_>X8n^2K7F&rB6HXqEf^YgnkgqWK&a__|;w8?^ zq+oo~>$r}9NPJQr!@^)+t%C4u`1|_@lk7xvX_o>@y84Rv#I(EBTuT`aGL4?@?)-e# zOWtCP^G1)7j64ZQ1Z_&`H;-?zfwGtv$CpJzk0!9RwN2=R^0Kl9>jO`$URn}v@Sj1N ztP0xDqu~nA^0gnUM&;+uXTXQHAkYWs=W0kYd>%UTNX4T73zmQRE|rZ-S$-zc97fwA z4y|s<*6LOf5YLH;c=1Vl(tWCy^14zGg}yE7V`c4G9TyqQPUm`6oF=0cW!|SRm%FPP z86`1(4k1ui2UuUeycfWayX|0GV}QndZ?7fS5cu0S)Z;6l*fJA5YvF1>((h&t`Ik9i zpSF`qqV*!zeTVTV(V%qMMgYynUNdBgj!4-#dwaRsx|bLobB0tiquAFX0L9+TtqCHG z_{~&~VgrKhtr^Zb-oJ8%gYT>j^nex7%k_AdGzqUHkf2JD;%4k;hu4`&;6bl?SooPP%p$WV%2_W)z zjKLDo6!NDzIC-o}&sMAGp~N3sa}*W)qPyf*slmY&vt0F(wjL^8p@#qtsTGir-C7mE z)`$rV>T+LGth**i10UU5dX+#ZquuuoK}YWd-#TILF}I{sGQNkJ#%>qDnyFSuHoAG7 z1;->7%;Q&Fd2JbTgpC-Dm=xGEb3ls3$@oFII4|4;oF-~pJ@r}b*E=U6 zjk7)$r`i}|WnE)vVsD*j;cD;2s1qo-hUT0~igWUQ^r)fs=8thg)*&xfqX)NU{N>h^ zsr|c_Fp*@M0-BOX*af)ym8Z6ze;VI=2O%-hgFAh2isI9zA<{gW_SUcyI&?IB z(56=o*1cV9vtX52O<_cO_MA z7!z3nG`T9adiJWj>iepj^yCPv1Ncp@7iHE9B#{BOc9spsL=OhLIK3&%Lad&EKtff9 zu~UqY)DghWTOI{NEU@HK$4P8|X}^y{pT3HZR|(3e3O(UNu)1EPXBF7>6JdQ;Nr`&3 zH8l;1k*#5R?#PfcNI6=$D7k0($DE4jo4Ro4aIEd?ma=2UJ;*l+C=M+7O-v*O%vLww z>hV0{UssT67=t@}BJuH2W~zY)GIF-`YESI(YR_|a7lI#kiASDlHFUOhuzQwou*;bP z3fti$*4#d~w7jp6!RdsZTK|4LuYI#g9z-M~sM=exEcA5>Ys!EEgXGUW8lFD;(a!R34fwFPm;~Lfp)r*l1PYO1JJ?!%6 z^;y!dVWkd|*j{MsP@2k~`eLSaDkK-OdrfNC+Ak^qyewavvqfqb?A^W9nS%`85dP?& z9||=6sG^~g7$ApFz%jXF{(1o(Hg1p#w|6x1RXj(;_zKDJcuII!SX!gDZ?9T&U+{qu z(YtV$krWpx*GV-{LK)@mTyCkCizC>cJ$KHUNaW}>$ffMzT>k*}_UtiDg?}#j(;^!W zqT=@X`G7x<+4|Ji81FP=BoJQazCIMr>@jN-_jrjku%W8gUADHr+=OP8IEEckr$PpV z8Vm78X-iAX1+{(&B4_asE5bev5y!f`6wotId_eUw6JcfRsDppIo$eoBZn(Dijw2?z z<3<%5t#b>2UL8t*h~+3-Xb5ai<}qw-m7#iy8Cz>p((tut-_H)x&lZwfw4FYm?BwL+ zNIz*)EjT;%|XvRsB@tBDX4~}|!jICWC0IO#fY1#hayFa2ZFSLuv@iW!q zaM*{4bB0o;A5A*O!RJCw{Vtn2unctc)~h>8^_hFmk009(9!1K4gq}enN@zo#%YY z&Yz1KPlMqkDJ1v4}Cuocr-qy$7{gRvd!(ty`qMg0%lByOK@6JOg)h{HS!^z;GoK< z5wO<}_>GmU;}f%(VL*tE4b8weo4LE^wR%+_fFz74IKj*@AgH5os9jl)%o0zZ<&Qk5jqVNB*L>hmMVn z$sCc7*s~u>Ibo_mf5>Q0pWHtr^*;x=>KK-Xo~;whsrgYb^y}^^q(?VnUC(VAI>xrN ziv;>{B63rY^6+(g`^u*|E0ZY$7NhxYP?nVVir!Va=~;f`Tj$NpC?{AYXHSsr(p$%j zqH|=b?h_VZHP>IrKp0Beg|uDMQOTQQ9Ype4g)F1_gTQ3(-@o5t-p<6yDWh4QR{Tgx znFKtznUz(-Y6Jewn?H|MJVK&*1&EsI_ula>EglGssaq%(cf>DV5<@jj?ERT|Dn&K7 zT{~yM<(p*n11S)2fAb?`H8fw58sYp>z`tD#p<1HcGwcnDp6^yeq$NR@92^!FX1e#y zemH?Z(7$)f4S^wF>NAb?k*rkAa4A7HG&wo>E8(t0=VeJD|Q_*wfvpgXcEo zeGR3rj*~!#jC|i)=u1TN}lG##hz`ioj+p*)Tapm(M^??dKXEk-}Eu?G48Ec(A81M z#tUpeEqv2g<5UKlU%c=hloL#pJht7Z&mu9dzjpO(=f;M-Xtr6eNsCAmF0K=SLjdvj zA39`B>>9IAI?!qtj^04g{!x-PTN)xe;NY?^u~rj?y&>FB^p`5$KYYBDD9Nor?>vPq z_Jz2Pl9+BG^vc<9MBfp{8Sh0o@Rd$xTe#Vu15kDOoYwI@{RehmCApBF#yO6qgbDk# zK#^i2Rat0g?oxKZ@I+0`89B4)7QWI~y{x1+5I3%N?AePn-7O{C61r`@-1*ZSasrm3 zcQvh8wEP=2%>frdYVPXl0kw96+NyZ}U@(k`uiMd|Jw~_mFU&+w`;sUc_re>0zF;MvWVL z>;>*h5d*1zX|3nF!;*~>7!A=5-CEsh`f};ijdI4Mo721B4+6HGC5WC|+qG%fV=m=K zR+(9E^F!}J0^t#Q_8^3EOX)B?{1%(`wkUB89iI4LqupC5!EbBtB&_7yC@O?AEDDD#Au$y96gxyZE*S{@)}u~oVH#eWWnh|#`MGW+CmivH~#KD(M58Z77Aw(88l zl|px#wRZiE48Y&kVgfv+zd?}q@AaO~G z01@y5D4rv6?CmL~zU<$vR5^~;kxfUCo6iO%G-~VFXw^?&)Qb!U*x_po?d|gtIU?`t zIz>;eUdbKXeI+`+%=ON}@|3EveLU02L(aJcih9FwP{)Gcn8p0oo|=`DPT*(i^y>P2e#8FHG*OtLPIWod&n*Wx3Dcx9*Rh3Yd8kS2rZGfr?PG1XSG9Ggc@f59+0LnISXfGI{wt zXVE9Rzr{*zo_w~!YWq0xkxpk{Cj71GgSOFhxBUkXUcTYxET8K#5$|rKVsK;#SpIl$ znHtB{a+Y?Ppl&Nxvd$g~tY8LN9LAE^rlP*<>);bObd?PBIQtVK&j1z2^f`StZSu|B zhE!b9!SZ`(YW$3eO|AVFlkit(iWCg|rj{RS+GFe1QX6#&AHHWHNGkhW{tZdkoqYi> zAea`mG!qBE(34jX^OnG~?JPuJh3LGYhszPb*oMMfGgYmV{6@hO>1oZ;20UypcXn+I zOB0`WpQzR)vND}veZ_B^bDgxY~v2Pejkq2BSVq;Jy zapN_KQ@XSDHJWc;UrrI(=g(n0IX@aeNj;x@Fx~TFR_mw*X_RbTv}Ma@o9mMJ63xMh z;0@;A^8AYwoVbh29ip2LK|xmQ4L&|TciMDb`?G_Hr^$m9L0{*qOGxOqq)Di7B5Cu+ zOY6MgoGbB-R8nFK;@7An3p13}WsAnM6y$x+z-#Gy_sL|xy_A)2o;B#GMAGZs)l7GB zoAuzI(|VS(H*wOc(cx1qc~1#l?<;jYEl2gzP_O&^{H1x$ObSwH#2`|${BZadC!}ig z{|9-X0Glf|4xR88ZzIZd`aI=wgaR=sx%KO@V&nn?J6DoTg=DKvhL+b(WtLV;*Gl(+ z8)Vv(HUp<=?cpIUd>_BiY;{orwc9ZxthRZOpq@r9JD0&_^iu56*i;i9pI}YhH;MVI zj~#l=D3D94Yi_o7baXUxXZrv)4QC4n>9U7=<6_q8rw;#j2Opkpi++WF%ZZuMF{Pjd zuQoD%vz@bNd2jaYk4^{0T(&i3N?WQ&lXmjdl+a}d@O1tRjD!K;?Z%cCn`Q3Kb4WLV zlo=quUEWFge~3$v13d9ch(uBO7GiyCUc5g*%#CY`YqGC%*kbWWq11+L+%yE&+R|dQ z>BPB;A7O|IP=;{MK%BBL$9T!JpTlEyLg0byk)Vba^-Pas2G`^szoE0o z&Mq(n1*zyHc-k|`H}VLcjD~g&+0HMuPJfVg1jI#ze3GrEjWRpyP~l0JZW|qEEK*?1 zl1<82$;x^CdP{|D-IppmNDl9S$61|5M1tW>ewTys6Ig-3dD>XHYW$4pDSS2EW$(V= z1*s7c*C6HRO6mdA0`Et>Y0O9!wnAwTA>$Qe6ycKF7mc!wn#bD{()I)wfZ@nQD2co}w((7be*7+3t{$GCV8wd3Oxnc;xO==#~_GJeL3tWUwUZ0d(1vw8xw zv6lkRk;7*n!I-Qt#sLBHop_U_i7ezyMYh>B{&0&p?*X+O zj%pE;-!KlvBSAb41Z~1KNSZO;5t3nw? zxzVCNQmsfX^Xk>Fjs!@Ht{xY@WXsTiX?R{~ZS9wTd0y8x?6B-{!#hZ+66qux4fM;} zX9$wg1H||-;R^Hk=9BV#*C1ga4A0uJwl(hGo+V@_Jxqnph`ku`i^0%D5j6x&{|%9E zk#digpFIjHs#tPJ+^2wEx45qX91(GjF_RJ%&}cj(0(sPowO{@eDnR5k z$>Ky=Om+mKMP0%^Obii$yneo#JEFQXGcGCV>CwAeb1V3eIjMUPers23;UB#ttZ<@0 z(kkNr5Xm z%8cN3L6Y&D#a4Tkz zEcf2FS#nCYb=TEvKo$u@vc%IZNG&hArqm%-d=xY4WtBUD04#O@Sgx^=LrZ6_7IsNW ziNr?N8J1Lh%0@R05hgti?#f7SzE2do_(d4@v*}c1Qh?4qNm71Oz^iLI?IkjcHD_%H z;8gpxoBj+E5UCVJ3RNmj#nYpD@ho~aTr}mtqwgu|oU?+=sAX%5r6srYAZ1L|Q=H#R z2G|rtheJ8=XKM3EtK!YT9Y(GIS8-@PTJ_JH1mYz^V#~Vd+SrCyodEoK9&KDS{<4A> z)y@&yXK-tZ^J-aepAM=-I?P7NEo-rEnTjM5$e}}j#!PT7Z7nFB5lNjy%>l{ALH!j; zVgxRqkHKyDbe_M~&TSWiEVbDVA1loyovdS~jfw99`ZSW%^|-nc`o6wwY`e~o{By8J zKOW_UFP)@ZkgA?U+%1|W-}Yz0>Z()&Qt;&zw)qJdeDx3~$r8_of9tBJWwE!hDPq{} zt!t24hNs(Ni*G?LptP4Tk>fLJ~({p&b2b za{igsamMP_Ts>=s&Z^yrX3D9am*-`omEh;TxjWhaHZeBd_)OPY#ZKMYjr=c93N%Q|CO!Ks2@Lr zwTVyb z9y|CZufKaboC!~z)R=j>kOFIyhxMqZ#}56=N5PMPtk%IM6lmGtSEIVLo5{6t+iBWB zY;Io_NH(S9J5IcISY-glBDUMiI^mNMi(cQ{!Hkq^5f3Ip6MtN_m&2302M#xO%`yNC zv@*ktg#%ZS7OOw+X2C_4Y{fXXP;>C=nSH$`_Bs6a4hk7NB6u?o$VfY;m99;CWb0mD zZB4x_{ixpTVRGqu0?5_C(@f{fgXQ|O1CJJy=fL*@8oc>M@n4pQA4w5NeV)b+co#f# zGQ!$?-1|~5n>i(9vT=pcbd0B|1GTy_i=t#Y5g0OP(5~S_DZ8k$CXa| z3D+dKmg?E;jGQiAZ@pJVpetK4}M+E={PiW`&%~EiE29*IM{BRGoR&Q$TE<`Kh#UtExg-IcA_dc zF}?bpGH)Pj=a@$-BAtFix^Fq7hdrc||lH^G>K|Bq+=?YI6ejsN?I zKl-1)yQcr0#Q#mm|0hoW6Q@5K&;MDc|BFTbpP%?YsSrf%|8sVKcTs + + +As shown above, Dynamic scheduler relies on `Prometheus` and `Node-exporter` to collect and aggregate metrics data, and it consists of two components: +- `Node-annotator` periodically pulls data from Prometheus and marks them with timestamp on the node in the form of annotations. +>**Note:** `Node-annotator` is currently a module of `Crane-scheduler-controller`. +- `Dynamic plugin` reads the load data directly from the node's annotation, filters and scores candidates based on a simple algorithm. + +### Scheduler Policy +Dynamic provides a default [scheduler policy](../deploy/manifests/policy.yaml) and supports user-defined policies. The default policy reies on following metrics: +- `cpu_usage_avg_5m` +- `cpu_usage_max_avg_1h` +- `cpu_usage_max_avg_1d` +- `mem_usage_avg_5m` +- `mem_usage_max_avg_1h` +- `mem_usage_max_avg_1d` + +At the scheduling `Filter` stage, the node will be filtered if the actual usage rate of this node is greater than the threshold of any of the above metrics. And at the `Score` stage, the final score is the weighted sum of these metrics' values. + +### Hot Value +In the production cluster, scheduling hotspots may occur frequently because the load of the nodes can not increase immediately after the pod is created. Therefore, we define an extra metrics named `Hot Value`, which represents the scheduling frequency of the node in recent times. And the final priority of the node is the final score minus the `Hot Value`. + diff --git a/docs/tutorials/scheduling-pods-based-on-actual-node-load.md b/docs/tutorials/scheduling-pods-based-on-actual-node-load.md new file mode 100644 index 000000000..fd5d52702 --- /dev/null +++ b/docs/tutorials/scheduling-pods-based-on-actual-node-load.md @@ -0,0 +1,213 @@ +# Crane-scheduler + +## Overview +Crane-scheduler is a collection of scheduler plugins based on [scheduler framework](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/), including: + +- [Dynamic scheuler: a load-aware scheduler plugin](./dynamic-scheduler-plugin.md) + +## Get Started + +### 1. Install Prometheus +Make sure your kubernetes cluster has Prometheus installed. If not, please refer to [Install Prometheus](https://github.com/gocrane/fadvisor/blob/main/README.md#prerequests). + +### 2. Configure Prometheus Rules +1) Configure the rules of Prometheus to get expected aggregated data: +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: example-record +spec: + groups: + - name: cpu_mem_usage_active + interval: 30s + rules: + - record: cpu_usage_active + expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[30s])) * 100) + - record: mem_usage_active + expr: 100*(1-node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes) + - name: cpu-usage-5m + interval: 5m + rules: + - record: cpu_usage_max_avg_1h + expr: max_over_time(cpu_usage_avg_5m[1h]) + - record: cpu_usage_max_avg_1d + expr: max_over_time(cpu_usage_avg_5m[1d]) + - name: cpu-usage-1m + interval: 1m + rules: + - record: cpu_usage_avg_5m + expr: avg_over_time(cpu_usage_active[5m]) + - name: mem-usage-5m + interval: 5m + rules: + - record: mem_usage_max_avg_1h + expr: max_over_time(mem_usage_avg_5m[1h]) + - record: mem_usage_max_avg_1d + expr: max_over_time(mem_usage_avg_5m[1d]) + - name: mem-usage-1m + interval: 1m + rules: + - record: mem_usage_avg_5m + expr: avg_over_time(mem_usage_active[5m]) +``` +>**⚠️Troubleshooting:** The sampling interval of Prometheus must be less than 30 seconds, otherwise the above rules(such as cpu_usage_active) may not take effect. +2) Update the configuration of Prometheus service discovery to ensure that node_exporters/telegraf are using node name as instance name: +```yaml + - job_name: kubernetes-node-exporter + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + scheme: https + kubernetes_sd_configs: + ... + # Host name + - source_labels: [__meta_kubernetes_node_name] + target_label: instance + ... +``` +>**Note:** This step can be skipped if the node name itself is the host IP. + +### 3. Install Crane-scheduler +There are two options: +1) Install Crane-scheduler as a second scheduler: + ```bash + helm repo add crane https://gocrane.github.io/helm-charts + helm install scheduler -n crane-system --create-namespace --set global.prometheusAddr="REPLACE_ME_WITH_PROMETHEUS_ADDR" crane/scheduler + ``` +2) Replace native Kube-scheduler with Crane-scheduler: + 1) Backup `/etc/kubernetes/manifests/kube-scheduler.yaml` + ```bash + cp /etc/kubernetes/manifests/kube-scheduler.yaml /etc/kubernetes/ + ``` + 2) Modify configfile of kube-scheduler(`scheduler-config.yaml`) to enable Dynamic scheduler plugin and configure plugin args: + ```yaml + apiVersion: kubescheduler.config.k8s.io/v1beta2 + kind: KubeSchedulerConfiguration + ... + profiles: + - schedulerName: default-scheduler + plugins: + filter: + enabled: + - name: Dynamic + score: + enabled: + - name: Dynamic + weight: 3 + pluginConfig: + - name: Dynamic + args: + policyConfigPath: /etc/kubernetes/policy.yaml + ... + ``` + 3) Create `/etc/kubernetes/policy.yaml`, using as scheduler policy of Dynamic plugin: + ```yaml + apiVersion: scheduler.policy.crane.io/v1alpha1 + kind: DynamicSchedulerPolicy + spec: + syncPolicy: + ##cpu usage + - name: cpu_usage_avg_5m + period: 3m + - name: cpu_usage_max_avg_1h + period: 15m + - name: cpu_usage_max_avg_1d + period: 3h + ##memory usage + - name: mem_usage_avg_5m + period: 3m + - name: mem_usage_max_avg_1h + period: 15m + - name: mem_usage_max_avg_1d + period: 3h + + predicate: + ##cpu usage + - name: cpu_usage_avg_5m + maxLimitPecent: 0.65 + - name: cpu_usage_max_avg_1h + maxLimitPecent: 0.75 + ##memory usage + - name: mem_usage_avg_5m + maxLimitPecent: 0.65 + - name: mem_usage_max_avg_1h + maxLimitPecent: 0.75 + + priority: + ##cpu usage + - name: cpu_usage_avg_5m + weight: 0.2 + - name: cpu_usage_max_avg_1h + weight: 0.3 + - name: cpu_usage_max_avg_1d + weight: 0.5 + ##memory usage + - name: mem_usage_avg_5m + weight: 0.2 + - name: mem_usage_max_avg_1h + weight: 0.3 + - name: mem_usage_max_avg_1d + weight: 0.5 + + hotValue: + - timeRange: 5m + count: 5 + - timeRange: 1m + count: 2 + ``` + 4) Modify `kube-scheduler.yaml` and replace kube-scheduler image with Crane-scheduler: + ```yaml + ... + image: docker.io/gocrane/crane-scheduler:0.0.23 + ... + ``` + 1) Install [crane-scheduler-controller](deploy/controller/deployment.yaml): + ```bash + kubectl apply ./deploy/controller/rbac.yaml && kubectl apply -f ./deploy/controller/deployment.yaml + ``` + +### 4. Schedule Pods With Crane-scheduler +Test Crane-scheduler with following example: +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cpu-stress +spec: + selector: + matchLabels: + app: cpu-stress + replicas: 1 + template: + metadata: + labels: + app: cpu-stress + spec: + schedulerName: crane-scheduler + hostNetwork: true + tolerations: + - key: node.kubernetes.io/network-unavailable + operator: Exists + effect: NoSchedule + containers: + - name: stress + image: docker.io/gocrane/stress:latest + command: ["stress", "-c", "1"] + resources: + requests: + memory: "1Gi" + cpu: "1" + limits: + memory: "1Gi" + cpu: "1" +``` +>**Note:** Change `crane-scheduler` to `default-scheduler` if `crane-scheduler` is used as default. + +There will be the following event if the test pod is successfully scheduled: +```bash +Type Reason Age From Message +---- ------ ---- ---- ------- +Normal Scheduled 28s crane-scheduler Successfully assigned default/cpu-stress-7669499b57-zmrgb to vm-162-247-ubuntu +``` diff --git a/mkdocs.yml b/mkdocs.yml index 98206640d..d704ea1ce 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -69,6 +69,7 @@ nav: - Analytics and Recommendation: tutorials/analytics-and-recommendation.md - Qos Ensurance: tutorials/using-qos-ensurance.md - Time Series Prediction: tutorials/using-time-series-prediction.md + - Load-aware Scheduling: tutorials/scheduling-pods-based-on-actual-node-load.md - Proposals: - Advanced CpuSet Manager: proposals/20220228-advanced-cpuset-manger.md - Contributing: CONTRIBUTING.md From 87ffcf0ca4e0aeffb083845879183c24a88c7869 Mon Sep 17 00:00:00 2001 From: shijieqin Date: Fri, 29 Apr 2022 16:55:58 +0800 Subject: [PATCH 40/41] bugfix for crane-agent create nodeResourceTsp --- go.sum | 2 -- pkg/agent/agent.go | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.sum b/go.sum index d5c3efd6f..b951e4689 100644 --- a/go.sum +++ b/go.sum @@ -306,8 +306,6 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.1.0-rc.5 h1:QOAag7FoBaBYYHRqzqkhhd8fq5RTubvI4v3Ft/gDVVQ= github.com/gobwas/ws v1.1.0-rc.5/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= -github.com/gocrane/api v0.2.1-0.20220311091718-54464ca2d930 h1:rJMo2ink4ECIUAVqVLcniB4BtWXTqkhnbRPgKvcDZdU= -github.com/gocrane/api v0.2.1-0.20220311091718-54464ca2d930/go.mod h1:GxI+t9AW8+NsHkz2JkPBIJN//9eLUjTZl1ScYAbXMbk= github.com/gocrane/api v0.3.0 h1:ziH+zYQy/shiqQ6yskMs67e+bQ9WmPp8eCVhLW85NFQ= github.com/gocrane/api v0.3.0/go.mod h1:GxI+t9AW8+NsHkz2JkPBIJN//9eLUjTZl1ScYAbXMbk= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index b8eda041d..e8b3778d7 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -144,12 +144,14 @@ func getAgentName(nodeName string) string { } func (a *Agent) CreateNodeResourceTsp() (string, error) { + foundTsp := true tsp, err := a.craneClient.PredictionV1alpha1().TimeSeriesPredictions(resource.TspNamespace).Get(context.TODO(), a.GenerateNodeResourceTspName(), metav1.GetOptions{}) if err != nil { if !errors.IsNotFound(err) { klog.Errorf("Failed to get noderesource tsp : %v", err) return "", err } + foundTsp = false } config, err := a.kubeClient.CoreV1().ConfigMaps(resource.TspNamespace).Get(context.TODO(), "noderesource-tsp-template", metav1.GetOptions{}) @@ -198,7 +200,7 @@ func (a *Agent) CreateNodeResourceTsp() (string, error) { Name: a.nodeName, } - if tsp != nil { + if foundTsp { klog.V(4).Infof("Discover the presence of old noderesource tsp and try to contrast the changes: %s", a.GenerateNodeResourceTspName()) if reflect.DeepEqual(tsp.Spec, spec) { return a.GenerateNodeResourceTspName(), nil From 308407003002533b4add6c1c771ee1b648030f60 Mon Sep 17 00:00:00 2001 From: qmhu Date: Fri, 29 Apr 2022 15:50:16 +0800 Subject: [PATCH 41/41] release 0.4 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index c3710bcf0..337ef666e 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/go-echarts/go-echarts/v2 v2.2.4 - github.com/gocrane/api v0.3.0 + github.com/gocrane/api v0.4.0 github.com/google/cadvisor v0.39.2 github.com/mjibson/go-dsp v0.0.0-20180508042940-11479a337f12 github.com/prometheus/client_golang v1.11.0 diff --git a/go.sum b/go.sum index b951e4689..732f29695 100644 --- a/go.sum +++ b/go.sum @@ -308,6 +308,8 @@ github.com/gobwas/ws v1.1.0-rc.5 h1:QOAag7FoBaBYYHRqzqkhhd8fq5RTubvI4v3Ft/gDVVQ= github.com/gobwas/ws v1.1.0-rc.5/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= github.com/gocrane/api v0.3.0 h1:ziH+zYQy/shiqQ6yskMs67e+bQ9WmPp8eCVhLW85NFQ= github.com/gocrane/api v0.3.0/go.mod h1:GxI+t9AW8+NsHkz2JkPBIJN//9eLUjTZl1ScYAbXMbk= +github.com/gocrane/api v0.4.0 h1:1IWP3gbkp3T4kX68w4+PfqUr4Cb/gaJrihLYg6aKOLY= +github.com/gocrane/api v0.4.0/go.mod h1:GxI+t9AW8+NsHkz2JkPBIJN//9eLUjTZl1ScYAbXMbk= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=

  • 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 r4eE}3olK6YN5g_sT=1pHA~)xL#Ru?qe_W!lqV literal 0 HcmV?d00001 diff --git a/docs/images/dashboard_nodeport.png b/docs/images/dashboard_nodeport.png new file mode 100644 index 0000000000000000000000000000000000000000..11d617c29c89dea49e21110a91ef6ddd96a27ef5 GIT binary patch literal 156973 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