From 9dfc27915c6b173b9bb382688d17bf39cdb8584d Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Wed, 14 Nov 2018 21:23:38 -0600 Subject: [PATCH 01/71] Initial implementation of device preemption --- nomad/structs/devices.go | 11 ++ scheduler/preemption.go | 51 ++++++++- scheduler/preemption_test.go | 195 +++++++++++++++++++++++++++++++++++ scheduler/rank.go | 34 +++++- 4 files changed, 287 insertions(+), 4 deletions(-) diff --git a/nomad/structs/devices.go b/nomad/structs/devices.go index 9ad363454..52cc21cae 100644 --- a/nomad/structs/devices.go +++ b/nomad/structs/devices.go @@ -129,3 +129,14 @@ func (d *DeviceAccounter) AddReserved(res *AllocatedDeviceResource) (collision b return } + +// FreeCount returns the number of free device instances +func (i *DeviceAccounterInstance) FreeCount() int { + count := 0 + for _, c := range i.Instances { + if c == 0 { + count++ + } + } + return count +} diff --git a/scheduler/preemption.go b/scheduler/preemption.go index f36c56cbc..9e9f00fff 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -113,9 +113,12 @@ type Preemptor struct { // currentAllocs is the candidate set used to find preemptible allocations currentAllocs []*structs.Allocation + + // ctx is the context from the scheduler stack + ctx Context } -func NewPreemptor(jobPriority int) *Preemptor { +func NewPreemptor(jobPriority int, ctx Context) *Preemptor { return &Preemptor{ currentPreemptions: make(map[structs.NamespacedID]map[string]int), jobPriority: jobPriority, @@ -435,6 +438,52 @@ OUTER: return filteredBestAllocs } +// PreemptForDevice tries to find allocations to preempt to meet devices needed +// This is called once per task when assigning devices to the task +func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *deviceAllocator) []*structs.Allocation { + // First group allocations by priority + allocsByPriority := filterAndGroupPreemptibleAllocs(p.jobPriority, p.currentAllocs) + neededCount := ask.Count + preemptedCount := 0 + var preemptedAllocs []*structs.Allocation + + for _, grpAllocs := range allocsByPriority { + for _, alloc := range grpAllocs.allocs { + for _, tr := range alloc.AllocatedResources.Tasks { + if len(tr.Devices) > 0 { + // Go through each assigned device group + for _, device := range tr.Devices { + devID := device.ID() + + // Look up the device instance from the device allocator + devInst := devAlloc.Devices[*devID] + + if devInst == nil { + continue + } + + // Check if the device matches the ask + if !nodeDeviceMatches(p.ctx, devInst.Device, ask) { + continue + } + + // Add to preemption list because this device matches + preemptedCount += len(device.DeviceIDs) + preemptedAllocs = append(preemptedAllocs, alloc) + + // Check if we met needed count + if preemptedCount+devInst.FreeCount() >= int(neededCount) { + return preemptedAllocs + } + } + } + } + } + } + + return nil +} + // basicResourceDistance computes a distance using a coordinate system. It compares resource fields like CPU/Memory and Disk. // Values emitted are in the range [0, maxFloat] func basicResourceDistance(resourceAsk *structs.ComparableResources, resourceUsed *structs.ComparableResources) float64 { diff --git a/scheduler/preemption_test.go b/scheduler/preemption_test.go index f2d83f1f4..fd4c12696 100644 --- a/scheduler/preemption_test.go +++ b/scheduler/preemption_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/nomad/helper/uuid" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" + psstructs "github.com/hashicorp/nomad/plugins/shared/structs" "github.com/stretchr/testify/require" ) @@ -162,6 +163,8 @@ func TestPreemption(t *testing.T) { // Create some persistent alloc ids to use in test cases allocIDs := []string{uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate()} + deviceIDs := []string{"dev1", "dev2", "dev3", "dev4"} + defaultNodeResources := &structs.NodeResources{ Cpu: structs.NodeCpuResources{ CpuShares: 4000, @@ -179,6 +182,55 @@ func TestPreemption(t *testing.T) { MBits: 1000, }, }, + Devices: []*structs.NodeDeviceResource{ + { + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + Attributes: map[string]*psstructs.Attribute{ + "memory": psstructs.NewIntAttribute(11, psstructs.UnitGiB), + "cuda_cores": psstructs.NewIntAttribute(3584, ""), + "graphics_clock": psstructs.NewIntAttribute(1480, psstructs.UnitMHz), + "memory_bandwidth": psstructs.NewIntAttribute(11, psstructs.UnitGBPerS), + }, + Instances: []*structs.NodeDevice{ + { + ID: deviceIDs[0], + Healthy: true, + }, + { + ID: deviceIDs[1], + Healthy: true, + }, + { + ID: deviceIDs[2], + Healthy: true, + }, + { + ID: deviceIDs[3], + Healthy: true, + }, + }, + }, + { + Type: "fpga", + Vendor: "intel", + Name: "F100", + Attributes: map[string]*psstructs.Attribute{ + "memory": psstructs.NewIntAttribute(4, psstructs.UnitGiB), + }, + Instances: []*structs.NodeDevice{ + { + ID: "fpga1", + Healthy: true, + }, + { + ID: "fpga2", + Healthy: false, + }, + }, + }, + }, } reservedNodeResources := &structs.NodeReservedResources{ @@ -827,6 +879,128 @@ func TestPreemption(t *testing.T) { allocIDs[1]: {}, }, }, + { + desc: "Preemption with one device instance per alloc", + // Add allocations that use two device instances + currentAllocations: []*structs.Allocation{ + createAllocWithDevice(allocIDs[0], lowPrioJob, &structs.Resources{ + CPU: 500, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + DeviceIDs: []string{deviceIDs[0]}, + }), + createAllocWithDevice(allocIDs[1], lowPrioJob, &structs.Resources{ + CPU: 200, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + DeviceIDs: []string{deviceIDs[1]}, + })}, + nodeReservedCapacity: reservedNodeResources, + nodeCapacity: defaultNodeResources, + jobPriority: 100, + resourceAsk: &structs.Resources{ + CPU: 1000, + MemoryMB: 512, + DiskMB: 4 * 1024, + Devices: []*structs.RequestedDevice{ + { + Name: "nvidia/gpu/1080ti", + Count: 4, + }, + }, + }, + preemptedAllocIDs: map[string]struct{}{ + allocIDs[0]: {}, + allocIDs[1]: {}, + }, + }, + { + desc: "Preemption multiple devices used", + currentAllocations: []*structs.Allocation{ + createAllocWithDevice(allocIDs[0], lowPrioJob, &structs.Resources{ + CPU: 500, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + DeviceIDs: []string{deviceIDs[0], deviceIDs[1], deviceIDs[2], deviceIDs[3]}, + }), + createAllocWithDevice(allocIDs[1], lowPrioJob, &structs.Resources{ + CPU: 200, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "fpga", + Vendor: "intel", + Name: "F100", + DeviceIDs: []string{"fpga1"}, + })}, + nodeReservedCapacity: reservedNodeResources, + nodeCapacity: defaultNodeResources, + jobPriority: 100, + resourceAsk: &structs.Resources{ + CPU: 1000, + MemoryMB: 512, + DiskMB: 4 * 1024, + Devices: []*structs.RequestedDevice{ + { + Name: "gpu", + Count: 4, + }, + }, + }, + preemptedAllocIDs: map[string]struct{}{ + allocIDs[0]: {}, + }, + }, + { + desc: "Device preemption not possible due to more instances needed than available", + currentAllocations: []*structs.Allocation{ + createAllocWithDevice(allocIDs[0], lowPrioJob, &structs.Resources{ + CPU: 500, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + DeviceIDs: []string{deviceIDs[0], deviceIDs[1], deviceIDs[2], deviceIDs[3]}, + }), + createAllocWithDevice(allocIDs[1], lowPrioJob, &structs.Resources{ + CPU: 200, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "fpga", + Vendor: "intel", + Name: "F100", + DeviceIDs: []string{"fpga1"}, + })}, + nodeReservedCapacity: reservedNodeResources, + nodeCapacity: defaultNodeResources, + jobPriority: 100, + resourceAsk: &structs.Resources{ + CPU: 1000, + MemoryMB: 512, + DiskMB: 4 * 1024, + Devices: []*structs.RequestedDevice{ + { + Name: "gpu", + Count: 6, + }, + }, + }, + }, // This test case exercises the code path for a final filtering step that tries to // minimize the number of preemptible allocations { @@ -946,6 +1120,10 @@ func TestPreemption(t *testing.T) { // helper method to create allocations with given jobs and resources func createAlloc(id string, job *structs.Job, resource *structs.Resources) *structs.Allocation { + return createAllocWithDevice(id, job, resource, nil) +} + +func createAllocWithDevice(id string, job *structs.Job, resource *structs.Resources, allocatedDevices *structs.AllocatedDeviceResource) *structs.Allocation { alloc := &structs.Allocation{ ID: id, Job: job, @@ -959,6 +1137,23 @@ func createAlloc(id string, job *structs.Job, resource *structs.Resources) *stru DesiredStatus: structs.AllocDesiredStatusRun, ClientStatus: structs.AllocClientStatusRunning, TaskGroup: "web", + AllocatedResources: &structs.AllocatedResources{ + Tasks: map[string]*structs.AllocatedTaskResources{ + "web": &structs.AllocatedTaskResources{ + Cpu: structs.AllocatedCpuResources{ + CpuShares: int64(resource.CPU), + }, + Memory: structs.AllocatedMemoryResources{ + MemoryMB: int64(resource.MemoryMB), + }, + Networks: resource.Networks, + }, + }, + }, + } + + if allocatedDevices != nil { + alloc.AllocatedResources.Tasks["web"].Devices = []*structs.AllocatedDeviceResource{allocatedDevices} } return alloc } diff --git a/scheduler/rank.go b/scheduler/rank.go index 7d2b4ad4e..d892d317f 100644 --- a/scheduler/rank.go +++ b/scheduler/rank.go @@ -211,7 +211,7 @@ OUTER: var allocsToPreempt []*structs.Allocation // Initialize preemptor with node - preemptor := NewPreemptor(iter.priority) + preemptor := NewPreemptor(iter.priority, iter.ctx) preemptor.SetNode(option.Node) // Count the number of existing preemptions @@ -285,8 +285,36 @@ OUTER: for _, req := range task.Resources.Devices { offer, sumAffinities, err := devAllocator.AssignDevice(req) if offer == nil { - iter.ctx.Metrics().ExhaustedNode(option.Node, fmt.Sprintf("devices: %s", err)) - continue OUTER + // If eviction is not enabled, mark this node as exhausted and continue + if !iter.evict { + iter.ctx.Metrics().ExhaustedNode(option.Node, fmt.Sprintf("devices: %s", err)) + continue OUTER + } + + // Attempt preemption + preemptor.SetCandidates(proposed) + devicePreemptions := preemptor.PreemptForDevice(req, devAllocator) + + if devicePreemptions == nil { + iter.ctx.Logger().Named("binpack").Error(fmt.Sprintf("unable to meet device resource need after attempting preemption:%v", req)) + netIdx.Release() + continue OUTER + } + allocsToPreempt = append(allocsToPreempt, devicePreemptions...) + + // First subtract out preempted allocations + proposed = structs.RemoveAllocs(proposed, allocsToPreempt) + + // Reset the device allocator with new set of proposed allocs + devAllocator := newDeviceAllocator(iter.ctx, option.Node) + devAllocator.AddAllocs(proposed) + + // Try offer again + offer, sumAffinities, err = devAllocator.AssignDevice(req) + if offer == nil { + iter.ctx.Logger().Named("binpack").Error(fmt.Sprintf("unexpected error, unable to create device offer after preempting:%v", err)) + continue OUTER + } } // Store the resource From 813143fee5c8a0261867e4c33597b7695b8613f5 Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Thu, 15 Nov 2018 12:27:32 -0600 Subject: [PATCH 02/71] fix linting --- scheduler/preemption_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scheduler/preemption_test.go b/scheduler/preemption_test.go index fd4c12696..d2e10f3bf 100644 --- a/scheduler/preemption_test.go +++ b/scheduler/preemption_test.go @@ -1139,7 +1139,7 @@ func createAllocWithDevice(id string, job *structs.Job, resource *structs.Resour TaskGroup: "web", AllocatedResources: &structs.AllocatedResources{ Tasks: map[string]*structs.AllocatedTaskResources{ - "web": &structs.AllocatedTaskResources{ + "web": { Cpu: structs.AllocatedCpuResources{ CpuShares: int64(resource.CPU), }, From 7f2826097de9bea9f241403695936e85b694957a Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Fri, 16 Nov 2018 20:32:10 -0600 Subject: [PATCH 03/71] Fix preemption logic bug, need to group allocations by device first. This ensures that the set of allocations chosen for preemption all share the same device where ID is --- scheduler/preemption.go | 113 +++++++++++++++++++++++++---------- scheduler/preemption_test.go | 113 ++++++++++++++++++++++++++++++++++- 2 files changed, 193 insertions(+), 33 deletions(-) diff --git a/scheduler/preemption.go b/scheduler/preemption.go index 9e9f00fff..6d6b929c6 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -123,6 +123,7 @@ func NewPreemptor(jobPriority int, ctx Context) *Preemptor { currentPreemptions: make(map[structs.NamespacedID]map[string]int), jobPriority: jobPriority, allocDetails: make(map[string]*allocInfo), + ctx: ctx, } } @@ -438,45 +439,95 @@ OUTER: return filteredBestAllocs } +// allocDeviceGroup represents a group of allocs that share a device +type allocDeviceGroup struct { + allocs []*structs.Allocation + + // deviceInstances tracks the number of instances used per alloc + deviceInstances map[string]int +} + +func newAllocDeviceGroup() *allocDeviceGroup { + return &allocDeviceGroup{ + deviceInstances: make(map[string]int), + } +} + // PreemptForDevice tries to find allocations to preempt to meet devices needed // This is called once per task when assigning devices to the task func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *deviceAllocator) []*structs.Allocation { - // First group allocations by priority - allocsByPriority := filterAndGroupPreemptibleAllocs(p.jobPriority, p.currentAllocs) - neededCount := ask.Count - preemptedCount := 0 - var preemptedAllocs []*structs.Allocation - for _, grpAllocs := range allocsByPriority { - for _, alloc := range grpAllocs.allocs { - for _, tr := range alloc.AllocatedResources.Tasks { - if len(tr.Devices) > 0 { - // Go through each assigned device group - for _, device := range tr.Devices { - devID := device.ID() + // Group allocations by device, tracking the number of + // instances used in each device by alloc id + deviceToAllocs := make(map[structs.DeviceIdTuple]*allocDeviceGroup) + for _, alloc := range p.currentAllocs { + for _, tr := range alloc.AllocatedResources.Tasks { + // Ignore allocs that don't use devices + if len(tr.Devices) == 0 { + continue + } - // Look up the device instance from the device allocator - devInst := devAlloc.Devices[*devID] + // Go through each assigned device group + for _, device := range tr.Devices { + devID := device.ID() - if devInst == nil { - continue - } + // Look up the device instance from the device allocator + deviceIdTuple := *devID + devInst := devAlloc.Devices[deviceIdTuple] - // Check if the device matches the ask - if !nodeDeviceMatches(p.ctx, devInst.Device, ask) { - continue - } - - // Add to preemption list because this device matches - preemptedCount += len(device.DeviceIDs) - preemptedAllocs = append(preemptedAllocs, alloc) - - // Check if we met needed count - if preemptedCount+devInst.FreeCount() >= int(neededCount) { - return preemptedAllocs - } - } + if devInst == nil { + continue } + + // Ignore if the device doesn't match the ask + if !nodeDeviceMatches(p.ctx, devInst.Device, ask) { + continue + } + + // Store both the alloc and the number of instances used + // in our tracking map + allocDeviceGrp := deviceToAllocs[deviceIdTuple] + if allocDeviceGrp == nil { + allocDeviceGrp = newAllocDeviceGroup() + deviceToAllocs[deviceIdTuple] = allocDeviceGrp + } + allocDeviceGrp.allocs = append(allocDeviceGrp.allocs, alloc) + devCount := allocDeviceGrp.deviceInstances[alloc.ID] + devCount += len(device.DeviceIDs) + allocDeviceGrp.deviceInstances[alloc.ID] = devCount + } + } + } + + neededCount := ask.Count + + // Examine matching allocs by device + for deviceIDTuple, allocsGrp := range deviceToAllocs { + + // First group and sort allocations using this device by priority + allocsByPriority := filterAndGroupPreemptibleAllocs(p.jobPriority, allocsGrp.allocs) + + // Reset preempted count for this device + preemptedCount := 0 + + // Initialize slice of preempted allocations + var preemptedAllocs []*structs.Allocation + + for _, grpAllocs := range allocsByPriority { + for _, alloc := range grpAllocs.allocs { + + // Look up the device instance from the device allocator + devInst := devAlloc.Devices[deviceIDTuple] + + // Add to preemption list because this device matches + preemptedCount += allocsGrp.deviceInstances[alloc.ID] + preemptedAllocs = append(preemptedAllocs, alloc) + + // Check if we met needed count + if preemptedCount+devInst.FreeCount() >= int(neededCount) { + return preemptedAllocs + } + } } } diff --git a/scheduler/preemption_test.go b/scheduler/preemption_test.go index d2e10f3bf..b526cac3c 100644 --- a/scheduler/preemption_test.go +++ b/scheduler/preemption_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + "strconv" + "github.com/hashicorp/nomad/helper/uuid" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" @@ -163,7 +165,10 @@ func TestPreemption(t *testing.T) { // Create some persistent alloc ids to use in test cases allocIDs := []string{uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate()} - deviceIDs := []string{"dev1", "dev2", "dev3", "dev4"} + var deviceIDs []string + for i := 0; i < 10; i++ { + deviceIDs = append(deviceIDs, "dev"+strconv.Itoa(i)) + } defaultNodeResources := &structs.NodeResources{ Cpu: structs.NodeCpuResources{ @@ -212,6 +217,35 @@ func TestPreemption(t *testing.T) { }, }, }, + { + Type: "gpu", + Vendor: "nvidia", + Name: "2080ti", + Attributes: map[string]*psstructs.Attribute{ + "memory": psstructs.NewIntAttribute(11, psstructs.UnitGiB), + "cuda_cores": psstructs.NewIntAttribute(3584, ""), + "graphics_clock": psstructs.NewIntAttribute(1480, psstructs.UnitMHz), + "memory_bandwidth": psstructs.NewIntAttribute(11, psstructs.UnitGBPerS), + }, + Instances: []*structs.NodeDevice{ + { + ID: deviceIDs[4], + Healthy: true, + }, + { + ID: deviceIDs[5], + Healthy: true, + }, + { + ID: deviceIDs[6], + Healthy: true, + }, + { + ID: deviceIDs[7], + Healthy: true, + }, + }, + }, { Type: "fpga", Vendor: "intel", @@ -954,7 +988,7 @@ func TestPreemption(t *testing.T) { DiskMB: 4 * 1024, Devices: []*structs.RequestedDevice{ { - Name: "gpu", + Name: "nvidia/gpu/1080ti", Count: 4, }, }, @@ -963,6 +997,81 @@ func TestPreemption(t *testing.T) { allocIDs[0]: {}, }, }, + { + // This test cases creates allocations across two GPUs + // Both GPUs are eligible for the task, but only allocs sharing the + // same device should be chosen for preemption + desc: "Preemption with allocs across multiple devices that match", + currentAllocations: []*structs.Allocation{ + createAllocWithDevice(allocIDs[0], lowPrioJob, &structs.Resources{ + CPU: 500, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + DeviceIDs: []string{deviceIDs[0], deviceIDs[1]}, + }), + createAllocWithDevice(allocIDs[1], highPrioJob, &structs.Resources{ + CPU: 200, + MemoryMB: 100, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + DeviceIDs: []string{deviceIDs[2]}, + }), + createAllocWithDevice(allocIDs[2], lowPrioJob, &structs.Resources{ + CPU: 200, + MemoryMB: 256, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "2080ti", + DeviceIDs: []string{deviceIDs[4], deviceIDs[5]}, + }), + createAllocWithDevice(allocIDs[3], lowPrioJob, &structs.Resources{ + CPU: 100, + MemoryMB: 256, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "2080ti", + DeviceIDs: []string{deviceIDs[6], deviceIDs[7]}, + }), + createAllocWithDevice(allocIDs[4], lowPrioJob, &structs.Resources{ + CPU: 200, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "fpga", + Vendor: "intel", + Name: "F100", + DeviceIDs: []string{"fpga1"}, + })}, + nodeReservedCapacity: reservedNodeResources, + nodeCapacity: defaultNodeResources, + jobPriority: 100, + resourceAsk: &structs.Resources{ + CPU: 1000, + MemoryMB: 512, + DiskMB: 4 * 1024, + Devices: []*structs.RequestedDevice{ + { + Name: "gpu", + Count: 4, + }, + }, + }, + preemptedAllocIDs: map[string]struct{}{ + allocIDs[2]: {}, + allocIDs[3]: {}, + }, + }, { desc: "Device preemption not possible due to more instances needed than available", currentAllocations: []*structs.Allocation{ From e8088e404b56bb84223eeb2118bb0cafaed67909 Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Fri, 16 Nov 2018 20:45:52 -0600 Subject: [PATCH 04/71] Fix formatting --- scheduler/preemption.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/scheduler/preemption.go b/scheduler/preemption.go index 6d6b929c6..a46d45612 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -503,7 +503,6 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev // Examine matching allocs by device for deviceIDTuple, allocsGrp := range deviceToAllocs { - // First group and sort allocations using this device by priority allocsByPriority := filterAndGroupPreemptibleAllocs(p.jobPriority, allocsGrp.allocs) @@ -515,7 +514,6 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev for _, grpAllocs := range allocsByPriority { for _, alloc := range grpAllocs.allocs { - // Look up the device instance from the device allocator devInst := devAlloc.Devices[deviceIDTuple] @@ -527,7 +525,6 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev if preemptedCount+devInst.FreeCount() >= int(neededCount) { return preemptedAllocs } - } } } From 026f976761611d4fbcac4280f745eaff164b7296 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 27 Nov 2018 09:59:57 -0600 Subject: [PATCH 05/71] code review suggestion Co-Authored-By: preetapan --- scheduler/preemption.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scheduler/preemption.go b/scheduler/preemption.go index a46d45612..64b549034 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -472,7 +472,7 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev devID := device.ID() // Look up the device instance from the device allocator - deviceIdTuple := *devID + deviceIdTuple := *device.ID() devInst := devAlloc.Devices[deviceIdTuple] if devInst == nil { From e7257fe5bed18b376898d42ae1c674d944467701 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 27 Nov 2018 10:03:11 -0600 Subject: [PATCH 06/71] Simplify map count update logic Co-Authored-By: preetapan --- scheduler/preemption.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scheduler/preemption.go b/scheduler/preemption.go index 64b549034..444db618c 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -494,7 +494,7 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev allocDeviceGrp.allocs = append(allocDeviceGrp.allocs, alloc) devCount := allocDeviceGrp.deviceInstances[alloc.ID] devCount += len(device.DeviceIDs) - allocDeviceGrp.deviceInstances[alloc.ID] = devCount + allocDeviceGrp.deviceInstances[alloc.ID] += len(device.DeviceIDs) } } } From e023b367fa30678d62d753698ff9fdf64eb619a5 Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Tue, 27 Nov 2018 11:02:06 -0600 Subject: [PATCH 07/71] addresses some code clarity review comments --- scheduler/preemption.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/scheduler/preemption.go b/scheduler/preemption.go index 444db618c..ec7973748 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -439,16 +439,16 @@ OUTER: return filteredBestAllocs } -// allocDeviceGroup represents a group of allocs that share a device -type allocDeviceGroup struct { +// deviceGroupAllocs represents a group of allocs that share a device +type deviceGroupAllocs struct { allocs []*structs.Allocation // deviceInstances tracks the number of instances used per alloc deviceInstances map[string]int } -func newAllocDeviceGroup() *allocDeviceGroup { - return &allocDeviceGroup{ +func newAllocDeviceGroup() *deviceGroupAllocs { + return &deviceGroupAllocs{ deviceInstances: make(map[string]int), } } @@ -459,7 +459,7 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev // Group allocations by device, tracking the number of // instances used in each device by alloc id - deviceToAllocs := make(map[structs.DeviceIdTuple]*allocDeviceGroup) + deviceToAllocs := make(map[structs.DeviceIdTuple]*deviceGroupAllocs) for _, alloc := range p.currentAllocs { for _, tr := range alloc.AllocatedResources.Tasks { // Ignore allocs that don't use devices @@ -469,8 +469,6 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev // Go through each assigned device group for _, device := range tr.Devices { - devID := device.ID() - // Look up the device instance from the device allocator deviceIdTuple := *device.ID() devInst := devAlloc.Devices[deviceIdTuple] From 4afd512f45372800eb0ca3ff5da10458a8d1989d Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Mon, 3 Dec 2018 08:31:41 -0600 Subject: [PATCH 08/71] use structured logging everywhere consistently --- scheduler/preemption.go | 5 ++--- scheduler/rank.go | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/scheduler/preemption.go b/scheduler/preemption.go index ec7973748..18d47eaca 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -454,7 +454,7 @@ func newAllocDeviceGroup() *deviceGroupAllocs { } // PreemptForDevice tries to find allocations to preempt to meet devices needed -// This is called once per task when assigning devices to the task +// This is called once per device request when assigning devices to the task func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *deviceAllocator) []*structs.Allocation { // Group allocations by device, tracking the number of @@ -473,6 +473,7 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev deviceIdTuple := *device.ID() devInst := devAlloc.Devices[deviceIdTuple] + // devInst can be nil if the device is no longer healthy if devInst == nil { continue } @@ -490,8 +491,6 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev deviceToAllocs[deviceIdTuple] = allocDeviceGrp } allocDeviceGrp.allocs = append(allocDeviceGrp.allocs, alloc) - devCount := allocDeviceGrp.deviceInstances[alloc.ID] - devCount += len(device.DeviceIDs) allocDeviceGrp.deviceInstances[alloc.ID] += len(device.DeviceIDs) } } diff --git a/scheduler/rank.go b/scheduler/rank.go index d892d317f..0b531e689 100644 --- a/scheduler/rank.go +++ b/scheduler/rank.go @@ -251,7 +251,7 @@ OUTER: netPreemptions := preemptor.PreemptForNetwork(ask, netIdx) if netPreemptions == nil { - iter.ctx.Logger().Named("binpack").Error(fmt.Sprintf("unable to meet network resource %v after preemption", ask)) + iter.ctx.Logger().Named("binpack").Error("preemption not possible ", "network_resource", ask) netIdx.Release() continue OUTER } @@ -268,7 +268,7 @@ OUTER: offer, err = netIdx.AssignNetwork(ask) if offer == nil { - iter.ctx.Logger().Named("binpack").Error(fmt.Sprintf("unexpected error, unable to create offer after preempting:%v", err)) + iter.ctx.Logger().Named("binpack").Error("unexpected error, unable to create network offer after considering preemption", "error", err) netIdx.Release() continue OUTER } @@ -296,7 +296,7 @@ OUTER: devicePreemptions := preemptor.PreemptForDevice(req, devAllocator) if devicePreemptions == nil { - iter.ctx.Logger().Named("binpack").Error(fmt.Sprintf("unable to meet device resource need after attempting preemption:%v", req)) + iter.ctx.Logger().Named("binpack").Error("preemption not possible", "requested_device", req) netIdx.Release() continue OUTER } @@ -312,7 +312,7 @@ OUTER: // Try offer again offer, sumAffinities, err = devAllocator.AssignDevice(req) if offer == nil { - iter.ctx.Logger().Named("binpack").Error(fmt.Sprintf("unexpected error, unable to create device offer after preempting:%v", err)) + iter.ctx.Logger().Named("binpack").Error("unexpected error, unable to create device offer after considering preemption", "error", err) continue OUTER } } From 87c12861729d5b575dd81154746df3c1a7c08b8d Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 1 Dec 2018 18:39:24 -0500 Subject: [PATCH 09/71] Test Stopping a multi-process exec Ensure that exec children processes get killed as well. --- drivers/exec/driver_test.go | 69 +++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/exec/driver_test.go b/drivers/exec/driver_test.go index f09eef52b..5d2b1e552 100644 --- a/drivers/exec/driver_test.go +++ b/drivers/exec/driver_test.go @@ -23,6 +23,7 @@ import ( "github.com/hashicorp/nomad/plugins/shared/hclspec" "github.com/hashicorp/nomad/testutil" "github.com/stretchr/testify/require" + "golang.org/x/sys/unix" ) func TestMain(m *testing.M) { @@ -137,7 +138,7 @@ func TestExecDriver_StartWaitStop(t *testing.T) { go func() { defer wg.Done() result := <-ch - require.Equal(2, result.Signal) + require.Equal(int(unix.SIGINT), result.Signal) }() require.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second)) @@ -160,7 +161,71 @@ func TestExecDriver_StartWaitStop(t *testing.T) { status, err := harness.InspectTask(task.ID) require.NoError(err) require.Equal(drivers.TaskStateExited, status.State) - case <-time.After(1 * time.Second): + case <-time.After(10 * time.Second): + require.Fail("timeout waiting for task to shutdown") + } + + require.NoError(harness.DestroyTask(task.ID, true)) +} + +func TestExecDriver_StartWaitStopKill(t *testing.T) { + t.Parallel() + require := require.New(t) + ctestutils.ExecCompatible(t) + + d := NewExecDriver(testlog.HCLogger(t)) + harness := drivers.NewDriverHarness(t, d) + task := &drivers.TaskConfig{ + ID: uuid.Generate(), + Name: "test", + } + + taskConfig := map[string]interface{}{ + "command": "/bin/bash", + "args": []string{"-c", "echo hi; sleep 600"}, + } + encodeDriverHelper(require, task, taskConfig) + + cleanup := harness.MkAllocDir(task, false) + defer cleanup() + + handle, _, err := harness.StartTask(task) + require.NoError(err) + + ch, err := harness.WaitTask(context.Background(), handle.Config.ID) + require.NoError(err) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + result := <-ch + + // /bin/bash typically ignores INT, so it will be killed eventually + require.Equal(int(unix.SIGKILL), result.Signal) + }() + + require.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second)) + + wg.Add(1) + go func() { + defer wg.Done() + err := harness.StopTask(task.ID, 2*time.Second, "SIGINT") + require.NoError(err) + }() + + waitCh := make(chan struct{}) + go func() { + defer close(waitCh) + wg.Wait() + }() + + select { + case <-waitCh: + status, err := harness.InspectTask(task.ID) + require.NoError(err) + require.Equal(drivers.TaskStateExited, status.State) + case <-time.After(10 * time.Second): require.Fail("timeout waiting for task to shutdown") } From 781d8558f29baac6b9165605f8e34b54f2a66ecf Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 1 Dec 2018 18:42:02 -0500 Subject: [PATCH 10/71] Kill all container processes on shutdown Currently, libcontainer-based executor, upon shutdown, kills the container initial process. The children of the killed process remain running, and the executor is never marked as terminated until they do. Also, fix a case where we treat processes as successful, when `proc.Wait()` fails. In some attempts, I was getting "waitid no child processes" errors and such error shouldn't get process to be considered successful. --- drivers/shared/executor/executor_linux.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/shared/executor/executor_linux.go b/drivers/shared/executor/executor_linux.go index 1a6a5864d..66cf389a4 100644 --- a/drivers/shared/executor/executor_linux.go +++ b/drivers/shared/executor/executor_linux.go @@ -247,7 +247,7 @@ func (l *LibcontainerExecutor) wait() { ps = exitErr.ProcessState } else { l.logger.Error("failed to call wait on user process", "error", err) - l.exitState = &ProcessState{Pid: 0, ExitCode: 0, Time: time.Now()} + l.exitState = &ProcessState{Pid: 0, ExitCode: -2, Time: time.Now()} return } } @@ -319,10 +319,10 @@ func (l *LibcontainerExecutor) Shutdown(signal string, grace time.Duration) erro case <-l.userProcExited: return nil case <-time.After(grace): - return l.container.Signal(os.Kill, false) + return l.container.Signal(os.Kill, true) } } else { - return l.container.Signal(os.Kill, false) + return l.container.Signal(os.Kill, true) } } From 104bbf78d97617562370e435e1f8b2dea15eb4af Mon Sep 17 00:00:00 2001 From: Michael Schurter Date: Mon, 3 Dec 2018 18:49:12 -0800 Subject: [PATCH 11/71] consul: fix script checks exiting after 1 run Fixes a regression caused in d335a82859ca2177bc6deda0c2c85b559daf2db3 The removal of the inner context made the remaining cancels cancel the outer context and cause script checks to exit prematurely. --- command/agent/consul/script.go | 4 ---- command/agent/consul/unit_test.go | 6 +----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/command/agent/consul/script.go b/command/agent/consul/script.go index 4a24d8f99..1f3213be3 100644 --- a/command/agent/consul/script.go +++ b/command/agent/consul/script.go @@ -97,7 +97,6 @@ func (s *scriptCheck) run() *scriptHandle { switch err { case context.Canceled: // check removed during execution; exit - cancel() return case context.DeadlineExceeded: metrics.IncrCounter([]string{"client", "consul", "script_timeouts"}, 1) @@ -112,9 +111,6 @@ func (s *scriptCheck) run() *scriptHandle { s.logger.Warn("check timed out", "timeout", s.check.Timeout) } - // cleanup context - cancel() - state := api.HealthCritical switch code { case 0: diff --git a/command/agent/consul/unit_test.go b/command/agent/consul/unit_test.go index 3ee625e39..6ad3570b4 100644 --- a/command/agent/consul/unit_test.go +++ b/command/agent/consul/unit_test.go @@ -777,10 +777,6 @@ func TestConsul_RegServices(t *testing.T) { // TestConsul_ShutdownOK tests the ok path for the shutdown logic in // ServiceClient. func TestConsul_ShutdownOK(t *testing.T) { - // FIXME: This test is failing now because checks are called once only - // not sure what changed - t.Skip("FIXME: unexpected failing test") - require := require.New(t) ctx := setupFake(t) @@ -832,7 +828,7 @@ func TestConsul_ShutdownOK(t *testing.T) { t.Fatalf("expected 1 checkTTL entry but found: %d", n) } for _, v := range ctx.FakeConsul.checkTTLs { - require.Equalf(2, v, "expected 2 updates but foud %d", v) + require.Equalf(2, v, "expected 2 updates but found %d", v) } for _, v := range ctx.FakeConsul.checks { if v.Status != "passing" { From 383c85ae6faa4eb1fa81d3e10bebcf8ba3320f0c Mon Sep 17 00:00:00 2001 From: Michael Schurter Date: Mon, 3 Dec 2018 20:26:31 -0800 Subject: [PATCH 12/71] consul: add ScriptExecutor context wrapper Since d335a82859ca2177bc6deda0c2c85b559daf2db3 ScriptExecutors now take a timeout duration instead of a context. This broke the script check removal code which used context cancelation propagation to remove script checks while they were executing. This commit adds a wrapper around ScriptExecutors that obeys context cancelation again. The only downside is that it leaks a goroutine until the underlying Exec call completes or timeouts. Since check removal is relatively rare, check timeouts usually low, and scripts usually fast, the risk of leaking a goroutine seems very small. --- command/agent/consul/script.go | 55 ++++++++++++++++++++++++- command/agent/consul/script_test.go | 64 ++++++++++++++++++----------- 2 files changed, 95 insertions(+), 24 deletions(-) diff --git a/command/agent/consul/script.go b/command/agent/consul/script.go index 1f3213be3..b4a99c847 100644 --- a/command/agent/consul/script.go +++ b/command/agent/consul/script.go @@ -18,6 +18,54 @@ type heartbeater interface { UpdateTTL(id, output, status string) error } +// contextExec allows canceling a ScriptExecutor with a context. +type contextExec struct { + // pctx is the parent context. A subcontext will be created with Exec's + // timeout. + pctx context.Context + + // exec to be wrapped in a context + exec interfaces.ScriptExecutor +} + +func newContextExec(ctx context.Context, exec interfaces.ScriptExecutor) *contextExec { + return &contextExec{ + pctx: ctx, + exec: exec, + } +} + +type execResult struct { + buf []byte + code int + err error +} + +// Exec a command until the timeout expires, the context is canceled, or the +// underlying Exec returns. +func (c *contextExec) Exec(timeout time.Duration, cmd string, args []string) ([]byte, int, error) { + resCh := make(chan execResult, 1) + + // Don't trust the underlying implementation to obey timeout + ctx, cancel := context.WithTimeout(c.pctx, timeout) + defer cancel() + + go func() { + output, code, err := c.exec.Exec(timeout, cmd, args) + select { + case resCh <- execResult{output, code, err}: + case <-ctx.Done(): + } + }() + + select { + case res := <-resCh: + return res.buf, res.code, res.err + case <-ctx.Done(): + return nil, 0, ctx.Err() + } +} + // scriptHandle is returned by scriptCheck.run by cancelling a scriptCheck and // waiting for it to shutdown. type scriptHandle struct { @@ -74,6 +122,11 @@ func newScriptCheck(allocID, taskName, checkID string, check *structs.ServiceChe func (s *scriptCheck) run() *scriptHandle { ctx, cancel := context.WithCancel(context.Background()) exitCh := make(chan struct{}) + + // Wrap the original ScriptExecutor in one that obeys context + // cancelation. + ctxExec := newContextExec(ctx, s.exec) + go func() { defer close(exitCh) timer := time.NewTimer(0) @@ -93,7 +146,7 @@ func (s *scriptCheck) run() *scriptHandle { metrics.IncrCounter([]string{"client", "consul", "script_runs"}, 1) // Execute check script with timeout - output, code, err := s.exec.Exec(s.check.Timeout, s.check.Command, s.check.Args) + output, code, err := ctxExec.Exec(s.check.Timeout, s.check.Command, s.check.Args) switch err { case context.Canceled: // check removed during execution; exit diff --git a/command/agent/consul/script_test.go b/command/agent/consul/script_test.go index 42bd1aed4..25b6329b3 100644 --- a/command/agent/consul/script_test.go +++ b/command/agent/consul/script_test.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "os/exec" + "sync/atomic" "testing" "time" @@ -23,20 +24,34 @@ func TestMain(m *testing.M) { // blockingScriptExec implements ScriptExec by running a subcommand that never // exits. type blockingScriptExec struct { + // pctx is canceled *only* for test cleanup. Just like real + // ScriptExecutors its Exec method cannot be canceled directly -- only + // with a timeout. + pctx context.Context + // running is ticked before blocking to allow synchronizing operations running chan struct{} - // set to true if Exec is called and has exited - exited bool + // set to 1 with atomics if Exec is called and has exited + exited int32 } -func newBlockingScriptExec() *blockingScriptExec { - return &blockingScriptExec{running: make(chan struct{})} +// newBlockingScriptExec returns a ScriptExecutor that blocks Exec() until the +// caller recvs on the b.running chan. It also returns a CancelFunc for test +// cleanup only. The runtime cannot cancel ScriptExecutors before their timeout +// expires. +func newBlockingScriptExec() (*blockingScriptExec, context.CancelFunc) { + ctx, cancel := context.WithCancel(context.Background()) + exec := &blockingScriptExec{ + pctx: ctx, + running: make(chan struct{}), + } + return exec, cancel } func (b *blockingScriptExec) Exec(dur time.Duration, _ string, _ []string) ([]byte, int, error) { b.running <- struct{}{} - ctx, cancel := context.WithTimeout(context.Background(), dur) + ctx, cancel := context.WithTimeout(b.pctx, dur) defer cancel() cmd := exec.CommandContext(ctx, testtask.Path(), "sleep", "9000h") testtask.SetCmdEnv(cmd) @@ -47,23 +62,20 @@ func (b *blockingScriptExec) Exec(dur time.Duration, _ string, _ []string) ([]by code = 1 } } - b.exited = true + atomic.StoreInt32(&b.exited, 1) return []byte{}, code, err } // TestConsulScript_Exec_Cancel asserts cancelling a script check shortcircuits // any running scripts. func TestConsulScript_Exec_Cancel(t *testing.T) { - // FIXME: This test is failing now as check process cancellation - // doesn't get propogated to the script check causing timeouts - t.Skip("FIXME: unexpected failing test") - serviceCheck := structs.ServiceCheck{ Name: "sleeper", Interval: time.Hour, Timeout: time.Hour, } - exec := newBlockingScriptExec() + exec, cancel := newBlockingScriptExec() + defer cancel() // pass nil for heartbeater as it shouldn't be called check := newScriptCheck("allocid", "testtask", "checkid", &serviceCheck, exec, nil, testlog.HCLogger(t), nil) @@ -80,8 +92,11 @@ func TestConsulScript_Exec_Cancel(t *testing.T) { case <-time.After(3 * time.Second): t.Fatalf("timed out waiting for script check to exit") } - if !exec.exited { - t.Errorf("expected script executor to run and exit but it has not") + + // The underlying ScriptExecutor (newBlockScriptExec) *cannot* be + // canceled. Only a wrapper around it obeys the context cancelation. + if atomic.LoadInt32(&exec.exited) == 1 { + t.Errorf("expected script executor to still be running after timeout") } } @@ -106,16 +121,19 @@ func newFakeHeartbeater() *fakeHeartbeater { return &fakeHeartbeater{updates: make(chan execStatus)} } -// TestConsulScript_Exec_Timeout asserts a script will be killed when the +// TestConsulScript_Exec_TimeoutBasic asserts a script will be killed when the // timeout is reached. -func TestConsulScript_Exec_Timeout(t *testing.T) { - t.Parallel() // run the slow tests in parallel +func TestConsulScript_Exec_TimeoutBasic(t *testing.T) { + t.Parallel() + serviceCheck := structs.ServiceCheck{ Name: "sleeper", Interval: time.Hour, Timeout: time.Second, } - exec := newBlockingScriptExec() + + exec, cancel := newBlockingScriptExec() + defer cancel() hb := newFakeHeartbeater() check := newScriptCheck("allocid", "testtask", "checkid", &serviceCheck, exec, hb, testlog.HCLogger(t), nil) @@ -132,8 +150,11 @@ func TestConsulScript_Exec_Timeout(t *testing.T) { case <-time.After(3 * time.Second): t.Fatalf("timed out waiting for script check to exit") } - if !exec.exited { - t.Errorf("expected script executor to run and exit but it has not") + + // The underlying ScriptExecutor (newBlockScriptExec) *cannot* be + // canceled. Only a wrapper around it obeys the context cancelation. + if atomic.LoadInt32(&exec.exited) == 1 { + t.Errorf("expected script executor to still be running after timeout") } // Cancel and watch for exit @@ -160,11 +181,8 @@ func (sleeperExec) Exec(time.Duration, string, []string) ([]byte, int, error) { // the timeout is reached and always set a critical status regardless of what // Exec returns. func TestConsulScript_Exec_TimeoutCritical(t *testing.T) { - // FIXME: This test is failing now because we no longer mark critical - // if check succeeded - t.Skip("FIXME: unexpected failing test") + t.Parallel() - t.Parallel() // run the slow tests in parallel serviceCheck := structs.ServiceCheck{ Name: "sleeper", Interval: time.Hour, From e9dc31c68f69ecfe9c18e4224790be3980396f69 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 4 Dec 2018 18:57:14 -0500 Subject: [PATCH 13/71] executor: Keep 0.8.6 exit code for wait() failures 0.8.6 uses exit code 1 when `proc.Wait()` fails: https://github.com/hashicorp/nomad/blob/v0.8.6/client/driver/executor/executor.go#L442 --- drivers/shared/executor/executor_linux.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/shared/executor/executor_linux.go b/drivers/shared/executor/executor_linux.go index 66cf389a4..e72fdc559 100644 --- a/drivers/shared/executor/executor_linux.go +++ b/drivers/shared/executor/executor_linux.go @@ -247,7 +247,7 @@ func (l *LibcontainerExecutor) wait() { ps = exitErr.ProcessState } else { l.logger.Error("failed to call wait on user process", "error", err) - l.exitState = &ProcessState{Pid: 0, ExitCode: -2, Time: time.Now()} + l.exitState = &ProcessState{Pid: 0, ExitCode: 1, Time: time.Now()} return } } @@ -310,6 +310,8 @@ func (l *LibcontainerExecutor) Shutdown(signal string, grace time.Duration) erro return fmt.Errorf("error unknown signal given for shutdown: %s", signal) } + // Signal initial container processes only during graceful + // shutdown; hence `false` arg. err = l.container.Signal(sig, false) if err != nil { return err @@ -319,6 +321,8 @@ func (l *LibcontainerExecutor) Shutdown(signal string, grace time.Duration) erro case <-l.userProcExited: return nil case <-time.After(grace): + // Force kill all container processes after grace period, + // hence `true` argument. return l.container.Signal(os.Kill, true) } } else { From 7a49e9b68e519050a0c2ef0b67c33503bfbc51be Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 4 Dec 2018 19:35:20 -0500 Subject: [PATCH 14/71] drivers/exec: refactor stop/kill tests Simplify the tests to do all assertions within the main goroutine and account for status propagation delay. --- drivers/exec/driver_test.go | 87 +++++++++++++++++-------------------- drivers/java/driver_test.go | 48 ++++++++++---------- 2 files changed, 62 insertions(+), 73 deletions(-) diff --git a/drivers/exec/driver_test.go b/drivers/exec/driver_test.go index 5d2b1e552..4b622beda 100644 --- a/drivers/exec/driver_test.go +++ b/drivers/exec/driver_test.go @@ -120,7 +120,7 @@ func TestExecDriver_StartWaitStop(t *testing.T) { taskConfig := map[string]interface{}{ "command": "/bin/sleep", - "args": []string{"5"}, + "args": []string{"600"}, } encodeDriverHelper(require, task, taskConfig) @@ -133,38 +133,35 @@ func TestExecDriver_StartWaitStop(t *testing.T) { ch, err := harness.WaitTask(context.Background(), handle.Config.ID) require.NoError(err) - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - result := <-ch - require.Equal(int(unix.SIGINT), result.Signal) - }() - require.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second)) - wg.Add(1) go func() { - defer wg.Done() - err := harness.StopTask(task.ID, 2*time.Second, "SIGINT") - require.NoError(err) - }() - - waitCh := make(chan struct{}) - go func() { - defer close(waitCh) - wg.Wait() + harness.StopTask(task.ID, 2*time.Second, "SIGINT") }() select { - case <-waitCh: - status, err := harness.InspectTask(task.ID) - require.NoError(err) - require.Equal(drivers.TaskStateExited, status.State) + case result := <-ch: + require.Equal(int(unix.SIGINT), result.Signal) case <-time.After(10 * time.Second): require.Fail("timeout waiting for task to shutdown") } + // Ensure that the task is marked as dead, but account + // for WaitTask() closing channel before internal state is updated + testutil.WaitForResult(func() (bool, error) { + status, err := harness.InspectTask(task.ID) + if err != nil { + return false, fmt.Errorf("inspecting task failed: %v", err) + } + if status.State != drivers.TaskStateExited { + return false, fmt.Errorf("task hasn't exited yet; status: %v", status.State) + } + + return true, nil + }, func(err error) { + require.NoError(err) + }) + require.NoError(harness.DestroyTask(task.ID, true)) } @@ -191,44 +188,40 @@ func TestExecDriver_StartWaitStopKill(t *testing.T) { handle, _, err := harness.StartTask(task) require.NoError(err) + defer harness.DestroyTask(task.ID, true) ch, err := harness.WaitTask(context.Background(), handle.Config.ID) require.NoError(err) - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - result := <-ch - - // /bin/bash typically ignores INT, so it will be killed eventually - require.Equal(int(unix.SIGKILL), result.Signal) - }() - require.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second)) - wg.Add(1) go func() { - defer wg.Done() - err := harness.StopTask(task.ID, 2*time.Second, "SIGINT") - require.NoError(err) - }() - - waitCh := make(chan struct{}) - go func() { - defer close(waitCh) - wg.Wait() + harness.StopTask(task.ID, 2*time.Second, "SIGINT") }() select { - case <-waitCh: - status, err := harness.InspectTask(task.ID) - require.NoError(err) - require.Equal(drivers.TaskStateExited, status.State) + case result := <-ch: + require.False(result.Successful()) case <-time.After(10 * time.Second): require.Fail("timeout waiting for task to shutdown") } + // Ensure that the task is marked as dead, but account + // for WaitTask() closing channel before internal state is updated + testutil.WaitForResult(func() (bool, error) { + status, err := harness.InspectTask(task.ID) + if err != nil { + return false, fmt.Errorf("inspecting task failed: %v", err) + } + if status.State != drivers.TaskStateExited { + return false, fmt.Errorf("task hasn't exited yet; status: %v", status.State) + } + + return true, nil + }, func(err error) { + require.NoError(err) + }) + require.NoError(harness.DestroyTask(task.ID, true)) } diff --git a/drivers/java/driver_test.go b/drivers/java/driver_test.go index e9882febc..6b8d4bda3 100644 --- a/drivers/java/driver_test.go +++ b/drivers/java/driver_test.go @@ -1,11 +1,11 @@ package java import ( + "fmt" "io" "io/ioutil" "os" "path/filepath" - "sync" "testing" "context" @@ -105,7 +105,7 @@ func TestJavaDriver_Jar_Stop_Wait(t *testing.T) { task := basicTask(t, "demo-app", map[string]interface{}{ "jar_path": "demoapp.jar", - "args": []string{"20"}, + "args": []string{"600"}, "jvm_options": []string{"-Xmx64m", "-Xms32m"}, }) @@ -120,40 +120,36 @@ func TestJavaDriver_Jar_Stop_Wait(t *testing.T) { ch, err := harness.WaitTask(context.Background(), handle.Config.ID) require.NoError(err) - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - result := <-ch - require.Equal(2, result.Signal) - }() - require.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second)) - wg.Add(1) go func() { - defer wg.Done() - time.Sleep(10 * time.Millisecond) - err := harness.StopTask(task.ID, 2*time.Second, "SIGINT") - require.NoError(err) - }() - - waitCh := make(chan struct{}) - go func() { - defer close(waitCh) - wg.Wait() + harness.StopTask(task.ID, 2*time.Second, "SIGINT") }() select { - case <-waitCh: - status, err := harness.InspectTask(task.ID) - require.NoError(err) - require.Equal(drivers.TaskStateExited, status.State) - case <-time.After(5 * time.Second): + case result := <-ch: + require.False(result.Successful()) + case <-time.After(10 * time.Second): require.Fail("timeout waiting for task to shutdown") } + // Ensure that the task is marked as dead, but account + // for WaitTask() closing channel before internal state is updated + testutil.WaitForResult(func() (bool, error) { + status, err := harness.InspectTask(task.ID) + if err != nil { + return false, fmt.Errorf("inspecting task failed: %v", err) + } + if status.State != drivers.TaskStateExited { + return false, fmt.Errorf("task hasn't exited yet; status: %v", status.State) + } + + return true, nil + }, func(err error) { + require.NoError(err) + }) + require.NoError(harness.DestroyTask(task.ID, true)) } From 65e9b3b8be7ea44a4bc533140dfad5bba7293480 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 4 Dec 2018 14:50:59 -0500 Subject: [PATCH 15/71] refactor device manipulation --- drivers/docker/config.go | 22 ++++++++++++++++++++++ drivers/docker/driver.go | 27 +++++---------------------- drivers/docker/utils.go | 12 ++++++++++++ 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/drivers/docker/config.go b/drivers/docker/config.go index 33ce1b465..59dcba6f5 100644 --- a/drivers/docker/config.go +++ b/drivers/docker/config.go @@ -356,6 +356,28 @@ type DockerDevice struct { CgroupPermissions string `codec:"cgroup_permissions"` } +func (d DockerDevice) toDockerDevice() (docker.Device, error) { + dd := docker.Device{ + PathOnHost: d.HostPath, + PathInContainer: d.ContainerPath, + CgroupPermissions: d.CgroupPermissions, + } + + if d.HostPath == "" { + return dd, fmt.Errorf("host path must be set in configuration for devices") + } + + if dd.CgroupPermissions == "" { + dd.CgroupPermissions = "rwm" + } + + if !validateCgroupPermission(dd.CgroupPermissions) { + return dd, fmt.Errorf("invalid cgroup permission string: %q", dd.CgroupPermissions) + } + + return dd, nil +} + type DockerLogging struct { Type string `codec:"type"` Config map[string]string `codec:"config"` diff --git a/drivers/docker/driver.go b/drivers/docker/driver.go index cfb8ae308..38d13623d 100644 --- a/drivers/docker/driver.go +++ b/drivers/docker/driver.go @@ -718,29 +718,12 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T } } - if len(driverConfig.Devices) > 0 { - var devices []docker.Device - for _, device := range driverConfig.Devices { - if device.HostPath == "" { - return c, fmt.Errorf("host path must be set in configuration for devices") - } - if device.CgroupPermissions != "" { - for _, char := range device.CgroupPermissions { - ch := string(char) - if ch != "r" && ch != "w" && ch != "m" { - return c, fmt.Errorf("invalid cgroup permission string: %q", device.CgroupPermissions) - } - } - } else { - device.CgroupPermissions = "rwm" - } - dev := docker.Device{ - PathOnHost: device.HostPath, - PathInContainer: device.ContainerPath, - CgroupPermissions: device.CgroupPermissions} - devices = append(devices, dev) + for _, device := range driverConfig.Devices { + dd, err := device.toDockerDevice() + if err != nil { + return c, err } - hostConfig.Devices = devices + hostConfig.Devices = append(hostConfig.Devices, dd) } // Setup mounts diff --git a/drivers/docker/utils.go b/drivers/docker/utils.go index a70e1b8b4..7b482e11a 100644 --- a/drivers/docker/utils.go +++ b/drivers/docker/utils.go @@ -188,3 +188,15 @@ func authIsEmpty(auth *docker.AuthConfiguration) bool { auth.Email == "" && auth.ServerAddress == "" } + +func validateCgroupPermission(s string) bool { + for _, c := range s { + switch c { + case 'r', 'w', 'm': + default: + return false + } + } + + return true +} From 04af0970084bb1c1b96910a5846d42ef4efe8828 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 4 Dec 2018 16:46:16 -0500 Subject: [PATCH 16/71] driver/docker: honor plugin devices --- drivers/docker/driver.go | 16 +++++++ drivers/docker/driver_test.go | 90 +++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/drivers/docker/driver.go b/drivers/docker/driver.go index 38d13623d..4b780b32b 100644 --- a/drivers/docker/driver.go +++ b/drivers/docker/driver.go @@ -718,6 +718,7 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T } } + // Setup devices for _, device := range driverConfig.Devices { dd, err := device.toDockerDevice() if err != nil { @@ -725,6 +726,13 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T } hostConfig.Devices = append(hostConfig.Devices, dd) } + for _, device := range task.Devices { + hostConfig.Devices = append(hostConfig.Devices, docker.Device{ + PathOnHost: device.HostPath, + PathInContainer: device.TaskPath, + CgroupPermissions: device.Permissions, + }) + } // Setup mounts for _, m := range driverConfig.Mounts { @@ -746,6 +754,14 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T hostConfig.Mounts = append(hostConfig.Mounts, hm) } + for _, m := range task.Mounts { + hostConfig.Mounts = append(hostConfig.Mounts, docker.HostMount{ + Type: "bind", + Target: m.TaskPath, + Source: m.HostPath, + ReadOnly: m.Readonly, + }) + } // set DNS search domains and extra hosts hostConfig.DNSSearch = driverConfig.DNSSearchDomains diff --git a/drivers/docker/driver_test.go b/drivers/docker/driver_test.go index 697e078ae..56ebcb758 100644 --- a/drivers/docker/driver_test.go +++ b/drivers/docker/driver_test.go @@ -11,6 +11,7 @@ import ( "reflect" "runtime" "runtime/debug" + "sort" "strconv" "strings" "testing" @@ -1902,6 +1903,95 @@ func TestDockerDriver_MountsSerialization(t *testing.T) { } +// TestDockerDriver_CreateContainerConfig_MountsCombined asserts that +// devices and mounts set by device managers/plugins are honored +// and present in docker.CreateContainerOptions, and that it is appended +// to any devices/mounts a user sets in the task config. +func TestDockerDriver_CreateContainerConfig_MountsCombined(t *testing.T) { + t.Parallel() + + task, cfg, _ := dockerTask(t) + + task.Devices = []*drivers.DeviceConfig{ + { + HostPath: "/dev/fuse", + TaskPath: "/container/dev/task-fuse", + Permissions: "rw", + }, + } + task.Mounts = []*drivers.MountConfig{ + { + HostPath: "/tmp/task-mount", + TaskPath: "/container/tmp/task-mount", + Readonly: true, + }, + } + + cfg.Devices = []DockerDevice{ + { + HostPath: "/dev/stdout", + ContainerPath: "/container/dev/cfg-stdout", + CgroupPermissions: "rwm", + }, + } + cfg.Mounts = []DockerMount{ + { + Type: "bind", + Source: "/tmp/cfg-mount", + Target: "/container/tmp/cfg-mount", + ReadOnly: false, + }, + } + + require.NoError(t, task.EncodeConcreteDriverConfig(cfg)) + + dh := dockerDriverHarness(t, nil) + driver := dh.Impl().(*Driver) + + c, err := driver.createContainerConfig(task, cfg, "org/repo:0.1") + require.NoError(t, err) + + expectedMounts := []docker.HostMount{ + { + Type: "bind", + Source: "/tmp/cfg-mount", + Target: "/container/tmp/cfg-mount", + ReadOnly: false, + BindOptions: &docker.BindOptions{}, + }, + { + Type: "bind", + Source: "/tmp/task-mount", + Target: "/container/tmp/task-mount", + ReadOnly: true, + }, + } + foundMounts := c.HostConfig.Mounts + sort.Slice(foundMounts, func(i, j int) bool { + return foundMounts[i].Target < foundMounts[j].Target + }) + require.EqualValues(t, expectedMounts, foundMounts) + + expectedDevices := []docker.Device{ + { + PathOnHost: "/dev/stdout", + PathInContainer: "/container/dev/cfg-stdout", + CgroupPermissions: "rwm", + }, + { + PathOnHost: "/dev/fuse", + PathInContainer: "/container/dev/task-fuse", + CgroupPermissions: "rw", + }, + } + + foundDevices := c.HostConfig.Devices + sort.Slice(foundDevices, func(i, j int) bool { + return foundDevices[i].PathInContainer < foundDevices[j].PathInContainer + }) + require.EqualValues(t, expectedDevices, foundDevices) +} + // TestDockerDriver_Cleanup ensures Cleanup removes only downloaded images. func TestDockerDriver_Cleanup(t *testing.T) { if !testutil.DockerIsConnected(t) { From 5a98dfa493702aa5dd7260616d470f7b077e97b6 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Wed, 5 Dec 2018 13:01:12 -0800 Subject: [PATCH 17/71] Don't GC running but desired stop allocations This PR fixes an edge case where we could GC an allocation that was in a desired stop state but had not terminated yet. This can be hit if the client hasn't shutdown the allocation yet or if the allocation is still shutting down (long kill_timeout). Fixes https://github.com/hashicorp/nomad/issues/4940 --- nomad/core_sched.go | 7 ++++++- nomad/core_sched_test.go | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/nomad/core_sched.go b/nomad/core_sched.go index a3fbe4010..396ef641f 100644 --- a/nomad/core_sched.go +++ b/nomad/core_sched.go @@ -7,7 +7,6 @@ import ( log "github.com/hashicorp/go-hclog" memdb "github.com/hashicorp/go-memdb" - "github.com/hashicorp/nomad/nomad/state" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/scheduler" @@ -623,6 +622,12 @@ func allocGCEligible(a *structs.Allocation, job *structs.Job, gcTime time.Time, return false } + // If the allocation is still running on the client we can not garbage + // collect it. + if a.ClientStatus == structs.AllocClientStatusRunning { + return false + } + // If the job is deleted, stopped or dead all allocs can be removed if job == nil || job.Stop || job.Status == structs.JobStatusDead { return true diff --git a/nomad/core_sched_test.go b/nomad/core_sched_test.go index 02ea29ea3..000f1a72d 100644 --- a/nomad/core_sched_test.go +++ b/nomad/core_sched_test.go @@ -1972,6 +1972,16 @@ func TestAllocation_GCEligible(t *testing.T) { ThresholdIndex: 90, ShouldGC: false, }, + { + Desc: "Don't GC when non terminal on client and job dead", + ClientStatus: structs.AllocClientStatusRunning, + DesiredStatus: structs.AllocDesiredStatusStop, + JobStatus: structs.JobStatusDead, + GCTime: fail, + ModifyIndex: 90, + ThresholdIndex: 90, + ShouldGC: false, + }, { Desc: "GC when terminal but not failed ", ClientStatus: structs.AllocClientStatusComplete, From 75ac7c4be0fcd9a2389b2c4bbe44cd88a08a9d1c Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Thu, 6 Dec 2018 12:30:31 -0800 Subject: [PATCH 18/71] Make alloc health watcher a postrun hook rather than shutdown hook --- client/allocrunner/health_hook.go | 6 ++-- client/allocrunner/health_hook_test.go | 45 ++++++++++++++------------ 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/client/allocrunner/health_hook.go b/client/allocrunner/health_hook.go index 8542e171c..c7b26a717 100644 --- a/client/allocrunner/health_hook.go +++ b/client/allocrunner/health_hook.go @@ -175,7 +175,7 @@ func (h *allocHealthWatcherHook) Update(req *interfaces.RunnerUpdateRequest) err return h.init() } -func (h *allocHealthWatcherHook) Destroy() error { +func (h *allocHealthWatcherHook) Postrun() error { h.hookLock.Lock() defer h.hookLock.Unlock() @@ -189,8 +189,8 @@ func (h *allocHealthWatcherHook) Destroy() error { } func (h *allocHealthWatcherHook) Shutdown() { - // Same as Destroy - h.Destroy() + // Same as Postrun + h.Postrun() } // watchHealth watches alloc health until it is set, the alloc is stopped, or diff --git a/client/allocrunner/health_hook_test.go b/client/allocrunner/health_hook_test.go index 4486cc369..cb2b3d7d1 100644 --- a/client/allocrunner/health_hook_test.go +++ b/client/allocrunner/health_hook_test.go @@ -22,7 +22,7 @@ import ( // statically assert health hook implements the expected interfaces var _ interfaces.RunnerPrerunHook = (*allocHealthWatcherHook)(nil) var _ interfaces.RunnerUpdateHook = (*allocHealthWatcherHook)(nil) -var _ interfaces.RunnerDestroyHook = (*allocHealthWatcherHook)(nil) +var _ interfaces.RunnerPostrunHook = (*allocHealthWatcherHook)(nil) var _ interfaces.ShutdownHook = (*allocHealthWatcherHook)(nil) // allocHealth is emitted to a chan whenever SetHealth is called @@ -76,8 +76,9 @@ func (m *mockHealthSetter) ClearHealth() { m.taskEvents = nil } -// TestHealthHook_PrerunDestroy asserts a health hook does not error if it is run and destroyed. -func TestHealthHook_PrerunDestroy(t *testing.T) { +// TestHealthHook_PrerunPostrun asserts a health hook does not error if it is +// run and postrunned. +func TestHealthHook_PrerunPostrun(t *testing.T) { t.Parallel() require := require.New(t) @@ -96,7 +97,7 @@ func TestHealthHook_PrerunDestroy(t *testing.T) { require.True(ok) _, ok = h.(interfaces.RunnerUpdateHook) require.True(ok) - destroyh, ok := h.(interfaces.RunnerDestroyHook) + postrunh, ok := h.(interfaces.RunnerPostrunHook) require.True(ok) // Prerun @@ -109,12 +110,12 @@ func TestHealthHook_PrerunDestroy(t *testing.T) { assert.False(t, ahw.isDeploy) ahw.hookLock.Unlock() - // Destroy - require.NoError(destroyh.Destroy()) + // Postrun + require.NoError(postrunh.Postrun()) } -// TestHealthHook_PrerunUpdateDestroy asserts Updates may be applied concurrently. -func TestHealthHook_PrerunUpdateDestroy(t *testing.T) { +// TestHealthHook_PrerunUpdatePostrun asserts Updates may be applied concurrently. +func TestHealthHook_PrerunUpdatePostrun(t *testing.T) { t.Parallel() require := require.New(t) @@ -147,13 +148,13 @@ func TestHealthHook_PrerunUpdateDestroy(t *testing.T) { assert.NoError(t, err) } - // Destroy - require.NoError(h.Destroy()) + // Postrun + require.NoError(h.Postrun()) } -// TestHealthHook_UpdatePrerunDestroy asserts that a hook may have Update +// TestHealthHook_UpdatePrerunPostrun asserts that a hook may have Update // called before Prerun. -func TestHealthHook_UpdatePrerunDestroy(t *testing.T) { +func TestHealthHook_UpdatePrerunPostrun(t *testing.T) { t.Parallel() require := require.New(t) @@ -191,12 +192,12 @@ func TestHealthHook_UpdatePrerunDestroy(t *testing.T) { assert.True(t, h.isDeploy) h.hookLock.Unlock() - // Destroy - require.NoError(h.Destroy()) + // Postrun + require.NoError(h.Postrun()) } -// TestHealthHook_Destroy asserts that a hook may have only Destroy called. -func TestHealthHook_Destroy(t *testing.T) { +// TestHealthHook_Postrun asserts that a hook may have only Postrun called. +func TestHealthHook_Postrun(t *testing.T) { t.Parallel() require := require.New(t) @@ -209,8 +210,8 @@ func TestHealthHook_Destroy(t *testing.T) { h := newAllocHealthWatcherHook(logger, mock.Alloc(), hs, b.Listen(), consul).(*allocHealthWatcherHook) - // Destroy - require.NoError(h.Destroy()) + // Postrun + require.NoError(h.Postrun()) } // TestHealthHook_SetHealth asserts SetHealth is called when health status is @@ -290,8 +291,8 @@ func TestHealthHook_SetHealth(t *testing.T) { require.Nilf(ev, "%#v", health.taskEvents) } - // Destroy - require.NoError(h.Destroy()) + // Postrun + require.NoError(h.Postrun()) } // TestHealthHook_SystemNoop asserts that system jobs return the noop tracker. @@ -309,7 +310,9 @@ func TestHealthHook_SystemNoop(t *testing.T) { require.False(t, ok) _, ok = h.(interfaces.RunnerUpdateHook) require.False(t, ok) - _, ok = h.(interfaces.RunnerDestroyHook) + _, ok = h.(interfaces.RunnerPostrunHook) + require.False(t, ok) + _, ok = h.(interfaces.ShutdownHook) require.False(t, ok) } From a0a58473157d2ea3069973c51d11e834d7f7fe37 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Thu, 6 Dec 2018 15:44:08 -0500 Subject: [PATCH 19/71] fixup: add missed docker utils test --- drivers/docker/utils_test.go | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 drivers/docker/utils_test.go diff --git a/drivers/docker/utils_test.go b/drivers/docker/utils_test.go new file mode 100644 index 000000000..6598d8313 --- /dev/null +++ b/drivers/docker/utils_test.go @@ -0,0 +1,37 @@ +package docker + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestValidateCgroupPermission(t *testing.T) { + positiveCases := []string{ + "r", + "rw", + "rwm", + "mr", + "mrw", + "", + } + + for _, c := range positiveCases { + t.Run("positive case: "+c, func(t *testing.T) { + require.True(t, validateCgroupPermission(c)) + }) + } + + negativeCases := []string{ + "q", + "asdf", + "rq", + } + + for _, c := range negativeCases { + t.Run("negative case: "+c, func(t *testing.T) { + require.False(t, validateCgroupPermission(c)) + }) + } + +} From bfa2854c8b323ce3d5c3f43c9f15551d8bba7def Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Wed, 28 Nov 2018 11:57:38 -0500 Subject: [PATCH 20/71] driver/lxc: mount plugin devices Also, LXC requires target paths to be relative. Container paths in LXC binds should never be absolute paths, so we strip any preceeding `/`, even if a user sets one. --- drivers/lxc/lxc.go | 97 ++++++++++++++++++++++++++++++++++++++--- drivers/lxc/lxc_test.go | 91 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 drivers/lxc/lxc_test.go diff --git a/drivers/lxc/lxc.go b/drivers/lxc/lxc.go index 44127593c..721752342 100644 --- a/drivers/lxc/lxc.go +++ b/drivers/lxc/lxc.go @@ -12,7 +12,8 @@ import ( "time" "github.com/hashicorp/nomad/plugins/drivers" - lxc "gopkg.in/lxc/go-lxc.v2" + ldevices "github.com/opencontainers/runc/libcontainer/devices" + "gopkg.in/lxc/go-lxc.v2" ) var ( @@ -91,6 +92,33 @@ func networkTypeConfigKey() string { } func (d *Driver) mountVolumes(c *lxc.Container, cfg *drivers.TaskConfig, taskConfig TaskConfig) error { + mounts, err := d.mountEntries(cfg, taskConfig) + if err != nil { + return err + } + + devCgroupAllows, err := d.devicesCgroupEntries(cfg) + if err != nil { + return err + } + + for _, mnt := range mounts { + if err := c.SetConfigItem("lxc.mount.entry", mnt); err != nil { + return fmt.Errorf("error setting bind mount %q error: %v", mnt, err) + } + } + + for _, cgroupDev := range devCgroupAllows { + if err := c.SetConfigItem("lxc.cgroup.devices.allow", cgroupDev); err != nil { + return fmt.Errorf("error setting cgroup permission %q error: %v", cgroupDev, err) + } + } + + return nil +} + +// mountEntries compute the mount entries to be set on the container +func (d *Driver) mountEntries(cfg *drivers.TaskConfig, taskConfig TaskConfig) ([]string, error) { // Bind mount the shared alloc dir and task local dir in the container mounts := []string{ fmt.Sprintf("%s local none rw,bind,create=dir", cfg.TaskDir().LocalDir), @@ -98,6 +126,9 @@ func (d *Driver) mountVolumes(c *lxc.Container, cfg *drivers.TaskConfig, taskCon fmt.Sprintf("%s secrets none rw,bind,create=dir", cfg.TaskDir().SecretsDir), } + mounts = append(mounts, d.formatTaskMounts(cfg.Mounts)...) + mounts = append(mounts, d.formatTaskDevices(cfg.Devices)...) + volumesEnabled := d.config.AllowVolumes for _, volDesc := range taskConfig.Volumes { @@ -106,23 +137,75 @@ func (d *Driver) mountVolumes(c *lxc.Container, cfg *drivers.TaskConfig, taskCon if filepath.IsAbs(paths[0]) { if !volumesEnabled { - return fmt.Errorf("absolute bind-mount volume in config but volumes are disabled") + return nil, fmt.Errorf("absolute bind-mount volume in config but volumes are disabled") } } else { // Relative source paths are treated as relative to alloc dir paths[0] = filepath.Join(cfg.TaskDir().Dir, paths[0]) } - mounts = append(mounts, fmt.Sprintf("%s %s none rw,bind,create=dir", paths[0], paths[1])) + // LXC assumes paths are relative with respect to rootfs + target := strings.TrimLeft(paths[1], "/") + mounts = append(mounts, fmt.Sprintf("%s %s none rw,bind,create=dir", paths[0], target)) } - for _, mnt := range mounts { - if err := c.SetConfigItem("lxc.mount.entry", mnt); err != nil { - return fmt.Errorf("error setting bind mount %q error: %v", mnt, err) + return mounts, nil + +} + +func (d *Driver) devicesCgroupEntries(cfg *drivers.TaskConfig) ([]string, error) { + entries := make([]string, len(cfg.Devices)) + + for i, d := range cfg.Devices { + hd, err := ldevices.DeviceFromPath(d.HostPath, d.Permissions) + if err != nil { + return nil, err } + + entries[i] = hd.CgroupString() } - return nil + return entries, nil +} + +func (d *Driver) formatTaskMounts(mounts []*drivers.MountConfig) []string { + result := make([]string, len(mounts)) + + for i, m := range mounts { + result[i] = d.formatMount(m.HostPath, m.TaskPath, m.Readonly) + } + + return result +} + +func (d *Driver) formatTaskDevices(devices []*drivers.DeviceConfig) []string { + result := make([]string, len(devices)) + + for i, m := range devices { + result[i] = d.formatMount(m.HostPath, m.TaskPath, + !strings.Contains(m.Permissions, "w")) + } + + return result +} + +func (d *Driver) formatMount(hostPath, taskPath string, readOnly bool) string { + typ := "dir" + s, err := os.Stat(hostPath) + if err != nil { + d.logger.Warn("failed to find mount host path type, defaulting to dir type", "path", hostPath, "error", err) + } else if !s.IsDir() { + typ = "file" + } + + perm := "rw" + if readOnly { + perm = "ro" + } + + // LXC assumes paths are relative with respect to rootfs + target := strings.TrimLeft(taskPath, "/") + return fmt.Sprintf("%s %s none %s,bind,create=%s", hostPath, target, perm, typ) } func (d *Driver) setResourceLimits(c *lxc.Container, cfg *drivers.TaskConfig) error { diff --git a/drivers/lxc/lxc_test.go b/drivers/lxc/lxc_test.go new file mode 100644 index 000000000..99f4d2ac6 --- /dev/null +++ b/drivers/lxc/lxc_test.go @@ -0,0 +1,91 @@ +//+build linux,lxc + +package lxc + +import ( + "testing" + + "github.com/hashicorp/nomad/helper/testlog" + "github.com/hashicorp/nomad/helper/uuid" + "github.com/hashicorp/nomad/nomad/structs" + "github.com/hashicorp/nomad/plugins/drivers" + "github.com/stretchr/testify/require" +) + +func TestLXCDriver_Mounts(t *testing.T) { + t.Parallel() + + task := &drivers.TaskConfig{ + ID: uuid.Generate(), + Name: "test", + Resources: &drivers.Resources{ + NomadResources: &structs.Resources{ + CPU: 1, + MemoryMB: 2, + }, + LinuxResources: &drivers.LinuxResources{ + CPUShares: 1024, + MemoryLimitBytes: 2 * 1024, + }, + }, + Mounts: []*drivers.MountConfig{ + {HostPath: "/dev", TaskPath: "/task-mounts/dev-path"}, + {HostPath: "/bin/sh", TaskPath: "/task-mounts/task-path-ro", Readonly: true}, + }, + Devices: []*drivers.DeviceConfig{ + {HostPath: "/dev", TaskPath: "/task-devices/dev-path", Permissions: "rw"}, + {HostPath: "/bin/sh", TaskPath: "/task-devices/task-path-ro", Permissions: "ro"}, + }, + } + taskConfig := TaskConfig{ + Template: "busybox", + Volumes: []string{ + "relative/path:/usr-config/container/path", + "relative/path2:usr-config/container/relative", + }, + } + + d := NewLXCDriver(testlog.HCLogger(t)).(*Driver) + d.config.Enabled = true + + entries, err := d.mountEntries(task, taskConfig) + require.NoError(t, err) + + expectedEntries := []string{ + "test/relative/path usr-config/container/path none rw,bind,create=dir", + "test/relative/path2 usr-config/container/relative none rw,bind,create=dir", + "/dev task-mounts/dev-path none rw,bind,create=dir", + "/bin/sh task-mounts/task-path-ro none ro,bind,create=file", + "/dev task-devices/dev-path none rw,bind,create=dir", + "/bin/sh task-devices/task-path-ro none ro,bind,create=file", + } + + for _, e := range expectedEntries { + require.Contains(t, entries, e) + } +} + +func TestLXCDriver_DevicesCgroup(t *testing.T) { + t.Parallel() + + task := &drivers.TaskConfig{ + ID: uuid.Generate(), + Name: "test", + Devices: []*drivers.DeviceConfig{ + {HostPath: "/dev/random", TaskPath: "/task-devices/devrandom", Permissions: "rw"}, + {HostPath: "/dev/null", TaskPath: "/task-devices/devnull", Permissions: "rwm"}, + }, + } + + d := NewLXCDriver(testlog.HCLogger(t)).(*Driver) + d.config.Enabled = true + + cgroupEntries, err := d.devicesCgroupEntries(task) + require.NoError(t, err) + + expected := []string{ + "c 1:8 rw", + "c 1:3 rwm", + } + require.EqualValues(t, expected, cgroupEntries) +} From 8c5e2e39a48d8b528a4c4dfb3401f6f154de715b Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Wed, 28 Nov 2018 14:13:23 -0500 Subject: [PATCH 21/71] driver/rkt: mount plugin devices --- drivers/rkt/driver.go | 15 +++++++ drivers/rkt/driver_test.go | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/drivers/rkt/driver.go b/drivers/rkt/driver.go index a93b0aaae..e31b8e747 100644 --- a/drivers/rkt/driver.go +++ b/drivers/rkt/driver.go @@ -488,6 +488,21 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *cstru } } + // Mount task volumes, always do + for i, vol := range cfg.Mounts { + volName := fmt.Sprintf("%s-%s-taskmounts-%d", cfg.AllocID, sanitizedName, i) + prepareArgs = append(prepareArgs, fmt.Sprintf("--volume=%s,kind=host,source=%s,readOnly=%v", volName, vol.HostPath, vol.Readonly)) + prepareArgs = append(prepareArgs, fmt.Sprintf("--mount=volume=%s,target=%s", volName, vol.TaskPath)) + } + + // Mount task devices, always do + for i, vol := range cfg.Devices { + volName := fmt.Sprintf("%s-%s-taskdevices-%d", cfg.AllocID, sanitizedName, i) + readOnly := !strings.Contains(vol.Permissions, "w") + prepareArgs = append(prepareArgs, fmt.Sprintf("--volume=%s,kind=host,source=%s,readOnly=%v", volName, vol.HostPath, readOnly)) + prepareArgs = append(prepareArgs, fmt.Sprintf("--mount=volume=%s,target=%s", volName, vol.TaskPath)) + } + // Inject environment variables for k, v := range cfg.Env { prepareArgs = append(prepareArgs, fmt.Sprintf("--set-env=%s=%s", k, v)) diff --git a/drivers/rkt/driver_test.go b/drivers/rkt/driver_test.go index 0c065ea9e..b7e0c904b 100644 --- a/drivers/rkt/driver_test.go +++ b/drivers/rkt/driver_test.go @@ -502,6 +502,89 @@ func TestRktDriver_Start_Wait_Volume(t *testing.T) { require.NoError(harness.DestroyTask(task.ID, true)) } +// Verifies mounting a task mount from the host machine and writing +// some data to it from inside the container +func TestRktDriver_Start_Wait_TaskMounts(t *testing.T) { + ctestutil.RktCompatible(t) + if !testutil.IsTravis() { + t.Parallel() + } + + require := require.New(t) + d := NewRktDriver(testlog.HCLogger(t)) + harness := dtestutil.NewDriverHarness(t, d) + + // mounts through task config should be enabled regardless + config := &Config{VolumesEnabled: false} + + var data []byte + require.NoError(basePlug.MsgPackEncode(&data, config)) + require.NoError(harness.SetConfig(data, nil)) + + tmpvol, err := ioutil.TempDir("", "nomadtest_rktdriver_volumes") + require.NoError(err) + defer os.RemoveAll(tmpvol) + + task := &drivers.TaskConfig{ + ID: uuid.Generate(), + AllocID: uuid.Generate(), + Name: "rkttest_alpine", + Resources: &drivers.Resources{ + NomadResources: &structs.Resources{ + MemoryMB: 128, + CPU: 100, + }, + LinuxResources: &drivers.LinuxResources{ + MemoryLimitBytes: 134217728, + CPUShares: 100, + }, + }, + Mounts: []*drivers.MountConfig{ + {HostPath: tmpvol, TaskPath: "/foo", Readonly: false}, + }, + } + exp := []byte{'w', 'i', 'n'} + file := "output.txt" + hostpath := filepath.Join(tmpvol, file) + + taskConfig := map[string]interface{}{ + "image": "docker://redis:3.2-alpine", + "command": "/bin/sh", + "args": []string{ + "-c", + fmt.Sprintf("echo -n %s > /foo/%s", string(exp), file), + }, + "net": []string{"none"}, + } + + encodeDriverHelper(require, task, taskConfig) + testtask.SetTaskConfigEnv(task) + + cleanup := harness.MkAllocDir(task, true) + defer cleanup() + + _, _, err = harness.StartTask(task) + require.NoError(err) + + // Task should terminate quickly + waitCh, err := harness.WaitTask(context.Background(), task.ID) + require.NoError(err) + + select { + case res := <-waitCh: + require.NoError(res.Err) + require.True(res.Successful(), fmt.Sprintf("exit code %v", res.ExitCode)) + case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): + require.Fail("WaitTask timeout") + } + + // Check that data was written to the shared alloc directory. + act, err := ioutil.ReadFile(hostpath) + require.NoError(err) + require.Exactly(exp, act) + require.NoError(harness.DestroyTask(task.ID, true)) +} + // Verifies port mapping func TestRktDriver_PortMapping(t *testing.T) { ctestutil.RktCompatible(t) From b78130eaaf27170f4da579c6bdeb147ddc7210fc Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 4 Dec 2018 21:00:54 -0500 Subject: [PATCH 22/71] Use absolute path in example device plugin deviceDir is used for specifying mount/device host paths, and those should be absolute paths. --- plugins/device/cmd/example/device.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/plugins/device/cmd/example/device.go b/plugins/device/cmd/example/device.go index cccc1de2c..1c96ea348 100644 --- a/plugins/device/cmd/example/device.go +++ b/plugins/device/cmd/example/device.go @@ -256,6 +256,11 @@ func (d *FsDevice) Reserve(deviceIDs []string) (*device.ContainerReservation, er return nil, status.New(codes.InvalidArgument, "no device ids given").Err() } + deviceDir, err := filepath.Abs(d.deviceDir) + if err != nil { + return nil, status.Newf(codes.Internal, "failed to load device dir abs path").Err() + } + resp := &device.ContainerReservation{} for _, id := range deviceIDs { @@ -265,10 +270,10 @@ func (d *FsDevice) Reserve(deviceIDs []string) (*device.ContainerReservation, er } // Add a mount - resp.Devices = append(resp.Devices, &device.DeviceSpec{ - TaskPath: fmt.Sprintf("/dev/%s", id), - HostPath: filepath.Join(d.deviceDir, id), - CgroupPerms: "rw", + resp.Mounts = append(resp.Mounts, &device.Mount{ + TaskPath: fmt.Sprintf("/tmp/task-mounts/%s", id), + HostPath: filepath.Join(deviceDir, id), + ReadOnly: false, }) } From 0953d913ed2aa31998534a4d9931ca7f812b4dc3 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Thu, 6 Dec 2018 15:09:26 -0800 Subject: [PATCH 23/71] Deprecate IOPS IOPS have been modelled as a resource since Nomad 0.1 but has never actually been detected and there is no plan in the short term to add detection. This is because IOPS is a bit simplistic of a unit to define the performance requirements from the underlying storage system. In its current state it adds unnecessary confusion and can be removed without impacting any users. This PR leaves IOPS defined at the jobspec parsing level and in the api/ resources since these are the two public uses of the field. These should be considered deprecated and only exist to allow users to stop using them during the Nomad 0.9.x release. In the future, there should be no expectation that the field will exist. --- api/compose_test.go | 2 -- api/jobs_test.go | 1 - api/resources.go | 15 +++++------ api/tasks_test.go | 1 - api/util_test.go | 1 - client/client.go | 3 --- command/agent/agent.go | 1 - command/agent/config-test-fixtures/basic.hcl | 1 - command/agent/config.go | 5 ---- command/agent/config_parse.go | 1 - command/agent/config_parse_test.go | 1 - command/agent/config_test.go | 2 -- command/agent/job_endpoint.go | 1 - command/alloc_status.go | 6 ++--- command/node_status.go | 15 ++++------- drivers/shared/executor/executor.go | 7 ++--- drivers/shared/executor/executor_linux.go | 9 ------- .../shared/executor/executor_linux_test.go | 1 - drivers/shared/executor/executor_test.go | 4 +-- jobspec/parse.go | 2 +- jobspec/parse_test.go | 4 +-- jobspec/test-fixtures/basic.hcl | 1 - jobspec/test-fixtures/basic_wrong_key.hcl | 1 - nomad/mock/mock.go | 1 - nomad/structs/diff_test.go | 24 ----------------- nomad/structs/funcs_test.go | 18 ------------- nomad/structs/structs.go | 13 ---------- nomad/structs/structs_test.go | 8 ------ plugins/drivers/proto/driver.proto | 1 - plugins/drivers/utils.go | 2 -- scheduler/annotate_test.go | 6 ----- scheduler/preemption_test.go | 21 --------------- scheduler/system_sched_test.go | 4 +-- scheduler/util.go | 2 -- website/source/api/agent.html.md | 1 - website/source/api/allocations.html.md | 4 --- website/source/api/jobs.html.md | 2 -- website/source/api/json-jobs.html.md | 2 -- website/source/api/nodes.html.md | 6 ----- website/source/api/quotas.html.md | 4 --- .../docs/commands/alloc/status.html.md.erb | 16 ++++++------ .../docs/commands/job/history.html.md.erb | 1 - .../docs/commands/job/inspect.html.md.erb | 1 - .../source/docs/commands/job/plan.html.md.erb | 1 - .../docs/commands/node/status.html.md.erb | 16 ++++++------ .../docs/commands/quota/inspect.html.md.erb | 2 -- .../source/docs/commands/status.html.md.erb | 8 +++--- .../docs/job-specification/resources.html.md | 3 --- website/source/docs/telemetry/index.html.md | 26 ------------------- .../check-restart.html.md | 6 ++--- .../reschedule.html.md | 6 ++--- .../restart.html.md | 4 +-- .../operating-a-job/inspecting-state.html.md | 4 +-- .../resource-utilization.html.md | 4 +-- .../source/intro/getting-started/jobs.html.md | 4 +-- 55 files changed, 53 insertions(+), 253 deletions(-) diff --git a/api/compose_test.go b/api/compose_test.go index 0dc3b08ea..b2618aff3 100644 --- a/api/compose_test.go +++ b/api/compose_test.go @@ -18,7 +18,6 @@ func TestCompose(t *testing.T) { CPU: helper.IntToPtr(1250), MemoryMB: helper.IntToPtr(1024), DiskMB: helper.IntToPtr(2048), - IOPS: helper.IntToPtr(500), Networks: []*NetworkResource{ { CIDR: "0.0.0.0/0", @@ -109,7 +108,6 @@ func TestCompose(t *testing.T) { CPU: helper.IntToPtr(1250), MemoryMB: helper.IntToPtr(1024), DiskMB: helper.IntToPtr(2048), - IOPS: helper.IntToPtr(500), Networks: []*NetworkResource{ { CIDR: "0.0.0.0/0", diff --git a/api/jobs_test.go b/api/jobs_test.go index 1d14185cf..857b1a850 100644 --- a/api/jobs_test.go +++ b/api/jobs_test.go @@ -412,7 +412,6 @@ func TestJobs_Canonicalize(t *testing.T) { Resources: &Resources{ CPU: helper.IntToPtr(500), MemoryMB: helper.IntToPtr(256), - IOPS: helper.IntToPtr(0), Networks: []*NetworkResource{ { MBits: helper.IntToPtr(10), diff --git a/api/resources.go b/api/resources.go index e21387769..47a9cee77 100644 --- a/api/resources.go +++ b/api/resources.go @@ -8,9 +8,14 @@ type Resources struct { CPU *int MemoryMB *int `mapstructure:"memory"` DiskMB *int `mapstructure:"disk"` - IOPS *int Networks []*NetworkResource Devices []*RequestedDevice + + // COMPAT(0.10) + // XXX Deprecated. Please do not use. The field will be removed in Nomad + // 0.10 and is only being kept to allow any references to be removed before + // then. + IOPS *int } // Canonicalize will supply missing values in the cases @@ -23,9 +28,6 @@ func (r *Resources) Canonicalize() { if r.MemoryMB == nil { r.MemoryMB = defaultResources.MemoryMB } - if r.IOPS == nil { - r.IOPS = defaultResources.IOPS - } for _, n := range r.Networks { n.Canonicalize() } @@ -42,7 +44,6 @@ func DefaultResources() *Resources { return &Resources{ CPU: helper.IntToPtr(100), MemoryMB: helper.IntToPtr(300), - IOPS: helper.IntToPtr(0), } } @@ -55,7 +56,6 @@ func MinResources() *Resources { return &Resources{ CPU: helper.IntToPtr(20), MemoryMB: helper.IntToPtr(10), - IOPS: helper.IntToPtr(0), } } @@ -73,9 +73,6 @@ func (r *Resources) Merge(other *Resources) { if other.DiskMB != nil { r.DiskMB = other.DiskMB } - if other.IOPS != nil { - r.IOPS = other.IOPS - } if len(other.Networks) != 0 { r.Networks = other.Networks } diff --git a/api/tasks_test.go b/api/tasks_test.go index 449f5650a..1d0205be2 100644 --- a/api/tasks_test.go +++ b/api/tasks_test.go @@ -266,7 +266,6 @@ func TestTask_Require(t *testing.T) { CPU: helper.IntToPtr(1250), MemoryMB: helper.IntToPtr(128), DiskMB: helper.IntToPtr(2048), - IOPS: helper.IntToPtr(500), Networks: []*NetworkResource{ { CIDR: "0.0.0.0/0", diff --git a/api/util_test.go b/api/util_test.go index c6f99018e..1589484ca 100644 --- a/api/util_test.go +++ b/api/util_test.go @@ -29,7 +29,6 @@ func testJob() *Job { Require(&Resources{ CPU: helper.IntToPtr(100), MemoryMB: helper.IntToPtr(256), - IOPS: helper.IntToPtr(10), }). SetLogConfig(&LogConfig{ MaxFiles: helper.IntToPtr(1), diff --git a/client/client.go b/client/client.go index ce2e87573..b162dd4c1 100644 --- a/client/client.go +++ b/client/client.go @@ -1242,9 +1242,6 @@ func resourcesAreEqual(first, second *structs.Resources) bool { if first.DiskMB != second.DiskMB { return false } - if first.IOPS != second.IOPS { - return false - } if len(first.Networks) != len(second.Networks) { return false } diff --git a/command/agent/agent.go b/command/agent/agent.go index 50261a4d2..a936282ad 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -485,7 +485,6 @@ func convertClientConfig(agentConfig *Config) (*clientconfig.Config, error) { r.CPU = agentConfig.Client.Reserved.CPU r.MemoryMB = agentConfig.Client.Reserved.MemoryMB r.DiskMB = agentConfig.Client.Reserved.DiskMB - r.IOPS = agentConfig.Client.Reserved.IOPS res := conf.Node.ReservedResources if res == nil { diff --git a/command/agent/config-test-fixtures/basic.hcl b/command/agent/config-test-fixtures/basic.hcl index 3cae860fc..8faba0641 100644 --- a/command/agent/config-test-fixtures/basic.hcl +++ b/command/agent/config-test-fixtures/basic.hcl @@ -51,7 +51,6 @@ client { cpu = 10 memory = 10 disk = 10 - iops = 10 reserved_ports = "1,100,10-12" } client_min_port = 1000 diff --git a/command/agent/config.go b/command/agent/config.go index 6716ccc03..54a7c3049 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -15,7 +15,6 @@ import ( "time" "github.com/hashicorp/go-sockaddr/template" - client "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/nomad" @@ -573,7 +572,6 @@ type Resources struct { CPU int `mapstructure:"cpu"` MemoryMB int `mapstructure:"memory"` DiskMB int `mapstructure:"disk"` - IOPS int `mapstructure:"iops"` ReservedPorts string `mapstructure:"reserved_ports"` } @@ -1394,9 +1392,6 @@ func (r *Resources) Merge(b *Resources) *Resources { if b.DiskMB != 0 { result.DiskMB = b.DiskMB } - if b.IOPS != 0 { - result.IOPS = b.IOPS - } if b.ReservedPorts != "" { result.ReservedPorts = b.ReservedPorts } diff --git a/command/agent/config_parse.go b/command/agent/config_parse.go index 5f5cdcbb7..641a10c2c 100644 --- a/command/agent/config_parse.go +++ b/command/agent/config_parse.go @@ -493,7 +493,6 @@ func parseReserved(result **Resources, list *ast.ObjectList) error { "cpu", "memory", "disk", - "iops", "reserved_ports", } if err := helper.CheckHCLKeys(listVal, valid); err != nil { diff --git a/command/agent/config_parse_test.go b/command/agent/config_parse_test.go index 1a02f73d0..649339d62 100644 --- a/command/agent/config_parse_test.go +++ b/command/agent/config_parse_test.go @@ -76,7 +76,6 @@ func TestConfig_Parse(t *testing.T) { CPU: 10, MemoryMB: 10, DiskMB: 10, - IOPS: 10, ReservedPorts: "1,100,10-12", }, GCInterval: 6 * time.Second, diff --git a/command/agent/config_test.go b/command/agent/config_test.go index dae2353ba..4c0d97f6e 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -96,7 +96,6 @@ func TestConfig_Merge(t *testing.T) { CPU: 10, MemoryMB: 10, DiskMB: 10, - IOPS: 10, ReservedPorts: "1,10-30,55", }, }, @@ -254,7 +253,6 @@ func TestConfig_Merge(t *testing.T) { CPU: 15, MemoryMB: 15, DiskMB: 15, - IOPS: 15, ReservedPorts: "2,10-30,55", }, GCInterval: 6 * time.Second, diff --git a/command/agent/job_endpoint.go b/command/agent/job_endpoint.go index 8bbec61b5..c34204cc2 100644 --- a/command/agent/job_endpoint.go +++ b/command/agent/job_endpoint.go @@ -853,7 +853,6 @@ func ApiResourcesToStructs(in *api.Resources) *structs.Resources { out := &structs.Resources{ CPU: *in.CPU, MemoryMB: *in.MemoryMB, - IOPS: *in.IOPS, } if l := len(in.Networks); l != 0 { diff --git a/command/alloc_status.go b/command/alloc_status.go index 5a1d50956..bc51b6bbb 100644 --- a/command/alloc_status.go +++ b/command/alloc_status.go @@ -9,7 +9,6 @@ import ( "time" humanize "github.com/dustin/go-humanize" - "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/api/contexts" "github.com/hashicorp/nomad/client/allocrunner/taskrunner/restarts" @@ -490,7 +489,7 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str } var resourcesOutput []string - resourcesOutput = append(resourcesOutput, "CPU|Memory|Disk|IOPS|Addresses") + resourcesOutput = append(resourcesOutput, "CPU|Memory|Disk|Addresses") firstAddr := "" if len(addr) > 0 { firstAddr = addr[0] @@ -512,11 +511,10 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str deviceStats = ru.ResourceUsage.DeviceStats } } - resourcesOutput = append(resourcesOutput, fmt.Sprintf("%v MHz|%v|%v|%v|%v", + resourcesOutput = append(resourcesOutput, fmt.Sprintf("%v MHz|%v|%v|%v", cpuUsage, memUsage, humanize.IBytes(uint64(*alloc.Resources.DiskMB*bytesPerMegabyte)), - *resource.IOPS, firstAddr)) for i := 1; i < len(addr); i++ { resourcesOutput = append(resourcesOutput, fmt.Sprintf("||||%v", addr[i])) diff --git a/command/node_status.go b/command/node_status.go index f722feda1..085cdfbda 100644 --- a/command/node_status.go +++ b/command/node_status.go @@ -9,11 +9,10 @@ import ( "time" humanize "github.com/dustin/go-humanize" - "github.com/posener/complete" - "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/api/contexts" "github.com/hashicorp/nomad/helper" + "github.com/posener/complete" ) const ( @@ -611,25 +610,22 @@ func getAllocatedResources(client *api.Client, runningAllocs []*api.Allocation, total := computeNodeTotalResources(node) // Get Resources - var cpu, mem, disk, iops int + var cpu, mem, disk int for _, alloc := range runningAllocs { cpu += *alloc.Resources.CPU mem += *alloc.Resources.MemoryMB disk += *alloc.Resources.DiskMB - iops += *alloc.Resources.IOPS } resources := make([]string, 2) - resources[0] = "CPU|Memory|Disk|IOPS" - resources[1] = fmt.Sprintf("%d/%d MHz|%s/%s|%s/%s|%d/%d", + resources[0] = "CPU|Memory|Disk" + resources[1] = fmt.Sprintf("%d/%d MHz|%s/%s|%s/%s", cpu, *total.CPU, humanize.IBytes(uint64(mem*bytesPerMegabyte)), humanize.IBytes(uint64(*total.MemoryMB*bytesPerMegabyte)), humanize.IBytes(uint64(disk*bytesPerMegabyte)), - humanize.IBytes(uint64(*total.DiskMB*bytesPerMegabyte)), - iops, - *total.IOPS) + humanize.IBytes(uint64(*total.DiskMB*bytesPerMegabyte))) return resources } @@ -647,7 +643,6 @@ func computeNodeTotalResources(node *api.Node) api.Resources { total.CPU = helper.IntToPtr(*r.CPU - *res.CPU) total.MemoryMB = helper.IntToPtr(*r.MemoryMB - *res.MemoryMB) total.DiskMB = helper.IntToPtr(*r.DiskMB - *res.DiskMB) - total.IOPS = helper.IntToPtr(*r.IOPS - *res.IOPS) return total } diff --git a/drivers/shared/executor/executor.go b/drivers/shared/executor/executor.go index 7239fd577..85cd4cac4 100644 --- a/drivers/shared/executor/executor.go +++ b/drivers/shared/executor/executor.go @@ -14,16 +14,14 @@ import ( "time" "github.com/armon/circbuf" + "github.com/hashicorp/consul-template/signals" hclog "github.com/hashicorp/go-hclog" multierror "github.com/hashicorp/go-multierror" - "github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/lib/fifo" "github.com/hashicorp/nomad/client/stats" - shelpers "github.com/hashicorp/nomad/helper/stats" - - "github.com/hashicorp/consul-template/signals" cstructs "github.com/hashicorp/nomad/client/structs" + shelpers "github.com/hashicorp/nomad/helper/stats" ) const ( @@ -83,7 +81,6 @@ type Resources struct { CPU int MemoryMB int DiskMB int - IOPS int } // ExecCommand holds the user command, args, and other isolation related diff --git a/drivers/shared/executor/executor_linux.go b/drivers/shared/executor/executor_linux.go index 989cea353..684e088de 100644 --- a/drivers/shared/executor/executor_linux.go +++ b/drivers/shared/executor/executor_linux.go @@ -26,7 +26,6 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" cgroupFs "github.com/opencontainers/runc/libcontainer/cgroups/fs" lconfigs "github.com/opencontainers/runc/libcontainer/configs" - "github.com/syndtr/gocapability/capability" ) @@ -555,14 +554,6 @@ func configureCgroups(cfg *lconfigs.Config, command *ExecCommand) error { // Set the relative CPU shares for this cgroup. cfg.Cgroups.Resources.CpuShares = uint64(command.Resources.CPU) - if command.Resources.IOPS != 0 { - // Validate it is in an acceptable range. - if command.Resources.IOPS < 10 || command.Resources.IOPS > 1000 { - return fmt.Errorf("resources.IOPS must be between 10 and 1000: %d", command.Resources.IOPS) - } - - cfg.Cgroups.Resources.BlkioWeight = uint16(command.Resources.IOPS) - } return nil } diff --git a/drivers/shared/executor/executor_linux_test.go b/drivers/shared/executor/executor_linux_test.go index de7bf54f4..90daa0fd0 100644 --- a/drivers/shared/executor/executor_linux_test.go +++ b/drivers/shared/executor/executor_linux_test.go @@ -67,7 +67,6 @@ func testExecutorCommandWithChroot(t *testing.T) (*ExecCommand, *allocdir.AllocD Resources: &Resources{ CPU: task.Resources.CPU, MemoryMB: task.Resources.MemoryMB, - IOPS: task.Resources.IOPS, DiskMB: task.Resources.DiskMB, }, } diff --git a/drivers/shared/executor/executor_test.go b/drivers/shared/executor/executor_test.go index 05ab48938..9ef5d4fb5 100644 --- a/drivers/shared/executor/executor_test.go +++ b/drivers/shared/executor/executor_test.go @@ -11,14 +11,13 @@ import ( "testing" "time" - tu "github.com/hashicorp/nomad/testutil" - hclog "github.com/hashicorp/go-hclog" "github.com/hashicorp/nomad/client/allocdir" cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/client/taskenv" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/mock" + tu "github.com/hashicorp/nomad/testutil" "github.com/stretchr/testify/require" ) @@ -54,7 +53,6 @@ func testExecutorCommand(t *testing.T) (*ExecCommand, *allocdir.AllocDir) { Resources: &Resources{ CPU: task.Resources.CPU, MemoryMB: task.Resources.MemoryMB, - IOPS: task.Resources.IOPS, DiskMB: task.Resources.DiskMB, }, } diff --git a/jobspec/parse.go b/jobspec/parse.go index 71f4faa42..c88df2d87 100644 --- a/jobspec/parse.go +++ b/jobspec/parse.go @@ -1411,7 +1411,7 @@ func parseResources(result *api.Resources, list *ast.ObjectList) error { // Check for invalid keys valid := []string{ "cpu", - "iops", + "iops", // COMPAT(0.10): Remove after one release to allow it to be removed from jobspecs "disk", "memory", "network", diff --git a/jobspec/parse_test.go b/jobspec/parse_test.go index cf202338d..babd9738a 100644 --- a/jobspec/parse_test.go +++ b/jobspec/parse_test.go @@ -7,12 +7,11 @@ import ( "testing" "time" + capi "github.com/hashicorp/consul/api" "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/nomad/structs" "github.com/kr/pretty" - - capi "github.com/hashicorp/consul/api" ) func TestParse(t *testing.T) { @@ -317,7 +316,6 @@ func TestParse(t *testing.T) { Resources: &api.Resources{ CPU: helper.IntToPtr(500), MemoryMB: helper.IntToPtr(128), - IOPS: helper.IntToPtr(30), }, Constraints: []*api.Constraint{ { diff --git a/jobspec/test-fixtures/basic.hcl b/jobspec/test-fixtures/basic.hcl index c42e7fcbc..553986bb8 100644 --- a/jobspec/test-fixtures/basic.hcl +++ b/jobspec/test-fixtures/basic.hcl @@ -270,7 +270,6 @@ job "binstore-storagelocker" { resources { cpu = 500 memory = 128 - iops = 30 } constraint { diff --git a/jobspec/test-fixtures/basic_wrong_key.hcl b/jobspec/test-fixtures/basic_wrong_key.hcl index 3a36c80ab..df555e031 100644 --- a/jobspec/test-fixtures/basic_wrong_key.hcl +++ b/jobspec/test-fixtures/basic_wrong_key.hcl @@ -115,7 +115,6 @@ job "binstore-storagelocker" { resources { cpu = 500 memory = 128 - iops = 30 } constraint { diff --git a/nomad/mock/mock.go b/nomad/mock/mock.go index 017efb584..d3ccda145 100644 --- a/nomad/mock/mock.go +++ b/nomad/mock/mock.go @@ -28,7 +28,6 @@ func Node() *structs.Node { CPU: 4000, MemoryMB: 8192, DiskMB: 100 * 1024, - IOPS: 150, }, Reserved: &structs.Resources{ CPU: 100, diff --git a/nomad/structs/diff_test.go b/nomad/structs/diff_test.go index 9dc41f10b..4b18f4a1e 100644 --- a/nomad/structs/diff_test.go +++ b/nomad/structs/diff_test.go @@ -3178,7 +3178,6 @@ func TestTaskDiff(t *testing.T) { CPU: 100, MemoryMB: 100, DiskMB: 100, - IOPS: 100, }, }, New: &Task{ @@ -3186,7 +3185,6 @@ func TestTaskDiff(t *testing.T) { CPU: 200, MemoryMB: 200, DiskMB: 200, - IOPS: 200, }, }, Expected: &TaskDiff{ @@ -3208,12 +3206,6 @@ func TestTaskDiff(t *testing.T) { Old: "100", New: "200", }, - { - Type: DiffTypeEdited, - Name: "IOPS", - Old: "100", - New: "200", - }, { Type: DiffTypeEdited, Name: "MemoryMB", @@ -3233,7 +3225,6 @@ func TestTaskDiff(t *testing.T) { CPU: 100, MemoryMB: 100, DiskMB: 100, - IOPS: 100, }, }, New: &Task{ @@ -3241,7 +3232,6 @@ func TestTaskDiff(t *testing.T) { CPU: 200, MemoryMB: 100, DiskMB: 200, - IOPS: 100, }, }, Expected: &TaskDiff{ @@ -3263,12 +3253,6 @@ func TestTaskDiff(t *testing.T) { Old: "100", New: "200", }, - { - Type: DiffTypeNone, - Name: "IOPS", - Old: "100", - New: "100", - }, { Type: DiffTypeNone, Name: "MemoryMB", @@ -3534,7 +3518,6 @@ func TestTaskDiff(t *testing.T) { CPU: 100, MemoryMB: 100, DiskMB: 100, - IOPS: 100, Devices: []*RequestedDevice{ { Name: "foo", @@ -3556,7 +3539,6 @@ func TestTaskDiff(t *testing.T) { CPU: 100, MemoryMB: 100, DiskMB: 100, - IOPS: 100, Devices: []*RequestedDevice{ { Name: "foo", @@ -3592,12 +3574,6 @@ func TestTaskDiff(t *testing.T) { Old: "100", New: "100", }, - { - Type: DiffTypeNone, - Name: "IOPS", - Old: "100", - New: "100", - }, { Type: DiffTypeNone, Name: "MemoryMB", diff --git a/nomad/structs/funcs_test.go b/nomad/structs/funcs_test.go index 1408c49f0..d29c8e178 100644 --- a/nomad/structs/funcs_test.go +++ b/nomad/structs/funcs_test.go @@ -143,7 +143,6 @@ func TestAllocsFit_Old(t *testing.T) { CPU: 2000, MemoryMB: 2048, DiskMB: 10000, - IOPS: 100, Networks: []*NetworkResource{ { Device: "eth0", @@ -156,7 +155,6 @@ func TestAllocsFit_Old(t *testing.T) { CPU: 1000, MemoryMB: 1024, DiskMB: 5000, - IOPS: 50, Networks: []*NetworkResource{ { Device: "eth0", @@ -173,7 +171,6 @@ func TestAllocsFit_Old(t *testing.T) { CPU: 1000, MemoryMB: 1024, DiskMB: 5000, - IOPS: 50, Networks: []*NetworkResource{ { Device: "eth0", @@ -213,20 +210,6 @@ func TestAllocsFit_TerminalAlloc_Old(t *testing.T) { CPU: 2000, MemoryMB: 2048, DiskMB: 10000, - IOPS: 100, - Networks: []*NetworkResource{ - { - Device: "eth0", - CIDR: "10.0.0.0/8", - MBits: 100, - }, - }, - }, - Reserved: &Resources{ - CPU: 1000, - MemoryMB: 1024, - DiskMB: 5000, - IOPS: 50, Networks: []*NetworkResource{ { Device: "eth0", @@ -243,7 +226,6 @@ func TestAllocsFit_TerminalAlloc_Old(t *testing.T) { CPU: 1000, MemoryMB: 1024, DiskMB: 5000, - IOPS: 50, Networks: []*NetworkResource{ { Device: "eth0", diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 09daf9895..922ae84ad 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -1698,7 +1698,6 @@ type Resources struct { CPU int MemoryMB int DiskMB int - IOPS int Networks Networks Devices []*RequestedDevice } @@ -1715,7 +1714,6 @@ func DefaultResources() *Resources { return &Resources{ CPU: 100, MemoryMB: 300, - IOPS: 0, } } @@ -1728,7 +1726,6 @@ func MinResources() *Resources { return &Resources{ CPU: 20, MemoryMB: 10, - IOPS: 0, } } @@ -1768,9 +1765,6 @@ func (r *Resources) Merge(other *Resources) { if other.DiskMB != 0 { r.DiskMB = other.DiskMB } - if other.IOPS != 0 { - r.IOPS = other.IOPS - } if len(other.Networks) != 0 { r.Networks = other.Networks } @@ -1806,9 +1800,6 @@ func (r *Resources) MeetsMinResources() error { if r.MemoryMB < minResources.MemoryMB { mErr.Errors = append(mErr.Errors, fmt.Errorf("minimum MemoryMB value is %d; got %d", minResources.MemoryMB, r.MemoryMB)) } - if r.IOPS < minResources.IOPS { - mErr.Errors = append(mErr.Errors, fmt.Errorf("minimum IOPS value is %d; got %d", minResources.IOPS, r.IOPS)) - } for i, n := range r.Networks { if err := n.MeetsMinResources(); err != nil { mErr.Errors = append(mErr.Errors, fmt.Errorf("network resource at index %d failed: %v", i, err)) @@ -1865,9 +1856,6 @@ func (r *Resources) Superset(other *Resources) (bool, string) { if r.DiskMB < other.DiskMB { return false, "disk" } - if r.IOPS < other.IOPS { - return false, "iops" - } return true, "" } @@ -1880,7 +1868,6 @@ func (r *Resources) Add(delta *Resources) error { r.CPU += delta.CPU r.MemoryMB += delta.MemoryMB r.DiskMB += delta.DiskMB - r.IOPS += delta.IOPS for _, n := range delta.Networks { // Find the matching interface by IP or CIDR diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index ea5258b42..2669f9399 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -800,7 +800,6 @@ func TestTask_Validate(t *testing.T) { Resources: &Resources{ CPU: 100, MemoryMB: 100, - IOPS: 10, }, LogConfig: DefaultLogConfig(), } @@ -874,7 +873,6 @@ func TestTask_Validate_Services(t *testing.T) { Resources: &Resources{ CPU: 100, MemoryMB: 100, - IOPS: 10, }, Services: []*Service{s1, s2}, } @@ -1752,13 +1750,11 @@ func TestResource_Superset(t *testing.T) { CPU: 2000, MemoryMB: 2048, DiskMB: 10000, - IOPS: 100, } r2 := &Resources{ CPU: 2000, MemoryMB: 1024, DiskMB: 5000, - IOPS: 50, } if s, _ := r1.Superset(r1); !s { @@ -1780,7 +1776,6 @@ func TestResource_Add(t *testing.T) { CPU: 2000, MemoryMB: 2048, DiskMB: 10000, - IOPS: 100, Networks: []*NetworkResource{ { CIDR: "10.0.0.0/8", @@ -1793,7 +1788,6 @@ func TestResource_Add(t *testing.T) { CPU: 2000, MemoryMB: 1024, DiskMB: 5000, - IOPS: 50, Networks: []*NetworkResource{ { IP: "10.0.0.1", @@ -1812,7 +1806,6 @@ func TestResource_Add(t *testing.T) { CPU: 3000, MemoryMB: 3072, DiskMB: 15000, - IOPS: 150, Networks: []*NetworkResource{ { CIDR: "10.0.0.0/8", @@ -3973,7 +3966,6 @@ func TestNode_Copy(t *testing.T) { CPU: 4000, MemoryMB: 8192, DiskMB: 100 * 1024, - IOPS: 150, Networks: []*NetworkResource{ { Device: "eth0", diff --git a/plugins/drivers/proto/driver.proto b/plugins/drivers/proto/driver.proto index 5abc10a42..a24ebb0b9 100644 --- a/plugins/drivers/proto/driver.proto +++ b/plugins/drivers/proto/driver.proto @@ -356,7 +356,6 @@ message RawResources { int64 cpu = 1; int64 memory = 2; int64 disk = 3; - int64 iops = 4; repeated NetworkResource networks = 5; } diff --git a/plugins/drivers/utils.go b/plugins/drivers/utils.go index 090ff014a..60b9ca0b4 100644 --- a/plugins/drivers/utils.go +++ b/plugins/drivers/utils.go @@ -100,7 +100,6 @@ func resourcesFromProto(pb *proto.Resources) *Resources { r.NomadResources = &structs.Resources{ CPU: int(pb.RawResources.Cpu), MemoryMB: int(pb.RawResources.Memory), - IOPS: int(pb.RawResources.Iops), DiskMB: int(pb.RawResources.Disk), } @@ -151,7 +150,6 @@ func resourcesToProto(r *Resources) *proto.Resources { pb.RawResources = &proto.RawResources{ Cpu: int64(r.NomadResources.CPU), Memory: int64(r.NomadResources.MemoryMB), - Iops: int64(r.NomadResources.IOPS), Disk: int64(r.NomadResources.DiskMB), Networks: make([]*proto.NetworkResource, len(r.NomadResources.Networks)), } diff --git a/scheduler/annotate_test.go b/scheduler/annotate_test.go index 54e90d7c5..57c95ce6e 100644 --- a/scheduler/annotate_test.go +++ b/scheduler/annotate_test.go @@ -228,12 +228,6 @@ func TestAnnotateTask(t *testing.T) { Old: "100", New: "200", }, - { - Type: structs.DiffTypeEdited, - Name: "IOPS", - Old: "100", - New: "200", - }, { Type: structs.DiffTypeEdited, Name: "MemoryMB", diff --git a/scheduler/preemption_test.go b/scheduler/preemption_test.go index f2d83f1f4..d4938eca4 100644 --- a/scheduler/preemption_test.go +++ b/scheduler/preemption_test.go @@ -201,7 +201,6 @@ func TestPreemption(t *testing.T) { CPU: 3200, MemoryMB: 7256, DiskMB: 4 * 1024, - IOPS: 150, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -234,7 +233,6 @@ func TestPreemption(t *testing.T) { CPU: 3200, MemoryMB: 7256, DiskMB: 4 * 1024, - IOPS: 150, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -250,7 +248,6 @@ func TestPreemption(t *testing.T) { CPU: 4000, MemoryMB: 8192, DiskMB: 4 * 1024, - IOPS: 300, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -268,7 +265,6 @@ func TestPreemption(t *testing.T) { CPU: 1200, MemoryMB: 2256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -281,7 +277,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -326,7 +321,6 @@ func TestPreemption(t *testing.T) { CPU: 1200, MemoryMB: 2256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -339,7 +333,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth1", @@ -358,7 +351,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -488,7 +480,6 @@ func TestPreemption(t *testing.T) { CPU: 2800, MemoryMB: 2256, DiskMB: 40 * 1024, - IOPS: 100, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -501,7 +492,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -608,7 +598,6 @@ func TestPreemption(t *testing.T) { CPU: 1200, MemoryMB: 2256, DiskMB: 4 * 1024, - IOPS: 150, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -621,7 +610,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -640,7 +628,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -683,7 +670,6 @@ func TestPreemption(t *testing.T) { CPU: 1200, MemoryMB: 2256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -696,7 +682,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -715,7 +700,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -757,7 +741,6 @@ func TestPreemption(t *testing.T) { CPU: 1200, MemoryMB: 2256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -770,7 +753,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 10, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -783,7 +765,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 10, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -813,7 +794,6 @@ func TestPreemption(t *testing.T) { CPU: 200, MemoryMB: 256, DiskMB: 4 * 1024, - IOPS: 10, Networks: []*structs.NetworkResource{ { Device: "eth0", @@ -836,7 +816,6 @@ func TestPreemption(t *testing.T) { CPU: 1800, MemoryMB: 2256, DiskMB: 4 * 1024, - IOPS: 50, Networks: []*structs.NetworkResource{ { Device: "eth0", diff --git a/scheduler/system_sched_test.go b/scheduler/system_sched_test.go index 27d99b205..9461fd85e 100644 --- a/scheduler/system_sched_test.go +++ b/scheduler/system_sched_test.go @@ -1,13 +1,12 @@ package scheduler import ( + "fmt" "reflect" "sort" "testing" "time" - "fmt" - memdb "github.com/hashicorp/go-memdb" "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/helper/uuid" @@ -1568,7 +1567,6 @@ func TestSystemSched_Preemption(t *testing.T) { CPU: 3072, MemoryMB: 5034, DiskMB: 20 * 1024, - IOPS: 150, Networks: []*structs.NetworkResource{ { Device: "eth0", diff --git a/scheduler/util.go b/scheduler/util.go index 85a93298f..c97005381 100644 --- a/scheduler/util.go +++ b/scheduler/util.go @@ -409,8 +409,6 @@ func tasksUpdated(jobA, jobB *structs.Job, taskGroup string) bool { return true } else if ar.MemoryMB != br.MemoryMB { return true - } else if ar.IOPS != br.IOPS { - return true } } return false diff --git a/website/source/api/agent.html.md b/website/source/api/agent.html.md index 5b0d17cb2..4ff04e1cb 100644 --- a/website/source/api/agent.html.md +++ b/website/source/api/agent.html.md @@ -194,7 +194,6 @@ $ curl \ "Reserved": { "CPU": 0, "DiskMB": 0, - "IOPS": 0, "MemoryMB": 0, "ParsedReservedPorts": null, "ReservedPorts": "" diff --git a/website/source/api/allocations.html.md b/website/source/api/allocations.html.md index e898d1568..46c7b9408 100644 --- a/website/source/api/allocations.html.md +++ b/website/source/api/allocations.html.md @@ -280,7 +280,6 @@ $ curl \ "CPU": 500, "MemoryMB": 10, "DiskMB": 0, - "IOPS": 0, "Networks": [ { "Device": "", @@ -336,7 +335,6 @@ $ curl \ "CPU": 500, "MemoryMB": 10, "DiskMB": 300, - "IOPS": 0, "Networks": [ { "Device": "lo0", @@ -357,7 +355,6 @@ $ curl \ "CPU": 0, "MemoryMB": 0, "DiskMB": 300, - "IOPS": 0, "Networks": null }, "TaskResources": { @@ -365,7 +362,6 @@ $ curl \ "CPU": 500, "MemoryMB": 10, "DiskMB": 0, - "IOPS": 0, "Networks": [ { "Device": "lo0", diff --git a/website/source/api/jobs.html.md b/website/source/api/jobs.html.md index ac3485d07..f699a434f 100644 --- a/website/source/api/jobs.html.md +++ b/website/source/api/jobs.html.md @@ -443,7 +443,6 @@ $ curl \ "CPU": 500, "MemoryMB": 256, "DiskMB": 0, - "IOPS": 0, "Networks": [ { "Device": "", @@ -647,7 +646,6 @@ $ curl \ "CPU": 500, "MemoryMB": 256, "DiskMB": 0, - "IOPS": 0, "Networks": [ { "Device": "", diff --git a/website/source/api/json-jobs.html.md b/website/source/api/json-jobs.html.md index dc2477762..208ae670f 100644 --- a/website/source/api/json-jobs.html.md +++ b/website/source/api/json-jobs.html.md @@ -512,8 +512,6 @@ The `Resources` object supports the following keys: - `CPU` - The CPU required in MHz. -- `IOPS` - The number of IOPS required given as a weight between 10-1000. - - `MemoryMB` - The memory required in MB. - `Networks` - A list of network objects. diff --git a/website/source/api/nodes.html.md b/website/source/api/nodes.html.md index 5dbd59e08..b0cf053e6 100644 --- a/website/source/api/nodes.html.md +++ b/website/source/api/nodes.html.md @@ -274,14 +274,12 @@ $ curl \ "Reserved": { "CPU": 0, "DiskMB": 0, - "IOPS": 0, "MemoryMB": 0, "Networks": null }, "Resources": { "CPU": 2200, "DiskMB": 25392, - "IOPS": 0, "MemoryMB": 3704, "Networks": [ { @@ -443,7 +441,6 @@ $ curl \ "Resources": { "CPU": 100, "DiskMB": 0, - "IOPS": 0, "MemoryMB": 300, "Networks": [ { @@ -541,7 +538,6 @@ $ curl \ "Resources": { "CPU": 100, "DiskMB": 300, - "IOPS": 0, "MemoryMB": 300, "Networks": [ { @@ -562,7 +558,6 @@ $ curl \ "SharedResources": { "CPU": 0, "DiskMB": 300, - "IOPS": 0, "MemoryMB": 0, "Networks": null }, @@ -571,7 +566,6 @@ $ curl \ "webapp": { "CPU": 100, "DiskMB": 0, - "IOPS": 0, "MemoryMB": 300, "Networks": [ { diff --git a/website/source/api/quotas.html.md b/website/source/api/quotas.html.md index 9c94f4e73..ee9590161 100644 --- a/website/source/api/quotas.html.md +++ b/website/source/api/quotas.html.md @@ -61,7 +61,6 @@ $ curl \ "RegionLimit": { "CPU": 2500, "DiskMB": 0, - "IOPS": 0, "MemoryMB": 2000, "Networks": null } @@ -115,7 +114,6 @@ $ curl \ "RegionLimit": { "CPU": 2500, "DiskMB": 0, - "IOPS": 0, "MemoryMB": 2000, "Networks": null } @@ -256,7 +254,6 @@ $ curl \ "CPU": 500, "MemoryMB": 256, "DiskMB": 0, - "IOPS": 0, "Networks": null }, "Hash": "NLOoV2WBU8ieJIrYXXx8NRb5C2xU61pVVWRDLEIMxlU=" @@ -308,7 +305,6 @@ $ curl \ "CPU": 500, "MemoryMB": 256, "DiskMB": 0, - "IOPS": 0, "Networks": null }, "Hash": "NLOoV2WBU8ieJIrYXXx8NRb5C2xU61pVVWRDLEIMxlU=" diff --git a/website/source/docs/commands/alloc/status.html.md.erb b/website/source/docs/commands/alloc/status.html.md.erb index b7e17d181..6432d96ba 100644 --- a/website/source/docs/commands/alloc/status.html.md.erb +++ b/website/source/docs/commands/alloc/status.html.md.erb @@ -85,8 +85,8 @@ Reschedule Attempts = 1/3 Task "redis" is "running" Task Resources -CPU Memory Disk IOPS Addresses -1/500 MHz 6.3 MiB/256 MiB 300 MiB 0 db: 127.0.0.1:27908 +CPU Memory Disk Addresses +1/500 MHz 6.3 MiB/256 MiB 300 MiB db: 127.0.0.1:27908 Task Events: Started At = 07/25/17 16:12:48 UTC @@ -102,8 +102,8 @@ Time Type Description Task "web" is "running" Task Resources -CPU Memory Disk IOPS Addresses -1/500 MHz 6.3 MiB/256 MiB 300 MiB 0 db: 127.0.0.1:30572 +CPU Memory Disk Addresses +1/500 MHz 6.3 MiB/256 MiB 300 MiB db: 127.0.0.1:30572 Task Events: Started At = 07/25/17 16:12:49 UTC @@ -144,8 +144,8 @@ Failures = 0 Task "redis" is "running" Task Resources -CPU Memory Disk IOPS Addresses -1/500 MHz 6.3 MiB/256 MiB 300 MiB 0 db: 127.0.0.1:27908 +CPU Memory Disk Addresses +1/500 MHz 6.3 MiB/256 MiB 300 MiB db: 127.0.0.1:27908 Task Events: Started At = 07/25/17 16:12:48 UTC @@ -161,8 +161,8 @@ Time Type Description Task "web" is "running" Task Resources -CPU Memory Disk IOPS Addresses -1/500 MHz 6.3 MiB/256 MiB 300 MiB 0 db: 127.0.0.1:30572 +CPU Memory Disk Addresses +1/500 MHz 6.3 MiB/256 MiB 300 MiB db: 127.0.0.1:30572 Task Events: Started At = 07/25/17 16:12:49 UTC diff --git a/website/source/docs/commands/job/history.html.md.erb b/website/source/docs/commands/job/history.html.md.erb index da5cd8a54..1ff827d21 100644 --- a/website/source/docs/commands/job/history.html.md.erb +++ b/website/source/docs/commands/job/history.html.md.erb @@ -54,7 +54,6 @@ Diff = +/- Resources { CPU: "500" DiskMB: "0" - IOPS: "0" +/- MemoryMB: "256" => "512" } diff --git a/website/source/docs/commands/job/inspect.html.md.erb b/website/source/docs/commands/job/inspect.html.md.erb index 485dc2386..abe842e44 100644 --- a/website/source/docs/commands/job/inspect.html.md.erb +++ b/website/source/docs/commands/job/inspect.html.md.erb @@ -106,7 +106,6 @@ $ nomad job inspect redis "CPU": 500, "MemoryMB": 256, "DiskMB": 300, - "IOPS": 0, "Networks": [ { "Public": false, diff --git a/website/source/docs/commands/job/plan.html.md.erb b/website/source/docs/commands/job/plan.html.md.erb index ce6c0caf9..6b157dc47 100644 --- a/website/source/docs/commands/job/plan.html.md.erb +++ b/website/source/docs/commands/job/plan.html.md.erb @@ -160,7 +160,6 @@ $ nomad job plan -verbose example.nomad + Resources { + CPU: "500" + DiskMB: "300" - + IOPS: "0" + MemoryMB: "256" + Network { + MBits: "10" diff --git a/website/source/docs/commands/node/status.html.md.erb b/website/source/docs/commands/node/status.html.md.erb index cd6d1e2c8..888cd72ed 100644 --- a/website/source/docs/commands/node/status.html.md.erb +++ b/website/source/docs/commands/node/status.html.md.erb @@ -114,8 +114,8 @@ Time Subsystem Message 2018-03-29T17:23:42Z Cluster Node registered Allocated Resources -CPU Memory Disk IOPS -500/2600 MHz 256 MiB/2.0 GiB 300 MiB/32 GiB 0/0 +CPU Memory Disk +500/2600 MHz 256 MiB/2.0 GiB 300 MiB/32 GiB Allocation Resource Utilization CPU Memory @@ -157,8 +157,8 @@ Time Subsystem Message 2018-03-29T17:23:42Z Cluster Node registered Allocated Resources -CPU Memory Disk IOPS -2500/2600 MHz 1.3 GiB/2.0 GiB 1.5 GiB/32 GiB 0/0 +CPU Memory Disk +2500/2600 MHz 1.3 GiB/2.0 GiB 1.5 GiB/32 GiB Allocation Resource Utilization CPU Memory @@ -222,8 +222,8 @@ Time Subsystem Message 2018-03-29T17:23:42Z Cluster Node registered Allocated Resources -CPU Memory Disk IOPS -2500/2600 MHz 1.3 GiB/2.0 GiB 1.5 GiB/32 GiB 0/0 +CPU Memory Disk +2500/2600 MHz 1.3 GiB/2.0 GiB 1.5 GiB/32 GiB Allocation Resource Utilization CPU Memory @@ -303,8 +303,8 @@ Time Subsystem Message Details 2018-03-29T17:23:42Z Cluster Node registered Allocated Resources -CPU Memory Disk IOPS -2500/2600 MHz 1.3 GiB/2.0 GiB 1.5 GiB/32 GiB 0/0 +CPU Memory Disk +2500/2600 MHz 1.3 GiB/2.0 GiB 1.5 GiB/32 GiB Allocation Resource Utilization CPU Memory diff --git a/website/source/docs/commands/quota/inspect.html.md.erb b/website/source/docs/commands/quota/inspect.html.md.erb index 5ed911e38..5487c5136 100644 --- a/website/source/docs/commands/quota/inspect.html.md.erb +++ b/website/source/docs/commands/quota/inspect.html.md.erb @@ -46,7 +46,6 @@ $ nomad quota inspect default-quota "RegionLimit": { "CPU": 2500, "DiskMB": 0, - "IOPS": 0, "MemoryMB": 2000, "Networks": null } @@ -68,7 +67,6 @@ $ nomad quota inspect default-quota "RegionLimit": { "CPU": 500, "DiskMB": 0, - "IOPS": 0, "MemoryMB": 256, "Networks": null } diff --git a/website/source/docs/commands/status.html.md.erb b/website/source/docs/commands/status.html.md.erb index 001ae0a3d..7ff6601ff 100644 --- a/website/source/docs/commands/status.html.md.erb +++ b/website/source/docs/commands/status.html.md.erb @@ -81,8 +81,8 @@ Deployment Health = healthy Task "redis" is "running" Task Resources -CPU Memory Disk IOPS Addresses -4/500 MHz 6.3 MiB/256 MiB 300 MiB 0 db: 127.0.0.1:21752 +CPU Memory Disk Addresses +4/500 MHz 6.3 MiB/256 MiB 300 MiB db: 127.0.0.1:21752 Task Events: Started At = 08/28/17 23:01:39 UTC @@ -126,8 +126,8 @@ Drivers = docker,exec,java,qemu,raw_exec,rkt Uptime = 4h17m24s Allocated Resources -CPU Memory Disk IOPS -500/8709 MHz 256 MiB/2.0 GiB 300 MiB/24 GiB 0/0 +CPU Memory Disk +500/8709 MHz 256 MiB/2.0 GiB 300 MiB/24 GiB Allocation Resource Utilization CPU Memory diff --git a/website/source/docs/job-specification/resources.html.md b/website/source/docs/job-specification/resources.html.md index cbc03bfee..f4733737b 100644 --- a/website/source/docs/job-specification/resources.html.md +++ b/website/source/docs/job-specification/resources.html.md @@ -46,9 +46,6 @@ job "docs" { - `cpu` `(int: 100)` - Specifies the CPU required to run this task in MHz. -- `iops` `(int: 0)` - Specifies the number of IOPS required given as a weight - between 0-1000. - - `memory` `(int: 300)` - Specifies the memory required in MB - `network` ([Network][]: ) - Specifies the network diff --git a/website/source/docs/telemetry/index.html.md b/website/source/docs/telemetry/index.html.md index 35fe122cb..e51f21e10 100644 --- a/website/source/docs/telemetry/index.html.md +++ b/website/source/docs/telemetry/index.html.md @@ -316,20 +316,6 @@ Starting in version 0.7, Nomad will emit tagged metrics, in the below format: Gauge node_id, datacenter - - `nomad.client.allocated.iops` - Total amount of IOPS the scheduler has allocated to tasks - IOPS - Gauge - node_id, datacenter - - - `nomad.client.unallocated.iops` - Total amount of IOPS free for the scheduler to allocate to tasks - IOPS - Gauge - node_id, datacenter - `nomad.client.allocated.network` Total amount of bandwidth the scheduler has allocated to tasks on the @@ -541,18 +527,6 @@ detailed above) but any new metrics will only be available in the new format. Megabytes Gauge - - `nomad.client.allocated.iops.` - Total amount of IOPS the scheduler has allocated to tasks - IOPS - Gauge - - - `nomad.client.unallocated.iops.` - Total amount of IOPS free for the scheduler to allocate to tasks - IOPS - Gauge - `nomad.client.allocated.network..` Total amount of bandwidth the scheduler has allocated to tasks on the diff --git a/website/source/guides/operating-a-job/failure-handling-strategies/check-restart.html.md b/website/source/guides/operating-a-job/failure-handling-strategies/check-restart.html.md index b236e21b4..207426b49 100644 --- a/website/source/guides/operating-a-job/failure-handling-strategies/check-restart.html.md +++ b/website/source/guides/operating-a-job/failure-handling-strategies/check-restart.html.md @@ -53,8 +53,8 @@ Modified = 39s ago Task "test" is "dead" Task Resources -CPU Memory Disk IOPS Addresses -100 MHz 300 MiB 300 MiB 0 p1: 127.0.0.1:28422 +CPU Memory Disk Addresses +100 MHz 300 MiB 300 MiB p1: 127.0.0.1:28422 Task Events: Started At = 2018-04-12T22:50:32Z @@ -76,4 +76,4 @@ Time Type Description 2018-04-12T17:49:53-05:00 Started Task started by client ``` -[check restart]: /docs/job-specification/check_restart.html "Nomad check restart Stanza" \ No newline at end of file +[check restart]: /docs/job-specification/check_restart.html "Nomad check restart Stanza" diff --git a/website/source/guides/operating-a-job/failure-handling-strategies/reschedule.html.md b/website/source/guides/operating-a-job/failure-handling-strategies/reschedule.html.md index d26389de5..4f926ef7e 100644 --- a/website/source/guides/operating-a-job/failure-handling-strategies/reschedule.html.md +++ b/website/source/guides/operating-a-job/failure-handling-strategies/reschedule.html.md @@ -70,8 +70,8 @@ Reschedule Eligibility = 25s from now Task "demo" is "dead" Task Resources -CPU Memory Disk IOPS Addresses -100 MHz 300 MiB 300 MiB 0 p1: 127.0.0.1:27646 +CPU Memory Disk Addresses +100 MHz 300 MiB 300 MiB p1: 127.0.0.1:27646 Task Events: Started At = 2018-04-12T20:44:25Z @@ -89,4 +89,4 @@ Time Type Description ``` -[reschedule]: /docs/job-specification/reschedule.html "Nomad reschedule Stanza" \ No newline at end of file +[reschedule]: /docs/job-specification/reschedule.html "Nomad reschedule Stanza" diff --git a/website/source/guides/operating-a-job/failure-handling-strategies/restart.html.md b/website/source/guides/operating-a-job/failure-handling-strategies/restart.html.md index 4d6fb202f..f8ca558d8 100644 --- a/website/source/guides/operating-a-job/failure-handling-strategies/restart.html.md +++ b/website/source/guides/operating-a-job/failure-handling-strategies/restart.html.md @@ -68,8 +68,8 @@ Modified = 22s ago Task "demo" is "dead" Task Resources -CPU Memory Disk IOPS Addresses -100 MHz 300 MiB 300 MiB 0 +CPU Memory Disk Addresses +100 MHz 300 MiB 300 MiB Task Events: Started At = 2018-04-12T22:29:08Z diff --git a/website/source/guides/operating-a-job/inspecting-state.html.md b/website/source/guides/operating-a-job/inspecting-state.html.md index 9ea83616c..f53b3b605 100644 --- a/website/source/guides/operating-a-job/inspecting-state.html.md +++ b/website/source/guides/operating-a-job/inspecting-state.html.md @@ -150,8 +150,8 @@ Client Status = running Task "server" is "running" Task Resources -CPU Memory Disk IOPS Addresses -0/100 MHz 728 KiB/10 MiB 300 MiB 0 http: 10.1.1.196:5678 +CPU Memory Disk Addresses +0/100 MHz 728 KiB/10 MiB 300 MiB http: 10.1.1.196:5678 Recent Events: Time Type Description diff --git a/website/source/guides/operating-a-job/resource-utilization.html.md b/website/source/guides/operating-a-job/resource-utilization.html.md index f01491de6..18012ccbb 100644 --- a/website/source/guides/operating-a-job/resource-utilization.html.md +++ b/website/source/guides/operating-a-job/resource-utilization.html.md @@ -45,8 +45,8 @@ Client Status = running Task "server" is "running" Task Resources -CPU Memory Disk IOPS Addresses -75/100 MHz 784 KiB/10 MiB 300 MiB 0 http: 10.1.1.196:5678 +CPU Memory Disk Addresses +75/100 MHz 784 KiB/10 MiB 300 MiB http: 10.1.1.196:5678 Memory Stats Cache Max Usage RSS Swap diff --git a/website/source/intro/getting-started/jobs.html.md b/website/source/intro/getting-started/jobs.html.md index ef50f0a61..c35dbf953 100644 --- a/website/source/intro/getting-started/jobs.html.md +++ b/website/source/intro/getting-started/jobs.html.md @@ -108,8 +108,8 @@ Deployment Health = healthy Task "redis" is "running" Task Resources -CPU Memory Disk IOPS Addresses -8/500 MHz 6.3 MiB/256 MiB 300 MiB 0 db: 127.0.0.1:22672 +CPU Memory Disk Addresses +8/500 MHz 6.3 MiB/256 MiB 300 MiB db: 127.0.0.1:22672 Task Events: Started At = 10/31/17 22:58:49 UTC From f555dc3f67730afc2cbb54aaba70aa80d6118ac8 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Thu, 6 Dec 2018 16:17:09 -0800 Subject: [PATCH 24/71] Warn if IOPS is being used --- command/agent/job_endpoint.go | 1 + nomad/structs/structs.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/command/agent/job_endpoint.go b/command/agent/job_endpoint.go index c34204cc2..8414eac2f 100644 --- a/command/agent/job_endpoint.go +++ b/command/agent/job_endpoint.go @@ -853,6 +853,7 @@ func ApiResourcesToStructs(in *api.Resources) *structs.Resources { out := &structs.Resources{ CPU: *in.CPU, MemoryMB: *in.MemoryMB, + IOPS: *in.IOPS, // COMPAT(0.10): Only being used to issue warnings } if l := len(in.Networks); l != 0 { diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 922ae84ad..3d081cc84 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -1698,6 +1698,7 @@ type Resources struct { CPU int MemoryMB int DiskMB int + IOPS int // COMPAT(0.10): Only being used to issue warnings Networks Networks Devices []*RequestedDevice } @@ -4663,6 +4664,13 @@ func (tg *TaskGroup) Warnings(j *Job) error { } } + for _, t := range tg.Tasks { + if err := t.Warnings(); err != nil { + err = multierror.Prefix(err, fmt.Sprintf("Task %q:", t.Name)) + mErr.Errors = append(mErr.Errors, err) + } + } + return mErr.ErrorOrNil() } @@ -5506,6 +5514,17 @@ func validateServices(t *Task) error { return mErr.ErrorOrNil() } +func (t *Task) Warnings() error { + var mErr multierror.Error + + // Validate the resources + if t.Resources != nil && t.Resources.IOPS != 0 { + mErr.Errors = append(mErr.Errors, fmt.Errorf("IOPS has been deprecated as of Nomad 0.9.0. Please remove IOPS from resource stanza.")) + } + + return mErr.ErrorOrNil() +} + const ( // TemplateChangeModeNoop marks that no action should be taken if the // template is re-rendered From 379e79ceff5e2a44c8d76893d0054ec89212451a Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Wed, 5 Dec 2018 11:33:03 -0500 Subject: [PATCH 25/71] Vendor libcontainer/devices --- .../runc/libcontainer/devices/devices.go | 105 ++++++++++++++++++ vendor/vendor.json | 1 + 2 files changed, 106 insertions(+) create mode 100644 vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go new file mode 100644 index 000000000..5e2ab0581 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go @@ -0,0 +1,105 @@ +package devices + +import ( + "errors" + "io/ioutil" + "os" + "path/filepath" + + "github.com/opencontainers/runc/libcontainer/configs" + + "golang.org/x/sys/unix" +) + +var ( + ErrNotADevice = errors.New("not a device node") +) + +// Testing dependencies +var ( + unixLstat = unix.Lstat + ioutilReadDir = ioutil.ReadDir +) + +// Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct. +func DeviceFromPath(path, permissions string) (*configs.Device, error) { + var stat unix.Stat_t + err := unixLstat(path, &stat) + if err != nil { + return nil, err + } + + var ( + devNumber = uint64(stat.Rdev) + major = unix.Major(devNumber) + minor = unix.Minor(devNumber) + ) + if major == 0 { + return nil, ErrNotADevice + } + + var ( + devType rune + mode = stat.Mode + ) + switch { + case mode&unix.S_IFBLK == unix.S_IFBLK: + devType = 'b' + case mode&unix.S_IFCHR == unix.S_IFCHR: + devType = 'c' + } + return &configs.Device{ + Type: devType, + Path: path, + Major: int64(major), + Minor: int64(minor), + Permissions: permissions, + FileMode: os.FileMode(mode), + Uid: stat.Uid, + Gid: stat.Gid, + }, nil +} + +func HostDevices() ([]*configs.Device, error) { + return getDevices("/dev") +} + +func getDevices(path string) ([]*configs.Device, error) { + files, err := ioutilReadDir(path) + if err != nil { + return nil, err + } + out := []*configs.Device{} + for _, f := range files { + switch { + case f.IsDir(): + switch f.Name() { + // ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825 + case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts": + continue + default: + sub, err := getDevices(filepath.Join(path, f.Name())) + if err != nil { + return nil, err + } + + out = append(out, sub...) + continue + } + case f.Name() == "console": + continue + } + device, err := DeviceFromPath(filepath.Join(path, f.Name()), "rwm") + if err != nil { + if err == ErrNotADevice { + continue + } + if os.IsNotExist(err) { + continue + } + return nil, err + } + out = append(out, device) + } + return out, nil +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 1063dfcf8..f724f07d8 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -301,6 +301,7 @@ {"path":"github.com/opencontainers/runc/libcontainer/configs","checksumSHA1":"PUv5rdj6oEGJoBij/9Elx8VO6bs=","origin":"github.com/hashicorp/runc/libcontainer/configs","revision":"8df81be073884e4e4c613d893f5877310136820f","revisionTime":"2018-09-10T14:23:11Z","version":"nomad","versionExact":"nomad"}, {"path":"github.com/opencontainers/runc/libcontainer/configs/validate","checksumSHA1":"YJq+f9izqizSzG/OuVFUOfloNEk=","origin":"github.com/hashicorp/runc/libcontainer/configs/validate","revision":"8df81be073884e4e4c613d893f5877310136820f","revisionTime":"2018-09-10T14:23:11Z","version":"nomad","versionExact":"nomad"}, {"path":"github.com/opencontainers/runc/libcontainer/criurpc","checksumSHA1":"I1iwXoDUJeDXviilCtkvDpEF/So=","origin":"github.com/hashicorp/runc/libcontainer/criurpc","revision":"8df81be073884e4e4c613d893f5877310136820f","revisionTime":"2018-09-10T14:23:11Z","version":"nomad","versionExact":"nomad"}, + {"path":"github.com/opencontainers/runc/libcontainer/devices","checksumSHA1":"I1iwXoDUJeDXviilCtkvDpEF/So=","origin":"github.com/hashicorp/runc/libcontainer/devices","revision":"8df81be073884e4e4c613d893f5877310136820f","revisionTime":"2018-09-10T14:23:11Z","version":"nomad","versionExact":"nomad"}, {"path":"github.com/opencontainers/runc/libcontainer/intelrdt","checksumSHA1":"bAWJX1XUDMd4GqPLSrCkUcdiTbg=","origin":"github.com/hashicorp/runc/libcontainer/intelrdt","revision":"459bfaec1fc6c17d8bfb12d0a0f69e7e7271ed2a","revisionTime":"2018-08-23T14:46:37Z","version":"nomad"}, {"path":"github.com/opencontainers/runc/libcontainer/keys","checksumSHA1":"QXuHZwxlqhoq/oHRJFbTi6+AWLY=","origin":"github.com/hashicorp/runc/libcontainer/keys","revision":"459bfaec1fc6c17d8bfb12d0a0f69e7e7271ed2a","revisionTime":"2018-08-23T14:46:37Z","version":"nomad"}, {"path":"github.com/opencontainers/runc/libcontainer/mount","checksumSHA1":"MJiogPDUU2nFr1fzQU6T+Ry1W8o=","origin":"github.com/hashicorp/runc/libcontainer/mount","revision":"459bfaec1fc6c17d8bfb12d0a0f69e7e7271ed2a","revisionTime":"2018-08-23T14:46:37Z","version":"nomad"}, From b91fa87d31655560527d48d9e09415b99999ebca Mon Sep 17 00:00:00 2001 From: Marcin Matlaszek Date: Fri, 7 Dec 2018 18:05:53 +0100 Subject: [PATCH 26/71] Recover from any possible io error when invoking Write on FileRotator As of now, FileRotator uses bufio.Write under the hood to write data to configured output file. Due to the way how bufio handles any occurred io error - saves it into `err` variable never resetting it automatically - any operation like `Write`, `Flush` etc will become a no-op, returning the very same, saved error (eg. Out of disk space) even when the problem is fixed (eg. disk space is available again). That automatically means that FileRotator will stop writing any logs, reporting the same error over and over again, even if it's no longer valid. This PR fixes it by resetting the bufio Writer, which resets any errors and tries to write requested data. --- client/logmon/logging/rotator.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/logmon/logging/rotator.go b/client/logmon/logging/rotator.go index 60b735b95..1288eb15c 100644 --- a/client/logmon/logging/rotator.go +++ b/client/logmon/logging/rotator.go @@ -145,6 +145,12 @@ func (f *FileRotator) Write(p []byte) (n int, err error) { f.currentWr += int64(n) if err != nil { f.logger.Error("error writing to file", "err", err) + + // As bufio writer does not automatically recover in case of any + // io error, we need to recover from it manually resetting the + // writter. + f.createOrResetBuffer() + return } } From 22a4bcd3ca80090decce5459fc3beafd2f56840a Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Fri, 7 Dec 2018 20:11:46 +0000 Subject: [PATCH 27/71] rpc accept loop: added backoff on logging for failed connections, in case there is a fast fail loop (NMD-1173) --- nomad/rpc.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/nomad/rpc.go b/nomad/rpc.go index 7695217f0..e65b73725 100644 --- a/nomad/rpc.go +++ b/nomad/rpc.go @@ -84,6 +84,7 @@ type RPCContext struct { // listen is used to listen for incoming RPC connections func (r *rpcHandler) listen(ctx context.Context) { defer close(r.listenerCh) + var tempDelay time.Duration for { select { case <-ctx.Done(): @@ -105,9 +106,21 @@ func (r *rpcHandler) listen(ctx context.Context) { default: } - r.logger.Error("failed to accept RPC conn", "error", err) + if ne, ok := err.(net.Error); ok && ne.Temporary() { + if tempDelay == 0 { + tempDelay = 5 * time.Millisecond + } else { + tempDelay *= 2 + } + if max := 1 * time.Second; tempDelay > max { + tempDelay = max + } + r.logger.Error("failed to accept RPC conn", "error", err, "delay", tempDelay) + time.Sleep(tempDelay) + } continue } + tempDelay = 0 go r.handleConn(ctx, conn, &RPCContext{Conn: conn}) metrics.IncrCounter([]string{"nomad", "rpc", "accept_conn"}, 1) From 591cdb00a4db8832372f0c3e1c26a0072ccdae8d Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Fri, 7 Dec 2018 22:14:15 +0000 Subject: [PATCH 28/71] nomad/rpc listener: modified to throttle logging on "permanent" Accept() errors as well (with a higher delay cap) --- nomad/rpc.go | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/nomad/rpc.go b/nomad/rpc.go index e65b73725..9edf5df5c 100644 --- a/nomad/rpc.go +++ b/nomad/rpc.go @@ -100,24 +100,20 @@ func (r *rpcHandler) listen(ctx context.Context) { return } - select { - case <-ctx.Done(): - return - default: + if tempDelay == 0 { + tempDelay = 5 * time.Millisecond + } else { + tempDelay *= 2 } - + maxDelay := 5 * time.Second if ne, ok := err.(net.Error); ok && ne.Temporary() { - if tempDelay == 0 { - tempDelay = 5 * time.Millisecond - } else { - tempDelay *= 2 - } - if max := 1 * time.Second; tempDelay > max { - tempDelay = max - } - r.logger.Error("failed to accept RPC conn", "error", err, "delay", tempDelay) - time.Sleep(tempDelay) + maxDelay = 1 * time.Second } + if tempDelay > maxDelay { + tempDelay = maxDelay + } + r.logger.Error("failed to accept RPC conn", "error", err, "delay", tempDelay) + time.Sleep(tempDelay) continue } tempDelay = 0 From bbe531ca0493e028f807d177042ac087e3c34def Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Fri, 7 Dec 2018 22:15:05 +0000 Subject: [PATCH 29/71] updated memberlist dependency to latest, which is missing NMD-1173 error --- .../github.com/hashicorp/memberlist/Makefile | 8 +- .../github.com/hashicorp/memberlist/README.md | 85 +---- .../github.com/hashicorp/memberlist/config.go | 49 ++- .../hashicorp/memberlist/delegate.go | 2 +- .../hashicorp/memberlist/memberlist.go | 311 ++++++++-------- .../hashicorp/memberlist/mock_transport.go | 121 +++++++ vendor/github.com/hashicorp/memberlist/net.go | 334 ++++++++++-------- .../hashicorp/memberlist/net_transport.go | 289 +++++++++++++++ .../github.com/hashicorp/memberlist/queue.go | 20 ++ .../github.com/hashicorp/memberlist/state.go | 85 +++-- .../hashicorp/memberlist/suspicion.go | 2 +- vendor/github.com/hashicorp/memberlist/tag.sh | 16 + .../hashicorp/memberlist/transport.go | 65 ++++ .../github.com/hashicorp/memberlist/util.go | 55 ++- vendor/vendor.json | 2 +- 15 files changed, 1010 insertions(+), 434 deletions(-) create mode 100644 vendor/github.com/hashicorp/memberlist/mock_transport.go create mode 100644 vendor/github.com/hashicorp/memberlist/net_transport.go create mode 100755 vendor/github.com/hashicorp/memberlist/tag.sh create mode 100644 vendor/github.com/hashicorp/memberlist/transport.go diff --git a/vendor/github.com/hashicorp/memberlist/Makefile b/vendor/github.com/hashicorp/memberlist/Makefile index 56ef6c28c..4ee0ee4ef 100644 --- a/vendor/github.com/hashicorp/memberlist/Makefile +++ b/vendor/github.com/hashicorp/memberlist/Makefile @@ -1,3 +1,5 @@ +DEPS := $(shell go list -f '{{range .Imports}}{{.}} {{end}}' ./...) + test: subnet go test ./... @@ -11,4 +13,8 @@ cov: gocov test github.com/hashicorp/memberlist | gocov-html > /tmp/coverage.html open /tmp/coverage.html -.PNONY: test cov integ +deps: + go get -t -d -v ./... + echo $(DEPS) | xargs -n1 go get -d + +.PHONY: test cov integ diff --git a/vendor/github.com/hashicorp/memberlist/README.md b/vendor/github.com/hashicorp/memberlist/README.md index fc605a59b..f47fb81aa 100644 --- a/vendor/github.com/hashicorp/memberlist/README.md +++ b/vendor/github.com/hashicorp/memberlist/README.md @@ -1,4 +1,4 @@ -# memberlist [![GoDoc](https://godoc.org/github.com/hashicorp/memberlist?status.png)](https://godoc.org/github.com/hashicorp/memberlist) +# memberlist [![GoDoc](https://godoc.org/github.com/hashicorp/memberlist?status.png)](https://godoc.org/github.com/hashicorp/memberlist) [![Build Status](https://travis-ci.org/hashicorp/memberlist.svg?branch=master)](https://travis-ci.org/hashicorp/memberlist) memberlist is a [Go](http://www.golang.org) library that manages cluster membership and member failure detection using a gossip based protocol. @@ -23,6 +23,8 @@ Please check your installation with: go version ``` +Run `make deps` to fetch dependencies before building + ## Usage Memberlist is surprisingly simple to use. An example is shown below: @@ -63,82 +65,11 @@ For complete documentation, see the associated [Godoc](http://godoc.org/github.c ## Protocol -memberlist is based on ["SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol"](http://www.cs.cornell.edu/~asdas/research/dsn02-swim.pdf), -with a few minor adaptations, mostly to increase propagation speed and +memberlist is based on ["SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol"](http://ieeexplore.ieee.org/document/1028914/). However, we extend the protocol in a number of ways: + +* Several extensions are made to increase propagation speed and convergence rate. +* Another set of extensions, that we call Lifeguard, are made to make memberlist more robust in the presence of slow message processing (due to factors such as CPU starvation, and network delay or loss). -A high level overview of the memberlist protocol (based on SWIM) is -described below, but for details please read the full -[SWIM paper](http://www.cs.cornell.edu/~asdas/research/dsn02-swim.pdf) -followed by the memberlist source. We welcome any questions related +For details on all of these extensions, please read our paper "[Lifeguard : SWIM-ing with Situational Awareness](https://arxiv.org/abs/1707.00788)", along with the memberlist source. We welcome any questions related to the protocol on our issue tracker. - -### Protocol Description - -memberlist begins by joining an existing cluster or starting a new -cluster. If starting a new cluster, additional nodes are expected to join -it. New nodes in an existing cluster must be given the address of at -least one existing member in order to join the cluster. The new member -does a full state sync with the existing member over TCP and begins gossiping its -existence to the cluster. - -Gossip is done over UDP with a configurable but fixed fanout and interval. -This ensures that network usage is constant with regards to number of nodes, as opposed to -exponential growth that can occur with traditional heartbeat mechanisms. -Complete state exchanges with a random node are done periodically over -TCP, but much less often than gossip messages. This increases the likelihood -that the membership list converges properly since the full state is exchanged -and merged. The interval between full state exchanges is configurable or can -be disabled entirely. - -Failure detection is done by periodic random probing using a configurable interval. -If the node fails to ack within a reasonable time (typically some multiple -of RTT), then an indirect probe as well as a direct TCP probe are attempted. An -indirect probe asks a configurable number of random nodes to probe the same node, -in case there are network issues causing our own node to fail the probe. The direct -TCP probe is used to help identify the common situation where networking is -misconfigured to allow TCP but not UDP. Without the TCP probe, a UDP-isolated node -would think all other nodes were suspect and could cause churn in the cluster when -it attempts a TCP-based state exchange with another node. It is not desirable to -operate with only TCP connectivity because convergence will be much slower, but it -is enabled so that memberlist can detect this situation and alert operators. - -If both our probe, the indirect probes, and the direct TCP probe fail within a -configurable time, then the node is marked "suspicious" and this knowledge is -gossiped to the cluster. A suspicious node is still considered a member of -cluster. If the suspect member of the cluster does not dispute the suspicion -within a configurable period of time, the node is finally considered dead, -and this state is then gossiped to the cluster. - -This is a brief and incomplete description of the protocol. For a better idea, -please read the -[SWIM paper](http://www.cs.cornell.edu/~asdas/research/dsn02-swim.pdf) -in its entirety, along with the memberlist source code. - -### Changes from SWIM - -As mentioned earlier, the memberlist protocol is based on SWIM but includes -minor changes, mostly to increase propagation speed and convergence rates. - -The changes from SWIM are noted here: - -* memberlist does a full state sync over TCP periodically. SWIM only propagates - changes over gossip. While both eventually reach convergence, the full state - sync increases the likelihood that nodes are fully converged more quickly, - at the expense of more bandwidth usage. This feature can be totally disabled - if you wish. - -* memberlist has a dedicated gossip layer separate from the failure detection - protocol. SWIM only piggybacks gossip messages on top of probe/ack messages. - memberlist also piggybacks gossip messages on top of probe/ack messages, but - also will periodically send out dedicated gossip messages on their own. This - feature lets you have a higher gossip rate (for example once per 200ms) - and a slower failure detection rate (such as once per second), resulting - in overall faster convergence rates and data propagation speeds. This feature - can be totally disabed as well, if you wish. - -* memberlist stores around the state of dead nodes for a set amount of time, - so that when full syncs are requested, the requester also receives information - about dead nodes. Because SWIM doesn't do full syncs, SWIM deletes dead node - state immediately upon learning that the node is dead. This change again helps - the cluster converge more quickly. diff --git a/vendor/github.com/hashicorp/memberlist/config.go b/vendor/github.com/hashicorp/memberlist/config.go index 1c13bfcd3..c85b1657a 100644 --- a/vendor/github.com/hashicorp/memberlist/config.go +++ b/vendor/github.com/hashicorp/memberlist/config.go @@ -11,10 +11,15 @@ type Config struct { // The name of this node. This must be unique in the cluster. Name string + // Transport is a hook for providing custom code to communicate with + // other nodes. If this is left nil, then memberlist will by default + // make a NetTransport using BindAddr and BindPort from this structure. + Transport Transport + // Configuration related to what address to bind to and ports to - // listen on. The port is used for both UDP and TCP gossip. - // It is assumed other nodes are running on this port, but they - // do not need to. + // listen on. The port is used for both UDP and TCP gossip. It is + // assumed other nodes are running on this port, but they do not need + // to. BindAddr string BindPort int @@ -28,8 +33,11 @@ type Config struct { // ProtocolVersionMax. ProtocolVersion uint8 - // TCPTimeout is the timeout for establishing a TCP connection with - // a remote node for a full state sync. + // TCPTimeout is the timeout for establishing a stream connection with + // a remote node for a full state sync, and for stream read and write + // operations. This is a legacy name for backwards compatibility, but + // should really be called StreamTimeout now that we have generalized + // the transport. TCPTimeout time.Duration // IndirectChecks is the number of nodes that will be asked to perform @@ -133,6 +141,16 @@ type Config struct { GossipNodes int GossipToTheDeadTime time.Duration + // GossipVerifyIncoming controls whether to enforce encryption for incoming + // gossip. It is used for upshifting from unencrypted to encrypted gossip on + // a running cluster. + GossipVerifyIncoming bool + + // GossipVerifyOutgoing controls whether to enforce encryption for outgoing + // gossip. It is used for upshifting from unencrypted to encrypted gossip on + // a running cluster. + GossipVerifyOutgoing bool + // EnableCompression is used to control message compression. This can // be used to reduce bandwidth usage at the cost of slightly more CPU // utilization. This is only available starting at protocol version 1. @@ -189,10 +207,13 @@ type Config struct { // while UDP messages are handled. HandoffQueueDepth int - // Maximum number of bytes that memberlist expects UDP messages to be. A safe - // value for this is typically 1400 bytes (which is the default.) However, - // depending on your network's MTU (Maximum Transmission Unit) you may be able - // to increase this. + // Maximum number of bytes that memberlist will put in a packet (this + // will be for UDP packets by default with a NetTransport). A safe value + // for this is typically 1400 bytes (which is the default). However, + // depending on your network's MTU (Maximum Transmission Unit) you may + // be able to increase this to get more content into each gossip packet. + // This is a legacy name for backward compatibility but should really be + // called PacketBufferSize now that we have generalized the transport. UDPBufferSize int } @@ -214,7 +235,7 @@ func DefaultLANConfig() *Config { TCPTimeout: 10 * time.Second, // Timeout after 10 seconds IndirectChecks: 3, // Use 3 nodes for the indirect ping RetransmitMult: 4, // Retransmit a message 4 * log(N+1) nodes - SuspicionMult: 5, // Suspect a node for 5 * log(N+1) * Interval + SuspicionMult: 4, // Suspect a node for 4 * log(N+1) * Interval SuspicionMaxTimeoutMult: 6, // For 10k nodes this will give a max timeout of 120 seconds PushPullInterval: 30 * time.Second, // Low frequency ProbeTimeout: 500 * time.Millisecond, // Reasonable RTT time for LAN @@ -222,9 +243,11 @@ func DefaultLANConfig() *Config { DisableTcpPings: false, // TCP pings are safe, even with mixed versions AwarenessMaxMultiplier: 8, // Probe interval backs off to 8 seconds - GossipNodes: 3, // Gossip to 3 nodes - GossipInterval: 200 * time.Millisecond, // Gossip more rapidly - GossipToTheDeadTime: 30 * time.Second, // Same as push/pull + GossipNodes: 3, // Gossip to 3 nodes + GossipInterval: 200 * time.Millisecond, // Gossip more rapidly + GossipToTheDeadTime: 30 * time.Second, // Same as push/pull + GossipVerifyIncoming: true, + GossipVerifyOutgoing: true, EnableCompression: true, // Enable compression by default diff --git a/vendor/github.com/hashicorp/memberlist/delegate.go b/vendor/github.com/hashicorp/memberlist/delegate.go index 66aa2da79..551548892 100644 --- a/vendor/github.com/hashicorp/memberlist/delegate.go +++ b/vendor/github.com/hashicorp/memberlist/delegate.go @@ -12,7 +12,7 @@ type Delegate interface { // NotifyMsg is called when a user-data message is received. // Care should be taken that this method does not block, since doing // so would block the entire UDP packet receive loop. Additionally, the byte - // slice may be modified after the call returns, so it should be copied if needed. + // slice may be modified after the call returns, so it should be copied if needed NotifyMsg([]byte) // GetBroadcasts is called when user data messages can be broadcast. diff --git a/vendor/github.com/hashicorp/memberlist/memberlist.go b/vendor/github.com/hashicorp/memberlist/memberlist.go index 371e3294b..3a4ce967b 100644 --- a/vendor/github.com/hashicorp/memberlist/memberlist.go +++ b/vendor/github.com/hashicorp/memberlist/memberlist.go @@ -15,6 +15,7 @@ multiple routes. package memberlist import ( + "container/list" "fmt" "log" "net" @@ -22,9 +23,10 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" - "github.com/hashicorp/go-multierror" + multierror "github.com/hashicorp/go-multierror" sockaddr "github.com/hashicorp/go-sockaddr" "github.com/miekg/dns" ) @@ -33,16 +35,23 @@ type Memberlist struct { sequenceNum uint32 // Local sequence number incarnation uint32 // Local incarnation number numNodes uint32 // Number of known nodes (estimate) + pushPullReq uint32 // Number of push/pull requests config *Config - shutdown bool + shutdown int32 // Used as an atomic boolean value shutdownCh chan struct{} - leave bool + leave int32 // Used as an atomic boolean value leaveBroadcast chan struct{} - udpListener *net.UDPConn - tcpListener *net.TCPListener - handoff chan msgHandoff + shutdownLock sync.Mutex // Serializes calls to Shutdown + leaveLock sync.Mutex // Serializes calls to Leave + + transport Transport + + handoffCh chan struct{} + highPriorityMsgQueue *list.List + lowPriorityMsgQueue *list.List + msgQueueLock sync.Mutex nodeLock sync.RWMutex nodes []*nodeState // Known nodes @@ -91,25 +100,6 @@ func newMemberlist(conf *Config) (*Memberlist, error) { } } - tcpAddr := &net.TCPAddr{IP: net.ParseIP(conf.BindAddr), Port: conf.BindPort} - tcpLn, err := net.ListenTCP("tcp", tcpAddr) - if err != nil { - return nil, fmt.Errorf("Failed to start TCP listener. Err: %s", err) - } - if conf.BindPort == 0 { - conf.BindPort = tcpLn.Addr().(*net.TCPAddr).Port - } - - udpAddr := &net.UDPAddr{IP: net.ParseIP(conf.BindAddr), Port: conf.BindPort} - udpLn, err := net.ListenUDP("udp", udpAddr) - if err != nil { - tcpLn.Close() - return nil, fmt.Errorf("Failed to start UDP listener. Err: %s", err) - } - - // Set the UDP receive window size - setUDPRecvBuf(udpLn) - if conf.LogOutput != nil && conf.Logger != nil { return nil, fmt.Errorf("Cannot specify both LogOutput and Logger. Please choose a single log configuration setting.") } @@ -124,26 +114,78 @@ func newMemberlist(conf *Config) (*Memberlist, error) { logger = log.New(logDest, "", log.LstdFlags) } + // Set up a network transport by default if a custom one wasn't given + // by the config. + transport := conf.Transport + if transport == nil { + nc := &NetTransportConfig{ + BindAddrs: []string{conf.BindAddr}, + BindPort: conf.BindPort, + Logger: logger, + } + + // See comment below for details about the retry in here. + makeNetRetry := func(limit int) (*NetTransport, error) { + var err error + for try := 0; try < limit; try++ { + var nt *NetTransport + if nt, err = NewNetTransport(nc); err == nil { + return nt, nil + } + if strings.Contains(err.Error(), "address already in use") { + logger.Printf("[DEBUG] memberlist: Got bind error: %v", err) + continue + } + } + + return nil, fmt.Errorf("failed to obtain an address: %v", err) + } + + // The dynamic bind port operation is inherently racy because + // even though we are using the kernel to find a port for us, we + // are attempting to bind multiple protocols (and potentially + // multiple addresses) with the same port number. We build in a + // few retries here since this often gets transient errors in + // busy unit tests. + limit := 1 + if conf.BindPort == 0 { + limit = 10 + } + + nt, err := makeNetRetry(limit) + if err != nil { + return nil, fmt.Errorf("Could not set up network transport: %v", err) + } + if conf.BindPort == 0 { + port := nt.GetAutoBindPort() + conf.BindPort = port + conf.AdvertisePort = port + logger.Printf("[DEBUG] memberlist: Using dynamic bind port %d", port) + } + transport = nt + } + m := &Memberlist{ - config: conf, - shutdownCh: make(chan struct{}), - leaveBroadcast: make(chan struct{}, 1), - udpListener: udpLn, - tcpListener: tcpLn, - handoff: make(chan msgHandoff, conf.HandoffQueueDepth), - nodeMap: make(map[string]*nodeState), - nodeTimers: make(map[string]*suspicion), - awareness: newAwareness(conf.AwarenessMaxMultiplier), - ackHandlers: make(map[uint32]*ackHandler), - broadcasts: &TransmitLimitedQueue{RetransmitMult: conf.RetransmitMult}, - logger: logger, + config: conf, + shutdownCh: make(chan struct{}), + leaveBroadcast: make(chan struct{}, 1), + transport: transport, + handoffCh: make(chan struct{}, 1), + highPriorityMsgQueue: list.New(), + lowPriorityMsgQueue: list.New(), + nodeMap: make(map[string]*nodeState), + nodeTimers: make(map[string]*suspicion), + awareness: newAwareness(conf.AwarenessMaxMultiplier), + ackHandlers: make(map[uint32]*ackHandler), + broadcasts: &TransmitLimitedQueue{RetransmitMult: conf.RetransmitMult}, + logger: logger, } m.broadcasts.NumNodes = func() int { return m.estNumNodes() } - go m.tcpListen() - go m.udpListen() - go m.udpHandler() + go m.streamListen() + go m.packetListen() + go m.packetHandler() return m, nil } @@ -187,7 +229,8 @@ func (m *Memberlist) Join(existing []string) (int, error) { } for _, addr := range addrs { - if err := m.pushPullNode(addr.ip, addr.port, true); err != nil { + hp := joinHostPort(addr.ip.String(), addr.port) + if err := m.pushPullNode(hp, true); err != nil { err = fmt.Errorf("Failed to join %s: %v", addr.ip, err) errs = multierror.Append(errs, err) m.logger.Printf("[DEBUG] memberlist: %v", err) @@ -273,23 +316,17 @@ func (m *Memberlist) tcpLookupIP(host string, defaultPort uint16) ([]ipPort, err // resolveAddr is used to resolve the address into an address, // port, and error. If no port is given, use the default func (m *Memberlist) resolveAddr(hostStr string) ([]ipPort, error) { - // Normalize the incoming string to host:port so we can apply Go's - // parser to it. - port := uint16(0) - if !hasPort(hostStr) { - hostStr += ":" + strconv.Itoa(m.config.BindPort) - } + // This captures the supplied port, or the default one. + hostStr = ensurePort(hostStr, m.config.BindPort) host, sport, err := net.SplitHostPort(hostStr) if err != nil { return nil, err } - - // This will capture the supplied port, or the default one added above. lport, err := strconv.ParseUint(sport, 10, 16) if err != nil { return nil, err } - port = uint16(lport) + port := uint16(lport) // If it looks like an IP address we are done. The SplitHostPort() above // will make sure the host part is in good shape for parsing, even for @@ -327,68 +364,30 @@ func (m *Memberlist) resolveAddr(hostStr string) ([]ipPort, error) { // as if we received an alive notification our own network channel for // ourself. func (m *Memberlist) setAlive() error { - var advertiseAddr net.IP - var advertisePort int - if m.config.AdvertiseAddr != "" { - // If AdvertiseAddr is not empty, then advertise - // the given address and port. - ip := net.ParseIP(m.config.AdvertiseAddr) - if ip == nil { - return fmt.Errorf("Failed to parse advertise address!") - } - - // Ensure IPv4 conversion if necessary - if ip4 := ip.To4(); ip4 != nil { - ip = ip4 - } - - advertiseAddr = ip - advertisePort = m.config.AdvertisePort - } else { - if m.config.BindAddr == "0.0.0.0" { - // Otherwise, if we're not bound to a specific IP, let's use a suitable - // private IP address. - var err error - m.config.AdvertiseAddr, err = sockaddr.GetPrivateIP() - if err != nil { - return fmt.Errorf("Failed to get interface addresses: %v", err) - } - if m.config.AdvertiseAddr == "" { - return fmt.Errorf("No private IP address found, and explicit IP not provided") - } - - advertiseAddr = net.ParseIP(m.config.AdvertiseAddr) - if advertiseAddr == nil { - return fmt.Errorf("Failed to parse advertise address: %q", m.config.AdvertiseAddr) - } - } else { - // Use the IP that we're bound to. - addr := m.tcpListener.Addr().(*net.TCPAddr) - advertiseAddr = addr.IP - } - - // Use the port we are bound to. - advertisePort = m.tcpListener.Addr().(*net.TCPAddr).Port + // Get the final advertise address from the transport, which may need + // to see which address we bound to. + addr, port, err := m.transport.FinalAdvertiseAddr( + m.config.AdvertiseAddr, m.config.AdvertisePort) + if err != nil { + return fmt.Errorf("Failed to get final advertise address: %v", err) } // Check if this is a public address without encryption - ipAddr, err := sockaddr.NewIPAddr(advertiseAddr.String()) + ipAddr, err := sockaddr.NewIPAddr(addr.String()) if err != nil { return fmt.Errorf("Failed to parse interface addresses: %v", err) } - ifAddrs := []sockaddr.IfAddr{ sockaddr.IfAddr{ SockAddr: ipAddr, }, } - _, publicIfs, err := sockaddr.IfByRFC("6890", ifAddrs) if len(publicIfs) > 0 && !m.config.EncryptionEnabled() { m.logger.Printf("[WARN] memberlist: Binding to public address without encryption!") } - // Get the node meta data + // Set any metadata from the delegate. var meta []byte if m.config.Delegate != nil { meta = m.config.Delegate.NodeMeta(MetaMaxSize) @@ -400,8 +399,8 @@ func (m *Memberlist) setAlive() error { a := alive{ Incarnation: m.nextIncarnation(), Node: m.config.Name, - Addr: advertiseAddr, - Port: uint16(advertisePort), + Addr: addr, + Port: uint16(port), Meta: meta, Vsn: []uint8{ ProtocolVersionMin, ProtocolVersionMax, m.config.ProtocolVersion, @@ -410,7 +409,6 @@ func (m *Memberlist) setAlive() error { }, } m.aliveNode(&a, nil, true) - return nil } @@ -473,13 +471,8 @@ func (m *Memberlist) UpdateNode(timeout time.Duration) error { return nil } -// SendTo is used to directly send a message to another node, without -// the use of the gossip mechanism. This will encode the message as a -// user-data message, which a delegate will receive through NotifyMsg -// The actual data is transmitted over UDP, which means this is a -// best-effort transmission mechanism, and the maximum size of the -// message is the size of a single UDP datagram, after compression. -// This method is DEPRECATED in favor or SendToUDP +// SendTo is deprecated in favor of SendBestEffort, which requires a node to +// target. func (m *Memberlist) SendTo(to net.Addr, msg []byte) error { // Encode as a user message buf := make([]byte, 1, len(msg)+1) @@ -487,36 +480,39 @@ func (m *Memberlist) SendTo(to net.Addr, msg []byte) error { buf = append(buf, msg...) // Send the message - return m.rawSendMsgUDP(to, nil, buf) + return m.rawSendMsgPacket(to.String(), nil, buf) } -// SendToUDP is used to directly send a message to another node, without -// the use of the gossip mechanism. This will encode the message as a -// user-data message, which a delegate will receive through NotifyMsg -// The actual data is transmitted over UDP, which means this is a -// best-effort transmission mechanism, and the maximum size of the -// message is the size of a single UDP datagram, after compression +// SendToUDP is deprecated in favor of SendBestEffort. func (m *Memberlist) SendToUDP(to *Node, msg []byte) error { + return m.SendBestEffort(to, msg) +} + +// SendToTCP is deprecated in favor of SendReliable. +func (m *Memberlist) SendToTCP(to *Node, msg []byte) error { + return m.SendReliable(to, msg) +} + +// SendBestEffort uses the unreliable packet-oriented interface of the transport +// to target a user message at the given node (this does not use the gossip +// mechanism). The maximum size of the message depends on the configured +// UDPBufferSize for this memberlist instance. +func (m *Memberlist) SendBestEffort(to *Node, msg []byte) error { // Encode as a user message buf := make([]byte, 1, len(msg)+1) buf[0] = byte(userMsg) buf = append(buf, msg...) // Send the message - destAddr := &net.UDPAddr{IP: to.Addr, Port: int(to.Port)} - return m.rawSendMsgUDP(destAddr, to, buf) + return m.rawSendMsgPacket(to.Address(), to, buf) } -// SendToTCP is used to directly send a message to another node, without -// the use of the gossip mechanism. This will encode the message as a -// user-data message, which a delegate will receive through NotifyMsg -// The actual data is transmitted over TCP, which means delivery -// is guaranteed if no error is returned. There is no limit -// to the size of the message -func (m *Memberlist) SendToTCP(to *Node, msg []byte) error { - // Send the message - destAddr := &net.TCPAddr{IP: to.Addr, Port: int(to.Port)} - return m.sendTCPUserMsg(destAddr, msg) +// SendReliable uses the reliable stream-oriented interface of the transport to +// target a user message at the given node (this does not use the gossip +// mechanism). Delivery is guaranteed if no error is returned, and there is no +// limit on the size of the message. +func (m *Memberlist) SendReliable(to *Node, msg []byte) error { + return m.sendUserMsg(to.Address(), msg) } // Members returns a list of all known live nodes. The node structures @@ -564,18 +560,17 @@ func (m *Memberlist) NumMembers() (alive int) { // This method is safe to call multiple times, but must not be called // after the cluster is already shut down. func (m *Memberlist) Leave(timeout time.Duration) error { - m.nodeLock.Lock() - // We can't defer m.nodeLock.Unlock() because m.deadNode will also try to - // acquire a lock so we need to Unlock before that. + m.leaveLock.Lock() + defer m.leaveLock.Unlock() - if m.shutdown { - m.nodeLock.Unlock() + if m.hasShutdown() { panic("leave after shutdown") } - if !m.leave { - m.leave = true + if !m.hasLeft() { + atomic.StoreInt32(&m.leave, 1) + m.nodeLock.Lock() state, ok := m.nodeMap[m.config.Name] m.nodeLock.Unlock() if !ok { @@ -601,8 +596,6 @@ func (m *Memberlist) Leave(timeout time.Duration) error { return fmt.Errorf("timeout waiting for leave broadcast") } } - } else { - m.nodeLock.Unlock() } return nil @@ -644,17 +637,55 @@ func (m *Memberlist) ProtocolVersion() uint8 { // // This method is safe to call multiple times. func (m *Memberlist) Shutdown() error { - m.nodeLock.Lock() - defer m.nodeLock.Unlock() + m.shutdownLock.Lock() + defer m.shutdownLock.Unlock() - if m.shutdown { + if m.hasShutdown() { return nil } - m.shutdown = true + // Shut down the transport first, which should block until it's + // completely torn down. If we kill the memberlist-side handlers + // those I/O handlers might get stuck. + if err := m.transport.Shutdown(); err != nil { + m.logger.Printf("[ERR] Failed to shutdown transport: %v", err) + } + + // Now tear down everything else. + atomic.StoreInt32(&m.shutdown, 1) close(m.shutdownCh) m.deschedule() - m.udpListener.Close() - m.tcpListener.Close() return nil } + +func (m *Memberlist) hasShutdown() bool { + return atomic.LoadInt32(&m.shutdown) == 1 +} + +func (m *Memberlist) hasLeft() bool { + return atomic.LoadInt32(&m.leave) == 1 +} + +func (m *Memberlist) getNodeState(addr string) nodeStateType { + m.nodeLock.RLock() + defer m.nodeLock.RUnlock() + + n := m.nodeMap[addr] + return n.State +} + +func (m *Memberlist) getNodeStateChange(addr string) time.Time { + m.nodeLock.RLock() + defer m.nodeLock.RUnlock() + + n := m.nodeMap[addr] + return n.StateChange +} + +func (m *Memberlist) changeNode(addr string, f func(*nodeState)) { + m.nodeLock.Lock() + defer m.nodeLock.Unlock() + + n := m.nodeMap[addr] + f(n) +} diff --git a/vendor/github.com/hashicorp/memberlist/mock_transport.go b/vendor/github.com/hashicorp/memberlist/mock_transport.go new file mode 100644 index 000000000..b8bafa802 --- /dev/null +++ b/vendor/github.com/hashicorp/memberlist/mock_transport.go @@ -0,0 +1,121 @@ +package memberlist + +import ( + "fmt" + "net" + "strconv" + "time" +) + +// MockNetwork is used as a factory that produces MockTransport instances which +// are uniquely addressed and wired up to talk to each other. +type MockNetwork struct { + transports map[string]*MockTransport + port int +} + +// NewTransport returns a new MockTransport with a unique address, wired up to +// talk to the other transports in the MockNetwork. +func (n *MockNetwork) NewTransport() *MockTransport { + n.port += 1 + addr := fmt.Sprintf("127.0.0.1:%d", n.port) + transport := &MockTransport{ + net: n, + addr: &MockAddress{addr}, + packetCh: make(chan *Packet), + streamCh: make(chan net.Conn), + } + + if n.transports == nil { + n.transports = make(map[string]*MockTransport) + } + n.transports[addr] = transport + return transport +} + +// MockAddress is a wrapper which adds the net.Addr interface to our mock +// address scheme. +type MockAddress struct { + addr string +} + +// See net.Addr. +func (a *MockAddress) Network() string { + return "mock" +} + +// See net.Addr. +func (a *MockAddress) String() string { + return a.addr +} + +// MockTransport directly plumbs messages to other transports its MockNetwork. +type MockTransport struct { + net *MockNetwork + addr *MockAddress + packetCh chan *Packet + streamCh chan net.Conn +} + +// See Transport. +func (t *MockTransport) FinalAdvertiseAddr(string, int) (net.IP, int, error) { + host, portStr, err := net.SplitHostPort(t.addr.String()) + if err != nil { + return nil, 0, err + } + + ip := net.ParseIP(host) + if ip == nil { + return nil, 0, fmt.Errorf("Failed to parse IP %q", host) + } + + port, err := strconv.ParseInt(portStr, 10, 16) + if err != nil { + return nil, 0, err + } + + return ip, int(port), nil +} + +// See Transport. +func (t *MockTransport) WriteTo(b []byte, addr string) (time.Time, error) { + dest, ok := t.net.transports[addr] + if !ok { + return time.Time{}, fmt.Errorf("No route to %q", addr) + } + + now := time.Now() + dest.packetCh <- &Packet{ + Buf: b, + From: t.addr, + Timestamp: now, + } + return now, nil +} + +// See Transport. +func (t *MockTransport) PacketCh() <-chan *Packet { + return t.packetCh +} + +// See Transport. +func (t *MockTransport) DialTimeout(addr string, timeout time.Duration) (net.Conn, error) { + dest, ok := t.net.transports[addr] + if !ok { + return nil, fmt.Errorf("No route to %q", addr) + } + + p1, p2 := net.Pipe() + dest.streamCh <- p1 + return p2, nil +} + +// See Transport. +func (t *MockTransport) StreamCh() <-chan net.Conn { + return t.streamCh +} + +// See Transport. +func (t *MockTransport) Shutdown() error { + return nil +} diff --git a/vendor/github.com/hashicorp/memberlist/net.go b/vendor/github.com/hashicorp/memberlist/net.go index e47da411e..f6a0d45fe 100644 --- a/vendor/github.com/hashicorp/memberlist/net.go +++ b/vendor/github.com/hashicorp/memberlist/net.go @@ -8,9 +8,10 @@ import ( "hash/crc32" "io" "net" + "sync/atomic" "time" - "github.com/armon/go-metrics" + metrics "github.com/armon/go-metrics" "github.com/hashicorp/go-msgpack/codec" ) @@ -55,6 +56,7 @@ const ( encryptMsg nackRespMsg hasCrcMsg + errMsg ) // compressionType is used to specify the compression algorithm @@ -68,11 +70,10 @@ const ( MetaMaxSize = 512 // Maximum size for node meta data compoundHeaderOverhead = 2 // Assumed header overhead compoundOverhead = 2 // Assumed overhead per entry in compoundHeader - udpBufSize = 65536 - udpRecvBuf = 2 * 1024 * 1024 userMsgOverhead = 1 blockingWarning = 10 * time.Millisecond // Warn if a UDP packet takes this long to process - maxPushStateBytes = 10 * 1024 * 1024 + maxPushStateBytes = 20 * 1024 * 1024 + maxPushPullRequests = 128 // Maximum number of concurrent push/pull requests ) // ping request sent directly to node @@ -107,6 +108,11 @@ type nackResp struct { SeqNo uint32 } +// err response is sent to relay the error from the remote end +type errResp struct { + Error string +} + // suspect is broadcast when we suspect a node is dead type suspect struct { Incarnation uint32 @@ -185,46 +191,45 @@ func (m *Memberlist) encryptionVersion() encryptionVersion { } } -// setUDPRecvBuf is used to resize the UDP receive window. The function -// attempts to set the read buffer to `udpRecvBuf` but backs off until -// the read buffer can be set. -func setUDPRecvBuf(c *net.UDPConn) { - size := udpRecvBuf +// streamListen is a long running goroutine that pulls incoming streams from the +// transport and hands them off for processing. +func (m *Memberlist) streamListen() { for { - if err := c.SetReadBuffer(size); err == nil { - break + select { + case conn := <-m.transport.StreamCh(): + go m.handleConn(conn) + + case <-m.shutdownCh: + return } - size = size / 2 } } -// tcpListen listens for and handles incoming connections -func (m *Memberlist) tcpListen() { - for { - conn, err := m.tcpListener.AcceptTCP() - if err != nil { - if m.shutdown { - break - } - m.logger.Printf("[ERR] memberlist: Error accepting TCP connection: %s", err) - continue - } - go m.handleConn(conn) - } -} - -// handleConn handles a single incoming TCP connection -func (m *Memberlist) handleConn(conn *net.TCPConn) { - m.logger.Printf("[DEBUG] memberlist: TCP connection %s", LogConn(conn)) +// handleConn handles a single incoming stream connection from the transport. +func (m *Memberlist) handleConn(conn net.Conn) { + m.logger.Printf("[DEBUG] memberlist: Stream connection %s", LogConn(conn)) defer conn.Close() metrics.IncrCounter([]string{"memberlist", "tcp", "accept"}, 1) conn.SetDeadline(time.Now().Add(m.config.TCPTimeout)) - msgType, bufConn, dec, err := m.readTCP(conn) + msgType, bufConn, dec, err := m.readStream(conn) if err != nil { if err != io.EOF { m.logger.Printf("[ERR] memberlist: failed to receive: %s %s", err, LogConn(conn)) + + resp := errResp{err.Error()} + out, err := encode(errMsg, &resp) + if err != nil { + m.logger.Printf("[ERR] memberlist: Failed to encode error response: %s", err) + return + } + + err = m.rawSendMsgStream(conn, out.Bytes()) + if err != nil { + m.logger.Printf("[ERR] memberlist: Failed to send error: %s %s", err, LogConn(conn)) + return + } } return } @@ -235,6 +240,16 @@ func (m *Memberlist) handleConn(conn *net.TCPConn) { m.logger.Printf("[ERR] memberlist: Failed to receive user message: %s %s", err, LogConn(conn)) } case pushPullMsg: + // Increment counter of pending push/pulls + numConcurrent := atomic.AddUint32(&m.pushPullReq, 1) + defer atomic.AddUint32(&m.pushPullReq, ^uint32(0)) + + // Check if we have too many open push/pull requests + if numConcurrent >= maxPushPullRequests { + m.logger.Printf("[ERR] memberlist: Too many pending push/pull requests") + return + } + join, remoteNodes, userState, err := m.readRemoteState(bufConn, dec) if err != nil { m.logger.Printf("[ERR] memberlist: Failed to read remote state: %s %s", err, LogConn(conn)) @@ -253,7 +268,7 @@ func (m *Memberlist) handleConn(conn *net.TCPConn) { case pingMsg: var p ping if err := dec.Decode(&p); err != nil { - m.logger.Printf("[ERR] memberlist: Failed to decode TCP ping: %s %s", err, LogConn(conn)) + m.logger.Printf("[ERR] memberlist: Failed to decode ping: %s %s", err, LogConn(conn)) return } @@ -265,13 +280,13 @@ func (m *Memberlist) handleConn(conn *net.TCPConn) { ack := ackResp{p.SeqNo, nil} out, err := encode(ackRespMsg, &ack) if err != nil { - m.logger.Printf("[ERR] memberlist: Failed to encode TCP ack: %s", err) + m.logger.Printf("[ERR] memberlist: Failed to encode ack: %s", err) return } - err = m.rawSendMsgTCP(conn, out.Bytes()) + err = m.rawSendMsgStream(conn, out.Bytes()) if err != nil { - m.logger.Printf("[ERR] memberlist: Failed to send TCP ack: %s %s", err, LogConn(conn)) + m.logger.Printf("[ERR] memberlist: Failed to send ack: %s %s", err, LogConn(conn)) return } default: @@ -279,49 +294,17 @@ func (m *Memberlist) handleConn(conn *net.TCPConn) { } } -// udpListen listens for and handles incoming UDP packets -func (m *Memberlist) udpListen() { - var n int - var addr net.Addr - var err error - var lastPacket time.Time +// packetListen is a long running goroutine that pulls packets out of the +// transport and hands them off for processing. +func (m *Memberlist) packetListen() { for { - // Do a check for potentially blocking operations - if !lastPacket.IsZero() && time.Now().Sub(lastPacket) > blockingWarning { - diff := time.Now().Sub(lastPacket) - m.logger.Printf( - "[DEBUG] memberlist: Potential blocking operation. Last command took %v", - diff) + select { + case packet := <-m.transport.PacketCh(): + m.ingestPacket(packet.Buf, packet.From, packet.Timestamp) + + case <-m.shutdownCh: + return } - - // Create a new buffer - // TODO: Use Sync.Pool eventually - buf := make([]byte, udpBufSize) - - // Read a packet - n, addr, err = m.udpListener.ReadFrom(buf) - if err != nil { - if m.shutdown { - break - } - m.logger.Printf("[ERR] memberlist: Error reading UDP packet: %s", err) - continue - } - - // Capture the reception time of the packet as close to the - // system calls as possible. - lastPacket = time.Now() - - // Check the length - if n < 1 { - m.logger.Printf("[ERR] memberlist: UDP packet too short (%d bytes) %s", - len(buf), LogAddress(addr)) - continue - } - - // Ingest this packet - metrics.IncrCounter([]string{"memberlist", "udp", "received"}, float32(n)) - m.ingestPacket(buf[:n], addr, lastPacket) } } @@ -331,8 +314,13 @@ func (m *Memberlist) ingestPacket(buf []byte, from net.Addr, timestamp time.Time // Decrypt the payload plain, err := decryptPayload(m.config.Keyring.GetKeys(), buf, nil) if err != nil { - m.logger.Printf("[ERR] memberlist: Decrypt packet failed: %v %s", err, LogAddress(from)) - return + if !m.config.GossipVerifyIncoming { + // Treat the message as plaintext + plain = buf + } else { + m.logger.Printf("[ERR] memberlist: Decrypt packet failed: %v %s", err, LogAddress(from)) + return + } } // Continue processing the plaintext buffer @@ -381,39 +369,77 @@ func (m *Memberlist) handleCommand(buf []byte, from net.Addr, timestamp time.Tim case deadMsg: fallthrough case userMsg: + // Determine the message queue, prioritize alive + queue := m.lowPriorityMsgQueue + if msgType == aliveMsg { + queue = m.highPriorityMsgQueue + } + + // Check for overflow and append if not full + m.msgQueueLock.Lock() + if queue.Len() >= m.config.HandoffQueueDepth { + m.logger.Printf("[WARN] memberlist: handler queue full, dropping message (%d) %s", msgType, LogAddress(from)) + } else { + queue.PushBack(msgHandoff{msgType, buf, from}) + } + m.msgQueueLock.Unlock() + + // Notify of pending message select { - case m.handoff <- msgHandoff{msgType, buf, from}: + case m.handoffCh <- struct{}{}: default: - m.logger.Printf("[WARN] memberlist: UDP handler queue full, dropping message (%d) %s", msgType, LogAddress(from)) } default: - m.logger.Printf("[ERR] memberlist: UDP msg type (%d) not supported %s", msgType, LogAddress(from)) + m.logger.Printf("[ERR] memberlist: msg type (%d) not supported %s", msgType, LogAddress(from)) } } -// udpHandler processes messages received over UDP, but is decoupled -// from the listener to avoid blocking the listener which may cause -// ping/ack messages to be delayed. -func (m *Memberlist) udpHandler() { +// getNextMessage returns the next message to process in priority order, using LIFO +func (m *Memberlist) getNextMessage() (msgHandoff, bool) { + m.msgQueueLock.Lock() + defer m.msgQueueLock.Unlock() + + if el := m.highPriorityMsgQueue.Back(); el != nil { + m.highPriorityMsgQueue.Remove(el) + msg := el.Value.(msgHandoff) + return msg, true + } else if el := m.lowPriorityMsgQueue.Back(); el != nil { + m.lowPriorityMsgQueue.Remove(el) + msg := el.Value.(msgHandoff) + return msg, true + } + return msgHandoff{}, false +} + +// packetHandler is a long running goroutine that processes messages received +// over the packet interface, but is decoupled from the listener to avoid +// blocking the listener which may cause ping/ack messages to be delayed. +func (m *Memberlist) packetHandler() { for { select { - case msg := <-m.handoff: - msgType := msg.msgType - buf := msg.buf - from := msg.from + case <-m.handoffCh: + for { + msg, ok := m.getNextMessage() + if !ok { + break + } + msgType := msg.msgType + buf := msg.buf + from := msg.from - switch msgType { - case suspectMsg: - m.handleSuspect(buf, from) - case aliveMsg: - m.handleAlive(buf, from) - case deadMsg: - m.handleDead(buf, from) - case userMsg: - m.handleUser(buf, from) - default: - m.logger.Printf("[ERR] memberlist: UDP msg type (%d) not supported %s (handler)", msgType, LogAddress(from)) + switch msgType { + case suspectMsg: + m.handleSuspect(buf, from) + case aliveMsg: + m.handleAlive(buf, from) + case deadMsg: + m.handleDead(buf, from) + case userMsg: + m.handleUser(buf, from) + default: + m.logger.Printf("[ERR] memberlist: Message type (%d) not supported %s (packet handler)", msgType, LogAddress(from)) + } } case <-m.shutdownCh: @@ -457,7 +483,7 @@ func (m *Memberlist) handlePing(buf []byte, from net.Addr) { if m.config.Ping != nil { ack.Payload = m.config.Ping.AckPayload() } - if err := m.encodeAndSendMsg(from, ackRespMsg, &ack); err != nil { + if err := m.encodeAndSendMsg(from.String(), ackRespMsg, &ack); err != nil { m.logger.Printf("[ERR] memberlist: Failed to send ack: %s %s", err, LogAddress(from)) } } @@ -478,7 +504,6 @@ func (m *Memberlist) handleIndirectPing(buf []byte, from net.Addr) { // Send a ping to the correct host. localSeqNo := m.nextSeqNo() ping := ping{SeqNo: localSeqNo, Node: ind.Node} - destAddr := &net.UDPAddr{IP: ind.Target, Port: int(ind.Port)} // Setup a response handler to relay the ack cancelCh := make(chan struct{}) @@ -488,14 +513,15 @@ func (m *Memberlist) handleIndirectPing(buf []byte, from net.Addr) { // Forward the ack back to the requestor. ack := ackResp{ind.SeqNo, nil} - if err := m.encodeAndSendMsg(from, ackRespMsg, &ack); err != nil { + if err := m.encodeAndSendMsg(from.String(), ackRespMsg, &ack); err != nil { m.logger.Printf("[ERR] memberlist: Failed to forward ack: %s %s", err, LogAddress(from)) } } m.setAckHandler(localSeqNo, respHandler, m.config.ProbeTimeout) // Send the ping. - if err := m.encodeAndSendMsg(destAddr, pingMsg, &ping); err != nil { + addr := joinHostPort(net.IP(ind.Target).String(), ind.Port) + if err := m.encodeAndSendMsg(addr, pingMsg, &ping); err != nil { m.logger.Printf("[ERR] memberlist: Failed to send ping: %s %s", err, LogAddress(from)) } @@ -507,7 +533,7 @@ func (m *Memberlist) handleIndirectPing(buf []byte, from net.Addr) { return case <-time.After(m.config.ProbeTimeout): nack := nackResp{ind.SeqNo} - if err := m.encodeAndSendMsg(from, nackRespMsg, &nack); err != nil { + if err := m.encodeAndSendMsg(from.String(), nackRespMsg, &nack); err != nil { m.logger.Printf("[ERR] memberlist: Failed to send nack: %s %s", err, LogAddress(from)) } } @@ -589,30 +615,30 @@ func (m *Memberlist) handleCompressed(buf []byte, from net.Addr, timestamp time. } // encodeAndSendMsg is used to combine the encoding and sending steps -func (m *Memberlist) encodeAndSendMsg(to net.Addr, msgType messageType, msg interface{}) error { +func (m *Memberlist) encodeAndSendMsg(addr string, msgType messageType, msg interface{}) error { out, err := encode(msgType, msg) if err != nil { return err } - if err := m.sendMsg(to, out.Bytes()); err != nil { + if err := m.sendMsg(addr, out.Bytes()); err != nil { return err } return nil } -// sendMsg is used to send a UDP message to another host. It will opportunistically -// create a compoundMsg and piggy back other broadcasts -func (m *Memberlist) sendMsg(to net.Addr, msg []byte) error { +// sendMsg is used to send a message via packet to another host. It will +// opportunistically create a compoundMsg and piggy back other broadcasts. +func (m *Memberlist) sendMsg(addr string, msg []byte) error { // Check if we can piggy back any messages bytesAvail := m.config.UDPBufferSize - len(msg) - compoundHeaderOverhead - if m.config.EncryptionEnabled() { + if m.config.EncryptionEnabled() && m.config.GossipVerifyOutgoing { bytesAvail -= encryptOverhead(m.encryptionVersion()) } extra := m.getBroadcasts(compoundOverhead, bytesAvail) // Fast path if nothing to piggypack if len(extra) == 0 { - return m.rawSendMsgUDP(to, nil, msg) + return m.rawSendMsgPacket(addr, nil, msg) } // Join all the messages @@ -624,11 +650,12 @@ func (m *Memberlist) sendMsg(to net.Addr, msg []byte) error { compound := makeCompoundMessage(msgs) // Send the message - return m.rawSendMsgUDP(to, nil, compound.Bytes()) + return m.rawSendMsgPacket(addr, nil, compound.Bytes()) } -// rawSendMsgUDP is used to send a UDP message to another host without modification -func (m *Memberlist) rawSendMsgUDP(addr net.Addr, node *Node, msg []byte) error { +// rawSendMsgPacket is used to send message via packet to another host without +// modification, other than compression or encryption if enabled. +func (m *Memberlist) rawSendMsgPacket(addr string, node *Node, msg []byte) error { // Check if we have compression enabled if m.config.EnableCompression { buf, err := compressPayload(msg) @@ -644,9 +671,9 @@ func (m *Memberlist) rawSendMsgUDP(addr net.Addr, node *Node, msg []byte) error // Try to look up the destination node if node == nil { - toAddr, _, err := net.SplitHostPort(addr.String()) + toAddr, _, err := net.SplitHostPort(addr) if err != nil { - m.logger.Printf("[ERR] memberlist: Failed to parse address %q: %v", addr.String(), err) + m.logger.Printf("[ERR] memberlist: Failed to parse address %q: %v", addr, err) return err } m.nodeLock.RLock() @@ -668,7 +695,7 @@ func (m *Memberlist) rawSendMsgUDP(addr net.Addr, node *Node, msg []byte) error } // Check if we have encryption enabled - if m.config.EncryptionEnabled() { + if m.config.EncryptionEnabled() && m.config.GossipVerifyOutgoing { // Encrypt the payload var buf bytes.Buffer primaryKey := m.config.Keyring.GetPrimaryKey() @@ -681,12 +708,13 @@ func (m *Memberlist) rawSendMsgUDP(addr net.Addr, node *Node, msg []byte) error } metrics.IncrCounter([]string{"memberlist", "udp", "sent"}, float32(len(msg))) - _, err := m.udpListener.WriteTo(msg, addr) + _, err := m.transport.WriteTo(msg, addr) return err } -// rawSendMsgTCP is used to send a TCP message to another host without modification -func (m *Memberlist) rawSendMsgTCP(conn net.Conn, sendBuf []byte) error { +// rawSendMsgStream is used to stream a message to another host without +// modification, other than applying compression and encryption if enabled. +func (m *Memberlist) rawSendMsgStream(conn net.Conn, sendBuf []byte) error { // Check if compresion is enabled if m.config.EnableCompression { compBuf, err := compressPayload(sendBuf) @@ -698,7 +726,7 @@ func (m *Memberlist) rawSendMsgTCP(conn net.Conn, sendBuf []byte) error { } // Check if encryption is enabled - if m.config.EncryptionEnabled() { + if m.config.EncryptionEnabled() && m.config.GossipVerifyOutgoing { crypt, err := m.encryptLocalState(sendBuf) if err != nil { m.logger.Printf("[ERROR] memberlist: Failed to encrypt local state: %v", err) @@ -719,43 +747,36 @@ func (m *Memberlist) rawSendMsgTCP(conn net.Conn, sendBuf []byte) error { return nil } -// sendTCPUserMsg is used to send a TCP userMsg to another host -func (m *Memberlist) sendTCPUserMsg(to net.Addr, sendBuf []byte) error { - dialer := net.Dialer{Timeout: m.config.TCPTimeout} - conn, err := dialer.Dial("tcp", to.String()) +// sendUserMsg is used to stream a user message to another host. +func (m *Memberlist) sendUserMsg(addr string, sendBuf []byte) error { + conn, err := m.transport.DialTimeout(addr, m.config.TCPTimeout) if err != nil { return err } defer conn.Close() bufConn := bytes.NewBuffer(nil) - if err := bufConn.WriteByte(byte(userMsg)); err != nil { return err } - // Send our node state header := userMsgHeader{UserMsgLen: len(sendBuf)} hd := codec.MsgpackHandle{} enc := codec.NewEncoder(bufConn, &hd) - if err := enc.Encode(&header); err != nil { return err } - if _, err := bufConn.Write(sendBuf); err != nil { return err } - - return m.rawSendMsgTCP(conn, bufConn.Bytes()) + return m.rawSendMsgStream(conn, bufConn.Bytes()) } -// sendAndReceiveState is used to initiate a push/pull over TCP with a remote node -func (m *Memberlist) sendAndReceiveState(addr []byte, port uint16, join bool) ([]pushNodeState, []byte, error) { +// sendAndReceiveState is used to initiate a push/pull over a stream with a +// remote host. +func (m *Memberlist) sendAndReceiveState(addr string, join bool) ([]pushNodeState, []byte, error) { // Attempt to connect - dialer := net.Dialer{Timeout: m.config.TCPTimeout} - dest := net.TCPAddr{IP: addr, Port: int(port)} - conn, err := dialer.Dial("tcp", dest.String()) + conn, err := m.transport.DialTimeout(addr, m.config.TCPTimeout) if err != nil { return nil, nil, err } @@ -769,11 +790,19 @@ func (m *Memberlist) sendAndReceiveState(addr []byte, port uint16, join bool) ([ } conn.SetDeadline(time.Now().Add(m.config.TCPTimeout)) - msgType, bufConn, dec, err := m.readTCP(conn) + msgType, bufConn, dec, err := m.readStream(conn) if err != nil { return nil, nil, err } + if msgType == errMsg { + var resp errResp + if err := dec.Decode(&resp); err != nil { + return nil, nil, err + } + return nil, nil, fmt.Errorf("remote error: %v", resp.Error) + } + // Quit if not push/pull if msgType != pushPullMsg { err := fmt.Errorf("received invalid msgType (%d), expected pushPullMsg (%d) %s", msgType, pushPullMsg, LogConn(conn)) @@ -785,7 +814,7 @@ func (m *Memberlist) sendAndReceiveState(addr []byte, port uint16, join bool) ([ return remoteNodes, userState, err } -// sendLocalState is invoked to send our local state over a tcp connection +// sendLocalState is invoked to send our local state over a stream connection. func (m *Memberlist) sendLocalState(conn net.Conn, join bool) error { // Setup a deadline conn.SetDeadline(time.Now().Add(m.config.TCPTimeout)) @@ -843,7 +872,7 @@ func (m *Memberlist) sendLocalState(conn net.Conn, join bool) error { } // Get the send buffer - return m.rawSendMsgTCP(conn, bufConn.Bytes()) + return m.rawSendMsgStream(conn, bufConn.Bytes()) } // encryptLocalState is used to help encrypt local state before sending @@ -901,9 +930,9 @@ func (m *Memberlist) decryptRemoteState(bufConn io.Reader) ([]byte, error) { return decryptPayload(keys, cipherBytes, dataBytes) } -// readTCP is used to read the start of a TCP stream. -// it decrypts and decompresses the stream if necessary -func (m *Memberlist) readTCP(conn net.Conn) (messageType, io.Reader, *codec.Decoder, error) { +// readStream is used to read from a stream connection, decrypting and +// decompressing the stream if necessary. +func (m *Memberlist) readStream(conn net.Conn) (messageType, io.Reader, *codec.Decoder, error) { // Created a buffered reader var bufConn io.Reader = bufio.NewReader(conn) @@ -929,7 +958,7 @@ func (m *Memberlist) readTCP(conn net.Conn) (messageType, io.Reader, *codec.Deco // Reset message type and bufConn msgType = messageType(plain[0]) bufConn = bytes.NewReader(plain[1:]) - } else if m.config.EncryptionEnabled() { + } else if m.config.EncryptionEnabled() && m.config.GossipVerifyIncoming { return 0, nil, nil, fmt.Errorf("Encryption is configured but remote state is not encrypted") } @@ -1044,7 +1073,7 @@ func (m *Memberlist) mergeRemoteState(join bool, remoteNodes []pushNodeState, us return nil } -// readUserMsg is used to decode a userMsg from a TCP stream +// readUserMsg is used to decode a userMsg from a stream. func (m *Memberlist) readUserMsg(bufConn io.Reader, dec *codec.Decoder) error { // Read the user message header var header userMsgHeader @@ -1075,13 +1104,12 @@ func (m *Memberlist) readUserMsg(bufConn io.Reader, dec *codec.Decoder) error { return nil } -// sendPingAndWaitForAck makes a TCP connection to the given address, sends +// sendPingAndWaitForAck makes a stream connection to the given address, sends // a ping, and waits for an ack. All of this is done as a series of blocking // operations, given the deadline. The bool return parameter is true if we // we able to round trip a ping to the other node. -func (m *Memberlist) sendPingAndWaitForAck(destAddr net.Addr, ping ping, deadline time.Time) (bool, error) { - dialer := net.Dialer{Deadline: deadline} - conn, err := dialer.Dial("tcp", destAddr.String()) +func (m *Memberlist) sendPingAndWaitForAck(addr string, ping ping, deadline time.Time) (bool, error) { + conn, err := m.transport.DialTimeout(addr, deadline.Sub(time.Now())) if err != nil { // If the node is actually dead we expect this to fail, so we // shouldn't spam the logs with it. After this point, errors @@ -1097,17 +1125,17 @@ func (m *Memberlist) sendPingAndWaitForAck(destAddr net.Addr, ping ping, deadlin return false, err } - if err = m.rawSendMsgTCP(conn, out.Bytes()); err != nil { + if err = m.rawSendMsgStream(conn, out.Bytes()); err != nil { return false, err } - msgType, _, dec, err := m.readTCP(conn) + msgType, _, dec, err := m.readStream(conn) if err != nil { return false, err } if msgType != ackRespMsg { - return false, fmt.Errorf("Unexpected msgType (%d) from TCP ping %s", msgType, LogConn(conn)) + return false, fmt.Errorf("Unexpected msgType (%d) from ping %s", msgType, LogConn(conn)) } var ack ackResp @@ -1116,7 +1144,7 @@ func (m *Memberlist) sendPingAndWaitForAck(destAddr net.Addr, ping ping, deadlin } if ack.SeqNo != ping.SeqNo { - return false, fmt.Errorf("Sequence number from ack (%d) doesn't match ping (%d) from TCP ping %s", ack.SeqNo, ping.SeqNo, LogConn(conn)) + return false, fmt.Errorf("Sequence number from ack (%d) doesn't match ping (%d)", ack.SeqNo, ping.SeqNo) } return true, nil diff --git a/vendor/github.com/hashicorp/memberlist/net_transport.go b/vendor/github.com/hashicorp/memberlist/net_transport.go new file mode 100644 index 000000000..e7b88b01f --- /dev/null +++ b/vendor/github.com/hashicorp/memberlist/net_transport.go @@ -0,0 +1,289 @@ +package memberlist + +import ( + "fmt" + "log" + "net" + "sync" + "sync/atomic" + "time" + + "github.com/armon/go-metrics" + sockaddr "github.com/hashicorp/go-sockaddr" +) + +const ( + // udpPacketBufSize is used to buffer incoming packets during read + // operations. + udpPacketBufSize = 65536 + + // udpRecvBufSize is a large buffer size that we attempt to set UDP + // sockets to in order to handle a large volume of messages. + udpRecvBufSize = 2 * 1024 * 1024 +) + +// NetTransportConfig is used to configure a net transport. +type NetTransportConfig struct { + // BindAddrs is a list of addresses to bind to for both TCP and UDP + // communications. + BindAddrs []string + + // BindPort is the port to listen on, for each address above. + BindPort int + + // Logger is a logger for operator messages. + Logger *log.Logger +} + +// NetTransport is a Transport implementation that uses connectionless UDP for +// packet operations, and ad-hoc TCP connections for stream operations. +type NetTransport struct { + config *NetTransportConfig + packetCh chan *Packet + streamCh chan net.Conn + logger *log.Logger + wg sync.WaitGroup + tcpListeners []*net.TCPListener + udpListeners []*net.UDPConn + shutdown int32 +} + +// NewNetTransport returns a net transport with the given configuration. On +// success all the network listeners will be created and listening. +func NewNetTransport(config *NetTransportConfig) (*NetTransport, error) { + // If we reject the empty list outright we can assume that there's at + // least one listener of each type later during operation. + if len(config.BindAddrs) == 0 { + return nil, fmt.Errorf("At least one bind address is required") + } + + // Build out the new transport. + var ok bool + t := NetTransport{ + config: config, + packetCh: make(chan *Packet), + streamCh: make(chan net.Conn), + logger: config.Logger, + } + + // Clean up listeners if there's an error. + defer func() { + if !ok { + t.Shutdown() + } + }() + + // Build all the TCP and UDP listeners. + port := config.BindPort + for _, addr := range config.BindAddrs { + ip := net.ParseIP(addr) + + tcpAddr := &net.TCPAddr{IP: ip, Port: port} + tcpLn, err := net.ListenTCP("tcp", tcpAddr) + if err != nil { + return nil, fmt.Errorf("Failed to start TCP listener on %q port %d: %v", addr, port, err) + } + t.tcpListeners = append(t.tcpListeners, tcpLn) + + // If the config port given was zero, use the first TCP listener + // to pick an available port and then apply that to everything + // else. + if port == 0 { + port = tcpLn.Addr().(*net.TCPAddr).Port + } + + udpAddr := &net.UDPAddr{IP: ip, Port: port} + udpLn, err := net.ListenUDP("udp", udpAddr) + if err != nil { + return nil, fmt.Errorf("Failed to start UDP listener on %q port %d: %v", addr, port, err) + } + if err := setUDPRecvBuf(udpLn); err != nil { + return nil, fmt.Errorf("Failed to resize UDP buffer: %v", err) + } + t.udpListeners = append(t.udpListeners, udpLn) + } + + // Fire them up now that we've been able to create them all. + for i := 0; i < len(config.BindAddrs); i++ { + t.wg.Add(2) + go t.tcpListen(t.tcpListeners[i]) + go t.udpListen(t.udpListeners[i]) + } + + ok = true + return &t, nil +} + +// GetAutoBindPort returns the bind port that was automatically given by the +// kernel, if a bind port of 0 was given. +func (t *NetTransport) GetAutoBindPort() int { + // We made sure there's at least one TCP listener, and that one's + // port was applied to all the others for the dynamic bind case. + return t.tcpListeners[0].Addr().(*net.TCPAddr).Port +} + +// See Transport. +func (t *NetTransport) FinalAdvertiseAddr(ip string, port int) (net.IP, int, error) { + var advertiseAddr net.IP + var advertisePort int + if ip != "" { + // If they've supplied an address, use that. + advertiseAddr = net.ParseIP(ip) + if advertiseAddr == nil { + return nil, 0, fmt.Errorf("Failed to parse advertise address %q", ip) + } + + // Ensure IPv4 conversion if necessary. + if ip4 := advertiseAddr.To4(); ip4 != nil { + advertiseAddr = ip4 + } + advertisePort = port + } else { + if t.config.BindAddrs[0] == "0.0.0.0" { + // Otherwise, if we're not bound to a specific IP, let's + // use a suitable private IP address. + var err error + ip, err = sockaddr.GetPrivateIP() + if err != nil { + return nil, 0, fmt.Errorf("Failed to get interface addresses: %v", err) + } + if ip == "" { + return nil, 0, fmt.Errorf("No private IP address found, and explicit IP not provided") + } + + advertiseAddr = net.ParseIP(ip) + if advertiseAddr == nil { + return nil, 0, fmt.Errorf("Failed to parse advertise address: %q", ip) + } + } else { + // Use the IP that we're bound to, based on the first + // TCP listener, which we already ensure is there. + advertiseAddr = t.tcpListeners[0].Addr().(*net.TCPAddr).IP + } + + // Use the port we are bound to. + advertisePort = t.GetAutoBindPort() + } + + return advertiseAddr, advertisePort, nil +} + +// See Transport. +func (t *NetTransport) WriteTo(b []byte, addr string) (time.Time, error) { + udpAddr, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return time.Time{}, err + } + + // We made sure there's at least one UDP listener, so just use the + // packet sending interface on the first one. Take the time after the + // write call comes back, which will underestimate the time a little, + // but help account for any delays before the write occurs. + _, err = t.udpListeners[0].WriteTo(b, udpAddr) + return time.Now(), err +} + +// See Transport. +func (t *NetTransport) PacketCh() <-chan *Packet { + return t.packetCh +} + +// See Transport. +func (t *NetTransport) DialTimeout(addr string, timeout time.Duration) (net.Conn, error) { + dialer := net.Dialer{Timeout: timeout} + return dialer.Dial("tcp", addr) +} + +// See Transport. +func (t *NetTransport) StreamCh() <-chan net.Conn { + return t.streamCh +} + +// See Transport. +func (t *NetTransport) Shutdown() error { + // This will avoid log spam about errors when we shut down. + atomic.StoreInt32(&t.shutdown, 1) + + // Rip through all the connections and shut them down. + for _, conn := range t.tcpListeners { + conn.Close() + } + for _, conn := range t.udpListeners { + conn.Close() + } + + // Block until all the listener threads have died. + t.wg.Wait() + return nil +} + +// tcpListen is a long running goroutine that accepts incoming TCP connections +// and hands them off to the stream channel. +func (t *NetTransport) tcpListen(tcpLn *net.TCPListener) { + defer t.wg.Done() + for { + conn, err := tcpLn.AcceptTCP() + if err != nil { + if s := atomic.LoadInt32(&t.shutdown); s == 1 { + break + } + + t.logger.Printf("[ERR] memberlist: Error accepting TCP connection: %v", err) + continue + } + + t.streamCh <- conn + } +} + +// udpListen is a long running goroutine that accepts incoming UDP packets and +// hands them off to the packet channel. +func (t *NetTransport) udpListen(udpLn *net.UDPConn) { + defer t.wg.Done() + for { + // Do a blocking read into a fresh buffer. Grab a time stamp as + // close as possible to the I/O. + buf := make([]byte, udpPacketBufSize) + n, addr, err := udpLn.ReadFrom(buf) + ts := time.Now() + if err != nil { + if s := atomic.LoadInt32(&t.shutdown); s == 1 { + break + } + + t.logger.Printf("[ERR] memberlist: Error reading UDP packet: %v", err) + continue + } + + // Check the length - it needs to have at least one byte to be a + // proper message. + if n < 1 { + t.logger.Printf("[ERR] memberlist: UDP packet too short (%d bytes) %s", + len(buf), LogAddress(addr)) + continue + } + + // Ingest the packet. + metrics.IncrCounter([]string{"memberlist", "udp", "received"}, float32(n)) + t.packetCh <- &Packet{ + Buf: buf[:n], + From: addr, + Timestamp: ts, + } + } +} + +// setUDPRecvBuf is used to resize the UDP receive window. The function +// attempts to set the read buffer to `udpRecvBuf` but backs off until +// the read buffer can be set. +func setUDPRecvBuf(c *net.UDPConn) error { + size := udpRecvBufSize + var err error + for size > 0 { + if err = c.SetReadBuffer(size); err == nil { + return nil + } + size = size / 2 + } + return err +} diff --git a/vendor/github.com/hashicorp/memberlist/queue.go b/vendor/github.com/hashicorp/memberlist/queue.go index 994b90ff1..1185c9eb0 100644 --- a/vendor/github.com/hashicorp/memberlist/queue.go +++ b/vendor/github.com/hashicorp/memberlist/queue.go @@ -27,6 +27,26 @@ type limitedBroadcast struct { transmits int // Number of transmissions attempted. b Broadcast } + +// for testing; emits in transmit order if reverse=false +func (q *TransmitLimitedQueue) orderedView(reverse bool) []*limitedBroadcast { + q.Lock() + defer q.Unlock() + + out := make([]*limitedBroadcast, 0, len(q.bcQueue)) + if reverse { + for i := 0; i < len(q.bcQueue); i++ { + out = append(out, q.bcQueue[i]) + } + } else { + for i := len(q.bcQueue) - 1; i >= 0; i-- { + out = append(out, q.bcQueue[i]) + } + } + + return out +} + type limitedBroadcasts []*limitedBroadcast // Broadcast is something that can be broadcasted via gossip to diff --git a/vendor/github.com/hashicorp/memberlist/state.go b/vendor/github.com/hashicorp/memberlist/state.go index 6b9122f08..6caded313 100644 --- a/vendor/github.com/hashicorp/memberlist/state.go +++ b/vendor/github.com/hashicorp/memberlist/state.go @@ -34,6 +34,17 @@ type Node struct { DCur uint8 // Current version delegate is speaking } +// Address returns the host:port form of a node's address, suitable for use +// with a transport. +func (n *Node) Address() string { + return joinHostPort(n.Addr.String(), n.Port) +} + +// String returns the node name +func (n *Node) String() string { + return n.Name +} + // NodeState is used to manage our state view of another node type nodeState struct { Node @@ -42,6 +53,12 @@ type nodeState struct { StateChange time.Time // Time last state change happened } +// Address returns the host:port form of a node's address, suitable for use +// with a transport. +func (n *nodeState) Address() string { + return n.Node.Address() +} + // ackHandler is used to register handlers for incoming acks and nacks. type ackHandler struct { ackFn func([]byte, time.Time) @@ -216,6 +233,15 @@ START: m.probeNode(&node) } +// probeNodeByAddr just safely calls probeNode given only the address of the node (for tests) +func (m *Memberlist) probeNodeByAddr(addr string) { + m.nodeLock.RLock() + n := m.nodeMap[addr] + m.nodeLock.RUnlock() + + m.probeNode(n) +} + // probeNode handles a single round of failure checking on a node. func (m *Memberlist) probeNode(node *nodeState) { defer metrics.MeasureSince([]string{"memberlist", "probeNode"}, time.Now()) @@ -234,13 +260,20 @@ func (m *Memberlist) probeNode(node *nodeState) { nackCh := make(chan struct{}, m.config.IndirectChecks+1) m.setProbeChannels(ping.SeqNo, ackCh, nackCh, probeInterval) + // Mark the sent time here, which should be after any pre-processing but + // before system calls to do the actual send. This probably over-reports + // a bit, but it's the best we can do. We had originally put this right + // after the I/O, but that would sometimes give negative RTT measurements + // which was not desirable. + sent := time.Now() + // Send a ping to the node. If this node looks like it's suspect or dead, // also tack on a suspect message so that it has a chance to refute as // soon as possible. - deadline := time.Now().Add(probeInterval) - destAddr := &net.UDPAddr{IP: node.Addr, Port: int(node.Port)} + deadline := sent.Add(probeInterval) + addr := node.Address() if node.State == stateAlive { - if err := m.encodeAndSendMsg(destAddr, pingMsg, &ping); err != nil { + if err := m.encodeAndSendMsg(addr, pingMsg, &ping); err != nil { m.logger.Printf("[ERR] memberlist: Failed to send ping: %s", err) return } @@ -261,17 +294,12 @@ func (m *Memberlist) probeNode(node *nodeState) { } compound := makeCompoundMessage(msgs) - if err := m.rawSendMsgUDP(destAddr, &node.Node, compound.Bytes()); err != nil { - m.logger.Printf("[ERR] memberlist: Failed to send compound ping and suspect message to %s: %s", destAddr, err) + if err := m.rawSendMsgPacket(addr, &node.Node, compound.Bytes()); err != nil { + m.logger.Printf("[ERR] memberlist: Failed to send compound ping and suspect message to %s: %s", addr, err) return } } - // Mark the sent time here, which should be after any pre-processing and - // system calls to do the actual send. This probably under-reports a bit, - // but it's the best we can do. - sent := time.Now() - // Arrange for our self-awareness to get updated. At this point we've // sent the ping, so any return statement means the probe succeeded // which will improve our health until we get to the failure scenarios @@ -305,7 +333,7 @@ func (m *Memberlist) probeNode(node *nodeState) { // probe interval it will give the TCP fallback more time, which // is more active in dealing with lost packets, and it gives more // time to wait for indirect acks/nacks. - m.logger.Printf("[DEBUG] memberlist: Failed UDP ping: %v (timeout reached)", node.Name) + m.logger.Printf("[DEBUG] memberlist: Failed ping: %v (timeout reached)", node.Name) } // Get some random live nodes. @@ -327,8 +355,7 @@ func (m *Memberlist) probeNode(node *nodeState) { expectedNacks++ } - destAddr := &net.UDPAddr{IP: peer.Addr, Port: int(peer.Port)} - if err := m.encodeAndSendMsg(destAddr, indirectPingMsg, &ind); err != nil { + if err := m.encodeAndSendMsg(peer.Address(), indirectPingMsg, &ind); err != nil { m.logger.Printf("[ERR] memberlist: Failed to send indirect ping: %s", err) } } @@ -345,12 +372,11 @@ func (m *Memberlist) probeNode(node *nodeState) { // config option to turn this off if desired. fallbackCh := make(chan bool, 1) if (!m.config.DisableTcpPings) && (node.PMax >= 3) { - destAddr := &net.TCPAddr{IP: node.Addr, Port: int(node.Port)} go func() { defer close(fallbackCh) - didContact, err := m.sendPingAndWaitForAck(destAddr, ping, deadline) + didContact, err := m.sendPingAndWaitForAck(node.Address(), ping, deadline) if err != nil { - m.logger.Printf("[ERR] memberlist: Failed TCP fallback ping: %s", err) + m.logger.Printf("[ERR] memberlist: Failed fallback ping: %s", err) } else { fallbackCh <- didContact } @@ -375,7 +401,7 @@ func (m *Memberlist) probeNode(node *nodeState) { // any additional time here. for didContact := range fallbackCh { if didContact { - m.logger.Printf("[WARN] memberlist: Was able to reach %s via TCP but not UDP, network may be misconfigured and not allowing bidirectional UDP", node.Name) + m.logger.Printf("[WARN] memberlist: Was able to connect to %s but other probes failed, network may be misconfigured", node.Name) return } } @@ -390,7 +416,7 @@ func (m *Memberlist) probeNode(node *nodeState) { awarenessDelta = 0 if expectedNacks > 0 { if nackCount := len(nackCh); nackCount < expectedNacks { - awarenessDelta += 2 * (expectedNacks - nackCount) + awarenessDelta += (expectedNacks - nackCount) } } else { awarenessDelta += 1 @@ -410,7 +436,7 @@ func (m *Memberlist) Ping(node string, addr net.Addr) (time.Duration, error) { m.setProbeChannels(ping.SeqNo, ackCh, nil, m.config.ProbeInterval) // Send a ping to the node. - if err := m.encodeAndSendMsg(addr, pingMsg, &ping); err != nil { + if err := m.encodeAndSendMsg(addr.String(), pingMsg, &ping); err != nil { return 0, err } @@ -496,18 +522,17 @@ func (m *Memberlist) gossip() { return } - destAddr := &net.UDPAddr{IP: node.Addr, Port: int(node.Port)} - + addr := node.Address() if len(msgs) == 1 { // Send single message as is - if err := m.rawSendMsgUDP(destAddr, &node.Node, msgs[0]); err != nil { - m.logger.Printf("[ERR] memberlist: Failed to send gossip to %s: %s", destAddr, err) + if err := m.rawSendMsgPacket(addr, &node.Node, msgs[0]); err != nil { + m.logger.Printf("[ERR] memberlist: Failed to send gossip to %s: %s", addr, err) } } else { // Otherwise create and send a compound message compound := makeCompoundMessage(msgs) - if err := m.rawSendMsgUDP(destAddr, &node.Node, compound.Bytes()); err != nil { - m.logger.Printf("[ERR] memberlist: Failed to send gossip to %s: %s", destAddr, err) + if err := m.rawSendMsgPacket(addr, &node.Node, compound.Bytes()); err != nil { + m.logger.Printf("[ERR] memberlist: Failed to send gossip to %s: %s", addr, err) } } } @@ -533,17 +558,17 @@ func (m *Memberlist) pushPull() { node := nodes[0] // Attempt a push pull - if err := m.pushPullNode(node.Addr, node.Port, false); err != nil { + if err := m.pushPullNode(node.Address(), false); err != nil { m.logger.Printf("[ERR] memberlist: Push/Pull with %s failed: %s", node.Name, err) } } // pushPullNode does a complete state exchange with a specific node. -func (m *Memberlist) pushPullNode(addr []byte, port uint16, join bool) error { +func (m *Memberlist) pushPullNode(addr string, join bool) error { defer metrics.MeasureSince([]string{"memberlist", "pushPullNode"}, time.Now()) // Attempt to send and receive with the node - remote, userState, err := m.sendAndReceiveState(addr, port, join) + remote, userState, err := m.sendAndReceiveState(addr, join) if err != nil { return err } @@ -821,7 +846,7 @@ func (m *Memberlist) aliveNode(a *alive, notify chan struct{}, bootstrap bool) { // in-queue to be processed but blocked by the locks above. If we let // that aliveMsg process, it'll cause us to re-join the cluster. This // ensures that we don't. - if m.leave && a.Node == m.config.Name { + if m.hasLeft() && a.Node == m.config.Name { return } @@ -1097,7 +1122,7 @@ func (m *Memberlist) deadNode(d *dead) { // Check if this is us if state.Name == m.config.Name { // If we are not leaving we need to refute - if !m.leave { + if !m.hasLeft() { m.refute(state, d.Incarnation) m.logger.Printf("[WARN] memberlist: Refuting a dead message (from: %s)", d.From) return // Do not mark ourself dead diff --git a/vendor/github.com/hashicorp/memberlist/suspicion.go b/vendor/github.com/hashicorp/memberlist/suspicion.go index 5f573e1fc..f8aa9e20a 100644 --- a/vendor/github.com/hashicorp/memberlist/suspicion.go +++ b/vendor/github.com/hashicorp/memberlist/suspicion.go @@ -117,7 +117,7 @@ func (s *suspicion) Confirm(from string) bool { // stop the timer then we will call the timeout function directly from // here. n := atomic.AddInt32(&s.n, 1) - elapsed := time.Now().Sub(s.start) + elapsed := time.Since(s.start) remaining := remainingSuspicionTime(n, s.k, elapsed, s.min, s.max) if s.timer.Stop() { if remaining > 0 { diff --git a/vendor/github.com/hashicorp/memberlist/tag.sh b/vendor/github.com/hashicorp/memberlist/tag.sh new file mode 100755 index 000000000..cd16623a7 --- /dev/null +++ b/vendor/github.com/hashicorp/memberlist/tag.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -e + +# The version must be supplied from the environment. Do not include the +# leading "v". +if [ -z $VERSION ]; then + echo "Please specify a version." + exit 1 +fi + +# Generate the tag. +echo "==> Tagging version $VERSION..." +git commit --allow-empty -a --gpg-sign=348FFC4C -m "Release v$VERSION" +git tag -a -m "Version $VERSION" -s -u 348FFC4C "v${VERSION}" master + +exit 0 diff --git a/vendor/github.com/hashicorp/memberlist/transport.go b/vendor/github.com/hashicorp/memberlist/transport.go new file mode 100644 index 000000000..6ce55ea47 --- /dev/null +++ b/vendor/github.com/hashicorp/memberlist/transport.go @@ -0,0 +1,65 @@ +package memberlist + +import ( + "net" + "time" +) + +// Packet is used to provide some metadata about incoming packets from peers +// over a packet connection, as well as the packet payload. +type Packet struct { + // Buf has the raw contents of the packet. + Buf []byte + + // From has the address of the peer. This is an actual net.Addr so we + // can expose some concrete details about incoming packets. + From net.Addr + + // Timestamp is the time when the packet was received. This should be + // taken as close as possible to the actual receipt time to help make an + // accurate RTT measurement during probes. + Timestamp time.Time +} + +// Transport is used to abstract over communicating with other peers. The packet +// interface is assumed to be best-effort and the stream interface is assumed to +// be reliable. +type Transport interface { + // FinalAdvertiseAddr is given the user's configured values (which + // might be empty) and returns the desired IP and port to advertise to + // the rest of the cluster. + FinalAdvertiseAddr(ip string, port int) (net.IP, int, error) + + // WriteTo is a packet-oriented interface that fires off the given + // payload to the given address in a connectionless fashion. This should + // return a time stamp that's as close as possible to when the packet + // was transmitted to help make accurate RTT measurements during probes. + // + // This is similar to net.PacketConn, though we didn't want to expose + // that full set of required methods to keep assumptions about the + // underlying plumbing to a minimum. We also treat the address here as a + // string, similar to Dial, so it's network neutral, so this usually is + // in the form of "host:port". + WriteTo(b []byte, addr string) (time.Time, error) + + // PacketCh returns a channel that can be read to receive incoming + // packets from other peers. How this is set up for listening is left as + // an exercise for the concrete transport implementations. + PacketCh() <-chan *Packet + + // DialTimeout is used to create a connection that allows us to perform + // two-way communication with a peer. This is generally more expensive + // than packet connections so is used for more infrequent operations + // such as anti-entropy or fallback probes if the packet-oriented probe + // failed. + DialTimeout(addr string, timeout time.Duration) (net.Conn, error) + + // StreamCh returns a channel that can be read to handle incoming stream + // connections from other peers. How this is set up for listening is + // left as an exercise for the concrete transport implementations. + StreamCh() <-chan net.Conn + + // Shutdown is called when memberlist is shutting down; this gives the + // transport a chance to clean up any listeners. + Shutdown() error +} diff --git a/vendor/github.com/hashicorp/memberlist/util.go b/vendor/github.com/hashicorp/memberlist/util.go index 2ee58ba10..1e582a8a1 100644 --- a/vendor/github.com/hashicorp/memberlist/util.go +++ b/vendor/github.com/hashicorp/memberlist/util.go @@ -8,6 +8,8 @@ import ( "io" "math" "math/rand" + "net" + "strconv" "strings" "time" @@ -76,10 +78,9 @@ func retransmitLimit(retransmitMult, n int) int { // shuffleNodes randomly shuffles the input nodes using the Fisher-Yates shuffle func shuffleNodes(nodes []*nodeState) { n := len(nodes) - for i := n - 1; i > 0; i-- { - j := rand.Intn(i + 1) + rand.Shuffle(n, func(i, j int) { nodes[i], nodes[j] = nodes[j], nodes[i] - } + }) } // pushPushScale is used to scale the time interval at which push/pull @@ -215,20 +216,6 @@ func decodeCompoundMessage(buf []byte) (trunc int, parts [][]byte, err error) { return } -// Given a string of the form "host", "host:port", -// "ipv6::addr" or "[ipv6::address]:port", -// return true if the string includes a port. -func hasPort(s string) bool { - last := strings.LastIndex(s, ":") - if last == -1 { - return false - } - if s[0] == '[' { - return s[last-1] == ']' - } - return strings.Index(s, ":") == last -} - // compressPayload takes an opaque input buffer, compresses it // and wraps it in a compress{} message that is encoded. func compressPayload(inp []byte) (*bytes.Buffer, error) { @@ -286,3 +273,37 @@ func decompressBuffer(c *compress) ([]byte, error) { // Return the uncompressed bytes return b.Bytes(), nil } + +// joinHostPort returns the host:port form of an address, for use with a +// transport. +func joinHostPort(host string, port uint16) string { + return net.JoinHostPort(host, strconv.Itoa(int(port))) +} + +// hasPort is given a string of the form "host", "host:port", "ipv6::address", +// or "[ipv6::address]:port", and returns true if the string includes a port. +func hasPort(s string) bool { + // IPv6 address in brackets. + if strings.LastIndex(s, "[") == 0 { + return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") + } + + // Otherwise the presence of a single colon determines if there's a port + // since IPv6 addresses outside of brackets (count > 1) can't have a + // port. + return strings.Count(s, ":") == 1 +} + +// ensurePort makes sure the given string has a port number on it, otherwise it +// appends the given port as a default. +func ensurePort(s string, port int) string { + if hasPort(s) { + return s + } + + // If this is an IPv6 address, the join call will add another set of + // brackets, so we have to trim before we add the default port. + s = strings.Trim(s, "[]") + s = net.JoinHostPort(s, strconv.Itoa(port)) + return s +} diff --git a/vendor/vendor.json b/vendor/vendor.json index f724f07d8..0b07d500f 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -216,7 +216,7 @@ {"path":"github.com/hashicorp/hcl2/hcldec","checksumSHA1":"wQ3hLj4s+5jN6LePSpT0XTTvdXA=","revision":"6743a2254ba3d642b7d3a0be506259a0842819ac","revisionTime":"2018-08-10T01:10:00Z"}, {"path":"github.com/hashicorp/hcl2/hclparse","checksumSHA1":"IzmftuG99BqNhbFGhxZaGwtiMtM=","revision":"6743a2254ba3d642b7d3a0be506259a0842819ac","revisionTime":"2018-08-10T01:10:00Z"}, {"path":"github.com/hashicorp/logutils","checksumSHA1":"vt+P9D2yWDO3gdvdgCzwqunlhxU=","revision":"0dc08b1671f34c4250ce212759ebd880f743d883"}, - {"path":"github.com/hashicorp/memberlist","checksumSHA1":"1zk7IeGClUqBo+Phsx89p7fQ/rQ=","revision":"23ad4b7d7b38496cd64c241dfd4c60b7794c254a","revisionTime":"2017-02-08T21:15:06Z"}, + {"path":"github.com/hashicorp/memberlist","checksumSHA1":"pd6KJd+33bGQ6oc+2X+ZvqgSAGI=","revision":"2072f3a3ff4b7b3d830be77678d5d4b978362bc4","revisionTime":"2018-10-22T22:19:44Z"}, {"path":"github.com/hashicorp/net-rpc-msgpackrpc","checksumSHA1":"qnlqWJYV81ENr61SZk9c65R1mDo=","revision":"a14192a58a694c123d8fe5481d4a4727d6ae82f3"}, {"path":"github.com/hashicorp/raft","checksumSHA1":"zkA9uvbj1BdlveyqXpVTh1N6ers=","revision":"077966dbc90f342107eb723ec52fdb0463ec789b","revisionTime":"2018-01-17T20:29:25Z","version":"master","versionExact":"master"}, {"path":"github.com/hashicorp/raft-boltdb","checksumSHA1":"QAxukkv54/iIvLfsUP6IK4R0m/A=","revision":"d1e82c1ec3f15ee991f7cc7ffd5b67ff6f5bbaee","revisionTime":"2015-02-01T20:08:39Z"}, From 3921793030877804921108bdb4bdcb0a46b25bb0 Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Fri, 7 Dec 2018 18:35:47 -0600 Subject: [PATCH 30/71] Score combinations of allocs from multiple devices for preemption --- scheduler/preemption.go | 37 ++++++++++++++++- scheduler/preemption_test.go | 77 +++++++++++++++++++++++++++++++++++- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/scheduler/preemption.go b/scheduler/preemption.go index 18d47eaca..90edcd94d 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -498,6 +498,7 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev neededCount := ask.Count + var preemptionOptions [][]*structs.Allocation // Examine matching allocs by device for deviceIDTuple, allocsGrp := range deviceToAllocs { // First group and sort allocations using this device by priority @@ -520,15 +521,49 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev // Check if we met needed count if preemptedCount+devInst.FreeCount() >= int(neededCount) { - return preemptedAllocs + preemptionOptions = append(preemptionOptions, preemptedAllocs) } } } } + // Find the combination of allocs with lowest net priority + if len(preemptionOptions) > 0 { + return selectBestAllocs(preemptionOptions) + } + return nil } +// selectBestAllocs finds the best allocations based on minimal net priority amongst +// all options. The net priority is the sum of unique priorities in each option +func selectBestAllocs(allocSets [][]*structs.Allocation) []*structs.Allocation { + if len(allocSets) == 1 { + return allocSets[0] + } + bestPriority := math.MaxInt32 + var bestAllocs []*structs.Allocation + + for _, allocs := range allocSets { + // Find unique priorities and add them + priorities := map[int]struct{}{} + netPriority := 0 + for _, alloc := range allocs { + _, ok := priorities[alloc.Job.Priority] + if !ok { + priorities[alloc.Job.Priority] = struct{}{} + netPriority += alloc.Job.Priority + } + } + if netPriority < bestPriority { + bestPriority = netPriority + bestAllocs = allocs + } + + } + return bestAllocs +} + // basicResourceDistance computes a distance using a coordinate system. It compares resource fields like CPU/Memory and Disk. // Values emitted are in the range [0, maxFloat] func basicResourceDistance(resourceAsk *structs.ComparableResources, resourceUsed *structs.ComparableResources) float64 { diff --git a/scheduler/preemption_test.go b/scheduler/preemption_test.go index b526cac3c..edbb71fb0 100644 --- a/scheduler/preemption_test.go +++ b/scheduler/preemption_test.go @@ -160,7 +160,7 @@ func TestPreemption(t *testing.T) { lowPrioJob.Priority = 30 lowPrioJob2 := mock.Job() - lowPrioJob2.Priority = 30 + lowPrioJob2.Priority = 40 // Create some persistent alloc ids to use in test cases allocIDs := []string{uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate()} @@ -1072,6 +1072,81 @@ func TestPreemption(t *testing.T) { allocIDs[3]: {}, }, }, + { + // This test cases creates allocations across two GPUs + // Both GPUs are eligible for the task, but only allocs with the lower + // priority are chosen + desc: "Preemption with allocs across multiple devices that match", + currentAllocations: []*structs.Allocation{ + createAllocWithDevice(allocIDs[0], lowPrioJob, &structs.Resources{ + CPU: 500, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + DeviceIDs: []string{deviceIDs[0], deviceIDs[1]}, + }), + createAllocWithDevice(allocIDs[1], lowPrioJob2, &structs.Resources{ + CPU: 200, + MemoryMB: 100, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "1080ti", + DeviceIDs: []string{deviceIDs[2], deviceIDs[3]}, + }), + createAllocWithDevice(allocIDs[2], lowPrioJob, &structs.Resources{ + CPU: 200, + MemoryMB: 256, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "2080ti", + DeviceIDs: []string{deviceIDs[4], deviceIDs[5]}, + }), + createAllocWithDevice(allocIDs[3], lowPrioJob, &structs.Resources{ + CPU: 100, + MemoryMB: 256, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "2080ti", + DeviceIDs: []string{deviceIDs[6], deviceIDs[7]}, + }), + createAllocWithDevice(allocIDs[4], lowPrioJob, &structs.Resources{ + CPU: 200, + MemoryMB: 512, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "fpga", + Vendor: "intel", + Name: "F100", + DeviceIDs: []string{"fpga1"}, + })}, + nodeReservedCapacity: reservedNodeResources, + nodeCapacity: defaultNodeResources, + jobPriority: 100, + resourceAsk: &structs.Resources{ + CPU: 1000, + MemoryMB: 512, + DiskMB: 4 * 1024, + Devices: []*structs.RequestedDevice{ + { + Name: "gpu", + Count: 4, + }, + }, + }, + preemptedAllocIDs: map[string]struct{}{ + allocIDs[2]: {}, + allocIDs[3]: {}, + }, + }, { desc: "Device preemption not possible due to more instances needed than available", currentAllocations: []*structs.Allocation{ From 070ed8b654978b1d78645eb75e46c0903f1b19d5 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 8 Dec 2018 09:58:23 -0500 Subject: [PATCH 31/71] fix dtestutil.NewDriverHarness ref --- drivers/exec/driver_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/exec/driver_test.go b/drivers/exec/driver_test.go index f2b04f4d5..325687b7a 100644 --- a/drivers/exec/driver_test.go +++ b/drivers/exec/driver_test.go @@ -173,7 +173,7 @@ func TestExecDriver_StartWaitStopKill(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "test", From bf17eae7c30c7cc7c5608687b684cc662a4dea02 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Thu, 6 Dec 2018 07:10:22 -0500 Subject: [PATCH 32/71] devices/nvidia: memory state as the summary stat --- devices/gpu/nvidia/stats.go | 2 +- devices/gpu/nvidia/stats_test.go | 180 +++++++++++++++++-------------- 2 files changed, 103 insertions(+), 79 deletions(-) diff --git a/devices/gpu/nvidia/stats.go b/devices/gpu/nvidia/stats.go index 6bbcd10e1..529b4e3c0 100644 --- a/devices/gpu/nvidia/stats.go +++ b/devices/gpu/nvidia/stats.go @@ -286,7 +286,7 @@ func statsForItem(statsItem *nvml.StatsData, timestamp time.Time) *device.Device } } return &device.DeviceStats{ - Summary: temperatureStat, + Summary: memoryStateStat, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ PowerUsageAttr: powerUsageStat, diff --git a/devices/gpu/nvidia/stats_test.go b/devices/gpu/nvidia/stats_test.go index 2c7d31559..f6221e0f4 100644 --- a/devices/gpu/nvidia/stats_test.go +++ b/devices/gpu/nvidia/stats_test.go @@ -447,9 +447,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -541,9 +542,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -634,9 +636,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -727,9 +730,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -821,9 +825,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -915,9 +920,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1009,9 +1015,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1103,9 +1110,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - StringVal: helper.StringToPtr(notAvailable), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1197,9 +1205,9 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + StringVal: helper.StringToPtr(notAvailable), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1290,9 +1298,9 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + StringVal: helper.StringToPtr(notAvailable), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1383,9 +1391,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1476,9 +1485,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1569,9 +1579,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1663,9 +1674,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1757,9 +1769,10 @@ func TestStatsForItem(t *testing.T) { }, ExpectedResult: &device.DeviceStats{ Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1913,9 +1926,10 @@ func TestStatsForGroup(t *testing.T) { InstanceStats: map[string]*device.DeviceStats{ "UUID1": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -1983,9 +1997,10 @@ func TestStatsForGroup(t *testing.T) { }, "UUID2": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(2), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(2), + IntDenominatorVal: helper.Int64ToPtr(2), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2053,9 +2068,10 @@ func TestStatsForGroup(t *testing.T) { }, "UUID3": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(3), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(3), + IntDenominatorVal: helper.Int64ToPtr(3), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2234,9 +2250,10 @@ func TestWriteStatsToChannel(t *testing.T) { InstanceStats: map[string]*device.DeviceStats{ "UUID1": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2311,9 +2328,10 @@ func TestWriteStatsToChannel(t *testing.T) { InstanceStats: map[string]*device.DeviceStats{ "UUID2": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(2), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(2), + IntDenominatorVal: helper.Int64ToPtr(2), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2388,9 +2406,10 @@ func TestWriteStatsToChannel(t *testing.T) { InstanceStats: map[string]*device.DeviceStats{ "UUID3": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(3), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(3), + IntDenominatorVal: helper.Int64ToPtr(3), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2545,9 +2564,10 @@ func TestWriteStatsToChannel(t *testing.T) { InstanceStats: map[string]*device.DeviceStats{ "UUID1": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2622,9 +2642,10 @@ func TestWriteStatsToChannel(t *testing.T) { InstanceStats: map[string]*device.DeviceStats{ "UUID3": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(3), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(3), + IntDenominatorVal: helper.Int64ToPtr(3), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2692,9 +2713,10 @@ func TestWriteStatsToChannel(t *testing.T) { }, "UUID2": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(2), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(2), + IntDenominatorVal: helper.Int64ToPtr(2), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2848,9 +2870,10 @@ func TestWriteStatsToChannel(t *testing.T) { InstanceStats: map[string]*device.DeviceStats{ "UUID1": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(1), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(1), + IntDenominatorVal: helper.Int64ToPtr(1), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ @@ -2925,9 +2948,10 @@ func TestWriteStatsToChannel(t *testing.T) { InstanceStats: map[string]*device.DeviceStats{ "UUID2": { Summary: &structs.StatValue{ - Unit: TemperatureUnit, - Desc: TemperatureDesc, - IntNumeratorVal: helper.Int64ToPtr(2), + Unit: MemoryStateUnit, + Desc: MemoryStateDesc, + IntNumeratorVal: helper.Int64ToPtr(2), + IntDenominatorVal: helper.Int64ToPtr(2), }, Stats: &structs.StatObject{ Attributes: map[string]*structs.StatValue{ From 612f79bd454491fc5e2a36e940df82105d3d3f80 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Mon, 10 Dec 2018 10:33:34 -0500 Subject: [PATCH 33/71] Rename helper_stats -> helper_devices --- command/{helper_stats.go => helper_devices.go} | 0 command/{helper_stats_test.go => helper_devices_test.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename command/{helper_stats.go => helper_devices.go} (100%) rename command/{helper_stats_test.go => helper_devices_test.go} (100%) diff --git a/command/helper_stats.go b/command/helper_devices.go similarity index 100% rename from command/helper_stats.go rename to command/helper_devices.go diff --git a/command/helper_stats_test.go b/command/helper_devices_test.go similarity index 100% rename from command/helper_stats_test.go rename to command/helper_devices_test.go From a802984c9ad9d3b7523f76771fe217c600597ce3 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Mon, 10 Dec 2018 11:51:43 -0500 Subject: [PATCH 34/71] device attributes in `nomad node status -verbose` This reports device attributes like the following: ``` $ nomad node status -self -verbose ID = f7adb958-29e1-2a5a-2303-9d61ffaab33a Name = mars.local Class = DC = dc1 Drain = false Eligibility = eligible Status = ready Uptime = 12h40m13s Drivers Driver Detected Healthy Message Time docker true true healthy 2018-12-10T11:47:19-05:00 ... Attributes cpu.arch = amd64 cpu.frequency = 2200 cpu.modelname = Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz cpu.numcores = 12 ... Device Group Attributes Device Group = nomad/file/mock block_device = sda1 filesystem = ext4 size = 63.2 GB Meta ``` --- api/nodes.go | 1 - api/resources.go | 41 +++++++++++++++++++++++++++++----- command/helper_devices.go | 12 ++++++++++ command/helper_devices_test.go | 26 +++++++++++++++++++++ command/node_status.go | 27 ++++++++++++++++++++++ 5 files changed, 101 insertions(+), 6 deletions(-) diff --git a/api/nodes.go b/api/nodes.go index 74381cb83..bfed5d8eb 100644 --- a/api/nodes.go +++ b/api/nodes.go @@ -683,7 +683,6 @@ func (v *StatValue) String() string { } return str case v.IntNumeratorVal != nil: - str := strconv.FormatInt(*v.IntNumeratorVal, 10) if v.IntDenominatorVal != nil { str += " / " + strconv.FormatInt(*v.IntDenominatorVal, 10) diff --git a/api/resources.go b/api/resources.go index e21387769..767d82625 100644 --- a/api/resources.go +++ b/api/resources.go @@ -1,6 +1,10 @@ package api -import "github.com/hashicorp/nomad/helper" +import ( + "strconv" + + "github.com/hashicorp/nomad/helper" +) // Resources encapsulates the required resources of // a given task or task group. @@ -125,6 +129,10 @@ type NodeDeviceResource struct { Attributes map[string]*Attribute } +func (r NodeDeviceResource) ID() string { + return r.Vendor + "/" + r.Type + "/" + r.Name +} + // NodeDevice is an instance of a particular device. type NodeDevice struct { // ID is the ID of the device. @@ -146,21 +154,44 @@ type NodeDevice struct { // specifying units type Attribute struct { // Float is the float value for the attribute - Float *float64 + FloatVal *float64 `json:"Float,omitempty"` // Int is the int value for the attribute - Int *int64 + IntVal *int64 `json:"Int,omitempty"` // String is the string value for the attribute - String *string + StringVal *string `json:"String,omitempty"` // Bool is the bool value for the attribute - Bool *bool + BoolVal *bool `json:"Bool,omitempty"` // Unit is the optional unit for the set int or float value Unit string } +func (a Attribute) String() string { + switch { + case a.FloatVal != nil: + str := strconv.FormatFloat(*a.FloatVal, 'f', -1, 64) + if a.Unit != "" { + str += " " + a.Unit + } + return str + case a.IntVal != nil: + str := strconv.FormatInt(*a.IntVal, 10) + if a.Unit != "" { + str += " " + a.Unit + } + return str + case a.StringVal != nil: + return *a.StringVal + case a.BoolVal != nil: + return strconv.FormatBool(*a.BoolVal) + default: + return "" + } +} + // NodeDeviceLocality stores information about the devices hardware locality on // the node. type NodeDeviceLocality struct { diff --git a/command/helper_devices.go b/command/helper_devices.go index 6bdce2d97..ba88cb3fd 100644 --- a/command/helper_devices.go +++ b/command/helper_devices.go @@ -109,3 +109,15 @@ func printDeviceStats(ui cli.Ui, deviceGroupStats []*api.DeviceGroupStats) { } } } + +func getDeviceAttributes(d *api.NodeDeviceResource) []string { + attrs := []string{fmt.Sprintf("Device Group|%s", d.ID())} + + for k, v := range d.Attributes { + attrs = append(attrs, k+"|"+v.String()) + } + + sort.Strings(attrs[1:]) + + return attrs +} diff --git a/command/helper_devices_test.go b/command/helper_devices_test.go index 5c71582fa..028d72701 100644 --- a/command/helper_devices_test.go +++ b/command/helper_devices_test.go @@ -247,3 +247,29 @@ func TestNodeStatusCommand_GetDeviceResources(t *testing.T) { assert.Equal(t, expected, formattedDevices) } +func TestGetDeviceAttributes(t *testing.T) { + d := &api.NodeDeviceResource{ + Vendor: "Vendor", + Type: "Type", + Name: "Name", + + Attributes: map[string]*api.Attribute{ + "utilization": &api.Attribute{ + FloatVal: helper.Float64ToPtr(0.78), + Unit: "%", + }, + "filesystem": &api.Attribute{ + StringVal: helper.StringToPtr("ext4"), + }, + }, + } + + formattedDevices := getDeviceAttributes(d) + expected := []string{ + "Device Group|Vendor/Type/Name", + "filesystem|ext4", + "utilization|0.78 %", + } + + assert.Equal(t, expected, formattedDevices) +} diff --git a/command/node_status.go b/command/node_status.go index f722feda1..0785181a7 100644 --- a/command/node_status.go +++ b/command/node_status.go @@ -419,6 +419,7 @@ func (c *NodeStatusCommand) formatNode(client *api.Client, node *api.Node) int { if c.verbose { c.formatAttributes(node) + c.formatDeviceAttributes(node) c.formatMeta(node) } return 0 @@ -529,6 +530,32 @@ func (c *NodeStatusCommand) formatAttributes(node *api.Node) { c.Ui.Output(formatKV(attributes)) } +func (c *NodeStatusCommand) formatDeviceAttributes(node *api.Node) { + devices := node.NodeResources.Devices + if len(devices) == 0 { + return + } + + sort.Slice(devices, func(i, j int) bool { + return devices[i].ID() < devices[j].ID() + }) + + first := true + for _, d := range devices { + if len(d.Attributes) == 0 { + continue + } + + if first { + c.Ui.Output("\nDevice Group Attributes") + first = false + } else { + c.Ui.Output("") + } + c.Ui.Output(formatKV(getDeviceAttributes(d))) + } +} + func (c *NodeStatusCommand) formatMeta(node *api.Node) { // Print the meta keys := make([]string, 0, len(node.Meta)) From 40164b3dc68cffec818473dd03531c2b14fa866c Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Mon, 10 Dec 2018 12:17:00 -0500 Subject: [PATCH 35/71] Use max 3 precision in displaying floats When formating floats in `nomad node status`, use a maximum precision of 3. --- api/nodes.go | 5 +++-- api/resources.go | 2 +- helper/funcs.go | 25 +++++++++++++++++++++++++ helper/funcs_test.go | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/api/nodes.go b/api/nodes.go index bfed5d8eb..bf7709fea 100644 --- a/api/nodes.go +++ b/api/nodes.go @@ -7,6 +7,7 @@ import ( "strconv" "time" + "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/nomad/structs" ) @@ -673,9 +674,9 @@ func (v *StatValue) String() string { case v.StringVal != nil: return *v.StringVal case v.FloatNumeratorVal != nil: - str := strconv.FormatFloat(*v.FloatNumeratorVal, 'f', -1, 64) + str := helper.FormatFloat(*v.FloatNumeratorVal, 3) if v.FloatDenominatorVal != nil { - str += " / " + strconv.FormatFloat(*v.FloatDenominatorVal, 'f', -1, 64) + str += " / " + helper.FormatFloat(*v.FloatDenominatorVal, 3) } if v.Unit != "" { diff --git a/api/resources.go b/api/resources.go index 767d82625..d2a1af965 100644 --- a/api/resources.go +++ b/api/resources.go @@ -172,7 +172,7 @@ type Attribute struct { func (a Attribute) String() string { switch { case a.FloatVal != nil: - str := strconv.FormatFloat(*a.FloatVal, 'f', -1, 64) + str := helper.FormatFloat(*a.FloatVal, 3) if a.Unit != "" { str += " " + a.Unit } diff --git a/helper/funcs.go b/helper/funcs.go index 89027b4cb..cf9cc3dae 100644 --- a/helper/funcs.go +++ b/helper/funcs.go @@ -4,6 +4,8 @@ import ( "crypto/sha512" "fmt" "regexp" + "strconv" + "strings" "time" multierror "github.com/hashicorp/go-multierror" @@ -344,3 +346,26 @@ func CheckHCLKeys(node ast.Node, valid []string) error { return result } + +// FormatFloat converts the floating-point number f to a string, +// after rounding it to the passed unit. +// +// Uses 'f' format (-ddd.dddddd, no exponent), and uses at most +// maxPrec digits after the decimal point. +func FormatFloat(f float64, maxPrec int) string { + v := strconv.FormatFloat(f, 'f', -1, 64) + + idx := strings.LastIndex(v, ".") + if idx == -1 { + return v + } + + sublen := idx + maxPrec + 1 + if sublen > len(v) { + sublen = len(v) + } + + return v[:sublen] + + return v +} diff --git a/helper/funcs_test.go b/helper/funcs_test.go index 774030be1..e9c9cdcd7 100644 --- a/helper/funcs_test.go +++ b/helper/funcs_test.go @@ -4,6 +4,8 @@ import ( "reflect" "sort" "testing" + + "github.com/stretchr/testify/require" ) func TestSliceStringIsSubset(t *testing.T) { @@ -87,3 +89,35 @@ func BenchmarkCleanEnvVar(b *testing.B) { CleanEnvVar(in, replacement) } } + +func TestFormatRoundedFloat(t *testing.T) { + cases := []struct { + input float64 + expected string + }{ + { + 1323, + "1323", + }, + { + 10.321, + "10.321", + }, + { + 100000.31324324, + "100000.313", + }, + { + 100000.3, + "100000.3", + }, + { + 0.7654321, + "0.765", + }, + } + + for _, c := range cases { + require.Equal(t, c.expected, FormatFloat(c.input, 3)) + } +} From ff1f007f918f65ebe633339b056657e49da0ca5d Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Mon, 10 Dec 2018 15:34:21 -0800 Subject: [PATCH 36/71] merge 087 and 090 changelog --- CHANGELOG.md | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 923e25e51..fab999f5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,17 +29,34 @@ IMPROVEMENTS: * vendor: Removed library obsoleted by go 1.8 [[GH-4469](https://github.com/hashicorp/nomad/issues/4469)] BUG FIXES: - * core: Fixed bug in reconciler where allocs already stopped were being unnecessarily updated [[GH-4764](https://github.com/hashicorp/nomad/issues/4764)] - * core: Fixed bug where some successfully completed jobs get re-run after job garbage collection [[GH-4861](https://github.com/hashicorp/nomad/pull/4861)] * core: Fix an issue where artifact checksums containing interpolated variables failed validation [[GH-4810](https://github.com/hashicorp/nomad/pull/4819)] - * core: Fixed bug that affects garbage collection of batch jobs that are purged and resubmitted with the same id [[GH-4839](https://github.com/hashicorp/nomad/pull/4839)] * client: Fix an issue reloading the client config [[GH-4730](https://github.com/hashicorp/nomad/issues/4730)] - * deployments: Fix an issue where a deployment with multiple task groups could - be marked as failed when the first progress deadline was hit regardless of if - that group was done deploying [[GH-4842](https://github.com/hashicorp/nomad/issues/4842)] * driver/raw_exec: Fix issue where tasks that used an interpolated command in driver configuration would not start [[GH-4813](https://github.com/hashicorp/nomad/pull/4813)] * server/vault: Fixed bug in Vault token renewal that could panic on a malformed Vault response [[GH-4904](https://github.com/hashicorp/nomad/issues/4904)], [[GH-4937](https://github.com/hashicorp/nomad/pull/4937)] +## 0.8.7 (Unreleased) + +IMPROVEMENTS: +* core: Added `filter_default`, `prefix_filter` and `disable_dispatched_job_summary_metrics` + client options to improve metric filtering [[GH-4878](https://github.com/hashicorp/nomad/issues/4878)] +* driver/docker: Support `bind` mount type in order to allow Windows users to mount absolute paths [[GH-4958](https://github.com/hashicorp/nomad/issues/4958)] + +BUG FIXES: +* core: Fixed panic when Vault secret response is nil [[GH-4904](https://github.com/hashicorp/nomad/pull/4904)] [[GH-4937](https://github.com/hashicorp/nomad/pull/4937)] +* core: Fixed issue with negative counts in job summary [[GH-4949](https://github.com/hashicorp/nomad/issues/4949)] +* core: Fixed issue with handling duplicated blocked evaluations [[GH-4867](https://github.com/hashicorp/nomad/pull/4867)] +* core: Fixed bug where some successfully completed jobs get re-run after job + garbage collection [[GH-4861](https://github.com/hashicorp/nomad/pull/4861)] +* core: Fixed bug in reconciler where allocs already stopped were being + unnecessarily updated [[GH-4764](https://github.com/hashicorp/nomad/issues/4764)] +* core: Fixed bug that affects garbage collection of batch jobs that are purged + and resubmitted with the same id [[GH-4839](https://github.com/hashicorp/nomad/pull/4839)] +* core: FIxed an issue with garbage collection where terminal but still running + allocations could be garbage collected server side [[GH-4965](https://github.com/hashicorp/nomad/issues/4965)] +* deployments: Fix an issue where a deployment with multiple task groups could + be marked as failed when the first progress deadline was hit regardless of if + that group was done deploying [[GH-4842](https://github.com/hashicorp/nomad/issues/4842)] + ## 0.8.6 (September 26, 2018) IMPROVEMENTS: From aeb9995daa697836582a0a332f8e9d615bebb632 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Mon, 10 Dec 2018 15:35:26 -0800 Subject: [PATCH 37/71] typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fab999f5d..0d989b3a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,7 +51,7 @@ BUG FIXES: unnecessarily updated [[GH-4764](https://github.com/hashicorp/nomad/issues/4764)] * core: Fixed bug that affects garbage collection of batch jobs that are purged and resubmitted with the same id [[GH-4839](https://github.com/hashicorp/nomad/pull/4839)] -* core: FIxed an issue with garbage collection where terminal but still running +* core: Fixed an issue with garbage collection where terminal but still running allocations could be garbage collected server side [[GH-4965](https://github.com/hashicorp/nomad/issues/4965)] * deployments: Fix an issue where a deployment with multiple task groups could be marked as failed when the first progress deadline was hit regardless of if From c6d19819556bed2b685e5b006ab019b9b2516c3a Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Wed, 5 Dec 2018 18:17:33 +0100 Subject: [PATCH 38/71] allocwatcher: Add Group AllocWatcher The Group Alloc watcher is an implementation of a PrevAllocWatcher that can wait for multiple previous allocs before terminating. This is to be used when running an allocation that is preempting upstream allocations, and thus only supports being ran with a local alloc watcher. It also currently requires all of its child watchers to correctly handle context cancellation. Should this be a problem, it should be fairly easy to implement a replacement using channels rather than a waitgroup. It obeys the PrevAllocWatcher interface for convenience, but it may be better to extract Migration capabilities into a seperate interface for greater clarity. --- client/allocwatcher/group_alloc_watcher.go | 92 ++++++++++ .../allocwatcher/group_alloc_watcher_test.go | 157 ++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 client/allocwatcher/group_alloc_watcher.go create mode 100644 client/allocwatcher/group_alloc_watcher_test.go diff --git a/client/allocwatcher/group_alloc_watcher.go b/client/allocwatcher/group_alloc_watcher.go new file mode 100644 index 000000000..22201cc55 --- /dev/null +++ b/client/allocwatcher/group_alloc_watcher.go @@ -0,0 +1,92 @@ +package allocwatcher + +import ( + "context" + "errors" + "sync" + + multierror "github.com/hashicorp/go-multierror" + "github.com/hashicorp/nomad/client/allocdir" +) + +type groupPrevAllocWatcher struct { + prevAllocs []PrevAllocWatcher + wg sync.WaitGroup + + // waiting and migrating are true when alloc runner is waiting on the + // prevAllocWatcher. Writers must acquire the waitingLock and readers + // should use the helper methods IsWaiting and IsMigrating. + waiting bool + waitingLock sync.RWMutex +} + +func NewGroupAllocWatcher(watchers ...PrevAllocWatcher) (PrevAllocWatcher, error) { + for _, watcher := range watchers { + _, ok := watcher.(*localPrevAlloc) + if !ok { + return nil, errors.New("PrevAllocWatchers must all be local watchers") + } + } + + return &groupPrevAllocWatcher{ + prevAllocs: watchers, + }, nil +} + +// Wait on the previous allocs to become terminal, exit, or, return due to +// context termination. Usage of the groupPrevAllocWatcher requires that all +// sub-watchers correctly handle context cancellation. +// We may need to adjust this to use channels rather than a wait group, if we +// wish to more strictly enforce timeouts. +func (g *groupPrevAllocWatcher) Wait(ctx context.Context) error { + g.waitingLock.Lock() + g.waiting = true + g.waitingLock.Unlock() + defer func() { + g.waitingLock.Lock() + g.waiting = false + g.waitingLock.Unlock() + }() + + var merr multierror.Error + var errmu sync.Mutex + + g.wg.Add(len(g.prevAllocs)) + + for _, alloc := range g.prevAllocs { + go func(ctx context.Context, alloc PrevAllocWatcher) { + defer g.wg.Done() + err := alloc.Wait(ctx) + if err != nil { + errmu.Lock() + merr.Errors = append(merr.Errors, err) + errmu.Unlock() + } + }(ctx, alloc) + } + + g.wg.Wait() + + // Check ctx.Err first, to avoid returning an mErr of ctx.Err from prevAlloc + // Wait routines. + if err := ctx.Err(); err != nil { + return err + } + + return merr.ErrorOrNil() +} + +func (g *groupPrevAllocWatcher) Migrate(ctx context.Context, dest *allocdir.AllocDir) error { + return errors.New("Migration unimplemented for a groupPrevAllocWatcher") +} + +func (g *groupPrevAllocWatcher) IsWaiting() bool { + g.waitingLock.RLock() + defer g.waitingLock.RUnlock() + + return g.waiting +} + +func (g *groupPrevAllocWatcher) IsMigrating() bool { + return false +} diff --git a/client/allocwatcher/group_alloc_watcher_test.go b/client/allocwatcher/group_alloc_watcher_test.go new file mode 100644 index 000000000..0740fb3f1 --- /dev/null +++ b/client/allocwatcher/group_alloc_watcher_test.go @@ -0,0 +1,157 @@ +package allocwatcher + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/nomad/nomad/structs" + "github.com/hashicorp/nomad/testutil" + "github.com/stretchr/testify/require" +) + +// TestPrevAlloc_GroupPrevAllocWatcher_Block asserts that when there are +// prevAllocs is set a groupPrevAllocWatcher will block on them +func TestPrevAlloc_GroupPrevAllocWatcher_Block(t *testing.T) { + t.Parallel() + conf, cleanup := newConfig(t) + + defer cleanup() + + conf.Alloc.Job.TaskGroups[0].Tasks[0].Config = map[string]interface{}{ + "run_for": "500ms", + } + + waiter := NewAllocWatcher(conf) + + groupWaiter := &groupPrevAllocWatcher{prevAllocs: []PrevAllocWatcher{waiter}} + + // Wait in a goroutine with a context to make sure it exits at the right time + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer cancel() + groupWaiter.Wait(ctx) + }() + + // Assert watcher is waiting + testutil.WaitForResult(func() (bool, error) { + return groupWaiter.IsWaiting(), fmt.Errorf("expected watcher to be waiting") + }, func(err error) { + t.Fatalf("error: %v", err) + }) + + // Broadcast a non-terminal alloc update to assert only terminal + // updates break out of waiting. + update := conf.PreviousRunner.Alloc().Copy() + update.DesiredStatus = structs.AllocDesiredStatusStop + update.ModifyIndex++ + update.AllocModifyIndex++ + + broadcaster := conf.PreviousRunner.(*fakeAllocRunner).Broadcaster + err := broadcaster.Send(update) + require.NoError(t, err) + + // Assert watcher is still waiting because alloc isn't terminal + testutil.WaitForResult(func() (bool, error) { + return groupWaiter.IsWaiting(), fmt.Errorf("expected watcher to be waiting") + }, func(err error) { + t.Fatalf("error: %v", err) + }) + + // Stop the previous alloc and assert watcher stops blocking + update = update.Copy() + update.DesiredStatus = structs.AllocDesiredStatusStop + update.ClientStatus = structs.AllocClientStatusComplete + update.ModifyIndex++ + update.AllocModifyIndex++ + + err = broadcaster.Send(update) + require.NoError(t, err) + + testutil.WaitForResult(func() (bool, error) { + if groupWaiter.IsWaiting() { + return false, fmt.Errorf("did not expect watcher to be waiting") + } + return !groupWaiter.IsMigrating(), fmt.Errorf("did not expect watcher to be migrating") + }, func(err error) { + t.Fatalf("error: %v", err) + }) +} + +// TestPrevAlloc_GroupPrevAllocWatcher_BlockMulti asserts that when there are +// multiple prevAllocs is set a groupPrevAllocWatcher will block until all +// are complete +func TestPrevAlloc_GroupPrevAllocWatcher_BlockMulti(t *testing.T) { + t.Parallel() + conf1, cleanup1 := newConfig(t) + defer cleanup1() + conf1.Alloc.Job.TaskGroups[0].Tasks[0].Config = map[string]interface{}{ + "run_for": "500ms", + } + + conf2, cleanup2 := newConfig(t) + defer cleanup2() + conf2.Alloc.Job.TaskGroups[0].Tasks[0].Config = map[string]interface{}{ + "run_for": "500ms", + } + + waiter1 := NewAllocWatcher(conf1) + waiter2 := NewAllocWatcher(conf2) + + groupWaiter := &groupPrevAllocWatcher{ + prevAllocs: []PrevAllocWatcher{ + waiter1, + waiter2, + }, + } + + terminalBroadcastFn := func(cfg Config) { + update := cfg.PreviousRunner.Alloc().Copy() + update.DesiredStatus = structs.AllocDesiredStatusStop + update.ClientStatus = structs.AllocClientStatusComplete + update.ModifyIndex++ + update.AllocModifyIndex++ + + broadcaster := cfg.PreviousRunner.(*fakeAllocRunner).Broadcaster + err := broadcaster.Send(update) + require.NoError(t, err) + } + + // Wait in a goroutine with a context to make sure it exits at the right time + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer cancel() + groupWaiter.Wait(ctx) + }() + + // Assert watcher is waiting + testutil.WaitForResult(func() (bool, error) { + return groupWaiter.IsWaiting(), fmt.Errorf("expected watcher to be waiting") + }, func(err error) { + t.Fatalf("error: %v", err) + }) + + // Broadcast a terminal alloc update to the first watcher + terminalBroadcastFn(conf1) + + // Assert watcher is still waiting because alloc isn't terminal + testutil.WaitForResult(func() (bool, error) { + return groupWaiter.IsWaiting(), fmt.Errorf("expected watcher to be waiting") + }, func(err error) { + t.Fatalf("error: %v", err) + }) + + // Broadcast a terminal alloc update to the second watcher + terminalBroadcastFn(conf2) + + testutil.WaitForResult(func() (bool, error) { + if groupWaiter.IsWaiting() { + return false, fmt.Errorf("did not expect watcher to be waiting") + } + return !groupWaiter.IsMigrating(), fmt.Errorf("did not expect watcher to be migrating") + }, func(err error) { + t.Fatalf("error: %v", err) + }) +} From a4cf83d00c6004141e102281af1de29a4679f0bc Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Wed, 5 Dec 2018 19:18:04 +0100 Subject: [PATCH 39/71] client: Wait for preempted allocs to terminate When starting an allocation that is preempting other allocs, we create a new group allocation watcher, and then wait for the allocations to terminate in the allocation PreRun hooks. If there's no preempted allocations, then we simply provide a NoopAllocWatcher. --- client/allocrunner/alloc_runner.go | 6 ++++- client/allocrunner/alloc_runner_hooks.go | 1 + client/allocrunner/config.go | 3 +++ client/allocrunner/preemption_hook.go | 32 ++++++++++++++++++++++++ client/client.go | 23 +++++++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 client/allocrunner/preemption_hook.go diff --git a/client/allocrunner/alloc_runner.go b/client/allocrunner/alloc_runner.go index 3907c2156..06eab7f0f 100644 --- a/client/allocrunner/alloc_runner.go +++ b/client/allocrunner/alloc_runner.go @@ -102,6 +102,9 @@ type allocRunner struct { // and if necessary migrate its alloc dir. prevAllocWatcher allocwatcher.PrevAllocWatcher + // preemptedAllocWatcher allows waiting for preempted allocations to exit + preemptedAllocWatcher allocwatcher.PrevAllocWatcher + // pluginSingletonLoader is a plugin loader that will returns singleton // instances of the plugins. pluginSingletonLoader loader.PluginCatalog @@ -134,6 +137,7 @@ func NewAllocRunner(config *Config) (*allocRunner, error) { taskStateUpdateHandlerCh: make(chan struct{}), deviceStatsReporter: config.DeviceStatsReporter, prevAllocWatcher: config.PrevAllocWatcher, + preemptedAllocWatcher: config.PreemptedAllocWatcher, pluginSingletonLoader: config.PluginSingletonLoader, devicemanager: config.DeviceManager, } @@ -668,7 +672,7 @@ func (ar *allocRunner) IsDestroyed() bool { // // This method is safe for calling concurrently with Run(). func (ar *allocRunner) IsWaiting() bool { - return ar.prevAllocWatcher.IsWaiting() + return ar.preemptedAllocWatcher.IsWaiting() || ar.prevAllocWatcher.IsWaiting() } // Shutdown AllocRunner gracefully. Blocks while shutting down all TaskRunners. diff --git a/client/allocrunner/alloc_runner_hooks.go b/client/allocrunner/alloc_runner_hooks.go index e9fe32aad..c147d2590 100644 --- a/client/allocrunner/alloc_runner_hooks.go +++ b/client/allocrunner/alloc_runner_hooks.go @@ -77,6 +77,7 @@ func (ar *allocRunner) initRunnerHooks() { // directory path exists for other hooks. ar.runnerHooks = []interfaces.RunnerHook{ newAllocDirHook(hookLogger, ar.allocDir), + newPreemptionHook(hookLogger, ar.preemptedAllocWatcher), newDiskMigrationHook(hookLogger, ar.prevAllocWatcher, ar.allocDir), newAllocHealthWatcherHook(hookLogger, ar.Alloc(), hs, ar.Listener(), ar.consulClient), } diff --git a/client/allocrunner/config.go b/client/allocrunner/config.go index 5912f6f80..476644d7a 100644 --- a/client/allocrunner/config.go +++ b/client/allocrunner/config.go @@ -43,6 +43,9 @@ type Config struct { // migrating their ephemeral disk when necessary. PrevAllocWatcher allocwatcher.PrevAllocWatcher + // PreemptedAllocWatcher allows waiting for preempted allocations to exit + PreemptedAllocWatcher allocwatcher.PrevAllocWatcher + // PluginLoader is used to load plugins. PluginLoader loader.PluginCatalog diff --git a/client/allocrunner/preemption_hook.go b/client/allocrunner/preemption_hook.go new file mode 100644 index 000000000..112c5d8e5 --- /dev/null +++ b/client/allocrunner/preemption_hook.go @@ -0,0 +1,32 @@ +package allocrunner + +import ( + "context" + + log "github.com/hashicorp/go-hclog" + "github.com/hashicorp/nomad/client/allocwatcher" +) + +// preemptionWatchingHook waits for a PrevAllocWatcher to exit before allowing +// an allocation to be executed +type preemptionWatchingHook struct { + allocWatcher allocwatcher.PrevAllocWatcher + logger log.Logger +} + +func newPreemptionHook(logger log.Logger, allocWatcher allocwatcher.PrevAllocWatcher) *preemptionWatchingHook { + h := &preemptionWatchingHook{ + allocWatcher: allocWatcher, + } + h.logger = logger.Named(h.Name()) + return h +} + +func (h *preemptionWatchingHook) Name() string { + return "await_preemptions" +} + +func (h *preemptionWatchingHook) Prerun(ctx context.Context) error { + // Wait for a previous alloc - if any - to terminate + return h.allocWatcher.Wait(ctx) +} diff --git a/client/client.go b/client/client.go index ce2e87573..27a91234f 100644 --- a/client/client.go +++ b/client/client.go @@ -2040,6 +2040,28 @@ func (c *Client) addAlloc(alloc *structs.Allocation, migrateToken string) error } prevAllocWatcher := allocwatcher.NewAllocWatcher(watcherConfig) + var preemptedAllocWatchers []allocwatcher.PrevAllocWatcher + for _, palloc := range alloc.PreemptedAllocations { + cfg := allocwatcher.Config{ + Alloc: alloc, + PreviousRunner: c.allocs[palloc], + RPC: c, + Config: c.configCopy, + Logger: c.logger, + } + w := allocwatcher.NewAllocWatcher(cfg) + preemptedAllocWatchers = append(preemptedAllocWatchers, w) + } + + var preemptedAllocWatcher allocwatcher.PrevAllocWatcher = allocwatcher.NoopPrevAlloc{} + if len(preemptedAllocWatchers) > 0 { + var err error + preemptedAllocWatcher, err = allocwatcher.NewGroupAllocWatcher(preemptedAllocWatchers...) + if err != nil { + return err + } + } + // Copy the config since the node can be swapped out as it is being updated. // The long term fix is to pass in the config and node separately and then // we don't have to do a copy. @@ -2054,6 +2076,7 @@ func (c *Client) addAlloc(alloc *structs.Allocation, migrateToken string) error StateUpdater: c, DeviceStatsReporter: c, PrevAllocWatcher: prevAllocWatcher, + PreemptedAllocWatcher: preemptedAllocWatcher, PluginLoader: c.config.PluginLoader, PluginSingletonLoader: c.config.PluginSingletonLoader, DeviceManager: c.devicemanager, From d44d4b57de9d76e8179f5adebd4bd06c9d17050b Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Thu, 6 Dec 2018 12:15:59 +0100 Subject: [PATCH 40/71] client: Unify handling of previous and preempted allocs --- client/allocrunner/alloc_runner.go | 14 +-- client/allocrunner/alloc_runner_hooks.go | 4 +- client/allocrunner/config.go | 9 +- client/allocrunner/migrate_hook.go | 4 +- ...mption_hook.go => upstream_allocs_hook.go} | 14 +-- client/allocwatcher/alloc_watcher.go | 97 +++++++++++++------ client/allocwatcher/alloc_watcher_test.go | 14 +-- client/allocwatcher/group_alloc_watcher.go | 21 +--- .../allocwatcher/group_alloc_watcher_test.go | 16 +-- client/client.go | 48 ++++----- 10 files changed, 124 insertions(+), 117 deletions(-) rename client/allocrunner/{preemption_hook.go => upstream_allocs_hook.go} (50%) diff --git a/client/allocrunner/alloc_runner.go b/client/allocrunner/alloc_runner.go index 06eab7f0f..3a5ab0f6d 100644 --- a/client/allocrunner/alloc_runner.go +++ b/client/allocrunner/alloc_runner.go @@ -98,12 +98,12 @@ type allocRunner struct { // allocBroadcaster sends client allocation updates to all listeners allocBroadcaster *cstructs.AllocBroadcaster - // prevAllocWatcher allows waiting for a previous allocation to exit - // and if necessary migrate its alloc dir. + // prevAllocWatcher allows waiting for any previous or preempted allocations + // to exit prevAllocWatcher allocwatcher.PrevAllocWatcher - // preemptedAllocWatcher allows waiting for preempted allocations to exit - preemptedAllocWatcher allocwatcher.PrevAllocWatcher + // prevAllocMigrator allows the migration of a previous allocations alloc dir. + prevAllocMigrator allocwatcher.PrevAllocMigrator // pluginSingletonLoader is a plugin loader that will returns singleton // instances of the plugins. @@ -137,7 +137,7 @@ func NewAllocRunner(config *Config) (*allocRunner, error) { taskStateUpdateHandlerCh: make(chan struct{}), deviceStatsReporter: config.DeviceStatsReporter, prevAllocWatcher: config.PrevAllocWatcher, - preemptedAllocWatcher: config.PreemptedAllocWatcher, + prevAllocMigrator: config.PrevAllocMigrator, pluginSingletonLoader: config.PluginSingletonLoader, devicemanager: config.DeviceManager, } @@ -672,7 +672,7 @@ func (ar *allocRunner) IsDestroyed() bool { // // This method is safe for calling concurrently with Run(). func (ar *allocRunner) IsWaiting() bool { - return ar.preemptedAllocWatcher.IsWaiting() || ar.prevAllocWatcher.IsWaiting() + return ar.prevAllocWatcher.IsWaiting() } // Shutdown AllocRunner gracefully. Blocks while shutting down all TaskRunners. @@ -717,7 +717,7 @@ func (ar *allocRunner) Shutdown() { // // This method is safe for calling concurrently with Run(). func (ar *allocRunner) IsMigrating() bool { - return ar.prevAllocWatcher.IsMigrating() + return ar.prevAllocMigrator.IsMigrating() } func (ar *allocRunner) StatsReporter() interfaces.AllocStatsReporter { diff --git a/client/allocrunner/alloc_runner_hooks.go b/client/allocrunner/alloc_runner_hooks.go index c147d2590..9119663e3 100644 --- a/client/allocrunner/alloc_runner_hooks.go +++ b/client/allocrunner/alloc_runner_hooks.go @@ -77,8 +77,8 @@ func (ar *allocRunner) initRunnerHooks() { // directory path exists for other hooks. ar.runnerHooks = []interfaces.RunnerHook{ newAllocDirHook(hookLogger, ar.allocDir), - newPreemptionHook(hookLogger, ar.preemptedAllocWatcher), - newDiskMigrationHook(hookLogger, ar.prevAllocWatcher, ar.allocDir), + newUpstreamAllocsHook(hookLogger, ar.prevAllocWatcher), + newDiskMigrationHook(hookLogger, ar.prevAllocMigrator, ar.allocDir), newAllocHealthWatcherHook(hookLogger, ar.Alloc(), hs, ar.Listener(), ar.consulClient), } } diff --git a/client/allocrunner/config.go b/client/allocrunner/config.go index 476644d7a..6406d2a5a 100644 --- a/client/allocrunner/config.go +++ b/client/allocrunner/config.go @@ -36,15 +36,14 @@ type Config struct { // StateUpdater is used to emit updated task state StateUpdater interfaces.AllocStateHandler - // deviceStatsReporter is used to lookup resource usage for alloc devices + // DeviceStatsReporter is used to lookup resource usage for alloc devices DeviceStatsReporter interfaces.DeviceStatsReporter - // PrevAllocWatcher handles waiting on previous allocations and - // migrating their ephemeral disk when necessary. + // PrevAllocWatcher handles waiting on previous or preempted allocations PrevAllocWatcher allocwatcher.PrevAllocWatcher - // PreemptedAllocWatcher allows waiting for preempted allocations to exit - PreemptedAllocWatcher allocwatcher.PrevAllocWatcher + // PrevAllocMigrator allows the migration of a previous allocations alloc dir + PrevAllocMigrator allocwatcher.PrevAllocMigrator // PluginLoader is used to load plugins. PluginLoader loader.PluginCatalog diff --git a/client/allocrunner/migrate_hook.go b/client/allocrunner/migrate_hook.go index ca9efcc25..3a6f5e3ee 100644 --- a/client/allocrunner/migrate_hook.go +++ b/client/allocrunner/migrate_hook.go @@ -13,11 +13,11 @@ import ( // being built but must be run before anything else manipulates the alloc dir. type diskMigrationHook struct { allocDir *allocdir.AllocDir - allocWatcher allocwatcher.PrevAllocWatcher + allocWatcher allocwatcher.PrevAllocMigrator logger log.Logger } -func newDiskMigrationHook(logger log.Logger, allocWatcher allocwatcher.PrevAllocWatcher, allocDir *allocdir.AllocDir) *diskMigrationHook { +func newDiskMigrationHook(logger log.Logger, allocWatcher allocwatcher.PrevAllocMigrator, allocDir *allocdir.AllocDir) *diskMigrationHook { h := &diskMigrationHook{ allocDir: allocDir, allocWatcher: allocWatcher, diff --git a/client/allocrunner/preemption_hook.go b/client/allocrunner/upstream_allocs_hook.go similarity index 50% rename from client/allocrunner/preemption_hook.go rename to client/allocrunner/upstream_allocs_hook.go index 112c5d8e5..eb53c4436 100644 --- a/client/allocrunner/preemption_hook.go +++ b/client/allocrunner/upstream_allocs_hook.go @@ -7,26 +7,26 @@ import ( "github.com/hashicorp/nomad/client/allocwatcher" ) -// preemptionWatchingHook waits for a PrevAllocWatcher to exit before allowing +// upstreamAllocsHook waits for a PrevAllocWatcher to exit before allowing // an allocation to be executed -type preemptionWatchingHook struct { +type upstreamAllocsHook struct { allocWatcher allocwatcher.PrevAllocWatcher logger log.Logger } -func newPreemptionHook(logger log.Logger, allocWatcher allocwatcher.PrevAllocWatcher) *preemptionWatchingHook { - h := &preemptionWatchingHook{ +func newUpstreamAllocsHook(logger log.Logger, allocWatcher allocwatcher.PrevAllocWatcher) *upstreamAllocsHook { + h := &upstreamAllocsHook{ allocWatcher: allocWatcher, } h.logger = logger.Named(h.Name()) return h } -func (h *preemptionWatchingHook) Name() string { - return "await_preemptions" +func (h *upstreamAllocsHook) Name() string { + return "await_previous_allocations" } -func (h *preemptionWatchingHook) Prerun(ctx context.Context) error { +func (h *upstreamAllocsHook) Prerun(ctx context.Context) error { // Wait for a previous alloc - if any - to terminate return h.allocWatcher.Wait(ctx) } diff --git a/client/allocwatcher/alloc_watcher.go b/client/allocwatcher/alloc_watcher.go index 1ca326bca..dc24e16c6 100644 --- a/client/allocwatcher/alloc_watcher.go +++ b/client/allocwatcher/alloc_watcher.go @@ -47,20 +47,26 @@ type AllocRunnerMeta interface { } // PrevAllocWatcher allows AllocRunners to wait for a previous allocation to -// terminate and migrate its data whether or not the previous allocation is -// local or remote. +// terminate whether or not the previous allocation is local or remote. +// See `PrevAllocMigrator` for migrating workloads. type PrevAllocWatcher interface { // Wait for previous alloc to terminate Wait(context.Context) error - // Migrate data from previous alloc - Migrate(ctx context.Context, dest *allocdir.AllocDir) error - // IsWaiting returns true if a concurrent caller is blocked in Wait IsWaiting() bool +} + +// PrevAllocMigrator allows AllocRunners to migrate a previous allocation +// whether or not the previous allocation is local or remote. +type PrevAllocMigrator interface { + PrevAllocWatcher // IsMigrating returns true if a concurrent caller is in Migrate IsMigrating() bool + + // Migrate data from previous alloc + Migrate(ctx context.Context, dest *allocdir.AllocDir) error } type Config struct { @@ -68,10 +74,13 @@ type Config struct { // previous allocation stopping. Alloc *structs.Allocation - // PreviousRunner is non-nil iff All has a PreviousAllocation and it is + // PreviousRunner is non-nil if Alloc has a PreviousAllocation and it is // running locally. PreviousRunner AllocRunnerMeta + // PreemptedRunners is non-nil if Alloc has one or more PreemptedAllocations. + PreemptedRunners map[string]AllocRunnerMeta + // RPC allows the alloc watcher to monitor remote allocations. RPC RPCer @@ -85,31 +94,30 @@ type Config struct { Logger hclog.Logger } -// NewAllocWatcher creates a PrevAllocWatcher appropriate for whether this -// alloc's previous allocation was local or remote. If this alloc has no -// previous alloc then a noop implementation is returned. -func NewAllocWatcher(c Config) PrevAllocWatcher { - if c.Alloc.PreviousAllocation == "" { - // No previous allocation, use noop transitioner - return NoopPrevAlloc{} - } - +func newWatcherForAlloc(c Config, tg *structs.TaskGroup, watchedAllocID string, m AllocRunnerMeta) PrevAllocMigrator { logger := c.Logger.Named("alloc_watcher") logger = logger.With("alloc_id", c.Alloc.ID) - logger = logger.With("previous_alloc", c.Alloc.PreviousAllocation) + logger = logger.With("previous_alloc", watchedAllocID) - tg := c.Alloc.Job.LookupTaskGroup(c.Alloc.TaskGroup) + var tasks []*structs.Task + var sticky bool + var migrate bool + if tg != nil { + tasks = tg.Tasks + sticky = tg.EphemeralDisk != nil && tg.EphemeralDisk.Sticky + migrate = tg.EphemeralDisk != nil && tg.EphemeralDisk.Migrate + } - if c.PreviousRunner != nil { - // Previous allocation is local, use local transitioner + if m != nil { + // Local Allocation because there's no meta return &localPrevAlloc{ allocID: c.Alloc.ID, - prevAllocID: c.Alloc.PreviousAllocation, - tasks: tg.Tasks, - sticky: tg.EphemeralDisk != nil && tg.EphemeralDisk.Sticky, - prevAllocDir: c.PreviousRunner.GetAllocDir(), - prevListener: c.PreviousRunner.Listener(), - prevStatus: c.PreviousRunner.Alloc(), + prevAllocID: watchedAllocID, + tasks: tasks, + sticky: sticky, + prevAllocDir: m.GetAllocDir(), + prevListener: m.Listener(), + prevStatus: m.Alloc(), logger: logger, } } @@ -117,15 +125,50 @@ func NewAllocWatcher(c Config) PrevAllocWatcher { return &remotePrevAlloc{ allocID: c.Alloc.ID, prevAllocID: c.Alloc.PreviousAllocation, - tasks: tg.Tasks, + tasks: tasks, config: c.Config, - migrate: tg.EphemeralDisk != nil && tg.EphemeralDisk.Migrate, + migrate: migrate, rpc: c.RPC, migrateToken: c.MigrateToken, logger: logger, } } +// NewAllocWatcher creates a PrevAllocWatcher appropriate for whether this +// alloc's previous allocation was local or remote. If this alloc has no +// previous alloc then a noop implementation is returned. +func NewAllocWatcher(c Config) (PrevAllocWatcher, PrevAllocMigrator) { + if c.Alloc.PreviousAllocation == "" && c.PreemptedRunners == nil { + return NoopPrevAlloc{}, NoopPrevAlloc{} + } + + var prevAllocWatchers []PrevAllocWatcher + var prevAllocMigrator PrevAllocMigrator = NoopPrevAlloc{} + + // We have a previous allocation, add its listener to the watchers, and + // use a migrator. + if c.Alloc.PreviousAllocation != "" { + tg := c.Alloc.Job.LookupTaskGroup(c.Alloc.TaskGroup) + w := newWatcherForAlloc(c, tg, c.Alloc.PreviousAllocation, c.PreviousRunner) + prevAllocWatchers = append(prevAllocWatchers, w) + prevAllocMigrator = w + } + + // We are preempting allocations, add their listeners to the watchers. + if c.PreemptedRunners != nil { + for aid, r := range c.PreemptedRunners { + w := newWatcherForAlloc(c, nil, aid, r) + prevAllocWatchers = append(prevAllocWatchers, w) + } + } + + groupWatcher := &groupPrevAllocWatcher{ + prevAllocs: prevAllocWatchers, + } + + return groupWatcher, prevAllocMigrator +} + // localPrevAlloc is a prevAllocWatcher for previous allocations on the same // node as an updated allocation. type localPrevAlloc struct { diff --git a/client/allocwatcher/alloc_watcher_test.go b/client/allocwatcher/alloc_watcher_test.go index 1eba8cd57..2f34894a2 100644 --- a/client/allocwatcher/alloc_watcher_test.go +++ b/client/allocwatcher/alloc_watcher_test.go @@ -97,20 +97,20 @@ func TestPrevAlloc_Noop(t *testing.T) { conf.Alloc.PreviousAllocation = "" - watcher := NewAllocWatcher(conf) + watcher, migrator := NewAllocWatcher(conf) require.NotNil(t, watcher) - _, ok := watcher.(NoopPrevAlloc) - require.True(t, ok, "expected watcher to be NoopPrevAlloc") + _, ok := migrator.(NoopPrevAlloc) + require.True(t, ok, "expected migrator to be NoopPrevAlloc") done := make(chan int, 2) go func() { watcher.Wait(context.Background()) done <- 1 - watcher.Migrate(context.Background(), nil) + migrator.Migrate(context.Background(), nil) done <- 1 }() require.False(t, watcher.IsWaiting()) - require.False(t, watcher.IsMigrating()) + require.False(t, migrator.IsMigrating()) <-done <-done } @@ -127,7 +127,7 @@ func TestPrevAlloc_LocalPrevAlloc_Block(t *testing.T) { "run_for": "500ms", } - waiter := NewAllocWatcher(conf) + _, waiter := NewAllocWatcher(conf) // Wait in a goroutine with a context to make sure it exits at the right time ctx, cancel := context.WithCancel(context.Background()) @@ -191,7 +191,7 @@ func TestPrevAlloc_LocalPrevAlloc_Terminated(t *testing.T) { conf.PreviousRunner.Alloc().ClientStatus = structs.AllocClientStatusComplete - waiter := NewAllocWatcher(conf) + waiter, _ := NewAllocWatcher(conf) ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() diff --git a/client/allocwatcher/group_alloc_watcher.go b/client/allocwatcher/group_alloc_watcher.go index 22201cc55..087e6256f 100644 --- a/client/allocwatcher/group_alloc_watcher.go +++ b/client/allocwatcher/group_alloc_watcher.go @@ -2,11 +2,9 @@ package allocwatcher import ( "context" - "errors" "sync" multierror "github.com/hashicorp/go-multierror" - "github.com/hashicorp/nomad/client/allocdir" ) type groupPrevAllocWatcher struct { @@ -20,17 +18,10 @@ type groupPrevAllocWatcher struct { waitingLock sync.RWMutex } -func NewGroupAllocWatcher(watchers ...PrevAllocWatcher) (PrevAllocWatcher, error) { - for _, watcher := range watchers { - _, ok := watcher.(*localPrevAlloc) - if !ok { - return nil, errors.New("PrevAllocWatchers must all be local watchers") - } - } - +func NewGroupAllocWatcher(watchers ...PrevAllocWatcher) PrevAllocWatcher { return &groupPrevAllocWatcher{ prevAllocs: watchers, - }, nil + } } // Wait on the previous allocs to become terminal, exit, or, return due to @@ -76,17 +67,9 @@ func (g *groupPrevAllocWatcher) Wait(ctx context.Context) error { return merr.ErrorOrNil() } -func (g *groupPrevAllocWatcher) Migrate(ctx context.Context, dest *allocdir.AllocDir) error { - return errors.New("Migration unimplemented for a groupPrevAllocWatcher") -} - func (g *groupPrevAllocWatcher) IsWaiting() bool { g.waitingLock.RLock() defer g.waitingLock.RUnlock() return g.waiting } - -func (g *groupPrevAllocWatcher) IsMigrating() bool { - return false -} diff --git a/client/allocwatcher/group_alloc_watcher_test.go b/client/allocwatcher/group_alloc_watcher_test.go index 0740fb3f1..f992f3410 100644 --- a/client/allocwatcher/group_alloc_watcher_test.go +++ b/client/allocwatcher/group_alloc_watcher_test.go @@ -22,7 +22,7 @@ func TestPrevAlloc_GroupPrevAllocWatcher_Block(t *testing.T) { "run_for": "500ms", } - waiter := NewAllocWatcher(conf) + waiter, _ := NewAllocWatcher(conf) groupWaiter := &groupPrevAllocWatcher{prevAllocs: []PrevAllocWatcher{waiter}} @@ -70,10 +70,7 @@ func TestPrevAlloc_GroupPrevAllocWatcher_Block(t *testing.T) { require.NoError(t, err) testutil.WaitForResult(func() (bool, error) { - if groupWaiter.IsWaiting() { - return false, fmt.Errorf("did not expect watcher to be waiting") - } - return !groupWaiter.IsMigrating(), fmt.Errorf("did not expect watcher to be migrating") + return !groupWaiter.IsWaiting(), fmt.Errorf("did not expect watcher to be waiting") }, func(err error) { t.Fatalf("error: %v", err) }) @@ -96,8 +93,8 @@ func TestPrevAlloc_GroupPrevAllocWatcher_BlockMulti(t *testing.T) { "run_for": "500ms", } - waiter1 := NewAllocWatcher(conf1) - waiter2 := NewAllocWatcher(conf2) + waiter1, _ := NewAllocWatcher(conf1) + waiter2, _ := NewAllocWatcher(conf2) groupWaiter := &groupPrevAllocWatcher{ prevAllocs: []PrevAllocWatcher{ @@ -147,10 +144,7 @@ func TestPrevAlloc_GroupPrevAllocWatcher_BlockMulti(t *testing.T) { terminalBroadcastFn(conf2) testutil.WaitForResult(func() (bool, error) { - if groupWaiter.IsWaiting() { - return false, fmt.Errorf("did not expect watcher to be waiting") - } - return !groupWaiter.IsMigrating(), fmt.Errorf("did not expect watcher to be migrating") + return !groupWaiter.IsWaiting(), fmt.Errorf("did not expect watcher to be waiting") }, func(err error) { t.Fatalf("error: %v", err) }) diff --git a/client/client.go b/client/client.go index 27a91234f..eed0a8373 100644 --- a/client/client.go +++ b/client/client.go @@ -2028,39 +2028,27 @@ func (c *Client) addAlloc(alloc *structs.Allocation, migrateToken string) error return err } + // Collect any preempted allocations to pass into the previous alloc watcher + var preemptedAllocs map[string]allocwatcher.AllocRunnerMeta + if len(alloc.PreemptedAllocations) > 0 { + preemptedAllocs = make(map[string]allocwatcher.AllocRunnerMeta) + for _, palloc := range alloc.PreemptedAllocations { + preemptedAllocs[palloc] = c.allocs[palloc] + } + } + // Since only the Client has access to other AllocRunners and the RPC // client, create the previous allocation watcher here. watcherConfig := allocwatcher.Config{ - Alloc: alloc, - PreviousRunner: c.allocs[alloc.PreviousAllocation], - RPC: c, - Config: c.configCopy, - MigrateToken: migrateToken, - Logger: c.logger, - } - prevAllocWatcher := allocwatcher.NewAllocWatcher(watcherConfig) - - var preemptedAllocWatchers []allocwatcher.PrevAllocWatcher - for _, palloc := range alloc.PreemptedAllocations { - cfg := allocwatcher.Config{ - Alloc: alloc, - PreviousRunner: c.allocs[palloc], - RPC: c, - Config: c.configCopy, - Logger: c.logger, - } - w := allocwatcher.NewAllocWatcher(cfg) - preemptedAllocWatchers = append(preemptedAllocWatchers, w) - } - - var preemptedAllocWatcher allocwatcher.PrevAllocWatcher = allocwatcher.NoopPrevAlloc{} - if len(preemptedAllocWatchers) > 0 { - var err error - preemptedAllocWatcher, err = allocwatcher.NewGroupAllocWatcher(preemptedAllocWatchers...) - if err != nil { - return err - } + Alloc: alloc, + PreviousRunner: c.allocs[alloc.PreviousAllocation], + PreemptedRunners: preemptedAllocs, + RPC: c, + Config: c.configCopy, + MigrateToken: migrateToken, + Logger: c.logger, } + prevAllocWatcher, prevAllocMigrator := allocwatcher.NewAllocWatcher(watcherConfig) // Copy the config since the node can be swapped out as it is being updated. // The long term fix is to pass in the config and node separately and then @@ -2076,7 +2064,7 @@ func (c *Client) addAlloc(alloc *structs.Allocation, migrateToken string) error StateUpdater: c, DeviceStatsReporter: c, PrevAllocWatcher: prevAllocWatcher, - PreemptedAllocWatcher: preemptedAllocWatcher, + PrevAllocMigrator: prevAllocMigrator, PluginLoader: c.config.PluginLoader, PluginSingletonLoader: c.config.PluginSingletonLoader, DeviceManager: c.devicemanager, From d9e9265e8ab448d579345189037073d653089a1b Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Tue, 11 Dec 2018 13:09:37 +0100 Subject: [PATCH 41/71] allocwatcher: Cleanup new migrator/watcher interface --- client/allocwatcher/alloc_watcher.go | 50 ++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/client/allocwatcher/alloc_watcher.go b/client/allocwatcher/alloc_watcher.go index dc24e16c6..b8a0ead09 100644 --- a/client/allocwatcher/alloc_watcher.go +++ b/client/allocwatcher/alloc_watcher.go @@ -94,19 +94,14 @@ type Config struct { Logger hclog.Logger } -func newWatcherForAlloc(c Config, tg *structs.TaskGroup, watchedAllocID string, m AllocRunnerMeta) PrevAllocMigrator { - logger := c.Logger.Named("alloc_watcher") +func newMigratorForAlloc(c Config, tg *structs.TaskGroup, watchedAllocID string, m AllocRunnerMeta) PrevAllocMigrator { + logger := c.Logger.Named("alloc_migrator") logger = logger.With("alloc_id", c.Alloc.ID) logger = logger.With("previous_alloc", watchedAllocID) - var tasks []*structs.Task - var sticky bool - var migrate bool - if tg != nil { - tasks = tg.Tasks - sticky = tg.EphemeralDisk != nil && tg.EphemeralDisk.Sticky - migrate = tg.EphemeralDisk != nil && tg.EphemeralDisk.Migrate - } + tasks := tg.Tasks + sticky := tg.EphemeralDisk != nil && tg.EphemeralDisk.Sticky + migrate := tg.EphemeralDisk != nil && tg.EphemeralDisk.Migrate if m != nil { // Local Allocation because there's no meta @@ -134,6 +129,33 @@ func newWatcherForAlloc(c Config, tg *structs.TaskGroup, watchedAllocID string, } } +func newWatcherForAlloc(c Config, watchedAllocID string, m AllocRunnerMeta) PrevAllocWatcher { + logger := c.Logger.Named("alloc_watcher") + logger = logger.With("alloc_id", c.Alloc.ID) + logger = logger.With("previous_alloc", watchedAllocID) + + if m != nil { + // Local Allocation because there's no meta + return &localPrevAlloc{ + allocID: c.Alloc.ID, + prevAllocID: watchedAllocID, + prevAllocDir: m.GetAllocDir(), + prevListener: m.Listener(), + prevStatus: m.Alloc(), + logger: logger, + } + } + + return &remotePrevAlloc{ + allocID: c.Alloc.ID, + prevAllocID: c.Alloc.PreviousAllocation, + config: c.Config, + rpc: c.RPC, + migrateToken: c.MigrateToken, + logger: logger, + } +} + // NewAllocWatcher creates a PrevAllocWatcher appropriate for whether this // alloc's previous allocation was local or remote. If this alloc has no // previous alloc then a noop implementation is returned. @@ -149,15 +171,15 @@ func NewAllocWatcher(c Config) (PrevAllocWatcher, PrevAllocMigrator) { // use a migrator. if c.Alloc.PreviousAllocation != "" { tg := c.Alloc.Job.LookupTaskGroup(c.Alloc.TaskGroup) - w := newWatcherForAlloc(c, tg, c.Alloc.PreviousAllocation, c.PreviousRunner) - prevAllocWatchers = append(prevAllocWatchers, w) - prevAllocMigrator = w + m := newMigratorForAlloc(c, tg, c.Alloc.PreviousAllocation, c.PreviousRunner) + prevAllocWatchers = append(prevAllocWatchers, m) + prevAllocMigrator = m } // We are preempting allocations, add their listeners to the watchers. if c.PreemptedRunners != nil { for aid, r := range c.PreemptedRunners { - w := newWatcherForAlloc(c, nil, aid, r) + w := newWatcherForAlloc(c, aid, r) prevAllocWatchers = append(prevAllocWatchers, w) } } From 419743f1657a9473623178fc8dbe9152a102a116 Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Tue, 11 Dec 2018 13:12:01 +0100 Subject: [PATCH 42/71] allocrunner: Test alloc runners should include a noop migrator --- client/allocrunner/testing.go | 1 + 1 file changed, 1 insertion(+) diff --git a/client/allocrunner/testing.go b/client/allocrunner/testing.go index 3e18379dc..0a3851b1d 100644 --- a/client/allocrunner/testing.go +++ b/client/allocrunner/testing.go @@ -63,6 +63,7 @@ func testAllocRunnerConfig(t *testing.T, alloc *structs.Allocation) (*Config, fu Vault: vaultclient.NewMockVaultClient(), StateUpdater: &MockStateUpdater{}, PrevAllocWatcher: allocwatcher.NoopPrevAlloc{}, + PrevAllocMigrator: allocwatcher.NoopPrevAlloc{}, PluginSingletonLoader: singleton.NewSingletonLoader(clientConf.Logger, pluginLoader), DeviceManager: devicemanager.NoopMockManager(), } From 744aab57515653aaf08c1e115a69f9c345b73b62 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 8 Dec 2018 14:50:47 -0500 Subject: [PATCH 43/71] tests: Lower package runtime Lowering the runtime here to pre 7ca535aa90748caff1522468cc0c4ab672a74abb expectations. The longest package at the time `client/driver` shrunk significantly, and now the longest packages take less than 5 minutes. We do have some long running timed out projects due to a stuck shutdown, but in completed jobs (though they failed), the longest packages took less than 5 minutes. The longest running packages in https://travis-ci.org/hashicorp/nomad/jobs/464640776 were: ``` FAIL github.com/hashicorp/nomad/nomad 268.089s ok github.com/hashicorp/nomad/drivers/docker 203.903s coverage: 68.8% of statements ok github.com/hashicorp/nomad/drivers/rkt 132.104s coverage: 65.0% of statements ok github.com/hashicorp/nomad/api 123.193s coverage: 62.9% of statements ok github.com/hashicorp/nomad/command/agent 74.657s coverage: 72.3% of statements ok github.com/hashicorp/nomad/command 63.592s coverage: 42.7% of statements ``` --- GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index fb8ed6529..81582fc40 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -264,7 +264,7 @@ test-nomad: dev ## Run Nomad test suites $(if $(ENABLE_RACE),GORACE="strip_path_prefix=$(GOPATH)/src") go test \ $(if $(ENABLE_RACE),-race) $(if $(VERBOSE),-v) \ -cover \ - -timeout=30m \ + -timeout=15m \ -tags="$(if $(HAS_LXC),lxc)" ./... $(if $(VERBOSE), >test.log ; echo $$? > exit-code) @if [ $(VERBOSE) ] ; then \ bash -C "$(PROJECT_ROOT)/scripts/test_check.sh" ; \ From d6e708fe2da24ed128686de095b11bd51a1df7b3 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 8 Dec 2018 18:15:13 -0500 Subject: [PATCH 44/71] tests: setup libcontainer rootfs Using statically linked busybox binary to setup a basic rootfs for testing, by symlinking it to provide the basic commands used in tests. I considered using a proper rootfs tarball, but the overhead of managing tarfile and expanding it seems significant enough that I went with this implementation. --- drivers/shared/executor/executor_test.go | 39 +++++++++++++++++- .../executor/test-resources/busybox/README | 3 ++ .../busybox/busybox-linux-amd64 | Bin 0 -> 1001112 bytes 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 drivers/shared/executor/test-resources/busybox/README create mode 100755 drivers/shared/executor/test-resources/busybox/busybox-linux-amd64 diff --git a/drivers/shared/executor/executor_test.go b/drivers/shared/executor/executor_test.go index 05ab48938..aca70a6b4 100644 --- a/drivers/shared/executor/executor_test.go +++ b/drivers/shared/executor/executor_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" "syscall" "testing" @@ -58,6 +59,8 @@ func testExecutorCommand(t *testing.T) (*ExecCommand, *allocdir.AllocDir) { DiskMB: task.Resources.DiskMB, }, } + + setupRootfs(t, td.Dir) configureTLogging(cmd) return cmd, allocDir } @@ -123,6 +126,7 @@ func TestExecutor_Start_Wait(pt *testing.T) { execCmd, allocDir := testExecutorCommand(t) execCmd.Cmd = "/bin/echo" execCmd.Args = []string{"hello world"} + defer allocDir.Destroy() executor := factory(testlog.HCLogger(t)) defer executor.Shutdown("", 0) @@ -190,7 +194,7 @@ func TestExecutor_Start_Kill(pt *testing.T) { require := require.New(t) execCmd, allocDir := testExecutorCommand(t) execCmd.Cmd = "/bin/sleep" - execCmd.Args = []string{"10 && hello world"} + execCmd.Args = []string{"10"} defer allocDir.Destroy() executor := factory(testlog.HCLogger(t)) defer executor.Shutdown("", 0) @@ -281,3 +285,36 @@ func TestUniversalExecutor_LookupPath(t *testing.T) { require.Nil(err) } + +// setupRoootfs setups the rootfs for libcontainer executor +// It uses busybox to make some binaries available - somewhat cheaper +// than mounting the underlying host filesystem +func setupRootfs(t *testing.T, rootfs string) { + paths := []string{ + "/bin/sh", + "/bin/sleep", + "/bin/echo", + "/bin/date", + } + + for _, p := range paths { + setupRootfsBinary(t, rootfs, p) + } +} + +// setupRootfsBinary installs a busybox link in the desired path +func setupRootfsBinary(t *testing.T, rootfs, path string) { + t.Helper() + + dst := filepath.Join(rootfs, path) + err := os.MkdirAll(filepath.Dir(dst), 666) + require.NoError(t, err) + + src := filepath.Join( + "test-resources", "busybox", + fmt.Sprintf("busybox-%s-%s", runtime.GOOS, runtime.GOARCH), + ) + + err = os.Link(src, dst) + require.NoError(t, err) +} diff --git a/drivers/shared/executor/test-resources/busybox/README b/drivers/shared/executor/test-resources/busybox/README new file mode 100644 index 000000000..f60a0f318 --- /dev/null +++ b/drivers/shared/executor/test-resources/busybox/README @@ -0,0 +1,3 @@ +Downloaded busybox https://busybox.net/downloads/binaries/ + +Busybox binaries are statically linked binaries, that is a multi-call binary. It's a single binary that can act like many commonly used utilities (e.g. /bin/sh, echo, sleep, etc). More info is found in https://busybox.net/downloads/BusyBox.html . diff --git a/drivers/shared/executor/test-resources/busybox/busybox-linux-amd64 b/drivers/shared/executor/test-resources/busybox/busybox-linux-amd64 new file mode 100755 index 0000000000000000000000000000000000000000..3391e45b3a8ab645bad05efbde88840d8c9aa745 GIT binary patch literal 1001112 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 ẓ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

3v!-Pd%|=4wW^@w74$5xU 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

UZNw)omJ zD}Zsx97X81OsQc)#2?`h^tO~nAR71T&&gw=hR)d1Wz1h&Ey~Hc=!>^WKk+?Ft|O)t)-V$JGwlIgY%W z;+>ds{2DKBERUuB3dd854e!_-cZa$!B0^ndiC#2zUVo3hhr*R^z366HADfU)%kn;x z7C;4(7I0a{!_)l6eMr1+L*n&tUhPTkGU~i0Qhss7dx=|*mg^={TkxPho-Ji{men+LruFYa^QOUVo~Zt@aocR8bndZD8(RvxLd`Yc5P{@uy>xDM z-;UDzd8HT{gTVDwluYxbmgI)sQ>9SK@!>);6sAZ=Ngz?OqvR2Jio7-Q{yWB+Yh!pY znKR8+{ZP}7Zg&?5q@^USm_!jJ8kCd=CFS-rQ>Kt&%$zNmPxF}MHhH~XawcUpGUk+43+XQakUX2g9% zeevQf{?CnVppZ8Iex^lePP!vFEc67LP3P9mnIe-_ds-stgyu}OY0r3h>L{5;DnAPC z1uY#VGpzU7GOX?4RB5s-v;^Tj5D(Rm&{2{ptRb!Bwqv3UlySB(Hb-;`#mLWBF>~7J znbWn%)AC}BO*bY@fnmwvNJ=QDIaBSyVxwd>lW8Iw(9ZPMXimXKZRy&p9nb0|v-Pe- zwRZeH7uIKU`*r7(c*(Tb6-LR_G13VXGKSUm$kQyeUv`);vh_=$j*_W#3Aca9)=Q99 zb2VR_9{1%$@1}(yBPDPpx=ORUEVw*pyjc>Fx*izxtHuiKqH1PWoE+rkE{!5~;eFNsj-3l4AZJ89Kn=$5rkh$Zd8& zeMryc|3Y&CDb|@tFUdoVXU}&j$$=q%q6}ubjFLzHqbwNxq3J$03SvUTK=V%7Gdujl znehKO56Urf%Vlq{Ov?PIrhV&IxR zv)&VU!>2l(f$N9}hRR*D44AnYEfUwNz>f%xc=*rdw%J+cwnn@zZpERM2z%9WO&WR? z4aHy5NrJK|k4Tec?%+iqihiS-=-jPJ6EE>$Bid@-K=>=BKr9>0uaf&+B{Pb(->wO* zNsR_oVZpZq+g!C1?__8!nk%e_Jo9bqVWPQM9++LP@+%wlB6$zt4d}FexU!{0K%t*( zsz;4SbU)>b8wRD?7LN=JxC2Fb{U8Kn;OFsptJ$YL?W?QNzIn&abzZ^Rnh))Z?UBdq z!HkXO+xFu6!?8o*wShkM=QL9Y4V}*O@@%0?|52D{(=64W{i6D__)<%y1{=9(U>gVO zgtu7~@RTARjOAjG<`-?PqiM7F+7Vz#$E@3lXZxe(n0`c=;nH@@3f|3)yeU<&4lR5x zqrnp zK9P^Nh~C={^AvtRjkFDP1n+MF2XkwLk+$lLSJ8{e)7vh!b+Lu-vK_M7#@K40Aj+>w zF&#j$Ue+z4<9U{#%DHy!sb+cR%N)PH8(p>FC6>dAyT%ai#VL7_*_JNnnj^3I^;{-9 zeRX+r0)2cqP9(51O>-Y+7%68)@$kh1?fpV{vvhOoA(;zaCI+mTPv?eWa(Z+NXpw1k zO_?0F#I7?-RmDL^;$uvqw1q-)gMG?5`Nf9HN~Y~lyt7nU366E_$Y0-k<_k;bzUdpO z2p98GQx-IwdDHv~6X-$Pq=`Nqw}am>gEL3AWE_%LUuzUkD`qZS9D*9$XX26P3WRJC z(|lr?ov@Jyj{P&V8$!5-xA=My24q0cwqMUuJS2ls%m6(DOc~9DU(Z*$kGo0`ef~H_ zag=SiDLM~C)RW+)=t~Bq7WDBK0oE-3XLmd%vPiypgfYRJ#7rs>+!Pb+Q4xtiDd`9O zsWXVb_YTpQ{f8HIBege_54r$-2 zO(L%&Evq0;31B2a>!_?8gSv>2RYj2m1roA?j6|dLT07-)BrO9fb-x7Kl z0ozgY_R$HaOnq!J@IP?4xr3jpj zpd-heg~v^WP~L{dCJT)6$P6sCKd_hU`_1tu_Eg1H}e`L?W!sK zMbO|qedc-6x+XVd!CZ#7GX)r(*WXLE_rjp!W^WTcI=U)V3*QRW#ZP^pf9R`Iz7Frm z+T*1XQXw!HNLZ(O3%$QDwasJ?^cF_`ELrJ+Ov7sn?K~Ljbm(3ZvQUn$tx_MZ(D{0q zfDk2opY9zg{da`QZ7D}r6{`okKl1aeWbF6BfKB(rN*Shu+_&>wVmiT8Skm7+l341>=2hhK3N=X;Wy+2)R zyp0&1^U}>X|D0;m8YiKzPb z!3d0iuS0kzTXYS7X61U>GH-X+9M1@#0pYLcM6V8gpG=LUeu47|=~;6;H!zI9*9CWY zY3pZR{cD6mu}$R_>&MmX%~hG+w{CkG$^g>r z>a)r!PO;&T_pfUt&*A(xhcnXmYp}#QAXrq`D*=0R(s4jiL@Sa~m{sx0%Mz z6zC?rK+o20f?V+JkI(oPPRKwhnbZvPQwku3-k&JHPRhd-)9y*W$X!|HGA@+ZFbywb zvZKk5u0P@)ya~LO4~ZgW3Mu9v6EFA4%L|E@S@NRu;@4jjDl11z4oji^Sw5Y!xOq2_ zm7rBv?2h8}X{MWvN_n)gOg5(EB0@Ev#Ou6KMU#{>D4iI3?ZWwt zAt<^ik(6P?A=VTp@m2J(j#1Q==Fj$Z$K7huq9>>hha!t{mS{_Ha>(DgX>of8{t#Nq z;w>lx;Eianu=4hkv8}o(mRa!+goCWu?$!s3%akK`-W6|i>)hNXlpLsb`N8I@kws|Tg8SeBpYc#YU6IH`>jG*U^jF4 z9NOh^?XGglz`e770)e8<4C=(ml6ocC9I{`%$GFws(e#uI;oiNZU`^j{mQlM57KCO1 z{gFf@59SM>bgRgZ$p$IAvE}g##fBb}QW}$U1}3J;zH40m>E#JbsICCi2(OWLic!H& zv_`dcl5~j8i#PVhHK@bW60!#)b{70d4X5$bNcFt|BxTlA#0d*6RKplHgUYDjL@%_W zRpxEdgNiOW@2uP`HQNH$hfdm2W(eejPNoJ6EEeOBG`IQE^U7K3*qKnuW-gGVTX89k zMQj?+u5Fm8!n-GJz=dg09D`3LdM;+#$oewPC=TWX4d5|dVWtK1yBZUOWL!msF zgM|;o{|C4Y?L0}LJlv*a%GIf(-s8M7IaFeh^boT;5fr2$0lu*5Qwb$+fzL75!o9+g zNpQY3!Lh6p8RXTw6(X;0h7=Q)jW00`Z{VXHxN7M~9q#%*=8s{{5M7PqTu(3H?M)Zj zo6;1kAy-&mFE2PAZ{P%cP_>JT$k10>zp2hE>T}HXQE8polqcPj205H&{=Z18YmwGu zhrT-0tTV+zAM|n8-(^#N>YJW@*K!58Kz+QXDMA66`Zc`Eb1M(k7TdN4Q{ z-%#3wkEPIiYK8=1Cl0~9M3o1lW*Ib!r#3wYC_jovVyr&lWAhoSaJnj-5_?d}klnP9 zVo87xo>?X}HZECaJ2+038FywGN9^KcnHSH1bFoz>Q`MCwy^UoyzeEApUcb;t`|iZJ z9yDK2OL9%qU&)qERSL?8y8)rHnG3~YLKrN;6T{&g6RdQHtRHQ8Mj; zv`Tk;96N;?!mrK8q4qKf3o-tYd1Ai)b#gqky5VYR3P-qVBdIc1DW<|DJ((_sBMKlh?{?-7@lafrwzbKm=*SB}@-~hkC*=zok1l4Twr7n>I95a8#Z)7rDP^c$u*5z^MCoLy%$haNC z5XyfBug_M;>Q71`9gCqu=*bL$^3KNsPzoF0UH8pB@C zgM{_&C$fK=gSaB#G{l*-%V#XyEX2)+Zr=@BV?WpW;Dzqc_k99aX^l@{vI}Ff%bdpW z(z!lDabrW|?{F4#WPwz4nvUZ5F6k~xwTNAG@+9RTUKrs0d1fE{6oO2~&CL9&JKp@| zCgBNIn>|deO1&h79Y%}DiBbe*axj)==lEf5t^jRv%E_{?5udD&H>Z5U4Ezla6|ioY zb)ViMnK^OinnNH@V(I-^flQ70<>jRW{MhyC$|`oHaw-zbQ&!lqiq&QnS z&5C8N7$9$H%G13NzPq4cYU-L_Zji|;bA2mM%6o#=_)v=Kjd>+iVXvv|#X>Y1CYHla z? z@;_zsgT<3={TkZB1eaks?u9qQ0yw!b9N*G8DaL&0-@B1PBW%@u*5 zvZ=*iC%wTVJ6tQ~wMi_Qjd;-%bjvB4Zi5q9d>4Kw)KQ{E(zgq&8pXs>QK+*n;3&I? z9Klg^8kHzy!D?CoN`*^SgZk|xi(_Oi*6v?GKmEpVF~6JwT`br41aKI9jV#tdEO{}D zH0zPe(Ald5`W_*w8)wR(&Ay2F4xt*IkoOcLr|4_i_9;Q&ulGA_7eUEZrN>@H<|5T_ zP!1ik(>SFfj9WVSlMz#AtMs<`L)n`%dp`W_$l&Q*CFcW5>)&eys=$OYrH3*a-mUY93d372q%M$!x8X7V{r?oupZ1`nYuS5#&-z(yAEo z9}6L(!8r-2S?ZU8iJR_c5Z6?FXw6s2<%*a_zW#_h^kHg@+ZE(q_&$qKe6yfy%A@ROk`lz^&M?HDck@MJ@H|L%kMyRHLJ1bcbiRPt^vBE(K`@5C z`Z|GRkj;lz^Wh2=B%U-yU=S9>%~^zdP|*_v!%uu82vg)HTOJc9@G_%OXj${9rv#G3 z`!I|73@>f0D6u;p-_4?Olq0swYWh217*%2T zM$sA`n;JD0OiHeKyQ-};S2jeI z9-5bH3*?CpSmlEN)DiF=zY9%^Z&M>TuUZyX+`O>^3C3EX`fofg@?6UWmPL)**!(0# zQR98m!?#G0rIgKA!nUvwlG_&i=&5!#E~uOegv0z+{7a7FN)*?$M|hH#xDFQ0RAEWB z2Y%f2!5h-+9p>+mp+M#~ia;I?>$9e>2Hqq~pINrK3Zk~`KiDK|{miz+6!Ta^If&H2 zn|VLBQ|u2~co%b`02!OWfA4qVTwXjQ*UMD~o-CLzKUdV98Mnraq)JE~5)lkYFa?cc zR$WUqamAr}INslDE}}&2^Tf+BUZmI?L`M|xk9`V8BC{_s&jVz_B@|zwX0*oq42Da3 zG_p{-+Ch&tvTg+DAFki{>MO@r_*RlyMW7*PO%BrYpwP zX3k{-kE7E;(*OX7`9b(hbp(Gn4-u-Z=DI6`=c8pLg2tLB>{q}Z`|NEzU5V8vnp8E{ zT@lz_bDb?v?lT%?1tIK0Isg6uHNW#CMFN?THuKZF$TGM^-PG(<6lSD(v!+-FMB~K$ z0QKPD7YrfJTaMX8k~q2ftwQN!?+zoT_UthCo7ad7D?QCO41yOaU&fb6>!-n)Hf;vB zc^*5f?p=(yenR{*+fnc0Vu|<}xZQ8uyR50}P`OMBbLJMAEy0Z1^2IeYJ9bsm=X@(U zx1Y`tac?ZA>0gPQ8?2lhz7fSu!@F2d+c7jx9`I^|1i!047t9mmb#1|KoA*mo{*IF+ zJpBKTLZIPQ0*$@ebnPB8&Wz>+;a2Wn}6t$aQu;TQVa(!jHFrL!X$&`+Y_a^C) z`R-#-fA3;PFh>}M4zC>Ig*Lq^zfnPA^8o39aS80>wxi$K$QRC@u zo@W7Bii;MDv7Xb-UDHF|{)&4SYT-v^_Do)=rh^FA&AS(HQ=Y@e6C$H_%1kkDrV4O+ zFs@3k;Pob(p6D6wK@j~Xr4~p(PmmwW(@Wl zmv;=wvsLP28ITsfO-laQ7U3TLB1$)lxRhEWCzUdzE-5M$_p&Lr;3#W$Uk+tc`F)yS z0ysXkn2`>rc@O>J$>U5Z*I$!Qqd%cqb&^wCiv%5;4%RJ!(h5E$B`TUDAZ>^i?#q*s zRGH@hNl+x0Eg3wcPpW*n@j8aBTUEjZQy*l#$8wNxYK^nA$|H@Z5ao_H9N#h>g9FQq zpsjhebUq6$H6|s?Vzt=;H0z`%CSm4qUa33_Qn;w;4GNbVqm;}deUsXl&T0~lPBy<| zh+P0Xgmw14%)0#tz3$nNC=$A+Tb@5yqIPYF?QG z^i|@IXkpPi7fPZq#AcKNdBS0k`G*KHU`UP6D2Io~)n((>_$ocS)@P*s&$)Tb=%Vg2 z<7tbYOmtwCr#&N)1$;(v`i+sy-BN{5FR#DRaO`Zzs^1v;@=(q3M=UqdTH_-Q#={=k zrI`!9mT?>~36Q$Cp5sC!o6t%t1g!Shj>@vNkyOKE{O%8)5%;sRlE zO{MXu-6(TZ>LV+4AC&J&DX0jf)gyEBe8LP(u2(&(K*(LbNc9FeQ}ibwQ%+RTsFEcN z>)&;YNT;BSiSK1DE1yPy~nv;;gdW!iaYZ!>bC{Su|zJZAY6D`42bWJgw+qj`3%3jQ7WWQVt2 zD&y!NKpgb0>P2cMRNQ1nerQ|6*~o$%3XdT(cX3y+KVHL#5*VFCy#$X4X2_?i60LEL z!fY-(B-f*;^MrPBLz<=4T}D|n5&}+eR^0NnLpF?-eGc}J$P;nbDcn0vwbs_zO;WHm=rm)S#6>)jN^^Ob2}}*u(-;?$Bc&V@X*X9}If%XEE>5GGmD%5ptm4 z&B_~xcQ_1Ot3UM{x2BiVGjGG$ZcfVXnx033*H^knkGBV}r2@QScyx^H=tH8V=6{1O zsmNofbT&ZZo<)9XuQbMECm4_E?1!;GBA?RgE~nLXo2*SodVH0d0qUIQUbc`AVhg~rucR8_PLt$5?q#F+)f!9esHGbIK|UynUl&wPw~ z>!XiBbA`G>LSBWM)EM4{KK%nUrz4(L&L`eQifzo&>tvKd@5^6X0F$27#56>+=_P1h zRJ2HC6G&)wp{;79l@Ahz^4@v`W*l1=c82_HM3=C#m(po|W$QZ|ksKUj9;(Hn zw9e2quc!UUR#?Y>L)xSSDe_So6JH5Z`~)?XBRNMG%G@(gnDM>lyJWLPSa$+S1oo9H7X)*arwrB1#c3)qt@o zIZlmI!QP$h_v$DqyDJ7I=6|WZ{oeYR69nZ3`|vkK;(LxZw}QFYK;G@>vGHCn>FLCoeXBtHV%nq zA@E#xEu0sNy-$4LMa@cBbKyGK*R}8#2nBdZX$u_tMq3;`U516j_e!OroSlkPvA228nnOgLB6a=|5C z&x)jdi<{5lBZ`a}AY3@JK#4epSiMjYWpD+E!L7=ZIcuIo>>;GSQ_+UWi<@Rz)tUvW zmdW)^HC6&pFCYmW6Ji`gGJ-84`grAYY4GG0Hvv%uD}NM3>06uTtB)oxGJmV!OZNlk zNXDbgbv+r}^CWZEqJKRRNo&EFzGf*zG9STdSG9cjJ}eK|es@?AcAA>8+VnZ3!O zPmHCyX`8$Ls=PxHeHp@7`Q^V{@WFl(Lh=hLZpOYlN7+K`GRW=ivW zWNCF`FWS7FN8r7QT%bt=0*bRS}>NzO|M|qWcL*L(oXq}Ov&=; zinazE4jlDcFs=ds( zJDodZqOPMoDEfbaG;oo9#M$Ij%{ezqopa@kon;<#&<#~SA+ohp3xl0}l0t|~ z^$D6;Qh3>y)C^>$hN!ggj;_h!)~#lDIvW8sDrG|jOce=)%8cvHo`9&apeTgwR`)t& z?d)h0*3EqH4r|PhpCet{Yc7QlAuhvfMpA6a5h1OqUmjMsl^x+Mga)!E@zI7|9uq@6 z8LEuga<6G+gnDKN_gksc&psp7AKYKrQ4>ZUfGg0NZ5K!uMg%n<_db2t`_$R{v^w$B zUehH{?KK8XrjE50+71R*o~Af36(oa=!W4;Nakf`RR+YvB@f&pC`ZCxKFsa#248* zN;`ahy_MpQrz^d#)R~!;9z8Q*D7`8;m;$Zi8p1aD%u^W7k>AHZucU~+#l9&zQ?0ZC zGc!OXj(jRp7usi2!oI0ezs0c&)&-lm?hAr@G2!1b_XdD@UQ9u0FK}g9MJF$QeCYV> z)adu`ME6g}xAd2GPsUnYX9W9D$&0Z*8%_J#*lrPKzHdc-*ks9?aeV9MzF01=j8c4* z3_F;fhhXY5pD`<4=2S;WuqOXHLNz>%VOt)JzPG+ri^#Eq5Mo6OZGl`vm7^89As=At zRjFr>Zx5d>JtYVnZi77HbH{@mT{O|UW6R@fa9M;YxBgf8VqPEo4qy{2_L>z3`1m35 zG&G;{X{0D3^|y!nD_C(u=7gLH`fH81T%VHvyv!Cu0YM|Gda+j@=iGQwZnE}zM4Tc4 zzvAmXhQk@$r!2oY?u?H(-Vg|Yhn3pV7E9iicRAHdm2eD+N~`)8qpDGbGfr}X!%BBv_#$G+!)@CgRZ zD=~duNG0c1dQt~fj?=T3jcb^%`sHa@c(wFTt!VK$?#8OZTe#7!l^z*ezoby|SnOHu z$f&+$@s3J;Rtj*Xt(E%B6xBM@LCZq#No(z5kDjePi%nqMPy?qmjz@4fxZJ4D@*2O$ zK~n2B#yNG>4YB&uGbg!?TXV~e$JMxt>zr`vY#BTju9|ac(o7TVP-7o|N*)P&qf1r0~b{WQsTrt#ZWI=v_F<5h+(m%G^?aMQ7#MczC>2 zqEuE-VuF}|kmHzGP~O0oqdoRc?adB*NJbnTp}^S!?wS<09aYyikK5mqkrzKv!o_gD z9wN6KYV_KZ6pD+LKeEkoNcC5IR94Yi7GI0!wfW6nK+T^QftBlVtk;l3N^IFhVdDU03fg@t$N|h*{VDmRXO=i}`^$md{CPL` z^4gb&H+b-J*E9@p*v3#ZhG!UeV2atA8fxhi8>D|08%VNSd9qs8K(qACWjOoNKa2hs z<3b2l=1I#YbS_DvJPx^EE$Q$CRxrN)h&QdBk?<4M^c@MWgIBM+5&k-OnZ z*%#8Elug2DkT!JvK~j#k_6?3Oo|K(Mm6wO&hIgb`as85%)#pKV)JOcNo#j}o7^MU! z8jmd*{@CJ(V?B)$Z&cdSr#Egv=o#^)G3wzJ(hg)9UhPfvv0Hqh_yxi3t!65r%{n)l zF4e%9{WpHC*lO3Y$A)6sjdrMd4QK@|wJX#XmkWVeNCZlhWe;=zb4o4+8lJtkH7#{oa$N9mjxRo&)hxJ3J1rta-d_&>+%)Ua$yG|2{Qlq~TWB`e+b z7EgXV!5y?P-au?)j-R5!r=I7LYpHF^ZPZU75L*pDa_@HJwSsuRLXx870YiZ4TjyA z^#7AUUif#zxqVs_$ESGBoI|$YCB~d3G#uAizSKF}Oo=ZEAq(}Ke7sM4$sv0z)n2ml zPPDd-VR#wV9J&-;|a6%&2T`vk{Ey2&wq%PU@#_un#ACXc!XTOvP zrlVY|Z1j{>0GGP%_qiKI!5F>!e6%}6&G+&;ski)F7U)&_iOqW}`&S)CBf3(rI;=Iu z&ASA?_ghr-wZ;?qtz#pe+(VnuSgSg$d%unKr+h}$Vf#0F`M1;|ob(T^4^WJ_CxydB zE|us3^t$yTXXu1|$XcNy{6azw6db7CrKre;c&H63f}*!J|9mhd+nFa)W%syxpeKRF zeX3m^*AXrJ1%1Hday8Mj2Xxqk!P@MLjCf9K{6{5JLTh|q2#lFY%iZyhf@V~lgg`n< zTwer+iF6!^N5m1<8sD;tFH^-OE(K(LiSvK>n1_{4Aw_1pBuD0*RL7mzIDEkLn|F~a z_m^Zjp;6}VWDZoFQfKSfg{r{clLdr!so;f?s-sPPX^i;@rA1bCzVzqUZEymZo*~2( zTGrMlc9wo5Hh@G$%2p^+_C;A76S9*Y{YdmPK0bYquFOP|3P4OI6%;BDsmb5Cc=dtv zba$v(F{r_dz>wS+fFVq5*-w+|bpj*$IlHzMe4t=^!KR~aeS?^1L~$YHZTOQWG^otD zsl|PCHI7gp!{{>eEWFW2ZixWxG42Sji=unMNNmK*P8P;C3(pnG8F>fih&B|t(Pf|e z4~ovB=ndwhRD}*^4q5{EYkKD(Gz(;C_$VK~^2KdKK+sK;C^K&BjFi}6ftW?vcUZ>I z`o_om>l<66eQR4;o?_NBU$aOrhZZWrmqHPe2?3m_Ot=xzN5~RS5Y#$UTl%(8Nmb)k zYJApD=gfbyJ-fU1dq+14vb0baSoY|Lqeu8f=a99~8p|>#PzrU4=s135efv&b1{wR7 zV4&5ofpZR`2xu} zijJFw9cJ--b&{i-vCt{|g1Z6VMf{dURyu941m%%8oI>W^_4Bi3kj($#%qy9BWSYNG zFJY(bXKrJO(@CPbeuf`Cx0?==<|j>rTYY(#4=2ip)A(@3AeyBuZTKt5(m#R2UO8VD z46<||d;%_9gS(U~$jD^7+nDbZ=E#l2S(qVjWSk?CeRJfNvj#?d{oMLOl^bg7*BVW2 z-It1k(9(?_SDW@^1b9fdwQ!gR>xO2B;+7|XAA$Bc(1d4>Ozaoh)jc+n4b#3*rJ8dY z85Y_pb2&OfC^wbcPaWGTH0yQV%WnUK_ z(#G3dpHzJ!+U#7Tn$M6BQ)j!+IyLK%E|NG37G6|18EHJ!JP&`|zfKz2tcmnT>qDJT<~f-)As zD&$R8aYx7_g(=bz@|`X$vC1hdl%2xUcxzIHXYeF*xFhrkPeO}w(j%NT;R;+2KQF|~XWy}TkN!=;QP(%sne_{= z6+$SH7!K8~b!)y(&YgCGBJ~Unw#7R+dMZ#v3cw9eI919H6|nWvIR&-{SB65Neh4;v zt)hBof^D(0D!a3SZRklS+t+%kZvqy9XX359`X+$kfhrX3yLlJPj|@Wv0*6msJv2A$ zvfy^m+)XqWZ)+{~E$Z06)Ofxgq*+I@Uofr=D*m*5V~XLeg8L#*E&wN$#`6sns?anAE!QzFfVE3D=;8LG8?P-fU>#-NdU$x6imKR!Sh zzmAfXk{i307hCO|m2w|FYk*=I`Z)i(zwi8plpo`}p zY#Hs2lr#2=H~ISCvr|uRCkx1ims@^}onj@!!Q4FHF@h_N@+I&YTDUw_bd<}tMcgUI z!_x3L>~1-rJi1Q)bK9z==Z+G zW}HnVU;5>){a#kE_H-kE#e?sdo@#krtX?C_`*2pOJ${0;@`!^_(P6uI02C&{rj=~P z%pz9_JaBg=?18&su8kP)4h}qXofiy=W3n}@cCRfH9=}6)75#8o#cEH(T<0*qeVwOJ zf(H|{$R;TlcnasHp!ahe$nFN4gope82zwj&sEVuce>b}!3j}W{pixnRt~D#5iJ&GX zXqIfqjchcE2#Qr&D8*_mCA$F&O5!Gv%XM2@t=iW9YM@h13T~Z1EIb;(XQvkO?%~~|-#w|H^6ur`tKYq;+j-CCJzKwLr>^6@ z5AS{Sd!N+Ryyx(qqu+B2oR4=gUajbgg`*LXV75@TWI-O-8k`prY_;A9u68+N z`O=sT7sw(}m%BbE2(mm0EBWk(rEz`WAk26*5=rS%x7>k}2 zl$7o=?*A(f_5%Ol*j~@!cRlyMpgP$tkRsbvtL;h4Q2%Vjl50o0J+Ki^+g8j!LqltN6tgH3s}YJKo^GgIauXwmGk3f_3()b(p4{{Ygeaoo!_9g>Bkzb{!3O- z(|vmR8jD|){l4+O{pb^(;!%}i&y(6AE#oa}5-W;rL$~|5D7XH%Hl52a=SZ{jdk(*= zo{_aYU#Y+FtKJcFYB=$e(rnx*aMljW&5;sTB)7lS`Xi{-;!~!W);aGSybz+fY8=}` zTM>V>)$c#E#7BxTRhzx;mdgu|KZ5GRRe)^ff&?WD)j}0IfeYj9YOa1`D0thb?$B>S z^sLJDYO3>w4%DjLs%m+Yt0t8@*d1s6T~f2hQ6nma`nNB1t!zgLF?E%8r}E?vt09|M zo(TZ{hq(6G2T4(DPBdpppVn%3>N`uuyI~u7jCz;!NqLrx=Q(Q)qKY>=_T`Bv^=$SW zYjg1BWkYa6ejv?OVRY=yvwA{(*RRoH2?94X9hI+mQLM4{6OEuV80f^%1D{;R@+oON zBZk~>;z@k3?5$j+>Vte|{ow-^wr88TkbI!3WwZ5ebX9MyQ`a2I{^J)Hx(bkMM9L@i z#*x#P#Z~>YTHTA{hoL6^N89P|qEdO~Z=&CdoPD#H_vVr!BbUla4APIuim$PstrEm; zm8-4JA$vd`Z7}j{p2>3Ea(JV@X#0-7*?+uPgx=U9yscg=!|G}5F7z}A^Ra-Ih3`0TOj3PTCN%(a7vaRotnjxl&R0qs$|jy zw6udABUkO~0h7|2oN+kVo)G$T;G_#BqG+qE@Jjq62ou{Zg#=)J2WNf((d$w_1w1Yl zt}~i@NXOnYnv*yS#HVr**SNe5xrtIe3~JQA9`17J+)%EFDqT0{ld`+~-iF~Avqr>@ zUk!e&hX}iPY4QR^hw{cl*_A-+3m)p@=8nIY!UBBI?t_;?UwvQo1p`7#UZ`}BeJkGH ztzlOO4qFu_MMMa#yjkNVbs2PvU5yQXt24wd#qaeWx}kA(Zg)PyUK0?A|o z`iX{o8KuD4NTcPiJcX@~4`oNC{b*U0eX-~gBSTKMtuAxg&5b^QSI19%^+d{ZS~}u< zz3dZ78}$a4a#nH(<6FHm1weX zQq0cM!ciASn7A?gyhKn>U<$6Ae5h`sv=e0d5Gav;#-7wGIX5xcnKMVY#lLcb6t%X) z@iF$Wt*-9u>pr^>+9*#oJjp-ROrOT4kq9%?-nsqsi7hE3t$xfGPLmPvC z$(JpueJMXGy}sOM=(rZC(;U&+8Eu>x2;3pcqyKTW8?MN}Hm*CR6SExTFG%&ImsUh> z@6O(#deQwJPx6mlf06^BpZVx#DF%4uGT?zsS6(C|U3rQhHNweRSgP=a&SXjD5-&UT znD)z^`W3jyRSjg}Mx9I#x#WP?gA6g&tEiVAU-=~-8phs6oz6VIQEm>8y`lHr%C3~= z&gRr@Wta2VOOIy?DHJ)x4NHX@@}e;?6a40?Ujp|Dx~pmCg(q?e71o)4+?y#l8J`^b z(xDmmUeW6qqC|7fwp${N$T4D=Y014RL|mqOW8>EZi3}k!TXZ%Dpjc`k#-XvVJ;pDt zqk3@zvnTl%%Hi2|44!Q-Y_6tetGoIo3kN+}v9f?B?D|HV9N5Z?n2WVl{H6u|H>D_0ra@6`m}t#R+e z=(Q&P<1C~3D~>_I#*dk_xABD1*JzoflkUkfj71amW39`BVNY;LPOz2F7fPBu2i+@p z!rw#+`-m4?sTWod^Up>#%s3ESoAJAOyt*q_PUfamJcQ9!ven>Am^61yuU(3 z8C)#k8?i`mR}@@wdadVB~H5^|sgjUYs7)U^)bZnOgNxRW9 zfOlfw8H?ohT1E3Aqs7I8vHW&7gJ02j{4`_nK1Mp8n;-v~hsorR9cS?WMUr{=y>NUk zI$mNIyeYn|{KCqH$kE;>UUw|0VLwCvo$T~ra#ri4tmLmL8~b`#Lv`%qVQp}-c<5Ym z2BDMPT=noZb;-t;+RK!19}F!y!&p8UKT|)-3bucSE_?arj-7pK4r3RwxhAmrTIo^h z`__j+5k9#(cJ*)C<*K0ak8`4Do~RNx!tJ`wJ=7U;uUT?N4ThFfNsUx!y5EsDs8>&o zFQ_+M`nJ(L1}xOZSGn57|HB@m`BPfZla~1k;>1U0OFMtNE1C~SE&=or!NzjG(clj@ z%2csFlMy}^4jctPsvj(U@n$_!l21~RAbjydJP5*@MUvmV*=SiTO~~XRcuwQd)8_tM zkbb>`^rObyJA;isbbTY$9;bSzW|nkeEu0nhJ3q`)e@67c02IQ9o>mjT*F%s<;vCkEr1p#yMq8N4KG-^riXd;MT zagtD&@w={YC*4}CKGN@ylp=PU;F4-LYnqjk+{9~D^ZQ0iv(wX?vsl@9_Bw5DLnuDf z6GXxqOB-|V&>dy9)iULRORlbHy)P@84bUlXaLHtMOMB~09_er7yc3-a!)d|t;Q3N5 zjLF?4d4(JE2ji95&SaEc2V1`*H3VC4a3>!H7`mAZ@>^qlLlE|4m`91Z;sAdYZ^iA& zEBFy&DiiemXil~>KizARb&`9;NWa)b%R2>&6sk+|f@IxUCSD$mlT zBDvVgmV2TDc*}9AXLOM+m}(06SaB$Vk+MjAd({N^?w6$!*twdmusk;~ad4^8TuVlL zM*DN|i_C3%t}5>BZqktp;KXp)MD z%H+59G1f!XK{g$X3j37t63IzCPRZ0-4k7tiK5bVE1T0vAT=;eped^9k!T?N<#YlN7 z@4}duZfO{&GiF5w>;8(Yd;uqLth2A^Et5rvH1fic^06FT@bRon1tg`iPohhm4$GLd zHH|*3*4VJ5AmL?xMIisYyvNoS{yU56xGQit&8E+bgu*&ZDqN?XJ@AtYT}vAyx$sgW zv$W_Sb@rjPJHS_mgRdKK0wW*Yt3<*HUpNp6&?rXVD_kVMxfQ~;GI&J=`d5xrp86b6 zJJJ)yN#Kq=KIYM^r`{(|Y)77xoUz7>8q2hjlccvhd&+i)AH$Q(Mcvug@+SY(KpaCz z4xh@&JmsomYz)Fa3fJS<(8J_<)bE_+QIhP~2$7tn#7PLlm8bSQ4};Zi=OJHx=sXP7 z(jGaiz554nNpbPWq^*po!L5R1LlDzXTUn{myg3Zv*rz`fhH&hk_))(mS=jygvW%P7 z3ch7o%E8umDEm)4IsHd+)LKRu@2leO#eD3RlkutBc7k=alE^$rJet-b_~0Td@y{t{ zb;iE%8mo4G#~N}gul0RnxL3@+o=5I0r&ZY>L|C$&aMkzSUG19MHt#;fBUW}c-;;gr zr|UT*`g~hkUMNn@PAleC%rW&G{*0`3DPQrP;48IH)@JUbO#}1HECUZ#99pe4-PxTV zIO72UfG%j)G5Y2*xn_*upw9Rv-0GQM$YNG6|H0$pZ0L&^Oyoq`nNL~x;$;|ysz+bY z2YWfb4pmEdkut1IAFiuBmwk_h;vo;WoDY+pYh4y5L70w?U0&teO&ut#h;oXb4N|yk zU}7QNvD2$QxJZNHBOt9*D4}?Lg!!{}%Ga9s(9^jaFjShJ@3lPYJNhXXXLc$_Kl-f7 zT=mWK9+!t!tFUpZ#5Ziyh}~@4!SveHGLjb)ZnY2Op{mc4cowwArBFEt zoC7k37H?jfgQY~IkG1|ecj{pC=Exf9Z|W6$NbFx1A~)ZFc*0UTP+r)&>~_-PWAYBa zXKm5-4?l<-;&UdEs=l`v_TI|AjAx{`QH|1qtCL$fmG<>MF3p*qA#2GRJK~Mz z5vl;!dUp9)>VxMvG!Ks*@k9r?-zNKi+f74;fz-m?HH&+!fTbz%U# zGe=~(UZ{mW+|sxm-z2h7F1tkE3aEJCOn5>!t>1zh-)Puj) z)4dIuy-VdY^;m0CI}{Nsl>c5t0VjbYmzHmSInhCc#tBzD9DE#lPvc`ZKPU0=2;NfU z;stS8rsXzVYS($=*Yw1WxEr!#NBiI`e+tXQ^qlh)g~U}KC!pHG6;K6X*6wwml^;m7`Ywmw3`)mE@64O~_DZ@P5Q^yO_}cUKjm%Ml@Xn*zQ5{|=F}tbS zrJg6B7+v;Dh;I#b5K5z_G-NDcxl&!Rt-pzqw?f;Jce^}PAF^h7xndx=Otk13sNS9B z_@qtDzMnd8r_Q8Y?K!k&aCB_qGj>1~A}x{RNuRFOW%8U^7uO~!Y$R~1<~B4S*bot-Knglp2%2o>Z-&Rg=dFGu#Ku` zDB4RUp4O%x?7u=M%r&(Ldep6z+=*G2dXRf&K4(3SurGTYl?_gqoA^;*H9@28vG>Ze zuStZ@`_zB^j@vYj3rwZwqswRY_wr$zDP^pZK zWTDA^paVPTW081F_qihY+Z7h{X}MTOn@!_nPsZsN_wN73e$>*AjcUZ-c8T7Iwkwz9 zD_v9X!BwG@%ooXUkVNrkzfb*yoiFtlIp^Ud%4e!A;9mMcPYC*TE-G)PrGOyv;FsIoS5wA5aJUr+W5R z0JNeY^UsXG{4kKBxw2yVp&dgz(G6qTF;>JigyfmNxlM#1decTBNKk}T@`XLt+78zv zAq=d;vil(F%TWGzYlxrQ^tlAe5F3==tW&Lw4L3=H@msUqD;uTB_O|S8*Sf0Qd$8Vt z-#$a&qCYd*+Hvr-QZ{ulv$VR!QU3z}0%x25Q0O9o?YXJYy4o+1T+|>oII;i5-PCSE zu^omT+1&JT8Um@3xJ{{<{x%=lG%4T4yR{9xTDuQErE8a(RHt}XX<94LI@{Sv6UR0I zRr*%kE(7yVeVjjlt0H=rPkuQ^vCp#*R?QHIt?l9X`~}jZ?KRdLYTQF`sgtlpoIgWH zs3Bkx5;>JmFYHNJ4$i;J30#w-6ADO(I0=U!pUa9?_NPw#Edgxo-YGnN5sp9KD(x6G zlcs2l$Q9ZRWVY`es(QX*0>)n!JB3vR8k#P3Wg&d-y#;EI^DS`dw{!U>fe|qIV|~k7 z8Xu0&2HKZJ!mc~i)$D(o=VI|I8)XO^SL<^e(!R&3DabBcyaBM#CrQ3pi`myE0W=X0(VQ3}c`MJ}5_5Z{8(3N{TjPjuO0CcWQLX80(rw;af5ZW4J+B z2vju`*24gmCQJii89pnxKn6}?T@b#ZQ%x3vN93zVKIy654U^HSC^-L_JHK_5SF9>iIZJP zwN-`UaCUE^91xRJ7}2nOuTLB(OvT5V59f@HS6>n>(Bck}nbx7h2D&k|_SLCvn0cfx zi5Ph64=(A03hcAm(l4W*m0uFsBV{vX4ymEKOmyoC(CJG4l0VP`g7o-LVyY2L4RNl{ zpSw-AL7Xexj06!Y-mZ5Y+avclwg!@;NQdtJ(+rQ}^yfZ@Rj%T2v$We%2LlAzjX4guMv z^2n~Y;RN=>F7?lI(XapYWkCnKaob-t6VVPs9t~^hz~Wz@h-1;8lB78sx;mzZY7C@j z)jgj`De=#``9+UQO}!3k=h71yrg5Mam6M!tT%H6FpOYtvmB%UHky?7;z zps2NjOR6N8$Jp{wk zxx(!E$AxHW{AigNaW%-(rRF;SLfqXch;J5_H8Y5Pk68VfCoJ zIb&tQw^ZgohkSE=Y8N=w!J8aT*PfrJjv%-v1Gn+n9iV0xv|S=F7j=W-GOxcu7+ML@ z!srOYuYSS@LMPglLVTk+5aWE8#)7Zn^J>oDp9h;h5w?*iWPHy{ydenbc};A+pi=#G zBpN*-#ocpWqkk`aAryPrO#qLa+`Xf7%J<*HV?_RRA9vDO8Hys^&2U&TL6>sd2+r1&S z%iWjYx*u6}z$2*FJ4&AVBb1mpJL{c#=~N`-w7%j;%c@g0o7W5Ms6qKvo#adWL%$tRUs)e zzmG|c5S=!?6R}+G-kBvtCR@#9D$(Pq$-mDLQjv~~g1tbU`L&j!>gWRM8Id6f08IV& zV4I*euBpkl2_wa2O(?lO@TupSIb7YmsUBuWW=~rk+0_2?Da*|5ml!acnVS!&LNGH1 zW_p9r9!v>xQ~bVInQ=g1sas5Dp_moap-HFN`=E&_YL#I^NcFmtiNEUne+hlutGf!Q zD8Gzm*$$8{-)%IDq4B~Cd7csZ!NSw9F*ll9NlISq2bV>o+SrR z0PRUW4uvnfN4{~)tAI!2$5e-LBde{*f-ks}9}AB%Jv;I@A;;oekWEmA_;OX;+r~EW zi31OlnJ63X=QXwtUyURo%R60HuKq-=soer)w#r|@ai(lk^c=$FVJMLCNu?GMBA}}I zlV$FZ5!#WO&Xfwi(o85a)dkF4mKJ2>^}2_B+|=AlaZS@P30D?{xbhWdI&lfZ2!%|_ z?9&vDF$JJ(bqSEA654)?>3b=yWdsYjFcQH+GqW$)c-*~kbXD`As3CP#QWuNun_}ca z;L9D!hq)i-TJgdABJtu6`%sUHj26+Hc6s8=_QV6uY?u8SRKx2%Dsym@kdELhG7WXU zuu((g9GP+#0Sr1`9OG}mI}kcuvCqXfuCq|oPsP<}99K|OVr?}`_s<>ISi<&M=Z=nP zoadepy|{5+7Qkpt^I{)PXgufm@OYRj zIlhvU)OtztcoFAb4<3_cb5v27L^6Acd5C#{1f5exw* zwz}19nasMp&><)7F3MvTcVpdzY`k`k%CsFZ{Eo`i}iZBb0A2T~tw)GC4 zcxQI(?K?Brk?db*ymZLg6pAle4I@f8^z7J2!_4?Z8R+a~GP z-p2yJXeKu_qkboOha_J?vH*Y6%uOn`!?UDuAp`@R@>S9-#t%PWy)kzC1M4M}RJ(a+ z`wZw-4xV)gV|92UUFL2~dt$eS>xOXr0e>U;1>PF9bCd>Uj>#k{y7@L*nJJIH6|JXq1Gv-jki#Xg&hdr`E6ONuQJy7|oxMxatRr>BQY9Eabic z#*L(%)czSQe{{aEvfq@RLI{hUCJ&CJNk+7tWEG-aY3@Np!zW8ee`qX!L1)0wjD0gg z-3>qFc}{e0;&Z2(r%$cs7{#TU**})0mZ|##7|G0ra!ph#8&!aO;30CgjzzL+<9ets zkPUIFEbQn>(?~FK4u7vTT12EM8`xK1k(7HPKK;o4Ds2s?E-uDrpnif$*4#t^?4{v` zo#u`K0T{=iykGKJx_biqGn@w12x9TT4eqC%reiLtLmPYPLH|9i%3NUalD>E>vYwgH z(kZU!MY4WBfn%3xh5b+O3ReHs-|_Wq{X|&nNN%bq5v8T%a@wY!aulnx^sx@PQ&QZM z|CY~*KRD2Mm^G4R#2swj!hvL(J6D>~&dWZe9%Ln&l75e!F8NQXn8h<&b{g;(Q7tJ;+J40YGXnRBst24sXQd;I_!r#On@N zzfQ39V#jl%TG>5YP0xdpO$&|N5@3Na}xr3g$hVI+xG4_ZE0ANP+E%cbw`f zsZKAkGAB3Z@Pi-gwXm8mU_NpIIM~pHWPd1R?FZ^^PGPBmiNj9u%PxYX`~xv&nhh_B z$LDnL_#4JAAERAO`><8z(VYpk6hR+j3 zYUG9!wC0t$8Co-xHee)J2H)WcaRE1w+!5NI9!bFY4gK6sN;32O+ zD>CXt#eQVOOb-Okk^C;`4I2pTzevNjtIP4%80_kENznHCmwF@BcC^UapMkqVR-%}u zio^nXsi*xF^F&@@G+)M?lnQ1o77uVn%WtVveO#^&GpYNQvWG90W*ozYTThcr(bH9@ zlOb|<;yGvdwyp#=yQ;)ws!myOsetZ_o_i8^z##FuKTLEv`MW4Tbe(RKIpato`m6;Cw{(f1v4k^^l87+5EPi7f^Nul0l+yZButmWIO zNSP)`xecVu{jL_HvtjU}rSDFdXD#YBn#)K{O1`n08a3|$8)IGVQo2B=HuBgqmPbK- z4eF#$#Ol0iZ$En=W{q(B!KQT*nikWse)VUndss{K0-fm*r*C0SUkockbZ(G{I^b>g z7o@iZ+Oaw84a~-Im?qIMR@?`Pq$#NjFAIP}0cul)YlT`JR`<@JyDLZsTSm(pa@GL1 z%X6Lam0d`A%4B?p7|mQ%fvvn!-Ub@YG2Wb!TOdP~2DsGsxUT3^H4roSf*;C@v~_l~ zCYqC++}GkUk>qa^Pva%{22>D}Dx~?Ty7{QzDR7Qd|G`cz$lJY~e7T8%+cgQ@eT%GtNsv#@pB>y^-7Ah zHJn;{g_efrCi*&}o83&>DFj_UL`t(Dhh;&}|MffnKs#=bgdyaxCl-UjbD=Xi>q5vCBu9}2PUmkqO zgA#Be7-|flh?G(*(BZWPfY>? z6g$_x*NZ{E`aA5tZe`!kb;uWGu-jpgxN~82u(AAg%*F;#)hz4PL=9+34Z#vDy?*R* z0GP`hi_S`X-@%p_>Vo8?*K$Y#vDgc}8egVeSCAYpf*gBtp=tGyZrXDS($gyRofMsi zk(8)Y_9cjR5VHhJ_uMxZsZ?p@;3$qH>+=b=s{^vA1FUCiBe!fK2ih(eE7-g*y*$C z>8jV=m%H=cRI^>_we$fWcTGvF{}x3JTXv>j9lmjDsPB%9MnnsU%=qH`Y*r=nPzSXY zHG)L)TFQ`y?VqyZW$K&(g!(gU4E2r5k@o^X_z?ZU0 zfg;~nd@l<^Ukc-kcu5v|3}P_;GFI(2>M!m6rhdc+sH#zaS`8j2(_Iys%M7-A9sSjg&jM%!oDmTC)IdI*#QqO#8^+L*9>*7_%V?ADDaUYs3ZZBOYJ|VnM z@FEia{rVP_WIoFHi6?Vl9BMRgqb9E8484yD?dX)qqxJA=6B)6>5S|J1mePGjvz*^B z(oDTuGril4zu^B9l`nZ9)5dz?=1;3wvRc1$L#dDWOkg-#AMgtlt+}WgI#a(k@7VJK zdv7p4J}Vr5d2ow9XQO9m9wEnf1x@I10U-l&?_$s zFN}jyEHye>n{)pNal!wdZz0wjFZiF}&GGRuy(`r}-5%SK6~8Mxo%*w}e08pTEbU(C zD?M%+*B!uwBMFD;X2j$wSo#?;Gp2I|7S-eGzdgxEJi*CDs)hfeg;ZPdhTishO@~&8b)zXRRpZ!? zTcV}y#xGVgBgWgeHsew>6u^bt_A2*#)=_tQ%T8-kdP611#F1cNQ>7Jd@^S+^^=ff@ zcXP8eFaJ)?8*EoVZ}ej^Y{+AV;G4o~hfB_b+Zt;8;`cPebr=zT_=+iL-qEgm8h_Z6 z&tQh**VKjMH+*Az?B@g#R!88#J-3?ECk!r|kQWu-(qV?XL~e!@g=J)9;uWYV44X{5 zg0KvbTofsi_DfQihwZ8PINi7Fy*OyF<`1Ur-2NTAe3qy08&zR*Zh|BS4b*nEk;0G8Wjb&b<)JWeIxliKCcAF~4O;(7iTPHs7p_dvUKit|uvy zCoyooa$G!efvc?EG#3AadT=Ce#PZ@^-6bI59{RAW;o{Wa_5ulj8T>w%eAqg$FHukbN_*Af~N5XHnenv4N{8~F81`qnKzeHLK z+drzXuk+iJi|p!h=dxCMLP7eUM(dv_V|90^e7WjYys=}quO=RKk6s;<^hz zv2`34RcgF#%ZPbQR+c>#G%Y(7i+*oiQEPVwgEtucOiGQL|unty#V_k_XnH zgdB?YF|8^2sbS8ER;YK)bWG$vG_#!w#-W|*#=4CW@i{wMe1%{mWKGLc!MhNb$QJ~Y zb*k=bVJZm(e2a(`eR{uAs}Q!tAAIvsNa#`D+_F2`pIC%=o0aOzc6DZdA1`jKeDD=C z)$MTDdjEhKHmz|L!~rB&)=g931YQ5YURV!!?4+_>?rwZ-+6ybxrR0G;Oic!O5T2!N z+%1g0*nc0NSQC34#^>`qwHtLBGo!^1_&TB-oF%JL4WZp){4=i$+6{T!$mCY0@M2HV zo^;1(c^3e6mwH3asmEAh`dh2qx>_OnO0f^ziuH>nSE%HC^QLI;h?z34#{I7p8zX44 z&5}}c3^8f{;P7OgXGPQWL29ZwefD6?(J?O!95g+%^SO^`Z9Dkn-1D^Q2@16!esrzQ z0CjIs=fNABrCXyHa90IcPt(1wakmf-Of!%YEhj$VcoHWm>EJ7@BrqzS*+jY+KKdqe zf}6e$uO^~eO%08GjecSp**NIL9iZ<1JLj^QQZlv{J^qf~rRAU-`v(KQZog?y?NO_4 z;!O0p}&pN3TqOdoZwj~wCti4Lb`ET&D~|FzZZPD8v5CbU91&8z;3chh$+B= zl>_;NUrLPE%x)fqIT5?Qt+u8x>CnRqAbQaQc)wW?9b_VUdXUDPoXIk(3tR1MV_N$d zyT|K__7@*e;>vblbe}cYuN`CB^C}?8rz5CU+bn7^vJbkht*+itc~Y3;+r<^C8G1XhC#s*xlNF{mJLShau^7lUw;y`-q52L z3>*(x5x*bu!WT=$?@c3S(>M62%?dX!5Nc_b_CyAG9%ycqv=*3yTb>cDsH!PV=(?_*{dJ$@+}mvc3aJ>C0od9)=88t?V7t4ql}G9 z2Wscp>`jK;O0sMKOjB%S5Z9EB^c%liC!39)x_LIv`Ao+Q3>1X?brKcfQTaao!}xeN zj(x&+roQ297>+w~TnS$hc@dvX;TBie&E0S>k`+YN=A8$7%(%BpctU}I3*{MJnO)nA zJJ6c=PNR{cD!cr#P-(eeZU-8_xLUGj#wo!u?F>AjZ1a_2eY&cI7 zn7~GyT82vZH4Kso5VHH?f3|deLv|>zKJ{s3JTz9WNO|jrgy5FE^wDcP3j5R3ydh*% zDP0+}_r@(dgeDQotX9UXgsDeIfPN+ zdSvohs6c4RNIxz`Dwa!v2EVc!RfoP}31PDxmOqt-^SuE7oPC&Y z$MuA*ac|YOQql^CvaaA3T&5pMZwL+lsO*7encb1T*i$x|c(r~%{c7_2!T})#i7}hK z$xC@d0PhzS-o+K+3hfk#%$Q{2wZ|C{#V8wohiWEOdekgr~<2SbtBW~M2LQHv4B zEcJyv#9w|wvUgWb<41mxJ#lo9C8bXP(&G~Q>^Go_uY7a0>_wQaO_H$99G^?a_>Gus zdv;~0w6bCj;*p6ZCh`$`elDR5B)^INvBs!;TV00Ah@GY~v~Um(4j-e?e?z9_@bW`V z+$q?yd0t=WRNz$;4gxN$TW%RMS1LpH#0oJcMB{5LA3P9l#gB90%8Fpj>-TNh+4t?_ z&!}UnrB0lg;g|HNYN?ISo?K!7G!%Hd^s9SsbGF)|@bpg+16c3iM8!EhvwHsJ4D|OP=1IJD5FwGVl-;&HHNd@2qHFE3?hF}^w4dN& zuxi(5sNUV=D`~gsb72CF<<%qYxrL&78!GES$#J5!bCUuYv7K(KOJC)Kanm_qTZgK9 z$ienE)apX@*ReN?Q=C;_7@vHc;z&p4Kj*Yq58AGW8M&mJhAg5~Vwk@@_EApY z)h&CqXiD#6v|OMrkeyVXjF(i0%A;A?%q06={(?N!htF2$;myWNn{hhOBHB|RD3F|g zYbGQ968VedBtCh+6?>3p;rt#FWpwfZGIO#Dd5e6!3PYXox%l}C$=DrgF5<$kW~ZHl z)*eYh-RdL>TNc$xx;RYt*n&)wzfk8wcN>mRn8vQ)FAA=3?YP#p@~+e6$|>2}Brj$K zD1_BWlzYqx2Np2mz!K}37v0P5J<>_hbvnLcn zHp(G!CBa*)33bNu2_vn_2#RsnQxvl%&PE&m9eE5+wI!xjr=!j$Bl?3ftu zQ{hV8C~N;lxpmAR^*G#(ezMkyGPO4#){H#`$eno{=_~D|tRC{bt{7<^#y80; z!wGm|EFG_$2CDt14jbYCVN)S#g7lHA#J_2q{K+7@K`u$R2d4yYHd;yn4y?14AA-dV zA&8Jy{|TgHj|u@sQ4a79+$zjDnnB7Pj`96Y_L7OyjOEw317Z9^y>x?bivsW%PAi5~ zSv!KXkAvNJ##uKu7bQj37(1F5yBZ~6)q2(c zQfuTEBqt7PF+`R61hGziH)iU~k@|9CA1&1N^*;fn*nSC={ZD~1((hz_pg2^j>amJg zn_Mcy!Ja=&ZFC%WjFd6dYnG)ap{nN>{`s9BhxjMLtd==HjZn-&nm9ypw8BYKIbH)AJdRqbb_zID+ z%i#>lRw#t`l&!FrEbFs$W1|}W z$Ss4|u{<2b9Gf21%{)OaV|fKKn!4DYyg=oRPHC%S%U&yK)z>M`W>U?}^P5Kri9ot7 z)zxrE+?V=$rldXpMr1|ZTlP}7#dCdK^kTbGcGZ0CD}Rc3!0>6e+*4e@Y_!}!Kf5dQ z-xo^`Urm2{Y>uC)69?Cb`}<^Qd-&t*!|6lemDlQ{Y{#ekHvyOp%(PcdG4ps(Nx zumkT7@34*r9C)pX3#dG}QhH4`d*XsBYdzF;A)?8n2$VJ%m7Rej z^>*bvVqk`h>h@3o_PN8VoHyqj5%`B-IpW@{@V27`1R;0j6#ie38m=)vA)jDCn5bD3 zr5)UHTlEW;3?A4z*d5*8G+&QGv>-Nr9s(Xc3dV0@K*ie>{yLEXQ`jJ~6>b2g^6ZrUNcC!ksBLV$X8bcb)#8e*KypKoo~}N`qn1tU00K?RoYt8C<*1qjpn!bJ&yR~eSS5_@yCQ~(T|k0 z8=HBPi0tjwujJ8aZpnOJsreD>J$qTJq+ox!L#*5>B+Z-F8&;G4VAtf^k31-~FkfDh zhgR>vri47ma7BlASL?~ry;vua+VQLu^u?YPNPMZV0MoJ5Nn5JZlDC3&yGaUI!8}_x zWCaWDCi&VL9GN11UAbRh&LMi$D*BB$&uAVlpWO^E-g#Os$>eREH!`Q;0=uHZvFT(<(ARkPNRD7q^}Kv_Rh7(E{ZgQc^$WEkvnddI?bv`PX2}p^VXc1p zXL4gyirP5gs*r`I&j?KO5;a7B6OWL*7OA&|ud?TJYM?&#ZV2_G+``&!p&^%RS(A!X zCy80)F56j1{udpYE1cbmB95SqlA+?~CFn~Tr3^+2!3w0fiT*R>AW0FrEbim+1k@i4)J$ef3Gr4%AZRW~z8Xs+d6c>gn}%{M3#-4M{k@qNxULy!r&^ zK)t%HxgqzR6~V?``H^uMsRd}0$`Yq!y1}lbwh2WN=BK`*u^dZhoc?#UcEmo)Z#$o8jBN)8q50)1A|73 zSgprv+`QXHOARj$Qj>BOSLBQ4NzW;I%4)^}-844{t9^4WHRBjIU5$;Em_+YYh0n-w za$#;_7)KXqWzlcx{$r+fr?5qyLZ%T*vC`KueJHx)e3Q)|_Zrb97ZI)yxmy-=5Jrl zrs~6ATU?%M?Xb3N+1FIHk-Gc@Z=*_5u%L3Bly5`5FW?D8Pr{J3e&<*>)*^sh~KS{-ITk{HD85{wNp<`vQ6nuQ0X+QLL3 zBZD!EGIULAtio3WCYh2KGs5YAM!&3?-ql?xSQfu!eu02rIcv(Vh&l24$&!_#%>ZI3NL+S?rHa=cHuVaS~$z(Z9t4Z*5Cl=X#D^mrT z$AxFqOvjRHd#2RLOsUik0vT4d_8_u1mOrxsmo858$)7N&=5$m(+iT;is~TxfJQ#ij zna5OWxSTp-$8vPAXQQ^WHvZxa`iUtQttY#|OHF((S`9+6It4~eh`(^z4gs39WlkFW zd>^MVR*u~PjV|y6c&=I7VC_W5bvhE&(-hXDmN;|ngy(i+|+sUF7SY%JlfC2 zv=p%&Df&ApvN;xz3y2wq7iaZDr)m6gU4^lH4_^fLx$(Px;*;_`7x0_QuP((^dTIDL zlo1Z4GdhG1<#DeFxQXm$y4#s1sZq6fA|;z3=q;TS1d(r*>^-6Qm~~D3GP#&bM4{2A zejKkh5yAmG$2`92i4(NeJJ^5+4#u!^D0T)c1Uyq1HKu8~bVkPfZdws*(C5z;eSydQzf2u~7 zvldEs7%flI=j5OHLv0xUGU){0yyOOB-B~=#q!U!;rm|n@Pd>s~i~zCs^x+^nW8N$w zBl%W)Xo(l^sXIjbkdHgwP^;HXxfwO3Ycb%{jncUFhLEW8uzQBTNIg|Xn>YGrgz%+S!dVcA>l>Vj~foy*W>>3TMT4m|635IQ4mogNOXuPyDEgZQVq z5H%2CS@Xhnj!D1=)0)htRfpSJj1XJBMP`}UifybhLLKQ1(RVN%W6z$Pzsy|^9iE)O z#?F~Eajc#c7eLRXS^GLKnh3i(zvCmskfs~;1i>dmG1CME6mlx#M0jL)mF)|CHC6WTR0X#Ql2|yuhgNA1#Q9xhi z4BRlC0 zNz)DvpHJJ%y2x`;OTsf_u9f zL+fgD?&Y>eW8YZ(b9M%e{t0Eg*^?KT zaeW}fX=|bSE=VHelr#tzTw-EKQ~w9C88pi#6wH0den=eD*q)GW%OP+0QQh|30@@A7 zgJKS(+eNoc+q>Wmy*~GT+N`o(vo_kJ!`3#@Rlz$3tuL?;B1&@*Zjiu9Oo%@{L5)ny zw?qnB+Szcio|z$QP$;lNV{ivHy)&&Q$!5l@;jTKOQxQZV#k?k+x}Mn^3cN#GRyPzx zU!od~w53USC1RyG<&4GSn9CY7yL{N7Sfe?ZpdGJZ#Z(H4`nbET`QGGEovXe=E|?$U z&NsHIsCkIO))P8kOBt5fa`UWa%MOQ~(QjKm3!PwQg0Ulg!tv%ox%!@pfULKjpyqV# z{%8)}n_+!26Yc^%;TSjY*I%#=?!rvBur*arx4uM&oWQy{8#J94vU#*V?AXgP#>4ot zUxrHGXc%mb4iSGENz$&4)&^ zjYZtq8G2|9ov5-B2Zk0;LDr;|0_v<+G;BXcF zI;+b1C}fRxw^yMGJ-j8@afGGx#!Ra?HLNOdpepc{(=91_BxH@yWGNJo3{}J5%XD!f zU6c_t#uVelMdtv=Ufo<%& zx*OY=BsoMVmcruj_*ksHpVNjNYo=sIpA~D=&yr$SF0k~gIs&D#AChH?(3`=Ck2@Ya znyooab{)(z(2sZQ$Uz{aM=bd-+F*Hv0`FE??|~&wRil~cRe_Bs7D%JOG50(@Zk2hx ziz7eG28GT@hHOlc`!Iz2&=Ar{i&6y_;u;whAIajtE?&jP3+08a&Lvr zcGh5{l$kqQufN?sTC&QZGN-P;91awi57r_A4IB?Jq}zF&*|9I%>K_aob(RZ@`9Z13 zSS-YdStWHyWqRod9dZ_PuA%2w>K+H+-!=-sfNym%#~gqUmL6{?adyDbp}Z12{JMAC#IiEqP`YxjOqgKa=}Q0Ux5p>thA=RWMEbFrSQ z=T5acZMG2{)E^~cL58Zn^uJQo>w9N&u0vH*4+aBYXfpYskV)OC3Esc~AuK{gpNOdn zAq~jA79@`|s1_U@O7Tref}z2{!@ncfHx`TiHZ~ODcuWqnL9J@vvNNdp418$_b?tQc z4S|!WUj$XMM{B-gW7wV9r%oZ8(@&7iPyT~!?m9s>OG5Va{~(*Y8aO8Z3$j_|-cS|z zCfM-}M03|nt0+}i75EaOSsf4eWiybH-#AqB^K5nwa)hjnTXvvpz<~NqWAV+hIrO8? zv1E3J&&aTN_5a3WV4q{ncQ#PrF|ae9=-s4Xem&MZ9mj_a-|ya--XI?;7sNy3-QY6% zca%+F>l3i0?Sx5lu$I{*J?MPp@ZRO{7!IpD^;_+Rt=TvmwFjVQ=ilY!N6O=z!om3I=tigA!{nUV|>BY41OPm zD1!~01#`I!bjUUtpAUP!R~<#fiCdqX*s z2QD26k7;p`f!r@Nv484Y?W<~Tzh_9SBPVv`YFJ8c=h<1|()DxRNDajftv_F*eRRl% zHQm)-sY?^|HO1{~!uEL18#m!etus8>u23jVzwr*?cnAwD?T%^ro8q8g=((;SuxPBC0knejREv>(HRe{#%Zl_-OhaPwIqOQt&++CIP zKv89pG{*HEuMyQ;q@Ny?q=&^3>se?l`YWHTP7I-BC+gUl#|1;zFxS|G zBu|{(kVo|>9xz2<=Lv(k#`*WSqA!pABkv?r3#{H4(#`loPe|GcHmAFC0q-O<$`Aj# zHSZx$jJ&4k@;tNKJ5I|d&9RqX0p|8~d#DXXubz@<;B?Cpy-N&!7GI^m&0>?3=6(Dm zm-Fr45k-HX_i}1+SI$m8{2w_6XW5mr$t3mQTLQ8%J9+nijQ%17PTYtWXBJwn`=4T3G&l`Ucvt{ z1W<#x{RBl$jzxO?$#dm#akNt8k%gHpxy`kH)CYVIn!9uuSY<>g{^lk^X;42sLfYoH6 z2ZN80F*uMjeldP#TVm*WB8kT+uyQ_T3l?X1Xrs&T1@@QB&W z621pU-)V{drN`&=)fT#y1(=J(J_AIkBZ8@K z_BmkfL~zA%Cf^1CYm+%b?%nP;OAi=}*YhQ?o}rOhuhA`33r%0_=wM^<5n!MVpoNg> zLjp(@Y&uvm1uJiBIGGpXak6y3u}Hja6ZDo5o>Ukn=J=vFNzjr3#<_}PY~V<^bW@E{ z{c0E^$4Clwma4={fm1XrO({XcS&tBjQDd1BoEQ$8k_kj6rjij(*8 ze5wtn=(`ARk-7XE8{2c=h0tU1-;`FlSE59>vUiarZhQ-h+cVoVQBe|dOjOOyqLxBo zf!x)MH@YC3;*|hxkSWiSUV`0l8_X|sofQ~@)w796@~orI!%6b(ZwsM31`5B4!IBJKZQwM zT6J82QY>CQP2{wi)Cx>YNLm-q0)^4>L2i9(7m~t+&Bh%r{xXJW3s`n`ZltK3d(rKE z1euEV!y_nuSl;FtMFc(2Fi4F>2=1eoNwtL{Q!Xmr+=vTUS7Z==1G6OqX6b1iOeJN& zwBb|`p6p-xgHy=zYNbepB*BKs#sBKOpq(QkgRgP?pLYz#KpZWk)s=Kk2+DJyuO^-l zh9%gYBRlyjL8wNvDjh8yFL2iz!Lr5eBpEGYlp1VI$ahzye^6hc zPX38Pkn6?555#(~tgQCW{RF`U##C5eYV6rcuU-cjC0o@fCeHy z=^0R%6jmYbZDDv^HQkGs@+1GqA|p!e6*bmk;h-`dycqzcgPXu$jjg}b#$S?tiW@H2 z#@XN0a08Qf^(mf1YV2RibFi%0kUU1qtpfg%#VdKqG$-vWz1nCQ3Lu0uBm~@}0tK2T zLFnVykPxZ3#ZS2!yBbUU>Y|jdrn_3Mrl-M<)a1HnM5du{7rs4Hc((>t7cS9-OQdjb z5nK0Ksa!@8B#~%kqeE*#pJctZ%oE^xQ*o-Q0B)v`lF^Q8-Hui8b8HY z{2b+ivHNCZp-`}{t&5J~)3k<*YwY_9)dS~o+sVFfikf&~W?7Cej1CHRkDo^EE=Q-8 z#OVRpdQ_vnd(ngPg@0t4rGLA|&vOU67s+-h{}@LBk-efGx85e*{^hCNX4D#?u&J%5 z%nt^@)J40i>*SaDBAlCEFEw^TI?jZVbs|a3q3V3q%4pyjIA0V<6)4G^%${nqW(3&+ znEifHev_G6XDl8mJt>=9Vk|ySBW0oA&5bs6#3ey{a)D~%V8$dZ(2KtX ze+)87F!4lP*pG@#qb22}m7GYc<0=|y6t5t!sjrdOc&ev~2FOQ9NIv+D<-e{|ENcBW z8)&AHwXVipJxdw1Sd*@vLaVdsH9*m8?S&@dFOUieLx5umS%z$)&HuynHse2s@kCqJ zSbjRlyqVUaGt$S@8&tu30h($*i#RgGSiVBH433IKa|Crt1u|>z5GEpI68&OJn0ixV zVM`)I(w)@y50X(%pr9x{I!C3x)4Ty+Zql~g6-u7ZQ}c!lwF_pBdo(SCDS4@I8F9Qp zL*5viUXMDgJ{hS3b>@j?BQQ^z%w2>LOmYLIfqS07ef^vgP6N>&fdF5Pd+}q`3;C0Y z7qlOJf**}$wVA4F(!Xq#bZfDsr$*``Wz|zyD3b12U8jafGLX&#au+p9RVkeyFxSKq zl9$YK0-_^ON=E*rM*VXglWu|BU(VdRK^#1|h?^aaJ3WyRSZzdmyCEizNkM{heqhW9 zR)`Cq7I7|@TAS(YSaRvfQR8S&R^`)*ii~oIxGh-d&he3!$$uS8W$!TkMF8s7WKxdG zWE7=-CgT7q7FyaOnc|5~ezXU~wh)`K8kA|^A{yZ9YQC~d2;o*XEwD=nJuzBDXu}F_ zv*n+UV?3QuyNr?Tn<%_bQ2Jv3r({JLkjHyAT=ncx2_Z$lq`mnN3x4lK^6gS@is@! zmU&bnPLTf3xe#{G43gQPE65F*lU>_~)o<`{7gPr0zOUIsGj>{fk3T=k{m5)_N_WVK>J4g5%0+sPAJ4HRe0)$M3r#|7j>9?{IQX@}ldOvbE z7^K7!A2dmPVK*MR1b_Z)h3;2VpF#Cd{#&~$mMj=RAkcIqU?Sx;V1dr8XiQ%c&Cxd; z5T2#mD_ZBJ@hgye%Zx9Q99>keVNw76!;^r-vB1|YYnQyjRO^W<-Oz4KqQ6WU;_#eiuR%>$y9T!rN~&V8$xVyXBg}rES%+Scl!IXF;St z76@0wRB^eR;Oe#722E}J8Q-{^fPR*3>;Gf#-NU1*&c*+k$qbo5U_6cpfr)uf6W;UGI8t>wTjONkx$fuGN3D z^D%6P2QlKna3c}reV^32{=yz<=EVHa260WAZ za_G6~Y_6?S>V3^4Q?8tCW|=(Z)$C6)P>v&SvOO>_X_k#8bu3W>iuldpH%C3Pm>$o= z98;!)gBm+MRrU|D+Fk09fB@i6g4?!LUw%QbTfNf4hj|Q7&#G|O&ZzTC1eGffnLOZrl<#U31EQ52eD4NqWk`kjdpVNIO?PhMc^*iX zGmB*Tk>tQUjIqFp839evOEeCdEpr`;a#7*s)O_XuiUVgK4y3I!R;`!7yJ>vfogRS3 zBsUNqID35{Z6ga(nw;USZK6C^vxQaeNX{rA#9H+ma#r=shWPTjB}--uxBD~Yp=Xl$ zrB5P9Nr;CtzQd0lRE52H^LVI;=<(>#@_!;zdBmN&M$9Q_i+DRSR%9+mUMgqlfrql9 za-bEH>oQIuCJ(5T-%Nl`et}Z%8t54T$pk0pyClT{Z|FQoWlAv(WnMj`P#@kHlK6&t zZW!EMm7sD$U*MvObOzmS~6=T#@jU?qLG zMfift=Cx_NG(iS%%b0n$p}Z9&;8lr!ZYGC)(COM499N%G+q5`6_OiXJkK$g|*|f1c zU_`n5%60xE2Bm{pMxi0CgX~jn(=7ppPFiws1rsbH$R_HL2Trdaop}=J;02LH4#ph% z=TL7EWJmZWO!bnPj$n2V`m=kYCei~tkWz4; z^=RAFna;%7v{}*ca_-rbCczQi$ZW{Te%5^Qa@zTHki+Qw&+O!@a%B+4ikn$P>%7=j zawkMpPD40nx@MSmG^daT1xR!xzJf90LhD;%f8dMCUt?8;o2}nuL^t`I8+^_!fk|SH z5!%1{*Zll9UuBe`{egymhrlm7^(i$?}KI@$jv!CUn+YkFSuLB2Ko=0 za|9Pk(ffF`i`KuUXG%vIlrNG=f5DnpiCZoSv!i)Xy`N?In|J4&XK&>7r)}Ic?4DL_ zDR2Hfoef-m_Inj+O181T&TatT{;LaUzjup@18?Mzxf{dXsXpVE0OpdpL<%aaJs8X( zj*<3&EsnwM$LQ^PbXBYY`-q5I|H#ePqZuSQn`BB-WA$O3>+QIf*(n zk%qxuqy**&`DL7w8HGTpgK$Ao&Ji3bhh&a4Dd{9P1Ga43+N_j1@C_ zzR!iYeUPN-Mr||AFCW75B{ucW)1|@768Yrh@s8k9{w@wK;%|kqVlb(YC9~9~L3B)z zvpBFlSNC%2ti(^LOP`b%(4uN!AhM70dwaB(&+`17hK(HZI1(Fs(s;AJkdLK2d?pVW zJZvY1Pfod5Vi*`sRFJo<;T1V^%kY4LyIt7>4NIMB-U2SA=mTEg)^q2o@4Y5xDd^OB zS71t;yNF|}9mc?@jnk^2#H>a!#uIAW4{2ns_2suAqHu2Wr+vBDO|J*W+-!VM)V<Y4?tn)~a_nC34E`E9Y;+6-?JFQ3d{0k-M!dp1 zFmt~eD3ZdZeUz6zLpIDx$i4mOXkBKT`cJ!rQG2yME4Vp2-!9NsZM#<&n5*Sn`c~3( zJ|#>9x70jWP2%n3n*6jU^C=QTUG?`<Y=`ANl2y{w__QoM%(wUyy2f@?CZGZ!U+mi;7}b+q3nTJES7+T5>d|3+RFnXEAv!#?-mJ zi6S$fYbSD?kI$5^L=ph_$7vD>T1!LF^zX}vcXDvpr{zSOIFLv_9$%X~SB@Pa83;J# zz(v1=Ith6r#9rBzRs}JG0KQ>Kj+#I%mPCeC<6e=eqRBxSJyRu=me3YXov<`RbsO?! zX_o5X0p$!gUV-`3wB(x9ZofjuLBTI#qeKV+|9=R$_TqkNY6EN_YWA2jB^A_Npk{A`yNFcDZL|V0g-nk< zWkaWr4>8&I>K54_m`9(!vO2Jgx}GC6CTDoSjH>`I%wECO2BBunsj!#Zc`f=K0fqSW z-rrv$&`vG=1(9fN1t_}~RjlB6dAd1H$SNk6i?NsX(oV-kIJFD(f9Vmd7hp;%a=Rso zGjt=z`wf_>t-1=S?AP^IIsNsQl$l$6&Aa=QneUesuIJO+brrc?q#*9cAK>~jW7P(E zlgGO@pDi|We)9w3E=~r2n;%|1CKto!J=h~wrL#3%wQQR_$=A-25V;kBs7P@Bi3Wb5u9fM;Z#fS9aM&p>_2#mdmC)L(#I! zmbgNzrMN_*%eM$TYca~rvNxoLhSy(}%1bIQ z-cbMgtGv8m@^nL5a6x%;eFbqh^AGuIzLg;_8tY5GokV%s22FTBS~2xci#pzYhs z!|}8V6eYXvA40oQu%~SbEgWQx@zwYB74-}4DNn{3vGq?X4WBrBk(b)S8*+%^eCX^7 zb4Qy4$C*7%g-@g{e2g?Kpu>mKe6&d~y*^s?*JWXQNjEDRZf3G;4(Vrehp%lalfAdJ z?jrmo=piz`K4o>&oxZx1@`kA{=^#!KD$Fg3PlVRQYL_kCZ4z~c?Qrug75N)ahOU#X zLU1>H*BuET>rbpt0u(MBi~HukKxX;GZpHZpqRyDt92n@t+XdSlJQ^X$57{iO`XZ_+UKjc@xejrL%h~1{*oGg`KzMD6 z9 zu`0E~1aWOD8MyF9f5WVfiiR7VKF&M8`HAu9gDBSg#XF3L3^(W~xxtr=`-+bkj~pP~ zXT}RV>*ribu!VQ(vM)q>NwI;UgAI!hAy|aexU9mtEg?){xp@?#qOy3c5q?w(8mlg> zY?$o~pD>I^o}?$j56$KSCW!uq8&U%K?Q#L&k>Bg2c9Pr``8#!z^v72}krOzjw64fk zzr=~a+F9PPB&DqWW|zNimJ8p9_1URqb=fXN9K~(m#trlgQ>Y6A&Msrsr4jQH%cMgmO6wQ8I7pM$-0+E!#v^Gor3X8k2Sz`U_9`1@I0Ic<|4U1vuF@?@ zPzSNel$KDS|B_d`C2H0!(9(jWum1iM;e9EkwVkELszdlagk6F#tw02te;8jzkKC-Q zX@WcDWGikr9=U{svijk~B?;giu^dIJzYecaPwVNp&B+v17H>Bm{#^HYvhna`(2vqt zD7-VxuI3IGcHZIrse!I-zUDnCmGgGU+L%Wg7UDjlJs|7WMNy2`jE4_Noe+D;cpx9R z*^xK`FogGw3>B2oMC~hlmf1if5$addCMO=GfwiaRgp*Mij|dyz5WIXOiL7~PQ-=$> za~ma=IGgwP@jJKCExk@%+i2QaLhttXtJ&`;l}1v{V?E6T{twOM+0CT>ADeORgcJ|t zAH&Bftd&u_fer_1I;1^r{umGGBU{GZ$p`!+Hr(ne&yUOYd1N~&{(6Khw*jPCrS;35 zkVmqR&cdeB`jQl1U5P|l7kF)$24C(^K`^M7a%-Z1-?DnP%kdOe%*BdP$F0~$RPup0 zK>s@K_f3O}yTO$xBC&T;Gfqw_^BtUO?YC!kQ87bhVvR&ZWJviNP3LOtq>|Qj{an~o ziR<6VY*)Es@EyKLEl87%_y)&PPG_c6(mLy3)6jT}xJZA8Lr;pAftlBv$7jT@VeB|g zg_p}v)wjXNz|f_ecV@IXTv|6P!tb~$`n^joxu(ybG%^zED@={Br`FZ;C*ed^zYB+J zO`bpL_@!K%l{$0)7qg=+rH?xLJ7^}ZYX5lFZ0we#w6L9ou7O2Qk3DB|T~FVrc`Zci z+lAed{uMUOpljk*=eXLrT>?}so^I*C)euS`LC6>RlGYWf$w-_K%M8=QQm@{M z%m)9s?WJB}jV;1t?8DzLwI?KOgB>9!z6QwxBAg>HNs}lJCG-R#O&#cj&0{D`(fu)= z0eUu6mgv1i^PgrAYHdKV3J!|Bp$Fg-^Q=1=gq6~k;(}|WHCqGOBN2yL6D?~NqY)3w zbbNM2WD!0z#}2J1Ru$&GIcO*Isz$1(!E?wZvJepF(KSb`)t;eeuA}nF;#*q1aSPo* zu2|tbtbKQ&E5PwDa-BTHSa}X>L}YoU+KWtz-GC2{>ps&ed=-Ly4nKf>C&7|F76AQ5f6R4JW#66G>}WWO0U8 z{wtBmgBsLjd}Hm=g_y@RpwL^d3NsQ7?2Q5|c8PpS%%aH6wqCA$yrXW0NMC!gg=q`_B=3>AJEbUCfBHfiIl9$1Rg^c~ULofBc z*C3cWXk8{!FiZib=7`qF8e>Gc+Lxg_Wp`;WfJ9201QOe)Cj1sT%8DlRLczb2s{S^V zrJ}=LI?NUEURzC(mXuyULstVM-qZ2pXONiyN9U@CJ`fS;h*1C87=D-?%pT$;N9;oz zj3aby76^!1uz(7BaT=UR0w7uf)+p8tvH>NU2-_}Ay(N7DT+*WZD6d|qU=D$$zOh5{ zdix9kg{cA5UOUx7&I%Ey$>x*g)jQ30IydoxkOz&G)fsi{7P;$Ab&Fk5uumWyPq99Y zCaF%+zZAiZH0cHx0yD|lY@q+eb=8Z`@2rB7iOV{WM<|4?C5n`bE>oN9q|!&d*# zKw%8x2#&Yl4Nw=$>PdKdc=xlKF{c-&@uIi%~geqg>sZ;IPpcf!G zsJf_7Pj9G%ypG@mYeJ)Bp#9i1evvpIXES3Tb6_c?3Upz7CdY+-6gT&Wl2|Gu1=kBBrXXP=l|0@=a33yo9q_if31jjV zg2G8i#89-On|s*q#-3}tliG-+v4kONxo7x5sSYh>ub^8E5x@v{ml!L8ED#zwci+%x z(QN1y_B3jH3-;`L9fSy7;#LQK%_JnJ2Jm+)5MO_XR$)rNaC{PG~G|o*b+@Sk#-IvgOqBd<_{B2LvFWw1<$x5Tv%TS}$s= zY9uCzq>Zx8SfvH@H0mJxT9R{4Padnb_9SOEiqVtq56D@?dXn8{Q%@L{vLZEW7EX{} zr)8v{U@DP*tL^;+e0CzOCXAI<`Hr!L*n#kyE2$CN-9SV?CG{N_fV>0$VOp+jJ6>G; zBpr){ur03&5LrRA9904JL-sEYhg@iZ!!4y6UCJ)&QfIvYtW1`^vLZlLyUK_WMm?@R zKbxOVd4KjC7e)0^;EnmWS2|P%K_gklKDa&R=ErO*iY(K?x<>}W%Q74s9#y3TqCHuw zdJ8)#Gj6#Gcc@3HHZbplHLDqS)O!Py*{()FZAc3}B2S6v9A4&?dd5(Xx|t#@6mn1y$^s@znLT>B|ZraWupfW356^0ZSnf z>TpzA*ilR2ztppb>`b`+(jG7)|%thG#FZC z{hD2oH6PtIkfC195fn8ux9^&xQfG=izDZzv36a=0_KMOtIf3UF(7K$JvIvAGEhjFO zAUi4SRaL0dR%V!Sbn9}^h4&b$uh0`7bu|qT2ALz3Amvd%eO_}7MVZ9yg1^~G(LTI$ zMqGd)UUUf0!SkR}qUXuenaH%F#quE-s1&6jj~N^7LrN*NN5f)t6sAnU4ZYDwf@l*o2PoLMLD4#uB*1S$4+W(v1hp3igIScb1u7`f6Gnus@n9 z#V&c|!aHg%zyI|s9}Zm-UgmZ{DL!rYbwQ<^ZJpE7osp}!C^4Ul_*Z56BMYxK)FA72bI$_bxvUaH5LSapyZA@i8% zx)9?P-~!%PZI$x|RYq31*@QyALTs1BCMi?Aub3Okir-xZdf3J-6JL^RFcrA9u>^Pu z)(qPVgx;^AzN06)0^I_T3usM@F($~bA9JZ9ae`CgH?dw+_uVW8GGrvcf;#$jSCZg+ zwGXoSaGaML$o~khzH(ADlsqA&)wgmsLD971j>}j4wejdNQp@M9L$}H)iK8Rq(cPrL z<%Z5RR!xPi9qdES%t`FRpa4f{95F_1j4X*i@&`X`Txnoe6CBlH)JoEPVwFJyBNC)bBITYc#7@{=E>+DV z(Z$jRrcmJn1!DDw>pd|RqmisD2r#JT(J~fF^E~cf5ViX9(c0Bw7c<{3=;SYTZs4Jmpo)+oeR< zFbO{s4)8|JclDnT# z!c~7g15zQWDR-C%mPDof!sUqmf&Nus)b=%}xlOVEnH2T6DIF&>q5E!qcA{t)rjK_CoJv`4UR^fyiE_2k zYx&j=q(I|2AV`S(v{O~uIlROS$y%`kkC;7`bx)DX*kD9C-J|RGnFp2eI(l#+XjS2> zvcl^3UYm2z(gyHq{8e@r`W7Zn5k6|#^_*bg&)vZ^^Ha*)m<7CtOL9R&m8@X5>H=EC zXK8mOq8&RLpo&ow&uk=z`a918HZy^F_N*&dNWi(y@cT*ix9Nn}Ch`t36rif8``9qX zc{)`|TDzuFTTX{$!EZJZHvs!awpe!TkUfbvzMA5=DLR*%FHpZ6Ha~k-CTezEze%x1 zp+1G}*~e4>dJc7>kJ~XLD#^W>t`Q6*)8tTVKgXnidCb%q)?mNtIP!;RaCm@uY{IMw zyM$`iG<XW6j-v(`BxfGWk;GRmw=F^k^o)tSctl%stTi_E>ZhNcxAgCf>i(Wi|)I#!{G! zWv@^?+;R;PA|X>L^=g4pi40l zthrI@+Z-K1Cm<`H%G5WR!2W*0-&AFNrv zi>26XM*}MY{4ie1@HbRf=YRPnw@|4}8{eS7}AVJa=@XF0H1IkliTP53ZwP4P|T?-jDo2 zHqNuVMVPZ+E#ma*^z537d?HvG{U>E(d+iG5{#jszRR?Qppsq?2(G9l_f59vMs|0Vx z2JC~w_|p7J6_OoZdVt%gt>U}YqB#&Yz3?DJE>km@%}7eLh1%I&Fdok6YMzDha7Cl? z1mlqs{q0MD$~s;(<8e0Cvl9P&8K!^8M0%;Y49$8JCd0d3>NrPg^od}pBX-r-j#TwE zQNyB_QK)wmPgAmbl9!U)^})Www%L)(IB!*uP1UE!o?$GFV#UoeG=RR~D9eiX84Zt+ z)ai*&8SQYFH7s-DZZH$RXQc(UH_9)OpVq2^ZHp7_FTDb4#*YxW^NcBHjgUPy5h4bbx1w;Mk`TXZ|gBYLIC1$zMYB+b_gIY%_a z_3-1F(djFx@gnXO1sY~}S2Qu-AF+RAXR+hnD}cM+f0@+UjtoLQ^PPyBm%uNy3e=x( zTgYu!VM!-S*%{^LLF}Y5%JW;NHmCa~#K4eA`9J%-_2rs;_O2U9_>XQ>B=%bCd8IpthAJ0EQ2yg>S%&XvpV4+mY% zTZgwZo@%0#>SWczy9(H$nNE8ruu${4F4Nk# zJTh7R>P3Buf*OpvpOcZpIbGkj*63RO2qcS~dr5FP4p`q3Y#H!;D}M#IumLi0;kT;H z5j@w2*#E2~?Z*~rV8QZCBcM#x=fxC_d$jl?zNS_lZuiO@7%QfchVN$UR^rNV&vH()UL)YOw!bfBl z#>y7vw?KZOI^;Midb<_o(O<5t1llH?1)`3{%YCAcS3~*%#@qKLWomD z!*Y!7$by%fTZDo@Pb})E-HOy08GJmHBZBNvOEiAK z3qUe5Evx5F%X3hM8>}+uXA0ccpy{{EBcAUrAMIG_3iVs*4(9tNLfiz;f!fKM1z>$7 z7kudz7Hb^Gv88&!)U7L19JUw!!G$|IJ#SLpi#G-;eU6PWyH`J=iC{V|0}$lQsCkJd2DD*_5x!N|qq=?yH*ntz-f;3C`GmEs&^J+5`tpgMtHpW#2C z*C9O75!y7n*K@1pt%zI+b0wOl$Z#YY1da=(L~hNF-02PG%GVg z2nD*-oy91QxFFNRkLsCg+(i+YJIILW2YMQW*~?PH^;8VGcBCwuX5h{^hug;uV?PL` zNs#jI!B(f~^aszY5ab|My5@d>+io5xG(QTjcdwjllzk*mu9Z1Fp}bSO#WXtH3Y20i z3_2UJCjVSLjpgPprV;JYyAR7OmKpxft*vre`+I{`(#$gN3>!(V93$|2M12gmqAiC5 z4NEdYgJBie!6+~tp9uGa(sifW-3R`Kqr6Z@u4hX0h;6|tAfv8B<4!)9zUT|*>djIQ ztpmQh?kv_Bj+V7vearLIhZhdR->nY+K`*n}V$?m#dK7}k;FvJ+&}fS7rEY*mUeUB{ zL}1=V0`ygwUk038^ha~8noV=WBC_6-j9-4oNe}#RET3J5hfnh;zFEa}st-y9Nf!vM zY3fCp5Btn*7Dogw#ZIg)+0PkU$e*sQ@P~mFZ%e1x;^#wIT7B#V2ng(Xg>ziU=zF2j zSWyVRvXtKMdb4*%M$DZEfTdRNafV8*i*QUav@`AsT`ceC#nKp_y5t4wJ)<-34vp-L zI}z&W)ErW)_qePN(IJTjX)5ocoX|6U@+3JT)Ty7o(psLnkn0i5>(Ol4KP7OCV_Rte zO5l0YBM*+jnF5Fdybag6P}1754(A_&Dvjec#7V-69m}{BDh%L&-Cg>!?I1#`NFJ}n z2SR;xekSQ%>S#J^g(TXY8{AM4$;}m`f9|88c0+qoxETi|#^Y-n#$JPT@B*-!&}GjY zk@M4xFE&bz$FT+JC^c4fCfh7eAr2t+Yo&p{&Wli#xOrDbviAzMIa~XySN|zu0f25H z?Oz#raBqfMOb;LzS-$^58~~J!6-h-TqcQg+F>vXEy z2as%3A2iARCb_R)H-WkX4X@=sMt;HWeVXNyQI}1+(YR+o)fv9dHdkoyN>|Vjbf2p< zx_|sqB!7*2GOE&6x?)A71+Owc@|)j;*LyqL>C8uIt>MoJyZ1KL0y4ymuiobhg2{~9 zH%T%-;l4+y5QNgtgf{)`NeccrcDLO|0d15=CSYFPp{5qfK8Fr!Q@?>I*N^S$Wl_VS zm(*fI($wo$%a#m%U(U#5JG&@OY*E3Am7J$u^>@q3=hY0&VFXkqc+(r42zXSQ->G-W zE+e}CCsIh=LxVI7_omt*#Aw+1Tcvr(`ZIq}*uJ1quv{phvR>5gyHx^Ir;h3K-$DO! z1_kslmdmr;pskS5plfj@rE&?M!onUn10=S2&>w;{`&Lf+R>2e zAERM3VjJz*8FUH!`|D|(2xo?Oi8dlVIyV7E_?FKW_gRjog}nM?J7^8Hzl`QH_~An? z4OAC7LT3t%F)MoiNeTIglI$3zcZx2nT}{z=FNo3g z0xkNQE2y}S57yrr2|?|Pfn1gcGu3b#KN^0F&lV@kicbW0aLhwey5X(W>o3cGXf?MZ zOOi9zFP8LSrGP6`4GA6;?d0{FXFK1!(-a0lm1#o~3PjxLNq4fvcxXrY-|E$x`onPkz7C zsCDsO1Kc4s>`N>HKupNz=5?!Xyt4ZvlSW+v9s{$8?em?!&UQ{45K!=n3ZfX78nwRx zLMrE7E^%lxmT}qCojawvgbB@*n@qEGA;L+N6sau`nW!6_B8wjrt#BRR9CneH$<7s7DXzyxRXs1=G9%iZkZLpXg^@oUP2Dcq$B<<5&}2V z_{n)BSnol#4)v>pdfkKP3QEn93E;P==Qo4Nm#`jr@{Zwp_5KWF z#fLoGDEB71n^@0l@toW|BfN?yCIA{q7Bf;HlYqmM2XpUqght74jw3W#MvL2{wn(X) z>yFD7K%Aq(mOQ}+tT+6{5a>%k5N41|7Nn~E%(oEmQdy4mSDhi$STT>OtVk)z^@;h< zOO!7nLM%foQ9pZ@gEVq+*T+!qB;=^T<4kH>>MUw0vZ{O9s^i|~in)wVBXIi;$&I>X zNiG>PRcr_IB6Fo)=P9vIcsgFQRM!b7?mn0lP0edEQ-o&37$6Hd#;X2F&UK`ajd@>y z(R(E5380zd09-DDQKrb2pXV@V_MQ8@Yw+YxGQN&0#P3tH`Yk7!7FB*QWVEBSvz03h z6XLUGqqq7Km8q6jT#}j-%+bzJgwoHBrPHLUh9nZ?-ul1*Wu7BKzW1!1==JpZo){5UfXTUhmRd*PUda&)u(6T z9wEQ_+wq~heDxKX&W8IomR6rgTXc)Oxq9EO_EkTanc@gt5msK*nTy;jopOTgi*-Rl zAzNvtZpa-@43GZ+`_u08BI_SD+>%A=EX3wCn*=Rq1I^FXj=l z3rgjejUh~<^sz{tdx)Z(E>ITqR*ysdgtNh}*c1v>x>`NCG$;@~0M_YRCm(Uh}KEX51U6{ZpVitu2K}n|C>_S7x7N6!dv4 zEq);0Tg?-;?1MG~=6mWMk)>1fU=f`jirpex=QA9~z3Q~i#l}u{h$m<4XorNzTo-aP}GG@sx>@gmyUkbBakvJJhulL^&H6<9U&9i&MV} z80R-xL(ndxPYrDPB9OLLlGc7@%#uczlIbhsR?mBHff0!%t@E#!{2TEg9oVD-X&WW~ zI`Y3wMt(Dfc-Occ^NsQAt0ec>Z>^zU8FSVLR?|!QSFIBRh3!3k{mK}~d8ZOEixlQj zxHY;;m!dDz@0)MIDZtYR0VMrjSc5eKsP6h16%F@z-xBp43Vr#jFW7@CxARrD9_zJD zOU3c|DVv_V2(O2f?_|Ae;d?#}QKrohr1$&qg9esChU+C#Z(cKr!1w^8;l|CZYb^)Te!&#Dcq6pP!C)PWnFv#mj%$*!9l=Gxc`nkjyrXme8FxA zvmHnDNI`%L=sv`u+qKpgA6iJ=Um_z&JU9r+|MZK*kOA8CQq&Ygc?A6yXjUDBObGQJ zOdmj>mJ{_+rQq3N5zhjuVAqHcva@ENz+Sk`r%uqeUUTZ(PsM^>ZtC<*A+wW!#l|b2 z^axQuRizyw+Im1Mxl47b>i)5onbqA#ZBRS2v_x#2qtxN}ljBu!BQ=W;b{C5(MVi22 zlE?9lRSHiz@^o!N_~A~^#?hl4Ia>Us#s7$MKSrN`8+uiISRX|Xyes+z_?tt@LjES` zOsmHW65T*v@Gk-4r00cpSbw040+&E)JXfZ=avGwQBty|c1d49nD~aA{|o z6YHY&Kpbq$pnL{QFc)AGQ>VbDZv(~6M(rKcL~IFvnZt_`9b=lLr;0W@*TRd6T``x8 z$(;XTh124Yt1$N*c`-3n(lOEj&3pk)&|YNWQ#MX-$Q*!^S~NV(VxyBE7XzJjh}vaC zA*1LrR%Ggq%eiP07MTO9OZ|jP0JTk_-H!XuxObSYk!8Ke?S;)(Gr; zx2}-_f$(~J$I09b6`K_^9;*@5d_NZ&FuMX+SIhPk@}uzW)id}M-dBn&qnVTs{pOe9 z&m^Q=7IzwGBoB-uw-I)3`hqh~T?2z1`x!-SRqPMo>@CmgTS%Z_;{yHL8UD-_dxl49 z$zF4ZWH$T=bKQ+13&g-GFB-BFAtcrUel0&^3(fOf(pPjLw~H=>5r@u*UOM<{M{H$` zuD7=`julN{=-?p8?1MyI6K_Uhtu@vv(|M@pymPygXxIrwOYjWLYl0FAu@r{qeK9Em zBw>71=OTfP;9Z)&?2+s~OF^v3gHwbk__R&86>R*N8Tmm|qJ0 zy@hemVox=-)v+o7&g-3N5PvCe6ksBffA?W!tw(kpWUL=)fErMXIszYAVy#18D}2V| z?ReT=cxD+c+J@@o6RCI?^)TK2A47Yh-2ll)pBX2FUaAFzOE3Y|Za=$*A%i z!JBNHEN!VjgyqE5ZE$Y?d;Lkf{y$R%^~OUi{~q;A#W4R&sVL+AJOB_i zWaDXTfjh`(e;WfAOa`4>JtDa>PUiCITs_q+kZR_WL9m7wu@Md#+G0cOhKG?eq1|TJ zw8*|j{(l+{5DBmt8~^nI*?8^hhBxis#mv>L#8KQm3YHK89>QHqCxNo)B)kU{6`7KQ3wI|?#lPwa4vuqc;BqNn`rQz;Y=;NjQzxbN>gj61PEkBxs`ze(O zl{Q6;3}nm1Lmu8ONcVR28pMSbzqF}r%;aQ?usuHF%NN3YL2XR8NBI+aO2&Zc&Q%9t zrsQBX+r`eQPgRP88xLt(Bpk}&6DF2?9xIaZC>){u-bXu7B53Z8_74pdI2ag70pa0J zCUn3Wi)$EXXn6Q&-w^lm55@Y^WxQRatHaRaRF_VoxlQfn&5Dap$f;7p9!(59FhDmP zIgsK|>&irf*P-6lUl#9^FN{GQ7N6B3c=W#ma6oL9$ZuGjVB-s=6`GnyTrC<#l>4L-m^z92K5)1}Ut&JC{i{JsG?q8!Yyu z@(@fd+>yut1F##h)|iu9dYV%3;)rJ_>Xc&77XB_9Edps;`AD}IdNe%gEs~wOP^fRa z=Vjj5>&rVm&F27Lp^<`vGMo#Cp=45wvR1P_>6yZJwVz35jRMYivVWl@y!y6i5%#Ovr|l-2 zt;{!_Fio}ldq3CdsE3a zZ1=3Bm@wFCkzB6;>-Qt^7m^4@FKlXb+=89`OpOFO+C2~PL1svOdemua=buj*ErRV8gO`Zkyy``WXUJ=YF3jR{ z^Mtca*5n}lF73X%kwbaXcPMpG4z+s@^C18Hk#PwgK^7?TU0tL=r_l$ z=d%Xy&?j`!Th%}M;w)R_Bo6eARg?Ze2K73!dyR)yIc-#=^>?D}#uytVTN6SJxt<=J|t(4MLbI2mn?N5Dm z-}ve_Sg%nmOJu~tSr}?G(mx?z8s?-pE!D6@?(ZH~YsEjj+zMgaq3}fX7DPagK%IpS zZI$gCx32aVcOz^`#_L4zywzC6J*69*fa`v1Lj5#n$-Ln7l7di1{WPqp+gxE)P?Acx zf~|6_fsEmKRk5G-2eS~*rO8@#5(fmmZ7Dg_YlX{DXZLAK!F@$sy+PC}kYcZaM@9bb zc0K#*5v|AAuMW0#CDqT!6%k5eAa+Av{Sm=`#~I!B{X3gCKWVTc5P78WAq{3bIii{6 z=yURh5Qx?8A#K&S@EPbX3Y>!9vp)zBK_2WgsQR*T7&8CZi9#{Fjyo-JFTy{M3JP1y z4#p}KsU5%SP4VmqChwHJwAZ#;7$XG6g_?7hE&8=gC|wqbg4#en_?E4)7i^TjpYF@7 z_es!?$cT(A`T@7bEu4w6fc?~KCMO2%TL+HDP2V#tt&S0@ivd&=_Zjet2`;$7NRkEE{qGQ>`zqX&1k zhepZ!$NNROX4GD;dr8-iv$!%O!6gaNlT~Qf^-b0<=uzS3t|Mqyn}fM#X0BEx1N7OD zycz1fM>tV=0QR#9KD*mzZmvXm^dP1^h9ek4jjpLWf=$M5d_)s&mog0LnzyHG-->yR zOj^59`#m8R&1Qlt6gz?+m75!U_4r>R+}iq*oREi+TZg7JOc+#>W=_a8R(zk_=HbH4 z7E=wDfDPISNYQf=JQh2ls0+sy0pif6!bf~{0vek&Ii zzS2{vqO!x0WEa3?38SyC1xYS(>`Y7%9sHEzm>^)_0mskSEqvrY3!HuNiO1RPrRihQnAHVstz?zo?@rLm|ZhHnXP*wzT-s3He$NGViyw} zVvUSF&7jrb4BY6UF>49#vc4bNS*_>cZ)~C1V}D0L*Kn6t<=9<1KVXjQM|oAod+g=+ zg<*@U6#FB-P(23+)8B-+;nZK10!BFWU!>dze3Bb41$3#MXJIG;4RS4g$ZB3g=#LkR z=_gU2s1Ii-a5WvSg7X!+U(xTys?Z``_`4DQfvs>S{)pN?=BN61`@-*R{*)|5uJZln=$ z6WU3#q*O%iWCU?_d=noC9#PzieO^0;S9P)azIlw-MAC z*&^r%ULn-3#~_gH>0>WId$^Kn5g!Gk3GfJ^DT6&r|009pcQ&weY9r6E4SNC6oif6A?BzhzsG4}xAS%_$E}o%&CvddwO)*kyRd4cL zERI4su~l49)x*{A8L<;z(C9Ng--DL{X<^;0KCgtUV-(WbXS!ioe03eUWlUG{D@f3f zLlNs2Secz_T>ve%Wcbw@iYM8%w}vue+VEps&%17Ih;FT%{3e1s-^-)4 z_OaaowH1k@_4}SFw8tuVKK66HXIj!2&Hdu}XhXd%z@UarWiI5h*j$4z%#~!d>ejB$g z3?G{m^n{Q7*iLyoZsmlJ-DH$oO{(yPTU=dnKX@zn56{CSV6}#@xnb(|&UmRj zgsa&Po$X$peZ}vZ+wX4=pn6|uz~IMjyh$G!uP#YJ+3B03wN{CB!@H9+Ah0Hn(PzEb z8FnI$QSXbMpZ)26OuTQ%J^DQkN%=JPrhNkc2h}hwH`|H>xoa<|B6KYp;$c|2sqwg8 zhPq{BK~81hW~X|szqaWD13=U;mH)8c`3i>!_$T86!(zE^ZItovT-}wlUI{eZ3KpFx z{E@n!5>oO?@@T8keTawzO=)T|9`Tfd0pK=*ZY-4IV()J9ZtzHgMb z%X5F&h<#X9@>p#=v9`fI4EX3j52dpCm6k~-Rxd>K)FV^`o~0k!aJxveVMiVY%pxhm z^-X}C59QZ$oeAEd`slb&pX$XfM{q>=ivqb5Ys8xEIeSbqf+?ESYZ0As9>a{b*&o+x z?huZw5ggFtGG^UUcrt{_NGI?AYSe$>$^-+7U<0uQ4h)15YZvLL%sPjNQCrN(in%W~ zaY7?{)jkG4I=%gFo5a-vjNH2;XBs1P)kw$#vZ_Ax{oIc*StS&#q z-IYZgR6CUfFtwiNz{TLXOV#owMqKD$sytTOxUBvPrwDM;78NAl5i=zm z_o3*aSK3Havh*Rz_qsDW_r(f_x>?KF;TbJ_*`CZMke?xX11pnoF2S+O&Ixzl7rZFk zy)cxI1y|!CU>R)%Gy9*_#e z^o-tROKxBEU6PYcYy%`RD5r=l0ck0=eoX1_7M{LIBwAHqqUZas!^@@y+Eau%MYhvl z97u~_4YizIBa*Ye6~JUh;x^e-wR?lhH46rCsab=x8GsE(4r>ryH^P!-uMu{;!QB>!fYD$m zd-Qlks_CxYZp^Xk(c0bMIGq98M7p8M{|+(BWFwOTfr-H=Q|z+)CLQ}V!6hRlZCKMf z)d=$X&2Df*RtT+imr5sr@SYkQ%|aZ&Oo1l5`vwOyrJ(_!_7JmO2@|x#LhP}@I;aL@ zf{=89oUM9`X2=>&OVwfPAfZ6E8chMs==HdQ$>Fk@TKJ#n zr<|9gM3pPAzYB``=*_|1nlaoGz$1rnhMz4YEbe zlm|wrecYiD_xzA8hggX_`C_I-Qo1%acaOBAH;H>TE;>n-n*mv*K{GDW$8bIkcY1z` zX4XYyIV?Q}a76d`H}B84h$qN5Fj61xA`P%|L}GYmtg8t2xv!QU>WVm!8N?^R44!!~ z5~Gf9WJ8Qg>yenAj3K2_f>)JdwV=%a+RUA^xCt?vZOGXMldhdQsiJ@TewpCcQ)i$a zOCEGol}E&TcZ5dhYbanry5ZR4bcELpf<-kwZ=|u)2Sp1H2`wfc_w3ekNpRyz3)~oS zr)*-tzsBjng`Xb>YmqxMjoM|heawSkek)gXy~{}qm6+t0pTqjKP1U}~&RnsV z3n~Qo>}<&h`4Vo5MKfs?P!hLG(R6u^gF(egJ1s5--bQo~iE?5HpP7cc%7f7}NC^$I zMq;1Sp)5i6#RtWCPV{d`ctr8GO=s0U4AdP1dO%Xdu$)qBF&{A71^JW$D(Y{V?Rp?D zFpo0~iC>_3pG#f$-?#>nq~uq@0si8S;7IzJ8Dr3O_rO4Cv4 zd`PPzt`V3s`ul-b!o0qLrL;#)e22{#uLc)pNZ2EYu;^dq^H1#0b?X5;=o@qUd7^>p zif8bb1aD|s@;woh%?-?J1);W!D9Ki71Wd8({^JdTDj0~CG%U^nZ7x2g`m=?ZQV-M& zcYA&+NK`HPrYqSQ$B126LbO}r2qhgXMviYDobdWW1sih3 zPzbxTIzXl8%SkxT^VPl{icW$&Z~$FFD`01&vNL$^7yX(@ZL!~cqBmeCt%!pH*%_xU zD&yKPdIdF7GuvXj%#2tr$vBJ3h9I+T64r9wkUCldhXPW5VkkuJj(3MYD}_qP%-lHTQ3H#mu7LbRH^Yu;{CQr5 zFi1d9&gv()4vA&bTHy}_r1;*oF}%yoGk~!xyvxfIW=cHe@HCbQ*4LcMG1Ot`e(+W% zihnUQ=(%upu5^XTd6wfxx7~_lNh@Lm?sDZ0xQI0fPJdiEUxF0qQvr(ShQ3I+<>G~H zqp0qkp(l6z$%FwqAtb@%W}Q;h3z0TaO=Pygveq(E2h09@*_YTknjg56+ z41_X~ri$&Qn0Yt!6S{Q9K~J-i8<{4eKz8(i>(6LIG(df*&nDtoHDrx~&TYH5e}zO% z#P`rHw<8samI~0oBM(E?PSxqLnRdG?v`fwX>aHJQym3etKHL(BNBS4K#HzcqwIFzj zdGyr_YIZvg<2dA~gL;Cwg-u4|XX#bhyjQb>y``P)<*%L}N^kB+5AQeXAGw9P@f?Z- z32JCM3c78Tv^mii3FOv%rYrhZDhlO>Pq@k>-q7&s;_;y&{(7IY4CaNqblu}&gkd9s z;=YI@>L2-QasTaK8y5x)x8cqEQxdbG;|iO!YDNOzoT-%c|kTyc{1&uUlxRXoD5Y0$%I=FF$ zQ`AA~t!rdOLW5-4&8a!ocy+T*;ra&vBMcAQzReT-Zj{4`DWrQPi0gN>V&~7cfAr<7 z0>r&gSYpd&PA!Odenhi`7aCNBIEtH7IBG56l{<}+=T6BZ55VPAC~`0<52f+|E}SaA z+2+)1_{lM+&XiaB&G?%G&0oM2CA$z;uEA_quYZ_c36wP@J*oL;awZKFAL4v_gI z9X%yy7IN_fpsBUvZguor7ldqka+FL?YiJ1k#aSyc<7f5myA3)P=Si0Kpb|TWYH)?E ze*VK0M}3(CAUUVxoS?g84tkwAe8WOu5uc1zT(-u)!CgFC+jJ>)8_%Nr7hyNv9Xi)+ z`(DpoyTs~Woiq@F%#MthL{9>d3o0U`IPFJN5iAjOR=D}pu^TDNt88HA)Vy>L;T3yug^UJnIe;2HFV)BotUTkTA5$kc*#MVDNYx3^AF+%==FzCf^{j zNbEGC6 z06~hSASR!kEnY!nRYkEQHacmzL&$8O(YV)J#d=ni#-2YzP-$S(33VUeoUO=Ea6k`f z6b{p1wzMZ26ks4WY4JV4~1Pt}{o3_{> zyU}*?I9nrAbI)_UDzP4O7Gxfrz1AT zZccono`@CLCGOXiN(uZ~FDa-hROYJ;7dnRh*4%grxuPRvu^(P7$&e(mnzyvJyGWO` zexTlZMdqjfeciz6nCYmD7rO&B&0$2ugzBC0o5PMp*!7)=O}86#N*BkWg3HvNV8zB; z8{RzhngA1ufHp^tWWUbNzWE0nO|AW_C#6xnBe=vLS&}UhIbxHcz?J@}wbM1K@<{kA zPWNw5BJ*k{2tKO4ypgHGh8E7fS*3?}8OEx|?qPX}5_B?)o~TfUkHZ2OGZ4YOv79Wi z*>*Rk(+xSBH=^KhwpLGC(j~n~kG;K9&&60i!{i&aAJGu&J&#gq7>T~F7DoYXGk|~; zF>1x?l0oGB+aN0cbr4BqpvtM9G*}7&`a!%${C_gA`){|cZ@bVaAkb*IJI}2y{T-K& zCq3EuFGDORqp&TECYT}es(#GTanRc1GBvhw#%A7pds@SUb3|ecW_@2BU?CWGwsWoAiFM-r1~N5M?&yY|v02)4SqZ+SJL#Xk zxXnRQbQ--c6OU-l=3c+kimNPbC~wpX^H@Ep>1$Rtl-B9l&7LX^juKGpYu9b!v{PdH z#y)MU6j6I1vH*t-s)FuHGDh+s56!Tl)pJ9aX(Op%A6ZK)r_FOaRXY81RPb-7Yr9VrcGt^TUfX#|L+6@>I-3)jICIg3aY9 z$%IlAyOTB%xSfaAibfG$^781j97t&S3CK{I<>X2`hQ!ZEBM0x5MsS7)>wjCPD7{;e zC9N$t@7}^T{*kt(PXmCkS40@x<=MhE%VBPUlvjSszz@=+;03Zz=3v1lLbGaOGzM*5UIRJE$u11@WPK>D zJiwD!PbR!l4K&8-puuL;clw0p*@j&Y%fbm{+j9cw-j^BMk(Xj(?%MA86)Ku*$e@m` zLLQe?KSA6mH>JJFb%k%6o(K8tTm2oEP#c$0Ec%!}F~w$Y)<#YnrV~MxTHUBg`?0Yq z!HHS->D3Po#r!jv6?ObYbnxx!53h)sibPL1hf1B$9cNXQiupZeN%zPV*?uH*Y{aC0 zD)W%!UOW;9YRd+5KW_OD`!Y|Z-4wNa{3W%B2aLWo=Y7lmPsUh}cur_g4djQ%L301y zB#U)#muI^m2$m%@+^(h%)qp4@f{2l9O7r}K???!*rOxW2`60@_pvyXPV548!#>am% zE)<(wZJ#Sv5i+Q&r8@#@dn2BEDEl|(pK=BQZC>2Xh({kdfu)d%IFm;|W1di@w&T@c zT7@|`gDc}O&tixkY8H6=oy_Y_Rd+;yM1wW=#6!j4fJze*;&o$Ux=Xs)ZqSvw;`UHAOrM z{YiakN=a2{1iax}p=np*-6D;@>Wl48$D0|9Kk*m-loZ+-YOXk$;bD|nZ^|_j9c{Mc zLV{&e!)Y0wk_A;J{q_ZGr7I`}3 zBZC9b8E*g#fphm)IHve$^*Ty4TPe+7xZX0#r7tfAu5@6*SeyH<)a6l6;M6823Q2Xm zThLldqr6}?EP~iSdbGQu0o*Mog*JUjbQ|mjB35+9a=y|8##;vk6<7orlpM(|4G*5_ zREMZcTOVtb+^VW@8X_9!MNgxhV|mi0`t;YJx3~z^!;tq_qWFkz!UYC>RA>#GE!BtP z^8Cl4QF0T1>@NCVy*T9}JjNr|85`Zkm<2yIDaHLo%ZMgUCTt@CMJ3ze*Z-95(4!~( z7rhsf08lNGP)^HigbmryLdC2(RF(GOq+D}A4Sa-5J8VmIkVQd;s@GZ&Bgr|_V$`0e$Zno?Cf~BkGMsf>n?`dR(+{5;8sN^G{_% zF@M;psFx?p8TEij-?Z{rt+tqJv~XH|`%$m)78^yoyMswJyF>@3W>Gy7&KEX8d$#6( zK(wNNhL1UoM|S|G6J&8W;BZQ0z%;N*<60(9b%y;DbTzpM=d2eptX1+>p&HZ1=Z55z}Z-&5!Q|)j^cr| z4;sP3n6le-;0wP+C*XO$d2hNZCfQiEQQQkq2h9c2J}N)Er6O&&l^Q_g;lU*cJN;H<^)onFeCOP-@@;?)o3spgTfpsJ;(+_nu&r?y)148 zbSg8mGuU5^`H28}oTjV+V!9MeSC2$U0*MZ@(o_ncp%+j9>{Msmq*aRodM*qZUIA*g zt&M$9ohIRK{0n{P(IiGcmaek}dc1-yrq@UV==RI+k8*HC?!;KS)qx){yn&%rk9UX8 zL!1VQ+Ou~@g>2VfIIVlhKId=(jh++;x2~;#?;!B=BA^dhtNL!1^wy|*2S|Z=)uN1x zko)(_WSh{zR1|+>OKyMiIA~=e68wg#*vDKg_*Bd;C#qcLi1xt-YU$@PU4qG=7t}Ms zlUFJallG*MHif;KMuvz|8Lpk1Mi#4UV-2vmp%nAb0`e&~8!0;q^e z;%iyUahioS>Y{X9&3sC0U}`U;RN@@|sQMp@bb3&b%dHp1(!N6PJ6}fJV0%Gp6nAOr z)hg-SvQIt&Q=EA0 zW^U3Qik)eHT*hoz`83yvO*2z;NS*bp^lvd}c4Ac6JN3IuH63D_phbJt5@Nu^u_>1* zPD3wpZ0aLZtHSY&j*Deb!TG4p1Ci-op>@&4vN>Q*_rlDkV6{rXyyYHM`VlLKoP&*-+IPX%h%gNRg`|NYDV~QV`HqT5X_}6pNsMf+7k%ySnq>|3p2U!ym{0d@Po?bcSVna79Nef*Q%3_&hV z{xV!+<-&KhpgtjX8Ls?_F`*V=Wr@4g3F1B}OZ!WLeie~twp<2TYL?v2LJ{9OIhZre zQW55!6tAur^aSL$ubTL$&@DM+>Uoxg~oV~wlw`4 zu2Kuv?`mZ*^xMikOpMz8wm^uQAj6OOppW7@^>Kh2vzs3uy%e3`8)s+`hYNd)+u0R6 z`*S5yCoO|kOoY@{n-|OV&C(pUmS&2g3qlL37xghiGB0mdul`OK^pl08KX@guEDDSB zdAzOwgIpfEX5*g>@*8z*unbaXH3lKyKsm0XL)0^X*PHN76Z+b2{}|F00+#p&6f<^K zG-{wHA#S$T>*I6ZO)_eByHs9ZUl{51`d%ULWD|&+)!a?9uOl*Np>W!FJMmgk#buxaUGo~=>jmszG+q|$u*7)_I2wv0F0f`DC$oHepbg%fPosTO$v3o6 zxDmrY#ymQYrH1kv`TXhK@7e=Lz`gWGq!JP~Pf|fvio>6RtbkPf=&v&!{v;|pr;~xK zq~S^$U|t94QD{x3T8jW?(ygWr(TF16ffJ$`2TFtW$&Xaw&)pH|ge#yTDY8WC`l;tA zV(u3PfE4)Ye-t?8zV%!IhbsM9f&bA0);Z_;dyTH8^4LF%i1T&9F&V=sx z|H>IVmvh{CIW%pceP1X zIGI@HI7ZZ-0#3N7WMr9H{(;g+ar8j~3on|=qv>2O3?g56mvAvBlcKi&9)#Y#^i`?D zKTwj8@B(28gI1*awA*mbyByxJeVG0ngj_eQ&*mrmS#Y$8%r zt!S-As|zU04L$-Imjj&^$S-T@JNr?Qx8;dp9L4!;^Mp!csR_M_MPJjz7m+QQyA9G+na9;J({=541rm(A9CSyJ0&iq}yT9_lR?!A`M|^hIF^e#|`{(Xz>n2xNVH%ktZ?-ddfF zK7EsCY(cJ??Cb<`di>#i7&8QJ1n&pYeaSeke+o) z?BGk-d5|A%rYKi*-8UHGZRB1)_NSzC9be41Y1q?r{KX}BEY7%q!pqt)oD%yU8i(8^ zWFp)>Zz~*kx(TZ%-j~YXBtvm>HK$;LHyIth8=r0`r3IQ{Y4Z`#|qq4-?ng(%naMX0hUnDzCm(jHPr~t1c6Xd#qDsCE} z9u#+sC~sN=weM&ipxAge4N&0ZeZa@6@kE(e5InWOy>yj=hlyE-?#2F^YHfEKz z^ZR3hHy^Xodh=$gxrA!ab(NE_QwOm8&o}1koKgJ7|X7T@3Lm26=MQhlre|~1J2pk3YfJS zc8%OMn;PQ7We(B#C{Z)XR1V+wWk;7u7-BMQCd6*C(c|8 zG9}&-ni-YF;SV)UPNj(4F5&chL^Bb^#bACPTCgEU41XT!%MmSvF=TGPM}CJUZx`B zG6^wI5)q>^yU4J46`W9~SmCYDLmCZ-;6kEm0Hq#JMn~-qow&p29+_18>6ZCTJdcXi zmpp5+ANbJ6JSQ%&z{bxcMxZ=357WLy^9m{jO5TcQSb}lLh_nL5m5m2 zjQxllJP6`!o9RKG)ZlzR*4y@AgYzkV2(`gCO-^DH;JaDGN@xy{CRC+Ib%t2he4*>f zETCH0Iubf8fYJ}*$zRYT_tGr3`e-;HoCYHUwtO!c{ewa@50nhTDG*O9dyvuGGMA1m zs(SW5(yM~^@V~NC3+k?Po?Y1+3g<8lqy@C?xvNGDMqt0~zfOElt>KF>l7Ade<#!;J z=N%U<@d?t{SnC}hEpd0pu{L$B_3q*Q7Wsa;^?&S zhAbhAxt~n!D5M*F#VX`(YVc|6J##h+6_D*s%{l!j7&~A7jD26T?*ey7u*8&u7I*m& z{USPA%)3XBrEJv?S&`_pcHx_N5+aNWBFI*f6aILn&A8vnm!|UtdKYVE9z_SKqu*&U zDEiG5)6k8wnTZG+=e%4WoR@1*F*{2TDJue|wh)cq%`9*l9@-}2PtB<>&`rubJY^Nm zmioBWrPX;>5)7c`R+}m{JH$g&#>JZQiQkPn87poA7v{gP)!IzPMGel?%k_p{&d*is zvq$+fUGON`bPw?IqMU}l+qku6@z&`4B}W^N{>Ank@waK9B-dQLa!4TPpI+gB=4t0Q%siWL6)Ms{7 zXSg0jxNwoejeb&nETZyA{^iup&139NtfVJ66#mkhFWjkd>x8NGTCx(u=lb5T=n^t;ENP-B?Hh;z3{ zL=e_w`*Xi7yDRjgm@Z1R6pBVBtRAE)WuK*UI?P3+Me>(u2?{n+sY)9al1u7YbbdYE z|GS=o=6b5dH%s;ylo(3X%ZI7G6n;^0w6G0alD=Q~ zOA*veI5cRC9fR6k$58m7pLGfjn$^FQBH6BFr!xp*8l9~HTlmzH$#E(NXGzG0>5p@U zBl*`8ELp7@pwXjd$1R=lXMn)^&yhIUcec-^=D(vQ3;~O;??>HF2q?JfR7BZ>jd|E#R%>ym$QZxSy z##&J;+s75S0d)b4VFCmw7&iQIjkfzxC5a3bm9PV9&|{j^&%3-R_XuJlIqQY004-$n zEr+!szq${(S#jy%5>yXd=4+yS&?&z77LgY2R~K?*rIv$_%DfNP?AyyQvZ|3RRdvfJ7z4!7X@a6RR1=mc1-E2eL@$%31&cZ(K|fk*fum`{ODtwg6UPs3)Q0OqtI?dg^{D1Q zjJZ+x4llvGM z?xl~~RacE3)T`s;M8|Z0lZDT&bBIooDY30EP7Jwmwh4#A(5?x z)kzbvDb{(&X5}1y`&fNWb1*C2TJ> zgZ2wqE{D}A9ah^H^(Dp7`ku0(d3U)(yQw5^lDk}#E6O_M6}ihlmXuMJc0fXqdmOzD z%9|0mHql02W?NCQ%UpT)1_tCkXtvHX+~rS8nYr%rU-6sR%Rew>AdcuaOdSqr-b7N3 z>uD}<;i!o#uD2mexM8#~GmEd*7DGMD=*HH^-vVL2b@_{>yl6PW-ZEYC4WSH#sMMXt zH*+qGc~TJkTZxCSCb6`p=vi=wX9-XPcS0Jid4vRMc@Qnrj`s7OWptJrMVPt7uKpz@ z`~GJ;e0W(tAQhMJ=~mWCQmR;q$|8Yo+2=twHl4M5nl{}VBK{7itIyfGvg_OuWLDVS zN39RS;)aMl#tzlkluNalB`1z0$1Qz23`r~qUZ(I`+a)qjYlTH5t!AEYL!>1fnwpEr zcLApAFom#nDo097eMN#{2D*qhf(wFk@iLzwehB>0i7xnhNFeohIr5oCA1L;BH;9JT zLlV?Eeut=i90yUT*4)3&f*pMqV_0y~!ShnnJNDu=h6<_Ys*%j@M{ zdLqy^Z;HG8ZeA0J*I?xVJ#=<IRU+#4IwAINi9@^2+BfN6v1m zN|Q>Zg1jju(dl+$7~BvX5ncc{MB-p;M}#Hr>%K8vd2o#j$tWx&IBqjQt=~Fk$Eg`l z^hfn(6(N|-zYHbQkmLrfY&h;9zG+RBWM-uT~bQN7uruu_HAdGcl< zRLA~Ym3Y_#+;X16s>@*u&vZXm$B(cUU3JC|a}!JRWBg^AlFNQ&O^H*?-8sYi<4=;z zDct!XAELLPNHoaC8z`AY*(5p#RucMzK3{acBaE@D8p9Y0XZX8Z+wTZIF>)bEieA%J!q9(l*5@r5!jO` z5Ur)$9aw^bH^96K??`wgiLITx!~J5dCWr6|(n>h5W?K!)aeyOzi*YJ*&VvQxvAxDz!< zO=D*tPu`YzhRe{p+_cq}@HePzF_5mKuOFW7CjTFpzO6&vWqc z&!)j$%;3;p+W%K@nCO5lM7G;wuiKL@K_fF4r=`M2Iu>W>r{Kq#i!*uBx~PHM=$NG^ zp$&%K!(d1NL2taql;a9Hcq)F*Le%s)1PAh&q>l z-#K-zC1%^;9z5r%5zDlbk#mt{bP!J}nlQ2EORAI`D7H{*=Im1Y-fY6VFSG{3WQxkH zQ=P7+n(%%(-=Y0!ew3P!8;R?Jo$=PkH8glY&_(vc>Sttg&J$Z62L>j>Q0k#WQeKOP zOKYrVwpzuR2<7w%Tx{+T^j@~qF16^6G_Ib@X6U#o_MU`FH~^SMXtY@WG5E5b?_x<~9b*I|btIzeqmL>-s1n7-u4=neXU z`z#+KS~EyvN15)zZG#WHZ%OhN@VW@6bNt~9p3zj{d7asU|3F*!Z)<^0odDwDFXMw) z1TdzVT8&~}CW@K;EE4^(jcnD6qeZA^6C*_8_0*z&@V$Go#&aftJebd`abyC94r+p- z=c$khZX@6%mP-qO)M^23EOIy27>LJVc;&UGH7@-NWPf9P1UZGxsgC0746xlz%<|EF zS8SJeB!KYh($L75&kV%*e!IKjk&9nCUtX!9akKg<;9-; zFwya7+*}KolOri$ZC!GH2(sv?;Xc2jCIre<%PrP(d=H_y|7ol z5APHW+=-w)v@qikADa2GC!qP4p=}0k=9w&Kr7!M^6@Dx&>k?`s0?1E{bK1f zwNNy1qX7DankHycF|>&ApB&rz^eTQY7-6p+SJNXaj$=tUu*PO? zk<6bwgHqde<5Gs}3K-J&tQdEnO}$Q6^jdS$s=$5BNrln-lPU?rj+736P6H+$4y;oh zttWK3=e1ESd8ym&_6_D5QNE~wmp7(ZVn%-JOMZl>w@7Z76apTKolF?gG{>wK*a>i@ z=}dJ7s|sSBkJ<)jFT9<2nI+L#JK*DCS|K-0>ylh7TPTng{xZ-WJ(2hrOJ25fpwKR& zXcAx7P0#IzqzG6r3B99wGRl-R0>uk`X9DIs{tF(?Eg$%aYE=@s%cg-0ur31&{{yNQ ztPExmK#<{em%qw##~zfE7Ct~0;GKGIAsI@yA@@ZAsR5(&uLNh{3}vS1P%7zz^)J~S zUKQt~fVe6FahZTPBgpnh7FLxe3oH9Kj7$!Wy@pPMI>0(w&COFUiE5oJsIBrziK9}YlffhitiyD-M4J_S97G~Z-F5GnR3Ty0tjHZ;o%|7 ziu0)w9eb>9PA>^FR+oZxGX0HBYQ>FBXVt3OYO63PDcDu>(tcY!q)Q2`^Hq(I697_e~Ml&DBE%Cc~Ub|Z%tx+}aeP&3{w zyUT+tJ?d;0<;1Ujb5ZVRv!@o7ZzqmlfS3@U6jo&n51%Z;PxHv=Si3kC%h_NYEUNs% z9D?z^qpW8^RbCr^>38UBhK{x(sY~FnxsOMGvOzM;$sog!@OOA0*kveaE%Oh)##&U8 zrOKAc56o5&0BGmA3lqL1sz|G}Cjg|??uv=55XT{ikCW0LbuB+qY4n!k!BbrVM}wyv za}II|&O>2xQ|{LArpLP!R6W)Ka$tS5>^MYcmq3F5jyZdLk%=AQ^|#Dj72f0?yN=fk zURyEpI*Y&N?snLfC- zsy*mjpWvz7GW-_5`T4`{g38ZAAA3SarqS4iIIJ%HHd$NQaR~EaZt*W_Z~)(_tIh1b z#ED83&vGyQK6JzrIy?2}`M#r{!%>;tyCPjR%`JThgYi#O*;`J7u^e>l@-)(K?~@)Ze}}-&H}v% z(B>|`gbf$}t+kC$trS?VBUpbimpkk^*^B}{1o|AgRdzNE9l*B*K)xcSWcUm@UYQ-e zph_@3vl1Pp5N4)XnjWy!xjCYnAIac&7^206wA!eo3}3 z9=XQI<99uuI=#gw(l^fONXn*1;7ahj&iz7d;wa}pr`>Eo81PglsXIxPDj%@QZ6p1Q zM>-l8=p5@HB%_74WJ1swzHGF5`Q%@$*HsC@Ktt=2`d5ET2#-xJ3un+1rzUlrL6{27hsYuPw5aIHw)ECKiU!|PQAWZ~lAt&_!4F^A^)3*sfC{p^P| zUt6D%7UDoY&@%oZ)tkL5oflLizPQOhaECM(CIH~>ExZ3RS0sYv-%`G5tBzfc=COwa zaBB6=D)y~#7(_Fc^=c5%7YCdTf^Iif_fFTOUL$OJ>n$RcWyP(bt4;IE&;0a*M z02~R}4UGL8ebMXe1}BLsEWn+(Lm(v@_A*rEhjSvkq{2>Wypg0t7oLR5YZ*G((&sK* z(`qE#ABvkVLr$Ie0|4S&^st}DvL1YR@OBY&my{kZuG^QcX7$qXry8CAM#x(r9>zqz zz91?AiRG!w(<%IHZQ$ZC&Z~A=_}LgxpX8bw!g<+DszhHjSCU(haMkZu_Eg-m7m?on z<~I&QjBd!G3>=1Kd=bNPYG#A&Gd-U42a(V<4?O;i{RT%@r_3vpGT2Th3U zCT1eyyo@{|5R48mL%RzA&*Dxkv=bTdAPOEX^Vg>~Q9Z1FLmWhz*T=3XG{E_Xp={y-E<{6!W)waYY7(eJ*4v=jj`- z#@wMT@E+h03v$81cMCH3rS*voSoS;FfMD$a6XAz?iX&59)kAKiQ6jlP!K%JE|A3ZS zt9CGc=51{YQA=B{v#=yB*zwTr9phQjQ4|~Vlk~0Zp6DZXNHz5td~T6=0Y#Tg(+)Ov z9(%jVd(>CVqEIEtnj}Mx=@`OZp;Rh3ob~SV{nRuMQt=wK3gX1KLNX9p%Xk375#eRF zwS`(k(CZZfzNwM%bBi>94wELnI6A7SFxZxHP1(5Ek?i*UOdE3?q_)WE7=}u+MOE`SNOV ziGoW(Vwd$LV04Imf0{2I{bi_EGqGu8f-y8QxW@C6C{ssTBUi}G{W#!4{g-Dn@1j5lrd(F0avnWjPV-A&0$Q^{H8RFbDPCBK?V_L!pz zDzVw!l{cPGy4U5YPcCx+B}$u0{34Z{ZFVAg2HrMxvp1)bE%}>tF!5y%tSm|yvAUb3 zDuAV*nqa=g_$Ft!IQ&^N9SClP>mqz>xYYMtaIlmFliTqSkI}heQKg>H$w??<%e>F`ls^0UND(qv1= zrqEJowcv?O>?GeEiN&O*SV?E#B2`Ma!6semGN`@lRljARDfl7yg1^(=zV-C-aNB$imf9vEJg^7O%SNKdvW>cK2#U zscUrpgUbpr&VK4yrG3GrntokaQ(dj53#I9Pjm`@4+LvENrwr{4Z21fxdo_D5svdeu z`h)Q=5o0?2t+_YerrroPDVn7c1Ivb%sb=hGT~90Sx$R?s&QYlZF!`rnz{A(E(V0DQ zhMqcpKTwH9AZ!(DjSsb`T8=GQZZK}vr&u{rD3>GHq-FaWY~w41o$?JFohGozo}i^w z;u~-rhYx;FPIuONGMm9#s)YSEvA8^9cF{ZgQoXZfJI%Xa&eTw^ZxU}!Byr*t48Vfm znL-T;0-y7EZ_^?1>jEsW`60>Ej4rY3cCoaBNfvOCwQ#@K>zeQK(Pwmx%*#?GA9A;a z8_w&@1O#k+zZ)o`VZ{&kr3xnu_8MQVGv-EoO(PC6Vq{122HC1NuERj^6w_*s&9@bB zN~SB~*Z(Qsb|=qm8F}C(Z9^9G$a6Gb92vyU-ox|4d>bJ6&9`y-1S-#jS?~I{GyZDBSp@jIorF6jPW6jK$_eu{0;pK*^ zQ!anq5l=6fU~w^q_T(jGo?u*RW&YcFnME(G?np+#phlp!IAbT{Z2F`jTDi`Mo?*gi zeHqcz+xz&UgF_}v2n@=yTorGl=ZFJ<+eLz921SZS6cjq%*h6y5sbIg?fh*uC)awKo)>a!Ne5) zcNkR4Q9b^z=sCCxcY_<<_8TpVs@FCrnv)fI9G^-oG#z{9TE- z&{>$Q10T)jSFtwQStnbr&Q(N+YE;Snw=^Q>g;fG6**I;;K)P%wA%ZIOJ- zrkV>QX}zwcmf(l>a9U)9BeZ)kuUiy%|pbA?EoKxi16;wWUMSH`nmX5oZxPIi%GKlS|~mWe#F;TbMG%?uD&;JK-i!2R%!#Un{t`jmbMpA5S!l=wfde(b*<_ zRnoRwT(4D-V_|C>8%xr^mGq7b&9!i}!v?pre&KXS@<0+NQ45nNq&-=F+waLG%kQS% z(<~92oL0`%)2f5YXqG;tNtta@A(drFxByAmEeRK<5*kLdPj6aHszEamR8j8bRA{cq zSQoo6a#dkuR7QLsr$U`XB?TRl{t^^&;8=Dons@t1Bfg2p*blC$Wl)I||JIlP!b6kT ziRD!Io_8?=^@pGHF44bFd4(TS5-#`F>ffil>-Y^6xcioSH}d4}`;>RL{(a8-t^WPJ z7uFu>f7B-4?!JHZ$}V^Jea|~c|E};B@avD3dmoZtl#~Qz&|HF8kQ#)BN6u32eT^46 z%1pU793PbWn57=PHXYBH#DfT(o?kWtJz%6T@C&X;)}qzmX&rX@NeEnOSHqoG^Q0-= zhuv$P19_1@OaAr~1PIvGYZEMsDv$cE4IU5&W{@fPST|2=33z(?&sGWW7nvb2hEV=N zNy9mxh*6*u5=3ZBp{qc5eQd$Ve%m7R`07rJQ!Ka?xflpA=eoKs?)o5(?%^r}MF7D@yitW`;kT3oV{(=6TAj4f876HUs*APq*4*d`6 z%3{rogOhZrJXLHDufpR)?v|B(DJV42mX#Bvis-~v@Un49;VwF;_MJt?Viy8CwVfx# z<==n-hZ}(HEZLZB1E=V`48KGlj>uBP>o*o8yAj(KipvUmHBb;* zjSH=;S4-CGtgI~QZ$vLk4$JAu0hDl6B9|FeZ|mV&=91z#>OAxPA7jfIwk4M-K)mP8 z^i32_W{z-8&}bm&hfJPFJqT!nYYs=#0ev!4n0+``+#4=p$ANl>i_oiqEgCMen1gQ3W;#39y_U9nvrrg&TH3UM=18|z5*>d(4DV;LjM0@?{349~|RavCR&XHK<; zG_fyauVF><(Hp&O!aZ8++`!W~64yG{@FaggZ%YLbHy{U=`q5znl4#EDqT!IcSSp1eZ&tF|AXL{_ekegCSXF2OC^ap{BbBDtyvDZ>5hUtQg5xtTeRZJk~qr)F9U;sDyNN5j{ z-Gq_NoQYF2m$^W8%=;uQ4hGsux7PSL0BORM$SBfv<8KlS zsXuedbhuP1sVA&D+tZ0@K(dw?mGt1aOu;;|q;3^Nq#70qp*lH}y|o9X+YGNOk;8Q- zqN|M1i3}KaZ5bOqpUic}K5R`ShWKS91x%UQ9@w3fg!BLY8fHZ+-hp)>JjZ+gsx{Mw z0RP4IISV(DkV8xqf|?`8-hsh*Vx(p~wAOn#5n&;u!EQ1MfnQpn_|C=fAc1IM=VU6E zvJrE2bly6trI#2T{L2mH&jyQ27!nb3gMi|3fEQxXVR5UQd|2{BL|m zIn!OSiZnXWjfpOVsqX>`xFkAHap~GI5pVORMN8UUE?U?USJ2wE#)ZXzeY-j;mLtqY zt@tjYHX^%7pU_az$*lN6xv|%(H}HsP`h}sWx5%BplSy<}4rdwsi-gC?g?5nb!gfe) z7hh;?n!*AR9k-ZV|FS&0+i~whVTLx?6B6kyxCfbHA3chu4ycou1Id=u0S1Y@J0Uga zus?U|IWJFTsAPF-#C($vvfoZk(tRrboTT_<*~k+C;`vYV8t9r|$q%|=a#I7BWZUZH zA>>Z#m5JQL0ZyzWi&bdKf{XNSU2uEz0D3Th&?iZ5lis>U10gZC_^GeD3Ghihey8>H<f-K)V00!`o-%}e73w)uo_Box3lOKY1m3xKf zWUrS3hs{LzSF$Ow^Fo+B@^T(SGhK70|oe$S4H5pl@2~Q5520*QUDk z`n)FPx4Y@pdA|8RzK1YK;UipSXl$ZjRsKKc|i!8{g=Ufn6Un4K21(w$xGGc7sE`rY|q#QDGR&4WO!17r_)vt~H|S z2vKar(Bne2S3hB-s=K=6WpZc;S)6+aT?&DFg02bhWX>OQX=vgvC0I8N6urgC(w`&j zIkK5}v|Wu$_Vc6BRJF{LVA#Y{Y?s#`hI?{tgLB}^@QQVqzQp@-gjomcU`ypk zMSW5b5D5VYE-_1hwicacI&{=|q&J~FF5Lnb7 z*?t0fE-8celqM65J=pO?i396cVBER7&Vq6#j_?WXv6mzwbRHB7cFs~h_O#CAsTEq;R zSt1k^;X=0f4i7tieSO41BrnHj*sv91Y`g}kT1PQKyp1^kb`)|}g8A=K7Q~F*C~(r~ zF8=-kU82v+8?jXQ?{{A(NUgYY39Fjq0xP?a`zU<4rD%@CC(M^G?oq_w*;}_8jle?h zIOfiB`C1|yBU}15DB`H(5EpvA?#gF?KqQH6o@e#|$wKfCBw~776-PQs_=R76uSe=s z>1;&ZmPE!2=AU?xZX2^$C@(g10?O1PjyGF#{w<6X4$oDh_A`JlVN-I&q`zVa>n_GE znQF;#kYtf5%63u_h~vZ=*<}6c`MDBS_HC@C!1=b;`5X$`&J}{A21cJH<@xnX3!>!A zMCqzaF<3=1C{axMu2LsyfbOB2F%Qqi1Vo8{ifJ%I-1WR1oD%P(2Ir-W%3kq-`{~Kl ziT{5YWZ(f&3YsJFfEZOfYR|Hlc(eK*w68b&VBCvzHCdZnADo+nCBn*QN%lZ10`VS5 zJS1C~R}{{kp20IgBU~Cq=rnQ)nBpdo}G!IjyeFFy;881rk zrCU_}l~8A@u&-hY{r=K=zfE~^FjXFutj(Q*L;okQ6$DDom4A^IMp1vHaN$q7_F`)1 z$k?T=EO+_)tQ!#|3OEFUoqE{^vry?>%GPB4yqet29upaGB+_lMyIho~p!9BP0u9{M z1C{Lexfm9|=MC~%P>{=;|yf z3YeSQ6CTbO4t`BZOGtKi@kYVmW>}EmqZhd~JJ1sy{VHrF`hRP|b0GNX!f@VVB&U@P zwAFNCtK}e;pr3zU?;kuM%^8>ZLlzs+Hvdvir<@P^bz%zVb9lMtFV4p+fmRn^@S3!O zTuY;A=xB@+8m>{E;%wJ79BJH~? zKL!bgdbZ4GsJyuJbG_l!Yb=))D=oQ(9m(R}#fC^sD0Y)2T(%IC+$rurS=0 z_NG};k>hPi8^ewCBq`BH(^BYyzC+SgE3i)#Gca#lbgh^;r(*#<1YBrEI;P2yYvmH0 zNw8bK&*eM5##~yxhDcQl&L2`s1j>niuWB1QB1+l&KX(Pz}yY0RK7R~XEN5cl|D34br#^Rw}a zSx_{W10T(dc$jCPWls$)o!|W$Z%qRBk<@$CiCt+a$4as!7o)7BIi4w7>RlFUr7pjM z4H#ad&UVoFPV9hjNHrmFj^-}H9LA%wbzZRP&oQ(>vMLSN%>NV1RE)CN; zad|Y-)yY2ACczBP#=G#Ou89iQxVjJBg16k208H>u;PaQ;?nLV1U${#DgvYyJnnJpO zXId_WskSH8`iZ|Sj;|tfQDR3T*+E5s!=#o(N=cmwvs&C@br4+~E~1=RJ^fX6f_YbU z^F~MR&2yHO%Bla3Bu%i_tNr?GM{n>{H}J09dUI;4Xy!i;!BU$zOlO0qE`~Wv z(jPEQ2%hSpUlO9f89e2&zPwUvZX!qGHzYVKhqq}pio+efN~A;d)?FML;B{#MWkRfrA$LW;o}ne)rwW{h zoYCtN7!^wPGK&AJnrf<{Od~}_Iq*MQd5O=V6TR`ZLWbB@0mVtR6XuZQBnk+K7~4ZV ztUD9vuFHq!W@2(JVr&=IXLh5ddWFyCgy5r?jaGaQ(9zi_$F@Zslmw9lhR$>r)k344 zFw~wCiY{@0PoXni3>Qg>&HAOS(NVol`}Enone$V+Em5aGU}(CZZzJ%x#(0(3wtpc8$R#dekc)9f=xX)m zRR4M!eBlXpF1J@*?5x1s<9=a7#2a}wwh7TfE!$yPZ?o|i7g(jn%N-SVj)^dbay?ak zA!h{r%8DLRRfsYiDf=2?o3c>P^^7avjUPD#VdT{tXgv#${D31I$vdmvEs- zZtJy60k2d;ucU@|pvTU=(u+IUWJ&d^NG6&qB#268b%z6^Z7Z+bJ6bSs8p4x|=6cZ~ zFxvf~c)C^10VsAC{Q$c#xmAvt`k|Fzf@#JG9gAf&AMpJyCa|#)GT>jqj)EBTvX@r~ zHAFSUCFTU`L7=HVoa$A$JxivI@I_u>Q}e_X2ioV_0aJx&+yQH4#?K2Qpz)59(j%gm z_>)*2uqZA{L(Ev5@%9B&!iu*7L?!D{LUttAEIcEs8wSQ|8#D%W0BuxUwv#63qS;es zvBen2u7b-286_CF7|!JoLsZ0~KKQSZ-huJB1_D^<6nU95R3O)@0=fNT!i?_<8=Sk!j-Mqze@z-p1ueeL7)KJ6eTx z$=x`{(!TaEe=F>J22hk+7oE`7=6>>s^rJGPBL-xLg2QifS8O67bON8z*JBj7h!;2l zkEYGVI8VS(Cai(bs+Qr;U`KURedulcq~6vkYJd4c^e_dcicE-Ig3x2FnlTsy^l~BY zftPasQ`TKRle)uO#OBbxA$ZC@2QhiFb@-rhVK`AUh~)}@j9z+W$Dzqpp;K2I-$f_3 z&a)S|Usy{vXTT{Aqq>GaTjnFDFZ^w?VPs{71FOK3w;A7tR&^zl!^(6anWjl~(69_N zPx3r!d`F(B|8(%Ay(|Ys=3uf#bhI76bVFMi9)2=fM@Og0Z=2}obotGQj&_DtIe6^Y z7C+jOK=9yA*dJCpGLp6VdSg}dxwUa;cvH0uD*DS71(j< zhE9w!_J&qvm^q;n`9>d>J~|Qg6UP7+3ALNxqv`qFq>nmo$MAoCnLY_lGovbXU+8O>**!3)iIvj# z3HVjPyrH(h;F8>09O(t{ygAehTcsrGv%8lLZO1;@De)r~Yiz^1zwQMMGGD}L+K{4( z55gyjU6p&rxIouqR5ORidA!nQ{7o0}h0j!Gbe6IGLGJ9I3GN7vE&P2(Ytg@!hlK0X zxR_XLxxiiO$vdno8vj762?d6nJa*zQ=*t}c^g>+39ahia4F~oRi#T9rZ(C?z!NN6m zt}lHbS<<3kq@XyFUh16!!o{S$k80ttpuNOCw+BXGE)<_g%XG#9+&2dqWq-8%0U2NV zQ8KBu0&z_}Kht0`6{17(j_f?3ycv-}o(J05$;|?!2}1; zGK@mpi7?~^^fPw9%q1w(W@!kHsk5at6k>~uD~>~0GZ0_V^>BCCf$SgK%C9%0v0b>$ z?5q_>^sCu=c~U-Eg2%_a?bN;f;iyEMCAz(7T&U3%UQyOi>yC2wJtVK%=9LN0x<<~# z3h!1v!y#Bn_)wclPbH!PXNwv1P<@xrslFoT23upjJf zpg;5|D2-D+i_s9gxD@ZLvt`28i=3M6$11jqh#wRQY=-Yq@yM9JygzORH&0~0i%7b` zUA~Y`a_Bqazmy}`18j|Z4h^vdv_}n-_~mm3ATPPz+#wg5_{VPpGSd?1np|goi{^;| zk8jtQ@Q>yq$Y)mpssbo_$eo8wbTTVpI#t@WT5sU_+H&?dwuz#DdQCrQ9r1N2$}1z# zM72v0%(J0d2lS}R=pmKa3B-jjhtjVfP(AWJwob*z>Ap6)ARl16vMqk{EB^0)UB zzmogax6A?)c-I)a#zZ+1m`ZkLt<=l6G5AvF^cmJ^P}gux0x>LYOvHVf_))`t3DW)7 zqpa0h_0ecnp%z8Vrbq!2zm#49I%1;pDcpb77l>fDsgXD6xn;iG<#u+YUQUa3e=_mLNoyePy%jRxlZ59g*fh{s8w78>r zQ9j$MP#{S-TAf6(pt7}yMpv0c4e;B;pH%tN>JB(+6KV1>t#Y*8K%%@V&FseKw9pY~ z>Q(9RaU6ADw?L3u(O5Y;x!}+KzPJfV=p845|N8wLTz;o#v$ory$Kn?;>zuApvZF#x zF#?)s1x+UOmNNvI&@`*5+2phzMl8i*{d>Bc6o;nhghnhlp&gin6eMeo$~h?Dd9@sq z6E~fk{V-#V4Y8_LKM7*Mrp+jc&Ti{lIegt{+~~%9sjoZF``W^{^2|Pg_RP^OYOH|^+;7c-Z$7CY zihg7@E_DSkOH;WJ+kvmlC7OrcLoK%sALmoKzXT2+39rQnN1)#&A6v8QpkH{`Wym@V zlrOneruN*$XI%(Lp9iL<)>6+?f0&fI3`(c{Uo*O2L8*epuf^L`WY{x(9F|(K%Gr-Y zRe>0)3byKO4iu#5g9Pq1UDZUUbU=pAcxS{%fO=} z)0Tl(fo@BNk^15n$Gp*w!n(DoyFhj<5IkK7oJf8PI-(+T;e2cDr7`zuFB5M)!DgLQv|Mg%sYfr6<(#ThiPCBZAQyqWsFSR)@C;A}2ao2UHhUMjE!8MZIci*H868!e9XKiL^ahv^#WSYFQ@Q zEtpdTu1`5{dn;OW93|wkSK!zhM8`c9THmq|qiM4rdJ2A6%;V-D$>Ik-uBfKKuAoC^ zM(9kNY8f3;trI1LWY0;i2_RWKoVZC}a?-g8*IAHboQNsr&eqk;_4nmj95QE_UEvsb z?eiazDVxNCc%?qyink{*xn#%$PuD0YXylgN725(`F&X?=Zb>K#^${Ww&8>|8iiLrb z`?23%_~9h3A%Ezk)7T(2WOK{1Tizh6xH`x(oqB$B>xp}S`|j9d-b>ZqB5NC=1TAMZ z_FF2{QYb}#K=AILL-6HE_NvV4m-!MrJ+o56+E~Zt+wqph%o@W{z8zonuaZNp+b5fR zmbb5O#dvUCB^nfJAOEc5WJL=IK03e_NN7i8E$$8tZ)xlRr)p^c`vrhFuYTes;Uab?cbO z%YhLlXfEk7wTXfG=!-uR0$}S+>jCvIk#;<4#Q@p?!^U&RKB2JZu z_;Th-4or#nYIPRj2-kxr@hQu~Zsy{kK}D)>g`m5M6{PD4Vv^;gsqf)w!03@RI(Mf) zW>~G_G!o>q!%Q%wxAM{jL+aL->EX9OyJ1q|Z9YzuG2!MCywjjSN8jjpJy3VRh$qo*|9asfS*+0!wNuVP+t?8J?&|z1j#l zvl+HppdSQ4T+D+R;7PFK(E6m=IWiJop($mj0wC3MtD+Mwu!lE_Y@kNWjuVSHS1@^F zx2(kLf!q)O0~MLhlH%#p0uI`1o$C1_>iiP)EYK2&`N29p%@_)53zfl15w?n)M)eoZ zsoDpEyut)fmw=w?t8)Hjlx!p4bJu{wpnHCqjNUD`X6Y8PY5=a@0!c;9&si0m3f!n=N>7 z{zd%69AG&r?J#Ru+UWvG7Zq%$O`f9NHo`6nw>|wZs@t~5X+E5;sYY||@$0fg=oENR zeTjzvfBa+*8i1>!ownvwt`DvEgbq#%p1KgzF1T3@p~OJ{mV?2QS1eEmq(OUBZOxcY_^O8pAzW@y$cg1AZCWT!dRh`lO5!qiMiIyjFjgghKn-I9o&2uOd|eQb;6HeuhwUcEWBQ$>bQ4Vt@g5x zO!IrcWG+P{s&71*cAsR^Vkg^9xt29!B=Fw6cJV8*N9H&jq_?J<7|ijP+?tds z4jfN5I>%69rqR+`%L;X?!RFaU0QXvf7}^ZQVw_+BmGUSV%6HNhY~4Sxd}6JK93gh8 zL*NYvl)77>jimV(VW8vau6_tHO?tD7F-rai4@pNGRL{%g2q6Dl4eGCkbQ3PoUb`_q zX74VGcvKaTA=2rel07o)P5F^p)iZ(%3a!&!&S|7mm@f?u+KddFuk+^L!;e}uP}5Qs z$7PR&@<)?~IW12)^5m{~hV;Y=`6#ubmp@34K>hh^=|0XZYh)YCJYSq@u=1}>xntQp zacf*_Q^N;Xy(yRa{P<%`h3ed;zUCOx&%nF}sb-g|V>mF%+Lg_urz=FHLSi@FOJic9 zRBm>9(w3fFWA&taQ%`id`dz)gb^1k|Z&H|BKhL;04gj#JEP)1*PLoIuqp}eOadKWS z4OmVsn;7+?<614dg(D;0U~6VLIWnVYOwKv-t+mb~O3@KipGNTHzK;=s%Z;0vMX8yY zve9_Y88_3$qjkHWHdcb<d`7u&>ZU!_xYYaW?6&gSN@pX&n|V(4^)xnI zeE|eq#91%$9B#8rR%9v9BKm_=maZ?BPm%oB>u!-I-nahLe~-mC5hb_!uRs;m_`rG_k=FJKViqG=HB>oG#Howi_2X;RG*K5H_{K$-?dE_vU{wM;{4@qUPJ>?P#uR#-Pzm-r92ti%t=q$)3R8xC4 zI^945mu0f#U^h|d*AT3}&_~I{YfK0@>)^&lXM!UKjB&??9ipg@$s^DN;%-=vP9lI{ zCMaTNY#J}74&}q~1pcq2j1MTyoy6|=E2cI$XxnSN+vt3mPsFqq7oteokHoLGTJA#2 zjPXXAklDL1Vz_{r8Sz`Jr8@z|>c`O<(a8S#3Ha55?YJ8?+YYWpnoL#hS8981OL+90 zIos+wY6F)yItS{;I!8oHYM7+QM_bJ;77BPon>Ya~dwYMCJ;7U))A z!=bh!dMn=!J0>KO0at{6EV)Fj8yk;Q4DUzoqe=>K5|5~7Zk8Hwm(g^Ii2n>Z=N3#6 z(@c2l@!50EkJlz5l-JmfoFOop>K3Tym58$i7;v^0)-7>Zb%ea+?0z+l#S*b@q<`#k znLv({>P;H}PIQ)!t`rnOjmeQ4EihT6rH54m6K{^;nzugA<{A^`yrAG@km+!#8I;iN zHv}%?cu?wDN@)g8C$Pf&TR81D1MUElbrOWF?rVj~1k%b1QDJ6`|G{AwMwMifCV)yA zRuuQIxamzL>_h98u)pi2 zhwTTOoSZuJBy)MFn?e2%0FJ{0GWOzJ!Y9%8>R3qCr4oYI;+dIzE`|W&Q@q_x>yO0qqJ@_NS2NJDD@wY)|n{ zN<1gEL=9)Wgu79mM028aCc7bE?cJn@zqq!zD%M`3sSQSX$RM? z?15_8x~aQY#51r@BnszZQe~nt)gu}Litg#o_(ZEu*WC?sMyNSvAv?T^A%ClFB3_e; z4?fh)f#5UiNpCF5LP6OdnF#Mnu#10l@o;XiFWecw-D+X) zT>#gjEC;qiXzrM!^>LAKEW6ZMD>u01&iHI{n`6i#lIv_gfy*!Dcv=1Nw<&U2t?Dy} zM~z-de2t_I-~<4`&GVN0DGJfVzCJF+L zsS7o9Afk|vFRC+0pTGvJ<5_AB{SoyV#H$qhuKn@ktwIf*C-2h%d9BG8b%f{)?I88o zJH?2I`@6uaq^A4ds#f-bXf^t!hf9}V=vFVh^u2ces4AQ^a7O@iSoS#{%?5|}QD z8srdY9?OT3ZUr|gXKyl=fnW}>n>*ucTCxwf^kicR%$Ow5X`rM<92Kik@-1#vWHYN} zLKiy%trn-pf5&9Yg^n4#zXDA_uD}{={#V~4M>4*Zx4`$>FYSKO#8$V9z8-c%h6&uu z`5DE}>>tX6zmuV^Mpcu0AtREdvisqBxgYOXc7?P<23R}AVSHXeR08evQk~t+QsH-d z9sS-O=p{?k?`v!I@Q8Yl(*l&izmB<2KD|S3WGqd%YRaDQ$C&6RN=S9_zHl#GX~a;q zff9kOT?IGm7E7DsDiA+ch2a^fXPiX%Y9fY{FX&eU<%`-&qQ8_Re|RE7O$|!DOe1ra z!8U@p#Sg=q^GKZ zNwGKrQ_l4f^fB#jS3y%BC!XsgU+j0gg7mTAfAlfP&bIn!wo}VtWrj8+*V^uoPAyz5 zeM@y4+WDLT8!IqAaJR+WTYiL<_Qh)1B}Emz10K*E)VP6Q-(<3-I;>?{v`;o5pmOTB zUF-*k>U@a+^C{_eM195@!Lvr(CdGPub%QNsyqMV9kY-!Hnr-M?Y1Mz14Kq<7Qo88l zP;FBDkUG@TO=&i%W@j_XAiD#)PDDD9{5ScDrODJ)eZ}S|?ewywhn*3AU^pQ3*%)s7 zD_#)4LBQa7nMH~Zq9JRUJ`#_3Y|%o!swK08O>$hWwJG`${>4a_8pm^N0A)ZLNXS$b z7wgkh?ZW$5iMwbw>8d}OSTnw7>F_zC)Ft;|2hs~=8TjJSK)tA7hD9aSUl6+zxyN?c2snzHUE znHR2>hJcO2Mz}%m^D~0csQw;V>PM3$rMoeWqtqt7i!|}lLfRqo_gIF4tOxVQNDpDIe=DZZpPIjK z-kQ3YzH+#0x(covUL$z-eJlnHI(PXK3^ADV3zkJoEgA}dICEp0ISH~f&)ueH zFVGvcq*CMNs*w)ufWE9G_^5M+ab4BO7S?-S!^oC4v!E(HZzl6O+d!F#+Ipkhib>Ic@h5FUQz#}vk*cUcixdHEy{(m28=Jz3 zrmPAoQ&hC-aCkwR2nsD>X(y-0sB`L=d*4^LxlK1WopZ=gNn2eYf#2Xp}kr*gT~;pK@ICl z;CG8!gj|Nn8=b82P%>}T+l{2}! z@oDUH`wI5?AMb$gx;6K-f*!slPi13DQ@f9HikBp7mh(KXwPMu}su6PJBU-hON!BFf z`E%0I*5Xx%9r6+kT7qJZIP4cv1Zz3|iZwlBx85aJf`= zI;SBF0x)%$HY4GElJ^|pTB!ctz*C}TBSl^D6Pc37xKf|57uE*yQcQxq59oR-)nk{l z`Sao^U%fwf9_3EP%&~Dr#qwSz#Sr6&Co~A|3jI>BUx}J5rf=Xb zO10=x`5>ldu5!_vI00*#xMc^Q4Cy6|Oi0I>()Llr)F2cCA(B+V`4a7*N8LkxawZ&q z`BoV3wivL?h|cPm~x&EmOSl)l;d^27BAb%x7J zENlYmu>vO6T2!JQb}oYILAd}z@8(yZ1aOBrN`(5PTwN2L@+(rw-=R0nj}be)U58x+)GV~?{J`}y4Y|Pq61O0GIKkRLl`Se zjt}D}56HPjo@l-ajTF(wCVU_2sCCz+s)vZ3?n%6@zA$#vf{E3k*t7-1tIzSb5%ZupZ@CPI90=ZH_?&Y=qb^l>gq~BfN0I0d(+*oTH1!jb{2N&u z_3x$}N#b4i6G{Buul~%FUhjJD04nb)e#u*k-naTD&XgAS&2U55pV4JSdc09{w~_C?o(e;x5?SW6$0cg6mS*Aw;bk>H;VOJq z&4v8H5!~m1{?ly890J~@?m-eFk`&8(427s(w4W1pPEUDulk7Umlmyjy84i0O7%_nW zTqiHY1=O86i!)ZaqsVES^TVn030%y_uq4Ef2%}OCs$X60d{+kON%SmIU(P3P!KTo% znAfFs$D`emY-grdkV{3soLZsYde>yq8^ZFbb>9f!mD%~B6$I$OZz?l{g6S_9g*qLk zU3fxrykTS(+ya0vLVLL(S9&hiJH4~y&_#XQ2^l%T}ynoT%XJ?Mf`UyF3Fg(Vu*GR2fi!W z05{1|fduq#6`K<^=j%p>Ih!^ka%dJls@v;~Welq^kT~lUqz>Yi<4GFQIhXxOfBhtq zzai~+g{$Ia{(H`otB%QT`3`{skp%^d_}dG3PJKmAef~BPkK;#JvN|gBaMOhj*fvRb z>X&^1zK(J5u9saI`>#Yzr?WkgfP%HHiv?>-O55~IKIUkdj6^-W?6c%vcddVQRxQRy zt8h(y+o%5aS9LR!+xaB)j0C5*9~Cs`v^sEsZdKAKRhOzGm@!#dvs*S?%~gB?Mwkbv zh~Q)Rh1?qiGp{nNTY_??AFCtVi}Q+!Z)Vd-*@@asM~twAt$Ih@OY&P9lLbiBym67N?O4nE78h0Cm-yQqdUpO=aIwkwaKS5nj$D;L7B+kvHzcrNzn9JPOjzgh*zxzt~%-yzzRuwkd> z3jBfsMDnM%|y_%K$zLOy$qu99ml){Kh{dni#;D!lXL)|OB?-!}%a)z!2XwvOH z@-3_J9NI?-el?m@QA6i-o&)FV z-eB)Si!i)NwyinP5lHNtji2#C_fTYeL@NmeY(oA8W8TERLdVeHeTo+t7O7$oGnoFw zS+4k(Jo1jEhThr(1cKx>t24$5Aot8_IqXPg9UV?1KnTXK^{p}b3YZz!ni**^CQvVP zoTiad(STzg{VD55aC= zuR=-lJI4@ap?q(R>R@l0CDw)O%tnu+Z9r4}DQD@5VB zL8ED?F#$>2Zli0!Yq*tBwXQX6Sm%}?t`kq?t@caFZ0&Qk^wi(5#c29YqySx?d6k5h z#{waUX|^tB;@32nK{Wbe9#|;ST1it~+q_gp*i5LRpRroqM%Cxd#hh~dGy2XA=-*^_ z(Ee;tv?ro=Pt~bQMwq)_A4tW9G@7SEBxIU}D>Mhz%wW>Z@0g&XTMG?qNkAR7zdwuX zZ(p6RYh2z95Tq~Hn(#1UW^)Ly!qIljwcs3U-iE3JtwoWhFY3*0(m}gEwE!k#(I&Hb zgT%Ay+U`{zX|Cxl>--JOIQB?y%TvR>yXy7UUXDVMv-H(Ez0Z~_j9T%a zs`-wMC#2Fh>QpZ6kEEnztm*S8nL0b|q%!ZTE0WuTatZ`EupGkUH_rgxt$7J2Vul|K zy9UC@Fohj}&$a3j@JXFURbxO7u*N{zg~hFUUO>%S#NpSYPDAFc%Tr6*1#2lH@vwP< zxVHRt)FW>dgHyW?SoSBXWiE`rr1_XH5iC*Mi#EO11$h_0;T z5>v|Kb2{qq1X~+Qz8oaV>_YM{sq*T=1rbqbNQM;kN5Zq{H<)T)ldvjC8@V z6WHB@*$ttgx>4d9M9?ejmTZLG9+Lwt5`3}#h=>)#M#bp6rWVqEXZT68fQ0vB93~ zzr?$7Q@*rvuTX=x8NoN^MpQ>{u|)zA^WtFCERRAu*snzhFZZ0f zd2fH#oaX_i*#V!a4U8(BnoFEef=Bn2t0#q5ODz<`S=o12A<2QzGt)s1%uInd2{n=-@n2=YfFV=WlO9R{GfNy9fxE3($v4|+6rMyG9Rx3*|0Q* zxq+ntRQ)T;Y6-P21PEI^zT4b`?=>R+Z>bw>fc%0}SPght37ssK2eD(nq6NL=5=@am zQ=d5tPyIiqe!g}M9sF9o@E@NZ^}}bE@!eByW}j3U=kr3rU_mNdFPS6+D zOn9MBp4f1rpqpuu#hY$$LY1i3W%jL>-8|<}&Ze<@^=|f;+9gC8@6^{2tPZx)L=G^# zN_+9KL4{`qc5@opL-z4o0=FXa`kM&W+@0)-e08r-%@Si4(wLKr74oT?AtE)He0Nl= zhCHQ6dr zg&}f2e8B{U5-k!{3h$2ISb??(u)XpFtYNc&Ij6?3bWOFi2)$0+UyQj#C;g6zLF(` z@RB`p1w5CLKU@3T`P(IqZ{|y??O?=ho$)gX1l|K&b>ry957ui zxi#p8@r}kY7lEDt0>oj&{4$z<{wCE&h-M?dc@x5_h#3kjJBL-zZr+K7ms`|=* zQr*jjm6Qi;r&?d1%Pkb8vlpxaXn>*qq(GHePszTJO(_`$3`X_4h){I8Hlyl*zg-p` z#y$v9SYL#FE&51|9f^n#X?n5V+_L9U?Rq5VtB)de zy`CYAbsR&|^}OmeMp$Qdk4_Kkzb$p0=t!LcuJKSpeofr=sXJ&~2$83D_Gh&MRG->3#bGr=h`2Y@Ex4=*@UU0T`tsn1SLiwfW6Kwr zQ>jM=3mlVYSWXdjG9n%4^kB%zVQwCyj^8Jsnp289gze)14+OXO+P9>`TQ18yLtTTL zBVs!7w&&v9Aeb$n_B|r1zM2J7VTr+*A!MTsSbK)78@Ya1)}O~kJT3;(md!35&uz6t z2LXCl3t`PhiZKpA)4yU3ghmhuk*!ZTMAih+iMsb-5_)$(k3-g-QsWOtN<50rV}Qgf z5i9)|Z)^^YG(7^fL`!QAJueyvrz2vjC#gozpJ6mn0%f1ETuuh9K}CK%-W4yqp%0%d)(CfMv$wfbS>8M@yu5o`xrM6H--OzE8i4T_9m*o7RO>bKIHl zXpGN;MygsuQY04VXNSgiuKv+>bg%ln1!0eM${Wk2FU}!?S90u2PLlTL_}=!0%rDFg zCtH!Lb*u!^5RdM?93zvY*?(Y}4tAKt%xS)qu3^^apav_GMP^EbI#L} zy&Ll>L&8_)T@r0HZ8Y2;s?nG1&AOFy#xgyVK)lDQSGwJx&XYLj)4HZd1%b<3B209W z0=%jxWU5}zX|9$6vnLZ_%OUO?hKG7wR|M0DmI1>Z!~L$DSAlScyBEPf=t<7P650)O zvW-`l3MkTjTm2#O7p(?dVe*zsNWg`_LnAEJz?!**a?BP!90l_IE zwQs{$4dN?%e0&DHk6~U85AZ%_AjikbwP_8Gpy`Vs)-y-SnFIA9=d2S9=?>;E1O&2J zv&k*}A~9Qt?~DFfIvmXWfe%pA`r9NJ04<#2Zx?_6gRN}oAcEfc?&?!wKc%IIs)xoN ztezcOR?v|8sT(^RX-YPS{^L`RT#K+5p!Vq&6IHY0h0@+^O6SRrDI-f9>>i1Y>hkDe zXxYrtEJ0@(F zDPVdL)5tG;i zP7(VWii^}Ap&I4^1|2kfaTv&pw%VT@l#f8mL!rx{H0lX0ePtYrD10uc@}(My)(r82 z5TuB6GeB!ggjZxRVnVn}g`r*vdr~A~EkYopza!F1XlZq6UUB~T_z7tidR*uQfeW>j zyn+!^oZgA|zOaN=Gu?c#w`T*O;ct^vNx}t(%ucg6v~(-COO|dI`E0~$EwTJdKjKMi zsA}D9a5dlCpNFOlA=BXZt`R`mPJUVGc%hdvLqevfw86RwstSea&uEnv5&j2|jg>6j zCV(gki`b;7*$nkXi!aEK$2p?lAk`e71~Z{l2dN|9WCz=b$C?8YP_>8&`lz6Cam2i$ zB!i72U8WH)jqL65y5#v(4m$=opD5=afI9|1`jU?bOh>)!EuJqRNUF#2`(H3T`-;Eq z5*}uR*OyX0N=c+3xejoBi@Y3s;0pNL4&%XsQSutdK3@O&Vn=19oW2RhZqUEAv1>B3 zdDtM#k;n%gLxeqEn5up?OwIx5s>65$AX&8~n4Q}A8!Rq;MBbmS&k2$KZadnaJVL4_ zX2MWcS{n^_3vt8Io{>IirH@myY6(f~q-_Z9;nV7T&Bb4Z{DC&Y#ACQ{A0%_;Wj@gA zUG+;ikjxA6eS$x#jxTjbjnv#)K6j+;Qb|sjAtK6twSrmF0(WlYu>BMF_8q!L>HEq) zm+MGsi_7MsgZ6YMl=$J&VL8A7hN%Hi@(@H)>bWn3kCP-SBw6r(VGA~rlm0^;MLn~0PcnB>c!t`s z9gU`oCg_ohX(9x%HK_8W&s2F_Nv3W%svXa)ri(v(ex77!#4n==%z}e~=Y&=v)q;xQv@$=IHe2~N z?b|BN^(e0}-PGM*=kdixTKR?bG|oHq1$$mANwHPUs$qcbRm zKp#rL7Z9z`(CTzLq6(x307ypUTiVP)jp2DZua*`%Xn|%CH1}X2Biqj!WYdmj-g1;e zDZra{4Z&lf7Z5-VOJhJKs2V^A56DY-WzW-Vsvh8jw2P(;{A$(FG^e3X zX8SNbx;|CM$LKO-;^Svf3v+8vcBc3e-Q0|2_F>NbH0S=0}_uR@1VmHSbLb!5veyOa-aT>GuafB|DL^%;i9w zL5t_|t5t!^1{YdCGZo5;dr`nG8$6aBhQd1LXlXt52SGK4xk#aYWdYe8Zw@R`4}p3B z5m%nSZ4^)Y*LKFYM_~Vg?4;3#IU~_rfR+SLm|;99X+BJDD(PZEXT;;#5zVcvvn!w) zsmaLJDJ(Ksk3}ohFm^ISMES}N(aXYLnRJg9F!AkC&Es>WALDq3Ah?M4^g^N&G`N^r z^&P12vAo!Nv136flTZa3qbzz%%>ni@l?>@|Ii_M!HGHc~*>GU#FB&X2NV@qRRUz^c z4b$F0tVn&f1xV}$&h4Q(ETn3out8`JJvsG(%r>A@bxEoJqEzN>Zk<&4OnU%{ef8cpEIC^*l*~cNcqJK$W5h{&);&S)F`cBLY9QM zT?Zvz&diBk5ojh8&&WVDH_q;p28G8jPq$mW;{Ghr@_nj@BD=?yYxM+nw z)Mq?vmwP<2S!XLKQ9ZdAWw{r{PWj!;1k|}lG%e*s49>1g4vhETxecV2E$s<@PYwdk zky+>(9GYMxG(laiiczwX#MqakFi1HFw=JV}7_+vKEU3^6Te2A+mly*0)EfOR{&MDB zCPe*wrnFe1?)y;IunQp&j<#EeH4kY(rGX8|%LLNFk-FYx z-Ht~G;uv&uW7WvB;I82TY7tF{bpwecOB&2pr2kCf5KcK?c*^Y_fASXkYFHQGZUR$S z+${v*$v9FOsawmWGD8H{wdxl;gm~Pme*1yI2~VVIgTUEA`xQb2+5bd+!G-#bUk;?FHE1R-knEAd~Og*mQ{)|7JDoQ9MhqVx@L3IH&apCBn zYPH^JPzj}O1|iBjT2klHjMEQP%9eKywE#`!>hK?WGX7u@f4c;~vWKfZ)Zp~feu1w} za=xlmn-4x$U;YxENl-(ux)9K%xQMRk{X4vo6<++VtaMiOn~ZcOr@e;gLo9~I1Mowl zgdn#|@tK4+jE{&m&G$vnC^Y0hqZ3VlRd%r!nSTkS>&yyg3tWGtXN&#eOqpztC-hm{ zrz&+9_p-?9ubT%)p|*1nWHx{|rDMP1xpeeKASm-355fQX4DZbRO&7tgVV7zK31$A9 zd(3Q0$xF-MeJsf?6{qn`8!wQNLzS=B70mNRraV!)ob`;4R=0tvNhR1c5ADb{ZzTT- zCuxR6ru4U+C*`STxb#8*Q@U~ri=6p~Km%}6qP~33c?XW}Q!j!%flLe<{B2&{Y`{A! zjfixhAO}|>0-2@G=48_<4jbzr5r*aFr_x!Z-|K!tpCg5>ST9x}eKJWsSFu{C_$wuU z5kGuYt4?mvvCeC0_5M!aek^f;D)8#<%p_=2dX2@?F4YKC%bAc_pdZ!+4w4wcEe%b- zE4!$RnU}JcfO8;==@_mDB)=d%0Lv!ws;`jP*(>FZRmmAZ9Q%b>4Hu+W^SPbQ5;=+4 zpsNC2dPl`jZp)ro@UAmUde1yTEiA5fos=Owqj3WGC4?F($V4T3gV-euh#@#OAkhf} zV)bQ>Fse2zeyqWAz^%c2-dQS4Tj);%6GE5C@G+g*BbM{Bfup2Tj>1{++zljwSFBs6 zc?c7e>)t`6<5L$4s?|uRH@@HyBtef*%uv5iJG`ky527FMojS%1O0}o!7wTyckldaV zq2A?KVXKoEln|TCg@0L&06%_$T8$9U5eGkCnxH4@evTt#l-@C~0wZriSd05=>>Z64 z<3lAC#TJke8Pif{ADSHvo6GUP3mH!IwL$8n?V<>&XTBK=(bQe4p$Pnj{ zOL>^#p`CHA+tIVwA2`=VYq);hxqe=*dqP%Q>2B(GIx31NP~hRn4q`rOy}HycM1djE zYDH=Nye_L&`@ulB(HgIw{rwEiQdTn;+m9ZA5#E=Muq-|;?A2!4 zY|LlLo76RcocW{ynnq5adFEh;F~~gvbr5#Fx~>>TQ_klxQmV*-$D#PX#xIp>K^usA zu{xcW?f4InDc%n(XOyvZwvCic0NKR8w5a+-+dWic9TVzw-a2i2K8NcO54a)^F?XD1vf2O~msB zFo1k8h5}c-OQA8Pc8Gg6`UGe9drIx{!LRaSFY0&vDU}bpWFL3Rp6aBLb+q{rRgk<7 z3QHHvky%IyNgshr#V+-GnTuvnw9Lir?=Tc7TTB5T*QS8eoCUjz=dw-M&usD9gRimv zLcpkBIuIeJ$LZYD7!X1G>onw?CgtAKn~HKAM(P!ABp~$wV2vJsFWbi0ilwSoUG;H4 zpP$qzeNJv|MIsv;MX<}*acJUB%b6Maf8A*h9lZV(7TcY6F}D>PS2FwBoY4Q|ob%HCV| zt-H5wpG!@qVsX~9W;_+1a(wIUVLHf#R~h#}m|8am?T@hO zwfjWMYxnhM2W>uJ0L<@*9{l9^69?rMV>vQMh7zr)ml@{G0h=I`H~Z|_TJ#}`!u*ZW zr!6c7(i`<#t&Hze_IPiT(ZccvkJzm7-d+JB^+RGqdzK0DUZ^`_sUifc` zKJ}Tp9q~D?{VJ!M)XK94PL-TZ%1fC3SIQ<5wYwNiHNxMF5s$8Nb*9XYNIt;I@nI~3 zI#KBES##(fvqUVrUxGelA)tVIRQE^yOrB`iOOSfQKR8GR`=q<{!JEsRM>zLcj?z4- zH?NajEeh=-bf+kp34+P+;bjHRr==#Hes1dYGWEyT>5kUQt!Zd_6CF zQPv|Vy`ttjdmi=QwUfGV2A@bRQR^Dgbxr6YYF|fjshCo|&dY|TS8yPxPu086T~<6S zUVvwsDDe~fP9#(9d6MnIf2U}8IGV_nrPIErjQskF^{;;$nm~l_6C0W~#D5z$Em;-Y3f;4oS$fcnmt#%4f#(Sfz+E{WG?$2fX9d)xXowN>;8sP zIPB43bsC)!(^i?}HHN!S-TNUdEX1wA!uzEnyjln>NF;dmn(#76fpoN5pTrOn;^K*r zrocV8bqJ6RilB0dIdZxb(UtE33WdatOJyGalc_}>QIj=}{ed@^9n60WWmIRHI^HM$i zvSjbw&M7YCy5!6N;cb?szx2iaY-R-1fb3zJE-CS^4@5!7_=P)rg02b0GWQ?(h>rOu zBuA)fSI9qo7e+Y7uF!;CdJ0&S9Ql8{e1a9+05k`QL{`gJkyQ1`A%A4AYAeGFPeg)x zUX?pH!wUrqea(l)Sd|gF-+BG9JW1}(+6$fgjdCwtlj1$xEbB7f*k)@6bG~}!(6@h< zn?hxu?R>fX(05kuOU`cb`LOZ%keuJKL(BYBZYtEmp_&lLyd-qj|K)~|`G>q2WKfdh zg+A))I2;>;<7$_^oqRQzYJIpikv($3u;j;ENE7I+Ga*ExZJv89r7{*a25Oh@wb}UGoVG z$VU^lVfINdby)!7rPz}ycCZfU1NTvo?N_WWr9vnIALL^(Cb7f7F{HuuwQQ=`!5QC^ z5hVz#>u%*FmksehY(-5SX}nFW3pQw(%53E%)mN9knJ0k`R~^mf!m8G~-x+{4`TC%o z-(6Zvq%D)f@5||X(QYw>+~PzCjqg@-p#n2=4*`GG27qM5k5xJ_E1G&V2k^KV4hSsd zQiWpNMRe{#V_+0=J?h2_#oV*~ z7t#apwoxsd(cs20tS20nx00>QHrpVh6M&GRH#%W!BZN;gGwQ3oAdEW0x~nw7drr2B zjS+L5jT!I3Ct8)r!~dv6{hJRR>TQeK0f{LjO_ts#&L4e={@SG)t-cZ z2?Qk4J(&g8v|PfaS~NhkP<^f~B5R>@@zm-$0=ny8l&?pZ2K;XzJtd}gxmdiG zDdTGjHjN4#7$O*RUYIlIjPJ^kX?rL z++#BHAFP!r!4#oSx#?FVwLlaEY72)cs7i z%#4t3Xm$CRDGn5XNT$x0&N8EITC9 zlwI{bJSMcQ4s0R}SMeRlirjs~wR}+;%^9(idt=M|JSY$nH>u}f)a8i0s*52)ZU$Yk z3DS)qOi{>DVgH5T0l-zK^l1@%j^3@AxRB|6b)8Si%J5;C3DL_NSr5 z_M$lcw*=6a03}s?CKHo=Mb*+Y=dmTGoG0}VBI-ur7Oh1KSFMs&=vU+AK1*)7nL7qV zcLhPXXd&Whzf9J4RzVId;qz)$tw`FF&o%Nuq6sE7H;l+y#EZM-)gq*|g=#V6EkjwZ z?_(cRg^*T2a&O&tr0>z7**u44ma9oLk|a^w85FvgLYk*OpiAhF)R)e+H0ku=dB&4i z^qnid-2Qj$ezo#JA`n)pulbRgJ0A!c#1;;hK!n+@;WBxgB9?a(_DM3cq{UHxWMgxQ zJGA%uedEA9ldv`*@*}_`o`_Iz#C<_D7$SD%D%zKSOH`Yz4XQeb8c-^)$N%t>*}PUS zU5|aZ&Li@iHiY%+Yj$t2*LxT({2TGj1u`xR>l&usb;T6&6$scj4-ZZ*r@c@B0ljO_tp*GEk#37XJ_P0;wLQIAP zZ#$h+F5NM9r1)v=A-tamTYmbHV6guc(bAgcn>f`M_gDoJhpb^5Pgq!!%;qhr?Dw8~ z#EGujxR<;5NrrW?FMTv)F|0G~QT^WWymL#!r;9ng&P<=i8$9wJU6SW=EGF{Ll2Eng z0T}61B)&k8{f#w4yOgdT;sdiiVX@>*JkciHyTmD2~m5BYJT{ zE?C|tN1f<;ED;}u^I?IyPsV-mV@^_o_=N`4Q2wcsy$tX(%i?J!~yHw{Qok&Mhhq02BvDe6wBl_FX=+_e8di)P| z6}|{1V|HPNSOmlUlKF1p6})wa`or&9!_%BY{awCTQEFitJB4Hx$FyGms*i>@d&oKc zz_=_EmG~$xb|j4!H5c-1Y2ve8_R#i?tAgNg_Q%psT>B-)NX|YU6O3GXTJ1+7xoJh5 zAjgfSG(}?{OwS(z7m~h)hw4R6DnYKyU!<>|wL_({Q9|0beUXs&({SntIa#VBxd>bp z8^P`7+d}DXfiA+{pwR5Tb!6E5NcT6?^=ZL`uF!;+?ah&4q=z`Yw*VeB8}E>T0^d<^-OdcKH%ITNe#2MV6mkLMPF^ZuJoPbO?vl5V`iR z`k3f|)kFNrxfIDgG_sx{k)|UIlc32TqmryX!kD=Dh~1>)FtRUVoxUz)4hdO9wAUa( z_6dijU8K88oP#hJvd%`8Dpa9idNNh-EG~|i8zQte-SP~Hn)oY|LQcuKlI#gc08uje zkxBQ@Ooeq?6qZBgZKV)zQ8Zi2_^sGc^-YU+$~@0vG{~=3Y@D#uKnxajXY8{=)=V#( zwlff#GSjs?zLlNyhIncBP1senujP1S-oD*o^qNFvSS|w&Sz(v2DqQ7@7gT)}GT&MJ z21GiNudYu$*6I0z_wt_)C!|Rl2~U81cs?wLj~VkUta^Jf4*su8(`GS*R<{iU(npW_ z|GnnCh$|N1V z*=IEMEv^h#y}I}`>3c)d>k(NH_lBv~?8ANGs#(6~VcEW%?UVg#+?PdWZ1`-#v31#L zoI`z!B@8?yAq(W`3!mjX-5kkPSFS8p-YevPR$HfOV>Mhfh*RbqCDqr|i#xrEGT*H*cee-JA3)I^?IBdunFko3TgBT;^5!rS2q z*{Tg@*OH^FdRp+pEgDkwZP;9o0142Jw&McPX>T!_SO8Us&vU58;vHHemsT8tp#Du>Zn~Q&X-ZpQK}T|v-S0Xstv8sJi8-J zr$1%P>n{pTiT=pbf^*jz`+c)}$tK*tY>zBsYMMJ-wKdYTHs-CjVu}6rRUa=N8ENt) z4mROW$+ihkf%K0Xp?O`yR!dMzBz$tf-yl0=4iv&%(GAQdEhUZes8SkLzlQvl{z_VxaUJ4G5>>uG~laC{wDoyoh za3Isicr@ zF;iojeVDayB;9%#BJ9r!Zw)*yhbZ9+`@(;tL!t>87^_P(|CwzH!o3@H$62!Voha7lQ!@CUBQ#PA0Lk*eO7%Sf42sunhDIs%)xH{E zARG$g$Mk#eq*_m`I31)~DBYWRO=9hW_)fdf?Bl@|x_qzwAYz@&B{DWD{h_{tUSm3Y zy_4S%79#bG(7Bqb6mC~TGz-P@RG0mbc(+<|oOtO#Fg{Xk9zobs$q5!8U$Hrp=Vfnq zswbiToQESS`qRe^#}==Za%{uAip@e@Ai6t$1IG(l&gQ5MrUX?zCVsJSe{)u+82P{9 zLtO+5kO!(?*g?5s`>Lanha!5Xf<**FhNr&Ws~#XSFkDRm4_k;EDh;r4!saLH=X|P- zad>qirtJ)AQn@yiO&);dKaPpP25h8@IEE|S63)JSm5_Rx|4mCyEwUge|2%QOy++he zJ%_%&LSBEQcKzlc~O-zKbPv<{^=XoXv8e2>TZ3!W0_RcwjQVGl>>a^3i-ny z+IjzUpS4VG5jBkr`RiY0E|zg=zl`>IB%4R#s*7N?X3~{+DB=+utq(?cj1X-Y|C1;p44Kvkg-P78lfMeZWZQP$UP9M+TAiNe_>J8KL0(x=Ns{n zo#|<02*^)}ZS`?}xT<%_@t_?~ZPXewIy!OoX!hn7Bl{X59r}n{n(X!!92CQ4+UO=Pd;CI1)eE?LE;Av9TD7l<2$ zYnkaOT{3i<87tnOS;hh~3V$2AXQC><<->b>LzfCT`EzQ0J$~W0U5Srt{p}05z*`d0 z`F#|NPl;H!!JqdN%gxz-#9mI{%)U^^-wGbEZX;G}Kk9$y<$Payf#%PYhqp%4=5&X? zC5wm$xQG&=)y9w|WKH)>v%&|QOdaVZltFi^gS$`fJU2i3o#$LD{CwF|Q3!@v%;Ksp z|Bu%J4d#pIn$i6;Aul#Wl3BM*&XLGrliTx>y%W{FR4vZh#WF9Hj*T&2UCElb((SYm zp3s}^<*C16x4Mp!Xb!0ZYWXI%UfQIDc!|w#fd2WA&V$n%qgCHE523P|u)J15$^iQ# zpm7ku${-c1>#;?l)UDx=^K~Ii9D7PhDaPI z=vULeCN78l%h0l2mZub2rp%vu2~J8#u?PO{9CfwI%3T?1DOW=F-OjIeY#olRlaofy z>oAkVxEzAs$VcQ*5sm&1#kyQos$a|1(zU_~46>TqFIuEI=~|XvR00umFH#+c57wj? zrL}}tOM%r@MPNG=&!%@ijYLz1=Z7qRgx&);xK_>gli=*XWKPX2Sh!*sB+W!8+!_+0Lva_)oi%edL<+%(29%S>vM`>MKylDs5Y zLc>N?Qr0S7G38g%NPGg%JDo4e<72Gk%UoC0RTICl)3P?m&H1(dwi}_LonB%8MMs^S zF(x$GLRRO{XJl{JxE$n-gdU*)#|w6dGR5XD^7A5UF4HRoV4{CV0zF}?6Y1QiewOaf z>Su63$e8|p_4#ma#r$#7q+{r>=1xa$C~+HG0;>97;#s)^3ka*F$UfGv8UoPQVi;pp zcc~QKPn@8EQ0ij0d66$nP>K4g?-#!dYXVyADTyTab4qGKZOWNI@PaS%PnnCRw$cQ@ z6&ocTZuyk9(l+i|X!U;0@*21cAhi=#sxlX_rX6FG;~BV?W3}%H`5*3S-%;;hv8}<} z?r(dP&-=Z9&j()o?Z4)RH#^R=W`0_p-psM&jOHTgIYw6qvFz0w3uD$P7WV>EYla zmg`n3v9H#9)_;FjE_u`a-IcG$exx4?!{{^{A0Aq{f%v$qu2$1s_OQ@O`CTPX(h;Yw z6QwS#;%HP7cSsA(;akSrvXZE~)CZ5r1THQ$)Eiu7-Z`MV&0YkHIc<}Fvu9A0`UCQ) zf*Hpu#O zBt7@9&bPyaX` zG{1*@xKVQ8)PvrUoS5rKFM|d95`V<1Ee{c|iFzVtZJ^%5)z=7wt6qym!sfaVq10Ti z--Pz=tLkf^tWoZ8|6%i0d&IdZ&tcB1)?K`+w1-uF-vW3PW_#^#s=jZ9c8U11ui9VJ zoP>8(SFn2!hMNuODBSX#V3-n;j_&iudk=4_=6e>quz8yT4~@ zz6n`VWe~lsB&c)-apwVmdX5}Wz&L5g7*{>SX?v%+=5|LHqOKr9PNs$;;l>U&9 zLw!?ytfcG%P8o0@E?$C7-}otM7IqMIF48m|RpazvPRj9`kih8WUlcE|61DAVAm0fc z5s)2Q5}OvCu#PAb=B||CHeZy&>L!NR-pSiQyjW+Q@~K^`HA&~oXemw;GU4gIhAVnhRouK zc-W99bJ9neE=FfFwWQu`Ekd&Be0FhBXyU~_G)~rSK?&gV2R|DS9^Ose(xB9x%#zr} z3rI?qUJ;d@z!qk4r_kq$jrL_BR39*L$4ecMg!h6=#P)>}M^Zu(ZCBRk--KjlEsuuq zD3omVxwQTFs?|(+*v!DErnhlv_`@5R?CY+}bK-3S2xY+g4*_z7{#*4OCB;hjYaLR` zr*=Y&B1UUZGH#j(ax0hz=ieBB{Et+4 z;w^3$^wrDC)1R#qHc9Lj7ZFsd*0y-Lt9MPf+|$0f^|%J>TIRN191OEBMa`f%r1%=l zZOZxsp#Fh?^I+TuQfo`DFtJmp$mUWseXN6;tBdjl7+WWDrkzYMYC1DCUcgTtv0F_P zdBU|DdQ`;ff+@7|L|eL6YRbh-ghiC8h^7`76l+Nf5|?PxSAxT=D+3c=n(#*Z=7se{ zJc+wfGqAmYuidDOr!;WFoX1YW1qj`nWA{5@jjH*FHpUtTJyT5Jq6u5=VbN5JJNuIT zY;s*T7yHv8#V-aiNZS{!Dj)k}*9?><<^e+R)8p%)^JN{{m_)G~jgL;$Z0;Y&#fj;> z!!>r<3Fz2Ag=`g0UtoEs79OY@pW(UJNzM%n{T;cPxkXe{GvGk0pR1Zz(EUSZe!->XT!IM9K+g7hREUUqw|1I${W5dM^BHL+9P?1y-r-t`8Qiu3{BEUmXX_c$FdLFcGLhMGn%!zd@ zIl8>{%g(kh@~=2Nb?XLl2No_Un%6m$zNW%~4Ym?Udu{J~k{_YI+r38J_|4$xC&orr zPe#5*|HzggnFl@+w9GAYX73914snOf%L&2E5xI1&oW~x`tBt1aaOw{5_ScEUL$a7!*YCp;G`5b-Pz_gh z#(R(C!(5{|d2Q)ya-6GAj>fm@eSJ{=2cXLs1kQ!moXeqLq}oca7Eoc!SBiY;YPNM2 zGJW;(6Y0v*taeep`(!D)ykoZKs??0V%Vy))v~P5L40%njVj0(g89&9U=B>S)zDcpI zE+kV30WP=L8SXuh(RW4Q&!pGggXWK8}IlS!T^i56OdY z2QQHF&sKk=Y@%{foK7wzQQqK3>RSgf`rFO{nG+C7D`MfNX8XhMfqX7=#fj%~qsJa0 z!J^u)#7!w=UGB9f2tNfW*G*{cU5IwguA@`)d4cYtWA_I4-eovcK&~E(xFQ zZ+nOfv6o-PZ${~-O|kh44omF2%HO_;dy>@J^Ah{6iOo;!yDoNnX00xBi@!}mTP+AC z_TAub+s~>e_RaUV?b8?Y{B19Ak@<}-+DvN{_5VD=-^9KJ{%Wq@V~y8Dtaw>`9O5JL zUjO%#I$y%8S3>AZtjY960(=)=#qAzh298+kzh(1m$rREf<}YsQ<YHY7b~P#>iN>ESUr?`>N-S5wH?ps``Z5AEwLejwJ^SX zm@hNGm(2$SQi=P-c1Q;G&J!9>rk~ecYnRthS-o9#^#ui4-(Jo&Cl4zQzlW9w|krfpwKNB zO3SddK{?d`xBnr~1X~mNvcK&O4n^s7P`#UzkU>@T2-Tq0@qh~>Jb|FCB5y7>me+G4 zB|C}SgyK^)3vl9^xh<>uz<<{#z!uymBs4q`WD_eSF;=6ZX{%MAqE3Or?G}w%t=9M5 zURDobHj27G6i1TT6uO$7An$7B#LTXtU7E6gk7Z4797|5AVhQBfv_6uG6&LS$6n!0% zn|3e@#1EF*+1N0rW9n7*qjX0HX^5bW4aj(me31=a#Nin+yJ)jGlurdw(zVu7Bew+E zjif@wVe|E!~!)c2vnIq_Wx-9*rCsXOLP|fs}{?K7}vF<%(!xLWDy>41h z0ZYt<-Qu_ixg3JfgA#^DTj^@6U-ClW^ikfvJ*lD#|jvh@CqFZ$5~ z?oyxs1AO`iW=w8A;0B4C*s`goDUj*VFZM~cCxg+^nRDn&rkTebjc)DqxNmaI&j}PC znVLT|weTC5lcv-{o2BTrFHOyteb8rL0QO4Hrh@pzc8z?MT9~!RlN0AjrE&b{KcUiN zsg!agN)YtB%O2wtbgL^Eu$;LE*lQtdfq4JDI*gl)&7brwPRD$^=R`Tq{x%YZAkz_89Qv1S;n z?*u@iR$ZBn>ccos4LjrPs}pGj&2cY>93lMrq)@IU$;meRyE6V1t7E*-|_Yfa5+IX>r=A!W2YRxZ?dp)s}QpB*WW5`2q1dG$9Mp*h^e?j;B^<7#I zfXSkfOUzhCXn;NU6VQurOinx-REOK3?7)q2GW7JRZNKWzrl0--HTy*nVjRTcVdTGC z@)Cu}T#;&gEAjCG|NUzShJSyjZ;ik05#C5o%Op)k269D;RZk=zK=!rj$*~cU?5ov5 zl3n77hrwKZEh5wBVF{S5foS1wfBVk_GMMW5GQ%X~44`qh#(iZodn|I){5F*Ql+*z7 z7PvR8+XJwAR$=0tpufJCG;{GU;FX3{)z|tTUW1ZH5@@sp2~NNd{-qCef`uiI=AQ)3 zSM0D_qG0669~ zBtEr)#;OfT=?JP2TYjNI)V+^_p9_^3>40Cv&ZmSm3Fx?s!B|l!`L#PoGd)f)Ap22j ziI~8JY?yQn!ELd1k+J$Oz|kP=pBdsTd6Oy4jG&0HIrE9DuiAuQGP{;-LjAk! zhn`NOr(etbbUY}%mF@*AIbi0y;}g|RgfH|^Iv0$O?)U!k^KmX>N#0l)8~Q`cg^PhIX$Jsw*hEnE8e!XpJ0Y=lRs>nuv?aLte`=k}k{NuJs>- zi)m`cY{Hi&d zV~4>TxF(Y1397HeK4bOkx%c_b`}o$(Lo}v0S*%E`#n3d)E;Vq-4?ATqae!Ad2Gb0!grM!qAznf_G$mG@%S zFDEKPo_k2G&N+(Fq58!km01+k)_ z0z>fA$keZPlwTM#tG-7Z*ylQSl(XW6{BS^xL{!8c9Vz0SkF@u4oh!^3TlaBBVP$9XO- zfRhH#21#hTmgSF);mlhFtp&yLsy2F3};T+LEZuH{q*@aCI!jjHQ(eX3i}I9`}Dxdm=3sT=sv$8_jF zhqe*&qSnX+pw^|K5h;kxd~VbS@Zl7=odQ#VM~9bn*`AK*Fn8PfWxm*iWM7`Z+J;`&Y~1j(o#Hgsl*qF*Bi z?KJn=PqVtBZyeaM$qkM*xO-%Xxu zR$0Wc$u)TqbB8KtYQ=i?-An1KGx=01Rx57_MV-qGQqobNwOF|T+Zg7cQFGAGqy!?( zdRIoQM5{|BImI-0-wHUSk zPTNdhgS6p$5mYtd!5ur>k)9t;mFZeOg>6(585@EccDT2Y#o;S)b+ASSw~TYC$A01j z1^IIa`*18EwwF3EkFu5woR4mnkDHFMvP>jQIJLQ;vrnfO7d3Rw789M`s) zZ==q)XY*~8q|p&`KT0ccgTl06r>b{44y+T@B6Y)Lx4H!Ql~^A;2|u`Ziz<}@yj_FW zIRr!%Z;2e1@=W{>ajv8-89?m+b;ZU|M^OMrg;aF_tdz_Y;)4>iaY4BagLy@?k22FX zQVnj5`bZ5rRH*t_Y{gal#Hvkn_g1I7_izfCA5Q4SDqc+>9F}w%3Pz$&HqQ+o5x34 zU621WNd`g)JW;l=1VRm%2xy{EiAiLJOmG4TVi83YMWceng_4;BL|||d&14+4)mE&w zT9?*}t+XOSluTHXfD5v?;2KoKJ3MTH286==-se7(fc<Z?gL?tiK|`y3EMZ3k1W21Z$CWT`bD2UqKL{ z?a2(cJR9#-VSQ(iEn^K@6^ExVl(yO(3%f?@=`|5%OR|F{Bh~$%i@;Rd_$}&{!>aTJ|y-^ullaSvF|21>=B1C)uTM2q%8l~8@->MAp@@9 z7n(r0j(w;Gz%jXT(~=zIeDMZ$Q-ZIr3ckLK^z!2B0fhxd&7;&;Sn6HKge_5b{}E?G z_GWVllFbp-T?+5;-fYe(toCLXF82P~yfNOMQ8OD{p^Fr?MX%=>P$Wfv#RJ@UFMtA3 zQX2)50%a;xm$fl&dGQ2Ga$8DDQq*G)u>B072=UDmqJ4RY{0pc>o54e?9h)~plNr^z zM+%S5qAWVv=hQaOJiw-G1<%gs@$t*&=ZVc(LS^`jGTmob+8 z(pl$Cv74LKpKGW>T2qhnWa8dyKowFQ0C&P#F_oW52FKPqB$N8JTu z9^fxG?!HV2(cL@;kYi)DeF?P(9CJu;Li?uii}d0eez*+?_9>V5P@l{BsT-7lxTMqF zHv9F|dbCu2bOqn_pG@(lp<poc;-Eb>OSm*4O{V;z{i>>uN9*kPjH{QOja+Lb@F~D<~7_M8L}PRGA+O!!K$VdtrJx(wv$me_~< zqVMd)^sWpQXJYK`>m67Gh08;ViNDtiw1TlYbjeVi3MoS0*xM6b>)uusiwn&z^5z|l z%ufr+`f19BmKYq;=@h{v3?FDUuqZQz>0&hwr@sKOjWieT{$*OI+@@&`jXMtm70CMtPb7R z9k#!~>aX-o8_Q>-_U%3IOb6ZAYox2`x|i;Ho-KVr6P2*T^;6vl5A98Xujv(Cas}G$ z{zVfO(P!V~FWE~B_tuh{Ek?}(BnEj+^;0MKPb~7G?q&AypID3`)*D6d9M2Cc*o0teL|n4nh2 z7`{6JAyE1SkFAbO{>ndA&1Cs=r5&`_2U9w5DI;Jpc%)0&G@8xt6w=SvV@E(snncze z9V&JLd%LoKVgoFL)efT+&7_F|c}oQZ9|D;gEXsTPeqfY@_xLHe9}pb4sKv ziMB#cWhax4JRxD4rz|mwQSrE3J}CBhb02aH?xKI+#BVyk8@g>vq2nAWuQX~tlfj|w zODCk)C=8>1O@vEoNYHKkn+*8Qy1{pcY>i`aGhltiB61shyzyX-)DXbd7lRv5_))p~ z^@RNTM`+kxp5?^IM37mQ^S!5FV)Eh}jMZ=wh|{ILDXN4n$^-!?NduvG(%f(#SH6z# zwsQiL!W+tRj(7_CwDG=pkS;GpQ#y-M>Qi-+OiY$QSXvn;L7P2ked=47l}>9eOaT+?Z*O(oHpM$mwy~K3dk}ibH_Lx{$1x0>X&I9 z@XuhB=q@eoB6vjL&fw|jK@hZK5($x}ZlpDC(tM_@f!X)Lb#s3YphmsJn2eg|K>PM$ zcaoQ@T5C1Dwhhe~WA(d||8C8`ROSkWWy(Qvf|%Vy5l?ukD7WcMrDTfEki^iUv1$qX zlHMo9d(Nn>FqPxtpMJLH%4x;iM9Uc1T=BnU7)gd`c1NwlKImBBM$IAQFtYLg^{>*Q zCVXoITdbYA@jbTOJ@Ree1(1jqGU`s!St3*9Mkg~tfub$koS{eIu$St@8NI`z|33d|U`!bOf930=0lnE=_tiE{Yf3~`c-o;yu?qfPwR^sBajmM5H z(Cls{*1k<*S*UU>Vo#%{nHM;TwTu)R?ahL`Unc&)7wH>HuF>1oDB6=9Ou{xn%FU0( z?j=)`a&`W8>3EZ~zR)fhY&gfBE(<#od}h7dZm&bcv%y(^G3Pa-=4xGf(pa{n?J~4u z3uP2V^R^DN)J+jNc?|b)b=@w~u~N`pm)Rw?XpLJdii}2@<_^z-;VsIi7(B9wsZ@p} z+jo-#jat?AF)SK4KGfk8{{^w= zj6{bq`+=fV(#}HOF1&Ui?|M1W1|quM$k4}w zGin_?d31^3J&38VROA8Xh!nZGHsZcgu_^B2?HcHDh<9#2I2zf!1gDoH(uZ4Q zj$4(1R**#=RwB2PJn(pzN*A5Q>r&E+EQ zKc~_5MY%0f4_}XbIs*Cfv?dCdA04AtQlfwCC?aQ2uaq%rhL9R_TABX zcp)8mjD<&^H~?g-#3A~8!?kXKI{Y@rWXHj`0Zz=ZpC9w@p3o&7lJV^t;W#Bb*6~SQ z#H$X!{RQ+J(l?e>7j*nlJ{4qWJ$bS0FJvLuf6Eo(K#h1s_saL*4C7$NP6Gcw><$t{ zPhps}G{>uD@Ux{QIv8x0{o!6=l4KS7B=r)OMv+ufp?RmGJb7NFKRHfGU9FA*{K!A% z#i-c>TO68_6`Yb8nldstB^$#tbFT_B%SK~Hk`!3BN$~b8C1kv^eg+DALawy>wDA06 zXt(vlq^6bMB&YF*7H9G???4ebGP4VjlU<8e!M4h7a0ec=oy=BIsQ4olwECsu0sL=q zR@o%AhSbobk}7(IN#XG~Zw#Cmu+r^K4xAYH?`gQwMoe%RZB|dtaZ$%$xil|y97D)- zl+qKVQx!YJ`H;jr5Zx2i;B6PbeR4dSv{O##H98%~hq6koQ>nA=Xyg;t4F)~!va%G% z3glvv1Q|U1?l7Bn`N2)Dr(&DC{(kuo?#<57Gw^jn>}}Bx3%mQ^=W2cRa1ZtiRhiCu zSh5|?u_rmYY;fDRyT%?D`D?TJQEZFv82XS+qE|At@$Sbxjc&sb-UawU(O2{P{rsiUXHd@6%yk(1W z#razm2O#~hY|-eBcl~g^fV~IhFld?OsqoBMnaOS2(U(Q2fng0S&S4hHR8Iw$V2fv| zxs{M{oK(c#HC{a#XiW|-#>_6Jd~9x>V96}?Dw`{wuC&^xJO67>sASgS?k!2lOSm_) ze`4;}K#vo}yaPlJHy(yS(0E2rmUabJR;LK>fmH~ncmCBloCtLM3idj z%`Msv;c(aO21B-PK~A;%)alK>T!N{JkM8`EWKQp#L-9Ob66C&P$vNtg_ra0y6jTxL zKJvXF*$ZZh*342~KDpXAWx9iNQbkYT_tF>7h-t(-OE$ZDM$EKfW`&ALo4an7eBRbq z`jZwz-X5%#myS+t^yHt8W7pKmZe{uw<_EKDS@>?bj-jjP(N#~*>F|wsfAA%j=Nt^2 zNbsfxP9%DJ22R+0eauwiN&q>B1|YuH(u6!t%fyh@79Jlf&3`Xgk~x0{c%59D|E|;c zT}vr0L!VghOy25qff&MgK2xGK-4c)t&enjGkblq_ zp{)NB`Vi{#G_`p``hj7=oC{c+|@RksUcOoWpF~x?bQ8o%1yqkT2Jtwn$eOD5V}nZl9@PsVR*uH@zmOxKDv za_VANzRoXb|E8!@X;C<`I#psR>osm^E9Y8r38IQ(kJQ0dD}(4Hl54)DMcM6wr>44I zAIF^dIn%ZzWl{6jrNKQM1C+boC#vk;DtF!Cg*ZX`*sAsGr9zQ6th^A{7m0;Ks=DHe zEx6N{7TE0cglE`W5^gM9ier*yin3qW>k?av?Y4!zq`VAMJtyVEQyu2HF8}Eitjohw z6UdU)QVcQ&w~2*%;CR&%A`a}0?56;n*L;mO`~7DYW2`wklZoWI^2Gno^Rru^CpQgc z*n5UD3Y-5Qrsz$XBDIzyC*X&Qc7k8anqAgS_el{q$2CX41SYP)DM-mCZx0?4e7*Ia zEcOjrS07oi2sLE2?Nxo{(Y~>?g7dwsKxC{0Eoevaj$3!5Fa-k16*Dx_-eT@kF-{lU z!W*kMN0RzzaJB%>8J)g~vmM_FXaDj#WxmI4^7ZDu0FL6~qI?TJsz_h7J>l%YuuDf;`yVYUTa z#h_TrO3!buL}=qF$gUby7W^?<2$oQ^?j3VIZ8&`C;bMuS-i-R(=1eTn3j0^R;y-zl zcNI$@y;CE>vg89GX!)}Vhetw0i5mBwJ19g10|jnl5INu%RJzEM+@s3b7Yk96=%_V+ z&}mtzkLWaCU$l7W?@t?s5k%?O&dlk9%*5pBgQR5(vxQ^&jIY$w?i`ea`o}a%Ms0!} zbcUYD>5KzSugDd8D%UZSF*TLbp?M9y``~SYI~!fVyg}5|aYLZ)9^av+KBg?^8`cy~ zorr_6Q-u-Pphqr4!Q)u7db}2x*>ZDCFh86`^H8%VIt=v306Z{z42BwKE%XFxGe zR`vJfoUo*_vA0z>4qh<+D4y;z6JcD06SipXdW+`TWN4vZF->m^+m3ky1Q#|IYugzz z^xfOc;Ady-8W~5L~EwUyJoJ8ptJrboCdh6|bP&N?E|6Nr6xP=}K!W z!)M_!#68922|tg|IqyC%+RMz)kXoj z_K+iAcVNNv(45@Z#{4h5DXO3DNvnBy`t>uTA226V)i12h_UP!W_NJygD|=phlTeWp z!hz<0T-galH9QVNwp|~bBSaHpc4=1OHCwi~byAS6EtSr)xe4%cwgIT=(HF^}o%&j4 zg|6WHntRlE`-84xA!0AWIANLC?86qp@f)ctG>7S6HN||t5IB?zrR6ly2P4w>-On5( zmLT-6xK2ied;VV2;fl3*lkz?@$62gE4)st$StyqXCe$Gs;hfRMb4HF?mVb2q2WKi9 zXjO)v*LTc4XaH$8K<=eRd5_&&Z88x!4q1w!Q$kRNWHB; zU8ep{M}sA{Xanzs7y0Ivg=gF2>TlnvXJnd03h^Bm*JU|-)x>5*aG_B{sE`Gf*W@p_ zNFVI7W(xN1@%t?YU|5Hx%t*aEe>Ss;Pu1Q;3>tmumJiV znt+aGXu7m$`ogZ-INfxp38K@09$xG{+&_kjr=z-=uycAJt`b5zo)Vf_*D8hP|8bS=Um%~k5$2Y~-)-Nf?dbn9?53i9U@bu^{>m_Z> zd$$oL@jQeoG{PN-qli3tTY@L>AMV*6T96xZj&_HyK;urtR9s?D*oIiMbZdBC4E^T` zTVop<7r$O^i>-%=c@UYm&ZS-uv<_?C#*ONs$K>5uosA&u8jt1NTs>Gp^Q}539}yU7?@01^ z9fWhHv^JeT955=17X*$k!Rtnq)$lxISY}UANtn98S@%k!pMzsiiKs(po+tSInJpmh zqBu0_w{IfvxSF+*kFRp07zuQKd9uftP_7+bl%hs`Re|6GY<2R&^IU;<#gZbGgKro1 zPCyd*t=0AqNUWkq=%fg5MRb>@F4kAI3ppfNxlFmi%Z|H&@nf~jrt)QE11@Joh4kH+ zS}AqhPaWc)$+?C>F2(6U=`vOdPewVKDhJCeepCh68A&sxcAQw?e&Dpa3#p^npKV&0 z+0h!vG>iHsg}s-uX;F{5>3hI4+?C(FWT;L>WsDE#vP|HE6w5rKMVL7h(<10+#MQKn z);q`&r9-!m-YfFR1zp=2%I|zh{_+ev$A*{aw7WxDpwrn{Y4Ef_JnqNx16D^mZZGsA z9nc`lo-<>)ngM?IwV@-_82`oO{wf&GQzqJyT*qAv;{h1H2ZPmG<;#^ku zbW&rRnUqv>HYu^q+m%Fx;yk-(I@fsWfMka@nO|$}w^f~H*Ki>U+`cb=!~8$RHd9_o zy9*fK;uRgmDrIkxV&BPSXlhlOx>?Gh_=@^b{vltKm>v1YD!T}Y@}(3^axcyePI8-Z zVm0aifmk(#ibsd0y6qeC->&W++?vx8Jj@+pF^BhqxFqsl-pz-o%ndkgBPO{^f{T%s zr{Y7cgZb-(Z6~XjO`z&`*MP(r__zW~vC$dm3f(l?6}l%^&E8MvNANP@p4@I`w;QsO z2*ZiJ=d~DrRu`6sU-cuW5fjA8>^J41+0$L2D}bdt|FH3Z>`GMRMj((EbH2XB_1cB_ zx4YAocC}pfU(MGYtgrkh&GCU>;L#i-6KDE?W!ryKv8~gD6 zSPhVZ@8iQZwl)8Vw>v?Rd)P81oYEfW>zU@j7-HO0OLgjv-jqPI(?l$>L9|lFxx-hA z>anZt&LVnt<(;nlE%&+eKUwPZRD54rf&J>CGCR6KH)IVdV?`4>5FH8rC#zXk!?kk% zEPfPGmzQt#;jfs{HN2&BQ6KAB~)Pz4J0}kC=DAr{eA4PSXhP%-dr2 zkGJGz^9zh)m?p*Ljtx$>*sdOyRtr-?~%wbK<^TBz<|y)mn9 zSMWi}1tw*89FXCrsJcm4lK-hO{?q)8i<2Y;VP$>}{QqH?Is1=g_N^j1lIw#{j=m6V zadWNGORwS{AKaK2cQJ#=m?O-vL8x)XTB5H*u>?WUsnh(WYn?62#`On$H~i0PB(32W zZJ?g8Gi&Za{!mgz-%y&BY9TT&v3lj({(0PCYz&-Sy7bpdqB94M53KG|YCPXOe}=Jo znm3;yfcOaaIs(U+`Z8kgL@r(d{jS*9Qsa=?ZE6`4&g7WhYLPR{bx|HL;Ds z*1DQLl8Lt#>&d2OG{RZ^mg}^q;2b#n?v5Y0reZ~RlH?4ki>zR)R$X~gMJd%xFN zd~K~xYY4L_dVQ4ZOxsj-J0@i8%5UQ4kbLKpPuq!hWEEz-@zNLAsP*Q2ZGzsY^`cO=U4R%H)f%^nFVvRh*2YEQpGGL^bP05R1Ke8VRx5UaBfyGfHIpc6q3KSTb6Wl z&270A2TSI;t@;D0LXOtl$}cwst^ByO{}$Ied2aYOJ$D-u=8mpCP-?ih`xj-l6a$<#M)IRO^X1iE)hjeq&x&&j=k&4z`i`y5@R{E zpkEgkBG89eUL4n=53mu@4mw(+_WX-m`Ab_$hTx8a#n)Ogk}0>TkpygrlMw$R&bu{J zg*OY8Ah0fh;(ca|BHyq%FY|e|%qdwr#8~P(&r>kdW;`%lGULBWOWr$R4dsen#A>49 z9^P*JO>x!zh)n7A6m=IZ%Q*huMscOUA%1s(8uE{7$+yt9a8@GflZp0{x{+D!C4&;Y zuW$_Ld( zqKm!QcNG=ey^{o#Z7__DSG)mnBn|*}Dqc{KI$^-@-huP97Nr1TS$Je(seKcAx3G(N zrIn6~0s_jNQSk<$Wi=g_1A;kPpBBPUzEUu!K)rV@YD01{)>@n{KWgA=LD)r8S=A#TEQbVr`@&J~ z9FIi!4alpSN?qnRt;LxXru8f^6o&vC<-m@{N3dP2yO_{YU5Ye%7L)d4&N&D4K;^(fQVphXbF(SI5{O~+vZH4 zqZEg8M=|9*RyfRuoLVMRDv|N=N!>*mvS*tU<+P9`5HDn!5I+6S3PzUVM$9)9u9JG@ z$or$zE9J6PSF4bjNTpUuuYCPpZU=H9%@|?U_if+M=Is@ph)_1EiWre%RaQ5Jm{jaj z^}IS0-Ap>$S`4mHleHU22x^LUjU> zfvV<@fI)rrdwo8yA(#>R|B;_qG@Nx7^g~(bfu>rWAcaUIjgs#Z$gFW zogrGBE`#DhR#cKTu()EMfJGy+HSOx(tS&)*Iqk)C~__T7^iqculbhX|}=_Yqe{zJ6NZ8$AdVp|>__Ers4!GriUaBK+z!@&FC(h4<%q)l{8VSAJGrcmY`J z^9YrzIk!h}87kXzgJ{v{{h0}v;v%$1FuLXdQx>_5!N3&1je}dmv#liOD<<(*5X)$Q z0iFSmYdU7?aqwh-lAuhvOacnj{A9=Qy-_A$`3abJfWp5kdK!+S^NN4*0+or1 z1{3ZRWPH(dtEp}c5-y?fqs?x7j=QePOaeP5EsiooS7 z$a1EycTYRh*Wc(0jM^8d`D~;)55ROF&HHRHtP(YVHn?Alv<6Ybnm`NX`9D zOO8@?hZY)|dvm^ip?a8}nCEgt;!Z3Q0Cm)Tl9EMA$6+fyawBc3@M~zElsNTiiiax{`RBx2>IQeQ3N&YNw7%^e3vet^IfAWGT})J^m?Of0EkQ-Wo48 zJO1euQ-R(u+EG$z<9w1;6#`5a4Ob>Y1EDrAU_?yksm3=lN;|} zGg)?2i=j>HgMuC};8Wnlkm}XJ;ycZMu`DW$+Ft@lltu5dmxq1Cg*wLBt1mES4*(sc z%HVoXShR@HaS=HLzDu+hx6~|k;Kq2yi>!>E5vf^Zu6Lrf%q0a*$k2KpqWmy^8o}X3 z7Q%Le_IHsan<(K{gUxz7lP#1?*|yM~Sy>B{hzyb~iulQKpAn)>!CL{z#v?ePvXuw- zOT1f)zZ0IxCsk@wJ`PP%5{UC1jcNx9gP%)#qqFoh3u_c*;^9r%)`!gYWq7m`GxWf; z7Zmt0Rl_`>`ZE71T*v4{Mg)`fyd;>Xrbh4f$k*`}A{pvShbnDG}MHrDaq6PbY z8*^im9W-#Ni}+pympihHyDzm|XD7h@I)Es-;N;0r7Tni3vBIJ!%4_AhM85LjObsQ; zG;xjfwGR`zz^FY=Et*>~Y7fX`d~5IAzzsLB5yGGW>K&+;EC%hcK8wIM7RACZ=yExD zA!}N@cwgYXMDO|K__GZjDbM*9@`LHD`uwXnTiu_V|Jnf*(f86?hHbu%)_dN8vI>fP zhkST+OuY?F)fs{tf>F$>!-C!aWbsEUG=QG&NkZyYR-Ul<2ici~^?ydi$Tne2PWeX;na8={$;2wQ>jWaN&$TwRs-Vzh<<+#bZ6Or>giu~^7vTR zw=X4>1NuYGI);a3OCMq*e+C}D#?nC`A6{@ex|Y1w}nRLX9+|$v3WczXuKa=ATs4!BD=#@klk0dR7MyMPHZH{dCFFCc&?<@!(!&HmKR_=pW?sd)DXh zlxIZsc%&%xhH7@|8|MNJ&(Hwl{=3Mi9kK)}_T zs&Bww8ub4v?oB?dzLMRD)3W{^Trr1iY70P+y=i^?cdh=FTnps$Y!HqHv{cg1$9Y^u0lK9EQMO1A%6lc=kBf?R3$ zS5;ILarVbA<7(OP|FnyGeH5@n03)XB9n3pAaB2z?kz|@SFAkiV=fm`x<+?-`C#tlb z@I=wo^P%A}HO)LneXG~DZ z4G|uM-3umVDT8YDF%M#_cTi?Y{RGx|Djw5yh|PKu?vhvSlw+1&eps~gJ&{ztL|Nn}zc zx=u#TB)Y2J6-pR-UIZg}uk<|=xfXB&%O3=mIpip>xRZ^V18{0tBAh8cBLRA81sVeE zzFFr8v3j9l9)-lUXKJW2vqbi1bA)&mB@`;xX3&>JF;M6lQ{5PEN4|#U6_af`b7Y~_ zreE3|!_tvr$>Ia{fG1IeL22rjFaXh9K3OXp;_>s9Z9KfV2cyY>7Mq_7LSqV*tXG1L zoLrv2x5|S=ZDf{6ySzo*jcP4=)%6++M~0FDnAGxZ)GWfTq%2V8EzV!2NTJfq6b?Sx zNZI_SM+PW*Mz!5&Gg`{AP8G1p1dHc|Ce0(}Va@l5g*2;;@I+Q4&!E{nIxjEzEmeJS zNGwJNJ#qUZUU76Tb2q8^+kILq;w+l*kLX{hFJAQ@bk*$GF!FJ}siW5F-tk(KsO0Pa zrJ}c^((A)UzG#tD%q2Oz;lp|I9DdUegWFQ0Z^muviRXY+P+za};|Is0 zDP;RORUfSdm>N8+g?-Q)ZLfj|B(R(k$Q_It*%h31+4}Ap37w>?reZ2bxRb1Mt!59j>mL0myPrF0BV+}G?}Y-{o-9g-%z2QC`P=hNDxJ)lP-D3{Wr=? zq<^}Jw`6HsN(Mh`9=A-ely-Jod^ z3!KXJr34m@v>6ZI!MC}^BU8d|$2PXe=#9KbV!Pow0LGK#qtCx9) z&*CV$<`V(|19E_+XXXpx%Jf|sz-I)^Z&nctH7E&&h z0;L`%j`}zj#=q_VAQscSo@9_z`6@HFlMgf@$-Y<4TJm+#e{w{WD>I?EA3&q&Es*u$ z9-~#IYS4Zq%IrGAs)(6$Hi;mcHq(fpqS*g>x%qhtU>WdIv_l|jq)WsMv2)|hMi z{*wG}jhYYH#ic#L=DZG^`BqZYXx&g!mgr&nhO5iLU6rJ}2sY>dI1C7-KWWr zrx)JOGCUT~p#DSQsJNbk0ZmX}F`Vc%y7{w*Yy`#&W1){1nt1A_WJP96fe{QzuZ-!k zGD?r>-F3XbFf#>rZ>OgFEMo{@E@L`ViM6Kp${c7Ibn@y=>gCOXkOUMEFBj2fq)+NU z3?guR28yqx!u9`)G%a(wOP^(t&vJpIBSpz6R=qCsf(n?7;u6^#R4!~auB!*fn%2z# zPDbrL)DZcz#a28Z!?=+I&Fzio4`bVb2K}DyMEr|d7nCq>D6yUraIDVar*rS0{*LjoGJg5tV zT2p_7M;{3J&!dhyg|Z;A5njTWC?uCsZwIS zlqidr81}!Hm>VylYcU6_!yFD#7eIUNt%3A=o%}Jo>L2_v;tp;$Vz>(FJeyDa_-m~< zH@uxb9m)LY6Vf)LMgkD1r$M`@#3Kouy49%tjt6~?R1Y?Hfap7jS>yY3S19obdTfrc zV7HYI(pbO7kF2ljD(H~FWE>RYiBJH#D-qXPJ3jx6f| zJ2!%nuW6X`z@B#*YT{8Ln(PE;ow8@Lh5gqO|2%paYNgJPlP-`6kpxZ&j>Jzu)`oct zD@$CH>o<4ZFFK*FJhJAVAh+5Bfs7OY77W!~lUZ#mD3;UNHS70F3rKre8s2h6rjeG3dV62GXrGqAw%3w^0{YicQCsHM$oV&@cHU>N2}!R}PXEP_DxM)t8<%+{6}v)}*w0A`ywoI-TvW zL5H;Q^xLNgMTDkugAfs-HQl=D$;-qvmJA<9C}cs8{F* z`I8}jzFr+y@TtN>hV=PO>hcsUO2)auYB_eZlFC9AX=Me^i}b)%cR++l^Skjb5`(I# z5w|GW{MuuY6gTX>2q83Tl4`wPEU#i|`d@l;BJV2=Y8^KmnSM>Afh0zUxQ}B|#^sNQZYzv6bWJV1 zLJwH@K5sr0Lx&7i8FWwtn8hPSgzwHuLQtNxI8_}5o$&ifgoT6ZUmCTVqvHEeC}fJj z?*gkjZx4wQ_<$*WXWa5xQ|#{6XNxJ6EEQyt1qQ)39(aVT#_D;o@HNK>r^KD{iKOaY zM6l63a0=_AizhZI&Ai4!|2E_ba;uD<#niO=@iEKKVpW#O7>m<%9%FT`T4QDNZZbda zFqW$BU7uk2WUWf+OnV{TjVdvqJd4Gcn^qn?Xx=D8NS6_MsE;F-myo81)IXs33e%;=y+HT9eSW+;nE4wRrRtepCxdBJUjQy)I&W%W3eRV7+?h_jD=znrPnV z#Tssvj8AWuNTDDHu8r2K%(Y@fAKb9)>)28;#kTWi6mKWm_b^EaP90rjC9TJEcBpbR z8rEtBP089Q=4ikYZq=K_0P5CW09v(HfNY>G#Xifqe4Gro78jD*u{>FgvRLEpw$<~W zoUNFs9+%fM8jZEQdctqkQNY?C?*CL&HzXdXqd)h(+FAS*R_v7NESs)6<;^^(*#S0`yOK}w*-o=Fsx_si`#V8H#H?_l%_YpUk`%6QYOQdLJUd(3P z3U3Xg@hlSOuZ7zWjlvKIsr_Ki=qLH2>~YdnSL~B(h+OtGPeI^WKKZ(fC4{#)`e$B* zx~X1#6yo3xy=jRIbw0u6e?gh}6<7kMMEHHbz>t2*kttAVf zHnx_MDtt13r-pF|_rEE42>(40>|@9)SyFOQo@%|$LvE@*1`N@YkV$nV)LFet7L43n zH^gnW>E%piGkx4-g5%SJ-z}e>x_ax>t2j^z19m2j=IIiGZ zY1rLNjOoHm^)`%Q$Z-j21Yd0qI&yeg`blIG)u_KvU`9s>SAEBXGv`iVVsG4t${~8*fmOo+8*)I|_L|VkE%M-d6 z>TpDC*-nF9^%FTvO+YVf1go}Sd^$E-W*`4gqvCH*H{q;7lCAP$UTxbbWh%z^ri{0z zWIY!TDQU*q2qNY87{bRTsR+z`6lx-z)DAfmgMSGm2H#W3jQS;PFsFc543G+$`c^Q;BwV>ddpM?rl|_c2Ah*J7rYz>H>kZ;T7yxe9P=O^Bt8&z+Pu$H`(lgfy2O*Oyn{JmUnB~jo6Wm;>+*2H66T1(&UMQo}_y0B)%9w_mOOi$3arnTf{neD`5b&L*t?v$~e9KbSZ%ob;pQK{>gJc0wiZx(cqyG{Vo5RvK8EEzx?? zCWm^@;WyoT+xS2sNx{#3J``-_iP8XmOJ|VTyhkyZgc( zG^j_duEGM}6Pn5NZxr$4aV|BzUDcWk7}I`{N9+OIp73qEuJ70w3GJmZBU^IL(2h2K z1P^wGewEuOPCe9z$LVJU?v&*2wm3UH(Js!Vf|GL9=i(n;m;)sKEk&|uM~B@B-GarV z3miL^471Jeh1PRkyDWY&v;R0c2ugCjUimWHkTJpVxGka+Qr5>m?m~1&mfCSnOi}fK z2e-ivHE@!c`z-{=i2sS30gI$qHmOMOc0@K0(#NQu%rkU_vynwx{=>Nl&J@QM`-MQD z-jvCY{AS57lIU!kI`*K9#GRF1&NilfEgnHKC1Q%d3VZ%0KK=s7dj>Jv=F)PB!A57) z`~{M#cdnr<#8iKeFBT88jgLM^IT(3gYK!9?6710`65Qd+uf(2REcj6YYgd~O*=*y3 zNv|j20WW&B6gin7bv#LtzVdkf$ zHuIbS&MPuo99?zN-@hz{g{Hkm0i^P9+Yx<6m+Rh8{z<9L`*q-Cs;^IrV;4GTHh+(u z{3JKrK`C={;A9V@HUUuS3L3uuqSV$nmRbaIEsnoQ0d?#rcoNLhgR=;k%e@!yG#aM? zciY-?RR^1Ti#xr&j03Z&oq>0Y}yfkjlb^5_p(;no9!*lHg><;CBS)Tj`Cm z=3^-8xb=l=8cS_#Y2Z+@>a&$9#hNdO#G^QULgMIbbE7M^6~|YsUmPjpvbF}FeYVK; zjKv%rIN8&8FY8>RueCmV;nfZu+Qoc_5l)tYrucu#_H~n}OKkk+F8@zCzMZ_;eDB3J z`?gq6>;cdl)9H1bQmEJIdMPs`nI|!jA3vjt zOsY@|DH}Kmt)7!+o)<1Y6gZwxO^^nryWzdgOjqkntmip!DbDohvs4&3+1q!%m9btj zPLbM1kdbQ=qGn?As`4R9QLoP1$Mc4``az-}>Wipb%4LD;7ob2nHZZ-E*XLFCz z9B5Wwg0r|Zj$L|JYnI*Ukb;uQ)Q2k3X*;Aw{z)W*y&ZzG>CBW*} zFp>e&4?YG?rZ;@dnlWnf^;>`6g;v8Kb~fBk8W!bw>ZSwgiy-(Hs?h<0%&fr40lsXj z$ezw3dvt$v?&PTSfNL4K84H{o=yO?_k9KB$gUorH$~MM5LmyIIpTuU7+sQjP3KEdd zs5vai!pJsoon*QLCkNrCT~D#C1C`Wo{zonAms_=**HO#M@mlJsMSAo{-UBByB*=iE z%Mht6lQcCKTX0%rK4FVJ4FZ2Dw=iE8pOY-__fi#hsB)d zV-Az-DRMBxo6XS`t&Y}et-8Fl)v=u?+i| zGNs4dvS3rv_#7irH|E28-REGvJ6Oo(J2Yi+1C4*-v#{Okt`>jj-md;0bE(z+Qi43r z;&HquD9-;vNjve|BxlmD^~rMDNJlHjmtESLlyzsrWUBbarR9HeY8i_B4RT`zuihmg z-kM4)4tUmo3*ViERu1uKWjzNS$Er9lQUjwUV)FOA*}SxO$Q>N@E-(15StUNcf{xX^ zamzA7xQU?>>Y^0~!a~pyxBO9mLlYv{J6jHa=11IkSvnG^^-^HCv3krCWLo<;7*Ue9 z1;&?vI4ZPB^Erllzfetc2mVWDlS_mlh*yq_Y{e;)T}oU$7@p6(-+Go6$WG&n25|l8 z{YDlCv7EsxKR)`s$(ree=cHe)ni^|{dD$kJ%x)c_o<#TmMG^u<2Yd`yqzC_*MktBk zQD3(}(HD{ib6oVke&`b}j^#T(;Tc@QV4&U2bP&b2`ZnSAPhKMj_i=a?VwYmf7!QLeZrlqe@@~_#85=XtR_8%3>ZWHfpjkK z00($Nw?lH;9X)8=iDiDWQL~N0rNJ-T9X~BVHc^UpG_qqD%qMbTFdZtl03?taH&|ia zLyjHfGa7cEQ+aV|{zrtlqC)WuqyB*K3|UtfmaEuS`ipA3K#JH8M$O~AN7?bDTw3L~ zlv|nUP3#o@R^!ufzCF5-%^G3Amdrr(X58jf?JK;=i}xCFI)l?#^-B@XiTl|4qy&78 zJrfrkZ#uik8-+Ld9x(sqV$n}0p2MKP<^&m$-bh_+_tQgt%t}1RRvx6&NVYtsz|kY{ zlLy)E1Qr@eg>1kI5MG;2xPiX2&e~P(-}M=*_66QUnm%Yy49+`HidM0QvDZr-v_D0| z0td3q=Djj(Bd`x%xitUF>J%$0AV`sn9@O!=#NvYO0d*VBT;uit0Nt#*>XW*}bM!eo zM{?m!M(yvUUTIM%M9)%ti*>mkEdric`WUspAp>zQqbH%F&dWv}m@nSlcQPcRAtga( zz>-wgu@(nZ)H__()%Am!%J!BdZ&xI92m4}4PYwYA0swn-23xetXxM91rqOC@f#Y$h z@DaSd$oEX6_Ir0cMs$KFm*>S zq!=sdMp8Kp1`1nj-VfZU6DGNZM|b6HB|f-L_8G2li5-ss*my%2&F`Q@*_0};I0Y-G z4@gfnh?WJmuH;fl!aIc=4zkF1bzg>HlHPOWM0e8;O#4gGys@P{MD&M`BWGvYM&=0?h=nEY65^Cc!jbnHFuB($R2qQ4pK6A zd7s6a07x@QtUi5EDu~%cPyY#nz&aknonN!SQ}E)WFQ*-I|wXo{P%TP zhlt}O+xDXZkGOoX$o4E}&tJ-BHDHs#+}kJbK)a)#)bE=s82%sJLzp*HXS&`w&zxAj zW%7A@Wt{3Y`v$c;+8`Neh>rNMiE=HDSMGuM=N&LJ;bHLKy@^*<4qM`~Cqb;@mvQ&A zO~QCczbrp?S~S*>$pO(4GBvr@CiCK2qvKLou7esEvqw-xr%&{&=g5h&#Zf(tokZMi zrK^X_G$HLh=0f9=le--pSP&Ik<4U<9XH9Y^nGGWgf( zI1qm#=$hjzo@<+yWDC78mZY>g-X%evJrzaGJaWiNRDVMl4KuKwcYH(05)EZ+;$^)` zBt%S|W4UBxqaMI*ZE|E5jVQ0kuY7t+sd#1vfDBJ?C}Exz!`EJOS{<+R zS@vB2Ww&{|0O3BBWPD!AzT_9T^2>QlKmy-96%Yi9{=qBE?+wj19}4rZO$SgwcnZ@K z-5ud~)Qrw9N&KxAb>i0y9WU$>d6s#z+z`-Q*=(T0xkG zpN!D3r}`%Xe4tm9PqMeWf7~cvUlF?aI4?SelJ*K{6@7w1v^&m~A$o6+<4c-4*`#^7 z$*hD97gA0@cX_+RWCO}J7p=|EVY~G3S-)xLlwW6U5zXN zg5n9kpTEdS2Ah^@`}*TU<^a+zgzO><6Sw!Zay?{z!a942E?5ly#?Y7xC?t|7i4>T* ztVMiE)9ijOL2%NcMb2x)cYM(CiB58y;0L)&u+R7M9_q6}eu9HG;NB7bYY$S)4{;XW z2F-j)zCcihvXf*A{=y|Vo+5E#0m_38mD!K0JUCZ#r^jw`-G_#wz83O!H&*uvkS~85 zJ4^n4RS9Ny{Cl`o5&n!Eo_w}lqc#Q7s=*f6gz)fe zCzQ-cdZ5Thi*_Fx?L~z=sqa37H9~r!&(o>ug89;gC3l1z6Zr}{B*!)f9hdVgMis%$ z#v9)Ub}x->4L|A!>6e`r=S0TpW@Ewzv>%t9IK^xA@D@jJ3M>jaQuxVt*!X+jvqBJ1 zunxQ*Qz0Y==95(Zg*iOr_;!vogm_ds5i0sCuS$I&xVR)a=Ge%qxfEe8YFUnYUOb_( z>Q9)|tHymIsz|UdFak|W%$Y@yB-@hn=o^?s_Up+Wxw#GV#!xOGzYD6oW-+apm(cc@ zq8N`@Wpa-x`M#71()mgx-+hwroEFDKzAZwJqD!5_DXjxl3k}z%%jOCuHh2eJskhvt z%v56{F93Q9gz@-nNDKd39qsWa@owRiz1L}_f8CkmbDrotJMkxyHf2sWwdXa>ksaLn zBh69iV|*6*VvFN(o>GKj&XRq5x|%I(C9o+sQ1m;g0xADec9#Ipw^Ffeh+~DIq#@7j z%Piv^s#PVxh=>n)S@n)GvWn`A#5O6ED)Ta zbvPHp3iT?IAoz{)u(yld{3^IJk^w;7IY)`C_ptc<4=>_k@k>0KDKFHYhLS{&Q2LKq z?^*49{jq?c#dU0xt&1=zjLCDmHKwxQs8SwLtWQ{1_&qY`-lc(7WC2SxYu{B3g4Hr{ zW9BF(mqdeKzZ+VFxs!*E!Sjo!>Z0@c7W*(y>~xhW;^NunGc2YCy*E`*o4ihk@6ZxBTT&P}AGwun|! zH>0JJM+q%KHb0=0(>Kual=LGQ>+>CCos5^a&Y z=?I&px^N2)LkEEavMmnZhB5^lIl2YB;@1B-j^b4sspfu_!T!yNk}d5|FFJ*VoZkXTgHqPD`MCLLz za`9~lUk|{xXTzbYy4}LN?bWTwd|gO0A{cv>bT(U~2H&aBzXiSW+N}`7KLx~to4R4I zP#BwUr^p%;gP%6$Ch3`6&Yq%^M2lB_hmcV&)mj&<5E_@+a2iDd*49+|?8Xrb6{XVe z+Rqk*q)?_->cKZ%i+fNe0dF#8dnCEVmeS&se(hBcx7zVKjK|(EPMIbBG=jW@RTS0U!U|Q6)y0d>tB>`EB8c;67NE0wA0Ukq6&3k`KCNhVeu2-3HVbY7ZIys=0ep}Ew8L+<<}nNI0^6jen#kOfxX7YL*HAGP05s z^+*foS-eK3gp<8YSZuiXmxZC!DatoMUNQWa*U1e_qg=7Vp4-&zzpy?`mf9nowWmw% z;kUBtB~Mlld8yGap729j@KDC@!{9&}>0*-J*k+YQEJf!&;f#kb+LO|^r#W0VcFT}{ zZ?L-lCSL_tk06(euo# zOP*%QQ>8pz!xNB7iAZhA!<#JE7e+9|Wt#-Fadx!h{##4&=2*_#p8(;4XhX1cJ)wDs zkK4V@$Wp0w=*;$54GiI?1(*2pBacebp^E`E7vBXUz%yXB^H2G@K$w%v{g&SO##bQ* z2jR>d>SBEExK<@LcD>nYi##i(vzF;a#9fFNR_MT+&K}&-UuI=^N-`u$2K;X0<&-U` zaiyf?BLQL$&b5*nC26>oqytEeU3&*k2~ZB6K*>WYgBqY|5%YS<@04AvMg0MB`4Qtf z$H5~Bwj&;6LvKJ`=55 zm^>KQL851H^aY)umf4vxCcjN6v7A;~jM_wyY~5gTngb)1RS17;zSL0ky&17{DW!I^ z^2}Ewwto_tV9mFHXRVE{HMH?0w`8wsl0%QZ1Jn}W<_X{Fu*+`ad$&=}p!z7Lf?!?T z!0V8DTo>`(XDv`cI_xggHu_|x2=ZxRlzOW(P0&!%GSy4ccb>9U2@5#3d5!JC$FS;s zyftsfv7^XonEX2%iQsFqkaacL8F8O1a9Lw-=sfP_CpHe9198|+t*nXRH(G1r8|Xvy zcBq-Z=*wH!MU2|#0A9msu0b1RTZpt@CmN=lr(gnmu+XNm0>H(k=2p-0#tX@->3WL} zziCsE0UFBQkI-Zy&ep_j5@p>XZo>`=@}##oV=0X$RYEJ(9KCT1O@46(ja(Oh&30pR z^b#*%PS3m@Yy35XZO4w{t>y})zU3?(t)jbm?XJ`BqQezmV_4JSRsNVd0P_%in_kga zZ}t;lVpCsDVjJbX5l;mOE?%)P#y2f;5Ll?X&#k#1gT8tqI1x$U4-gvZX2;hFrvzj> zNa`<1@)r3ePD7)w3!fXru911*>&ar)X@hjD%<5KP0sf1e>bEox@KPg;W*`83IACts_1%4PeJVL(lv&UzGt zh6)~C0a9HxRH*Qxk&R!^Wg7_AWGR549*~J)g{0ixTBEab+eKJ0$}Qn{ZTxq6{P#)u zRSUWbtzMP&5MZOmvIZN;YW2URtuG@-o@b>v_VBW7lk`J-@5c5?>$5wC-$1N1gnAUU z)u+LGRB&C@H1^Ta0M~a!!k(ly=39V%I$uv$YOq;7270SOOfNzGl6}|nHv#d=dQyqH zm*g80aZyCAL;4#UTN_*2%V>P9l#~elvZ<$D2L6NNNh-`6RO<_~PpI%uwyyN`P5KH- zIn=skbefZdKy_op7Czq=9Y7QG+=Idy8(os>AJd!{A!P8hE1oJ6#RPH?fBG%uPkJBz z^iLYLw3p4#Q^q;`8QiOfpW*T}WB`A93tN|}#V38V7$w<3CwWgRU?WsFR4^Z~XqKuV zKCeaE`NLG?ZVyctw)ewzvu4}_d-R!i0-#4TbFT`d%OaHP>P4a_p(?F+{HDSmm%y0v zU&bfY{z&{5(!@db7b2f~U3RbSB7_U$^YsmUABj+bnmxgpQ0Bevy2?~_Gd0F*Z^)## z9sFZ-!%BhJ{`4UJtu0_jhcQ!c5Q2strGdn$>V|Jb^IV-C4As%|(Lxqe2Z(@Zr-R`7 z;1hQwx{pI>ZEVRXyzHxe8>v0ycda|!ut23Eipi(3O{`OqIF|R4^ zA-+E2;u|@qUdGb3b_H44p={-0z4(jz@a)-31?+?-1^vmc ze*6rUD!VRY_sn4yHw#B4zF6R(rZbM3CVWuD-Qqoz1zQBPYO>(A)6Ot zp`u5@t%h_mFc~Ls%P)+Y*tA4AqzTPChUSm@Js$|K#EMJMMN?Yby(zE#31(`YYxS~l zRLeFAd^*^mtEXwEV`^mC5Vozr{!A5IK-Yv{#%++?{%HSXjb)wdH34~wm6pY(tChag zLC#MNH;|?AOxmZCcKgrMS|n}W&(r=bX|n$|eu>x8NG3y4f9_1XSK4(-T775QgPmzr zooSll`z7Bkq(vcijE0>H3>}nZNuI>eFfDR>CZy=9sj?@T=mXnwkAmEY<|){F3` zO|@JLo8saeC}QBB$jX|-bB{(vsU&?TRw|!ze;iXka&nV$%zT?#o6sIx`zoEonVOrz zdxbmtL$#1EqxNo)+3XvdmfQF{={}TKW^Mw&G~bbYW6Agb(f01)QB_w1_e?S&69}9D zL87825;PG|qNoW5$ssdv1`Z`6 zTpxW!DH`Qv2Cl`;c^*0EEgM{NV+Hy^gW?rvln>W3tPNA|CxWZI3cmsEn?4}vP zZdIJys+Kg2UA>lsm20H&HqU2*LB_zy;TQRtY#Q#Ml4RKg@(-aPCkc;kBtF@R1y%0e zt8N~OjAk3A$?av8yD;}?*P(FLdrsT9fw0gD`_a!_n9;_!O>gt<(e+6OLReGP55nxD zfT>g`j>|U2Lx_l|Y<6ty>-W>QzJ-gj@c+xeQy(Sr#2|p+C#q44D%tYKOVTrt4g8i$ zP~Be#w}BT>%ffT&6K7R-J=JM}qEYiJI;57cTx#J(P&dsfMdu6@7}*1~5b02sF{lC8 zsk~sdFm(0T0@)6_Y!=l81o0wVilngWkpv9eQZX97sDEgeg$ajO{RO}fX?1gbf4%uz z#_G@I-l(nW@AN=`dJ}Dm`0+CiPfqP$A~yk2^F&OFC|>UF6apCej?jT^K`!l@k?yP6 zX?Fx~c=>^l_jqY~R_LlYW-QzF)gioB!ucvBmAjdzgC^37HuV=6M|i1D_2f&MIIWBC z60M7KfzV5EY`qGr=k@*oUcC-hSj@Jnzl`qpEzDO`RF5pdC7qr`Wve?L;G}Cw5n(G? z+RYSEBbi)hJRd^(>eG6^7|0jcf!{~*GvBBe_+nP<5Cs`;LE{YbZPzozIJ}?|+E=~J zsJ@h0t~!MU(sxL3h3*Et=Szcn^6%wi=;VVHnob7OT1(PdR#*JUTf!@-g)-6FFej9% zcWC@C#)_%wFP{z#4dcN~RuYfsl36Z}Sja7SjX&CA5+!)7~ z{Ewd+^>HICC`%nh0i>Sf>u`?|%ntXYul)3MPU%}x)bMRx{e6bH@`wE4br&@XQTQxY5+jy zb1YI{b2)9IUF&tiz*$w{Lx>3f$Em!K(>3LO@d<~Tx1=X+DV3C&w4#y?auKF@VaDmvsYs<1!)$=fn-vJ>{ovSXPf}@D{?$p%r+&^#%6aGzOl@~?+ zb5P%gpw;RJlUS{q2dIry5fR8;bs^rr5g(MOb-X%Ts`8ts#lWq40P5#(I1kI~EP3@v z@9&b=fV>Lfuv<_8scDjSwWP`JOlwgeA{bM-B&4;7$5+8|f;zC^_fB*$_0oE~%`u-- zNn$d|EPhJVim~>`_3l253m7eyiE7dG*Xd)+^9*tMnipxrq3O7M^amXyG7gRqdGYY- zZ6TuN1Y^Z%T-%28Z1om)RQwYhNlq;kcMXs$9>=4Op)!DG_sl@Mxu?V@YW7`;mhi4* zOvI1jmo`QxqEoEBU_C{3V`mF@3yy2P7>}Ig`vt+MJvauTMN2w`a12oPu^@69t)i#O zdL35sn%hOnE&g-uQk27#ca@-2(vJRF-+d{lI(%Pl<`e29B{-Ar&aLA2u0bsD;@@i-ZE#q_Ajz^nS3kdB6YH3cuTo0?)5g+{U-+@+FQJTN$jyTtl)>06>Ld}>)}1JYu%)ic8J z$C3~cVmMVsJ90RdE;=BSK@VW4HSrnCU>xPZgxlDKm-B}ulu7&Mh7f(0=c+!5rxE)l zJrr%$N>{8*YqOjS2g8#D9c~qMDto3I6}%vrh2CEOu!}U5Fu2HQZbRWA>xp9(DATI!oFT4Nag{qb365wDC^ZYR%&>-%AQz<;sm1#=03hz; z_RhDnnNbZp*hEaq_8H}uf_6<<1A^{schv4l$|Q=K_Pj);%cjVv*N`45$>^=q-}lCH zXsrjAqkbiJucy?d!eiNM)g2pUicn!O!@W?G*wLr)w<6bA82vrs<$!y9)$zg8oM6JS zC3}%>Y1X2CAA?0FK;ua2k+-OW$jIT{21FjpO%L~snm;l=4rkCv@n<_Q^hO3?f2I;C znz&@a)LP+FmxR6`xuL^Zl5@-HS9ncEug!sdBz$tzd^CTVAIkT5B@yj)P7v>f9N^q} zReTv6!Yk^h1B^{3qHU^RRMgfr!*f__hP)kH1o)C}$P#mpWUMDSw4>p$td%(pePr^) zOEOYXl1{uh#hV?>m^d!^xpPB9+Dg4_Cs%wJ4}u>Ex7zJ=^wBap8kK7Vx2r$uN<;q= zJ(aKux(ku{ME9ShOk@zu^8gV=VBoFd8)U*SfgyPOVhx1u0IlDip*q96RLhzFKKh5R4T~E7Q`qEJ%v&yqo&Pw^YCUXA-#p7*cmTG5W>q-dE|uYYa21}n{V&0z`5<$Dkt2%>71vqDJ%C&7i| z5kA}#%;#^(%4bKFxy*Ndo(GU2^Jo9UHkgSIVa;qD#$2(-_ye595qc)lR;O7YWTOQQIfb1hA+speeKB@6;lD7U1XH91>;Ba>s)#vmKwCCq);Z|iwLEdB--9&}e&vq2(Q z6A6q5$wd>A0txqYplbJNM3aQB!>oI>QzCe;6>c2LCt941j8c_wTGO9$@C<$+!V0ky zQsaq)fJG}GL(0D?{DBmfl$yrZ5SJ4}k z`PA9<(a0e76KkH+L$c2!Lqrn4IEYy4YGwdp(ClL(-DJq57aFVg44iwOEOnlMT~T%J zbF9HKFVhf{_}b(fbB9U5j_vAqaARE1^3#o!WZ4BMjhYAOZhVYWU{P-Ylmas6eUQ2E zby>&N^Y(UL_^OX3VG5|%c(SYrEnyl z4wPLD{Ij}FM~=WvN>4}jb)-|hNuk)IlyItfgK7x%#NHtgkm?6z(Ry#Aww?VWR@AfV zo0tfO%?(t&AW1)0vZc8I%dZL=QIe=P5m~}H0*4_T)MUF_pj%!x9Bny(qCQU}jy#qY zM*Wf452a>gguV5u**8j~3kf8XP%9`G6Q?h#VkIT%NnvvmG}9&F(9EvS)Xyly2Sa2w zXY0ij_&h?42`N8UnmV%y^`xFhZ(|r>>9xLC-2x`H54O1mJ0nvYIOJA0E=!|(hho|k z9pJGK^$zz%(Ag4!{L5z16DLso{j@DpKHCr#ZYRA}w{{-Gy!rS-ZrF(lto`~kVC{MS z0BbkXx0p?9vOj})0Q)@v{~ZEMgVOb2a5?*={*AN1b0nXL1zSIQZ68^_)AgFfS8-(n z13DMBv!r1oCFE>ccZt? zUAzGEipxS))k031lOex^f|(@25SR<^Di_}e>>Wt?a%CEn7t0^6bdw5127(bcnA~GU zED%^b3=M?ZZWp##6fo}q&|*9xm57D;a<-qy`U*61Y|-Zj@E#6SxBf&*e6Ek|ZR$&e zDio<{6rT{)y&v?qe2rAnXQ4UsCi@sX-q&ySHX!-{=`R=(3w#t#x*Y)xZ!n+hv=Tzz zml6Do-ogzAhv^Qqs+ochu*zvs+wPK{u91p*8RgaIyaHozJoXf2pw-8SOCh`op3LWN zTfXc2_jjq~EpJ}XRpW+L^`D_%_204UHBLG3{=%U~A15 zAMQbc|HcO%Z*~X!ZQfV#Njz!uzQm@`Ry(tnizlt+CuE?Z)e>RB-a?!1BUaHz!QpmW zlghfXU(;SLwrs_H>#E}Ac6WUD*=2^6)V7sed3}?TA|eRC%Cjo|Wv^1~m|m0948&Z% zQH-?Bw^QgPQnf1D(~+9H)ZP|-C~8@lDmTOJ;(qa>1HlY%7Ng^eMfT9|n)@b5Ld!S@ zTCL+@ZVIi)U4Q}deQmjc*wLt-3F1cXk8F@cWK z?5#&wrzvj3DHdKYSZHv$Jv+;6o8pyuj(x_m<8%xk26YWy7{Cob(T4f!wGHQqJn0GN zyU;$olj75i6(M)S`J{_EE5^KPj*}fs!O%4R1!b^oy*zZWSvQqoWD<`Eb~`RlF-L?3ZeyfRcMosng(|1(=bcP2Q(SaE$(cW@Z9Uv<4JbeMaA8(twd zHlG2?Ql1BPoBwHH!Bh}3NwVnXR z9)F5(f*Tv;t1_kl9see|Yc*R%ohsz2)$B5eL0;%Z@)}(Ior2lwA*X=kWe0~yeIQX+ z{a>V)*8=GDZf>ZM+ziR9B2UQTlyswp<1**qMnL^TDeR|@We|d$*pEp8?GDS=I9V;H zq)aArl~i0Ayk&m>Vl#Mt@%Mtc@$VNu8k|`i3VlzHgeqe12%4fjKxS5UczT9ga>$Sx zlBgj$`snY7vX?pk@&-43wTwS@%^hjhrpCugK>^Fy<5VFpCGu5kYGv&EB*@%%(NRG5 zpOZwCKro)YTn&qzxi9(yVk;d~#jyJUdrFpBmzi6=CD^~}sm$I9 zrL*$)aXZjuZuL6ELrUule)b8smS`@idmIwo%8f%MwM!GB17+?VR=(oKA?R!X4;%A1 zW0@B9<;j;Bp`7rdEP^|r0Lv6x%3&-Y-81N(><$?;y^D#4P8URccYf?m-f*x-l-L;T zj8xzf;BwE%A{q&EMgh>S#737Xw<1M?it=?%grHtBtC5nDqUI&Tj++@tAtUmmEDllL z{0{E^b(@*tg_-W9ldXuUD=(5$I<}fRWYE(r^Q!KwvSJP{Ks60m>aS#-uZAUaOM5+cBgzv`h3JGvJk@3ljb8*^-{ei4ox*xM>E58-CnTIzGhU#VK;cLmqrm|iX4 zV6gT&0o+8v$H7P>GW*m|5q!uroMGTX=Zc0O!Z407m5bA@{0_@KqYz0x#_7bpjZA!; zhA|y6wZcO*h@C1;96R|cxwNp?5`g~mO(~AN;#hGZgXdVT35akJqJTLQo)AWZsX*Va zok~+E=a0iRrlqVy)kr2oym6(COHU=J=UoTuziGW zLrPHRC-9)gZJXfd8qK&J@g_zpWuuY@-86@lK}~PhNVFR5Q%TA zS~SJQX@>n<`JsrIy;xq|uofX+pz>=18>1Z>n6?K<7wA#H;$RB?ulXe}K;og@NWiUU zBrOQ5B|B(Aw|clxz<-Kc>)~EBi#m;Ju`eUEJ#1tx*n-lrc+^)nH=U?{>ANz{hQZv_a3WqV?iTjkG@itTv;gf z5C(l*{Ba^v(Y7mmG7(J4Z?}k_4&a;iH%%? z=bm5GTAI#I<2e~ZqMO}{r)TffkqKfZ{+7&QX<2W*EI=BIuArB?STM zEhU_;IA{|#677mn{W%oUJPrwS8#P94g5cBrc)7p$6HI4`aoZcwOQ1O~vuIOX|ianYBUO>=KRQjMYhh z-Jv0U-=)=gp(?fPNi#A93-@fJT26QKuMc;7jOw4$wfX2T+`(mpFfnS->Og^(W;rI5 zg}iZ1H}{k2hu)C&vBkVibn(ZiMmgr1e_^=01aD^^!;Mu&&7I^(9c-BxYIlm#Pp8$1 z!iE_&*Y%cwiaq{Epl5XNdt`25EKBNLag(e5W2R=pITA#xH9pP?w|ay(IvAb2Biw!0 ze0;X2WaxW}UMYHcqx4YxLE^7S16ADcmP0F2r0Gli z6OUWVTW_P=(gb7sJypiPTXk|7fr4Cf>)$t!?De2|Nquo##_uAOa9O@G3 zxv@$7mPc}PW9RaqNj!*D?~-nZL(sr=3!L;geK3QjLCmLujmBA#IZ*fm!3hyRaN`bU z>eUNzuiO$DT_dm}7h^2Rip&+)qStsALMXXvh`>Jm=v)TwhY`Ygt`oAf99@`3D>m!dXb;CJ-R-L>X!0L-# zPe3iP3x-8AB;$xTLI=Q6XYogl z3mPZkr>k*7fN7e9yedn}bKX4SR1;$rouml0a zcUqNQ-aEb)Rmq@1g8c&anA|wpr|qIQ8~zz0&A*@J;3s;h)6#qN3j0SOb^rapwb)u) z3e!V85}_{fYErwjV9W;XI<(qshv1NH#+f7%BY>X0vP#n zEbiz=Hr-Gs$0K8cQ$cDpgfV8L=r?^XNXI|~{<)2El$R`Uq?6k(872-R(mrk)=p^SkjF?iJB zm}V2Uaa`f<8{ZwddC|FCQ`w0E7YwOhB34hUhggTQRY&9sb|7Y0AG{JbhyiDz0MrJU zoNv6YLy2YTi(bx8=L(t_q!riN*gy(c_GXyxx6Ur*NQu5(&2Rb&IDGbLnQB(n2@GK4 zoT-ID$_i_!Pc7IMYhtQ^^gQlYj69T^F-pXW6J6PmcRcDJ$}J@Liau^Myxf2z+cCG= z)B!YThwLDn&|YP3(eGf3;G<=c>*^21#VaGBCLo;xqPf9iE{Ls5UFN)(aR8Oq^PSg; z%wjrWjR;5)`j_sUeEaf`^%hJmBlvisaIge>7b%u{%E@>_GBQF{(tfG*$MM}hYp3Y= zOaf*-5&@kt7Hrd?=2bcHiCUbty*|gy7CLc9U;mBjcPL0$=&$%$-D^RhCbNk_2X|Gy zl_dKmlr260d+UV*Qt$nR$(u1ts;gYfCFgc#b^L$mZ59X4;271$7>ze)3?Y7Q$C3*O zNJ8K^*>8WlOt@zF?KYJe*R%AuzK=51PtRm_?bDe*B@-%!*C`EQ_Kq7~^P+z~SrB65UE|{?x=JYU2Qd*EidIy95i9&`wkh(3%Y(Io znX_fCG!PrrL7oNZa_IGK|I2WKjl-e~?0MBtIwHPeY|avPO!is5;f#p@Tr9{%_<)w| zMTS{_Za?9D9Ra#}5Ue4roL9TR3&2vb*32@oLU{!(ltpq6>`-MOO>M_zO1$^I>IYzJ zLC6cQRsZ~l;QN80A>x%Nc{lXsov(i0n>SeFbuvM{SCDPD)NJ$H`vspEJ|nQJ{;KIB z-o%80r+XN{hefEMXIsl7I#=xhW9<1*1>a9 zcwdMIC)P2*)*$XXGw2MsOJvVw(fe|TswXtTTr2a)IcHzJ@aU@U3HUNF%_N*NC^}A1`C#6)MAuvjlUw4ZEy{BInwTEsaueC zuf(FuAzG(}XgRU11xz<_2-Rw?wZW?dgAIn$;p@rbORkyEp%;?}y34h(s z409(Sx~)C&cT9V~BqjUpONDV5)@SLW?s7h!-0H~|Us!FR(i^c{z(n9NU9$|b6b{MI zNfIj-0+$Ylo0(V-Ax)RtI^E53+eC6JO8eg8UWW}h3i^_n<9SPKJRABc=h9gEnt%9+=Q}dR-!{+3gZ^MSQ9pVKx0L2g>Q%(+QkZY zg12~s(%=at#<%~Fx8sy^RoQdZ#>5jc44fpcQ0Euq7$mFzl-2KiB`N>+(+xq;lAkTKcsxs$(-6} zpWp#DoA|@w#tSX?Cb2m0H8&TKM2NTdka}>YWit&zsUYIJxiE(y_C4AR&+jLC3H6! zffa5`N;J`!TU9J!&qZ`bfSY`(3MT}+2(6b#EG(qkv0GSEK-X%ksbvJ&FO_lr&690v zpKyFFtBPE~Y<;_TRK{o~)~Z!90}=fS^W#pAZ}XuTZTcd`ikcUmHD|0@->hkF_Z?~C zDBJU}1P&=Jv$?E97V1%wEnC;8?xgNO)R#&q9;bnb&NfyQ;y;~)(2dz`%C;9O+w3L| zEUIHiE-8%hTr0c`0eZAX7BqCXvBF!uE;!)28?%B)CmZwP2U&-UmX$|t1nD)`dSwZA zim9_*;R#;;|9$q62xl>S%yD-73HV+N1;nJHW?P${W!WS~HRuQ70JsF{2Wm$g(oRn> zsvmHkCK)SA-Jwj5U*YaFMUJ+80E%>hWF)MOO9!;6$#@Q=hKO0(dYH>M);z0 zI>_+Z|B!WwrAvO{rr_{ExFyf58&JJ2bf}@u*-1aWR014N2xZ`4J^?*YYpL5E!yFrw zH##)5ZhBJHi3vduU!+P_Qv4|j2R-24H2;7_p4h*1$+4jkXO%>O4H4>*4P~k zx#&=+z>K8lhEE6tw-Xy7kPOdl+UXjCH956_U;*WbctHg0((FKVx+f4_x<@@^z8$+Fu zDV{VD+{WLs5*zr9EfOX=QnP^hX-m1H|0u=*o`^2+s)aaa;Qa)U2~1j%XJr?oC<9AK zY0&<{H8MS{Bqt}nc~;s-DTzd@=#YIlI7s&P0m%wC=fz{bn#a%}ea3s_F>hqD2N1Up zcWpMiHm5b2IZZi-d^v~Bv~|9Mc9Bd+Cc_0b29pxtkE<75$|+AIb&oKMb(87Sce9G! zVz~HUH7p0~0@Tg-6uegNhh2VXR*Jvobnw#A7i6XpWTWV_Wg{G15mv4R-lFFPv=*oN z?5ks!5ZPr&)jNVB2`j4pi_?x+8i+57Xy4C@H@8~K0FeNq4ZM|;tU&s!t!RJ<0k%J(({R#f5Uz4Tk{UP~swejoEVKv$^2khcRTU(J zveC}-~fu{;u%$yDK*S*c>{@fqA^(%k! ztgo6{Q{9_PcZ=O#(2;Yfpu^|hN>(>n-A#?@?n9>gefvnk`kdy1^=7j5wV53F+UNeH zX}#fYHth}e;ew`|%>{>j?vI<+^>=SBC&<>1%~e|&s=2z6-l17O*RsZWQ`5S1_vXOz z6N*k5H4ieg=3COiw_JZL<36E}`F0_wb3GQ>8D_zj(g`9efLOTwf-PEd@|<7?xa(Pw;=yV-GGE(sj_u3jl8t7M6+T%K z+8Z%vM!sL+FW3ep0F8Je<}55|;ln+=c_Zc>5`omqb9%(QM@$gXdCsugCPzHaS73>6 z+C4t|eV_fFX&>=J0^S} z+z&9&{=}Dd#LW3T=cN2bO9uL*k9z&!1Wwu3bLExjd8@M~U*-ExR(a(i{mY-XvnY{4 z=H|x9Hg8OwO$p#OIhdPi!to{EZQ77zhIbf5Vxo8Mk9=+zp|3IN>j@6}rmwME0m6Wg z;8Px>M%0-;D)9P}8NBEya3pS#-+NEB?aPxy1%nwt9a=;NZyf^|73d<6up-EO)!Opd0H^J5w5-WtFbkogJ@ zCFB-J;}|2iH^Hfkbc2YB8Oe75Pj2N)PS5qhVR?M+y{wLx)k?P~SJ;oww0|(izU?8O zJ&k3We1|>l9{aKTSS4A6|FueG(Hkpdnc&Vv;oJzN6z4Z9G8NmJ2RJT1f|LtggT}x7@7Rmz(+o>h;kj(>1VZ@KqBgJl257C=u`#j^o_1?hp?kZL{v_}?uoCsCM z=|(K1j3tP)#aLo}z+MNb=@)2fO17HT4=pQLU(SiMU_AyP-Bz+y5@=fIwcP8=?504I zO0_nxE92-^&_ohfyDi`f=FmUOFe%Ox57X>`9TSl!z2gjpkU&DsAOr;jgmd7F_8TI1 zWOB=0`;hYF-?&&q+8ksRK<6L}&0ediaky2$@pyfid#ly8C17tT&xu<(pOh7R5`coc zDcBuoYT>ZcKBCNhvfO?zPyos7F3%zUSmU|8l-Z4C1?^T&cUeJqz}_Bkw@izAt}M4( z%iN!^!d1*ba5z!b%4yNw7_eb$o8b6jce2W5EOWNSI_H(Scb2ivWvnx!@3e%YwpeYJ z<>m~_UYb>A|B(5=3+43<*=6<=mT3wrbVDKQEi3td*8A=}y)E&~vZ61Da2=1*^9#>0 z-*J7GdQ|`)L;bHxR_Zk?IwucACQNZ=s&&=O)I9l9A%7NFS3Q&ZB4y$6Jg@O51wMpz z40q>+HcON{(z?L`0nB#<1gy>FLva3qE0|1sSb(M5m zcyav7c=MTSN?;p&wVRQZy}twDfgB{N(mF78et)Ocv@^Rb=LkHJRgh|hPiGl5Z5%t! zo_Vb$L43_#e!D~_4VI1V65cThCeLj3rMRkm+(i_fIT68J{we!o0D+rej=nN4D-iKp z644IjCcC6f;WLKJ+Yd+0rE52pVD@<`bzU=!q4w2kn_A%>>3^VY>P-7@8#~*k&N}_+ z>gU>~-Z5|HmBfCXYSA|KzEex47Ef~|mgYOspPMi={lMW&WkbVuTJDbUo=KKH)xvNAL4g>DjRIsbe$JFK0ToTlV-| z^(^Nl3&Bpjsc(_`=E70h$#iUk7XdLXUsNK4;!3T8bD6bqV z-T>2c!8cXS`!%wVX_3XFGgJd*K>wp*_1Cihdtj~TaRxnJB`bdP&nrv#>DwY8&XcRg zlTgseJsUqpi0u+cbxf>3m=SqG_Xf0UAB#jJH@^vbQS^anOnw*X;d_DnudSl4Xy!QB znL6LqV2)PbIM2}dKFi(XZZ8VUCn&$^Y&VO6et4BLKxyB(;_aIzs>Y}Gi##D8B-*Py zsa2{~mQN=7^KbWD`w>DeJ18nAT`pVt|L3?1Nj-DU_0rn6&$)T;!!{MFOZm~d4JXi@ z`pr-jwci=eNm7(eg4SV$W$OuAHeTHXp29e{!!k;nw2HD}7DD<}qb@-+utj13{kLF? zezP`rTJCP08|XSj-aXbtxww4Z#q0n~xtmmf?uR9zA%kxp+|qw}vzX8{?du=^D15Si z=)Bcl(vbxt;IIteNuV6-a^vUC@!_O|hJ;Ug<|UKeAjPz_*jSM!_VSHtwuDc#+h)Zc zX~Fhz|B@Tn&g-n@i5F1nW0vv$jCn(?2NV6Rrq2FiQ?AqJALf3#l@bbz^Jv$hnsp}j z1M>|(X9EFVgPnyU6s5QXV>xSgpIDd-Kl! z?MJ!cM_b%=O!`8NW}Rn<(}S%}&NqGQHbt$h``cHrc1luw0{X%&roP_S>^jmqCFydz zt?mhFvY~IVE2VcR1G??4y{*)FhBHXBZn@;>5qJjFP9Yl0loU`60l%4TgPDYCygx6q zZxJ}__NLDVP|jKff6Y4keY?rDKMCDyu97jz66mo@17`0c$Si+*5g6in>5?o$@1T0; zzr8QZnUlc`wJt1`#UDbTI&ZqU`b;xN-jb1?U31@vw<2GVnsszEdSq{51_gp>tfS78 z%p}AI*^RAJ+?Ur?>AC3FyO^|BS|^i|%%pg3Z<*bOFAwt)ZcQrK!UXy1QaQhMU{rsp zueK2ndms0qn^h-M=BI?!E%6~tNpKPttP_GGM0zlGC|CsN?;yb5pIt1aNo{>+xko;`Y5b4 z7oNlgIO_GMfq`vpuJ6%8j4EAStqDU=R1YE~PcZ#1hcd+e{Dk8xH$?6iX^{RsR;*1b z<5zcWA&|DOW?!g()4@Sz?N`ui1g8_97=V-#w}W^}Uk(tfTQiX3w5)-_P14l~iyBG-R=q{Irmtn1uBMOty`Qc@m+|GDrmQ(aB$F?CPk0tSi zX4<~~shAMSniVwSl^(hJVg%}p4l{287~beLSBkcRz1^;Ns}=ElBtq_S)^*;{C@XTU zRrIKr`(AFz!sG3b_IN9S`Fo~$LPZv)li|j5sk0;_zJWQ@aajQe+Qk4vD90f!{N@y= zie;Xo3$oR2B+x7raqKvkl4C^|oom_2I<6f-dm{cmD+Aq3X_k6@9bbkg{s2KYH_kV# zOkCn#onEctuErg@hArT^DM^a#hwmKBA_{A3h zIEmmOIXA1kH??>6L&2)HxmW7avg&%iWD%m7z|m>z{exC?vOB=p(|ENpP;|&LrZ$IT zN#PTxL!UCQ;_k}MlLlETQO@;O&2Pxl+qqAYrOn`)c6rsWwjApXZO~s%9osSGw42@U z7bFrJL!U_7e6GVV;kPBmCt^^V|B)3wJp6L8@Pnfm996`9Gi z?aWf_gYhmrjKE>o7EDH@ee5tW(`!X zv)ugm@$5*!Y#`4x8d~}M?r`^|X7oF5?!N54ICP$$q!bfz&@g<1s0^v8`Y!dwxgixL z`RwJJT<+O+0W>rIPx!%{@X5va;kAWNUWX%UWBBAHytSI%L!qpa>O^QL>`P@k%^D4v z17>41(h;9dHRt+_2H$|wl%~g_LE$fZW`|D~2e*iWb)y;XzFush5}{_Jp=>}BohaH2 zuooORR&0sR%y6q_&Oox4UvdW}gUi*^o_SZ3@sD#;6;!{0@i={8%H&8&?~cIeCa-~>I9 zSuU1dtWU&od=rk2>KB)u&JG@Raxc_1$~r|nGo)js)Rv8YnV;fdItoKjdiV823b=@g z4PAt~_57;qD!Fb%0$FE-PbP&1^y+81dv3M45;_C4a!T)Q$rU=vRl{2BU=l~)s$3U7 zk+9bXN73MPsd|1t{GnPOOXEgjUKfXU^mSZrSCD>Xmeytp2U)!ZOm7pr2K&tmveLoP z;YAfL9CAx%VRThN-!l^J_>{NVrL$D+zcI($qn7i714IR#!VpwG+%CvHvS^%|Em;u` zWOq6b7QD@$LBVLgrb~*%@R-bl$U23n3PqI=km4|BMV4i&-whDvyV0mVLFJJ9)%Vy=WS;SSU=XLbmVEsJlM4SLWGjT~ht+!X3e}p7Tm^>j7Vj8vWGmayU z$zFl>GnCi^d(}!RiEl@~n`q$x_7xGH&J>DP{octbkE=xwZ zg6G;>iBq_SIA2Dhg>oyUDG39#7ZWhl*`QCnOy;KJlN)*H16&CXg!=jH`!nKW63DhX zi?&kd=jzq9#}dwgz-zYF$U(q`jKoZ=DYGA1n-^aVs*oA!JLzG|hl4DI=3giz1qZfE zhC$XoZayYXv$t`1H5yiYY&f{fU$&1d$~5Rqu%9eT95>uWg^-?x*Rf6=_5)%hlx7xe zX)D!)v}>*xgKT?7I!3*{%VNH9I}~^ujad>r>ssx)>4ZtzMMNnv_v5ZFtfwxObCqU! zM2HDNfxcEva2eHcKvtw-m&mPjTEJPxVK2*9H^Hn*++oz*M!v6(yS}OtLGCpGr6QY~ ziGkzA*x*Yw8D?!;*>!wER7=XrU9Xse=vpU(7QpSjpU=X{jdh=Y167&x^Z8q1gvCXQ zr(B~3!x~H+-^IM9;5cy;MiLLZJGPxfvS%9AFF6HoF{;7ml4b>G$Ao?3F=$kWWzsL= z`A(zy*G}r3pr7~Kxq*rI*w3BB`N4%GE-?#s5RfZIj+^Md(7@cED56=(f=Ea6e zBj`uUiG3lrenq!f|m=_3N};e}!&-yGj9asl=%Mog{$aS&6*ZQ@n^Rhmc%3 zPv@=9(B(V*c2^z7JD$rW%ZoYJIF}mvC$~#qOERxNM$N50&$R>ym;5}ej>Su|=+NRX zE$-7p>v=jk^a}B%duvk)Uy^@K!UxXZu7S&}eNT5FKFD9#6G}6~$NI$pe8Mvn2iB)%G;CZCt{HS{ZcEEU(K6#>#y2Yq@ zW4c(ZVtU@DhBOG5(j|7D^Z$7)5lf{(m=&2g5jJjD-y@a%x4z#fmyTCMWjIM8d#oI% z*0$*R(*P_UKTKe0p|i96;;s??)^!rHjl)y}j}j@(W)tUe0S$bEnsF~mYNl8(xM4Np zTanl1`LU#&*~QxS*FL8Aah4j)#x09nJ)Y{ygo7c37Q;AbwobWE!q=(~rvZ+<(AZiv zwOY(9F?~}L_0xdR_kglV@!N@ab&ISpQ3wgytVItcwGWL*BXZY8F7@{J1Sr~rS71d# zV55G))OW6=OYvWrZ};QZ1WUt&26Mr_o$pK{MfEEesFTa|5G=0A>O1^sRV0#MN9!LM zyEH`@&8(tsW6D}TC2!0Hu!zCFFHc1h1deywD24I72cU$g+n$usSUSHkAMC~{b9F2PUSi?>9 zP`&!LhAP0gvL(^NT6pf@33rP`i@$b^C;sjkvtE%J)+KRz9#VYKJWuhmP)h7yf8%Qy z4W+4Zy+>%VGsaZLhhUC@~J1b%+Abf<-mNACvDZztd)l>tF+ zY^T)3OEfiSs{}_omymw09_n?n-zk@hHvEw8!)3n4_L9AIw{V;7>RG;nz-UQhA5GHG z46Cpeuz{3}a8MHDr%;?w)I*?4K}lWxy&r zG;PQ%ZmQ4?oD+XufXW>lD2XdU)!GSFULJcHB9IQ?I%D3pfCT?bPLZ}L@ zqP2J!N0zvhkJ3WNi}f#|p7^Cp*|2;9*=MnQnmd-La*+#`5&J4KJxj2BWK11Otx>2j z5~b;h#^pT;cp{wUmkprOXYLRQd@x<()_BT0+0>|6W5L#GVv|vs4%g;&`9@cIl`ZaM zg!RQU_v$~toJ2_qL66g1>hRs#9(h4#Lz~U!Dt{1T@zRX8Qjy1i9M)v$tqI)iN#wdB z6(fo&vgW45rZEX;5afEY1VMuR1or`I;{`3|sc|sbpv8;S+m!Fk?P}Z33qr1;PG(yC z3-vrHTK}WZ7>lH((h)_aS#wj>4kk8!_;#`U_Nvb*M^|p6KzKnqS2y0KV?xF*VYAGl zKlU+VX;P3t_=9x#ynx`$opXpCIgsI~(?E%_;*?s05=Z@v${POmhW6WPpvWw{llXH# zLR}-o`1t8u2{X1oiRb}yN7zjwFe$~E3Af|?*5uO6+q(`!qe_t;$EuxPt>KHhiu-`^ z^Jl0-i@~8tRLD}xX;p0}!Opt9B~oz@*tFuFGqd+3-$fqGip&^M^da7wk?A;ct=IJe!N-+5>3pTzVPWX(*C zqweqmB2Hw=v^ZqwDanp4p=VNJ5G7_rZw69vwR<#ARo?n-exucs45I+WS-$NNKiwTow#HUCePOD@ zyYOlaFTnj}kh(#C?RO=tzAuSgn#8w``CcEL(FC5u(gpqdx{!nyG)FXIya#O5LYG1d z!i#2ssXrx^<>%yAa6nEZ>S0(xPR=}geMR@>dY2Nnv9y9XushTk*lS$;%amaCol!p$ zZ^4!*3%l^^3U|YUwJseBCh-2+>_R%?4sXTOXia>8+(70vwbnCGxkmg2dv9vX_80Bv zHs_@ar$xtzMXk%h(jXoQJP-m~jBh5^abm6dS+>l3oB9dx5MMVXIwIRwbO*iT%8KI4 zd?5HSW};2ivBq-nS|!2#8|Jb{^5H9?_L1>gBD$wpdRQa4Uw1YALAS)=*_$+J6Q0n{JCt2}b5QB8l4dF8(zb;%n->09HoeIoF& z+g7nyjzZDO@AMTl&poG%(UnKi)381BniIwsh5iRlaSsQV__Ku6Vap4E6e^#teyu>+ z7DigNI3;lf6$b~3nMO8$aDz^?mLo6~B+v^0U|THPeEDiJTIl5`MGms;;j&6GIsb>vfTSD`y-JOc-4iZip$zIiQEOydg~=5Dtu0v{RKq<*NfFn$<=^6L2nvHSLX>VQ&z#H?c&) zpNA*t`y>|vN?|i#_ESo`LChSy=2+4H}gm>6`SR$O$YBM$QYpudc2L%Pg zJNgqWA~b=i6nD5i2cTD*1->G~f-fc^tJ2$P2)vgD!RtZ8vZ=NrKC@e5SMX{s@A+n- z360|$R!+>78xJD)CtjRPo6mkQJD3*ndn|jjEw*yk;f0b7@z$!96!l5GccT*w4Lf|h zA~R6g(^e{y09RY-2>F5EPEs>^7${&RBjaq6r@qhmLV01>0mX~Xqt7A|St~xYh02t| zktNv_EK%d-g}5!y^AUW*SfS?X1bD`Zmd-)IIp^wor@7j~homi+E2BXg)rJCEUX!8j zD&=-3U#a1Z-;9bj)f^&6@P_jDQ6Tyf=E zHZ9!qzEPbE1Gj8=xaTdS`e_Pv5PM)hqx8c&J!Nx0{PQ9Xm#*ew2pdrs3AHk$F|HvWoxV|7q6 zuhW_7M)k*hvkV_Suj6^OY(%&x#i$;lv-=sRM(wwu20{fl{%7r1jDc&HJ=@o~A;f&Fp%R!STBY zSD_F=H2Ah^&TbD0P%llZM$gS6Qf&c+1)Vli3Z_eBE%^l69sh(qV}xh{G`pq#^)vk) z2n7TJ?oPyhPI(c^K(->Dr?p&b{sm!`Ry;g3L_JOCdh7iG<>DU|d*{erP-~ zfkgc=c%8>$kMWZNeq$H&N7nlVSX92puB;7Wxa}YtX`@j)h+Kt`3zpbcFv!t|69zhP z68|BIajqWQA@e~e3lWP0v$FtX7#769`~a-~(FGcQ?4X;A_0AyPKxv^0eutK!^GuR( zxprx$dPR(#*m6>*+KsTQ7v3QtP-<=KtrmbX!reo-l&HFfV&U#(5=7sN&K`x+6rnkF z)gGxJyrZ$Wia1i3wR{Q9YjskIsuC^PF>!k$G0Ax1Q;G=&D-jSg?Su5cgoVFBG`&kN zBV>}8d2)M_Db373SB{TXw9oAYHUZtgI`DUPcqADCIdJ(*qZz5lWO*yM)NENWClGn4 zLq{OHwQnLI3qogLM1=MD5kwL!BD7mexbuSJOz@E|B>6WB%D`ln%teL7?gQqm{FpsG zOWpDtj)uQyH{eqqe@2sUe89)cxSe2xvHy@MF0k+{2{ll796qKRHG)q?6iMur5d~YA zekNZQgrrq(~mH&`Zt=tI0%1SzYe%aO$$d5)GC z-$f+h>NlWSy{t6Cx&A$tKuJ%77`f&M2F`)$J3U-l9h)aevfX1W# zzNPOWokO1)z3FsOhY=k`OTNh5EV*WW#t5?rmoU8F&zo$Id5!I#XztzjstLRs>jo{B zSDyCeA2GW=nifreN7_7dZt`N8Gv2GVMc|1#nQJ+e-~I z8iGRXRXZ54vqX7n;d953+>LN8n?t}XWa*VNMj$|t+~@c*v%eN4s6XzO-Lg1$j(YDa zSyH%tO-a;L4+p?S$T%Xmk5DV5loOQoTi(v$o-{`R68jbGN?ByIdEC#L=%-qX6?`I4 z`EUl}fb*h$diSOE9Llk^d8!fljja6r%x<94k2S2MuK$%Z4;)xoMH?}rXwQ=gS$r9? zpgi>tojD+4GPfM2iaM-HwZx#eP2(&(*pw#>-#(&SFbBTq!*11eOc+OBXP(rEFv(}n z!CPYv0e&DT2LS5c@S*jlAnCud<`VB~tx+rI)7~2+A<+A~gz)ZFzkh|kRkkM@83k-P zUfWm+ciNs@#8vn|aC+bYzC-h`e|(LTNKrA$9SQ122O`!8l-Lm~%dQyF^hHw9dgCWQ zAP0g^2vKM}BBf;6t&xgsv9_^q%9e0E3w8m(GyW~hKeXYuU_OjNvh`iK7k3{^=-{WY zv+$Jq&QGYwt{=)M7TjjHfkagf0a`FV_hHqRXuHmzvE;&Ok(oWP7Vp)+e2c`Yvh4I+ z^wIcX({#Sg#{_U4H9FFPBquFZFZCbX(^_t0%n_zJWl-#LC{*ozSSpyG#*iGCN zw6D*VMT?sQ?oM3kmm1R}i#t)2Y*eS7<>;_q7}&!+#TIgWQrQCczXMP-6BxS>DmkO! ze;Ard`#!Lbbo%Ogxo(wl!5pgR{-RmFwAPfnI&vXTS@rkSNSws&YN?Zx+M41cC&{^V zQY=YfGM{5#$tnIu?t~RG&|lESzX?C%$cl1qC7CL=9AJL5Itm9%ib&cEGj+HCF5o4B zJ5_3ZB5=ZTC&cY{x&1jTqamrf6p7*2pC@PcsnBf*Q~#8L|eM=hQl?w%(lHcE+!@jQ8+&U3s# zo^GUD@k@Ja-|19bg?u6Ik#XwuIF!kmF=TE9s58|QWw0h9&XW201stWC!`1>7$TW*E zL|urj3Z;`N-Melx_=c3jgokVRr>yQ|5)i8iK%!v(;upsfGt?j0C9Lu3SH&Kts3my$ zTW<=C)5W15xTXOy@IL}^7YX|;Lr{W@9eq zcki|$h@vIj$CoNcHvv)iEF{k6Zk%|D)3{yT%7jF+y0*nk=Da*|g@|kmG&6(#zKocm z!cIsK4lMRK`V+d6D)I$@;C%!#Jb zsa!P3oakUHLzStsVfrQTPpnf`F8YjiIU|sWEIrG*{0ZGf_&hmms6oA-)V#?X2Xo?z z)w`UMx9E~a&5Pv7F4)TNstNKUG;wtaPZ;zub$M#lb&@Jl@!t08J-QByU@~$XBP%Ps z<1}yS^b9aN^%JKT!SaZc_Ogew1W_oy^}Um&qgAi(`vAU2gPKnL52^8FR+)iKd_{{a z0z^m%d1D64OFF&tsFCDg*D*|I4VHafp!O0ZDPX6@lK_t8Ycx1+Jxg?OmT=JtMJ3Ur zFE4h_%i?^EX3MlczzoH*IXK!qF+pdn0%0ydbCrxR{xM=av(AsryiwgqZt)eN10?zD zmWZ{%6~Uu~cNf(T<^Mo70UHv*PCi*NriBTiA01`>QnzeNKYnMQhcZ7F%*beEz(Xrd$H=vBGsQ_uF z-C{2PauP{K^<(^%TcchiCnj781k@}d)ZMK-V`pZ6u4*Jp6bNd={nEi z9>ec~iS{)-whR0{n$rC z=~YYJkA(Um-o|2A7%wV$M%>Mzu>I>;rQk)yV}j?`kD*4%GhT4=i1ath9p6M0F-Ote zg8B4H5#JQ7Yf|Z}7jVCzxk_#?!0oiI>fiLVHs#cIR1S?;WYl!G`jXsZgM&)yUi&*) zgyc^Pc>gI0bl*yq_6R;!g_~j(m7I9Ex0DyB &-T@DYfx=J%ZKr)fGa6cTk44l0;k+ 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

FK_de)jd0?X|tp!-Wl2F$hx*?I_8WzsGK+5 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
~fa-ssH=AFWz4sXr;@8$^iKv1o6v6G9eG>S^ zECd!dY9aALt7~Y#15)3WrP^GWSzcCzsHIR_oA!tuh^;D_a@@mC9dO-bn!41Ek5K7lC`r5iXce!I-~Z32^k^2&s0 zvkQwpBm0c7AZZhTY;yktv|;gBVA-W-MyW0@vQk@c!txCMwJCeC6itrTELP<@uX~~V zo9f4E`g-9B`e0)t*#>c#h_oWH9V3Xu2j2AXP=PeTpo0((H@=i}6%~#rI}VQzx7){i zT@;l{|AySIVB}!v28|KM8yKdaNi;$GvfQ}|f<^CtL}+R~5=*Uql!M9lXaF|$i#re2 zHtyOrl7z*jhts9~kzgn6<>`9hIbPCl*EaI zu-D~~CIDUlF?O?RCLuo&q`8plQr+dC-Pu3gRtlo+qvkU*PgB20%$Sni)LA-o6eL$3 zlhZhfApPo0^R{Q2Z;ZL>4Kf0lo46m>cJy%8$i-Cgy$sc-k=dEZBTALtC0~j^7-d)c zJN8z(>_#KRrW_8dvusLieF)EZ=@H)~KX1BI>bS~R_y+)LakOeV*blFa@pl8KD=&?%o^g=q;YNM}hA7cR1KOr5>!IOOw(>y0@hjgW| z0wfVJJ<%%uSBeq@wpv@&4+(UZ6)Mt1JEiN#jPBs!;6Io8g><7G9%V#un8T4j3#%Br zmEVKsEl=rQd16A>c&O|17N07HxcJ~<@jpOXK`$(-jyN8Y3sxV6M;P3Xe~CFg6T5x1 z3*BfI-#HoB#HUXx#aok)#>*ehlo#veoiD5E)r%$8aj-n!*CA`J+qbDZt_vW{!IZPZ zdgmYI>*}(7kn>o?DG~co9nKI@mn<0bBs>SM`ln}|2Lyduny;)Y?KN==41#GZLbk=! zG^zpbS2&$PZdWDo#2brD9<0Nib41-;(>J51b#;kW+7J-p5w&Li9cd&J68`4 z10KOi1NOl}99;_}5RloQG5wfvjhS#zZS_j4hR!2)nMjDgxo z`Nyb3+D*RVbTB71agFh;Jx>*pO1VHI@oTE^6Hq<>t9Vls_JF$L7ZHYh+=jDU8y_i6 z2(`S2J9BJra~6snl3_-?EcP?YmddM=eU`fG*fteOIc!(Xf?H{X`Oh|xMsCcngxbQ7 zJ$70k-3~YgX|FEGeRDtH!npNdW@&RGznToP6Sl%YrX6IN_UQ%79QbHw@5UWvx3t0H z&H!t~iH8po7AaxGUC3Xsinq7K3V0>M~;=7-H|8({2^tgJx zRy|m%Hg8YWXSR2jL$g^uZC95N11K9S=8LYrDk==r3npctp#$VRz?XI8qNw~`aZYe{ zhwN1aR90%KEzXIZ-WHjptndI{4q^_HnX?)bP?@bEy0?3nrAdg7?a@xN{wxq$&LW+w zMCuRud5%x@y^`!fRBqVS$}K~N)HJ0VJHT~JFBtJI;ro~@o!`WNU^5AWm;lPpaaR(M zXNW@p)9mKY)b?4i4Uzxe)hg{vsETJ+X(#*HzMQ;uWgaey5wru9d1LI>4nxj*1aoe3 zGA4(EsO&%iqDU?9&~6M#_vH1!l$kwM3?m^miJ@dTf|b+N;%}r6+2BA=UZbh*2l>Y zCe=Eb!cahjNW6oXHD4gK`@z!aBDTPa83sV^ap1Ups8nin)6E8-}Q8k|VPSY!@(Y#%?vk^hZ9 zh{&mgU727Vqn&QTS6mM|WEC(K#OQ@Al(t9;%6f183VgnN#AIBPuO>1G_Ed)8T?QNm z{rono*9?DpGAfqYBAKbhv@SBJYv3?V+6f(O4tXrJY>f^DwajDjMuJIFE~q%iCCC+2 zP%6bHAOX7|Ds!7HLzo;ZYHp=|vRjElAny~Q+O2Qtn?8=f_sh!9IC<>J3>Y}3h)p@r z0dC_tzNwwPaMr;39H?DS4hrH`sC^igjaXxCE!vZ*%#ti-X>MiR&EE4$KQ>d+{O1PA zl+b*eNiy?gYBX?d^dqxL9|>w^Y72d}__I9jhm1b$1=P0Z961Z=CXD<1RL;m>}PHP`$BKg%G6lqt_zAfr;ag@x9j{hB&~=*$ka|#LUzLnn)d> zTJ2)6|CCQPz8hyay#}(ju`ScTfQ#iwCfKCsU?w zQ|~QW#7L=p8>vf~@DNT=xWI%7u_!i}HDya$TKW%jQ94shiL-c#V+eog7LSY0E#E>O zl}KS|%i3dOsUZg7W z-?3?Y?RQXvg<*Z7-3Y@RlS=;=Ub}(P__WGr_t#g*a zdjW^UM)zPJJ$Ur1ffwwvn0i1pFwdGdK*9=#46PVzJQmYO8sELcxB7Oc`gWU4YV?D%%OZ7~#e43vtT+OYOP|`OlmTEwmW_i+=6Fae^el=m zc5$hTzF+8)FH(h_D-M{@ht0Y5a03iEhkMf*Hg^Zrh3)DdvbvLtTsgKbdYtV-bOwk7 zX#jTZ`FEPG>fhKspYU9<6OGeU@yS%w`jb9}eJVvg8Jnc4>uX zAL)g5$>T83ZW%K7Ir-8TMC?Y~C}le(u!C?XV05DXa8sN6-N$518ABdpcDqX33>&9v zV_4Z4)eQpZw5o5ChT~v(*Fp=L{==Kh8nJB9XuR=!m<-Y2Qu$OL08*Hqw}wp*lYUEB z!L%x@K7tRr;5QIOCk8X(Wrz~dKE^Q$Dyizq4W+Rk6SzKBG>p4=S!`DqYn*rCbg{Z$ zE}vFU%fu!7`s=TMIrQ}}|KRJt9{T#PFH3Uf9S7^kznna=^%7JWpEZ!$R3Z6`m z0lN1>u7@(ZOi@IUR9RcewvC1A_AE`j>2o9tF!_%Qn`~QZ9ygb3AQbZOK$3Ih!4Jt3l)62?GDA!-9)J^e{(>K!XU9ZwksbygLJTzba4s>A2m*J|Q?(yM z+t}z4T(HL_v$}~RAMB|K8bAW-5X6g`Yc&akrKC66$Ly{!C>4coY=^ZH)PFXhk-Nqd zjN<-D>()UABX+pZDIaQhH?FriF1;HXJmKN9frkU^lg>K?k%Msm7%4aUtlMYs8if2N z0NRt*v-9m_C}UgividU4LsCK@pdQIPo@pi_p0%28*#U^QO~w*ZK-r_huvt-j1sZwV zsq(uQCL#Rx<;%pmKJNAox0KoQXqWJDooC7v0>Tn6$n1{F?Qy-yV0#L_>!#mx5rSCSt7`M6||#}hN{}!01QZ-t8Ovy9?0Yy z@58(xLuwKIWWQ~m;NMuYceGWk936Jx0xhwcfb>F7sgVPcG0DEB@K-NX#KN?^wpiZ4 z?0q3TUR*k8cbX@JncK&d`?&g)WAL>4oNySB-U$28h+4C>et&9tMPkCB zStgrkRF>IwJs|cMgB8YdL_IrV)^pW>zvc! z@@wB?(`@Nz*b>BrS6~0O3S_YxUcLOAx^C^tENDwfeqX($J%%K3P$Vl8g%>mFhDlta z8sNCT-wD#L_k(DIZkM0}TaJW78Mg-zbQu~(rVt^Tx7i8hBTq)eyxROQ0~bbzMnRiS z0%g3yp-Un{{LV7Dv}m?;k||_3Feh5e%F5+WxCJ+X>a2IX1u{5$W)1-H@&WHd6PtSr zK$BA+S2432abFeud!U`zY!ntt?m$%OCESF~Ox`nI00({c%zU><=^Z^~qVtwLP;|;t zTDmfgK*5Du4wG~H%H#YnToZF z{(N#-Z7JCaWP;5H6L0UJ5xm#vtEk!CdS@HA7owRVnrWfblH5u3jlD^TJ_)Wh`?)hl z$dzB6DEE-oKjfa8)#zOH!yr{=W?q1qmI1L8+Cb}%{3L0#9j#{qgM=a( zoSY85nZd9gH=fqk5G;INy+>>i;+Bx$M+e8(e4QV1KDcrk9J)!L=8#BhISM$ShNnK2 z<lHp0_kXw#L1L#Xiu zu0*GE+iCgc4*iPo_9_g&l+zccjtgLok161qIlU5x|6|kh= z5eraGJ;mkOOON4Fq;vlB==4KVI8_a8^0P(_l{V0pXvB3uVFz=1=Ch(Y@ft8V@I9c@F<-;fVU|YX#Da1 z9>l{97GAs6{$X2e9IjdOdXbS`lBkNU(oWLBJuyWVlJ{nQ9Y`1aN2T=w;F2h zU+$ZHxe`f2@F+(^C5@6z@gfemus4T+E!Duts%TX;FpqL$Dy*@Vl~8eu3yA2uWS(1< z=@k|=rku5ml%dtx+JpVsJ)wm|eIQ{YN~5fG zLD9kSjJ?)KK{c9Qpo;_$fad@n3_8M9=x?*l!h;JWbQPnQrUZXLVgy*;kithcG&6b^#+ZKw8>lDhLcxyPU{PAAOf(uUFfJD+}K>%T3vXs zy0G-w9q1aj_C(sRtAGt+HAd-b9~^dxRPI>i;6Sr1gysVNj?kg#Q*il?(2l~|s{dG@ zngJ?zw_70BJ_v~nKWi)N%L|(e{2*4v+?|=(WnE+LV&CW_Wv&0ABIX{< zU;%w>RRIuyfF+x-hp(Rb{?>h<7iUPJ{yqC?h)gn?NRAR$xW|ieEAvQ197EDY8ph6u zzUCJ$>Sw+C=cG;@Ucxb83psA>t;%V#E#GhOw)(VTyQNHw1OoEk%{X zBfM@N#P#Nh)D(^b^UZCOV6%OMgE|u*l^s6r5LG`)U;-IXLB)2vV(+f_lH~1Zz0?BZ zwl{ja-U}_l0R1AH4Kfno@KpBN))^9UuJ;vdLlxD6S~3XmNVIVd01Y}A>V{C{sfev> z;p~ZLj<~VGxdU-v_4twt2(-uGAaVeJC&un&*g++Tj_C&gMekw-4Pv-b2_SQ1G-22| zJyc|WrF&I>4R)k*K!B&io&T!M24JtM5yp3n4X)jUWC7nv&$0V^udy8vcZ+He|8v> zGK=tqcE-TTZsO#*upF>U%h=X%Ax0`o6)6G(BWmPe9RJW9Ee+ePZq3;=V((p0GX$)p zu1ETS`-h-Lqs0$XaF`Swpdcxw#|+4H8wQHSUJP0$2RBT30Xjh+|8*(g z(%R^n=_!CHlM(jy0fqAveJKWRnAY%lWS@np&gVRm&RTCb+QQbA_OFbnO5ZTzyoU= z*!++u#|WT}O$-R+j1Sm%Nm5SOQg$P|xKM|#w`D*jC@`zE=9M^`9Mz^i>-5sQ^OkYF zw01xo$<{5FRMjKc;VaP7IZZ3<`|Jvnf`SAP7CF`F)wfbjdFhEFOI)*4HE_KQ=~1cq zC1C-`EP`$Y1n16cFT~2&Z?#$wv500uyd0aDu*->CWcl3hH0$4}3YVjtp(NkiQwAD> zl#?Uq;HdHBq~q|NtaN(#vEy*h;Zeshgw1E9B>pm{{K})z5zD}xe8>(D2tfJB*~d=b zZo=9LAnYKrU>pJy58i2}AlMQj_I}?%33IkRoPZMPK*! z$sv zHWaLX=tAVIE%+gpAuvrQUr=C+Z3tz6gXuJyD4qylAPY7Q4WLjt@S~b@pY{QKVcE-` zu#-q_+u4b6FL<3(3zeiWcWgLOo;TS8&$6pJ?XE(QyQI{;P!%ZMAyQPAODyWTxV3ct9NT(HzVFH+|s%#D1Wo!mP3xe3l$_i#m^xM#97S7 z6VPCxLOc@8TUV78A~99V4~}0`-+~zz?$=`{*&y-IVeH8LP({Um0nWmWD?~BD1PQ~N z7+8t|%`Yb8(fm?a6ZLQk&M9-g!c9V8CPtEsca|-i3?2{X$y}-j2Q^9Lq3k=bhk48N zX&Tf{Pb8r;>EON)^0ax{Zb_j(T^gI1{D8F+NZ%BC#2`9t zZVdvC02!PR3}~6V4h8wx<4q_e*haFEh28R)`JLEDStK9OB4*jxbT}A&X6rp#&iDK5U!l3r*?#ow;>pl|2Qu z^%;hqD?nM=PCyWFjie(2k$aqwMMs+?xaZQ*U#0k^5v1R7}iX;UJ}6Ne7GXOuP3doU@& zfNWIz00%lo%c0DG9PjWRU$+QxN83GkGA*>vu@nyy8`w0i&Jf;*v?2L6O{MO*AH#{e z21&!XIA@RN?i1j8uZpdZjANf}bkNqD(&a{Nrg~$odj06EdVObhyIw`KeS(1Mdsl~s z&@a9j-kBNto@)a4n`ILzgt-&&DY2Log*FV`mzKgvtf4y=!f|LZ->G4UTnl(~w^5I1 zlZK&Vmbv4vhi2f8(MG{C#YfA&wrF+G zx5Vui%TSpd0g$Lg4gAASVK0zlC`ohic|&5NCAn0OSPCr*i)RNJJB_sjGiq~Ssc8#T zg+IglKnWJV=_6|^8tz%hb#C?`o=0XkBt@)%jdpEclw`@n))fNgoR-0e;UQ%^gxk|@ z5uoZ3wi|BAequ)LrYOnSn+GK7$p@(?;{gIvh}zvqOuXzK);xk{;S4-Yu*uDX zQ@6Tf8JWXS5JHpz3V>~Xih8+W(Y%aJ6EUh;vl&W^@rAM9fGpLpWqlvdRE*TIMT`-r zgo-h2GIJZw2|vSyQts6@Ch+l{W7>=)huxfd5%gW&6C+T*?6wFAouz*(Y>}f1!#_%C zc>(oKa+Cor#O;G9M zo!V0M!~(;Hi4PGbPkjK&nj|;R;KzHnIRVr3hRIv+5r_~2A?>d4KBrfrfV||^6eUo7 zX4~vVhSdBLlgFoyfW@|D8kGCUo3o>P zaH7ZU7GJ9+O0!Rtc@BB9Jt9RcPu%V@edhKk?Y^$w>n zk%nNEGuhYn^$)a>_0A4~uCei`$F#i&zqTRdB?k=1E+jW&uY}NXbhZOBC%`0%8AQK( z0HThsc#8Q_s^FQ8S6AKqYBya4C^$ROKmfJou_yG4^-mmZiVfXjpyJx+UO!Hq7EZKZBU zx&aP3K9d6$o6FdVcrJq5EG?LYRUqX?40;^tB550LW)_zrp4aB=YgQtOSROFI@ge8& z(+@-Q@kjKV5(aRq(evfFII-inCngBHKsuUaDiRiGM*M+zB2X3!qDK
36FABO@m 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 literal 0 HcmV?d00001 From da070a58b770bb574a47f13dd44bf690015d7ab4 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 8 Dec 2018 18:47:37 -0500 Subject: [PATCH 45/71] test: fix TestFingerprintManager_Run_Combination Let's use a fingerprinter that doesn't have values prepopulated in test fixtures. --- client/fingerprint_manager_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/fingerprint_manager_test.go b/client/fingerprint_manager_test.go index 538f8b8f7..922559ba2 100644 --- a/client/fingerprint_manager_test.go +++ b/client/fingerprint_manager_test.go @@ -426,7 +426,7 @@ func TestFingerprintManager_Run_Combination(t *testing.T) { testClient, cleanup := TestClient(t, func(c *config.Config) { c.Options = map[string]string{ "fingerprint.whitelist": " arch,cpu,memory,foo,bar ", - "fingerprint.blacklist": " memory,nomad ", + "fingerprint.blacklist": " memory,host ", } }) defer cleanup() @@ -449,7 +449,7 @@ func TestFingerprintManager_Run_Combination(t *testing.T) { require.NotEqual(node.Attributes["cpu.frequency"], "") require.NotEqual(node.Attributes["cpu.arch"], "") require.NotContains(node.Attributes, "memory.totalbytes") - require.NotContains(node.Attributes, "nomad.version") + require.NotContains(node.Attributes, "os.name") } func TestFingerprintManager_Run_WhitelistDrivers(t *testing.T) { From d31e52b1f649aa11e0c145ff041c431960146bf4 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 8 Dec 2018 19:25:57 -0500 Subject: [PATCH 46/71] tests: update stop/kill tests with new pattern Update rawexec and rkt stop/kill tests with the patterns introduced in 7a49e9b68e519050a0c2ef0b67c33503bfbc51be. This implementation should be more resilient to discrepancy between task stopping and task being marked as exited. --- drivers/rawexec/driver_test.go | 44 +++++++++++++-------------- drivers/rkt/driver_test.go | 54 +++++++++++++--------------------- 2 files changed, 42 insertions(+), 56 deletions(-) diff --git a/drivers/rawexec/driver_test.go b/drivers/rawexec/driver_test.go index 18629b908..5a7083e5e 100644 --- a/drivers/rawexec/driver_test.go +++ b/drivers/rawexec/driver_test.go @@ -25,6 +25,7 @@ import ( pstructs "github.com/hashicorp/nomad/plugins/shared/structs" "github.com/hashicorp/nomad/testutil" "github.com/stretchr/testify/require" + "golang.org/x/sys/unix" ) func TestMain(m *testing.M) { @@ -189,38 +190,35 @@ func TestRawExecDriver_StartWaitStop(t *testing.T) { ch, err := harness.WaitTask(context.Background(), handle.Config.ID) require.NoError(err) - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - result := <-ch - require.Equal(2, result.Signal) - }() - require.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second)) - wg.Add(1) go func() { - defer wg.Done() - err := harness.StopTask(task.ID, 2*time.Second, "SIGINT") - require.NoError(err) - }() - - waitCh := make(chan struct{}) - go func() { - defer close(waitCh) - wg.Wait() + harness.StopTask(task.ID, 2*time.Second, "SIGINT") }() select { - case <-waitCh: - status, err := harness.InspectTask(task.ID) - require.NoError(err) - require.Equal(drivers.TaskStateExited, status.State) - case <-time.After(1 * time.Second): + case result := <-ch: + require.Equal(int(unix.SIGINT), result.Signal) + case <-time.After(10 * time.Second): require.Fail("timeout waiting for task to shutdown") } + // Ensure that the task is marked as dead, but account + // for WaitTask() closing channel before internal state is updated + testutil.WaitForResult(func() (bool, error) { + status, err := harness.InspectTask(task.ID) + if err != nil { + return false, fmt.Errorf("inspecting task failed: %v", err) + } + if status.State != drivers.TaskStateExited { + return false, fmt.Errorf("task hasn't exited yet; status: %v", status.State) + } + + return true, nil + }, func(err error) { + require.NoError(err) + }) + require.NoError(harness.DestroyTask(task.ID, true)) } diff --git a/drivers/rkt/driver_test.go b/drivers/rkt/driver_test.go index b7e0c904b..b58eb3ddf 100644 --- a/drivers/rkt/driver_test.go +++ b/drivers/rkt/driver_test.go @@ -14,6 +14,7 @@ import ( "time" dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" + "golang.org/x/sys/unix" "github.com/hashicorp/hcl2/hcl" ctestutil "github.com/hashicorp/nomad/client/testutil" @@ -121,52 +122,39 @@ func TestRktDriver_Start_Wait_Stop_DNS(t *testing.T) { require.NoError(err) require.Nil(driverNet) - // Wait for task to start ch, err := harness.WaitTask(context.Background(), handle.Config.ID) require.NoError(err) - var wg sync.WaitGroup - wg.Add(1) - - // Block on the channel returned by wait task - go func() { - defer wg.Done() - result := <-ch - require.Equal(15, result.Signal) - }() - - // Wait until task started require.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second)) - // Add to the wait group - wg.Add(1) - - // Stop the task go func() { - defer wg.Done() - err := harness.StopTask(task.ID, 1*time.Second, "SIGTERM") - require.NoError(err) + harness.StopTask(task.ID, 2*time.Second, "SIGTERM") }() - // Wait on the wait group - waitCh := make(chan struct{}) - go func() { - defer close(waitCh) - wg.Wait() - }() - - // Verify that the task exited select { - case <-waitCh: - status, err := harness.InspectTask(task.ID) - require.NoError(err) - require.Equal(drivers.TaskStateExited, status.State) - case <-time.After(2 * time.Second): + case result := <-ch: + require.Equal(int(unix.SIGTERM), result.Signal) + case <-time.After(10 * time.Second): require.Fail("timeout waiting for task to shutdown") } - require.NoError(harness.DestroyTask(task.ID, true)) + // Ensure that the task is marked as dead, but account + // for WaitTask() closing channel before internal state is updated + testutil.WaitForResult(func() (bool, error) { + status, err := harness.InspectTask(task.ID) + if err != nil { + return false, fmt.Errorf("inspecting task failed: %v", err) + } + if status.State != drivers.TaskStateExited { + return false, fmt.Errorf("task hasn't exited yet; status: %v", status.State) + } + return true, nil + }, func(err error) { + require.NoError(err) + }) + + require.NoError(harness.DestroyTask(task.ID, true)) } // Verifies waiting on task to exit cleanly From 06a4b4add2d0a3b265270f7db39ad43af6c08fec Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 8 Dec 2018 18:24:42 -0500 Subject: [PATCH 47/71] tests: prevent indefinite blocking in some tests Noticed few places where tests seem to block indefinitely and panic after the test run reaches the test package timeout. I intend to follow up with the proper fix later, but timing out is much better than indefinitely blocking. --- client/testing.go | 26 ++++++++++++++++--- command/agent/testagent.go | 15 +++++++++-- .../shared/executor/executor_linux_test.go | 15 ++++++++++- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/client/testing.go b/client/testing.go index bd67fd5a4..791047282 100644 --- a/client/testing.go +++ b/client/testing.go @@ -1,6 +1,8 @@ package client import ( + "time" + "github.com/hashicorp/nomad/client/config" consulApi "github.com/hashicorp/nomad/client/consul" "github.com/hashicorp/nomad/client/fingerprint" @@ -47,10 +49,26 @@ func TestClient(t testing.T, cb func(c *config.Config)) (*Client, func()) { t.Fatalf("err: %v", err) } return client, func() { - // Shutdown client - client.Shutdown() + ch := make(chan error, 1) - // Call TestClientConfig cleanup - cleanup() + go func() { + defer close(ch) + + // Shutdown client + err := client.Shutdown() + if err != nil { + t.Errorf("failed to shutdown client: %v", err) + } + + // Call TestClientConfig cleanup + cleanup() + }() + + select { + case <-ch: + // all good + case <-time.After(1 * time.Minute): + t.Errorf("timed out cleaning up test client") + } } } diff --git a/command/agent/testagent.go b/command/agent/testagent.go index 3ad4f9bf2..87219fcee 100644 --- a/command/agent/testagent.go +++ b/command/agent/testagent.go @@ -240,8 +240,19 @@ func (a *TestAgent) Shutdown() error { }() // shutdown agent before endpoints - a.Server.Shutdown() - return a.Agent.Shutdown() + ch := make(chan error, 1) + go func() { + defer close(ch) + a.Server.Shutdown() + ch <- a.Agent.Shutdown() + }() + + select { + case err := <-ch: + return err + case <-time.After(1 * time.Minute): + return fmt.Errorf("timed out while shutting down test agent") + } } func (a *TestAgent) HTTPAddr() string { diff --git a/drivers/shared/executor/executor_linux_test.go b/drivers/shared/executor/executor_linux_test.go index de7bf54f4..ec557a098 100644 --- a/drivers/shared/executor/executor_linux_test.go +++ b/drivers/shared/executor/executor_linux_test.go @@ -170,11 +170,24 @@ func TestExecutor_ClientCleanup(t *testing.T) { execCmd.ResourceLimits = true ps, err := executor.Launch(execCmd) + require.NoError(err) require.NotZero(ps.Pid) time.Sleep(500 * time.Millisecond) require.NoError(executor.Shutdown("SIGINT", 100*time.Millisecond)) - executor.Wait() + + ch := make(chan interface{}) + go func() { + executor.Wait() + close(ch) + }() + + select { + case <-ch: + // all good + case <-time.After(5 * time.Second): + require.Fail("timeout waiting for exec to shutdown") + } output := execCmd.stdout.(*bufferCloser).String() require.NotZero(len(output)) From 8a752066f84be91db13d89059830315b97afd70d Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 11 Dec 2018 06:49:20 -0500 Subject: [PATCH 48/71] tests: no need for buffer channel --- client/testing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/testing.go b/client/testing.go index 791047282..9eed9dc77 100644 --- a/client/testing.go +++ b/client/testing.go @@ -49,7 +49,7 @@ func TestClient(t testing.T, cb func(c *config.Config)) (*Client, func()) { t.Fatalf("err: %v", err) } return client, func() { - ch := make(chan error, 1) + ch := make(chan error) go func() { defer close(ch) From c02dbc7f67c2c05a448599d041d3de06c574d5a7 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 11 Dec 2018 09:34:01 -0500 Subject: [PATCH 49/71] add a note about busybox license --- drivers/shared/executor/test-resources/busybox/README | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/shared/executor/test-resources/busybox/README b/drivers/shared/executor/test-resources/busybox/README index f60a0f318..5b82d46dc 100644 --- a/drivers/shared/executor/test-resources/busybox/README +++ b/drivers/shared/executor/test-resources/busybox/README @@ -1,3 +1,5 @@ -Downloaded busybox https://busybox.net/downloads/binaries/ +Downloaded busybox https://busybox.net/downloads/binaries/, unmodified. Busybox binaries are statically linked binaries, that is a multi-call binary. It's a single binary that can act like many commonly used utilities (e.g. /bin/sh, echo, sleep, etc). More info is found in https://busybox.net/downloads/BusyBox.html . + +Busybox is GPLv2: https://www.busybox.net/license.html . From cbdc8f4c3265ec1531e37030e25773e45f2e5d6d Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Tue, 11 Dec 2018 15:46:58 +0100 Subject: [PATCH 50/71] client: Correctly pass a noop PrevAllocMigrator when restoring --- client/client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/client.go b/client/client.go index eed0a8373..f3565727b 100644 --- a/client/client.go +++ b/client/client.go @@ -861,6 +861,7 @@ func (c *Client) restoreState() error { // we need the local AllocRunners initialized first. We could // add a second loop to initialize just the alloc watcher. prevAllocWatcher := allocwatcher.NoopPrevAlloc{} + prevAllocMigrator := allocwatcher.NoopPrevAlloc{} c.configLock.RLock() arConf := &allocrunner.Config{ @@ -873,6 +874,7 @@ func (c *Client) restoreState() error { Consul: c.consulService, Vault: c.vaultClient, PrevAllocWatcher: prevAllocWatcher, + PrevAllocMigrator: prevAllocMigrator, PluginLoader: c.config.PluginLoader, PluginSingletonLoader: c.config.PluginSingletonLoader, DeviceManager: c.devicemanager, From e7162e8bd8aee7521a1a8315c6720a2be59f0016 Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Tue, 11 Dec 2018 10:12:18 -0600 Subject: [PATCH 51/71] Early continue after meeting needed count Also adds another optimization that filters out un-needed allocations as a final filtering step --- scheduler/preemption.go | 49 +++++++++++++++++++++++++++--------- scheduler/preemption_test.go | 18 +++++++++++-- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/scheduler/preemption.go b/scheduler/preemption.go index 90edcd94d..d65c2f71c 100644 --- a/scheduler/preemption.go +++ b/scheduler/preemption.go @@ -498,8 +498,9 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev neededCount := ask.Count - var preemptionOptions [][]*structs.Allocation + var preemptionOptions []*deviceGroupAllocs // Examine matching allocs by device +OUTER: for deviceIDTuple, allocsGrp := range deviceToAllocs { // First group and sort allocations using this device by priority allocsByPriority := filterAndGroupPreemptibleAllocs(p.jobPriority, allocsGrp.allocs) @@ -521,7 +522,11 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev // Check if we met needed count if preemptedCount+devInst.FreeCount() >= int(neededCount) { - preemptionOptions = append(preemptionOptions, preemptedAllocs) + preemptionOptions = append(preemptionOptions, &deviceGroupAllocs{ + allocs: preemptedAllocs, + deviceInstances: allocsGrp.deviceInstances, + }) + continue OUTER } } } @@ -529,7 +534,7 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev // Find the combination of allocs with lowest net priority if len(preemptionOptions) > 0 { - return selectBestAllocs(preemptionOptions) + return selectBestAllocs(preemptionOptions, int(neededCount)) } return nil @@ -537,18 +542,39 @@ func (p *Preemptor) PreemptForDevice(ask *structs.RequestedDevice, devAlloc *dev // selectBestAllocs finds the best allocations based on minimal net priority amongst // all options. The net priority is the sum of unique priorities in each option -func selectBestAllocs(allocSets [][]*structs.Allocation) []*structs.Allocation { - if len(allocSets) == 1 { - return allocSets[0] - } +func selectBestAllocs(preemptionOptions []*deviceGroupAllocs, neededCount int) []*structs.Allocation { bestPriority := math.MaxInt32 var bestAllocs []*structs.Allocation - for _, allocs := range allocSets { - // Find unique priorities and add them + // We iterate over allocations in priority order, so its possible + // that we have more allocations than needed to meet the needed count. + // e.g we need 4 instances, and we get 3 from a priority 10 alloc, and 4 from + // a priority 20 alloc. We should filter out the priority 10 alloc in that case. + // This loop does a filter and chooses the set with the smallest net priority + for _, allocGrp := range preemptionOptions { + // Find unique priorities and add them to calculate net priority priorities := map[int]struct{}{} netPriority := 0 - for _, alloc := range allocs { + + devInst := allocGrp.deviceInstances + var filteredAllocs []*structs.Allocation + + // Sort by number of device instances used, descending + sort.Slice(allocGrp.allocs, func(i, j int) bool { + instanceCount1 := devInst[allocGrp.allocs[i].ID] + instanceCount2 := devInst[allocGrp.allocs[j].ID] + return instanceCount1 > instanceCount2 + }) + + // Filter and calculate net priority + preemptedInstanceCount := 0 + for _, alloc := range allocGrp.allocs { + if preemptedInstanceCount >= neededCount { + break + } + instanceCount := devInst[alloc.ID] + preemptedInstanceCount += instanceCount + filteredAllocs = append(filteredAllocs, alloc) _, ok := priorities[alloc.Job.Priority] if !ok { priorities[alloc.Job.Priority] = struct{}{} @@ -557,9 +583,8 @@ func selectBestAllocs(allocSets [][]*structs.Allocation) []*structs.Allocation { } if netPriority < bestPriority { bestPriority = netPriority - bestAllocs = allocs + bestAllocs = filteredAllocs } - } return bestAllocs } diff --git a/scheduler/preemption_test.go b/scheduler/preemption_test.go index edbb71fb0..e54d5c77d 100644 --- a/scheduler/preemption_test.go +++ b/scheduler/preemption_test.go @@ -163,7 +163,7 @@ func TestPreemption(t *testing.T) { lowPrioJob2.Priority = 40 // Create some persistent alloc ids to use in test cases - allocIDs := []string{uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate()} + allocIDs := []string{uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate(), uuid.Generate()} var deviceIDs []string for i := 0; i < 10; i++ { @@ -244,6 +244,10 @@ func TestPreemption(t *testing.T) { ID: deviceIDs[7], Healthy: true, }, + { + ID: deviceIDs[8], + Healthy: true, + }, }, }, { @@ -1076,7 +1080,7 @@ func TestPreemption(t *testing.T) { // This test cases creates allocations across two GPUs // Both GPUs are eligible for the task, but only allocs with the lower // priority are chosen - desc: "Preemption with allocs across multiple devices that match", + desc: "Preemption with lower/higher priority combinations", currentAllocations: []*structs.Allocation{ createAllocWithDevice(allocIDs[0], lowPrioJob, &structs.Resources{ CPU: 500, @@ -1119,6 +1123,16 @@ func TestPreemption(t *testing.T) { DeviceIDs: []string{deviceIDs[6], deviceIDs[7]}, }), createAllocWithDevice(allocIDs[4], lowPrioJob, &structs.Resources{ + CPU: 100, + MemoryMB: 256, + DiskMB: 4 * 1024, + }, &structs.AllocatedDeviceResource{ + Type: "gpu", + Vendor: "nvidia", + Name: "2080ti", + DeviceIDs: []string{deviceIDs[8]}, + }), + createAllocWithDevice(allocIDs[5], lowPrioJob, &structs.Resources{ CPU: 200, MemoryMB: 512, DiskMB: 4 * 1024, From 971586d73c2e58df7dc112604f0f6401435e1916 Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Tue, 11 Dec 2018 18:03:45 +0100 Subject: [PATCH 52/71] client: Style: use fluent style for building loggers --- client/allocwatcher/alloc_watcher.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/client/allocwatcher/alloc_watcher.go b/client/allocwatcher/alloc_watcher.go index b8a0ead09..192a9a0f0 100644 --- a/client/allocwatcher/alloc_watcher.go +++ b/client/allocwatcher/alloc_watcher.go @@ -95,9 +95,7 @@ type Config struct { } func newMigratorForAlloc(c Config, tg *structs.TaskGroup, watchedAllocID string, m AllocRunnerMeta) PrevAllocMigrator { - logger := c.Logger.Named("alloc_migrator") - logger = logger.With("alloc_id", c.Alloc.ID) - logger = logger.With("previous_alloc", watchedAllocID) + logger := c.Logger.Named("alloc_migrator").With("alloc_id", c.Alloc.ID).With("previous_alloc", watchedAllocID) tasks := tg.Tasks sticky := tg.EphemeralDisk != nil && tg.EphemeralDisk.Sticky @@ -130,9 +128,7 @@ func newMigratorForAlloc(c Config, tg *structs.TaskGroup, watchedAllocID string, } func newWatcherForAlloc(c Config, watchedAllocID string, m AllocRunnerMeta) PrevAllocWatcher { - logger := c.Logger.Named("alloc_watcher") - logger = logger.With("alloc_id", c.Alloc.ID) - logger = logger.With("previous_alloc", watchedAllocID) + logger := c.Logger.Named("alloc_watcher").With("alloc_id", c.Alloc.ID).With("previous_alloc", watchedAllocID) if m != nil { // Local Allocation because there's no meta From 1678a8499b1752455efcbb5713415fe6f0d9cfbc Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 11 Dec 2018 14:22:50 -0500 Subject: [PATCH 53/71] drivers/docker: enforce volumes.enabled (#4983) When volumes.enable flag is off in Docker driver, disable all mounts of paths outside alloc dir. --- drivers/docker/driver.go | 40 ++++----- drivers/docker/driver_test.go | 147 ++++++++++++++++++++++++++++++++-- drivers/docker/utils.go | 18 +++++ drivers/docker/utils_test.go | 35 ++++++++ 4 files changed, 207 insertions(+), 33 deletions(-) diff --git a/drivers/docker/driver.go b/drivers/docker/driver.go index 4b780b32b..bb94d3435 100644 --- a/drivers/docker/driver.go +++ b/drivers/docker/driver.go @@ -541,7 +541,9 @@ func (d *Driver) containerBinds(task *drivers.TaskConfig, driverConfig *TaskConf secretDirBind := fmt.Sprintf("%s:%s", task.TaskDir().SecretsDir, task.Env[taskenv.SecretsDir]) binds := []string{allocDirBind, taskLocalBind, secretDirBind} - if !d.config.Volumes.Enabled && driverConfig.VolumeDriver != "" { + localBindVolume := driverConfig.VolumeDriver == "" || driverConfig.VolumeDriver == "local" + + if !d.config.Volumes.Enabled && !localBindVolume { return nil, fmt.Errorf("volumes are not enabled; cannot use volume driver %q", driverConfig.VolumeDriver) } @@ -551,25 +553,15 @@ func (d *Driver) containerBinds(task *drivers.TaskConfig, driverConfig *TaskConf return nil, fmt.Errorf("invalid docker volume: %q", userbind) } - // Resolve dotted path segments - parts[0] = filepath.Clean(parts[0]) - - // Absolute paths aren't always supported - if filepath.IsAbs(parts[0]) { - if !d.config.Volumes.Enabled { - // Disallow mounting arbitrary absolute paths - return nil, fmt.Errorf("volumes are not enabled; cannot mount host paths: %+q", userbind) - } - binds = append(binds, userbind) - continue - } - - // Relative paths are always allowed as they mount within a container + // Paths inside task dir are always allowed, Relative paths are always allowed as they mount within a container // When a VolumeDriver is set, we assume we receive a binding in the format volume-name:container-dest // Otherwise, we assume we receive a relative path binding in the format relative/to/task:/also/in/container - if driverConfig.VolumeDriver == "" { - // Expand path relative to alloc dir - parts[0] = filepath.Join(task.TaskDir().Dir, parts[0]) + if localBindVolume { + parts[0] = expandPath(task.TaskDir().Dir, parts[0]) + + if !d.config.Volumes.Enabled && !isParentPath(task.AllocDir, parts[0]) { + return nil, fmt.Errorf("volumes are not enabled; cannot mount host paths: %+q", userbind) + } } binds = append(binds, strings.Join(parts, ":")) @@ -742,13 +734,11 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T } if hm.Type == "bind" { - if filepath.IsAbs(filepath.Clean(hm.Source)) { - if !d.config.Volumes.Enabled { - return c, fmt.Errorf("volumes are not enabled; cannot mount host path: %q", hm.Source) - } - } else { - // Relative paths are always allowed as they mount within a container, and treated as relative to task dir - hm.Source = filepath.Join(task.TaskDir().Dir, hm.Source) + hm.Source = expandPath(task.TaskDir().Dir, hm.Source) + + // paths inside alloc dir are always allowed as they mount within a container, and treated as relative to task dir + if !d.config.Volumes.Enabled && !isParentPath(task.AllocDir, hm.Source) { + return c, fmt.Errorf("volumes are not enabled; cannot mount host path: %q %q", hm.Source, task.AllocDir) } } diff --git a/drivers/docker/driver_test.go b/drivers/docker/driver_test.go index 1a03c1b98..58f8f2102 100644 --- a/drivers/docker/driver_test.go +++ b/drivers/docker/driver_test.go @@ -1149,7 +1149,6 @@ func TestDockerDriver_CreateContainerConfig(t *testing.T) { require.Equal(t, "org/repo:0.1", c.Config.Image) require.EqualValues(t, opt, c.HostConfig.StorageOpt) } - func TestDockerDriver_Capabilities(t *testing.T) { if !tu.IsTravis() { t.Parallel() @@ -1638,6 +1637,143 @@ func TestDockerDriver_VolumesDisabled(t *testing.T) { } +func TestDockerDriver_BindMountsHonorVolumesEnabledFlag(t *testing.T) { + t.Parallel() + + allocDir := "/tmp/nomad/alloc-dir" + + cases := []struct { + name string + requiresVolumes bool + + volumeDriver string + volumes []string + + expectedVolumes []string + }{ + { + name: "basic plugin", + requiresVolumes: true, + volumeDriver: "nfs", + volumes: []string{"test-path:/tmp/taskpath"}, + expectedVolumes: []string{"test-path:/tmp/taskpath"}, + }, + { + name: "absolute default driver", + requiresVolumes: true, + volumeDriver: "", + volumes: []string{"/abs/test-path:/tmp/taskpath"}, + expectedVolumes: []string{"/abs/test-path:/tmp/taskpath"}, + }, + { + name: "absolute local driver", + requiresVolumes: true, + volumeDriver: "local", + volumes: []string{"/abs/test-path:/tmp/taskpath"}, + expectedVolumes: []string{"/abs/test-path:/tmp/taskpath"}, + }, + { + name: "relative default driver", + requiresVolumes: false, + volumeDriver: "", + volumes: []string{"test-path:/tmp/taskpath"}, + expectedVolumes: []string{"/tmp/nomad/alloc-dir/demo/test-path:/tmp/taskpath"}, + }, + { + name: "relative local driver", + requiresVolumes: false, + volumeDriver: "local", + volumes: []string{"test-path:/tmp/taskpath"}, + expectedVolumes: []string{"/tmp/nomad/alloc-dir/demo/test-path:/tmp/taskpath"}, + }, + { + name: "relative outside task-dir default driver", + requiresVolumes: false, + volumeDriver: "", + volumes: []string{"../test-path:/tmp/taskpath"}, + expectedVolumes: []string{"/tmp/nomad/alloc-dir/test-path:/tmp/taskpath"}, + }, + { + name: "relative outside task-dir local driver", + requiresVolumes: false, + volumeDriver: "local", + volumes: []string{"../test-path:/tmp/taskpath"}, + expectedVolumes: []string{"/tmp/nomad/alloc-dir/test-path:/tmp/taskpath"}, + }, + { + name: "relative outside alloc-dir default driver", + requiresVolumes: true, + volumeDriver: "", + volumes: []string{"../../test-path:/tmp/taskpath"}, + expectedVolumes: []string{"/tmp/nomad/test-path:/tmp/taskpath"}, + }, + { + name: "relative outside task-dir local driver", + requiresVolumes: true, + volumeDriver: "local", + volumes: []string{"../../test-path:/tmp/taskpath"}, + expectedVolumes: []string{"/tmp/nomad/test-path:/tmp/taskpath"}, + }, + } + + t.Run("with volumes enabled", func(t *testing.T) { + dh := dockerDriverHarness(t, nil) + driver := dh.Impl().(*Driver) + driver.config.Volumes.Enabled = true + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + task, cfg, _ := dockerTask(t) + cfg.VolumeDriver = c.volumeDriver + cfg.Volumes = c.volumes + + task.AllocDir = allocDir + task.Name = "demo" + + require.NoError(t, task.EncodeConcreteDriverConfig(cfg)) + + cc, err := driver.createContainerConfig(task, cfg, "org/repo:0.1") + require.NoError(t, err) + + for _, v := range c.expectedVolumes { + require.Contains(t, cc.HostConfig.Binds, v) + } + }) + } + }) + + t.Run("with volumes disabled", func(t *testing.T) { + dh := dockerDriverHarness(t, nil) + driver := dh.Impl().(*Driver) + driver.config.Volumes.Enabled = false + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + task, cfg, _ := dockerTask(t) + cfg.VolumeDriver = c.volumeDriver + cfg.Volumes = c.volumes + + task.AllocDir = allocDir + task.Name = "demo" + + require.NoError(t, task.EncodeConcreteDriverConfig(cfg)) + + cc, err := driver.createContainerConfig(task, cfg, "org/repo:0.1") + if c.requiresVolumes { + require.Error(t, err, "volumes are not enabled") + } else { + require.NoError(t, err) + + for _, v := range c.expectedVolumes { + require.Contains(t, cc.HostConfig.Binds, v) + } + } + }) + } + }) + +} + func TestDockerDriver_VolumesEnabled(t *testing.T) { if !tu.IsTravis() { t.Parallel() @@ -1810,13 +1946,8 @@ func TestDockerDriver_MountsSerialization(t *testing.T) { }, }, { - - // FIXME: This needs to be true but we have a bug with security implications. - // The relative paths check should restrict access to alloc-dir subtree - // documenting existing behavior in test here and need to follow up in another commit - requiresVolumes: false, - - name: "bind relative outside", + name: "bind relative outside", + requiresVolumes: true, passedMounts: []DockerMount{ { Type: "bind", diff --git a/drivers/docker/utils.go b/drivers/docker/utils.go index 7b482e11a..fc20b30b7 100644 --- a/drivers/docker/utils.go +++ b/drivers/docker/utils.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "strings" "github.com/docker/cli/cli/config/configfile" @@ -200,3 +201,20 @@ func validateCgroupPermission(s string) bool { return true } + +// expandPath returns the absolute path of dir, relative to base if dir is relative path. +// base is expected to be an absolute path +func expandPath(base, dir string) string { + if filepath.IsAbs(dir) { + return filepath.Clean(dir) + } + + return filepath.Clean(filepath.Join(base, dir)) +} + +// isParentPath returns true if path is a child or a descendant of parent path. +// Both inputs need to be absolute paths. +func isParentPath(parent, path string) bool { + rel, err := filepath.Rel(parent, path) + return err == nil && !strings.HasPrefix(rel, "..") +} diff --git a/drivers/docker/utils_test.go b/drivers/docker/utils_test.go index 6598d8313..edc10dd0f 100644 --- a/drivers/docker/utils_test.go +++ b/drivers/docker/utils_test.go @@ -35,3 +35,38 @@ func TestValidateCgroupPermission(t *testing.T) { } } + +func TestExpandPath(t *testing.T) { + cases := []struct { + base string + target string + expected string + }{ + {"/tmp/alloc/task", "/home/user", "/home/user"}, + {"/tmp/alloc/task", "/home/user/..", "/home"}, + + {"/tmp/alloc/task", ".", "/tmp/alloc/task"}, + {"/tmp/alloc/task", "..", "/tmp/alloc"}, + + {"/tmp/alloc/task", "d1/d2", "/tmp/alloc/task/d1/d2"}, + {"/tmp/alloc/task", "../d1/d2", "/tmp/alloc/d1/d2"}, + {"/tmp/alloc/task", "../../d1/d2", "/tmp/d1/d2"}, + } + + for _, c := range cases { + t.Run(c.expected, func(t *testing.T) { + require.Equal(t, c.expected, expandPath(c.base, c.target)) + }) + } +} + +func TestIsParentPath(t *testing.T) { + require.True(t, isParentPath("/a/b/c", "/a/b/c")) + require.True(t, isParentPath("/a/b/c", "/a/b/c/d")) + require.True(t, isParentPath("/a/b/c", "/a/b/c/d/e")) + + require.False(t, isParentPath("/a/b/c", "/a/b/d")) + require.False(t, isParentPath("/a/b/c", "/a/b/cd")) + require.False(t, isParentPath("/a/b/c", "/a/d/c")) + require.False(t, isParentPath("/a/b/c", "/d/e/c")) +} From cae36e49a6b17c93658047ce27cf28abffe611a6 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 11 Dec 2018 12:20:51 -0500 Subject: [PATCH 54/71] client: update driver info on new fingerprint Fixes a bug where a driver health and attributes are never updated from their initial status. If a driver started unhealthy, it may never go into a healthy status. --- client/client.go | 5 +-- client/client_test.go | 77 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/client/client.go b/client/client.go index ce2e87573..019234460 100644 --- a/client/client.go +++ b/client/client.go @@ -1154,7 +1154,6 @@ func (c *Client) updateNodeFromDriver(name string, info *structs.DriverInfo) *st if !hadDriver { // If the driver info has not yet been set, do that here hasChanged = true - c.config.Node.Drivers[name] = info for attrName, newVal := range info.Attributes { c.config.Node.Attributes[attrName] = newVal } @@ -1163,11 +1162,11 @@ func (c *Client) updateNodeFromDriver(name string, info *structs.DriverInfo) *st // The driver info has already been set, fix it up if oldVal.Detected != info.Detected { hasChanged = true - c.config.Node.Drivers[name].Detected = info.Detected } if oldVal.Healthy != info.Healthy || oldVal.HealthDescription != info.HealthDescription { hasChanged = true + if info.HealthDescription != "" { event := &structs.NodeEvent{ Subsystem: "Driver", @@ -1186,6 +1185,7 @@ func (c *Client) updateNodeFromDriver(name string, info *structs.DriverInfo) *st } hasChanged = true + if newVal == "" { delete(c.config.Node.Attributes, attrName) } else { @@ -1205,6 +1205,7 @@ func (c *Client) updateNodeFromDriver(name string, info *structs.DriverInfo) *st } if hasChanged { + c.config.Node.Drivers[name] = info c.config.Node.Drivers[name].UpdateTime = time.Now() c.updateNodeLocked() } diff --git a/client/client_test.go b/client/client_test.go index 3dadc3ce6..e5e68ed1c 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1183,3 +1183,80 @@ func TestClient_computeAllocatedDeviceStats(t *testing.T) { assert.EqualValues(t, expected, result) } + +func TestClient_updateNodeFromDriverUpdatesAll(t *testing.T) { + t.Parallel() + client, cleanup := TestClient(t, nil) + defer cleanup() + + // initial update + { + info := &structs.DriverInfo{ + Detected: true, + Healthy: false, + HealthDescription: "not healthy at start", + Attributes: map[string]string{ + "node.mock.testattr1": "val1", + }, + } + n := client.updateNodeFromDriver("mock", info) + + updatedInfo := *n.Drivers["mock"] + // compare without update time + updatedInfo.UpdateTime = info.UpdateTime + assert.EqualValues(t, updatedInfo, *info) + + // check node attributes + assert.Equal(t, "val1", n.Attributes["node.mock.testattr1"]) + } + + // initial update + { + info := &structs.DriverInfo{ + Detected: true, + Healthy: true, + HealthDescription: "healthy", + Attributes: map[string]string{ + "node.mock.testattr1": "val2", + }, + } + n := client.updateNodeFromDriver("mock", info) + + updatedInfo := *n.Drivers["mock"] + // compare without update time + updatedInfo.UpdateTime = info.UpdateTime + assert.EqualValues(t, updatedInfo, *info) + + // check node attributes are updated + assert.Equal(t, "val2", n.Attributes["node.mock.testattr1"]) + + // update once more with the same info, updateTime shouldn't change + un := client.updateNodeFromDriver("mock", info) + assert.EqualValues(t, n, un) + } + + // update once more to unhealthy because why not + { + info := &structs.DriverInfo{ + Detected: true, + Healthy: false, + HealthDescription: "lost track", + Attributes: map[string]string{ + "node.mock.testattr1": "", + }, + } + n := client.updateNodeFromDriver("mock", info) + + updatedInfo := *n.Drivers["mock"] + // compare without update time + updatedInfo.UpdateTime = info.UpdateTime + assert.EqualValues(t, updatedInfo, *info) + + // check node attributes are updated + assert.Equal(t, "", n.Attributes["node.mock.testattr1"]) + + // update once more with the same info, updateTime shouldn't change + un := client.updateNodeFromDriver("mock", info) + assert.EqualValues(t, n, un) + } +} From 338683a4db22a2490abcc55e44872fcdd3d70aa9 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 11 Dec 2018 09:44:42 -0500 Subject: [PATCH 55/71] ci: use Ubuntu 16.04 (Xenial) in TravisCI --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc79d5738..5ce671d5c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,28 +15,28 @@ git: matrix: include: - os: linux - dist: trusty + dist: xenial sudo: required - os: linux - dist: trusty + dist: xenial sudo: required env: ENABLE_RACE=1 - os: linux - dist: trusty + dist: xenial sudo: false env: RUN_WEBSITE_TESTS=1 SKIP_NOMAD_TESTS=1 - os: linux - dist: trusty + dist: xenial sudo: false env: RUN_UI_TESTS=1 SKIP_NOMAD_TESTS=1 - os: linux - dist: trusty + dist: xenial sudo: false env: RUN_STATIC_CHECKS=1 SKIP_NOMAD_TESTS=1 - os: osx osx_image: xcode9.1 - os: linux - dist: trusty + dist: xenial sudo: required env: RUN_E2E_TESTS=1 SKIP_NOMAD_TESTS=1 allow_failures: From 8f2454029acc9d991f121580107957e85fc1dcb3 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 11 Dec 2018 15:13:43 -0500 Subject: [PATCH 56/71] tests: skip checking rdma cgroup rdma was added in most recent kernels and libcontainer/docker don't isolate them by default. --- drivers/exec/driver_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/exec/driver_test.go b/drivers/exec/driver_test.go index 325687b7a..1299c1136 100644 --- a/drivers/exec/driver_test.go +++ b/drivers/exec/driver_test.go @@ -466,8 +466,9 @@ func TestExecDriver_HandlerExec(t *testing.T) { if line == "" { continue } - // Skip systemd cgroup - if strings.HasPrefix(line, "1:name=systemd") { + // Skip systemd and rdma cgroups; rdma was added in most recent kernels and libcontainer/docker + // don't isolate them by default. + if strings.HasPrefix(line, "1:name=systemd") || strings.Contains(line, ":rdma:") { continue } if !strings.Contains(line, ":/nomad/") { From d0215f42302c99174797914e94e52eab8b97885b Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Tue, 11 Dec 2018 15:14:57 -0500 Subject: [PATCH 57/71] ci: install lxc-templates explicitly LXC package on Ubuntu 16.04 doesn't depend on lxc-template, but we require it in our tests. --- scripts/travis-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/travis-linux.sh b/scripts/travis-linux.sh index 77cad6924..aeb022189 100644 --- a/scripts/travis-linux.sh +++ b/scripts/travis-linux.sh @@ -10,7 +10,7 @@ sudo service docker restart # true errors would fail in the apt-get install phase apt-get update || true -apt-get install -y liblxc1 lxc-dev lxc shellcheck +apt-get install -y liblxc1 lxc-dev lxc lxc-templates shellcheck apt-get install -y qemu bash ./scripts/travis-rkt.sh bash ./scripts/travis-consul.sh From ce01603e04b7d762d5de640063645f95c0685282 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Tue, 11 Dec 2018 12:52:45 -0800 Subject: [PATCH 58/71] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d989b3a7..e769f4885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ __BACKWARDS INCOMPATIBILITIES:__ * core: Switch to structured logging using [go-hclog](https://github.com/hashicorp/go-hclog) + * core: IOPS as a resource is now deprecated [[GH-4970](https://github.com/hashicorp/nomad/issues/4970)] * core: Allow the != constraint to match against keys that do not exist [[GH-4875](https://github.com/hashicorp/nomad/pull/4875)] * client: Task config interpolation requires names to be valid identifiers (`node.region` or `NOMAD_DC`). Interpolating other variables requires a new From e716c451a96c0dc9b8325db3d4a6b327cc5138f0 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sat, 8 Dec 2018 21:19:39 -0500 Subject: [PATCH 59/71] tests: tag image explicitly --- drivers/docker/driver_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/docker/driver_test.go b/drivers/docker/driver_test.go index 1a03c1b98..510170fff 100644 --- a/drivers/docker/driver_test.go +++ b/drivers/docker/driver_test.go @@ -72,7 +72,7 @@ func dockerTask(t *testing.T) (*drivers.TaskConfig, *TaskConfig, []int) { dockerDynamic := ports[1] cfg := TaskConfig{ - Image: "busybox", + Image: "busybox:latest", LoadImage: "busybox.tar", Command: "/bin/nc", Args: []string{"-l", "127.0.0.1", "-p", "0"}, From aa59ea6ac7a96c3a53a26f599e91aff1ea7b2807 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Tue, 11 Dec 2018 15:23:39 -0800 Subject: [PATCH 60/71] fix iops bug and increase test matrix coverage --- command/agent/job_endpoint.go | 6 +++++- e2e/vault/matrix_test.go | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/command/agent/job_endpoint.go b/command/agent/job_endpoint.go index 8414eac2f..e7b07d2d3 100644 --- a/command/agent/job_endpoint.go +++ b/command/agent/job_endpoint.go @@ -853,7 +853,11 @@ func ApiResourcesToStructs(in *api.Resources) *structs.Resources { out := &structs.Resources{ CPU: *in.CPU, MemoryMB: *in.MemoryMB, - IOPS: *in.IOPS, // COMPAT(0.10): Only being used to issue warnings + } + + // COMPAT(0.10): Only being used to issue warnings + if in.IOPS != nil { + out.IOPS = *in.IOPS } if l := len(in.Networks); l != 0 { diff --git a/e2e/vault/matrix_test.go b/e2e/vault/matrix_test.go index 87325bb25..1dc786a6a 100644 --- a/e2e/vault/matrix_test.go +++ b/e2e/vault/matrix_test.go @@ -3,6 +3,11 @@ package vault var ( // versions is the set of Vault versions we test for backwards compatibility versions = []string{ + "1.0.0", + "0.11.5", + "0.11.4", + "0.11.3", + "0.11.2", "0.11.1", "0.11.0", "0.10.4", From 97f33bb1537d04905cb84199672bcdf46ebb4e65 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Sun, 9 Dec 2018 22:30:23 -0500 Subject: [PATCH 61/71] drivers/exec: support device binds and mounts --- drivers/exec/driver.go | 2 + drivers/exec/driver_test.go | 91 +++++++++++++++++++ drivers/java/driver.go | 2 + drivers/shared/executor/executor.go | 7 ++ drivers/shared/executor/executor_linux.go | 81 +++++++++++++++-- .../shared/executor/executor_linux_test.go | 66 ++++++++++++++ 6 files changed, 243 insertions(+), 6 deletions(-) diff --git a/drivers/exec/driver.go b/drivers/exec/driver.go index 14eca02c3..213b5dd92 100644 --- a/drivers/exec/driver.go +++ b/drivers/exec/driver.go @@ -308,6 +308,8 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *cstru TaskDir: cfg.TaskDir().Dir, StdoutPath: cfg.StdoutPath, StderrPath: cfg.StderrPath, + Mounts: cfg.Mounts, + Devices: cfg.Devices, } ps, err := exec.Launch(execCmd) diff --git a/drivers/exec/driver_test.go b/drivers/exec/driver_test.go index 1299c1136..6de0a7c72 100644 --- a/drivers/exec/driver_test.go +++ b/drivers/exec/driver_test.go @@ -490,6 +490,97 @@ func TestExecDriver_HandlerExec(t *testing.T) { require.NoError(harness.DestroyTask(task.ID, true)) } +func TestExecDriver_DevicesAndMounts(t *testing.T) { + t.Parallel() + require := require.New(t) + ctestutils.ExecCompatible(t) + + tmpDir, err := ioutil.TempDir("", "exec_binds_mounts") + require.NoError(err) + defer os.RemoveAll(tmpDir) + + err = ioutil.WriteFile(filepath.Join(tmpDir, "testfile"), []byte("from-host"), 600) + require.NoError(err) + + d := NewExecDriver(testlog.HCLogger(t)) + harness := dtestutil.NewDriverHarness(t, d) + task := &drivers.TaskConfig{ + ID: uuid.Generate(), + Name: "test", + StdoutPath: filepath.Join(tmpDir, "task-stdout"), + StderrPath: filepath.Join(tmpDir, "task-stderr"), + Devices: []*drivers.DeviceConfig{ + { + TaskPath: "/dev/inserted-random", + HostPath: "/dev/random", + Permissions: "rw", + }, + }, + Mounts: []*drivers.MountConfig{ + { + TaskPath: "/tmp/task-path-rw", + HostPath: tmpDir, + Readonly: false, + }, + { + TaskPath: "/tmp/task-path-ro", + HostPath: tmpDir, + Readonly: true, + }, + }, + } + + require.NoError(ioutil.WriteFile(task.StdoutPath, []byte{}, 660)) + require.NoError(ioutil.WriteFile(task.StderrPath, []byte{}, 660)) + + taskConfig := map[string]interface{}{ + "command": "/bin/bash", + "args": []string{"-c", ` +export LANG=en.UTF-8 +echo "mounted device /inserted-random: $(stat -c '%t:%T' /dev/inserted-random)" +echo "reading from ro path: $(cat /tmp/task-path-ro/testfile)" +echo "reading from rw path: $(cat /tmp/task-path-rw/testfile)" +touch /tmp/task-path-rw/testfile && echo 'overwriting file in rw succeeded' +touch /tmp/task-path-rw/testfile-from-rw && echo from-exec > /tmp/task-path-rw/testfile-from-rw && echo 'writing new file in rw succeeded' +touch /tmp/task-path-ro/testfile && echo 'overwriting file in ro succeeded' +touch /tmp/task-path-ro/testfile-from-ro && echo from-exec > /tmp/task-path-ro/testfile-from-ro && echo 'writing new file in ro succeeded' +exit 0 +`}, + } + encodeDriverHelper(require, task, taskConfig) + + cleanup := harness.MkAllocDir(task, false) + defer cleanup() + + handle, _, err := harness.StartTask(task) + require.NoError(err) + + ch, err := harness.WaitTask(context.Background(), handle.Config.ID) + require.NoError(err) + result := <-ch + require.NoError(harness.DestroyTask(task.ID, true)) + + stdout, err := ioutil.ReadFile(task.StdoutPath) + require.NoError(err) + require.Equal(`mounted device /inserted-random: 1:8 +reading from ro path: from-host +reading from rw path: from-host +overwriting file in rw succeeded +writing new file in rw succeeded`, strings.TrimSpace(string(stdout))) + + stderr, err := ioutil.ReadFile(task.StderrPath) + require.NoError(err) + require.Equal(`touch: cannot touch '/tmp/task-path-ro/testfile': Read-only file system +touch: cannot touch '/tmp/task-path-ro/testfile-from-ro': Read-only file system`, strings.TrimSpace(string(stderr))) + + // testing exit code last so we can inspect output first + require.Zero(result.ExitCode) + + fromRWContent, err := ioutil.ReadFile(filepath.Join(tmpDir, "testfile-from-rw")) + require.NoError(err) + require.Equal("from-exec", strings.TrimSpace(string(fromRWContent))) +} + func encodeDriverHelper(require *require.Assertions, task *drivers.TaskConfig, taskConfig map[string]interface{}) { evalCtx := &hcl.EvalContext{ Functions: shared.GetStdlibFuncs(), diff --git a/drivers/java/driver.go b/drivers/java/driver.go index a9ac5a0fb..68373f6c8 100644 --- a/drivers/java/driver.go +++ b/drivers/java/driver.go @@ -344,6 +344,8 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *cstru TaskDir: cfg.TaskDir().Dir, StdoutPath: cfg.StdoutPath, StderrPath: cfg.StderrPath, + Mounts: cfg.Mounts, + Devices: cfg.Devices, } ps, err := exec.Launch(execCmd) diff --git a/drivers/shared/executor/executor.go b/drivers/shared/executor/executor.go index 85cd4cac4..1c5160fc0 100644 --- a/drivers/shared/executor/executor.go +++ b/drivers/shared/executor/executor.go @@ -22,6 +22,7 @@ import ( "github.com/hashicorp/nomad/client/stats" cstructs "github.com/hashicorp/nomad/client/structs" shelpers "github.com/hashicorp/nomad/helper/stats" + "github.com/hashicorp/nomad/plugins/drivers" ) const ( @@ -120,6 +121,12 @@ type ExecCommand struct { // doesn't enforce resource limits. To enforce limits, set ResourceLimits. // Using the cgroup does allow more precise cleanup of processes. BasicProcessCgroup bool + + // Mounts are the host paths to be be made available inside rootfs + Mounts []*drivers.MountConfig + + // Devices are the the device nodes to be created in isolation environment + Devices []*drivers.DeviceConfig } type nopCloser struct { diff --git a/drivers/shared/executor/executor_linux.go b/drivers/shared/executor/executor_linux.go index bb6da7890..92280059c 100644 --- a/drivers/shared/executor/executor_linux.go +++ b/drivers/shared/executor/executor_linux.go @@ -22,11 +22,14 @@ import ( "github.com/hashicorp/nomad/helper/discover" shelpers "github.com/hashicorp/nomad/helper/stats" "github.com/hashicorp/nomad/helper/uuid" + "github.com/hashicorp/nomad/plugins/drivers" "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer/cgroups" cgroupFs "github.com/opencontainers/runc/libcontainer/cgroups/fs" lconfigs "github.com/opencontainers/runc/libcontainer/configs" + ldevices "github.com/opencontainers/runc/libcontainer/devices" "github.com/syndtr/gocapability/capability" + "golang.org/x/sys/unix" ) const ( @@ -125,7 +128,11 @@ func (l *LibcontainerExecutor) Launch(command *ExecCommand) (*ProcessState, erro } // A container groups processes under the same isolation enforcement - container, err := factory.Create(l.id, newLibcontainerConfig(command)) + containerCfg, err := newLibcontainerConfig(command) + if err != nil { + return nil, fmt.Errorf("failed to configure container(%s): %v", l.id, err) + } + container, err := factory.Create(l.id, containerCfg) if err != nil { return nil, fmt.Errorf("failed to create container(%s): %v", l.id, err) } @@ -468,7 +475,7 @@ func configureCapabilities(cfg *lconfigs.Config, command *ExecCommand) { } -func configureIsolation(cfg *lconfigs.Config, command *ExecCommand) { +func configureIsolation(cfg *lconfigs.Config, command *ExecCommand) error { defaultMountFlags := syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV // set the new root directory for the container @@ -491,6 +498,14 @@ func configureIsolation(cfg *lconfigs.Config, command *ExecCommand) { } cfg.Devices = lconfigs.DefaultAutoCreatedDevices + if len(command.Devices) > 0 { + devs, err := cmdDevices(command.Devices) + if err != nil { + return err + } + cfg.Devices = append(cfg.Devices, devs...) + } + cfg.Mounts = []*lconfigs.Mount{ { Source: "tmpfs", @@ -532,6 +547,12 @@ func configureIsolation(cfg *lconfigs.Config, command *ExecCommand) { Flags: defaultMountFlags | syscall.MS_RDONLY, }, } + + if len(command.Mounts) > 0 { + cfg.Mounts = append(cfg.Mounts, cmdMounts(command.Mounts)...) + } + + return nil } func configureCgroups(cfg *lconfigs.Config, command *ExecCommand) error { @@ -592,7 +613,7 @@ func configureBasicCgroups(cfg *lconfigs.Config) error { return nil } -func newLibcontainerConfig(command *ExecCommand) *lconfigs.Config { +func newLibcontainerConfig(command *ExecCommand) (*lconfigs.Config, error) { cfg := &lconfigs.Config{ Cgroups: &lconfigs.Cgroup{ Resources: &lconfigs.Resources{ @@ -605,9 +626,13 @@ func newLibcontainerConfig(command *ExecCommand) *lconfigs.Config { } configureCapabilities(cfg, command) - configureIsolation(cfg, command) - configureCgroups(cfg, command) - return cfg + if err := configureIsolation(cfg, command); err != nil { + return nil, err + } + if err := configureCgroups(cfg, command); err != nil { + return nil, err + } + return cfg, nil } // JoinRootCgroup moves the current process to the cgroups of the init process @@ -631,3 +656,47 @@ func JoinRootCgroup(subsystems []string) error { return mErrs.ErrorOrNil() } + +// cmdDevices converts a list of driver.DeviceConfigs into excutor.Devices. +func cmdDevices(devices []*drivers.DeviceConfig) ([]*lconfigs.Device, error) { + if len(devices) == 0 { + return nil, nil + } + + r := make([]*lconfigs.Device, len(devices)) + + for i, d := range devices { + ed, err := ldevices.DeviceFromPath(d.HostPath, d.Permissions) + if err != nil { + return nil, fmt.Errorf("failed to make device out for %s: %v", d.HostPath, err) + } + ed.Path = d.TaskPath + r[i] = ed + } + + return r, nil +} + +// cmdMounts converts a list of driver.MountConfigs into excutor.Mounts. +func cmdMounts(mounts []*drivers.MountConfig) []*lconfigs.Mount { + if len(mounts) == 0 { + return nil + } + + r := make([]*lconfigs.Mount, len(mounts)) + + for i, m := range mounts { + flags := unix.MS_BIND + if m.Readonly { + flags |= unix.MS_RDONLY + } + r[i] = &lconfigs.Mount{ + Source: m.HostPath, + Destination: m.TaskPath, + Device: "bind", + Flags: flags, + } + } + + return r +} diff --git a/drivers/shared/executor/executor_linux_test.go b/drivers/shared/executor/executor_linux_test.go index e127825b3..041196ffc 100644 --- a/drivers/shared/executor/executor_linux_test.go +++ b/drivers/shared/executor/executor_linux_test.go @@ -17,8 +17,11 @@ import ( "github.com/hashicorp/nomad/client/testutil" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/mock" + "github.com/hashicorp/nomad/plugins/drivers" tu "github.com/hashicorp/nomad/testutil" + lconfigs "github.com/opencontainers/runc/libcontainer/configs" "github.com/stretchr/testify/require" + "golang.org/x/sys/unix" ) func init() { @@ -194,3 +197,66 @@ func TestExecutor_ClientCleanup(t *testing.T) { output1 := execCmd.stdout.(*bufferCloser).String() require.Equal(len(output), len(output1)) } + +func TestExecutor_cmdDevices(t *testing.T) { + input := []*drivers.DeviceConfig{ + { + HostPath: "/dev/null", + TaskPath: "/task/dev/null", + Permissions: "rwm", + }, + } + + expected := &lconfigs.Device{ + Path: "/task/dev/null", + Type: 99, + Major: 1, + Minor: 3, + Permissions: "rwm", + } + + found, err := cmdDevices(input) + require.NoError(t, err) + require.Len(t, found, 1) + + // ignore file permission and ownership + // as they are host specific potentially + d := found[0] + d.FileMode = 0 + d.Uid = 0 + d.Gid = 0 + + require.EqualValues(t, expected, d) +} + +func TestExecutor_cmdMounts(t *testing.T) { + input := []*drivers.MountConfig{ + { + HostPath: "/host/path-ro", + TaskPath: "/task/path-ro", + Readonly: true, + }, + { + HostPath: "/host/path-rw", + TaskPath: "/task/path-rw", + Readonly: false, + }, + } + + expected := []*lconfigs.Mount{ + { + Source: "/host/path-ro", + Destination: "/task/path-ro", + Flags: unix.MS_BIND | unix.MS_RDONLY, + Device: "bind", + }, + { + Source: "/host/path-rw", + Destination: "/task/path-rw", + Flags: unix.MS_BIND, + Device: "bind", + }, + } + + require.EqualValues(t, expected, cmdMounts(input)) +} From bc6929b8fdf6feed62fc975d132e43121ffacc5f Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Wed, 12 Dec 2018 09:17:31 -0500 Subject: [PATCH 62/71] fixup! device attributes in `nomad node status -verbose` --- command/helper_devices_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command/helper_devices_test.go b/command/helper_devices_test.go index 028d72701..a54af1cad 100644 --- a/command/helper_devices_test.go +++ b/command/helper_devices_test.go @@ -254,11 +254,11 @@ func TestGetDeviceAttributes(t *testing.T) { Name: "Name", Attributes: map[string]*api.Attribute{ - "utilization": &api.Attribute{ + "utilization": { FloatVal: helper.Float64ToPtr(0.78), Unit: "%", }, - "filesystem": &api.Attribute{ + "filesystem": { StringVal: helper.StringToPtr("ext4"), }, }, From 875dd737cbe987bc92c5007880448d76f97ade75 Mon Sep 17 00:00:00 2001 From: Danielle Tomlinson Date: Wed, 12 Dec 2018 16:30:01 +0100 Subject: [PATCH 63/71] client: updateAlloc release lock after read The allocLock is used to synchronize access to the alloc runner map, not to ensure internal consistency of the alloc runners themselves. This updates the updateAlloc process to avoid hanging on to an exclusive lock of the map while applying changes to allocrunners themselves, as they should be internally consistent. This fixes a bug where any client allocation api will block during the shutdown or updating of an allocrunner and its child taskrunners. --- client/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/client.go b/client/client.go index f3565727b..229b62240 100644 --- a/client/client.go +++ b/client/client.go @@ -1996,9 +1996,9 @@ func (c *Client) removeAlloc(allocID string) { // updateAlloc is invoked when we should update an allocation func (c *Client) updateAlloc(update *structs.Allocation) { - c.allocLock.Lock() - defer c.allocLock.Unlock() + c.allocLock.RLock() ar, ok := c.allocs[update.ID] + c.allocLock.RUnlock() if !ok { c.logger.Warn("cannot update nonexistent alloc", "alloc_id", update.ID) return From 1a34550c8a42377803b137da3868d956d8c88b7d Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Wed, 12 Dec 2018 18:52:06 +0000 Subject: [PATCH 64/71] improved code for readability --- nomad/rpc.go | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/nomad/rpc.go b/nomad/rpc.go index 9edf5df5c..aa681d5f8 100644 --- a/nomad/rpc.go +++ b/nomad/rpc.go @@ -51,6 +51,7 @@ type rpcHandler struct { *Server logger log.Logger gologger *golog.Logger + acceptLoopDelay time.Duration } func newRpcHandler(s *Server) *rpcHandler { @@ -84,7 +85,6 @@ type RPCContext struct { // listen is used to listen for incoming RPC connections func (r *rpcHandler) listen(ctx context.Context) { defer close(r.listenerCh) - var tempDelay time.Duration for { select { case <-ctx.Done(): @@ -99,30 +99,44 @@ func (r *rpcHandler) listen(ctx context.Context) { if r.shutdown { return } - - if tempDelay == 0 { - tempDelay = 5 * time.Millisecond - } else { - tempDelay *= 2 - } - maxDelay := 5 * time.Second - if ne, ok := err.(net.Error); ok && ne.Temporary() { - maxDelay = 1 * time.Second - } - if tempDelay > maxDelay { - tempDelay = maxDelay - } - r.logger.Error("failed to accept RPC conn", "error", err, "delay", tempDelay) - time.Sleep(tempDelay) + r.handleAcceptErr(err, ctx) continue } - tempDelay = 0 + // No error, reset delay loop + r.acceptLoopDelay = 0 go r.handleConn(ctx, conn, &RPCContext{Conn: conn}) metrics.IncrCounter([]string{"nomad", "rpc", "accept_conn"}, 1) } } +// Sleep to avoid spamming the log, with a maximum delay according to whether or not the error is temporary +func (r *rpcHandler) handleAcceptErr(err error, ctx context.Context) { + const baseAcceptLoopDelay = 5 * time.Millisecond + const maxAcceptLoopDelay = 5 * time.Second + const maxAcceptLoopDelayTemporaryError = 1 * time.Second + + if r.acceptLoopDelay == 0 { + r.acceptLoopDelay = baseAcceptLoopDelay + } else { + r.acceptLoopDelay *= 2 + } + temporaryError := false + if ne, ok := err.(net.Error); ok && ne.Temporary() { + temporaryError = true + } + if temporaryError && r.acceptLoopDelay > maxAcceptLoopDelayTemporaryError { + r.acceptLoopDelay = maxAcceptLoopDelayTemporaryError + } else if r.acceptLoopDelay > maxAcceptLoopDelay { + r.acceptLoopDelay = maxAcceptLoopDelay + } + r.logger.Error("failed to accept RPC conn", "error", err, "delay", r.acceptLoopDelay) + select { + case <-ctx.Done(): + case <-time.After(maxAcceptLoopDelay): + } +} + // handleConn is used to determine if this is a Raft or // Nomad type RPC connection and invoke the correct handler func (r *rpcHandler) handleConn(ctx context.Context, conn net.Conn, rpcCtx *RPCContext) { From 44a6d9dffd1cd2cd366b4062d8c32ac4b88cacc9 Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Wed, 12 Dec 2018 19:09:06 +0000 Subject: [PATCH 65/71] gofmt --- nomad/rpc.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nomad/rpc.go b/nomad/rpc.go index aa681d5f8..f39c52c76 100644 --- a/nomad/rpc.go +++ b/nomad/rpc.go @@ -49,8 +49,8 @@ const ( type rpcHandler struct { *Server - logger log.Logger - gologger *golog.Logger + logger log.Logger + gologger *golog.Logger acceptLoopDelay time.Duration } @@ -102,7 +102,7 @@ func (r *rpcHandler) listen(ctx context.Context) { r.handleAcceptErr(err, ctx) continue } - // No error, reset delay loop + // No error, reset loop delay r.acceptLoopDelay = 0 go r.handleConn(ctx, conn, &RPCContext{Conn: conn}) @@ -113,7 +113,7 @@ func (r *rpcHandler) listen(ctx context.Context) { // Sleep to avoid spamming the log, with a maximum delay according to whether or not the error is temporary func (r *rpcHandler) handleAcceptErr(err error, ctx context.Context) { const baseAcceptLoopDelay = 5 * time.Millisecond - const maxAcceptLoopDelay = 5 * time.Second + const maxAcceptLoopDelay = 5 * time.Second const maxAcceptLoopDelayTemporaryError = 1 * time.Second if r.acceptLoopDelay == 0 { From 33b9f9d3aec755aa7f274cd778c07d9fbfe7cf17 Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Wed, 12 Dec 2018 19:16:41 +0000 Subject: [PATCH 66/71] fixed bug in loop delay --- nomad/rpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nomad/rpc.go b/nomad/rpc.go index f39c52c76..58e09303b 100644 --- a/nomad/rpc.go +++ b/nomad/rpc.go @@ -133,7 +133,7 @@ func (r *rpcHandler) handleAcceptErr(err error, ctx context.Context) { r.logger.Error("failed to accept RPC conn", "error", err, "delay", r.acceptLoopDelay) select { case <-ctx.Done(): - case <-time.After(maxAcceptLoopDelay): + case <-time.After(r.acceptLoopDelay): } } From d5dd9c2c692f951356f81bcc74847441c7c19eea Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Wed, 12 Dec 2018 14:32:22 -0800 Subject: [PATCH 67/71] fix iops related tests --- nomad/structs/diff_test.go | 12 ++++++++++++ nomad/structs/funcs_test.go | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/nomad/structs/diff_test.go b/nomad/structs/diff_test.go index 4b18f4a1e..42321a413 100644 --- a/nomad/structs/diff_test.go +++ b/nomad/structs/diff_test.go @@ -3253,6 +3253,12 @@ func TestTaskDiff(t *testing.T) { Old: "100", New: "200", }, + { + Type: DiffTypeNone, + Name: "IOPS", + Old: "0", + New: "0", + }, { Type: DiffTypeNone, Name: "MemoryMB", @@ -3574,6 +3580,12 @@ func TestTaskDiff(t *testing.T) { Old: "100", New: "100", }, + { + Type: DiffTypeNone, + Name: "IOPS", + Old: "0", + New: "0", + }, { Type: DiffTypeNone, Name: "MemoryMB", diff --git a/nomad/structs/funcs_test.go b/nomad/structs/funcs_test.go index d29c8e178..486440e63 100644 --- a/nomad/structs/funcs_test.go +++ b/nomad/structs/funcs_test.go @@ -210,6 +210,18 @@ func TestAllocsFit_TerminalAlloc_Old(t *testing.T) { CPU: 2000, MemoryMB: 2048, DiskMB: 10000, + Networks: []*NetworkResource{ + { + Device: "eth0", + CIDR: "10.0.0.0/8", + MBits: 100, + }, + }, + }, + Reserved: &Resources{ + CPU: 1000, + MemoryMB: 1024, + DiskMB: 5000, Networks: []*NetworkResource{ { Device: "eth0", From 3ee692cb45fe20423ef271b74ba2cad5d2d85cef Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Wed, 12 Dec 2018 23:10:24 +0000 Subject: [PATCH 68/71] some changes for more idiomatic code --- nomad/rpc.go | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/nomad/rpc.go b/nomad/rpc.go index 58e09303b..ed662762a 100644 --- a/nomad/rpc.go +++ b/nomad/rpc.go @@ -49,9 +49,8 @@ const ( type rpcHandler struct { *Server - logger log.Logger - gologger *golog.Logger - acceptLoopDelay time.Duration + logger log.Logger + gologger *golog.Logger } func newRpcHandler(s *Server) *rpcHandler { @@ -85,6 +84,8 @@ type RPCContext struct { // listen is used to listen for incoming RPC connections func (r *rpcHandler) listen(ctx context.Context) { defer close(r.listenerCh) + + var acceptLoopDelay time.Duration for { select { case <-ctx.Done(): @@ -99,41 +100,46 @@ func (r *rpcHandler) listen(ctx context.Context) { if r.shutdown { return } - r.handleAcceptErr(err, ctx) + r.handleAcceptErr(ctx, err, &acceptLoopDelay) continue } // No error, reset loop delay - r.acceptLoopDelay = 0 + acceptLoopDelay = 0 go r.handleConn(ctx, conn, &RPCContext{Conn: conn}) metrics.IncrCounter([]string{"nomad", "rpc", "accept_conn"}, 1) } } -// Sleep to avoid spamming the log, with a maximum delay according to whether or not the error is temporary -func (r *rpcHandler) handleAcceptErr(err error, ctx context.Context) { - const baseAcceptLoopDelay = 5 * time.Millisecond - const maxAcceptLoopDelay = 5 * time.Second - const maxAcceptLoopDelayTemporaryError = 1 * time.Second +// handleAcceptErr sleeps to avoid spamming the log, +// with a maximum delay according to whether or not the error is temporary +func (r *rpcHandler) handleAcceptErr(ctx context.Context, err error, loopDelay *time.Duration) { + const baseDelay = 5 * time.Millisecond + const maxDelayPerm = 5 * time.Second + const maxDelayTemp = 1 * time.Second - if r.acceptLoopDelay == 0 { - r.acceptLoopDelay = baseAcceptLoopDelay + if *loopDelay == 0 { + *loopDelay = baseDelay } else { - r.acceptLoopDelay *= 2 + *loopDelay *= 2 } + temporaryError := false if ne, ok := err.(net.Error); ok && ne.Temporary() { temporaryError = true } - if temporaryError && r.acceptLoopDelay > maxAcceptLoopDelayTemporaryError { - r.acceptLoopDelay = maxAcceptLoopDelayTemporaryError - } else if r.acceptLoopDelay > maxAcceptLoopDelay { - r.acceptLoopDelay = maxAcceptLoopDelay + + if temporaryError && *loopDelay > maxDelayTemp { + *loopDelay = maxDelayTemp + } else if *loopDelay > maxDelayPerm { + *loopDelay = maxDelayPerm } - r.logger.Error("failed to accept RPC conn", "error", err, "delay", r.acceptLoopDelay) + + r.logger.Error("failed to accept RPC conn", "error", err, "delay", *loopDelay) + select { case <-ctx.Done(): - case <-time.After(r.acceptLoopDelay): + case <-time.After(*loopDelay): } } From 5ef81ed6734cfa814c54784fbd4849ddcf27d6b8 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Wed, 12 Dec 2018 20:40:38 -0500 Subject: [PATCH 69/71] tests: ensure exec tests pass valid task resources (#4992) Prior to 97f33bb1537d04905cb84199672bcdf46ebb4e65, executor cgroup validation errors were silently ignored. Enforcing them reveals test cases that missed them. This doesn't change customer facing contract, as resource struct is is either configured or we default to 100 (much higher than 2). --- drivers/exec/driver_test.go | 58 +++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/drivers/exec/driver_test.go b/drivers/exec/driver_test.go index 6de0a7c72..577ed96bb 100644 --- a/drivers/exec/driver_test.go +++ b/drivers/exec/driver_test.go @@ -13,14 +13,14 @@ import ( "testing" "time" - dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" - "github.com/hashicorp/hcl2/hcl" ctestutils "github.com/hashicorp/nomad/client/testutil" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/helper/testtask" "github.com/hashicorp/nomad/helper/uuid" + "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/plugins/drivers" + dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" "github.com/hashicorp/nomad/plugins/shared" "github.com/hashicorp/nomad/plugins/shared/hclspec" "github.com/hashicorp/nomad/testutil" @@ -34,6 +34,17 @@ func TestMain(m *testing.M) { } } +var testResources = &drivers.Resources{ + NomadResources: &structs.Resources{ + MemoryMB: 128, + CPU: 100, + }, + LinuxResources: &drivers.LinuxResources{ + MemoryLimitBytes: 134217728, + CPUShares: 100, + }, +} + func TestExecDriver_Fingerprint_NonLinux(t *testing.T) { if !testutil.IsTravis() { t.Parallel() @@ -84,8 +95,9 @@ func TestExecDriver_StartWait(t *testing.T) { d := NewExecDriver(testlog.HCLogger(t)) harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ - ID: uuid.Generate(), - Name: "test", + ID: uuid.Generate(), + Name: "test", + Resources: testResources, } taskConfig := map[string]interface{}{ @@ -116,8 +128,9 @@ func TestExecDriver_StartWaitStop(t *testing.T) { d := NewExecDriver(testlog.HCLogger(t)) harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ - ID: uuid.Generate(), - Name: "test", + ID: uuid.Generate(), + Name: "test", + Resources: testResources, } taskConfig := map[string]interface{}{ @@ -175,8 +188,9 @@ func TestExecDriver_StartWaitStopKill(t *testing.T) { d := NewExecDriver(testlog.HCLogger(t)) harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ - ID: uuid.Generate(), - Name: "test", + ID: uuid.Generate(), + Name: "test", + Resources: testResources, } taskConfig := map[string]interface{}{ @@ -235,8 +249,9 @@ func TestExecDriver_StartWaitRecover(t *testing.T) { d := NewExecDriver(testlog.HCLogger(t)) harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ - ID: uuid.Generate(), - Name: "test", + ID: uuid.Generate(), + Name: "test", + Resources: testResources, } taskConfig := map[string]interface{}{ @@ -304,8 +319,9 @@ func TestExecDriver_Stats(t *testing.T) { d := NewExecDriver(testlog.HCLogger(t)) harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ - ID: uuid.Generate(), - Name: "test", + ID: uuid.Generate(), + Name: "test", + Resources: testResources, } taskConfig := map[string]interface{}{ @@ -337,8 +353,9 @@ func TestExecDriver_Start_Wait_AllocDir(t *testing.T) { d := NewExecDriver(testlog.HCLogger(t)) harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ - ID: uuid.Generate(), - Name: "sleep", + ID: uuid.Generate(), + Name: "sleep", + Resources: testResources, } cleanup := harness.MkAllocDir(task, false) defer cleanup() @@ -385,9 +402,10 @@ func TestExecDriver_User(t *testing.T) { d := NewExecDriver(testlog.HCLogger(t)) harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ - ID: uuid.Generate(), - Name: "sleep", - User: "alice", + ID: uuid.Generate(), + Name: "sleep", + User: "alice", + Resources: testResources, } cleanup := harness.MkAllocDir(task, false) defer cleanup() @@ -418,8 +436,9 @@ func TestExecDriver_HandlerExec(t *testing.T) { d := NewExecDriver(testlog.HCLogger(t)) harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ - ID: uuid.Generate(), - Name: "sleep", + ID: uuid.Generate(), + Name: "sleep", + Resources: testResources, } cleanup := harness.MkAllocDir(task, false) defer cleanup() @@ -507,6 +526,7 @@ func TestExecDriver_DevicesAndMounts(t *testing.T) { task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "test", + Resources: testResources, StdoutPath: filepath.Join(tmpDir, "task-stdout"), StderrPath: filepath.Join(tmpDir, "task-stderr"), Devices: []*drivers.DeviceConfig{ From 63cd9c972bba194842c60bd8e16f716c038c9e94 Mon Sep 17 00:00:00 2001 From: Michael Lange Date: Thu, 13 Dec 2018 07:39:16 -0800 Subject: [PATCH 70/71] Always create a running allocation when testing task state --- ui/tests/acceptance/task-detail-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/tests/acceptance/task-detail-test.js b/ui/tests/acceptance/task-detail-test.js index efa3cc877..177df255d 100644 --- a/ui/tests/acceptance/task-detail-test.js +++ b/ui/tests/acceptance/task-detail-test.js @@ -194,7 +194,7 @@ moduleForAcceptance('Acceptance | task detail (no addresses)', { server.create('agent'); server.create('node'); server.create('job'); - allocation = server.create('allocation', 'withoutTaskWithPorts'); + allocation = server.create('allocation', 'withoutTaskWithPorts', { clientStatus: 'running' }); task = server.db.taskStates.where({ allocationId: allocation.id })[0]; Task.visit({ id: allocation.id, name: task.name }); From 40697ab6c15a219a2ff896ccaddbb531c7c45ee6 Mon Sep 17 00:00:00 2001 From: Brian Lalor Date: Thu, 13 Dec 2018 13:22:17 -0500 Subject: [PATCH 71/71] Fix output of 'nomad deployment fail' with no arg --- command/deployment_fail.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command/deployment_fail.go b/command/deployment_fail.go index 25ad154b7..2b795c631 100644 --- a/command/deployment_fail.go +++ b/command/deployment_fail.go @@ -79,10 +79,10 @@ func (c *DeploymentFailCommand) Run(args []string) int { return 1 } - // Check that we got no arguments + // Check that we got one argument args = flags.Args() if l := len(args); l != 1 { - c.Ui.Error("This command takes no arguments") + c.Ui.Error("This command takes one argument: ") c.Ui.Error(commandErrorText(c)) return 1 }