Update dependencies for logrus rename
Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
parent
1d2a079f08
commit
1491293260
@ -12,10 +12,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
"github.com/containerd/containerd/testutil"
|
"github.com/containerd/containerd/testutil"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -7,12 +7,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/containerd/containerd/progress"
|
"github.com/containerd/containerd/progress"
|
||||||
"github.com/containerd/containerd/rootfs"
|
"github.com/containerd/containerd/rootfs"
|
||||||
"github.com/containerd/containerd/snapshot"
|
"github.com/containerd/containerd/snapshot"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ github.com/containerd/go-runc 2774a2ea124a5c2d0aba13b5c2dd8a5a9a48775d
|
|||||||
github.com/containerd/console 7fed77e673ca4abcd0cbd6d4d0e0e22137cbd778
|
github.com/containerd/console 7fed77e673ca4abcd0cbd6d4d0e0e22137cbd778
|
||||||
github.com/containerd/cgroups 4fd64a776f25b5540cddcb72eea6e35e58baca6e
|
github.com/containerd/cgroups 4fd64a776f25b5540cddcb72eea6e35e58baca6e
|
||||||
github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87
|
github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87
|
||||||
github.com/docker/go-events aa2e3b613fbbfdddbe055a7b9e3ce271cfd83eca
|
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||||
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||||
github.com/prometheus/client_golang v0.8.0
|
github.com/prometheus/client_golang v0.8.0
|
||||||
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
|
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
|
||||||
@ -35,8 +35,9 @@ github.com/BurntSushi/toml v0.2.0-21-g9906417
|
|||||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||||
github.com/Microsoft/go-winio v0.4.3
|
github.com/Microsoft/go-winio v0.4.3
|
||||||
github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
|
github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
|
||||||
github.com/Microsoft/hcsshim v0.5.15
|
# Based on v0.6.0, pending https://github.com/Microsoft/hcsshim/pull/136
|
||||||
github.com/Azure/go-ansiterm fa152c58bc15761d0200cb75fe958b89a9d4888e
|
github.com/Microsoft/hcsshim 007f139973e2d02396f37b7f0a87bedec7716dce https://github.com/dmcgowan/hcsshim.git
|
||||||
|
github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e
|
||||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf
|
github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf
|
||||||
|
2
vendor/github.com/Azure/go-ansiterm/parser.go
generated
vendored
2
vendor/github.com/Azure/go-ansiterm/parser.go
generated
vendored
@ -5,7 +5,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger *logrus.Logger
|
var logger *logrus.Logger
|
||||||
|
2
vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
generated
vendored
2
vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/Azure/go-ansiterm"
|
"github.com/Azure/go-ansiterm"
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger *logrus.Logger
|
var logger *logrus.Logger
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/activatelayer.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/activatelayer.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// ActivateLayer will find the layer with the given id and mount it's filesystem.
|
// ActivateLayer will find the layer with the given id and mount it's filesystem.
|
||||||
// For a read/write layer, the mounted filesystem will appear as a volume on the
|
// For a read/write layer, the mounted filesystem will appear as a volume on the
|
||||||
|
74
vendor/github.com/Microsoft/hcsshim/container.go
generated
vendored
74
vendor/github.com/Microsoft/hcsshim/container.go
generated
vendored
@ -4,12 +4,11 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -20,6 +19,7 @@ const (
|
|||||||
pendingUpdatesQuery = `{ "PropertyTypes" : ["PendingUpdates"]}`
|
pendingUpdatesQuery = `{ "PropertyTypes" : ["PendingUpdates"]}`
|
||||||
statisticsQuery = `{ "PropertyTypes" : ["Statistics"]}`
|
statisticsQuery = `{ "PropertyTypes" : ["Statistics"]}`
|
||||||
processListQuery = `{ "PropertyTypes" : ["ProcessList"]}`
|
processListQuery = `{ "PropertyTypes" : ["ProcessList"]}`
|
||||||
|
mappedVirtualDiskQuery = `{ "PropertyTypes" : ["MappedVirtualDisk"]}`
|
||||||
)
|
)
|
||||||
|
|
||||||
type container struct {
|
type container struct {
|
||||||
@ -36,7 +36,6 @@ type ContainerProperties struct {
|
|||||||
SystemType string
|
SystemType string
|
||||||
Owner string
|
Owner string
|
||||||
SiloGUID string `json:"SiloGuid,omitempty"`
|
SiloGUID string `json:"SiloGuid,omitempty"`
|
||||||
IsDummy bool `json:",omitempty"`
|
|
||||||
RuntimeID string `json:"RuntimeId,omitempty"`
|
RuntimeID string `json:"RuntimeId,omitempty"`
|
||||||
IsRuntimeTemplate bool `json:",omitempty"`
|
IsRuntimeTemplate bool `json:",omitempty"`
|
||||||
RuntimeImagePath string `json:",omitempty"`
|
RuntimeImagePath string `json:",omitempty"`
|
||||||
@ -46,6 +45,7 @@ type ContainerProperties struct {
|
|||||||
ObRoot string `json:",omitempty"`
|
ObRoot string `json:",omitempty"`
|
||||||
Statistics Statistics `json:",omitempty"`
|
Statistics Statistics `json:",omitempty"`
|
||||||
ProcessList []ProcessListItem `json:",omitempty"`
|
ProcessList []ProcessListItem `json:",omitempty"`
|
||||||
|
MappedVirtualDiskControllers map[int]MappedVirtualDiskController `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemoryStats holds the memory statistics for a container
|
// MemoryStats holds the memory statistics for a container
|
||||||
@ -105,6 +105,11 @@ type ProcessListItem struct {
|
|||||||
UserTime100ns uint64 `json:",omitempty"`
|
UserTime100ns uint64 `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MappedVirtualDiskController is the structure of an item returned by a MappedVirtualDiskList call on a container
|
||||||
|
type MappedVirtualDiskController struct {
|
||||||
|
MappedVirtualDisks map[int]MappedVirtualDisk `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// Type of Request Support in ModifySystem
|
// Type of Request Support in ModifySystem
|
||||||
type RequestType string
|
type RequestType string
|
||||||
|
|
||||||
@ -122,7 +127,7 @@ const (
|
|||||||
// Supported resource types are Network and Request Types are Add/Remove
|
// Supported resource types are Network and Request Types are Add/Remove
|
||||||
type ResourceModificationRequestResponse struct {
|
type ResourceModificationRequestResponse struct {
|
||||||
Resource ResourceType `json:"ResourceType"`
|
Resource ResourceType `json:"ResourceType"`
|
||||||
Data string `json:"Settings"`
|
Data interface{} `json:"Settings"`
|
||||||
Request RequestType `json:"RequestType,omitempty"`
|
Request RequestType `json:"RequestType,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +211,6 @@ func createContainerWithJSON(id string, c *ContainerConfig, additionalJSON strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf(title+" succeeded id=%s handle=%d", id, container.handle)
|
logrus.Debugf(title+" succeeded id=%s handle=%d", id, container.handle)
|
||||||
runtime.SetFinalizer(container, closeContainer)
|
|
||||||
return container, nil
|
return container, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +268,6 @@ func OpenContainer(id string) (Container, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf(title+" succeeded id=%s handle=%d", id, handle)
|
logrus.Debugf(title+" succeeded id=%s handle=%d", id, handle)
|
||||||
runtime.SetFinalizer(container, closeContainer)
|
|
||||||
return container, nil
|
return container, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,6 +494,55 @@ func (container *container) ProcessList() ([]ProcessListItem, error) {
|
|||||||
return properties.ProcessList, nil
|
return properties.ProcessList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MappedVirtualDisks returns a map of the controllers and the disks mapped
|
||||||
|
// to a container.
|
||||||
|
//
|
||||||
|
// Example of JSON returned by the query.
|
||||||
|
//{
|
||||||
|
// "Id":"1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3_svm",
|
||||||
|
// "SystemType":"Container",
|
||||||
|
// "RuntimeOsType":"Linux",
|
||||||
|
// "RuntimeId":"00000000-0000-0000-0000-000000000000",
|
||||||
|
// "State":"Running",
|
||||||
|
// "MappedVirtualDiskControllers":{
|
||||||
|
// "0":{
|
||||||
|
// "MappedVirtualDisks":{
|
||||||
|
// "2":{
|
||||||
|
// "HostPath":"C:\\lcow\\lcow\\scratch\\1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3.vhdx",
|
||||||
|
// "ContainerPath":"/mnt/gcs/LinuxServiceVM/scratch",
|
||||||
|
// "Lun":2,
|
||||||
|
// "CreateInUtilityVM":true
|
||||||
|
// },
|
||||||
|
// "3":{
|
||||||
|
// "HostPath":"C:\\lcow\\lcow\\1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3\\sandbox.vhdx",
|
||||||
|
// "Lun":3,
|
||||||
|
// "CreateInUtilityVM":true,
|
||||||
|
// "AttachOnly":true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) {
|
||||||
|
container.handleLock.RLock()
|
||||||
|
defer container.handleLock.RUnlock()
|
||||||
|
operation := "MappedVirtualDiskList"
|
||||||
|
title := "HCSShim::Container::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", container.id)
|
||||||
|
|
||||||
|
if container.handle == 0 {
|
||||||
|
return nil, makeContainerError(container, operation, "", ErrAlreadyClosed)
|
||||||
|
}
|
||||||
|
|
||||||
|
properties, err := container.properties(mappedVirtualDiskQuery)
|
||||||
|
if err != nil {
|
||||||
|
return nil, makeContainerError(container, operation, "", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf(title+" succeeded id=%s", container.id)
|
||||||
|
return properties.MappedVirtualDiskControllers, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Pause pauses the execution of the container. This feature is not enabled in TP5.
|
// Pause pauses the execution of the container. This feature is not enabled in TP5.
|
||||||
func (container *container) Pause() error {
|
func (container *container) Pause() error {
|
||||||
container.handleLock.RLock()
|
container.handleLock.RLock()
|
||||||
@ -588,8 +640,7 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
|
|||||||
return nil, makeContainerError(container, operation, "", err)
|
return nil, makeContainerError(container, operation, "", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
|
logrus.Debugf(title+" succeeded id=%s processid=%d", container.id, process.processID)
|
||||||
runtime.SetFinalizer(process, closeProcess)
|
|
||||||
return process, nil
|
return process, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +677,6 @@ func (container *container) OpenProcess(pid int) (Process, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
|
logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
|
||||||
runtime.SetFinalizer(process, closeProcess)
|
|
||||||
return process, nil
|
return process, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,17 +702,11 @@ func (container *container) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
container.handle = 0
|
container.handle = 0
|
||||||
runtime.SetFinalizer(container, nil)
|
|
||||||
|
|
||||||
logrus.Debugf(title+" succeeded id=%s", container.id)
|
logrus.Debugf(title+" succeeded id=%s", container.id)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// closeContainer wraps container.Close for use by a finalizer
|
|
||||||
func closeContainer(container *container) {
|
|
||||||
container.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (container *container) registerCallback() error {
|
func (container *container) registerCallback() error {
|
||||||
context := ¬ifcationWatcherContext{
|
context := ¬ifcationWatcherContext{
|
||||||
channels: newChannels(),
|
channels: newChannels(),
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/createlayer.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/createlayer.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// CreateLayer creates a new, empty, read-only layer on the filesystem based on
|
// CreateLayer creates a new, empty, read-only layer on the filesystem based on
|
||||||
// the parent layer provided.
|
// the parent layer provided.
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// CreateSandboxLayer creates and populates new read-write layer for use by a container.
|
// CreateSandboxLayer creates and populates new read-write layer for use by a container.
|
||||||
// This requires both the id of the direct parent layer, as well as the full list
|
// This requires both the id of the direct parent layer, as well as the full list
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// DeactivateLayer will dismount a layer that was mounted via ActivateLayer.
|
// DeactivateLayer will dismount a layer that was mounted via ActivateLayer.
|
||||||
func DeactivateLayer(info DriverInfo, id string) error {
|
func DeactivateLayer(info DriverInfo, id string) error {
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/destroylayer.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/destroylayer.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// DestroyLayer will remove the on-disk files representing the layer with the given
|
// DestroyLayer will remove the on-disk files representing the layer with the given
|
||||||
// id, including that layer's containing folder, if any.
|
// id, including that layer's containing folder, if any.
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// ExpandSandboxSize expands the size of a layer to at least size bytes.
|
// ExpandSandboxSize expands the size of a layer to at least size bytes.
|
||||||
func ExpandSandboxSize(info DriverInfo, layerId string, size uint64) error {
|
func ExpandSandboxSize(info DriverInfo, layerId string, size uint64) error {
|
||||||
|
4
vendor/github.com/Microsoft/hcsshim/exportlayer.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/exportlayer.go
generated
vendored
@ -4,11 +4,10 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/Microsoft/go-winio"
|
"github.com/Microsoft/go-winio"
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExportLayer will create a folder at exportFolderPath and fill that folder with
|
// ExportLayer will create a folder at exportFolderPath and fill that folder with
|
||||||
@ -143,7 +142,6 @@ func NewLayerReader(info DriverInfo, layerID string, parentLayerPaths []string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, makeError(err, "ExportLayerBegin", "")
|
return nil, makeError(err, "ExportLayerBegin", "")
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(r, func(r *FilterLayerReader) { r.Close() })
|
|
||||||
return r, err
|
return r, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/getlayermountpath.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/getlayermountpath.go
generated
vendored
@ -3,7 +3,7 @@ package hcsshim
|
|||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetLayerMountPath will look for a mounted layer with the given id and return
|
// GetLayerMountPath will look for a mounted layer with the given id and return
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// GetSharedBaseImages will enumerate the images stored in the common central
|
// GetSharedBaseImages will enumerate the images stored in the common central
|
||||||
// image store and return descriptive info about those images for the purpose
|
// image store and return descriptive info about those images for the purpose
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/hcsshim.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/hcsshim.go
generated
vendored
@ -8,7 +8,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
|
//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
|
||||||
|
183
vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
generated
vendored
Normal file
183
vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
generated
vendored
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
package hcsshim
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HNSEndpoint represents a network endpoint in HNS
|
||||||
|
type HNSEndpoint struct {
|
||||||
|
Id string `json:"ID,omitempty"`
|
||||||
|
Name string `json:",omitempty"`
|
||||||
|
VirtualNetwork string `json:",omitempty"`
|
||||||
|
VirtualNetworkName string `json:",omitempty"`
|
||||||
|
Policies []json.RawMessage `json:",omitempty"`
|
||||||
|
MacAddress string `json:",omitempty"`
|
||||||
|
IPAddress net.IP `json:",omitempty"`
|
||||||
|
DNSSuffix string `json:",omitempty"`
|
||||||
|
DNSServerList string `json:",omitempty"`
|
||||||
|
GatewayAddress string `json:",omitempty"`
|
||||||
|
EnableInternalDNS bool `json:",omitempty"`
|
||||||
|
DisableICC bool `json:",omitempty"`
|
||||||
|
PrefixLength uint8 `json:",omitempty"`
|
||||||
|
IsRemoteEndpoint bool `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
|
||||||
|
func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
|
||||||
|
endpoint := &HNSEndpoint{}
|
||||||
|
err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoint, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
|
||||||
|
func HNSListEndpointRequest() ([]HNSEndpoint, error) {
|
||||||
|
var endpoint []HNSEndpoint
|
||||||
|
err := hnsCall("GET", "/endpoints/", "", &endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoint, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
|
||||||
|
func HotAttachEndpoint(containerID string, endpointID string) error {
|
||||||
|
return modifyNetworkEndpoint(containerID, endpointID, Add)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
|
||||||
|
func HotDetachEndpoint(containerID string, endpointID string) error {
|
||||||
|
return modifyNetworkEndpoint(containerID, endpointID, Remove)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyContainer corresponding to the container id, by sending a request
|
||||||
|
func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
|
||||||
|
container, err := OpenContainer(id)
|
||||||
|
if err != nil {
|
||||||
|
if IsNotExist(err) {
|
||||||
|
return ErrComputeSystemDoesNotExist
|
||||||
|
}
|
||||||
|
return getInnerError(err)
|
||||||
|
}
|
||||||
|
defer container.Close()
|
||||||
|
err = container.Modify(request)
|
||||||
|
if err != nil {
|
||||||
|
if IsNotSupported(err) {
|
||||||
|
return ErrPlatformNotSupported
|
||||||
|
}
|
||||||
|
return getInnerError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
|
||||||
|
requestMessage := &ResourceModificationRequestResponse{
|
||||||
|
Resource: Network,
|
||||||
|
Request: request,
|
||||||
|
Data: endpointID,
|
||||||
|
}
|
||||||
|
err := modifyContainer(containerID, requestMessage)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHNSEndpointByID
|
||||||
|
func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
|
||||||
|
return HNSEndpointRequest("GET", endpointID, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHNSNetworkName filtered by Name
|
||||||
|
func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
|
||||||
|
hnsResponse, err := HNSListEndpointRequest()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, hnsEndpoint := range hnsResponse {
|
||||||
|
if hnsEndpoint.Name == endpointName {
|
||||||
|
return &hnsEndpoint, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Endpoint %v not found", endpointName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
|
||||||
|
func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
|
||||||
|
operation := "Create"
|
||||||
|
title := "HCSShim::HNSEndpoint::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", endpoint.Id)
|
||||||
|
|
||||||
|
jsonString, err := json.Marshal(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return HNSEndpointRequest("POST", "", string(jsonString))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Endpoint by sending EndpointRequest to HNS
|
||||||
|
func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
|
||||||
|
operation := "Delete"
|
||||||
|
title := "HCSShim::HNSEndpoint::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", endpoint.Id)
|
||||||
|
|
||||||
|
return HNSEndpointRequest("DELETE", endpoint.Id, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Endpoint by sending EndpointRequest to HNS
|
||||||
|
func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
|
||||||
|
operation := "Update"
|
||||||
|
title := "HCSShim::HNSEndpoint::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", endpoint.Id)
|
||||||
|
jsonString, err := json.Marshal(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = hnsCall("POST", "/endpoints/"+endpoint.Id+"/update", string(jsonString), &endpoint)
|
||||||
|
|
||||||
|
return endpoint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hot Attach an endpoint to a container
|
||||||
|
func (endpoint *HNSEndpoint) HotAttach(containerID string) error {
|
||||||
|
operation := "HotAttach"
|
||||||
|
title := "HCSShim::HNSEndpoint::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
|
||||||
|
|
||||||
|
return modifyNetworkEndpoint(containerID, endpoint.Id, Add)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hot Detach an endpoint from a container
|
||||||
|
func (endpoint *HNSEndpoint) HotDetach(containerID string) error {
|
||||||
|
operation := "HotDetach"
|
||||||
|
title := "HCSShim::HNSEndpoint::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
|
||||||
|
|
||||||
|
return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply Acl Policy on the Endpoint
|
||||||
|
func (endpoint *HNSEndpoint) ApplyACLPolicy(policy *ACLPolicy) error {
|
||||||
|
operation := "ApplyACLPolicy"
|
||||||
|
title := "HCSShim::HNSEndpoint::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", endpoint.Id)
|
||||||
|
|
||||||
|
jsonString, err := json.Marshal(policy)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
endpoint.Policies[0] = jsonString
|
||||||
|
_, err = endpoint.Update()
|
||||||
|
return err
|
||||||
|
}
|
233
vendor/github.com/Microsoft/hcsshim/hnsfuncs.go
generated
vendored
233
vendor/github.com/Microsoft/hcsshim/hnsfuncs.go
generated
vendored
@ -3,99 +3,10 @@ package hcsshim
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NatPolicy struct {
|
|
||||||
Type string
|
|
||||||
Protocol string
|
|
||||||
InternalPort uint16
|
|
||||||
ExternalPort uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
type QosPolicy struct {
|
|
||||||
Type string
|
|
||||||
MaximumOutgoingBandwidthInBytes uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type VlanPolicy struct {
|
|
||||||
Type string
|
|
||||||
VLAN uint
|
|
||||||
}
|
|
||||||
|
|
||||||
type VsidPolicy struct {
|
|
||||||
Type string
|
|
||||||
VSID uint
|
|
||||||
}
|
|
||||||
|
|
||||||
type PaPolicy struct {
|
|
||||||
Type string
|
|
||||||
PA string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subnet is assoicated with a network and represents a list
|
|
||||||
// of subnets available to the network
|
|
||||||
type Subnet struct {
|
|
||||||
AddressPrefix string `json:",omitempty"`
|
|
||||||
GatewayAddress string `json:",omitempty"`
|
|
||||||
Policies []json.RawMessage `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// MacPool is assoicated with a network and represents a list
|
|
||||||
// of macaddresses available to the network
|
|
||||||
type MacPool struct {
|
|
||||||
StartMacAddress string `json:",omitempty"`
|
|
||||||
EndMacAddress string `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// HNSNetwork represents a network in HNS
|
|
||||||
type HNSNetwork struct {
|
|
||||||
Id string `json:"ID,omitempty"`
|
|
||||||
Name string `json:",omitempty"`
|
|
||||||
Type string `json:",omitempty"`
|
|
||||||
NetworkAdapterName string `json:",omitempty"`
|
|
||||||
SourceMac string `json:",omitempty"`
|
|
||||||
Policies []json.RawMessage `json:",omitempty"`
|
|
||||||
MacPools []MacPool `json:",omitempty"`
|
|
||||||
Subnets []Subnet `json:",omitempty"`
|
|
||||||
DNSSuffix string `json:",omitempty"`
|
|
||||||
DNSServerList string `json:",omitempty"`
|
|
||||||
DNSServerCompartment uint32 `json:",omitempty"`
|
|
||||||
ManagementIP string `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// HNSEndpoint represents a network endpoint in HNS
|
|
||||||
type HNSEndpoint struct {
|
|
||||||
Id string `json:"ID,omitempty"`
|
|
||||||
Name string `json:",omitempty"`
|
|
||||||
VirtualNetwork string `json:",omitempty"`
|
|
||||||
VirtualNetworkName string `json:",omitempty"`
|
|
||||||
Policies []json.RawMessage `json:",omitempty"`
|
|
||||||
MacAddress string `json:",omitempty"`
|
|
||||||
IPAddress net.IP `json:",omitempty"`
|
|
||||||
DNSSuffix string `json:",omitempty"`
|
|
||||||
DNSServerList string `json:",omitempty"`
|
|
||||||
GatewayAddress string `json:",omitempty"`
|
|
||||||
EnableInternalDNS bool `json:",omitempty"`
|
|
||||||
DisableICC bool `json:",omitempty"`
|
|
||||||
PrefixLength uint8 `json:",omitempty"`
|
|
||||||
IsRemoteEndpoint bool `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type hnsNetworkResponse struct {
|
|
||||||
Success bool
|
|
||||||
Error string
|
|
||||||
Output HNSNetwork
|
|
||||||
}
|
|
||||||
|
|
||||||
type hnsResponse struct {
|
|
||||||
Success bool
|
|
||||||
Error string
|
|
||||||
Output json.RawMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
func hnsCall(method, path, request string, returnResponse interface{}) error {
|
func hnsCall(method, path, request string, returnResponse interface{}) error {
|
||||||
var responseBuffer *uint16
|
var responseBuffer *uint16
|
||||||
logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
|
logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
|
||||||
@ -127,145 +38,3 @@ func hnsCall(method, path, request string, returnResponse interface{}) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HNSNetworkRequest makes a call into HNS to update/query a single network
|
|
||||||
func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
|
|
||||||
var network HNSNetwork
|
|
||||||
err := hnsCall(method, "/networks/"+path, request, &network)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &network, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HNSListNetworkRequest makes a HNS call to query the list of available networks
|
|
||||||
func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
|
|
||||||
var network []HNSNetwork
|
|
||||||
err := hnsCall(method, "/networks/"+path, request, &network)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return network, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
|
|
||||||
func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
|
|
||||||
endpoint := &HNSEndpoint{}
|
|
||||||
err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return endpoint, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
|
|
||||||
func HNSListEndpointRequest() ([]HNSEndpoint, error) {
|
|
||||||
var endpoint []HNSEndpoint
|
|
||||||
err := hnsCall("GET", "/endpoints/", "", &endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return endpoint, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
|
|
||||||
func HotAttachEndpoint(containerID string, endpointID string) error {
|
|
||||||
return modifyNetworkEndpoint(containerID, endpointID, Add)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
|
|
||||||
func HotDetachEndpoint(containerID string, endpointID string) error {
|
|
||||||
return modifyNetworkEndpoint(containerID, endpointID, Remove)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModifyContainer corresponding to the container id, by sending a request
|
|
||||||
func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
|
|
||||||
container, err := OpenContainer(id)
|
|
||||||
if err != nil {
|
|
||||||
if IsNotExist(err) {
|
|
||||||
return ErrComputeSystemDoesNotExist
|
|
||||||
}
|
|
||||||
return getInnerError(err)
|
|
||||||
}
|
|
||||||
defer container.Close()
|
|
||||||
err = container.Modify(request)
|
|
||||||
if err != nil {
|
|
||||||
if IsNotSupported(err) {
|
|
||||||
return ErrPlatformNotSupported
|
|
||||||
}
|
|
||||||
return getInnerError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
|
|
||||||
requestMessage := &ResourceModificationRequestResponse{
|
|
||||||
Resource: Network,
|
|
||||||
Request: request,
|
|
||||||
Data: endpointID,
|
|
||||||
}
|
|
||||||
err := modifyContainer(containerID, requestMessage)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHNSNetworkByID
|
|
||||||
func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
|
|
||||||
return HNSNetworkRequest("GET", networkID, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHNSNetworkName filtered by Name
|
|
||||||
func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
|
|
||||||
hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, hnsnetwork := range hsnnetworks {
|
|
||||||
if hnsnetwork.Name == networkName {
|
|
||||||
return &hnsnetwork, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("Network %v not found", networkName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
|
|
||||||
func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
|
|
||||||
jsonString, err := json.Marshal(endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return HNSEndpointRequest("POST", "", string(jsonString))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Endpoint by sending EndpointRequest to HNS
|
|
||||||
func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
|
|
||||||
return HNSEndpointRequest("DELETE", endpoint.Id, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHNSEndpointByID
|
|
||||||
func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
|
|
||||||
return HNSEndpointRequest("GET", endpointID, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHNSNetworkName filtered by Name
|
|
||||||
func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
|
|
||||||
hnsResponse, err := HNSListEndpointRequest()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, hnsEndpoint := range hnsResponse {
|
|
||||||
if hnsEndpoint.Name == endpointName {
|
|
||||||
return &hnsEndpoint, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("Endpoint %v not found", endpointName)
|
|
||||||
}
|
|
||||||
|
142
vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
generated
vendored
Normal file
142
vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package hcsshim
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Subnet is assoicated with a network and represents a list
|
||||||
|
// of subnets available to the network
|
||||||
|
type Subnet struct {
|
||||||
|
AddressPrefix string `json:",omitempty"`
|
||||||
|
GatewayAddress string `json:",omitempty"`
|
||||||
|
Policies []json.RawMessage `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MacPool is assoicated with a network and represents a list
|
||||||
|
// of macaddresses available to the network
|
||||||
|
type MacPool struct {
|
||||||
|
StartMacAddress string `json:",omitempty"`
|
||||||
|
EndMacAddress string `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// HNSNetwork represents a network in HNS
|
||||||
|
type HNSNetwork struct {
|
||||||
|
Id string `json:"ID,omitempty"`
|
||||||
|
Name string `json:",omitempty"`
|
||||||
|
Type string `json:",omitempty"`
|
||||||
|
NetworkAdapterName string `json:",omitempty"`
|
||||||
|
SourceMac string `json:",omitempty"`
|
||||||
|
Policies []json.RawMessage `json:",omitempty"`
|
||||||
|
MacPools []MacPool `json:",omitempty"`
|
||||||
|
Subnets []Subnet `json:",omitempty"`
|
||||||
|
DNSSuffix string `json:",omitempty"`
|
||||||
|
DNSServerList string `json:",omitempty"`
|
||||||
|
DNSServerCompartment uint32 `json:",omitempty"`
|
||||||
|
ManagementIP string `json:",omitempty"`
|
||||||
|
AutomaticDNS bool `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type hnsNetworkResponse struct {
|
||||||
|
Success bool
|
||||||
|
Error string
|
||||||
|
Output HNSNetwork
|
||||||
|
}
|
||||||
|
|
||||||
|
type hnsResponse struct {
|
||||||
|
Success bool
|
||||||
|
Error string
|
||||||
|
Output json.RawMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
// HNSNetworkRequest makes a call into HNS to update/query a single network
|
||||||
|
func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
|
||||||
|
var network HNSNetwork
|
||||||
|
err := hnsCall(method, "/networks/"+path, request, &network)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &network, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HNSListNetworkRequest makes a HNS call to query the list of available networks
|
||||||
|
func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
|
||||||
|
var network []HNSNetwork
|
||||||
|
err := hnsCall(method, "/networks/"+path, request, &network)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return network, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHNSNetworkByID
|
||||||
|
func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
|
||||||
|
return HNSNetworkRequest("GET", networkID, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHNSNetworkName filtered by Name
|
||||||
|
func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
|
||||||
|
hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, hnsnetwork := range hsnnetworks {
|
||||||
|
if hnsnetwork.Name == networkName {
|
||||||
|
return &hnsnetwork, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Network %v not found", networkName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Network by sending NetworkRequest to HNS.
|
||||||
|
func (network *HNSNetwork) Create() (*HNSNetwork, error) {
|
||||||
|
operation := "Create"
|
||||||
|
title := "HCSShim::HNSNetwork::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", network.Id)
|
||||||
|
|
||||||
|
jsonString, err := json.Marshal(network)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return HNSNetworkRequest("POST", "", string(jsonString))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Network by sending NetworkRequest to HNS
|
||||||
|
func (network *HNSNetwork) Delete() (*HNSNetwork, error) {
|
||||||
|
operation := "Delete"
|
||||||
|
title := "HCSShim::HNSNetwork::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", network.Id)
|
||||||
|
|
||||||
|
return HNSNetworkRequest("DELETE", network.Id, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an endpoint on the Network.
|
||||||
|
func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {
|
||||||
|
return &HNSEndpoint{
|
||||||
|
VirtualNetwork: network.Id,
|
||||||
|
IPAddress: ipAddress,
|
||||||
|
MacAddress: string(macAddress),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
|
||||||
|
operation := "CreateEndpoint"
|
||||||
|
title := "HCSShim::HNSNetwork::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)
|
||||||
|
|
||||||
|
endpoint.VirtualNetwork = network.Id
|
||||||
|
return endpoint.Create()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
|
||||||
|
operation := "CreateRemoteEndpoint"
|
||||||
|
title := "HCSShim::HNSNetwork::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", network.Id)
|
||||||
|
endpoint.IsRemoteEndpoint = true
|
||||||
|
return network.CreateEndpoint(endpoint)
|
||||||
|
}
|
95
vendor/github.com/Microsoft/hcsshim/hnspolicy.go
generated
vendored
Normal file
95
vendor/github.com/Microsoft/hcsshim/hnspolicy.go
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package hcsshim
|
||||||
|
|
||||||
|
// Type of Request Support in ModifySystem
|
||||||
|
type PolicyType string
|
||||||
|
|
||||||
|
// RequestType const
|
||||||
|
const (
|
||||||
|
Nat PolicyType = "NAT"
|
||||||
|
ACL PolicyType = "ACL"
|
||||||
|
PA PolicyType = "PA"
|
||||||
|
VLAN PolicyType = "VLAN"
|
||||||
|
VSID PolicyType = "VSID"
|
||||||
|
VNet PolicyType = "VNET"
|
||||||
|
L2Driver PolicyType = "L2Driver"
|
||||||
|
Isolation PolicyType = "Isolation"
|
||||||
|
QOS PolicyType = "QOS"
|
||||||
|
OutboundNat PolicyType = "OutBoundNAT"
|
||||||
|
ExternalLoadBalancer PolicyType = "ELB"
|
||||||
|
Route PolicyType = "ROUTE"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NatPolicy struct {
|
||||||
|
Type PolicyType `json:"Type"`
|
||||||
|
Protocol string
|
||||||
|
InternalPort uint16
|
||||||
|
ExternalPort uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type QosPolicy struct {
|
||||||
|
Type PolicyType `json:"Type"`
|
||||||
|
MaximumOutgoingBandwidthInBytes uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type IsolationPolicy struct {
|
||||||
|
Type PolicyType `json:"Type"`
|
||||||
|
VLAN uint
|
||||||
|
VSID uint
|
||||||
|
InDefaultIsolation bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type VlanPolicy struct {
|
||||||
|
Type PolicyType `json:"Type"`
|
||||||
|
VLAN uint
|
||||||
|
}
|
||||||
|
|
||||||
|
type VsidPolicy struct {
|
||||||
|
Type PolicyType `json:"Type"`
|
||||||
|
VSID uint
|
||||||
|
}
|
||||||
|
|
||||||
|
type PaPolicy struct {
|
||||||
|
Type PolicyType `json:"Type"`
|
||||||
|
PA string `json:"PA"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OutboundNatPolicy struct {
|
||||||
|
Policy
|
||||||
|
VIP string `json:"VIP,omitempty"`
|
||||||
|
Exceptions []string `json:"ExceptionList,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActionType string
|
||||||
|
type DirectionType string
|
||||||
|
type RuleType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Allow ActionType = "Allow"
|
||||||
|
Block ActionType = "Block"
|
||||||
|
|
||||||
|
In DirectionType = "In"
|
||||||
|
Out DirectionType = "Out"
|
||||||
|
|
||||||
|
Host RuleType = "Host"
|
||||||
|
Switch RuleType = "Switch"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ACLPolicy struct {
|
||||||
|
Type PolicyType `json:"Type"`
|
||||||
|
Protocol uint16
|
||||||
|
InternalPort uint16
|
||||||
|
Action ActionType
|
||||||
|
Direction DirectionType
|
||||||
|
LocalAddress string
|
||||||
|
RemoteAddress string
|
||||||
|
LocalPort uint16
|
||||||
|
RemotePort uint16
|
||||||
|
RuleType RuleType `json:"RuleType,omitempty"`
|
||||||
|
|
||||||
|
Priority uint16
|
||||||
|
ServiceName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Policy struct {
|
||||||
|
Type PolicyType `json:"Type"`
|
||||||
|
}
|
187
vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
generated
vendored
Normal file
187
vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
generated
vendored
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
package hcsshim
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoutePolicy struct {
|
||||||
|
Policy
|
||||||
|
DestinationPrefix string `json:"DestinationPrefix,omitempty"`
|
||||||
|
NextHop string `json:"NextHop,omitempty"`
|
||||||
|
EncapEnabled bool `json:"NeedEncap,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ELBPolicy struct {
|
||||||
|
LBPolicy
|
||||||
|
SourceVIP string `json:"SourceVIP,omitempty"`
|
||||||
|
VIPs []string `json:"VIPs,omitempty"`
|
||||||
|
ILB bool `json:"ILB,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LBPolicy struct {
|
||||||
|
Policy
|
||||||
|
Protocol uint16 `json:"Protocol,omitempty"`
|
||||||
|
InternalPort uint16
|
||||||
|
ExternalPort uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type PolicyList struct {
|
||||||
|
Id string `json:"ID,omitempty"`
|
||||||
|
EndpointReferences []string `json:"References,omitempty"`
|
||||||
|
Policies []string `json:"Policies,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// HNSPolicyListRequest makes a call into HNS to update/query a single network
|
||||||
|
func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
|
||||||
|
var policy PolicyList
|
||||||
|
err := hnsCall(method, "/policylists/"+path, request, &policy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policy, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func HNSListPolicyListRequest() ([]PolicyList, error) {
|
||||||
|
var plist []PolicyList
|
||||||
|
err := hnsCall("GET", "/policylists/", "", &plist)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return plist, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PolicyListRequest makes a HNS call to modify/query a network endpoint
|
||||||
|
func PolicyListRequest(method, path, request string) (*PolicyList, error) {
|
||||||
|
policylist := &PolicyList{}
|
||||||
|
err := hnsCall(method, "/policylists/"+path, request, &policylist)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return policylist, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create PolicyList by sending PolicyListRequest to HNS.
|
||||||
|
func (policylist *PolicyList) Create() (*PolicyList, error) {
|
||||||
|
operation := "Create"
|
||||||
|
title := "HCSShim::PolicyList::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", policylist.Id)
|
||||||
|
jsonString, err := json.Marshal(policylist)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return PolicyListRequest("POST", "", string(jsonString))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create PolicyList by sending PolicyListRequest to HNS
|
||||||
|
func (policylist *PolicyList) Delete() (*PolicyList, error) {
|
||||||
|
operation := "Delete"
|
||||||
|
title := "HCSShim::PolicyList::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s", policylist.Id)
|
||||||
|
|
||||||
|
return PolicyListRequest("DELETE", policylist.Id, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an endpoint to a Policy List
|
||||||
|
func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
|
||||||
|
operation := "AddEndpoint"
|
||||||
|
title := "HCSShim::PolicyList::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s, endpointId:%s", policylist.Id, endpoint.Id)
|
||||||
|
|
||||||
|
_, err := policylist.Delete()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Endpoint to the Existing List
|
||||||
|
policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
|
||||||
|
|
||||||
|
return policylist.Create()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove an endpoint from the Policy List
|
||||||
|
func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
|
||||||
|
operation := "RemoveEndpoint"
|
||||||
|
title := "HCSShim::PolicyList::" + operation
|
||||||
|
logrus.Debugf(title+" id=%s, endpointId:%s", policylist.Id, endpoint.Id)
|
||||||
|
|
||||||
|
_, err := policylist.Delete()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
elementToRemove := "/endpoints/" + endpoint.Id
|
||||||
|
|
||||||
|
var references []string
|
||||||
|
|
||||||
|
for _, endpointReference := range policylist.EndpointReferences {
|
||||||
|
if endpointReference == elementToRemove {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
references = append(references, endpointReference)
|
||||||
|
}
|
||||||
|
policylist.EndpointReferences = references
|
||||||
|
return policylist.Create()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddLoadBalancer policy list for the specified endpoints
|
||||||
|
func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
|
||||||
|
operation := "AddLoadBalancer"
|
||||||
|
title := "HCSShim::PolicyList::" + operation
|
||||||
|
logrus.Debugf(title+" Vip:%s", vip)
|
||||||
|
|
||||||
|
policylist := &PolicyList{}
|
||||||
|
|
||||||
|
elbPolicy := &ELBPolicy{
|
||||||
|
VIPs: []string{vip},
|
||||||
|
ILB: isILB,
|
||||||
|
}
|
||||||
|
elbPolicy.Type = ExternalLoadBalancer
|
||||||
|
elbPolicy.Protocol = protocol
|
||||||
|
elbPolicy.InternalPort = internalPort
|
||||||
|
elbPolicy.ExternalPort = externalPort
|
||||||
|
|
||||||
|
for _, endpoint := range endpoints {
|
||||||
|
policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonString, err := json.Marshal(elbPolicy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
policylist.Policies[0] = string(jsonString)
|
||||||
|
return policylist.Create()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddLoadBalancer policy list for the specified endpoints
|
||||||
|
func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
|
||||||
|
operation := "AddRoute"
|
||||||
|
title := "HCSShim::PolicyList::" + operation
|
||||||
|
logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)
|
||||||
|
|
||||||
|
policylist := &PolicyList{}
|
||||||
|
|
||||||
|
rPolicy := &RoutePolicy{
|
||||||
|
DestinationPrefix: destinationPrefix,
|
||||||
|
NextHop: nextHop,
|
||||||
|
EncapEnabled: encapEnabled,
|
||||||
|
}
|
||||||
|
rPolicy.Type = Route
|
||||||
|
|
||||||
|
for _, endpoint := range endpoints {
|
||||||
|
policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonString, err := json.Marshal(rPolicy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
policylist.Policies[0] = string(jsonString)
|
||||||
|
return policylist.Create()
|
||||||
|
}
|
4
vendor/github.com/Microsoft/hcsshim/importlayer.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/importlayer.go
generated
vendored
@ -5,10 +5,9 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/Microsoft/go-winio"
|
"github.com/Microsoft/go-winio"
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImportLayer will take the contents of the folder at importFolderPath and import
|
// ImportLayer will take the contents of the folder at importFolderPath and import
|
||||||
@ -209,6 +208,5 @@ func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, makeError(err, "ImportLayerStart", "")
|
return nil, makeError(err, "ImportLayerStart", "")
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(w, func(w *FilterLayerWriter) { w.Close() })
|
|
||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
68
vendor/github.com/Microsoft/hcsshim/interface.go
generated
vendored
68
vendor/github.com/Microsoft/hcsshim/interface.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -8,16 +9,19 @@ import (
|
|||||||
// ProcessConfig is used as both the input of Container.CreateProcess
|
// ProcessConfig is used as both the input of Container.CreateProcess
|
||||||
// and to convert the parameters to JSON for passing onto the HCS
|
// and to convert the parameters to JSON for passing onto the HCS
|
||||||
type ProcessConfig struct {
|
type ProcessConfig struct {
|
||||||
ApplicationName string
|
ApplicationName string `json:",omitempty"`
|
||||||
CommandLine string
|
CommandLine string `json:",omitempty"`
|
||||||
User string
|
CommandArgs []string `json:",omitempty"` // Used by Linux Containers on Windows
|
||||||
WorkingDirectory string
|
User string `json:",omitempty"`
|
||||||
Environment map[string]string
|
WorkingDirectory string `json:",omitempty"`
|
||||||
EmulateConsole bool
|
Environment map[string]string `json:",omitempty"`
|
||||||
CreateStdInPipe bool
|
EmulateConsole bool `json:",omitempty"`
|
||||||
CreateStdOutPipe bool
|
CreateStdInPipe bool `json:",omitempty"`
|
||||||
CreateStdErrPipe bool
|
CreateStdOutPipe bool `json:",omitempty"`
|
||||||
ConsoleSize [2]uint
|
CreateStdErrPipe bool `json:",omitempty"`
|
||||||
|
ConsoleSize [2]uint `json:",omitempty"`
|
||||||
|
CreateInUtilityVm bool `json:",omitempty"` // Used by Linux Containers on Windows
|
||||||
|
OCISpecification *json.RawMessage `json:",omitempty"` // Used by Linux Containers on Windows
|
||||||
}
|
}
|
||||||
|
|
||||||
type Layer struct {
|
type Layer struct {
|
||||||
@ -33,9 +37,26 @@ type MappedDir struct {
|
|||||||
IOPSMaximum uint64
|
IOPSMaximum uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MappedPipe struct {
|
||||||
|
HostPath string
|
||||||
|
ContainerPipeName string
|
||||||
|
}
|
||||||
|
|
||||||
type HvRuntime struct {
|
type HvRuntime struct {
|
||||||
ImagePath string `json:",omitempty"`
|
ImagePath string `json:",omitempty"`
|
||||||
SkipTemplate bool `json:",omitempty"`
|
SkipTemplate bool `json:",omitempty"`
|
||||||
|
LinuxInitrdFile string `json:",omitempty"` // File under ImagePath on host containing an initrd image for starting a Linux utility VM
|
||||||
|
LinuxKernelFile string `json:",omitempty"` // File under ImagePath on host containing a kernel for starting a Linux utility VM
|
||||||
|
LinuxBootParameters string `json:",omitempty"` // Additional boot parameters for starting a Linux Utility VM in initrd mode
|
||||||
|
}
|
||||||
|
|
||||||
|
type MappedVirtualDisk struct {
|
||||||
|
HostPath string `json:",omitempty"` // Path to VHD on the host
|
||||||
|
ContainerPath string // Platform-specific mount point path in the container
|
||||||
|
CreateInUtilityVM bool `json:",omitempty"`
|
||||||
|
ReadOnly bool `json:",omitempty"`
|
||||||
|
Cache string `json:",omitempty"` // "" (Unspecified); "Disabled"; "Enabled"; "Private"; "PrivateAllowSharing"
|
||||||
|
AttachOnly bool `json:",omitempty:`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerConfig is used as both the input of CreateContainer
|
// ContainerConfig is used as both the input of CreateContainer
|
||||||
@ -43,30 +64,32 @@ type HvRuntime struct {
|
|||||||
type ContainerConfig struct {
|
type ContainerConfig struct {
|
||||||
SystemType string // HCS requires this to be hard-coded to "Container"
|
SystemType string // HCS requires this to be hard-coded to "Container"
|
||||||
Name string // Name of the container. We use the docker ID.
|
Name string // Name of the container. We use the docker ID.
|
||||||
Owner string // The management platform that created this container
|
Owner string `json:",omitempty"` // The management platform that created this container
|
||||||
IsDummy bool // Used for development purposes.
|
|
||||||
VolumePath string `json:",omitempty"` // Windows volume path for scratch space. Used by Windows Server Containers only. Format \\?\\Volume{GUID}
|
VolumePath string `json:",omitempty"` // Windows volume path for scratch space. Used by Windows Server Containers only. Format \\?\\Volume{GUID}
|
||||||
IgnoreFlushesDuringBoot bool // Optimization hint for container startup in Windows
|
IgnoreFlushesDuringBoot bool `json:",omitempty"` // Optimization hint for container startup in Windows
|
||||||
LayerFolderPath string `json:",omitempty"` // Where the layer folders are located. Used by Windows Server Containers only. Format %root%\windowsfilter\containerID
|
LayerFolderPath string `json:",omitempty"` // Where the layer folders are located. Used by Windows Server Containers only. Format %root%\windowsfilter\containerID
|
||||||
Layers []Layer // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
|
Layers []Layer // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
|
||||||
Credentials string `json:",omitempty"` // Credentials information
|
Credentials string `json:",omitempty"` // Credentials information
|
||||||
ProcessorCount uint32 `json:",omitempty"` // Number of processors to assign to the container.
|
ProcessorCount uint32 `json:",omitempty"` // Number of processors to assign to the container.
|
||||||
ProcessorWeight uint64 `json:",omitempty"` // CPU Shares 0..10000 on Windows; where 0 will be omitted and HCS will default.
|
ProcessorWeight uint64 `json:",omitempty"` // CPU shares (relative weight to other containers with cpu shares). Range is from 1 to 10000. A value of 0 results in default shares.
|
||||||
ProcessorMaximum int64 `json:",omitempty"` // CPU maximum usage percent 1..100
|
ProcessorMaximum int64 `json:",omitempty"` // Specifies the portion of processor cycles that this container can use as a percentage times 100. Range is from 1 to 10000. A value of 0 results in no limit.
|
||||||
StorageIOPSMaximum uint64 `json:",omitempty"` // Maximum Storage IOPS
|
StorageIOPSMaximum uint64 `json:",omitempty"` // Maximum Storage IOPS
|
||||||
StorageBandwidthMaximum uint64 `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
|
StorageBandwidthMaximum uint64 `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
|
||||||
StorageSandboxSize uint64 `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
|
StorageSandboxSize uint64 `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
|
||||||
MemoryMaximumInMB int64 `json:",omitempty"` // Maximum memory available to the container in Megabytes
|
MemoryMaximumInMB int64 `json:",omitempty"` // Maximum memory available to the container in Megabytes
|
||||||
HostName string // Hostname
|
HostName string `json:",omitempty"` // Hostname
|
||||||
MappedDirectories []MappedDir // List of mapped directories (volumes/mounts)
|
MappedDirectories []MappedDir `json:",omitempty"` // List of mapped directories (volumes/mounts)
|
||||||
SandboxPath string `json:",omitempty"` // Location of unmounted sandbox. Used by Hyper-V containers only. Format %root%\windowsfilter
|
MappedPipes []MappedPipe `json:",omitempty"` // List of mapped Windows named pipes
|
||||||
HvPartition bool // True if it a Hyper-V Container
|
HvPartition bool // True if it a Hyper-V Container
|
||||||
EndpointList []string // List of networking endpoints to be attached to container
|
|
||||||
NetworkSharedContainerName string `json:",omitempty"` // Name (ID) of the container that we will share the network stack with.
|
NetworkSharedContainerName string `json:",omitempty"` // Name (ID) of the container that we will share the network stack with.
|
||||||
|
EndpointList []string `json:",omitempty"` // List of networking endpoints to be attached to container
|
||||||
HvRuntime *HvRuntime `json:",omitempty"` // Hyper-V container settings. Used by Hyper-V containers only. Format ImagePath=%root%\BaseLayerID\UtilityVM
|
HvRuntime *HvRuntime `json:",omitempty"` // Hyper-V container settings. Used by Hyper-V containers only. Format ImagePath=%root%\BaseLayerID\UtilityVM
|
||||||
Servicing bool // True if this container is for servicing
|
Servicing bool `json:",omitempty"` // True if this container is for servicing
|
||||||
AllowUnqualifiedDNSQuery bool // True to allow unqualified DNS name resolution
|
AllowUnqualifiedDNSQuery bool `json:",omitempty"` // True to allow unqualified DNS name resolution
|
||||||
DNSSearchList string `json:",omitempty"` // Comma seperated list of DNS suffixes to use for name resolution
|
DNSSearchList string `json:",omitempty"` // Comma seperated list of DNS suffixes to use for name resolution
|
||||||
|
ContainerType string `json:",omitempty"` // "Linux" for Linux containers on Windows. Omitted otherwise.
|
||||||
|
TerminateOnLastHandleClosed bool `json:",omitempty"` // Should HCS terminate the container once all handles have been closed
|
||||||
|
MappedVirtualDisks []MappedVirtualDisk `json:",omitempty"` // Array of virtual disks to mount at start
|
||||||
}
|
}
|
||||||
|
|
||||||
type ComputeSystemQuery struct {
|
type ComputeSystemQuery struct {
|
||||||
@ -109,6 +132,9 @@ type Container interface {
|
|||||||
// ProcessList returns details for the processes in a container.
|
// ProcessList returns details for the processes in a container.
|
||||||
ProcessList() ([]ProcessListItem, error)
|
ProcessList() ([]ProcessListItem, error)
|
||||||
|
|
||||||
|
// MappedVirtualDisks returns virtual disks mapped to a utility VM, indexed by controller
|
||||||
|
MappedVirtualDisks() (map[int]MappedVirtualDiskController, error)
|
||||||
|
|
||||||
// CreateProcess launches a new process within the container.
|
// CreateProcess launches a new process within the container.
|
||||||
CreateProcess(c *ProcessConfig) (Process, error)
|
CreateProcess(c *ProcessConfig) (Process, error)
|
||||||
|
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/layerexists.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/layerexists.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// LayerExists will return true if a layer with the given id exists and is known
|
// LayerExists will return true if a layer with the given id exists and is known
|
||||||
// to the system.
|
// to the system.
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/layerutils.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/layerutils.go
generated
vendored
@ -7,7 +7,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* To pass into syscall, we need a struct matching the following:
|
/* To pass into syscall, we need a struct matching the following:
|
||||||
|
48
vendor/github.com/Microsoft/hcsshim/legacy.go
generated
vendored
48
vendor/github.com/Microsoft/hcsshim/legacy.go
generated
vendored
@ -23,6 +23,13 @@ var mutatedUtilityVMFiles = map[string]bool{
|
|||||||
`EFI\Microsoft\Boot\BCD.LOG2`: true,
|
`EFI\Microsoft\Boot\BCD.LOG2`: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
filesPath = `Files`
|
||||||
|
hivesPath = `Hives`
|
||||||
|
utilityVMPath = `UtilityVM`
|
||||||
|
utilityVMFilesPath = `UtilityVM\Files`
|
||||||
|
)
|
||||||
|
|
||||||
func openFileOrDir(path string, mode uint32, createDisposition uint32) (file *os.File, err error) {
|
func openFileOrDir(path string, mode uint32, createDisposition uint32) (file *os.File, err error) {
|
||||||
return winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createDisposition)
|
return winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createDisposition)
|
||||||
}
|
}
|
||||||
@ -44,6 +51,10 @@ func makeLongAbsPath(path string) (string, error) {
|
|||||||
return `\\?\` + path, nil
|
return `\\?\` + path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hasPathPrefix(p, prefix string) bool {
|
||||||
|
return strings.HasPrefix(p, prefix) && len(p) > len(prefix) && p[len(prefix)] == '\\'
|
||||||
|
}
|
||||||
|
|
||||||
type fileEntry struct {
|
type fileEntry struct {
|
||||||
path string
|
path string
|
||||||
fi os.FileInfo
|
fi os.FileInfo
|
||||||
@ -83,7 +94,7 @@ func readTombstones(path string) (map[string]([]string), error) {
|
|||||||
|
|
||||||
ts := make(map[string]([]string))
|
ts := make(map[string]([]string))
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
t := filepath.Join("Files", s.Text()[1:]) // skip leading `\`
|
t := filepath.Join(filesPath, s.Text()[1:]) // skip leading `\`
|
||||||
dir := filepath.Dir(t)
|
dir := filepath.Dir(t)
|
||||||
ts[dir] = append(ts[dir], t)
|
ts[dir] = append(ts[dir], t)
|
||||||
}
|
}
|
||||||
@ -212,7 +223,7 @@ func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if fe.fi.IsDir() && strings.HasPrefix(path, `Files\`) {
|
if fe.fi.IsDir() && hasPathPrefix(path, filesPath) {
|
||||||
fe.path += ".$wcidirs$"
|
fe.path += ".$wcidirs$"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,14 +242,14 @@ func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(path, `Files\`) {
|
if !hasPathPrefix(path, filesPath) {
|
||||||
size = fe.fi.Size()
|
size = fe.fi.Size()
|
||||||
r.backupReader = winio.NewBackupFileReader(f, false)
|
r.backupReader = winio.NewBackupFileReader(f, false)
|
||||||
if path == "Hives" || path == "Files" {
|
if path == hivesPath || path == filesPath {
|
||||||
// The Hives directory has a non-deterministic file time because of the
|
// The Hives directory has a non-deterministic file time because of the
|
||||||
// nature of the import process. Use the times from System_Delta.
|
// nature of the import process. Use the times from System_Delta.
|
||||||
var g *os.File
|
var g *os.File
|
||||||
g, err = os.Open(filepath.Join(r.root, `Hives\System_Delta`))
|
g, err = os.Open(filepath.Join(r.root, hivesPath, `System_Delta`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -357,7 +368,7 @@ func (w *legacyLayerWriter) init() error {
|
|||||||
|
|
||||||
func (w *legacyLayerWriter) initUtilityVM() error {
|
func (w *legacyLayerWriter) initUtilityVM() error {
|
||||||
if !w.HasUtilityVM {
|
if !w.HasUtilityVM {
|
||||||
err := os.Mkdir(filepath.Join(w.destRoot, `UtilityVM`), 0)
|
err := os.Mkdir(filepath.Join(w.destRoot, utilityVMPath), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -365,7 +376,7 @@ func (w *legacyLayerWriter) initUtilityVM() error {
|
|||||||
// clone the utility VM from the parent layer into this layer. Use hard
|
// clone the utility VM from the parent layer into this layer. Use hard
|
||||||
// links to avoid unnecessary copying, since most of the files are
|
// links to avoid unnecessary copying, since most of the files are
|
||||||
// immutable.
|
// immutable.
|
||||||
err = cloneTree(filepath.Join(w.parentRoots[0], `UtilityVM\Files`), filepath.Join(w.destRoot, `UtilityVM\Files`), mutatedUtilityVMFiles)
|
err = cloneTree(filepath.Join(w.parentRoots[0], utilityVMFilesPath), filepath.Join(w.destRoot, utilityVMFilesPath), mutatedUtilityVMFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cloning the parent utility VM image failed: %s", err)
|
return fmt.Errorf("cloning the parent utility VM image failed: %s", err)
|
||||||
}
|
}
|
||||||
@ -490,15 +501,15 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if name == `UtilityVM` {
|
if name == utilityVMPath {
|
||||||
return w.initUtilityVM()
|
return w.initUtilityVM()
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(name, `UtilityVM\`) {
|
if hasPathPrefix(name, utilityVMPath) {
|
||||||
if !w.HasUtilityVM {
|
if !w.HasUtilityVM {
|
||||||
return errors.New("missing UtilityVM directory")
|
return errors.New("missing UtilityVM directory")
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(name, `UtilityVM\Files\`) && name != `UtilityVM\Files` {
|
if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
|
||||||
return errors.New("invalid UtilityVM layer")
|
return errors.New("invalid UtilityVM layer")
|
||||||
}
|
}
|
||||||
path := filepath.Join(w.destRoot, name)
|
path := filepath.Join(w.destRoot, name)
|
||||||
@ -585,7 +596,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(name, `Hives\`) {
|
if hasPathPrefix(name, hivesPath) {
|
||||||
w.backupWriter = winio.NewBackupFileWriter(f, false)
|
w.backupWriter = winio.NewBackupFileWriter(f, false)
|
||||||
} else {
|
} else {
|
||||||
// The file attributes are written before the stream.
|
// The file attributes are written before the stream.
|
||||||
@ -608,22 +619,19 @@ func (w *legacyLayerWriter) AddLink(name string, target string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var requiredPrefix string
|
|
||||||
var roots []string
|
var roots []string
|
||||||
if prefix := `Files\`; strings.HasPrefix(name, prefix) {
|
if hasPathPrefix(target, filesPath) {
|
||||||
requiredPrefix = prefix
|
|
||||||
// Look for cross-layer hard link targets in the parent layers, since
|
// Look for cross-layer hard link targets in the parent layers, since
|
||||||
// nothing is in the destination path yet.
|
// nothing is in the destination path yet.
|
||||||
roots = w.parentRoots
|
roots = w.parentRoots
|
||||||
} else if prefix := `UtilityVM\Files\`; strings.HasPrefix(name, prefix) {
|
} else if hasPathPrefix(target, utilityVMFilesPath) {
|
||||||
requiredPrefix = prefix
|
|
||||||
// Since the utility VM is fully cloned into the destination path
|
// Since the utility VM is fully cloned into the destination path
|
||||||
// already, look for cross-layer hard link targets directly in the
|
// already, look for cross-layer hard link targets directly in the
|
||||||
// destination path.
|
// destination path.
|
||||||
roots = []string{w.destRoot}
|
roots = []string{w.destRoot}
|
||||||
}
|
}
|
||||||
|
|
||||||
if requiredPrefix == "" || !strings.HasPrefix(target, requiredPrefix) {
|
if roots == nil || (!hasPathPrefix(name, filesPath) && !hasPathPrefix(name, utilityVMFilesPath)) {
|
||||||
return errors.New("invalid hard link in layer")
|
return errors.New("invalid hard link in layer")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,9 +665,9 @@ func (w *legacyLayerWriter) AddLink(name string, target string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *legacyLayerWriter) Remove(name string) error {
|
func (w *legacyLayerWriter) Remove(name string) error {
|
||||||
if strings.HasPrefix(name, `Files\`) {
|
if hasPathPrefix(name, filesPath) {
|
||||||
w.tombstones = append(w.tombstones, name[len(`Files\`):])
|
w.tombstones = append(w.tombstones, name[len(filesPath)+1:])
|
||||||
} else if strings.HasPrefix(name, `UtilityVM\Files\`) {
|
} else if hasPathPrefix(name, utilityVMFilesPath) {
|
||||||
err := w.initUtilityVM()
|
err := w.initUtilityVM()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
934
vendor/github.com/Microsoft/hcsshim/mksyscall_windows.go
generated
vendored
Normal file
934
vendor/github.com/Microsoft/hcsshim/mksyscall_windows.go
generated
vendored
Normal file
@ -0,0 +1,934 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
mksyscall_windows generates windows system call bodies
|
||||||
|
|
||||||
|
It parses all files specified on command line containing function
|
||||||
|
prototypes (like syscall_windows.go) and prints system call bodies
|
||||||
|
to standard output.
|
||||||
|
|
||||||
|
The prototypes are marked by lines beginning with "//sys" and read
|
||||||
|
like func declarations if //sys is replaced by func, but:
|
||||||
|
|
||||||
|
* The parameter lists must give a name for each argument. This
|
||||||
|
includes return parameters.
|
||||||
|
|
||||||
|
* The parameter lists must give a type for each argument:
|
||||||
|
the (x, y, z int) shorthand is not allowed.
|
||||||
|
|
||||||
|
* If the return parameter is an error number, it must be named err.
|
||||||
|
|
||||||
|
* If go func name needs to be different from it's winapi dll name,
|
||||||
|
the winapi name could be specified at the end, after "=" sign, like
|
||||||
|
//sys LoadLibrary(libname string) (handle uint32, err error) = LoadLibraryA
|
||||||
|
|
||||||
|
* Each function that returns err needs to supply a condition, that
|
||||||
|
return value of winapi will be tested against to detect failure.
|
||||||
|
This would set err to windows "last-error", otherwise it will be nil.
|
||||||
|
The value can be provided at end of //sys declaration, like
|
||||||
|
//sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA
|
||||||
|
and is [failretval==0] by default.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
mksyscall_windows [flags] [path ...]
|
||||||
|
|
||||||
|
The flags are:
|
||||||
|
-output
|
||||||
|
Specify output file name (outputs to console if blank).
|
||||||
|
-trace
|
||||||
|
Generate print statement after every syscall.
|
||||||
|
*/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
filename = flag.String("output", "", "output file name (standard output if omitted)")
|
||||||
|
printTraceFlag = flag.Bool("trace", false, "generate print statement after every syscall")
|
||||||
|
systemDLL = flag.Bool("systemdll", true, "whether all DLLs should be loaded from the Windows system directory")
|
||||||
|
)
|
||||||
|
|
||||||
|
func trim(s string) string {
|
||||||
|
return strings.Trim(s, " \t")
|
||||||
|
}
|
||||||
|
|
||||||
|
var packageName string
|
||||||
|
|
||||||
|
func packagename() string {
|
||||||
|
return packageName
|
||||||
|
}
|
||||||
|
|
||||||
|
func syscalldot() string {
|
||||||
|
if packageName == "syscall" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return "syscall."
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is function parameter
|
||||||
|
type Param struct {
|
||||||
|
Name string
|
||||||
|
Type string
|
||||||
|
fn *Fn
|
||||||
|
tmpVarIdx int
|
||||||
|
}
|
||||||
|
|
||||||
|
// tmpVar returns temp variable name that will be used to represent p during syscall.
|
||||||
|
func (p *Param) tmpVar() string {
|
||||||
|
if p.tmpVarIdx < 0 {
|
||||||
|
p.tmpVarIdx = p.fn.curTmpVarIdx
|
||||||
|
p.fn.curTmpVarIdx++
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("_p%d", p.tmpVarIdx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolTmpVarCode returns source code for bool temp variable.
|
||||||
|
func (p *Param) BoolTmpVarCode() string {
|
||||||
|
const code = `var %s uint32
|
||||||
|
if %s {
|
||||||
|
%s = 1
|
||||||
|
} else {
|
||||||
|
%s = 0
|
||||||
|
}`
|
||||||
|
tmp := p.tmpVar()
|
||||||
|
return fmt.Sprintf(code, tmp, p.Name, tmp, tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SliceTmpVarCode returns source code for slice temp variable.
|
||||||
|
func (p *Param) SliceTmpVarCode() string {
|
||||||
|
const code = `var %s *%s
|
||||||
|
if len(%s) > 0 {
|
||||||
|
%s = &%s[0]
|
||||||
|
}`
|
||||||
|
tmp := p.tmpVar()
|
||||||
|
return fmt.Sprintf(code, tmp, p.Type[2:], p.Name, tmp, p.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringTmpVarCode returns source code for string temp variable.
|
||||||
|
func (p *Param) StringTmpVarCode() string {
|
||||||
|
errvar := p.fn.Rets.ErrorVarName()
|
||||||
|
if errvar == "" {
|
||||||
|
errvar = "_"
|
||||||
|
}
|
||||||
|
tmp := p.tmpVar()
|
||||||
|
const code = `var %s %s
|
||||||
|
%s, %s = %s(%s)`
|
||||||
|
s := fmt.Sprintf(code, tmp, p.fn.StrconvType(), tmp, errvar, p.fn.StrconvFunc(), p.Name)
|
||||||
|
if errvar == "-" {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
const morecode = `
|
||||||
|
if %s != nil {
|
||||||
|
return
|
||||||
|
}`
|
||||||
|
return s + fmt.Sprintf(morecode, errvar)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TmpVarCode returns source code for temp variable.
|
||||||
|
func (p *Param) TmpVarCode() string {
|
||||||
|
switch {
|
||||||
|
case p.Type == "bool":
|
||||||
|
return p.BoolTmpVarCode()
|
||||||
|
case strings.HasPrefix(p.Type, "[]"):
|
||||||
|
return p.SliceTmpVarCode()
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TmpVarHelperCode returns source code for helper's temp variable.
|
||||||
|
func (p *Param) TmpVarHelperCode() string {
|
||||||
|
if p.Type != "string" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return p.StringTmpVarCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyscallArgList returns source code fragments representing p parameter
|
||||||
|
// in syscall. Slices are translated into 2 syscall parameters: pointer to
|
||||||
|
// the first element and length.
|
||||||
|
func (p *Param) SyscallArgList() []string {
|
||||||
|
t := p.HelperType()
|
||||||
|
var s string
|
||||||
|
switch {
|
||||||
|
case t[0] == '*':
|
||||||
|
s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
|
||||||
|
case t == "bool":
|
||||||
|
s = p.tmpVar()
|
||||||
|
case strings.HasPrefix(t, "[]"):
|
||||||
|
return []string{
|
||||||
|
fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.tmpVar()),
|
||||||
|
fmt.Sprintf("uintptr(len(%s))", p.Name),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
s = p.Name
|
||||||
|
}
|
||||||
|
return []string{fmt.Sprintf("uintptr(%s)", s)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsError determines if p parameter is used to return error.
|
||||||
|
func (p *Param) IsError() bool {
|
||||||
|
return p.Name == "err" && p.Type == "error"
|
||||||
|
}
|
||||||
|
|
||||||
|
// HelperType returns type of parameter p used in helper function.
|
||||||
|
func (p *Param) HelperType() string {
|
||||||
|
if p.Type == "string" {
|
||||||
|
return p.fn.StrconvType()
|
||||||
|
}
|
||||||
|
return p.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// join concatenates parameters ps into a string with sep separator.
|
||||||
|
// Each parameter is converted into string by applying fn to it
|
||||||
|
// before conversion.
|
||||||
|
func join(ps []*Param, fn func(*Param) string, sep string) string {
|
||||||
|
if len(ps) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
a := make([]string, 0)
|
||||||
|
for _, p := range ps {
|
||||||
|
a = append(a, fn(p))
|
||||||
|
}
|
||||||
|
return strings.Join(a, sep)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rets describes function return parameters.
|
||||||
|
type Rets struct {
|
||||||
|
Name string
|
||||||
|
Type string
|
||||||
|
ReturnsError bool
|
||||||
|
FailCond string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorVarName returns error variable name for r.
|
||||||
|
func (r *Rets) ErrorVarName() string {
|
||||||
|
if r.ReturnsError {
|
||||||
|
return "err"
|
||||||
|
}
|
||||||
|
if r.Type == "error" {
|
||||||
|
return r.Name
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToParams converts r into slice of *Param.
|
||||||
|
func (r *Rets) ToParams() []*Param {
|
||||||
|
ps := make([]*Param, 0)
|
||||||
|
if len(r.Name) > 0 {
|
||||||
|
ps = append(ps, &Param{Name: r.Name, Type: r.Type})
|
||||||
|
}
|
||||||
|
if r.ReturnsError {
|
||||||
|
ps = append(ps, &Param{Name: "err", Type: "error"})
|
||||||
|
}
|
||||||
|
return ps
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns source code of syscall return parameters.
|
||||||
|
func (r *Rets) List() string {
|
||||||
|
s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ")
|
||||||
|
if len(s) > 0 {
|
||||||
|
s = "(" + s + ")"
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintList returns source code of trace printing part correspondent
|
||||||
|
// to syscall return values.
|
||||||
|
func (r *Rets) PrintList() string {
|
||||||
|
return join(r.ToParams(), func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReturnValuesCode returns source code that accepts syscall return values.
|
||||||
|
func (r *Rets) SetReturnValuesCode() string {
|
||||||
|
if r.Name == "" && !r.ReturnsError {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
retvar := "r0"
|
||||||
|
if r.Name == "" {
|
||||||
|
retvar = "r1"
|
||||||
|
}
|
||||||
|
errvar := "_"
|
||||||
|
if r.ReturnsError {
|
||||||
|
errvar = "e1"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s, _, %s := ", retvar, errvar)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rets) useLongHandleErrorCode(retvar string) string {
|
||||||
|
const code = `if %s {
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
} else {
|
||||||
|
err = %sEINVAL
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
cond := retvar + " == 0"
|
||||||
|
if r.FailCond != "" {
|
||||||
|
cond = strings.Replace(r.FailCond, "failretval", retvar, 1)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(code, cond, syscalldot())
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetErrorCode returns source code that sets return parameters.
|
||||||
|
func (r *Rets) SetErrorCode() string {
|
||||||
|
const code = `if r0 != 0 {
|
||||||
|
%s = %sErrno(r0)
|
||||||
|
}`
|
||||||
|
const hrCode = `if int32(r0) < 0 {
|
||||||
|
%s = %sErrno(win32FromHresult(r0))
|
||||||
|
}`
|
||||||
|
if r.Name == "" && !r.ReturnsError {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if r.Name == "" {
|
||||||
|
return r.useLongHandleErrorCode("r1")
|
||||||
|
}
|
||||||
|
if r.Type == "error" {
|
||||||
|
if r.Name == "hr" {
|
||||||
|
return fmt.Sprintf(hrCode, r.Name, syscalldot())
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf(code, r.Name, syscalldot())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s := ""
|
||||||
|
switch {
|
||||||
|
case r.Type[0] == '*':
|
||||||
|
s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.Name, r.Type)
|
||||||
|
case r.Type == "bool":
|
||||||
|
s = fmt.Sprintf("%s = r0 != 0", r.Name)
|
||||||
|
default:
|
||||||
|
s = fmt.Sprintf("%s = %s(r0)", r.Name, r.Type)
|
||||||
|
}
|
||||||
|
if !r.ReturnsError {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return s + "\n\t" + r.useLongHandleErrorCode(r.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fn describes syscall function.
|
||||||
|
type Fn struct {
|
||||||
|
Name string
|
||||||
|
Params []*Param
|
||||||
|
Rets *Rets
|
||||||
|
PrintTrace bool
|
||||||
|
confirmproc bool
|
||||||
|
dllname string
|
||||||
|
dllfuncname string
|
||||||
|
src string
|
||||||
|
// TODO: get rid of this field and just use parameter index instead
|
||||||
|
curTmpVarIdx int // insure tmp variables have uniq names
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractParams parses s to extract function parameters.
|
||||||
|
func extractParams(s string, f *Fn) ([]*Param, error) {
|
||||||
|
s = trim(s)
|
||||||
|
if s == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
a := strings.Split(s, ",")
|
||||||
|
ps := make([]*Param, len(a))
|
||||||
|
for i := range ps {
|
||||||
|
s2 := trim(a[i])
|
||||||
|
b := strings.Split(s2, " ")
|
||||||
|
if len(b) != 2 {
|
||||||
|
b = strings.Split(s2, "\t")
|
||||||
|
if len(b) != 2 {
|
||||||
|
return nil, errors.New("Could not extract function parameter from \"" + s2 + "\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ps[i] = &Param{
|
||||||
|
Name: trim(b[0]),
|
||||||
|
Type: trim(b[1]),
|
||||||
|
fn: f,
|
||||||
|
tmpVarIdx: -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ps, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractSection extracts text out of string s starting after start
|
||||||
|
// and ending just before end. found return value will indicate success,
|
||||||
|
// and prefix, body and suffix will contain correspondent parts of string s.
|
||||||
|
func extractSection(s string, start, end rune) (prefix, body, suffix string, found bool) {
|
||||||
|
s = trim(s)
|
||||||
|
if strings.HasPrefix(s, string(start)) {
|
||||||
|
// no prefix
|
||||||
|
body = s[1:]
|
||||||
|
} else {
|
||||||
|
a := strings.SplitN(s, string(start), 2)
|
||||||
|
if len(a) != 2 {
|
||||||
|
return "", "", s, false
|
||||||
|
}
|
||||||
|
prefix = a[0]
|
||||||
|
body = a[1]
|
||||||
|
}
|
||||||
|
a := strings.SplitN(body, string(end), 2)
|
||||||
|
if len(a) != 2 {
|
||||||
|
return "", "", "", false
|
||||||
|
}
|
||||||
|
return prefix, a[0], a[1], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// newFn parses string s and return created function Fn.
|
||||||
|
func newFn(s string) (*Fn, error) {
|
||||||
|
s = trim(s)
|
||||||
|
f := &Fn{
|
||||||
|
Rets: &Rets{},
|
||||||
|
src: s,
|
||||||
|
PrintTrace: *printTraceFlag,
|
||||||
|
}
|
||||||
|
// function name and args
|
||||||
|
prefix, body, s, found := extractSection(s, '(', ')')
|
||||||
|
if !found || prefix == "" {
|
||||||
|
return nil, errors.New("Could not extract function name and parameters from \"" + f.src + "\"")
|
||||||
|
}
|
||||||
|
f.Name = prefix
|
||||||
|
var err error
|
||||||
|
f.Params, err = extractParams(body, f)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// return values
|
||||||
|
_, body, s, found = extractSection(s, '(', ')')
|
||||||
|
if found {
|
||||||
|
r, err := extractParams(body, f)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch len(r) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
if r[0].IsError() {
|
||||||
|
f.Rets.ReturnsError = true
|
||||||
|
} else {
|
||||||
|
f.Rets.Name = r[0].Name
|
||||||
|
f.Rets.Type = r[0].Type
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if !r[1].IsError() {
|
||||||
|
return nil, errors.New("Only last windows error is allowed as second return value in \"" + f.src + "\"")
|
||||||
|
}
|
||||||
|
f.Rets.ReturnsError = true
|
||||||
|
f.Rets.Name = r[0].Name
|
||||||
|
f.Rets.Type = r[0].Type
|
||||||
|
default:
|
||||||
|
return nil, errors.New("Too many return values in \"" + f.src + "\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fail condition
|
||||||
|
_, body, s, found = extractSection(s, '[', ']')
|
||||||
|
if found {
|
||||||
|
f.Rets.FailCond = body
|
||||||
|
}
|
||||||
|
// dll and dll function names
|
||||||
|
s = trim(s)
|
||||||
|
if s == "" {
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(s, "=") {
|
||||||
|
return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
|
||||||
|
}
|
||||||
|
s = trim(s[1:])
|
||||||
|
a := strings.Split(s, ".")
|
||||||
|
switch len(a) {
|
||||||
|
case 1:
|
||||||
|
f.dllfuncname = a[0]
|
||||||
|
case 2:
|
||||||
|
f.dllname = a[0]
|
||||||
|
f.dllfuncname = a[1]
|
||||||
|
default:
|
||||||
|
return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
|
||||||
|
}
|
||||||
|
if f.dllfuncname[len(f.dllfuncname)-1] == '?' {
|
||||||
|
f.confirmproc = true
|
||||||
|
f.dllfuncname = f.dllfuncname[0 : len(f.dllfuncname)-1]
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DLLName returns DLL name for function f.
|
||||||
|
func (f *Fn) DLLName() string {
|
||||||
|
if f.dllname == "" {
|
||||||
|
return "kernel32"
|
||||||
|
}
|
||||||
|
return f.dllname
|
||||||
|
}
|
||||||
|
|
||||||
|
// DLLName returns DLL function name for function f.
|
||||||
|
func (f *Fn) DLLFuncName() string {
|
||||||
|
if f.dllfuncname == "" {
|
||||||
|
return f.Name
|
||||||
|
}
|
||||||
|
return f.dllfuncname
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Fn) ConfirmProc() bool {
|
||||||
|
return f.confirmproc
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamList returns source code for function f parameters.
|
||||||
|
func (f *Fn) ParamList() string {
|
||||||
|
return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// HelperParamList returns source code for helper function f parameters.
|
||||||
|
func (f *Fn) HelperParamList() string {
|
||||||
|
return join(f.Params, func(p *Param) string { return p.Name + " " + p.HelperType() }, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamPrintList returns source code of trace printing part correspondent
|
||||||
|
// to syscall input parameters.
|
||||||
|
func (f *Fn) ParamPrintList() string {
|
||||||
|
return join(f.Params, func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamCount return number of syscall parameters for function f.
|
||||||
|
func (f *Fn) ParamCount() int {
|
||||||
|
n := 0
|
||||||
|
for _, p := range f.Params {
|
||||||
|
n += len(p.SyscallArgList())
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyscallParamCount determines which version of Syscall/Syscall6/Syscall9/...
|
||||||
|
// to use. It returns parameter count for correspondent SyscallX function.
|
||||||
|
func (f *Fn) SyscallParamCount() int {
|
||||||
|
n := f.ParamCount()
|
||||||
|
switch {
|
||||||
|
case n <= 3:
|
||||||
|
return 3
|
||||||
|
case n <= 6:
|
||||||
|
return 6
|
||||||
|
case n <= 9:
|
||||||
|
return 9
|
||||||
|
case n <= 12:
|
||||||
|
return 12
|
||||||
|
case n <= 15:
|
||||||
|
return 15
|
||||||
|
default:
|
||||||
|
panic("too many arguments to system call")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syscall determines which SyscallX function to use for function f.
|
||||||
|
func (f *Fn) Syscall() string {
|
||||||
|
c := f.SyscallParamCount()
|
||||||
|
if c == 3 {
|
||||||
|
return syscalldot() + "Syscall"
|
||||||
|
}
|
||||||
|
return syscalldot() + "Syscall" + strconv.Itoa(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyscallParamList returns source code for SyscallX parameters for function f.
|
||||||
|
func (f *Fn) SyscallParamList() string {
|
||||||
|
a := make([]string, 0)
|
||||||
|
for _, p := range f.Params {
|
||||||
|
a = append(a, p.SyscallArgList()...)
|
||||||
|
}
|
||||||
|
for len(a) < f.SyscallParamCount() {
|
||||||
|
a = append(a, "0")
|
||||||
|
}
|
||||||
|
return strings.Join(a, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// HelperCallParamList returns source code of call into function f helper.
|
||||||
|
func (f *Fn) HelperCallParamList() string {
|
||||||
|
a := make([]string, 0, len(f.Params))
|
||||||
|
for _, p := range f.Params {
|
||||||
|
s := p.Name
|
||||||
|
if p.Type == "string" {
|
||||||
|
s = p.tmpVar()
|
||||||
|
}
|
||||||
|
a = append(a, s)
|
||||||
|
}
|
||||||
|
return strings.Join(a, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsUTF16 is true, if f is W (utf16) function. It is false
|
||||||
|
// for all A (ascii) functions.
|
||||||
|
func (_ *Fn) IsUTF16() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// StrconvFunc returns name of Go string to OS string function for f.
|
||||||
|
func (f *Fn) StrconvFunc() string {
|
||||||
|
if f.IsUTF16() {
|
||||||
|
return syscalldot() + "UTF16PtrFromString"
|
||||||
|
}
|
||||||
|
return syscalldot() + "BytePtrFromString"
|
||||||
|
}
|
||||||
|
|
||||||
|
// StrconvType returns Go type name used for OS string for f.
|
||||||
|
func (f *Fn) StrconvType() string {
|
||||||
|
if f.IsUTF16() {
|
||||||
|
return "*uint16"
|
||||||
|
}
|
||||||
|
return "*byte"
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasStringParam is true, if f has at least one string parameter.
|
||||||
|
// Otherwise it is false.
|
||||||
|
func (f *Fn) HasStringParam() bool {
|
||||||
|
for _, p := range f.Params {
|
||||||
|
if p.Type == "string" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var uniqDllFuncName = make(map[string]bool)
|
||||||
|
|
||||||
|
// IsNotDuplicate is true if f is not a duplicated function
|
||||||
|
func (f *Fn) IsNotDuplicate() bool {
|
||||||
|
funcName := f.DLLFuncName()
|
||||||
|
if uniqDllFuncName[funcName] == false {
|
||||||
|
uniqDllFuncName[funcName] = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HelperName returns name of function f helper.
|
||||||
|
func (f *Fn) HelperName() string {
|
||||||
|
if !f.HasStringParam() {
|
||||||
|
return f.Name
|
||||||
|
}
|
||||||
|
return "_" + f.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source files and functions.
|
||||||
|
type Source struct {
|
||||||
|
Funcs []*Fn
|
||||||
|
Files []string
|
||||||
|
StdLibImports []string
|
||||||
|
ExternalImports []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (src *Source) Import(pkg string) {
|
||||||
|
src.StdLibImports = append(src.StdLibImports, pkg)
|
||||||
|
sort.Strings(src.StdLibImports)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (src *Source) ExternalImport(pkg string) {
|
||||||
|
src.ExternalImports = append(src.ExternalImports, pkg)
|
||||||
|
sort.Strings(src.ExternalImports)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseFiles parses files listed in fs and extracts all syscall
|
||||||
|
// functions listed in sys comments. It returns source files
|
||||||
|
// and functions collection *Source if successful.
|
||||||
|
func ParseFiles(fs []string) (*Source, error) {
|
||||||
|
src := &Source{
|
||||||
|
Funcs: make([]*Fn, 0),
|
||||||
|
Files: make([]string, 0),
|
||||||
|
StdLibImports: []string{
|
||||||
|
"unsafe",
|
||||||
|
},
|
||||||
|
ExternalImports: make([]string, 0),
|
||||||
|
}
|
||||||
|
for _, file := range fs {
|
||||||
|
if err := src.ParseFile(file); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return src, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DLLs return dll names for a source set src.
|
||||||
|
func (src *Source) DLLs() []string {
|
||||||
|
uniq := make(map[string]bool)
|
||||||
|
r := make([]string, 0)
|
||||||
|
for _, f := range src.Funcs {
|
||||||
|
name := f.DLLName()
|
||||||
|
if _, found := uniq[name]; !found {
|
||||||
|
uniq[name] = true
|
||||||
|
r = append(r, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseFile adds additional file path to a source set src.
|
||||||
|
func (src *Source) ParseFile(path string) error {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
s := bufio.NewScanner(file)
|
||||||
|
for s.Scan() {
|
||||||
|
t := trim(s.Text())
|
||||||
|
if len(t) < 7 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(t, "//sys") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t = t[5:]
|
||||||
|
if !(t[0] == ' ' || t[0] == '\t') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
f, err := newFn(t[1:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
src.Funcs = append(src.Funcs, f)
|
||||||
|
}
|
||||||
|
if err := s.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
src.Files = append(src.Files, path)
|
||||||
|
|
||||||
|
// get package name
|
||||||
|
fset := token.NewFileSet()
|
||||||
|
_, err = file.Seek(0, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pkg, err := parser.ParseFile(fset, "", file, parser.PackageClauseOnly)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
packageName = pkg.Name.Name
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStdRepo returns true if src is part of standard library.
|
||||||
|
func (src *Source) IsStdRepo() (bool, error) {
|
||||||
|
if len(src.Files) == 0 {
|
||||||
|
return false, errors.New("no input files provided")
|
||||||
|
}
|
||||||
|
abspath, err := filepath.Abs(src.Files[0])
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
goroot := runtime.GOROOT()
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
abspath = strings.ToLower(abspath)
|
||||||
|
goroot = strings.ToLower(goroot)
|
||||||
|
}
|
||||||
|
sep := string(os.PathSeparator)
|
||||||
|
if !strings.HasSuffix(goroot, sep) {
|
||||||
|
goroot += sep
|
||||||
|
}
|
||||||
|
return strings.HasPrefix(abspath, goroot), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate output source file from a source set src.
|
||||||
|
func (src *Source) Generate(w io.Writer) error {
|
||||||
|
const (
|
||||||
|
pkgStd = iota // any package in std library
|
||||||
|
pkgXSysWindows // x/sys/windows package
|
||||||
|
pkgOther
|
||||||
|
)
|
||||||
|
isStdRepo, err := src.IsStdRepo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var pkgtype int
|
||||||
|
switch {
|
||||||
|
case isStdRepo:
|
||||||
|
pkgtype = pkgStd
|
||||||
|
case packageName == "windows":
|
||||||
|
// TODO: this needs better logic than just using package name
|
||||||
|
pkgtype = pkgXSysWindows
|
||||||
|
default:
|
||||||
|
pkgtype = pkgOther
|
||||||
|
}
|
||||||
|
if *systemDLL {
|
||||||
|
switch pkgtype {
|
||||||
|
case pkgStd:
|
||||||
|
src.Import("internal/syscall/windows/sysdll")
|
||||||
|
case pkgXSysWindows:
|
||||||
|
default:
|
||||||
|
src.ExternalImport("golang.org/x/sys/windows")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src.ExternalImport("github.com/Microsoft/go-winio")
|
||||||
|
if packageName != "syscall" {
|
||||||
|
src.Import("syscall")
|
||||||
|
}
|
||||||
|
funcMap := template.FuncMap{
|
||||||
|
"packagename": packagename,
|
||||||
|
"syscalldot": syscalldot,
|
||||||
|
"newlazydll": func(dll string) string {
|
||||||
|
arg := "\"" + dll + ".dll\""
|
||||||
|
if !*systemDLL {
|
||||||
|
return syscalldot() + "NewLazyDLL(" + arg + ")"
|
||||||
|
}
|
||||||
|
switch pkgtype {
|
||||||
|
case pkgStd:
|
||||||
|
return syscalldot() + "NewLazyDLL(sysdll.Add(" + arg + "))"
|
||||||
|
case pkgXSysWindows:
|
||||||
|
return "NewLazySystemDLL(" + arg + ")"
|
||||||
|
default:
|
||||||
|
return "windows.NewLazySystemDLL(" + arg + ")"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
t := template.Must(template.New("main").Funcs(funcMap).Parse(srcTemplate))
|
||||||
|
err = t.Execute(w, src)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("Failed to execute template: " + err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func usage() {
|
||||||
|
fmt.Fprintf(os.Stderr, "usage: mksyscall_windows [flags] [path ...]\n")
|
||||||
|
flag.PrintDefaults()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Usage = usage
|
||||||
|
flag.Parse()
|
||||||
|
if len(flag.Args()) <= 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
||||||
|
usage()
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := ParseFiles(flag.Args())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := src.Generate(&buf); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := format.Source(buf.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if *filename == "" {
|
||||||
|
_, err = os.Stdout.Write(data)
|
||||||
|
} else {
|
||||||
|
err = ioutil.WriteFile(*filename, data, 0644)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use println instead to print in the following template
|
||||||
|
const srcTemplate = `
|
||||||
|
|
||||||
|
{{define "main"}}// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
||||||
|
|
||||||
|
package {{packagename}}
|
||||||
|
|
||||||
|
import (
|
||||||
|
{{range .StdLibImports}}"{{.}}"
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{range .ExternalImports}}"{{.}}"
|
||||||
|
{{end}}
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
|
// Do the interface allocations only once for common
|
||||||
|
// Errno values.
|
||||||
|
const (
|
||||||
|
errnoERROR_IO_PENDING = 997
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errERROR_IO_PENDING error = {{syscalldot}}Errno(errnoERROR_IO_PENDING)
|
||||||
|
)
|
||||||
|
|
||||||
|
// errnoErr returns common boxed Errno values, to prevent
|
||||||
|
// allocations at runtime.
|
||||||
|
func errnoErr(e {{syscalldot}}Errno) error {
|
||||||
|
switch e {
|
||||||
|
case 0:
|
||||||
|
return nil
|
||||||
|
case errnoERROR_IO_PENDING:
|
||||||
|
return errERROR_IO_PENDING
|
||||||
|
}
|
||||||
|
// TODO: add more here, after collecting data on the common
|
||||||
|
// error values see on Windows. (perhaps when running
|
||||||
|
// all.bat?)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
{{template "dlls" .}}
|
||||||
|
{{template "funcnames" .}})
|
||||||
|
{{range .Funcs}}{{if .HasStringParam}}{{template "helperbody" .}}{{end}}{{template "funcbody" .}}{{end}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{/* help functions */}}
|
||||||
|
|
||||||
|
{{define "dlls"}}{{range .DLLs}} mod{{.}} = {{newlazydll .}}
|
||||||
|
{{end}}{{end}}
|
||||||
|
|
||||||
|
{{define "funcnames"}}{{range .Funcs}}{{if .IsNotDuplicate}} proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}"){{end}}
|
||||||
|
{{end}}{{end}}
|
||||||
|
|
||||||
|
{{define "helperbody"}}
|
||||||
|
func {{.Name}}({{.ParamList}}) {{template "results" .}}{
|
||||||
|
{{template "helpertmpvars" .}} return {{.HelperName}}({{.HelperCallParamList}})
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "funcbody"}}
|
||||||
|
func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
|
||||||
|
{{template "tmpvars" .}} {{template "syscallcheck" .}}{{template "syscall" .}}
|
||||||
|
{{template "seterror" .}}{{template "printtrace" .}} return
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}}
|
||||||
|
{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
|
{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}}
|
||||||
|
{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
|
{{define "results"}}{{if .Rets.List}}{{.Rets.List}} {{end}}{{end}}
|
||||||
|
|
||||||
|
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
|
||||||
|
|
||||||
|
{{define "syscallcheck"}}{{if .ConfirmProc}}if {{.Rets.ErrorVarName}} = proc{{.DLLFuncName}}.Find(); {{.Rets.ErrorVarName}} != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
{{end}}{{end}}
|
||||||
|
|
||||||
|
|
||||||
|
{{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}}
|
||||||
|
{{end}}{{end}}
|
||||||
|
|
||||||
|
{{define "printtrace"}}{{if .PrintTrace}} print("SYSCALL: {{.Name}}(", {{.ParamPrintList}}") (", {{.Rets.PrintList}}")\n")
|
||||||
|
{{end}}{{end}}
|
||||||
|
|
||||||
|
`
|
2
vendor/github.com/Microsoft/hcsshim/nametoguid.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/nametoguid.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// NameToGuid converts the given string into a GUID using the algorithm in the
|
// NameToGuid converts the given string into a GUID using the algorithm in the
|
||||||
// Host Compute Service, ensuring GUIDs generated with the same string are common
|
// Host Compute Service, ensuring GUIDs generated with the same string are common
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/preparelayer.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/preparelayer.go
generated
vendored
@ -3,7 +3,7 @@ package hcsshim
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var prepareLayerLock sync.Mutex
|
var prepareLayerLock sync.Mutex
|
||||||
|
9
vendor/github.com/Microsoft/hcsshim/process.go
generated
vendored
9
vendor/github.com/Microsoft/hcsshim/process.go
generated
vendored
@ -3,12 +3,11 @@ package hcsshim
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContainerError is an error encountered in HCS
|
// ContainerError is an error encountered in HCS
|
||||||
@ -322,17 +321,11 @@ func (process *process) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
process.handle = 0
|
process.handle = 0
|
||||||
runtime.SetFinalizer(process, nil)
|
|
||||||
|
|
||||||
logrus.Debugf(title+" succeeded processid=%d", process.processID)
|
logrus.Debugf(title+" succeeded processid=%d", process.processID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// closeProcess wraps process.Close for use by a finalizer
|
|
||||||
func closeProcess(process *process) {
|
|
||||||
process.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (process *process) registerCallback() error {
|
func (process *process) registerCallback() error {
|
||||||
context := ¬ifcationWatcherContext{
|
context := ¬ifcationWatcherContext{
|
||||||
channels: newChannels(),
|
channels: newChannels(),
|
||||||
|
2
vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package hcsshim
|
package hcsshim
|
||||||
|
|
||||||
import "github.com/Sirupsen/logrus"
|
import "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// UnprepareLayer disables the filesystem filter for the read-write layer with
|
// UnprepareLayer disables the filesystem filter for the read-write layer with
|
||||||
// the given id.
|
// the given id.
|
||||||
|
3
vendor/github.com/Microsoft/hcsshim/waithelper.go
generated
vendored
3
vendor/github.com/Microsoft/hcsshim/waithelper.go
generated
vendored
@ -3,7 +3,7 @@ package hcsshim
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
|
func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
|
||||||
@ -59,4 +59,5 @@ func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotific
|
|||||||
case <-c:
|
case <-c:
|
||||||
return ErrTimeout
|
return ErrTimeout
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/docker/go-events/broadcast.go
generated
vendored
2
vendor/github.com/docker/go-events/broadcast.go
generated
vendored
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Broadcaster sends events to multiple, reliable Sinks. The goal of this
|
// Broadcaster sends events to multiple, reliable Sinks. The goal of this
|
||||||
|
2
vendor/github.com/docker/go-events/queue.go
generated
vendored
2
vendor/github.com/docker/go-events/queue.go
generated
vendored
@ -4,7 +4,7 @@ import (
|
|||||||
"container/list"
|
"container/list"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Queue accepts all messages into a queue for asynchronous consumption
|
// Queue accepts all messages into a queue for asynchronous consumption
|
||||||
|
2
vendor/github.com/docker/go-events/retry.go
generated
vendored
2
vendor/github.com/docker/go-events/retry.go
generated
vendored
@ -7,7 +7,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RetryingSink retries the write until success or an ErrSinkClosed is
|
// RetryingSink retries the write until success or an ErrSinkClosed is
|
||||||
|
100
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
100
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
@ -1,100 +0,0 @@
|
|||||||
# 1.0.0
|
|
||||||
|
|
||||||
* Officially changed name to lower-case
|
|
||||||
* bug: colors on Windows 10 (#541)
|
|
||||||
* bug: fix race in accessing level (#512)
|
|
||||||
|
|
||||||
# 0.11.5
|
|
||||||
|
|
||||||
* feature: add writer and writerlevel to entry (#372)
|
|
||||||
|
|
||||||
# 0.11.4
|
|
||||||
|
|
||||||
* bug: fix undefined variable on solaris (#493)
|
|
||||||
|
|
||||||
# 0.11.3
|
|
||||||
|
|
||||||
* formatter: configure quoting of empty values (#484)
|
|
||||||
* formatter: configure quoting character (default is `"`) (#484)
|
|
||||||
* bug: fix not importing io correctly in non-linux environments (#481)
|
|
||||||
|
|
||||||
# 0.11.2
|
|
||||||
|
|
||||||
* bug: fix windows terminal detection (#476)
|
|
||||||
|
|
||||||
# 0.11.1
|
|
||||||
|
|
||||||
* bug: fix tty detection with custom out (#471)
|
|
||||||
|
|
||||||
# 0.11.0
|
|
||||||
|
|
||||||
* performance: Use bufferpool to allocate (#370)
|
|
||||||
* terminal: terminal detection for app-engine (#343)
|
|
||||||
* feature: exit handler (#375)
|
|
||||||
|
|
||||||
# 0.10.0
|
|
||||||
|
|
||||||
* feature: Add a test hook (#180)
|
|
||||||
* feature: `ParseLevel` is now case-insensitive (#326)
|
|
||||||
* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
|
|
||||||
* performance: avoid re-allocations on `WithFields` (#335)
|
|
||||||
|
|
||||||
# 0.9.0
|
|
||||||
|
|
||||||
* logrus/text_formatter: don't emit empty msg
|
|
||||||
* logrus/hooks/airbrake: move out of main repository
|
|
||||||
* logrus/hooks/sentry: move out of main repository
|
|
||||||
* logrus/hooks/papertrail: move out of main repository
|
|
||||||
* logrus/hooks/bugsnag: move out of main repository
|
|
||||||
* logrus/core: run tests with `-race`
|
|
||||||
* logrus/core: detect TTY based on `stderr`
|
|
||||||
* logrus/core: support `WithError` on logger
|
|
||||||
* logrus/core: Solaris support
|
|
||||||
|
|
||||||
# 0.8.7
|
|
||||||
|
|
||||||
* logrus/core: fix possible race (#216)
|
|
||||||
* logrus/doc: small typo fixes and doc improvements
|
|
||||||
|
|
||||||
|
|
||||||
# 0.8.6
|
|
||||||
|
|
||||||
* hooks/raven: allow passing an initialized client
|
|
||||||
|
|
||||||
# 0.8.5
|
|
||||||
|
|
||||||
* logrus/core: revert #208
|
|
||||||
|
|
||||||
# 0.8.4
|
|
||||||
|
|
||||||
* formatter/text: fix data race (#218)
|
|
||||||
|
|
||||||
# 0.8.3
|
|
||||||
|
|
||||||
* logrus/core: fix entry log level (#208)
|
|
||||||
* logrus/core: improve performance of text formatter by 40%
|
|
||||||
* logrus/core: expose `LevelHooks` type
|
|
||||||
* logrus/core: add support for DragonflyBSD and NetBSD
|
|
||||||
* formatter/text: print structs more verbosely
|
|
||||||
|
|
||||||
# 0.8.2
|
|
||||||
|
|
||||||
* logrus: fix more Fatal family functions
|
|
||||||
|
|
||||||
# 0.8.1
|
|
||||||
|
|
||||||
* logrus: fix not exiting on `Fatalf` and `Fatalln`
|
|
||||||
|
|
||||||
# 0.8.0
|
|
||||||
|
|
||||||
* logrus: defaults to stderr instead of stdout
|
|
||||||
* hooks/sentry: add special field for `*http.Request`
|
|
||||||
* formatter/text: ignore Windows for colors
|
|
||||||
|
|
||||||
# 0.7.3
|
|
||||||
|
|
||||||
* formatter/\*: allow configuration of timestamp layout
|
|
||||||
|
|
||||||
# 0.7.2
|
|
||||||
|
|
||||||
* formatter/text: Add configuration option for time format (#158)
|
|
74
vendor/github.com/sirupsen/logrus/alt_exit_test.go
generated
vendored
74
vendor/github.com/sirupsen/logrus/alt_exit_test.go
generated
vendored
@ -1,74 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"os/exec"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestRegister(t *testing.T) {
|
|
||||||
current := len(handlers)
|
|
||||||
RegisterExitHandler(func() {})
|
|
||||||
if len(handlers) != current+1 {
|
|
||||||
t.Fatalf("can't add handler")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandler(t *testing.T) {
|
|
||||||
gofile := "/tmp/testprog.go"
|
|
||||||
if err := ioutil.WriteFile(gofile, testprog, 0666); err != nil {
|
|
||||||
t.Fatalf("can't create go file")
|
|
||||||
}
|
|
||||||
|
|
||||||
outfile := "/tmp/testprog.out"
|
|
||||||
arg := time.Now().UTC().String()
|
|
||||||
err := exec.Command("go", "run", gofile, outfile, arg).Run()
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("completed normally, should have failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(outfile)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("can't read output file %s", outfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(data) != arg {
|
|
||||||
t.Fatalf("bad data")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var testprog = []byte(`
|
|
||||||
// Test program for atexit, gets output file and data as arguments and writes
|
|
||||||
// data to output file in atexit handler.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
var outfile = ""
|
|
||||||
var data = ""
|
|
||||||
|
|
||||||
func handler() {
|
|
||||||
ioutil.WriteFile(outfile, []byte(data), 0666)
|
|
||||||
}
|
|
||||||
|
|
||||||
func badHandler() {
|
|
||||||
n := 0
|
|
||||||
fmt.Println(1/n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
outfile = flag.Arg(0)
|
|
||||||
data = flag.Arg(1)
|
|
||||||
|
|
||||||
logrus.RegisterExitHandler(handler)
|
|
||||||
logrus.RegisterExitHandler(badHandler)
|
|
||||||
logrus.Fatal("Bye bye")
|
|
||||||
}
|
|
||||||
`)
|
|
77
vendor/github.com/sirupsen/logrus/entry_test.go
generated
vendored
77
vendor/github.com/sirupsen/logrus/entry_test.go
generated
vendored
@ -1,77 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestEntryWithError(t *testing.T) {
|
|
||||||
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
ErrorKey = "error"
|
|
||||||
}()
|
|
||||||
|
|
||||||
err := fmt.Errorf("kaboom at layer %d", 4711)
|
|
||||||
|
|
||||||
assert.Equal(err, WithError(err).Data["error"])
|
|
||||||
|
|
||||||
logger := New()
|
|
||||||
logger.Out = &bytes.Buffer{}
|
|
||||||
entry := NewEntry(logger)
|
|
||||||
|
|
||||||
assert.Equal(err, entry.WithError(err).Data["error"])
|
|
||||||
|
|
||||||
ErrorKey = "err"
|
|
||||||
|
|
||||||
assert.Equal(err, entry.WithError(err).Data["err"])
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEntryPanicln(t *testing.T) {
|
|
||||||
errBoom := fmt.Errorf("boom time")
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
p := recover()
|
|
||||||
assert.NotNil(t, p)
|
|
||||||
|
|
||||||
switch pVal := p.(type) {
|
|
||||||
case *Entry:
|
|
||||||
assert.Equal(t, "kaboom", pVal.Message)
|
|
||||||
assert.Equal(t, errBoom, pVal.Data["err"])
|
|
||||||
default:
|
|
||||||
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
logger := New()
|
|
||||||
logger.Out = &bytes.Buffer{}
|
|
||||||
entry := NewEntry(logger)
|
|
||||||
entry.WithField("err", errBoom).Panicln("kaboom")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEntryPanicf(t *testing.T) {
|
|
||||||
errBoom := fmt.Errorf("boom again")
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
p := recover()
|
|
||||||
assert.NotNil(t, p)
|
|
||||||
|
|
||||||
switch pVal := p.(type) {
|
|
||||||
case *Entry:
|
|
||||||
assert.Equal(t, "kaboom true", pVal.Message)
|
|
||||||
assert.Equal(t, errBoom, pVal.Data["err"])
|
|
||||||
default:
|
|
||||||
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
logger := New()
|
|
||||||
logger.Out = &bytes.Buffer{}
|
|
||||||
entry := NewEntry(logger)
|
|
||||||
entry.WithField("err", errBoom).Panicf("kaboom %v", true)
|
|
||||||
}
|
|
59
vendor/github.com/sirupsen/logrus/examples/basic/basic.go
generated
vendored
59
vendor/github.com/sirupsen/logrus/examples/basic/basic.go
generated
vendored
@ -1,59 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
// "os"
|
|
||||||
)
|
|
||||||
|
|
||||||
var log = logrus.New()
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.Formatter = new(logrus.JSONFormatter)
|
|
||||||
log.Formatter = new(logrus.TextFormatter) // default
|
|
||||||
|
|
||||||
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
|
|
||||||
// if err == nil {
|
|
||||||
// log.Out = file
|
|
||||||
// } else {
|
|
||||||
// log.Info("Failed to log to file, using default stderr")
|
|
||||||
// }
|
|
||||||
|
|
||||||
log.Level = logrus.DebugLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
defer func() {
|
|
||||||
err := recover()
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"err": err,
|
|
||||||
"number": 100,
|
|
||||||
}).Fatal("The ice breaks!")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"number": 8,
|
|
||||||
}).Debug("Started observing beach")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"size": 10,
|
|
||||||
}).Info("A group of walrus emerges from the ocean")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"number": 122,
|
|
||||||
}).Warn("The group's number increased tremendously!")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"temperature": -4,
|
|
||||||
}).Debug("Temperature changes")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "orca",
|
|
||||||
"size": 9009,
|
|
||||||
}).Panic("It's over 9000!")
|
|
||||||
}
|
|
30
vendor/github.com/sirupsen/logrus/examples/hook/hook.go
generated
vendored
30
vendor/github.com/sirupsen/logrus/examples/hook/hook.go
generated
vendored
@ -1,30 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
var log = logrus.New()
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.Formatter = new(logrus.TextFormatter) // default
|
|
||||||
log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"size": 10,
|
|
||||||
}).Info("A group of walrus emerges from the ocean")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"number": 122,
|
|
||||||
}).Warn("The group's number increased tremendously!")
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"number": 100,
|
|
||||||
}).Fatal("The ice breaks!")
|
|
||||||
}
|
|
101
vendor/github.com/sirupsen/logrus/formatter_bench_test.go
generated
vendored
101
vendor/github.com/sirupsen/logrus/formatter_bench_test.go
generated
vendored
@ -1,101 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// smallFields is a small size data set for benchmarking
|
|
||||||
var smallFields = Fields{
|
|
||||||
"foo": "bar",
|
|
||||||
"baz": "qux",
|
|
||||||
"one": "two",
|
|
||||||
"three": "four",
|
|
||||||
}
|
|
||||||
|
|
||||||
// largeFields is a large size data set for benchmarking
|
|
||||||
var largeFields = Fields{
|
|
||||||
"foo": "bar",
|
|
||||||
"baz": "qux",
|
|
||||||
"one": "two",
|
|
||||||
"three": "four",
|
|
||||||
"five": "six",
|
|
||||||
"seven": "eight",
|
|
||||||
"nine": "ten",
|
|
||||||
"eleven": "twelve",
|
|
||||||
"thirteen": "fourteen",
|
|
||||||
"fifteen": "sixteen",
|
|
||||||
"seventeen": "eighteen",
|
|
||||||
"nineteen": "twenty",
|
|
||||||
"a": "b",
|
|
||||||
"c": "d",
|
|
||||||
"e": "f",
|
|
||||||
"g": "h",
|
|
||||||
"i": "j",
|
|
||||||
"k": "l",
|
|
||||||
"m": "n",
|
|
||||||
"o": "p",
|
|
||||||
"q": "r",
|
|
||||||
"s": "t",
|
|
||||||
"u": "v",
|
|
||||||
"w": "x",
|
|
||||||
"y": "z",
|
|
||||||
"this": "will",
|
|
||||||
"make": "thirty",
|
|
||||||
"entries": "yeah",
|
|
||||||
}
|
|
||||||
|
|
||||||
var errorFields = Fields{
|
|
||||||
"foo": fmt.Errorf("bar"),
|
|
||||||
"baz": fmt.Errorf("qux"),
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkErrorTextFormatter(b *testing.B) {
|
|
||||||
doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSmallTextFormatter(b *testing.B) {
|
|
||||||
doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLargeTextFormatter(b *testing.B) {
|
|
||||||
doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSmallColoredTextFormatter(b *testing.B) {
|
|
||||||
doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLargeColoredTextFormatter(b *testing.B) {
|
|
||||||
doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSmallJSONFormatter(b *testing.B) {
|
|
||||||
doBenchmark(b, &JSONFormatter{}, smallFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLargeJSONFormatter(b *testing.B) {
|
|
||||||
doBenchmark(b, &JSONFormatter{}, largeFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
|
|
||||||
logger := New()
|
|
||||||
|
|
||||||
entry := &Entry{
|
|
||||||
Time: time.Time{},
|
|
||||||
Level: InfoLevel,
|
|
||||||
Message: "message",
|
|
||||||
Data: fields,
|
|
||||||
Logger: logger,
|
|
||||||
}
|
|
||||||
var d []byte
|
|
||||||
var err error
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
d, err = formatter.Format(entry)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
b.SetBytes(int64(len(d)))
|
|
||||||
}
|
|
||||||
}
|
|
122
vendor/github.com/sirupsen/logrus/hook_test.go
generated
vendored
122
vendor/github.com/sirupsen/logrus/hook_test.go
generated
vendored
@ -1,122 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestHook struct {
|
|
||||||
Fired bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hook *TestHook) Fire(entry *Entry) error {
|
|
||||||
hook.Fired = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hook *TestHook) Levels() []Level {
|
|
||||||
return []Level{
|
|
||||||
DebugLevel,
|
|
||||||
InfoLevel,
|
|
||||||
WarnLevel,
|
|
||||||
ErrorLevel,
|
|
||||||
FatalLevel,
|
|
||||||
PanicLevel,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHookFires(t *testing.T) {
|
|
||||||
hook := new(TestHook)
|
|
||||||
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Hooks.Add(hook)
|
|
||||||
assert.Equal(t, hook.Fired, false)
|
|
||||||
|
|
||||||
log.Print("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, hook.Fired, true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type ModifyHook struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hook *ModifyHook) Fire(entry *Entry) error {
|
|
||||||
entry.Data["wow"] = "whale"
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hook *ModifyHook) Levels() []Level {
|
|
||||||
return []Level{
|
|
||||||
DebugLevel,
|
|
||||||
InfoLevel,
|
|
||||||
WarnLevel,
|
|
||||||
ErrorLevel,
|
|
||||||
FatalLevel,
|
|
||||||
PanicLevel,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHookCanModifyEntry(t *testing.T) {
|
|
||||||
hook := new(ModifyHook)
|
|
||||||
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Hooks.Add(hook)
|
|
||||||
log.WithField("wow", "elephant").Print("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["wow"], "whale")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCanFireMultipleHooks(t *testing.T) {
|
|
||||||
hook1 := new(ModifyHook)
|
|
||||||
hook2 := new(TestHook)
|
|
||||||
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Hooks.Add(hook1)
|
|
||||||
log.Hooks.Add(hook2)
|
|
||||||
|
|
||||||
log.WithField("wow", "elephant").Print("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["wow"], "whale")
|
|
||||||
assert.Equal(t, hook2.Fired, true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type ErrorHook struct {
|
|
||||||
Fired bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hook *ErrorHook) Fire(entry *Entry) error {
|
|
||||||
hook.Fired = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hook *ErrorHook) Levels() []Level {
|
|
||||||
return []Level{
|
|
||||||
ErrorLevel,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestErrorHookShouldntFireOnInfo(t *testing.T) {
|
|
||||||
hook := new(ErrorHook)
|
|
||||||
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Hooks.Add(hook)
|
|
||||||
log.Info("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, hook.Fired, false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestErrorHookShouldFireOnError(t *testing.T) {
|
|
||||||
hook := new(ErrorHook)
|
|
||||||
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Hooks.Add(hook)
|
|
||||||
log.Error("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, hook.Fired, true)
|
|
||||||
})
|
|
||||||
}
|
|
39
vendor/github.com/sirupsen/logrus/hooks/syslog/README.md
generated
vendored
39
vendor/github.com/sirupsen/logrus/hooks/syslog/README.md
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"log/syslog"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log := logrus.New()
|
|
||||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
log.Hooks.Add(hook)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). Just assign empty string to the first two parameters of `NewSyslogHook`. It should look like the following.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"log/syslog"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log := logrus.New()
|
|
||||||
hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
log.Hooks.Add(hook)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
54
vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
54
vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
@ -1,54 +0,0 @@
|
|||||||
// +build !windows,!nacl,!plan9
|
|
||||||
|
|
||||||
package logrus_syslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"log/syslog"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SyslogHook to send logs via syslog.
|
|
||||||
type SyslogHook struct {
|
|
||||||
Writer *syslog.Writer
|
|
||||||
SyslogNetwork string
|
|
||||||
SyslogRaddr string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a hook to be added to an instance of logger. This is called with
|
|
||||||
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
|
||||||
// `if err == nil { log.Hooks.Add(hook) }`
|
|
||||||
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
|
||||||
w, err := syslog.Dial(network, raddr, priority, tag)
|
|
||||||
return &SyslogHook{w, network, raddr}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
|
||||||
line, err := entry.String()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch entry.Level {
|
|
||||||
case logrus.PanicLevel:
|
|
||||||
return hook.Writer.Crit(line)
|
|
||||||
case logrus.FatalLevel:
|
|
||||||
return hook.Writer.Crit(line)
|
|
||||||
case logrus.ErrorLevel:
|
|
||||||
return hook.Writer.Err(line)
|
|
||||||
case logrus.WarnLevel:
|
|
||||||
return hook.Writer.Warning(line)
|
|
||||||
case logrus.InfoLevel:
|
|
||||||
return hook.Writer.Info(line)
|
|
||||||
case logrus.DebugLevel:
|
|
||||||
return hook.Writer.Debug(line)
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hook *SyslogHook) Levels() []logrus.Level {
|
|
||||||
return logrus.AllLevels
|
|
||||||
}
|
|
26
vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
26
vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
package logrus_syslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"log/syslog"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestLocalhostAddAndPrint(t *testing.T) {
|
|
||||||
log := logrus.New()
|
|
||||||
hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Unable to connect to local syslog.")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Hooks.Add(hook)
|
|
||||||
|
|
||||||
for _, level := range hook.Levels() {
|
|
||||||
if len(log.Hooks[level]) != 1 {
|
|
||||||
t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Congratulations!")
|
|
||||||
}
|
|
95
vendor/github.com/sirupsen/logrus/hooks/test/test.go
generated
vendored
95
vendor/github.com/sirupsen/logrus/hooks/test/test.go
generated
vendored
@ -1,95 +0,0 @@
|
|||||||
// The Test package is used for testing logrus. It is here for backwards
|
|
||||||
// compatibility from when logrus' organization was upper-case. Please use
|
|
||||||
// lower-case logrus and the `null` package instead of this one.
|
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Hook is a hook designed for dealing with logs in test scenarios.
|
|
||||||
type Hook struct {
|
|
||||||
// Entries is an array of all entries that have been received by this hook.
|
|
||||||
// For safe access, use the AllEntries() method, rather than reading this
|
|
||||||
// value directly.
|
|
||||||
Entries []*logrus.Entry
|
|
||||||
mu sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGlobal installs a test hook for the global logger.
|
|
||||||
func NewGlobal() *Hook {
|
|
||||||
|
|
||||||
hook := new(Hook)
|
|
||||||
logrus.AddHook(hook)
|
|
||||||
|
|
||||||
return hook
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLocal installs a test hook for a given local logger.
|
|
||||||
func NewLocal(logger *logrus.Logger) *Hook {
|
|
||||||
|
|
||||||
hook := new(Hook)
|
|
||||||
logger.Hooks.Add(hook)
|
|
||||||
|
|
||||||
return hook
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewNullLogger creates a discarding logger and installs the test hook.
|
|
||||||
func NewNullLogger() (*logrus.Logger, *Hook) {
|
|
||||||
|
|
||||||
logger := logrus.New()
|
|
||||||
logger.Out = ioutil.Discard
|
|
||||||
|
|
||||||
return logger, NewLocal(logger)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Hook) Fire(e *logrus.Entry) error {
|
|
||||||
t.mu.Lock()
|
|
||||||
defer t.mu.Unlock()
|
|
||||||
t.Entries = append(t.Entries, e)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Hook) Levels() []logrus.Level {
|
|
||||||
return logrus.AllLevels
|
|
||||||
}
|
|
||||||
|
|
||||||
// LastEntry returns the last entry that was logged or nil.
|
|
||||||
func (t *Hook) LastEntry() *logrus.Entry {
|
|
||||||
t.mu.RLock()
|
|
||||||
defer t.mu.RUnlock()
|
|
||||||
i := len(t.Entries) - 1
|
|
||||||
if i < 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// Make a copy, for safety
|
|
||||||
e := *t.Entries[i]
|
|
||||||
return &e
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllEntries returns all entries that were logged.
|
|
||||||
func (t *Hook) AllEntries() []*logrus.Entry {
|
|
||||||
t.mu.RLock()
|
|
||||||
defer t.mu.RUnlock()
|
|
||||||
// Make a copy so the returned value won't race with future log requests
|
|
||||||
entries := make([]*logrus.Entry, len(t.Entries))
|
|
||||||
for i, entry := range t.Entries {
|
|
||||||
// Make a copy, for safety
|
|
||||||
e := *entry
|
|
||||||
entries[i] = &e
|
|
||||||
}
|
|
||||||
return entries
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset removes all Entries from this test hook.
|
|
||||||
func (t *Hook) Reset() {
|
|
||||||
t.mu.Lock()
|
|
||||||
defer t.mu.Unlock()
|
|
||||||
t.Entries = make([]*logrus.Entry, 0)
|
|
||||||
}
|
|
39
vendor/github.com/sirupsen/logrus/hooks/test/test_test.go
generated
vendored
39
vendor/github.com/sirupsen/logrus/hooks/test/test_test.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAllHooks(t *testing.T) {
|
|
||||||
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
logger, hook := NewNullLogger()
|
|
||||||
assert.Nil(hook.LastEntry())
|
|
||||||
assert.Equal(0, len(hook.Entries))
|
|
||||||
|
|
||||||
logger.Error("Hello error")
|
|
||||||
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
|
|
||||||
assert.Equal("Hello error", hook.LastEntry().Message)
|
|
||||||
assert.Equal(1, len(hook.Entries))
|
|
||||||
|
|
||||||
logger.Warn("Hello warning")
|
|
||||||
assert.Equal(logrus.WarnLevel, hook.LastEntry().Level)
|
|
||||||
assert.Equal("Hello warning", hook.LastEntry().Message)
|
|
||||||
assert.Equal(2, len(hook.Entries))
|
|
||||||
|
|
||||||
hook.Reset()
|
|
||||||
assert.Nil(hook.LastEntry())
|
|
||||||
assert.Equal(0, len(hook.Entries))
|
|
||||||
|
|
||||||
hook = NewGlobal()
|
|
||||||
|
|
||||||
logrus.Error("Hello error")
|
|
||||||
assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
|
|
||||||
assert.Equal("Hello error", hook.LastEntry().Message)
|
|
||||||
assert.Equal(1, len(hook.Entries))
|
|
||||||
|
|
||||||
}
|
|
199
vendor/github.com/sirupsen/logrus/json_formatter_test.go
generated
vendored
199
vendor/github.com/sirupsen/logrus/json_formatter_test.go
generated
vendored
@ -1,199 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestErrorNotLost(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("error", errors.New("wild walrus")))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
entry := make(map[string]interface{})
|
|
||||||
err = json.Unmarshal(b, &entry)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry["error"] != "wild walrus" {
|
|
||||||
t.Fatal("Error field not set")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestErrorNotLostOnFieldNotNamedError(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("omg", errors.New("wild walrus")))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
entry := make(map[string]interface{})
|
|
||||||
err = json.Unmarshal(b, &entry)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry["omg"] != "wild walrus" {
|
|
||||||
t.Fatal("Error field not set")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFieldClashWithTime(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("time", "right now!"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
entry := make(map[string]interface{})
|
|
||||||
err = json.Unmarshal(b, &entry)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry["fields.time"] != "right now!" {
|
|
||||||
t.Fatal("fields.time not set to original time field")
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry["time"] != "0001-01-01T00:00:00Z" {
|
|
||||||
t.Fatal("time field not set to current time, was: ", entry["time"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFieldClashWithMsg(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("msg", "something"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
entry := make(map[string]interface{})
|
|
||||||
err = json.Unmarshal(b, &entry)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry["fields.msg"] != "something" {
|
|
||||||
t.Fatal("fields.msg not set to original msg field")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFieldClashWithLevel(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("level", "something"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
entry := make(map[string]interface{})
|
|
||||||
err = json.Unmarshal(b, &entry)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry["fields.level"] != "something" {
|
|
||||||
t.Fatal("fields.level not set to original level field")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJSONEntryEndsWithNewline(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("level", "something"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if b[len(b)-1] != '\n' {
|
|
||||||
t.Fatal("Expected JSON log entry to end with a newline")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJSONMessageKey(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{
|
|
||||||
FieldMap: FieldMap{
|
|
||||||
FieldKeyMsg: "message",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := formatter.Format(&Entry{Message: "oh hai"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
s := string(b)
|
|
||||||
if !(strings.Contains(s, "message") && strings.Contains(s, "oh hai")) {
|
|
||||||
t.Fatal("Expected JSON to format message key")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJSONLevelKey(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{
|
|
||||||
FieldMap: FieldMap{
|
|
||||||
FieldKeyLevel: "somelevel",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("level", "something"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
s := string(b)
|
|
||||||
if !strings.Contains(s, "somelevel") {
|
|
||||||
t.Fatal("Expected JSON to format level key")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJSONTimeKey(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{
|
|
||||||
FieldMap: FieldMap{
|
|
||||||
FieldKeyTime: "timeywimey",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("level", "something"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
s := string(b)
|
|
||||||
if !strings.Contains(s, "timeywimey") {
|
|
||||||
t.Fatal("Expected JSON to format time key")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJSONDisableTimestamp(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{
|
|
||||||
DisableTimestamp: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("level", "something"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
s := string(b)
|
|
||||||
if strings.Contains(s, FieldKeyTime) {
|
|
||||||
t.Error("Did not prevent timestamp", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJSONEnableTimestamp(t *testing.T) {
|
|
||||||
formatter := &JSONFormatter{}
|
|
||||||
|
|
||||||
b, err := formatter.Format(WithField("level", "something"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Unable to format entry: ", err)
|
|
||||||
}
|
|
||||||
s := string(b)
|
|
||||||
if !strings.Contains(s, FieldKeyTime) {
|
|
||||||
t.Error("Timestamp not present", s)
|
|
||||||
}
|
|
||||||
}
|
|
61
vendor/github.com/sirupsen/logrus/logger_bench_test.go
generated
vendored
61
vendor/github.com/sirupsen/logrus/logger_bench_test.go
generated
vendored
@ -1,61 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// smallFields is a small size data set for benchmarking
|
|
||||||
var loggerFields = Fields{
|
|
||||||
"foo": "bar",
|
|
||||||
"baz": "qux",
|
|
||||||
"one": "two",
|
|
||||||
"three": "four",
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkDummyLogger(b *testing.B) {
|
|
||||||
nullf, err := os.OpenFile("/dev/null", os.O_WRONLY, 0666)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("%v", err)
|
|
||||||
}
|
|
||||||
defer nullf.Close()
|
|
||||||
doLoggerBenchmark(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkDummyLoggerNoLock(b *testing.B) {
|
|
||||||
nullf, err := os.OpenFile("/dev/null", os.O_WRONLY|os.O_APPEND, 0666)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("%v", err)
|
|
||||||
}
|
|
||||||
defer nullf.Close()
|
|
||||||
doLoggerBenchmarkNoLock(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func doLoggerBenchmark(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
|
|
||||||
logger := Logger{
|
|
||||||
Out: out,
|
|
||||||
Level: InfoLevel,
|
|
||||||
Formatter: formatter,
|
|
||||||
}
|
|
||||||
entry := logger.WithFields(fields)
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
|
||||||
for pb.Next() {
|
|
||||||
entry.Info("aaa")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func doLoggerBenchmarkNoLock(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
|
|
||||||
logger := Logger{
|
|
||||||
Out: out,
|
|
||||||
Level: InfoLevel,
|
|
||||||
Formatter: formatter,
|
|
||||||
}
|
|
||||||
logger.SetNoLock()
|
|
||||||
entry := logger.WithFields(fields)
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
|
||||||
for pb.Next() {
|
|
||||||
entry.Info("aaa")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
386
vendor/github.com/sirupsen/logrus/logrus_test.go
generated
vendored
386
vendor/github.com/sirupsen/logrus/logrus_test.go
generated
vendored
@ -1,386 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
var fields Fields
|
|
||||||
|
|
||||||
logger := New()
|
|
||||||
logger.Out = &buffer
|
|
||||||
logger.Formatter = new(JSONFormatter)
|
|
||||||
|
|
||||||
log(logger)
|
|
||||||
|
|
||||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
assertions(fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
|
|
||||||
logger := New()
|
|
||||||
logger.Out = &buffer
|
|
||||||
logger.Formatter = &TextFormatter{
|
|
||||||
DisableColors: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
log(logger)
|
|
||||||
|
|
||||||
fields := make(map[string]string)
|
|
||||||
for _, kv := range strings.Split(buffer.String(), " ") {
|
|
||||||
if !strings.Contains(kv, "=") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
kvArr := strings.Split(kv, "=")
|
|
||||||
key := strings.TrimSpace(kvArr[0])
|
|
||||||
val := kvArr[1]
|
|
||||||
if kvArr[1][0] == '"' {
|
|
||||||
var err error
|
|
||||||
val, err = strconv.Unquote(val)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
fields[key] = val
|
|
||||||
}
|
|
||||||
assertions(fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPrint(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Print("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "test")
|
|
||||||
assert.Equal(t, fields["level"], "info")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfo(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Info("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "test")
|
|
||||||
assert.Equal(t, fields["level"], "info")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWarn(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Warn("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "test")
|
|
||||||
assert.Equal(t, fields["level"], "warning")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Infoln("test", "test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "test test")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Infoln("test", 10)
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "test 10")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Infoln(10, 10)
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "10 10")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Infoln(10, 10)
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "10 10")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Info("test", 10)
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "test10")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.Info("test", "test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "testtest")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWithFieldsShouldAllowAssignments(t *testing.T) {
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
var fields Fields
|
|
||||||
|
|
||||||
logger := New()
|
|
||||||
logger.Out = &buffer
|
|
||||||
logger.Formatter = new(JSONFormatter)
|
|
||||||
|
|
||||||
localLog := logger.WithFields(Fields{
|
|
||||||
"key1": "value1",
|
|
||||||
})
|
|
||||||
|
|
||||||
localLog.WithField("key2", "value2").Info("test")
|
|
||||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, "value2", fields["key2"])
|
|
||||||
assert.Equal(t, "value1", fields["key1"])
|
|
||||||
|
|
||||||
buffer = bytes.Buffer{}
|
|
||||||
fields = Fields{}
|
|
||||||
localLog.Info("test")
|
|
||||||
err = json.Unmarshal(buffer.Bytes(), &fields)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
_, ok := fields["key2"]
|
|
||||||
assert.Equal(t, false, ok)
|
|
||||||
assert.Equal(t, "value1", fields["key1"])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.WithField("msg", "hello").Info("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "test")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.WithField("msg", "hello").Info("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["msg"], "test")
|
|
||||||
assert.Equal(t, fields["fields.msg"], "hello")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.WithField("time", "hello").Info("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["fields.time"], "hello")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
|
|
||||||
LogAndAssertJSON(t, func(log *Logger) {
|
|
||||||
log.WithField("level", 1).Info("test")
|
|
||||||
}, func(fields Fields) {
|
|
||||||
assert.Equal(t, fields["level"], "info")
|
|
||||||
assert.Equal(t, fields["fields.level"], 1.0) // JSON has floats only
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
|
|
||||||
LogAndAssertText(t, func(log *Logger) {
|
|
||||||
ll := log.WithField("herp", "derp")
|
|
||||||
ll.Info("hello")
|
|
||||||
ll.Info("bye")
|
|
||||||
}, func(fields map[string]string) {
|
|
||||||
for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
|
|
||||||
if _, ok := fields[fieldName]; ok {
|
|
||||||
t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
|
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
var fields Fields
|
|
||||||
|
|
||||||
logger := New()
|
|
||||||
logger.Out = &buffer
|
|
||||||
logger.Formatter = new(JSONFormatter)
|
|
||||||
|
|
||||||
llog := logger.WithField("context", "eating raw fish")
|
|
||||||
|
|
||||||
llog.Info("looks delicious")
|
|
||||||
|
|
||||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
|
||||||
assert.NoError(t, err, "should have decoded first message")
|
|
||||||
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
|
||||||
assert.Equal(t, fields["msg"], "looks delicious")
|
|
||||||
assert.Equal(t, fields["context"], "eating raw fish")
|
|
||||||
|
|
||||||
buffer.Reset()
|
|
||||||
|
|
||||||
llog.Warn("omg it is!")
|
|
||||||
|
|
||||||
err = json.Unmarshal(buffer.Bytes(), &fields)
|
|
||||||
assert.NoError(t, err, "should have decoded second message")
|
|
||||||
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
|
||||||
assert.Equal(t, fields["msg"], "omg it is!")
|
|
||||||
assert.Equal(t, fields["context"], "eating raw fish")
|
|
||||||
assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConvertLevelToString(t *testing.T) {
|
|
||||||
assert.Equal(t, "debug", DebugLevel.String())
|
|
||||||
assert.Equal(t, "info", InfoLevel.String())
|
|
||||||
assert.Equal(t, "warning", WarnLevel.String())
|
|
||||||
assert.Equal(t, "error", ErrorLevel.String())
|
|
||||||
assert.Equal(t, "fatal", FatalLevel.String())
|
|
||||||
assert.Equal(t, "panic", PanicLevel.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseLevel(t *testing.T) {
|
|
||||||
l, err := ParseLevel("panic")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, PanicLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("PANIC")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, PanicLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("fatal")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, FatalLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("FATAL")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, FatalLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("error")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, ErrorLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("ERROR")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, ErrorLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("warn")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, WarnLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("WARN")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, WarnLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("warning")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, WarnLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("WARNING")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, WarnLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("info")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, InfoLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("INFO")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, InfoLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("debug")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, DebugLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("DEBUG")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, DebugLevel, l)
|
|
||||||
|
|
||||||
l, err = ParseLevel("invalid")
|
|
||||||
assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetSetLevelRace(t *testing.T) {
|
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
wg.Add(1)
|
|
||||||
go func(i int) {
|
|
||||||
defer wg.Done()
|
|
||||||
if i%2 == 0 {
|
|
||||||
SetLevel(InfoLevel)
|
|
||||||
} else {
|
|
||||||
GetLevel()
|
|
||||||
}
|
|
||||||
}(i)
|
|
||||||
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLoggingRace(t *testing.T) {
|
|
||||||
logger := New()
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(100)
|
|
||||||
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
go func() {
|
|
||||||
logger.Info("info")
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile test
|
|
||||||
func TestLogrusInterface(t *testing.T) {
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
fn := func(l FieldLogger) {
|
|
||||||
b := l.WithField("key", "value")
|
|
||||||
b.Debug("Test")
|
|
||||||
}
|
|
||||||
// test logger
|
|
||||||
logger := New()
|
|
||||||
logger.Out = &buffer
|
|
||||||
fn(logger)
|
|
||||||
|
|
||||||
// test Entry
|
|
||||||
e := logger.WithField("another", "value")
|
|
||||||
fn(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements io.Writer using channels for synchronization, so we can wait on
|
|
||||||
// the Entry.Writer goroutine to write in a non-racey way. This does assume that
|
|
||||||
// there is a single call to Logger.Out for each message.
|
|
||||||
type channelWriter chan []byte
|
|
||||||
|
|
||||||
func (cw channelWriter) Write(p []byte) (int, error) {
|
|
||||||
cw <- p
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEntryWriter(t *testing.T) {
|
|
||||||
cw := channelWriter(make(chan []byte, 1))
|
|
||||||
log := New()
|
|
||||||
log.Out = cw
|
|
||||||
log.Formatter = new(JSONFormatter)
|
|
||||||
log.WithField("foo", "bar").WriterLevel(WarnLevel).Write([]byte("hello\n"))
|
|
||||||
|
|
||||||
bs := <-cw
|
|
||||||
var fields Fields
|
|
||||||
err := json.Unmarshal(bs, &fields)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, fields["foo"], "bar")
|
|
||||||
assert.Equal(t, fields["level"], "warning")
|
|
||||||
}
|
|
87
vendor/github.com/sirupsen/logrus/text_formatter_test.go
generated
vendored
87
vendor/github.com/sirupsen/logrus/text_formatter_test.go
generated
vendored
@ -1,87 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestQuoting(t *testing.T) {
|
|
||||||
tf := &TextFormatter{DisableColors: true}
|
|
||||||
|
|
||||||
checkQuoting := func(q bool, value interface{}) {
|
|
||||||
b, _ := tf.Format(WithField("test", value))
|
|
||||||
idx := bytes.Index(b, ([]byte)("test="))
|
|
||||||
cont := bytes.Contains(b[idx+5:], []byte(tf.QuoteCharacter))
|
|
||||||
if cont != q {
|
|
||||||
if q {
|
|
||||||
t.Errorf("quoting expected for: %#v", value)
|
|
||||||
} else {
|
|
||||||
t.Errorf("quoting not expected for: %#v", value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkQuoting(false, "")
|
|
||||||
checkQuoting(false, "abcd")
|
|
||||||
checkQuoting(false, "v1.0")
|
|
||||||
checkQuoting(false, "1234567890")
|
|
||||||
checkQuoting(true, "/foobar")
|
|
||||||
checkQuoting(true, "x y")
|
|
||||||
checkQuoting(true, "x,y")
|
|
||||||
checkQuoting(false, errors.New("invalid"))
|
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
|
||||||
|
|
||||||
// Test for custom quote character.
|
|
||||||
tf.QuoteCharacter = "`"
|
|
||||||
checkQuoting(false, "")
|
|
||||||
checkQuoting(false, "abcd")
|
|
||||||
checkQuoting(true, "/foobar")
|
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
|
||||||
|
|
||||||
// Test for multi-character quotes.
|
|
||||||
tf.QuoteCharacter = "§~±"
|
|
||||||
checkQuoting(false, "abcd")
|
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
|
||||||
|
|
||||||
// Test for quoting empty fields.
|
|
||||||
tf.QuoteEmptyFields = true
|
|
||||||
checkQuoting(true, "")
|
|
||||||
checkQuoting(false, "abcd")
|
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimestampFormat(t *testing.T) {
|
|
||||||
checkTimeStr := func(format string) {
|
|
||||||
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
|
|
||||||
customStr, _ := customFormatter.Format(WithField("test", "test"))
|
|
||||||
timeStart := bytes.Index(customStr, ([]byte)("time="))
|
|
||||||
timeEnd := bytes.Index(customStr, ([]byte)("level="))
|
|
||||||
timeStr := customStr[timeStart+5+len(customFormatter.QuoteCharacter) : timeEnd-1-len(customFormatter.QuoteCharacter)]
|
|
||||||
if format == "" {
|
|
||||||
format = time.RFC3339
|
|
||||||
}
|
|
||||||
_, e := time.Parse(format, (string)(timeStr))
|
|
||||||
if e != nil {
|
|
||||||
t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkTimeStr("2006-01-02T15:04:05.000000000Z07:00")
|
|
||||||
checkTimeStr("Mon Jan _2 15:04:05 2006")
|
|
||||||
checkTimeStr("")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDisableTimestampWithColoredOutput(t *testing.T) {
|
|
||||||
tf := &TextFormatter{DisableTimestamp: true, ForceColors: true}
|
|
||||||
|
|
||||||
b, _ := tf.Format(WithField("test", "test"))
|
|
||||||
if strings.Contains(string(b), "[0000]") {
|
|
||||||
t.Error("timestamp not expected when DisableTimestamp is true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO add tests for sorting etc., this requires a parser for the text
|
|
||||||
// formatter output.
|
|
@ -10,7 +10,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Microsoft/hcsshim"
|
"github.com/Microsoft/hcsshim"
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
eventsapi "github.com/containerd/containerd/api/services/events/v1"
|
eventsapi "github.com/containerd/containerd/api/services/events/v1"
|
||||||
containerdtypes "github.com/containerd/containerd/api/types"
|
containerdtypes "github.com/containerd/containerd/api/types"
|
||||||
@ -24,6 +23,7 @@ import (
|
|||||||
"github.com/containerd/containerd/windows/hcsshimopts"
|
"github.com/containerd/containerd/windows/hcsshimopts"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Microsoft/hcsshim"
|
"github.com/Microsoft/hcsshim"
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
eventsapi "github.com/containerd/containerd/api/services/events/v1"
|
eventsapi "github.com/containerd/containerd/api/services/events/v1"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/events"
|
"github.com/containerd/containerd/events"
|
||||||
@ -20,6 +19,7 @@ import (
|
|||||||
"github.com/gogo/protobuf/types"
|
"github.com/gogo/protobuf/types"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type task struct {
|
type task struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user