feature: remove uvtool dependency #6748

Merged
merged 15 commits into from Jan 5, 2017

Conversation

Projects
None yet
5 participants
Contributor

reedobrien commented Dec 22, 2016

follow up to #6580

@perrito666 @babbageclunk

This removes uvtool as a dependency, which should allow kvm containers to work on arm64, amd64, and ppc64el. QA has only been done by me on amd64 with vmaas.

NB: Since merging develop back into this branch there are some network updates that break kvm containers. When the rest of the network updates are complete and land it should be fine again. In order to test, once you have checked out the branch you will need to undo the changes so you can QA. Do that with git revert -m 1 37a1a3b87fc54dc7391b4027e385ac48722ddf42 --no-commit

QA:

  1. juju bootstrap vmaas21 kvm/purego --build-agent
  2. juju add-machine
  3. juju add-machine --series trusty
  4. juju deploy ubuntu --to kvm:0
  5. juju deploy mysql --to kvm:0
  6. juju deploy wordpress --to kvm:1
  7. juju deploy postgresql --to kvm:1 --series xenial
  8. juju add-relation wordpress mysql

verify that machines 0 and 1 came up with xenial and trusty respectively
verify that machines 0/kvm/0 cam up with xenial and 0/kvm/1 with trusty
verify that machine 1/kvm/0 came up with trusty and 1/kvm/1 with xenial
verify the relation was added...
why not create a wordpress blog to be sure.

  1. juju remove-application ubuntu
  2. juju remove-application postgresql

verify that the disk images for those are gone ,by juju ssh 0 (or 1) and look in /var/lib/juju/kvm/guests to be sure they were removed.

reedobrien added some commits Nov 2, 2016

Add simple streams content-download products fetch
feature: remove-uvtool-dependency
cloud-server image caching to local disk and tests
This updates the Sync method to fetch one image from simplestreams and
cache/update a local copy. This functionality was previously provided
by uvtool subclassing a mirorring library from the python simplestreams
package.

Refs: remove-uvtool-dependency
Add domainXML creation logic
Refs: remove-uvtool-dependency
Doc comment updates
Refs: remove-uvtool-dependency
Update kvm initialisation
 - Update dependencies
 - Create storage pool
 - Add internal initialisation test

Refs: remove-uvtool-dependency
rename cache sync
Refs: remove-uvtool-dependency
Rewire Updater to be a fetcher
Don't check for updates and fill the cache if they exist. Check if
we've already got an image for the provided arch and series. If so
exit, otherwise fetch it and create a qcow v3 backing file.

Refs: remove-uvtool-dependency
Address review comments on WIP
Refs: remove-uvtool-dependency
Update kvm to directly shell out in leiu of uvtool
- Add and update shell out commands and tests
- Refactor runFunc to runCmd and enable runAsLibirt
- This puts all the kvm bits behind build flags specific to linux and our
  supported architectures: amd64, arm64, and ppc64el.
- Make initialisation idempotent.
- Skip tests if not on supported os or arch.
- Fix cloud-init bits

Refs: remove-uvtool-dependency
Fix worker provisioner test
Refs: remove-uvtool-dependency
Updates per second review in #6580
Refs: remove-uvtool-dependency
Move chown after all the libvirt commands
Refs: remove-uvtool-dependency

@reedobrien reedobrien referenced this pull request Dec 22, 2016

Closed

WIP: remove uvtool dep #6580

Contributor

reedobrien commented Dec 22, 2016

!!BaronBomburst!!

@reedobrien reedobrien changed the base branch from staging to develop Dec 23, 2016

Contributor

reedobrien commented Dec 23, 2016

!!BaronessBomburst!!

Merge branch 'develop' into f/remove-uvtool-dependency
Very minor conflicts in imports and a modification to a removed file.

Also made updates to paths.DataDir call in container/kvm/sync.go and
container/kvm/wrappedcmds.go to use the new series.MustSeries call.
Contributor

reedobrien commented Dec 23, 2016

!!CaractacusPott!!

Contributor

reedobrien commented Dec 23, 2016

Note to self. see #6733

Failures to start kvm containers occurring after seeing
juju.provisioner failed to prepare container "2/kvm/0" network config: unable to find host bridge for spaces [] for container "2/kvm/0"

This started occurring after merging in develop to the feature branch. #6733 looks suspiciously related.

failing logs http://paste.ubuntu.com/23674094/
working logs http://paste.ubuntu.com/23674173/

cc/ @jameinel @frobware @voidspace

container/kvm/doc.go
+
+package kvm
+
+/*
@perrito666

perrito666 Dec 23, 2016

Contributor

some docs seem missing here :)

"github.com/juju/errors"
"github.com/juju/utils/packaging/manager"
"github.com/juju/utils/series"
"github.com/juju/juju/container"
+ "github.com/juju/juju/juju/paths"
)
var requiredPackages = []string{
@perrito666

perrito666 Dec 23, 2016

Contributor

my question is most likely way out of scope but ill make it anyway, how good is this when deploying to something other than ubuntu (say for instance CentOS)

@reedobrien

reedobrien Jan 4, 2017

Contributor

AFAIU this is only supported on trusty and xenial on arm64 amd64 and ppc64el. No Centos or other.

container/kvm/libvirt/domainxml.go
+// Details of the domain XML format are at: https://libvirt.org/formatdomain.html
+// We only use a subset, just enough to create instances in the pool. We don't
+// check any argument types here. We expect incoming params to be validate-able
+// by a function on the incoming domainParams. XXX: Or validate the params before being called.
@perrito666

perrito666 Dec 23, 2016

Contributor

XXX?

@reedobrien

reedobrien Jan 4, 2017

Contributor

removed. there's a method to validate them.

container/kvm/libvirt/domainxml.go
+}
+
+// InterfaceInfo is to allow callers to pass InterfaceInfo in domainParams.
+type InterfaceInfo interface {
@perrito666

perrito666 Dec 23, 2016

Contributor

perhaps doc string in theinterface?

@reedobrien

reedobrien Jan 4, 2017

Contributor

done

container/kvm/libvirt/domainxml.go
+ DeviceName() string
+}
+
+type domainParams interface {
@perrito666

perrito666 Dec 23, 2016

Contributor

same as with InterfaceInfo

@reedobrien

reedobrien Jan 4, 2017

Contributor

done.

container/kvm/package_test.go
}
gc.TestingT(t)
}
+
+func supportedArch() bool {
+ for _, arch := range []string{"amd64", "arm64", "ppc64el"} {
@perrito666

perrito666 Dec 23, 2016

Contributor

We have (I think) constants for these values, if we dont, lets have them.

@reedobrien

reedobrien Jan 4, 2017

Contributor

used.

container/kvm/run.go
+
+import "github.com/juju/utils"
+
+const libvirtUser = "libvirt-qemu"
@perrito666

perrito666 Dec 23, 2016

Contributor

I believe this is only the case for ubuntu? if so I would add a comment stating that.

@reedobrien

reedobrien Jan 4, 2017

Contributor

commented.

container/kvm/sync.go
+ "github.com/juju/juju/juju/paths"
+)
+
+const (
@perrito666

perrito666 Dec 23, 2016

Contributor

// blah
const blah

@reedobrien

reedobrien Jan 4, 2017

Contributor

FType is commented. Perhaps I'm misunderstanding.

@babbageclunk

babbageclunk Jan 4, 2017

Member

Maybe he's asking why the parens?

@perrito666

perrito666 Jan 4, 2017

Contributor

yes, I believe I was, just making a very unclear comment but I believe I meant: convert this to comment newline const declaration

container/kvm/sync.go
+
+// Oner is an interface which allows us to use sync params to call
+// imagedownloads.One or pass in a fake for testing.
+type Oner interface {
@perrito666

perrito666 Dec 23, 2016

Contributor

this is just a nit, this name is terrible for non english natives.

@reedobrien

reedobrien Jan 4, 2017

Contributor

Lo siento.

container/kvm/sync.go
+ One() (*imagedownloads.Metadata, error)
+}
+
+// SyncParams conveys the information necessary for calling imagedownloads.One.
@perrito666

perrito666 Dec 23, 2016

Contributor

s/Sync/sinc/

@reedobrien

reedobrien Jan 4, 2017

Contributor

lowered.

container/kvm/sync_internal_test.go
+ jc "github.com/juju/testing/checkers"
+)
+
+// cacheInternalSuite is gocheck boilerplate.
@perrito666

perrito666 Dec 23, 2016

Contributor

update the comment to reflect the struct

@reedobrien

reedobrien Jan 4, 2017

Contributor

updated. good catch.

environs/imagedownloads/doc.go
+// Copyright 2016 Canonical Ltd.
+// Licensed under the AGPLv3, see LICENCE file for details.
+
+package imagedownloads
@perrito666

perrito666 Dec 23, 2016

Contributor

I believe something went wrong here as you want the docs below and the Copyright above?

@reedobrien

reedobrien Jan 4, 2017

Contributor

fixed.

Contributor

reedobrien commented Dec 24, 2016

!!merryXmas!!

Owner

jameinel commented Dec 28, 2016

Small note, I'm @jameinel on Github, not jam, I'm not sure who that is. :)

For the failure case, my guess is there is something odd about what spaces your host machine is seen as being part of. The logic is supposed to be:

  1. If the container has a constraint "juju add-machine --constraints spaces=X,Y,Z", use it, or if the application has a binding "juju deploy app --bind X", use it.
  2. With no constraints/binding, if the host machine is in a single space, use it.
  3. The above looks like you had no constraints, and the host itself had no spaces. I'm not entirely sure how that would happen if you're using MAAS, and not using a manually provisioned machine.

I'd happily do a hangout with you to debug this, because I'm currently working on tweaking our logic and our fallback paths.

Contributor

reedobrien commented Dec 28, 2016

fixed nick. I'm happy to debug live, but that will most certainly be next Tues at the earliest :(

Contributor

reedobrien commented Jan 4, 2017

@jameinel @frobware FWIW if I back out #6733 it works again.

reedobrien added a commit to reedobrien/juju that referenced this pull request Jan 4, 2017

Address review feedback on #6748 and delint
Refs: remove-uvtool-dependency

Whew, this is a big chunk of work!
It mostly looks great, I have a few queries and suggestions. I started off commenting on typos but stopped after a while because it seemed too nitpicky.

@@ -19,6 +24,9 @@ type kvmContainer struct {
// this allows for checking when we don't know, but using a
// value if we already know it (like in the list situation).
started *bool
+
+ pathfinder func(string) (string, error)
@babbageclunk

babbageclunk Jan 4, 2017

Member

findPath would be more consistent with runCmd, wouldn't it?

@reedobrien

reedobrien Jan 4, 2017

Contributor

renamed. This started out as an internal package interface, but became just a function.

container/kvm/doc.go
+github.com/digitalocean/go-libvirt and github.com/digitalocean/go-qemu. Those
+packages are nascent and alpha at the time of this writing. They implement pure
+go interfaces to libvirt and qemu by way of libvirt/qemu's custom RPC protocol.
+While this would reduce the number of commnads that require shelling out, it
@babbageclunk

babbageclunk Jan 4, 2017

Member

Typo: commnads

@reedobrien

reedobrien Jan 4, 2017

Contributor

I don't think typos are too nitpicky. They are distracting when reading... fixed

+
+After the provisioner initializes the kvm environment, we synchronise (fetch if
+we don't have one) an ubuntu qcow image for the appropriate series and
+architecture. This happens in sync.go and uses Juju's simplestreams
@babbageclunk

babbageclunk Jan 4, 2017

Member

Is this dependency the reason this code lives inside juju/juju?

@reedobrien

reedobrien Jan 4, 2017

Contributor

I think I am having pronoun problems. Sync or fetching used to happen in uvtool and we shelled out to it. It depended on a python simplestreams impl. Juju already had some simplestreams parsing code for cloud images and tools (agents) streams. I added the bits for also handling content-download stream which is dependent on the existing simplestreams code. That is why the simplestreams code lives in juju/juju. The kvm code implements kvm as a juju container, so it is not useful outside juju/juju.

@babbageclunk

babbageclunk Jan 4, 2017

Member

Ok, makes sense.

container/kvm/doc.go
+we don't have one) an ubuntu qcow image for the appropriate series and
+architecture. This happens in sync.go and uses Juju's simplestreams
+implementation in juju/environs/simplestreams and juju/environs/imagedownloads.
+Once we fetch a compressed ubuntu image we then uncompress and conviert it for
@babbageclunk

babbageclunk Jan 4, 2017

Member

Typo: conviert

@reedobrien

reedobrien Jan 4, 2017

Contributor

fixed

container/kvm/doc.go
+
+Once the backing store is ready, we create a system disk and a datasource disk.
+The system disk is a sparse file with a maximum file size which uses the
+aforementioned backing store as it's base image. The data source disk is an iso
@babbageclunk

babbageclunk Jan 4, 2017

Member

Typo: "it's" should be "its" here.

@reedobrien

reedobrien Jan 4, 2017

Contributor

I should learn to type.

container/kvm/doc.go
+image with user-data and meta-data for cloud-init's NoCloud method to configure
+our system. The cloud init data is written in kvm.go, via a call to machinery
+in juju/cloudconfig/containerinit/container_userdata.go. Destruction of a
+container rmeoves the system and data source disk files, but leaves the backing
@babbageclunk

babbageclunk Jan 4, 2017

Member

Typo: rmeoves

@reedobrien

reedobrien Jan 4, 2017

Contributor

can you tell I was riding in a car? That's my excuse;)

container/kvm/doc.go
+image with user-data and meta-data for cloud-init's NoCloud method to configure
+our system. The cloud init data is written in kvm.go, via a call to machinery
+in juju/cloudconfig/containerinit/container_userdata.go. Destruction of a
+container rmeoves the system and data source disk files, but leaves the backing
@babbageclunk

babbageclunk Jan 4, 2017

Member

Is this a potential resource leak? Should there be some kind of refcount for the backing store?

@reedobrien

reedobrien Jan 4, 2017

Contributor

no. The backing store is a read only copy of the ubuntu image, which domains are based on.
So multiple domain drives use the same backing store which cannot change without breaking anything that uses it. qcow doesn't support updating the backing store like squashfs (lxd) AFAIU.

There is the possibility that you remove all the containers (kvm domains) that are using a backing store while it sticks around. However, in prior discussions we decided it was best to leave it so re-deploying an app to a kvm container on the same machine would consistently have the same backing store. So we left it. This also means that 2 different machines started at different times could have different backing store versions, e.g. 16.04.1 vs 16.04.2. There is discussion about getting this through the controller to alleviate that variation, but that is beyond the scope of this PR. Which is to simply replace the functionality of uvtool which worked this way. There is definitely room for improvement in the future.

@babbageclunk

babbageclunk Jan 4, 2017

Member

Right - if that's how uvtool was already working then this seems fine.

container/kvm/export_test.go
@@ -13,6 +18,41 @@ var (
TestStartParams = &startParams
)
+func MakeTestableCreateMachineParams(params *CreateMachineParams, pathfinder func(string) (string, error), runCmd runFunc) {
@babbageclunk

babbageclunk Jan 4, 2017

Member

From the name I'd expect this to return a new CreateMachineParams. Maybe call it MakeCreateMachineParamsTestable?

@reedobrien

reedobrien Jan 4, 2017

Contributor

renamed.

+ call = append(call, args...)
+ s.calls = append(s.calls, strings.Join(call, " "))
+ if s.err != nil {
+ return s.err.Error(), s.err
@babbageclunk

babbageclunk Jan 4, 2017

Member

Why return this info twice? Is this how the real Run function behaves?

@reedobrien

reedobrien Jan 4, 2017

Contributor

Exactly that. The run func was pre-existing, and seems based on the utils.RunCommand which returns combined output.

+ }
+
+ // Check if we've done this already.
+ poolInfo, err := poolInfo(run)
@babbageclunk

babbageclunk Jan 4, 2017

Member

Is this racy?

@reedobrien

reedobrien Jan 4, 2017

Contributor

I don't think so. The worker/provisioner.ContainerSetup.runInitialiser method calls Initialise() in a mutex. This allows it to be called more than once (idempotently) if there is an error after createPool. Let me know if you read otherwise.

@babbageclunk

babbageclunk Jan 4, 2017

Member

Makes sense.

+// createPool creates the libvirt storage pool directory. runCmd and chownFunc
+// are here for testing. runCmd so we can check the right shell out calls are
+// made, and chownFunc because we cannot chown unless we are root.
+func createPool(pathfinder func(string) (string, error), runCmd runFunc, chownFunc func(string) error) error {
@babbageclunk

babbageclunk Jan 4, 2017

Member

I feel like this would make more sense as a method of a type that had runCmd and chownFunc members. Then you wouldn't need to pass the functions down into definePool, buildPool, startPool &c. You could construct one for testing with the right test functions.

(Also why pass in the pathfinder func here? Could you just pass the string instead? Maybe there's some reason later.)

Something like:

type PoolCreator struct {
   runCmd runFunc
   chownFunc func(string) error
}

func (pc *PoolCreator) create(poolDir string) error {
    // ...
}

func (pc *PoolCreator) definePool(poolDir string) error {
}

// and so on
@reedobrien

reedobrien Jan 4, 2017

Contributor

I can see that and I think if this were ever going to be used outside of this file -- more or less package -- it would be worthwhile to refactor. As it is, it should never be used outside of here, so an unexported type with unexported methods just means a bunch more more constructors and test code. As it is I don't see a cost-benefit worth changing it, is that OK with you?

findPath nee pathfinder fakes paths.DataDir which takes a string arg and returns an error:(

Hopefully, one day soon digital ocean's libvirt and qemu libraries grow the functionality we need and this could all just go away:)

@babbageclunk

babbageclunk Jan 4, 2017

Member

Yeah, I'm ok with this since it's internal.

+ "pool-define-as",
+ poolName,
+ "dir",
+ "-", "-", "-", "-",
@babbageclunk

babbageclunk Jan 4, 2017

Member

Why are these needed? I can't understand it from reading the virsh help. Worth a comment at least.

@reedobrien

reedobrien Jan 4, 2017

Contributor

They are positional parameters for defining other non-directory pools: e.g. file, lvm, scsi, disk, NFS.

pool-define-as <name> <type> [source-host] [source-path] [source-dev] [source-name] <target>

I think you can now use --type --target to just name params, but trusty still has the above signature.

Comment added.

@babbageclunk

babbageclunk Jan 4, 2017

Member

Ah, I looked at the virsh help on xenial, that's probably why I couldn't see the other positional args.

+
+// chownToLibvirt changes ownership of the provided directory to
+// libvirt-qemu:kvm.
+func chownToLibvirt(dir string) error {
@babbageclunk

babbageclunk Jan 4, 2017

Member

This is the real chownFunc, right? Does it get unit tested? If you actually passed around a func(string, int, int) error you could test this as well.

@reedobrien

reedobrien Jan 4, 2017

Contributor

The function itself isn't, but we really can't. You cannot chown unless you're root. It is a couple of syscalls which work on linux. Abstracting them out to make them moar test-able would just make them more complex thereby much more bug prone, while the tests themselves would be rather contrived testing the abstraction not the function.

I also considered shelling out ("chown", libvirtUser, libvirtGroup, path`) but shelling out is also bad. So I though keeping it as simple as possible was the least of all evils.

@babbageclunk

babbageclunk Jan 4, 2017

Member

I mean, I'm ok with this not being tested, but in general it would be better to mock out the thing we can't call and pass the fake one in - it reduces the amount of code that only runs in CI.

container/kvm/initialisation.go
+
+// buildPool sets up libvirt internals for the guest pool.
+func buildPool(runCmd runFunc) error {
+ // This can run without errror if the pool isn't active.
@babbageclunk

babbageclunk Jan 4, 2017

Member

Typo: errror

@reedobrien

reedobrien Jan 4, 2017

Contributor

fixed.

container/kvm/kvm.go
@@ -26,20 +29,29 @@ import (
var (
logger = loggo.GetLogger("juju.container.kvm")
+ // KvmObjectFactory is the container factory for kvm containers.
@babbageclunk

babbageclunk Jan 4, 2017

Member

This comment feels a bit redundant. Is there more useful info that could go here? I guess you define it so that you can swap it out for testing?

@reedobrien

reedobrien Jan 4, 2017

Contributor

This is pre-existing code. Horatio asked for comments here. So I just added comments. I didn't actually get up into the container factory and container interface code that is used by the worker/provisioner/kvm-broker code. I mostly made changes that removed the need for uvtool but left the API untouched.

Modified the comment a smidge.

container/kvm/libvirt/domainxml.go
+// check any argument types here. We expect incoming params to be validate-able
+// by a function on the incoming domainParams.
+
+// DiskInfo is an interface to allow callers to pass DiskInfo in domainParams.
@babbageclunk

babbageclunk Jan 4, 2017

Member

This doc comment is a bit too focused on how we use the thing rather than what the thing is. How about "DiskInfo represents a KVM disk image."?

@reedobrien

reedobrien Jan 4, 2017

Contributor

changed DiskInfo represents the type and location of a libvirt pool image.

container/kvm/libvirt/domainxml.go
+ Driver() string
+}
+
+// InterfaceInfo is to allow callers to pass InterfaceInfo in domainParams.
@babbageclunk

babbageclunk Jan 4, 2017

Member

Same here - "InterfaceInfo represents a network interface for a KVM instance being created."? (These might be wrong in the details, but I think something like this would be more useful than what's here.)

@reedobrien

reedobrien Jan 4, 2017

Contributor

updated.

container/kvm/libvirt/domainxml.go
+ DiskInfo() []DiskInfo
+ // Host returns the host name.
+ Host() string
+ // NetworkInfo returns a slice of InterfaceInfo.
@babbageclunk

babbageclunk Jan 4, 2017

Member

"NetworkInfo contains the network interfaces to create in the domain."?

@reedobrien

reedobrien Jan 4, 2017

Contributor

changed

+ return fmt.Sprintf("vd%s", string('a'+i)), nil
+}
+
+// Domain describes a libvirt domain. A domain is an instance of an operating
@babbageclunk

babbageclunk Jan 4, 2017

Member

I like this.

@reedobrien

reedobrien Jan 4, 2017

Contributor

🥇

container/kvm/package_test.go
- if runtime.GOOS == "windows" {
- t.Skip("KVM is currently not supported on windows")
+ if runtime.GOOS != "linux" || !supportedArch() {
+ t.Skip("KVM is currently only supported on linux architecures amd64, arm64, and ppc64el")
@babbageclunk

babbageclunk Jan 4, 2017

Member

Typo: architecures

@reedobrien

reedobrien Jan 4, 2017

Contributor

fixed

container/kvm/sync.go
+ "github.com/juju/juju/juju/paths"
+)
+
+const (
@perrito666

perrito666 Dec 23, 2016

Contributor

// blah
const blah

@reedobrien

reedobrien Jan 4, 2017

Contributor

FType is commented. Perhaps I'm misunderstanding.

@babbageclunk

babbageclunk Jan 4, 2017

Member

Maybe he's asking why the parens?

@perrito666

perrito666 Jan 4, 2017

Contributor

yes, I believe I was, just making a very unclear comment but I believe I meant: convert this to comment newline const declaration

container/kvm/sync.go
+ FType = "disk1.img"
+)
+
+// Oner is an interface which allows us to use sync params to call
@babbageclunk

babbageclunk Jan 4, 2017

Member

What does it actually do? The description shouldn't really be in terms of the implementation - I don't know what imagedownloads.One does. Maybe say that it finds the first matching item to download?

@reedobrien

reedobrien Jan 4, 2017

Contributor

updated, "Oner gets the one matching item from simplestreams."

+// syncParams conveys the information necessary for calling imagedownloads.One.
+type syncParams struct {
+ arch, series, ftype string
+ srcFunc func() simplestreams.DataSource
@babbageclunk

babbageclunk Jan 4, 2017

Member

As mentioned below I think just passing in a DataSource rather than a func() DataSource for testing would make more sense.

@reedobrien

reedobrien Jan 4, 2017

Contributor

It is a func because we allow passing in a custom simplestreams url (if you make your own golden images/tools/whatever) and building a datasource from that. If the arg is empty then the default source is used. This was an early bit of work from the simplestreams implementation, so it isn't fresh in my head. I'll look at it after I get through the rest of the review.

+ }()
+
+ hash := sha256.New()
+ _, err := io.Copy(io.MultiWriter(i.tmpFile, hash), r)
@babbageclunk

babbageclunk Jan 4, 2017

Member

Ooh, I haven't seen io.MultiWriter before (or this way of calculating a hash). Neat!

@reedobrien

reedobrien Jan 4, 2017

Contributor

The inverse of a teereader.

container/kvm/sync.go
+
+ output, err := i.runCmd(
+ "qemu-img", "convert", "-f", "qcow2", tmpPath, i.FilePath)
+ fmt.Println(output)
@babbageclunk

babbageclunk Jan 4, 2017

Member

Is this intentional?

@reedobrien

reedobrien Jan 4, 2017

Contributor

😊 I usually format those with "XXX: %s\n"... so I can find all my crap to remove before I commit. I guess I missed it there. runCmd prints it anyhow:/

container/kvm/wrappedcmds.go
+ }
+
+ // We need to run some commands as root and some as libvirt. Alternatively,
+ // we could just run commands as root then change ownership as nessecary,
@babbageclunk

babbageclunk Jan 4, 2017

Member

Typo: nessecary

@reedobrien

reedobrien Jan 4, 2017

Contributor

fixed

container/kvm/wrappedcmds.go
+ )
+ // if there isn't a runCmd passed in, we're not testing so use real
+ // runFuncs.
+ if params.runCmd == nil {
@babbageclunk

babbageclunk Jan 4, 2017

Member

Having test-specific code in the middle of this function is a bit surprising - can you make it so the normal construction of the CreateMachineParams has the right values and the test constructs one with the test stubs so that this is cleaner?

@reedobrien

reedobrien Jan 5, 2017

Contributor

split default selection as discussed.

container/kvm/wrappedcmds.go
+ // for creating our guest.
+ templateDir := filepath.Dir(params.UserDataFile)
+
+ // Write out the meta-data to disk.
@babbageclunk

babbageclunk Jan 4, 2017

Member

This is a little redundant.

@reedobrien

reedobrien Jan 5, 2017

Contributor

gone

container/kvm/wrappedcmds.go
+ params.disks = append(params.disks, diskInfo{source: imgPath, driver: "qcow2"})
+ params.disks = append(params.disks, diskInfo{source: dsPath, driver: "raw"})
+
+ // Write out domain XML file.
@babbageclunk

babbageclunk Jan 4, 2017

Member

This is too.

@reedobrien

reedobrien Jan 5, 2017

Contributor

gone.

container/kvm/wrappedcmds.go
+ }
+ logger.Debugf("create domain: %s", out)
+
+ // Start the domain guest.
@babbageclunk

babbageclunk Jan 4, 2017

Member

The comments in here read as if they were a todo list while writing the function. I do that too, but in general those kind of comments should be deleted as you replace them with the code. At best they're just noise.

@reedobrien

reedobrien Jan 5, 2017

Contributor

Code is self documenting!
removed.

container/kvm/wrappedcmds.go
+ return err
+}
+
+// DestroyMachine destroys the virtual machine identified by hostname.
@babbageclunk

babbageclunk Jan 4, 2017

Member

What's hostname here?

@reedobrien

reedobrien Jan 5, 2017

Contributor

stale comment, updated.

container/kvm/wrappedcmds.go
+}
+
+// writeMetadata writes out a metadata file with an UUID instance-id. The
+// meta-data file is use din the data source image along with user-data nee
@babbageclunk

babbageclunk Jan 4, 2017

Member

Typo: use din

@reedobrien

reedobrien Jan 5, 2017

Contributor

fixed.

environs/imagedownloads/simplstreams.go
@@ -0,0 +1,251 @@
+// Copyright 2016 Canonical Ltd.
@babbageclunk

babbageclunk Jan 4, 2017

Member

Should the name of this file be simplestreams.go?

@reedobrien

reedobrien Jan 5, 2017

Contributor

yes.

environs/imagedownloads/simplstreams.go
+ for i, im := range items {
+ md[i] = im.(*Metadata)
+ }
+ // TODO(ro) 2016-11-04 Do we really need to sort here? If so what on? Other
@babbageclunk

babbageclunk Jan 4, 2017

Member

If nothing else deterministic output is probably nice for testing, although I guess you can get the same benefit by sorting in the test.

@reedobrien

reedobrien Jan 5, 2017

Contributor

Good thoughts. I'll just leave it as it isn't expensive.

environs/imagedownloads/simplstreams.go
+// One gets Metadata for one content download item -- the most recent of
+// 'series', for architecture, 'arch', of the format 'ftype'. 'src' exists to
+// pass in a data source for testing.
+func One(arch, release, ftype string, src func() simplestreams.DataSource) (*Metadata, error) {
@babbageclunk

babbageclunk Jan 4, 2017

Member

Why pass in a func() DataSource instead of just a DataSource here?

environs/imagedownloads/simplstreams.go
+// One gets Metadata for one content download item -- the most recent of
+// 'series', for architecture, 'arch', of the format 'ftype'. 'src' exists to
+// pass in a data source for testing.
+func One(arch, release, ftype string, src func() simplestreams.DataSource) (*Metadata, error) {
@babbageclunk

babbageclunk Jan 4, 2017

Member

Would FetchOne be a better name? One's pretty abstract.

@reedobrien

reedobrien Jan 5, 2017

Contributor

It doesn't really fetch anything it gets the metadata needed to fetch an item. However, Fetch is the name used in imagemetadata (tool/agent stream). So I copied it. In a preimplementation discussion we called the convenience method to get one metadata item One. So I named it one. It also fulfilled the Oner interface in kvm/sync.go. In my head I read it as imagedownloads.One, so it gets me one image download item from simplestreams. Familiarity permits brevity and all that.

Also, in sync there is a fetcher that fetches the one item, so I'd prefer not to confuse names there with FetchOne.

network/network.go
@@ -303,6 +303,21 @@ func (i *InterfaceInfo) CIDRAddress() string {
return ipNet.String()
}
+// MAC returns the MacAddress member value.
@babbageclunk

babbageclunk Jan 4, 2017

Member

Hmm, it's weird that you had to come up with slightly different names so that the accessors needed for the interface didn't collide with the public attributes. That suggests that this isn't the right thing.

Did you really need an interface for InterfaceInfo for testing? The structs in network are passive data structures and can be directly constructed, so I think it would make more sense to use them for testing. Is there some reason you can't?

@reedobrien

reedobrien Jan 5, 2017

Contributor

fixing per conversation

Contributor

reedobrien commented Jan 4, 2017

!!Iwouldliketobuyavowel!!

Contributor

perrito666 commented Jan 4, 2017

!!doitonemoretime!!

Contributor

reedobrien commented Jan 5, 2017

!!Iwouldliketospinthewheelalex!!

Contributor

reedobrien commented Jan 5, 2017

!!roullette!!

reedobrien added a commit to reedobrien/juju that referenced this pull request Jan 5, 2017

Contributor

reedobrien commented Jan 5, 2017

!!buildme!!

container/kvm/wrappedcmds.go
- runCmdAsRoot = params.runCmd
+ }
+ if params.runCmdAsRoot == nil {
+ params.runCmdAsRoot = run
@babbageclunk

babbageclunk Jan 5, 2017

Member

Thanks - I think I was just confused because of the way the defaulting was intertwined before.

Member

babbageclunk commented Jan 5, 2017

$$merge$$

Contributor

jujubot commented Jan 5, 2017

Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju

Contributor

jujubot commented Jan 5, 2017

Build failed: Tests failed
build url: http://juju-ci.vapour.ws:8080/job/github-merge-juju/9952

reedobrien added a commit to reedobrien/juju that referenced this pull request Jan 5, 2017

Squash of a few cleanup commits
- Make containerInitialiser patchable
    We now do more work in the KVM intialiser. So we patch it out here,
    and test that the machinery works to start the container where
    initialization works.
- Add some narrative pkg documentation.
- Tidying API and other general polish
- Address reviews on #6748

Refs: remove-uvtool-dependency
Contributor

reedobrien commented Jan 5, 2017

$$merge$$

Contributor

jujubot commented Jan 5, 2017

Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju

Contributor

jujubot commented Jan 5, 2017

Build failed: Tests failed
build url: http://juju-ci.vapour.ws:8080/job/github-merge-juju/9954

Squash of a few cleanup commits
- Make containerInitialiser patchable
    We now do more work in the KVM intialiser. So we patch it out here,
    and test that the machinery works to start the container where
    initialization works.
- Add some narrative pkg documentation.
- Tidying API and other general polish
- Change file name with colon for windows
- Address reviews on #6748

Refs: remove-uvtool-dependency
Contributor

reedobrien commented Jan 5, 2017

$$merge$$

Contributor

reedobrien commented Jan 5, 2017

!!build!!

Contributor

jujubot commented Jan 5, 2017

Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju

Contributor

jujubot commented Jan 5, 2017

Build failed: Tests failed
build url: http://juju-ci.vapour.ws:8080/job/github-merge-juju/9956

Remove build flags, just skip tests
Had used build flags to prevent builing on windows, but we apparently
build there and just skip tests. This seems like a good place to save
some time in test runs, but not as part of this work.

This removes the build tags except immediately surrounding the bits
that won't compile on windows.

Refs: remove-uvtool-dependency
Contributor

reedobrien commented Jan 5, 2017

!!reallybuild!!

Contributor

reedobrien commented Jan 5, 2017

$$ormerge$$

Contributor

jujubot commented Jan 5, 2017

Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju

Contributor

reedobrien commented Jan 5, 2017

$$isthereanybodyoutther$$

@jujubot jujubot merged commit b4b0632 into juju:develop Jan 5, 2017

1 check was pending

github-check-merge-juju Jenkins queued the run (Commit changed)
Details
Member

babbageclunk commented Jan 5, 2017

@reedobrien reedobrien deleted the reedobrien:f/remove-uvtool-dependency branch Jan 6, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment