Skip to content
This repository has been archived by the owner on Sep 26, 2021. It is now read-only.

Upgrade the boot2docker.iso cache if possible when creating a VirtualBox machine #2298

Merged
merged 1 commit into from
Dec 18, 2015

Conversation

skatsuta
Copy link
Contributor

close #1790

This PR will

  • check the version of the local ISO cache and the latest release tag, then upgrade the ISO if possible when creating a VirtualBox machine from boot2docker.iso.
  • add many unit tests for B2dUtils's methods

Signed-off-by: Soshi Katsuta soshi.katsuta@gmail.com

@skatsuta skatsuta force-pushed the create-update-iso branch 2 times, most recently from a4d1b80 to 711e1c4 Compare November 15, 2015 06:46
@skatsuta skatsuta changed the title Upgrade an ISO cache if possible when creating a VirtualBox machine Upgrade the ISO cache if possible when creating a VirtualBox machine Nov 16, 2015
@skatsuta skatsuta changed the title Upgrade the ISO cache if possible when creating a VirtualBox machine Upgrade the boot2docker.iso cache if possible when creating a VirtualBox machine Nov 16, 2015
@dmp42
Copy link
Contributor

dmp42 commented Nov 16, 2015

cc @docker/machine-maintainers

@jeanlaurent
Copy link
Member

Could probably help #2248

@nathanleclaire
Copy link
Contributor

Very nice. Will review this soon.

@nathanleclaire nathanleclaire added this to the 0.5.2 milestone Nov 17, 2015
@nathanleclaire nathanleclaire self-assigned this Nov 17, 2015

// offset and length of ISO volume ID
// cf. http://serverfault.com/questions/361474/is-there-a-way-to-change-a-iso-files-volume-id-from-the-command-line
volumeIDOffset int64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just make these package-level const instead? They are unlikely to change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nathanleclaire Actually I did at first, but I added these fields for testing.
0x8028 is too big and I want to set the offset as a smaller value in testing.
Any idea for cooler way? Maybe interface here too?

@nathanleclaire
Copy link
Contributor

Instead of spinning up a whole server each time you need one, why not move the bits that you need to "mock" out into an embedded interface instead? I worry that spinning up fake API servers like that for each bit will become a big hairy mess to maintain, and also is more up the alley of "integration test" than "unit test".

}

// pathExists reports whether a file or directory specified by path exists.
func pathExists(path string) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For instance, this could become a method on an interface and embedded into the B2DUtils struct:

type PathChecker interface {
    PathExists(string) bool
}

type StatPathChecker struct {}

func (spc *StatPathChecker) PathExists(path string) bool {
    _, err := os.Stat(path)
    return os.IsNotExist(err)
}

type B2DUtils struct {
    StatPathChecker
    ...
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, GetLatestBoot2DockerReleaseURL and other methods that contact the GitHub API could be turned into interfaces and embedded:

type LatestReleaseGetter interface {
    GetLatestBoot2DockerReleaseURL(string) (string, error)
}

type GithubLatestReleaseGetter struct {}

func (g GithubLatestReleaseGetter) GetLatestBoot2DockerReleaseURL(url string) (string, error) {
    ....
}

type B2DUtils struct {
    LatestReleaseGetter
    ...
}

Then it could be mocked out in a struct for the tests:

type FakeLatestReleaseGetter struct {}

func (g FakeLatestReleaseGetter) GetLatestBoot2DockerReleaseURL(url string) (string, error) {
    return "v1.9.0", nil // or however you wish to configure the behavior
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nathanleclaire Useful sample code! Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... Current GetLatestBoot2DockerReleaseURL() heavily relies on B2dUtils.
If I delegate its implementation to GitHubLatestReleaseGetter, I have to rethink an implementation of LatestReleaseGetter interface...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, sounds like you're on exactly the right track. You notice that GetLatestBoot2DockerReleaseURL relies on getReleaseTag. So, you will actually have to make that method as an interface of LatestReleaseGetter with getReleaseTag method instead. This will enable you to embed it in the next interface up and mock that out completely in the bits which rely on it. It will require some jiggery-pokery due to all the passing of API URLs and so on that we're doing here, but doesn't have to be perfect on the first iteration.

@nathanleclaire
Copy link
Contributor

Have posted some feedback, mostly that I would prefer to use interfaces to test instead of spinning up whole web servers in the tests (we're long past due for implementing this). Looking pretty decent so far though 👍

@skatsuta
Copy link
Contributor Author

@nathanleclaire Thank you for your kind review!
I should rewrite them to use interfaces and mocks more.

@nathanleclaire
Copy link
Contributor

Good times. Make sure to ping us (@docker/machine-maintainers) when you've done some work in that direction.

@nathanleclaire
Copy link
Contributor

Any update on this @skatsuta ?

@nathanleclaire nathanleclaire modified the milestones: 0.5.3, 0.5.2 Nov 25, 2015
@skatsuta skatsuta force-pushed the create-update-iso branch 2 times, most recently from e636400 to a361636 Compare November 29, 2015 06:09
@skatsuta
Copy link
Contributor Author

@nathanleclaire Sorry for the late fix. Now I'm done. Please re-review it.

Changelog

  • define releaseGetter interface and B2dUtils holds b2dReleaseGetter that implements releaseGetter
  • define iso interface and B2dUtils holds b2dISO that implements iso
  • use mockReleaseGetter and mockISO in testing

@skatsuta skatsuta force-pushed the create-update-iso branch 2 times, most recently from e53b0d9 to 9e3af3c Compare November 29, 2015 06:46
@@ -0,0 +1,27 @@
#!/usr/bin/env bats

load ${BASE_TEST_DIR}/helpers.bash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not give this test file a more descriptive name? create.bats doesn't tell me much about what it's intended to test.

@skatsuta skatsuta force-pushed the create-update-iso branch 2 times, most recently from c068697 to bc15894 Compare December 2, 2015 02:25
@nathanleclaire
Copy link
Contributor

Reviewed this and everything looks solid. Even works without network access (defaults to the cached version). Great work @skatsuta.

LGTM

cc @docker/machine-maintainers

@nathanleclaire
Copy link
Contributor

We can follow-up after merge to rename the test file to something more specific.

@skatsuta
Copy link
Contributor Author

skatsuta commented Dec 3, 2015

Very sorry I seemed to make a mistake to merge and rebase the upstream.
I'll fix soon. Please wait to merge.

@skatsuta skatsuta force-pushed the create-update-iso branch 2 times, most recently from 6f3a746 to fa69652 Compare December 3, 2015 04:33
@skatsuta
Copy link
Contributor Author

skatsuta commented Dec 3, 2015

OK fixed and renamed create.bats to create-with-upgrading.bats.
You can change it to whatever more suitable.

@nathanleclaire
Copy link
Contributor

OK thanks @skatsuta. @dgageot @jeanlaurent please take a look at this when you get a chance.

@dgageot
Copy link
Member

dgageot commented Dec 7, 2015

Hi @skatsuta Each time I upgrade a VBox VM that has docker 1.9.1 installed, b2d 1.9.1 is downloaded again even if it is already in my cache folder. Isn't it unexpected?

$ file ~/.docker/machine/cache/boot2docker.iso
/Users/dgageot/.docker/machine/cache/boot2docker.iso: ISO 9660 CD-ROM filesystem data 'Boot2Docker-v1.9.1             ' (bootable)

$ /bin/docker-machine upgrade default
Detecting the provisioner...
Upgrading docker...
Downloading latest boot2docker iso...
Latest release for github.com/boot2docker/boot2docker is v1.9.1
Downloading https://github.com/boot2docker/boot2docker/releases/download/v1.9.1/boot2docker.iso to /Users/dgageot/.docker/machine/cache/boot2docker.iso...
0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
Stopping machine to do the upgrade...
(default) Stopping VM...
Upgrading machine "default"...
Latest Boot2Docker ISO found locally, copying it to /Users/dgageot/.docker/machine/machines/default/boot2docker.iso...
Starting machine back up...
(default) Starting VM...
Restarting docker...

@dgageot
Copy link
Member

dgageot commented Dec 7, 2015

Also, when the cache folder does not exist, the upgrade fails.

$ rm -Rf ~/.docker/machine/cache

$ ./bin/docker-machine upgrade default
Detecting the provisioner...
Upgrading docker...
Downloading latest boot2docker iso...
Latest release for github.com/boot2docker/boot2docker is v1.9.1
Downloading https://github.com/boot2docker/boot2docker/releases/download/v1.9.1/boot2docker.iso to /Users/dgageot/.docker/machine/cache/boot2docker.iso...

open /Users/dgageot/.docker/machine/cache/boot2docker.iso.tmp212374960: no such file or directory

@nathanleclaire
Copy link
Contributor

Nice catches @dgageot . @skatsuta do you have time to work on this? Or maybe one of us could take a look at it?

… latest one when it is out-of-date

Signed-off-by: Soshi Katsuta <soshi.katsuta@gmail.com>
@skatsuta
Copy link
Contributor Author

@nathanleclaire @dgageot
Thank you for your reviews and comments!
To fix @dgageot's issues I removed unnecessary explicit downloading process in Boot2DockerProvisioner#upgradeIso(). This solved the both problems.

@nathanleclaire
Copy link
Contributor

Thanks @skatsuta. This PR LGTM. @dgageot @jeanlaurent at your discretion whether you'd like to merge in for the 0.5.3 release. I'm in favor but don't feel like there's any hurry.

@dgageot dgageot modified the milestones: 0.5.3, 0.6.0 Dec 14, 2015
@nathanleclaire
Copy link
Contributor

@dgageot @jeanlaurent PTAL at this when you get a chance.

@dgageot
Copy link
Member

dgageot commented Dec 18, 2015

LGTM

dgageot added a commit that referenced this pull request Dec 18, 2015
Upgrade the boot2docker.iso cache if possible when creating a VirtualBox machine
@dgageot dgageot merged commit 0a74068 into docker:master Dec 18, 2015
@skatsuta skatsuta deleted the create-update-iso branch January 29, 2016 14:36
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

docker-machine create does not update ISO when a new version is available
6 participants