Remove lmctfy driver in favor of the raw driver
This commit is contained in:
parent
4658d5c32a
commit
07b9ed3244
@ -1,59 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package lmctfy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"os/exec"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
)
|
||||
|
||||
func Register() error {
|
||||
if _, err := exec.LookPath("lmctfy"); err != nil {
|
||||
return errors.New("cannot find lmctfy")
|
||||
}
|
||||
log.Printf("Registering lmctfy factory")
|
||||
container.RegisterContainerHandlerFactory(&lmctfyFactory{})
|
||||
return nil
|
||||
}
|
||||
|
||||
type lmctfyFactory struct {
|
||||
}
|
||||
|
||||
func (self *lmctfyFactory) String() string {
|
||||
return "lmctfy"
|
||||
}
|
||||
|
||||
func (self *lmctfyFactory) NewContainerHandler(name string) (container.ContainerHandler, error) {
|
||||
c, err := New(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// XXX(dengnan): /user is created by ubuntu 14.04. Not sure if we should list it
|
||||
handler := container.NewBlackListFilter(c, "/user")
|
||||
return handler, nil
|
||||
}
|
||||
|
||||
func (self *lmctfyFactory) CanHandle(name string) bool {
|
||||
cmd := exec.Command(lmctfyBinary, "stats", "summary", name)
|
||||
_, err := cmd.Output()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,199 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// A container object
|
||||
|
||||
package lmctfy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"code.google.com/p/goprotobuf/proto"
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/info"
|
||||
)
|
||||
|
||||
type lmctfyContainerHandler struct {
|
||||
// Container name
|
||||
Name string
|
||||
}
|
||||
|
||||
const (
|
||||
lmctfyBinary = "lmctfy"
|
||||
notFoundExitCode = 5
|
||||
)
|
||||
|
||||
// Create a new
|
||||
func New(name string) (container.ContainerHandler, error) {
|
||||
el := &lmctfyContainerHandler{
|
||||
Name: name,
|
||||
}
|
||||
return el, nil
|
||||
}
|
||||
|
||||
func (self *lmctfyContainerHandler) ContainerReference() (info.ContainerReference, error) {
|
||||
return info.ContainerReference{Name: self.Name}, nil
|
||||
}
|
||||
|
||||
func getExitCode(err error) int {
|
||||
msg, ok := err.(*exec.ExitError)
|
||||
if ok {
|
||||
return msg.Sys().(syscall.WaitStatus).ExitStatus()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func protobufToContainerSpec(pspec *ContainerSpec) *info.ContainerSpec {
|
||||
ret := new(info.ContainerSpec)
|
||||
if pspec.GetCpu() != nil {
|
||||
cpuspec := new(info.CpuSpec)
|
||||
cpuspec.Limit = pspec.GetCpu().GetLimit()
|
||||
cpuspec.MaxLimit = pspec.GetCpu().GetMaxLimit()
|
||||
if pspec.GetCpu().GetMask() != nil {
|
||||
cpuspec.Mask.Data = pspec.GetCpu().GetMask().GetData()
|
||||
}
|
||||
ret.Cpu = cpuspec
|
||||
}
|
||||
if pspec.GetMemory() != nil {
|
||||
pmem := pspec.GetMemory()
|
||||
memspec := new(info.MemorySpec)
|
||||
memspec.Limit = uint64(pmem.GetLimit())
|
||||
memspec.Reservation = uint64(pmem.GetReservation())
|
||||
memspec.SwapLimit = uint64(pmem.GetSwapLimit())
|
||||
ret.Memory = memspec
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Gets spec.
|
||||
func (c *lmctfyContainerHandler) GetSpec() (*info.ContainerSpec, error) {
|
||||
// Run lmctfy spec "container_name" and get spec.
|
||||
// Ignore if the container was not found.
|
||||
cmd := exec.Command(lmctfyBinary, "spec", string(c.Name))
|
||||
data, err := cmd.Output()
|
||||
if err != nil && getExitCode(err) != notFoundExitCode {
|
||||
return nil, fmt.Errorf("unable to run command %v spec %v: %v", lmctfyBinary, c.Name, err)
|
||||
}
|
||||
|
||||
// Parse output into a protobuf.
|
||||
pspec := &ContainerSpec{}
|
||||
err = proto.UnmarshalText(string(data), pspec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
spec := protobufToContainerSpec(pspec)
|
||||
return spec, nil
|
||||
}
|
||||
|
||||
func protobufToMemoryData(pmd *MemoryStats_MemoryData, data *info.MemoryStatsMemoryData) {
|
||||
if pmd == nil {
|
||||
return
|
||||
}
|
||||
data.Pgfault = uint64(pmd.GetPgfault())
|
||||
data.Pgmajfault = uint64(pmd.GetPgmajfault())
|
||||
return
|
||||
}
|
||||
|
||||
func protobufToContainerStats(pstats *ContainerStats) *info.ContainerStats {
|
||||
ret := new(info.ContainerStats)
|
||||
if pstats.GetCpu() != nil {
|
||||
pcpu := pstats.GetCpu()
|
||||
cpustats := new(info.CpuStats)
|
||||
cpustats.Usage.Total = pcpu.GetUsage().GetTotal()
|
||||
percpu := pcpu.GetUsage().GetPerCpu()
|
||||
if len(percpu) > 0 {
|
||||
cpustats.Usage.PerCpu = make([]uint64, len(percpu))
|
||||
for i, p := range percpu {
|
||||
cpustats.Usage.PerCpu[i] = uint64(p)
|
||||
}
|
||||
}
|
||||
cpustats.Usage.User = uint64(pcpu.GetUsage().GetUser())
|
||||
cpustats.Usage.System = uint64(pcpu.GetUsage().GetSystem())
|
||||
cpustats.Load = pcpu.GetLoad()
|
||||
ret.Cpu = cpustats
|
||||
}
|
||||
if pstats.GetMemory() != nil {
|
||||
pmem := pstats.GetMemory()
|
||||
memstats := new(info.MemoryStats)
|
||||
memstats.Limit = uint64(pmem.GetLimit())
|
||||
memstats.Usage = uint64(pmem.GetUsage())
|
||||
protobufToMemoryData(pmem.GetContainerData(), &memstats.ContainerData)
|
||||
protobufToMemoryData(pmem.GetHierarchicalData(), &memstats.HierarchicalData)
|
||||
ret.Memory = memstats
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Gets full stats.
|
||||
func (c *lmctfyContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||
// Ignore if the container was not found.
|
||||
cmd := exec.Command(lmctfyBinary, "stats", "full", string(c.Name))
|
||||
data, err := cmd.Output()
|
||||
if err != nil && getExitCode(err) != notFoundExitCode {
|
||||
return nil, fmt.Errorf("unable to run command %v stats full %v: %v", lmctfyBinary, c.Name, err)
|
||||
}
|
||||
|
||||
// Parse output into a protobuf.
|
||||
pstats := &ContainerStats{}
|
||||
err = proto.UnmarshalText(string(data), pstats)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stats := protobufToContainerStats(pstats)
|
||||
stats.Timestamp = time.Now()
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// Gets all subcontainers.
|
||||
func (c *lmctfyContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {
|
||||
// Prepare the arguments.
|
||||
args := []string{"list", "containers", "-v"}
|
||||
if listType == container.LIST_RECURSIVE {
|
||||
args = append(args, "-r")
|
||||
}
|
||||
args = append(args, c.Name)
|
||||
|
||||
// Run the command.
|
||||
cmd := exec.Command(lmctfyBinary, args...)
|
||||
data, err := cmd.Output()
|
||||
if err != nil && getExitCode(err) != notFoundExitCode {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Parse lines as container names.
|
||||
if len(data) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
names := strings.Split(string(data), "\n")
|
||||
containerNames := make([]info.ContainerReference, 0, len(names))
|
||||
for _, name := range names {
|
||||
if len(name) != 0 {
|
||||
ref := info.ContainerReference{Name: name}
|
||||
containerNames = append(containerNames, ref)
|
||||
}
|
||||
}
|
||||
return containerNames, nil
|
||||
}
|
||||
|
||||
// TODO(vmarmol): Implement
|
||||
func (c *lmctfyContainerHandler) ListThreads(listType container.ListType) ([]int, error) {
|
||||
return []int{}, nil
|
||||
}
|
||||
func (c *lmctfyContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {
|
||||
return []int{}, nil
|
||||
}
|
@ -1,273 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go.
|
||||
// source: virtual_host.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
package lmctfy
|
||||
|
||||
import proto "code.google.com/p/goprotobuf/proto"
|
||||
import json "encoding/json"
|
||||
import math "math"
|
||||
|
||||
// Reference proto, json, and math imports to suppress error if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = &json.SyntaxError{}
|
||||
var _ = math.Inf
|
||||
|
||||
type Network_Bridge_Type int32
|
||||
|
||||
const (
|
||||
Network_Bridge_ETH Network_Bridge_Type = 0
|
||||
Network_Bridge_OVS Network_Bridge_Type = 1
|
||||
)
|
||||
|
||||
var Network_Bridge_Type_name = map[int32]string{
|
||||
0: "ETH",
|
||||
1: "OVS",
|
||||
}
|
||||
var Network_Bridge_Type_value = map[string]int32{
|
||||
"ETH": 0,
|
||||
"OVS": 1,
|
||||
}
|
||||
|
||||
func (x Network_Bridge_Type) Enum() *Network_Bridge_Type {
|
||||
p := new(Network_Bridge_Type)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x Network_Bridge_Type) String() string {
|
||||
return proto.EnumName(Network_Bridge_Type_name, int32(x))
|
||||
}
|
||||
func (x *Network_Bridge_Type) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(Network_Bridge_Type_value, data, "Network_Bridge_Type")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = Network_Bridge_Type(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
Interface *string `protobuf:"bytes,1,opt,name=interface" json:"interface,omitempty"`
|
||||
Connection *Network_Connection `protobuf:"bytes,3,opt,name=connection" json:"connection,omitempty"`
|
||||
VirtualIp *Network_VirtualIp `protobuf:"bytes,2,opt,name=virtual_ip" json:"virtual_ip,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Network) Reset() { *m = Network{} }
|
||||
func (m *Network) String() string { return proto.CompactTextString(m) }
|
||||
func (*Network) ProtoMessage() {}
|
||||
|
||||
func (m *Network) GetInterface() string {
|
||||
if m != nil && m.Interface != nil {
|
||||
return *m.Interface
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Network) GetConnection() *Network_Connection {
|
||||
if m != nil {
|
||||
return m.Connection
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Network) GetVirtualIp() *Network_VirtualIp {
|
||||
if m != nil {
|
||||
return m.VirtualIp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Network_VethPair struct {
|
||||
Outside *string `protobuf:"bytes,1,opt,name=outside" json:"outside,omitempty"`
|
||||
Inside *string `protobuf:"bytes,2,opt,name=inside" json:"inside,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Network_VethPair) Reset() { *m = Network_VethPair{} }
|
||||
func (m *Network_VethPair) String() string { return proto.CompactTextString(m) }
|
||||
func (*Network_VethPair) ProtoMessage() {}
|
||||
|
||||
func (m *Network_VethPair) GetOutside() string {
|
||||
if m != nil && m.Outside != nil {
|
||||
return *m.Outside
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Network_VethPair) GetInside() string {
|
||||
if m != nil && m.Inside != nil {
|
||||
return *m.Inside
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Network_Bridge struct {
|
||||
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
Type *Network_Bridge_Type `protobuf:"varint,2,opt,name=type,enum=containers.Network_Bridge_Type" json:"type,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Network_Bridge) Reset() { *m = Network_Bridge{} }
|
||||
func (m *Network_Bridge) String() string { return proto.CompactTextString(m) }
|
||||
func (*Network_Bridge) ProtoMessage() {}
|
||||
|
||||
func (m *Network_Bridge) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
return *m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Network_Bridge) GetType() Network_Bridge_Type {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Network_Bridge_ETH
|
||||
}
|
||||
|
||||
type Network_Connection struct {
|
||||
VethPair *Network_VethPair `protobuf:"bytes,1,opt,name=veth_pair" json:"veth_pair,omitempty"`
|
||||
Bridge *Network_Bridge `protobuf:"bytes,2,opt,name=bridge" json:"bridge,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Network_Connection) Reset() { *m = Network_Connection{} }
|
||||
func (m *Network_Connection) String() string { return proto.CompactTextString(m) }
|
||||
func (*Network_Connection) ProtoMessage() {}
|
||||
|
||||
func (m *Network_Connection) GetVethPair() *Network_VethPair {
|
||||
if m != nil {
|
||||
return m.VethPair
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Network_Connection) GetBridge() *Network_Bridge {
|
||||
if m != nil {
|
||||
return m.Bridge
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Network_VirtualIp struct {
|
||||
Ip *string `protobuf:"bytes,1,opt,name=ip" json:"ip,omitempty"`
|
||||
Netmask *string `protobuf:"bytes,2,opt,name=netmask" json:"netmask,omitempty"`
|
||||
Gateway *string `protobuf:"bytes,3,opt,name=gateway" json:"gateway,omitempty"`
|
||||
Mtu *int32 `protobuf:"varint,4,opt,name=mtu" json:"mtu,omitempty"`
|
||||
IpForward *bool `protobuf:"varint,5,opt,name=ip_forward" json:"ip_forward,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Network_VirtualIp) Reset() { *m = Network_VirtualIp{} }
|
||||
func (m *Network_VirtualIp) String() string { return proto.CompactTextString(m) }
|
||||
func (*Network_VirtualIp) ProtoMessage() {}
|
||||
|
||||
func (m *Network_VirtualIp) GetIp() string {
|
||||
if m != nil && m.Ip != nil {
|
||||
return *m.Ip
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Network_VirtualIp) GetNetmask() string {
|
||||
if m != nil && m.Netmask != nil {
|
||||
return *m.Netmask
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Network_VirtualIp) GetGateway() string {
|
||||
if m != nil && m.Gateway != nil {
|
||||
return *m.Gateway
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Network_VirtualIp) GetMtu() int32 {
|
||||
if m != nil && m.Mtu != nil {
|
||||
return *m.Mtu
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Network_VirtualIp) GetIpForward() bool {
|
||||
if m != nil && m.IpForward != nil {
|
||||
return *m.IpForward
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type Mounts struct {
|
||||
Mount []*Mounts_Mount `protobuf:"bytes,1,rep,name=mount" json:"mount,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Mounts) Reset() { *m = Mounts{} }
|
||||
func (m *Mounts) String() string { return proto.CompactTextString(m) }
|
||||
func (*Mounts) ProtoMessage() {}
|
||||
|
||||
func (m *Mounts) GetMount() []*Mounts_Mount {
|
||||
if m != nil {
|
||||
return m.Mount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Mounts_Mount struct {
|
||||
Source *string `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
|
||||
Target *string `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"`
|
||||
ReadOnly *bool `protobuf:"varint,3,opt,name=read_only" json:"read_only,omitempty"`
|
||||
Private *bool `protobuf:"varint,4,opt,name=private" json:"private,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Mounts_Mount) Reset() { *m = Mounts_Mount{} }
|
||||
func (m *Mounts_Mount) String() string { return proto.CompactTextString(m) }
|
||||
func (*Mounts_Mount) ProtoMessage() {}
|
||||
|
||||
func (m *Mounts_Mount) GetSource() string {
|
||||
if m != nil && m.Source != nil {
|
||||
return *m.Source
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Mounts_Mount) GetTarget() string {
|
||||
if m != nil && m.Target != nil {
|
||||
return *m.Target
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Mounts_Mount) GetReadOnly() bool {
|
||||
if m != nil && m.ReadOnly != nil {
|
||||
return *m.ReadOnly
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Mounts_Mount) GetPrivate() bool {
|
||||
if m != nil && m.Private != nil {
|
||||
return *m.Private
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("containers.Network_Bridge_Type", Network_Bridge_Type_name, Network_Bridge_Type_value)
|
||||
}
|
@ -3,8 +3,7 @@ MAINTAINER dengnan@google.com vmarmol@google.com
|
||||
|
||||
# NOTE: Run prepare.sh before building this Docker image.
|
||||
|
||||
# Grab lmctfy and cadvisor from the staging directory.
|
||||
ADD lmctfy /usr/bin/lmctfy
|
||||
# Grab cadvisor from the staging directory.
|
||||
ADD cadvisor /usr/bin/cadvisor
|
||||
|
||||
EXPOSE 8080
|
||||
|
@ -3,9 +3,5 @@
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Download lmctfy.
|
||||
wget http://storage.googleapis.com/cadvisor-bin/lmctfy/lmctfy
|
||||
chmod +x lmctfy
|
||||
|
||||
# Statically build cAdvisor from source and stage it.
|
||||
go build --ldflags '-extldflags "-static"' github.com/google/cadvisor
|
||||
|
Loading…
Reference in New Issue
Block a user