Remove lmctfy driver in favor of the raw driver

This commit is contained in:
Victor Marmol 2014-07-22 14:09:42 -07:00
parent 4658d5c32a
commit 07b9ed3244
6 changed files with 1 additions and 2640 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -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