Commit 1bdf7b51 authored by Nick Rosbrook's avatar Nick Rosbrook
Browse files

redctld: create xenlightCtx to implement xen.Driver


Signed-off-by: default avatarNick Rosbrook <nr@enr0n.net>
parent 3842363d
Pipeline #253356391 failed with stages
in 54 seconds
......@@ -639,6 +639,54 @@ var (
},
}
vmPciAttachCmd = &cobra.Command{
Use: "attach",
Short: "Passthrough a PCI device",
Long: ``,
PreRun: func(cmd *cobra.Command, args []string) {
preRunFlagsFixup(cmd)
},
Run: func(cmd *cobra.Command, args []string) {
client, domain := initDomainOp()
defer client.Close()
address := viper.GetString("address")
if address == "" {
log.Fatal("PCI device address required")
}
pci := api.NewDomainPCIDevice(address)
if err := client.DomainHotplugPCIAttach(domain.Uuid, domain.Config.Name, pci); err != nil {
log.Fatalf("Failed to passthrough PCI device: %v", err)
}
},
}
vmPciDetachCmd = &cobra.Command{
Use: "detach",
Short: "Detach a PCI device",
Long: ``,
PreRun: func(cmd *cobra.Command, args []string) {
preRunFlagsFixup(cmd)
},
Run: func(cmd *cobra.Command, args []string) {
client, domain := initDomainOp()
defer client.Close()
address := viper.GetString("address")
if address == "" {
log.Fatal("PCI device address required")
}
pci := api.NewDomainPCIDevice(address)
if err := client.DomainHotplugPCIDetach(domain.Uuid, domain.Config.Name, pci); err != nil {
log.Fatalf("Failed to detach PCI device: %v", err)
}
},
}
vmPciGetCmd = &cobra.Command{
Use: "get-property",
Short: "Get key property-value",
......@@ -903,6 +951,16 @@ func init() {
vmPciAssignCmd.Flags().String("name", "", "vm name")
vmPciAssignCmd.Flags().String("address", "", "pci device address")
vmPciCmd.AddCommand(vmPciAttachCmd)
vmPciAttachCmd.Flags().String("uuid", "", "vm uuid")
vmPciAttachCmd.Flags().String("name", "", "vm name")
vmPciAttachCmd.Flags().String("address", "", "pci device address")
vmPciCmd.AddCommand(vmPciDetachCmd)
vmPciDetachCmd.Flags().String("uuid", "", "vm uuid")
vmPciDetachCmd.Flags().String("name", "", "vm name")
vmPciDetachCmd.Flags().String("address", "", "pci device address")
vmPciCmd.AddCommand(vmPciGetCmd)
vmPciGetCmd.Flags().String("uuid", "", "vm uuid")
vmPciGetCmd.Flags().String("name", "", "vm name")
......
......@@ -2,6 +2,7 @@ module gitlab.com/redfield/redctl
require (
github.com/Equanox/gotron v0.2.23
github.com/enr0n/xenlight v0.0.0-20200412173819-c21253ad19bb
github.com/ghodss/yaml v1.0.0 // indirect
github.com/gofrs/flock v0.7.1
github.com/golang/protobuf v1.3.0
......@@ -11,6 +12,7 @@ require (
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/nanobox-io/golang-scribble v0.0.0-20180621225840-336beac0a992
github.com/otiai10/curr v1.0.0 // indirect
github.com/pkg/errors v0.8.1
github.com/rs/xid v1.2.1
github.com/spf13/cobra v0.0.3
......
bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U=
bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Benchkram/errz v0.0.0-20180825145403-619d291cb54f h1:FRzI8csOWCO+a4dtjCk+C5lsb8t6UIStMT7ay+5rnxk=
......@@ -13,14 +14,16 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/enr0n/xenlight v0.0.0-20200411195453-e021bd9c3774 h1:ZgX+YBkxhkNd4CTB4Q/w85pNlU8N1krQ9WJaNCzyeQ8=
github.com/enr0n/xenlight v0.0.0-20200411195453-e021bd9c3774/go.mod h1:U1MZrY2Ug/8OOHMMvO/TbCc1nRzK6L84pBwiucAyB98=
github.com/enr0n/xenlight v0.0.0-20200412173516-5ac937a64bde h1:8PJ0dWxuq59ofJcKmjEmfhPpQSYRbdZUiHToKMMyXXs=
github.com/enr0n/xenlight v0.0.0-20200412173516-5ac937a64bde/go.mod h1:U1MZrY2Ug/8OOHMMvO/TbCc1nRzK6L84pBwiucAyB98=
github.com/enr0n/xenlight v0.0.0-20200412173819-c21253ad19bb h1:sydYBOfzXTMkgqGfoevztAbgNRb9QWYprNfK9DS40Z0=
github.com/enr0n/xenlight v0.0.0-20200412173819-c21253ad19bb/go.mod h1:U1MZrY2Ug/8OOHMMvO/TbCc1nRzK6L84pBwiucAyB98=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/gofrs/flock v0.7.0 h1:pGFUjl501gafK9HBt1VGL1KCOd/YhIooID+xgyJCf3g=
github.com/gofrs/flock v0.7.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
......@@ -30,8 +33,6 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/google/uuid v1.1.0 h1:Jf4mxPC/ziBnoPIdpQdPJ9OeiomAUHLvxmPRSPH9m4s=
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
......@@ -47,9 +48,10 @@ github.com/jaypipes/pcidb v0.0.0-20190216134740-adf5a9192458/go.mod h1:kPBABoOV7
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 h1:EFT6MH3igZK/dIVqgGbTqWVvkZ7wJ5iGN03SVtvvdd8=
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25/go.mod h1:sWkGw/wsaHtRsT9zGQ/WyJCotGWG/Anow/9hsAcBWRw=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
......@@ -61,7 +63,13 @@ github.com/nanobox-io/golang-scribble v0.0.0-20180621225840-336beac0a992 h1:zIRk
github.com/nanobox-io/golang-scribble v0.0.0-20180621225840-336beac0a992/go.mod h1:4Mct/lWCFf1jzQTTAaWtOI7sXqmG+wBeiBfT4CxoaJk=
github.com/otiai10/copy v1.0.1 h1:gtBjD8aq4nychvRZ2CyJvFWAw0aja+VHazDdruZKGZA=
github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.2.3 h1:PsrRBmrxR68kyNu6YlqYHbNlItc5vOkuS6LBEsNttVA=
github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw=
github.com/otiai10/mint v1.3.0 h1:Ady6MKVezQwHBkGzLFbrsywyp09Ah7rkmfjV3Bcr5uc=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
......@@ -99,33 +107,29 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006 h1:bfLnR+k0tq5Lqt6dflRLcZiz6UaXCMt3vhYJ1l4FQ80=
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.18.0 h1:IZl7mfBGfbhYx2p2rKRtYgDFw6SBz+kclmxYrCksPPA=
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
......@@ -70,8 +70,6 @@ func (s *server) DomainFindAll(ctx context.Context, in *api.DomainFindAllRequest
return nil, fmt.Errorf("failed to find all domains: %v", err)
}
log.Printf("findall domains: %+v\n", domains)
return &api.DomainFindAllReply{Domains: domains}, nil
}
......
......@@ -87,9 +87,13 @@ func Serve(opts RedctlServerOptions) error {
domainRepo := repository.NewScribbleDomainRepo(db)
imageRepo := repository.NewFilesystemImageRepo(opts.ImagesPath)
xenDriver := &xenDriver{}
graphicsRepo := repository.NewGraphicsRepo(opts.GraphicsPath)
xenDriver, err := newXenlightCtx()
if err != nil {
return errors.WithMessage(err, "failed to create xenlight context")
}
iconsDir := filepath.Join(opts.DataDir, "icons")
if err := graphicsRepo.ImportDirectory(iconsDir, api.GraphicType_GRAPHIC_DESKTOP_ICON); err != nil {
log.Printf("Failed to initialize graphics repo: %v", err)
......
package server
import (
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"log"
"net"
"strings"
"github.com/enr0n/xenlight"
"gitlab.com/redfield/redctl/api"
)
// xenlightCtx implements a xen.Driver with the
// use of a xenlight.Context.
type xenlightCtx struct {
*xenlight.Context
}
func newXenlightCtx() (*xenlightCtx, error) {
ctx, err := xenlight.NewContext()
if err != nil {
return nil, err
}
return &xenlightCtx{ctx}, nil
}
func (xctx *xenlightCtx) StartDomain(domain api.Domain) error {
// TODO
xd := xenDriver{}
return xd.StartDomain(domain)
}
func (xctx *xenlightCtx) StopDomain(domain api.Domain) error {
domid, err := xctx.NameToDomid(domain.Config.Name)
if err != nil {
return err
}
log.Printf("DEBUG: stopping domain %v", domid)
return xctx.DomainShutdown(domid)
}
func (xctx *xenlightCtx) DestroyDomain(domain api.Domain) error {
// XXX:
return xctx.StopDomain(domain)
}
func (xctx *xenlightCtx) RestartDomain(domain api.Domain) error {
domid, err := xctx.NameToDomid(domain.Config.Name)
if err != nil {
return err
}
log.Printf("DEBUG: restarting domain %v", domid)
return xctx.DomainReboot(domid)
}
func (xctx *xenlightCtx) IsDomainCreated(domain api.Domain) bool {
_, err := xctx.NameToDomid(domain.Config.Name)
return (err == nil)
}
func (xctx *xenlightCtx) NetworkAttach(domain api.Domain, network api.DomainNetwork) error {
domid, err := xctx.NameToDomid(domain.Config.Name)
if err != nil {
return err
}
nic, err := xenlight.NewDeviceNic()
if err != nil {
return err
}
mac, err := net.ParseMAC(network.Mac)
if err != nil {
return err
}
copy(nic.Mac[:], mac[:6])
nic.Bridge = network.Bridge
nic.BackendDomname = network.Backend
log.Printf("DEBUG: attaching nic to %v (mac=%s, bridge=%s, backend=%s)", domid, nic.Mac, nic.Bridge, nic.BackendDomname)
return xctx.DeviceNicAdd(domid, *nic)
}
func (xctx *xenlightCtx) NetworkDetach(domain api.Domain, network api.DomainNetwork) error {
domid, err := xctx.NameToDomid(domain.Config.Name)
if err != nil {
return err
}
nic, err := xenlight.NewDeviceNic()
if err != nil {
return err
}
mac, err := net.ParseMAC(network.Mac)
copy(nic.Mac[:], mac[:6])
log.Printf("DEBUG: detaching nic from %v (mac=%s)", domid, nic.Mac)
return xctx.DeviceNicRemove(domid, *nic)
}
// XXX: this is lazy and not well-tested
func parseBDF(s string) (*xenlight.DevicePci, error) {
pci, err := xenlight.NewDevicePci()
if err != nil {
return nil, err
}
s = strings.Replace(s, ":", "/", 2)
s = strings.Replace(s, ".", "/", 1)
split := strings.Split(s, "/")
if len(split) != 3 && len(split) != 4 {
return nil, errors.New("ill-formatted BDF")
}
bdf := make([]byte, len(split))
for i, v := range split {
if len(v) == 1 {
v = "0" + v
}
b, err := hex.DecodeString(v)
if err != nil {
return nil, err
}
if len(b) != 1 {
if i == 0 {
pci.Domain = int(binary.BigEndian.Uint16(b))
continue
}
return nil, fmt.Errorf("expected one byte, got %v", b)
}
bdf[i] = b[0]
}
pci.Bus = bdf[0]
pci.Dev = bdf[1]
pci.Func = bdf[2]
return pci, nil
}
func (xctx *xenlightCtx) PCIDeviceAttach(domain api.Domain, pci api.DomainPciDevice) error {
if pci.GetAddress() == "" {
return fmt.Errorf("pci device address is required")
}
domid, err := xctx.NameToDomid(domain.Config.Name)
if err != nil {
return err
}
pcidev, err := parseBDF(pci.Address)
if err != nil {
return err
}
log.Printf("DEBUG: attaching PCI device to %v", domid)
return xctx.DevicePciAdd(domid, *pcidev)
}
func (xctx *xenlightCtx) PCIDeviceDetach(domain api.Domain, pci api.DomainPciDevice) error {
if pci.GetAddress() == "" {
return fmt.Errorf("pci device address is required")
}
bdf := strings.Split(pci.Address, ":")
if len(bdf) != 3 {
return errors.New("unexpected format of BDF")
}
domid, err := xctx.NameToDomid(domain.Config.Name)
if err != nil {
return err
}
pcidev, err := parseBDF(pci.Address)
if err != nil {
return err
}
log.Printf("DEBUG: removing PCI device from %v", domid)
return xctx.DevicePciRemove(domid, *pcidev)
}
func (xctx *xenlightCtx) RunningDomainsByName() ([]string, error) {
doms := xctx.ListDomain()
names := make([]string, len(doms))
for i, dom := range doms {
names[i] = xctx.DomidToName(dom.Domid)
}
log.Printf("DEGBUG: running domains - %v", names)
return names, nil
}
# xenlight
Repo to publish xenlight package in a go-gettable fashion for testing convenience.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -15,8 +15,6 @@ type context struct {
chroot string
cacheOnly bool
cachePath string
path string
localOnly bool
searchPaths []string
}
......@@ -24,8 +22,6 @@ func contextFromOptions(merged *WithOption) *context {
ctx := &context{
chroot: *merged.Chroot,
cacheOnly: *merged.CacheOnly,
path: *merged.Path,
localOnly: *merged.LocalOnly,
cachePath: getCachePath(),
searchPaths: make([]string, 0),
}
......@@ -58,8 +54,6 @@ func (ctx *context) setSearchPaths() {
return
}
ctx.searchPaths = append(ctx.searchPaths, ctx.path)
rootPath := ctx.chroot
if runtime.GOOS != "windows" {
......
......@@ -9,7 +9,6 @@ package pcidb
import (
"bufio"
"compress/gzip"
"fmt"
"io"
"net/http"
"os"
......@@ -22,36 +21,26 @@ const (
func (db *PCIDB) load(ctx *context) error {
var foundPath string
var foundCompressedPath string
for _, fp := range ctx.searchPaths {
if _, err := os.Stat(fp); err == nil {
foundPath = fp
break
}
if _, err := os.Stat(fp + ".gz"); err == nil {
foundCompressedPath = fp
break
}
}
if foundPath == "" {
// OK, so we didn't find any host-local copy of the pci-ids DB file. If
// we found a local compressed copy, we'll use that. If not, we fetch the
// latest from the network.
if err := cacheDBFile(ctx.cachePath, foundCompressedPath, ctx.localOnly); err != nil {
// OK, so we didn't find any host-local copy of the pci-ids DB file. Let's
// try fetching it from the network and storing it
if err := cacheDBFile(ctx.cachePath); err != nil {
return err
}
foundPath = ctx.cachePath
}
f, err := os.Open(foundPath)
if err != nil {
return err
}
defer f.Close()
scanner := bufio.NewScanner(f)
return parseDBFile(db, scanner)
}
......@@ -68,26 +57,13 @@ func ensureDir(fp string) error {
// Pulls down the latest copy of the pci-ids file from the network and stores
// it in the local host filesystem
func cacheDBFile(cacheFilePath string, compressedFilePath string, localOnly bool) error {
func cacheDBFile(cacheFilePath string) error {
ensureDir(cacheFilePath)
var response *http.Response
var err error
if localOnly {
t := &http.Transport{}
t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
c := &http.Client{Transport: t}
if compressedFilePath == "" {
return fmt.Errorf("failed to locate compressed pci-ids.")
}
response, err = c.Get("file://" + compressedFilePath)
} else {
response, err = http.Get(PCIIDS_URI)
if err != nil {
return err
}
response, err := http.Get(PCIIDS_URI)
if err != nil {
return err
}
defer response.Body.Close()
f, err := os.Create(cacheFilePath)
if err != nil {
......
......@@ -9,13 +9,11 @@ package pcidb
import (
"fmt"
"os"
"path/filepath"
"strconv"
)
var (
cacheOnlyTrue = true
localOnlyTrue = true
)
// ProgrammingInterface is the PCI programming interface for a class of PCI
......@@ -89,11 +87,6 @@ type WithOption struct {
// looking for any non ~/.cache/pci.ids filepaths (which is useful when we
// want to test the fetch-from-network code paths
CacheOnly *bool
// Path provides a search path directly to find pci.ids or pci.ids
Path *string
// LocalOnly disables any fetch-from-network capability, for use in
// environments were it is undesirable
LocalOnly *bool
}
func WithChroot(dir string) *WithOption {
......@@ -104,14 +97,6 @@ func WithCacheOnly() *WithOption {
return &WithOption{CacheOnly: &cacheOnlyTrue}
}
func WithPath(path string) *WithOption {
return &WithOption{Path: &path}
}
func WithLocalOnly() *WithOption {
return &WithOption{LocalOnly: &localOnlyTrue}
}
func mergeOptions(opts ...*WithOption) *WithOption {
// Grab options from the environs by default
defaultChroot := "/"
......@@ -131,25 +116,6 @@ func mergeOptions(opts ...*WithOption) *WithOption {
defaultCacheOnly = parsed
}
}
defaultPath := filepath.Join(defaultChroot, "usr", "share", "hwdata", "pci.ids")
if val, exists := os.LookupEnv("PCIDB_PATH"); exists {
defaultChroot = "/"
defaultPath = val
}
defaultLocalOnly := false
if val, exists := os.LookupEnv("PCIDB_LOCAL_ONLY"); exists {