Skip to content

Commit

Permalink
Merge 2.2 tip into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
wallyworld committed Aug 10, 2017
2 parents 3e79b63 + 4e9636a commit 14851f1
Show file tree
Hide file tree
Showing 66 changed files with 1,517 additions and 569 deletions.
35 changes: 35 additions & 0 deletions api/action/pruner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2017 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package action

import (
"time"

"github.com/juju/juju/api/base"
"github.com/juju/juju/api/common"
"github.com/juju/juju/apiserver/params"
)

const apiName = "ActionPruner"

// Facade allows calls to "ActionPruner" endpoints
type Facade struct {
facade base.FacadeCaller
*common.ModelWatcher
}

// NewFacade builds a facade for the action pruner endpoints
func NewFacade(caller base.APICaller) *Facade {
facadeCaller := base.NewFacadeCaller(caller, apiName)
return &Facade{facade: facadeCaller, ModelWatcher: common.NewModelWatcher(facadeCaller)}
}

// Prunes action entries by specified age and size
func (s *Facade) Prune(maxHistoryTime time.Duration, maxHistoryMB int) error {
p := params.ActionPruneArgs{
MaxHistoryTime: maxHistoryTime,
MaxHistoryMB: maxHistoryMB,
}
return s.facade.FacadeCall("Prune", p, nil)
}
1 change: 1 addition & 0 deletions api/facadeversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package api
// Facades that existed before versioning start at 0.
var facadeVersions = map[string]int{
"Action": 2,
"ActionPruner": 1,
"Agent": 2,
"AgentTools": 1,
"AllModelWatcher": 2,
Expand Down
2 changes: 2 additions & 0 deletions apiserver/allfacades.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import (
"github.com/juju/juju/apiserver/facades/client/storage"
"github.com/juju/juju/apiserver/facades/client/subnets"
"github.com/juju/juju/apiserver/facades/client/usermanager"
"github.com/juju/juju/apiserver/facades/controller/actionpruner"
"github.com/juju/juju/apiserver/facades/controller/agenttools"
"github.com/juju/juju/apiserver/facades/controller/applicationscaler"
"github.com/juju/juju/apiserver/facades/controller/charmrevisionupdater"
Expand Down Expand Up @@ -114,6 +115,7 @@ func AllFacades() *facade.Registry {
}

reg("Action", 2, action.NewActionAPI)
reg("ActionPruner", 1, actionpruner.NewAPI)
reg("Agent", 2, agent.NewAgentAPIV2)
reg("AgentTools", 1, agenttools.NewFacade)
reg("Annotations", 2, annotations.NewAPI)
Expand Down
33 changes: 33 additions & 0 deletions apiserver/facades/controller/actionpruner/pruner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2017 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package actionpruner

import (
"github.com/juju/juju/apiserver/common"
"github.com/juju/juju/apiserver/facade"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/state"
)

type API struct {
*common.ModelWatcher
st *state.State
authorizer facade.Authorizer
}

func NewAPI(st *state.State, r facade.Resources, auth facade.Authorizer) (*API, error) {
return &API{
ModelWatcher: common.NewModelWatcher(st, r, auth),
st: st,
authorizer: auth,
}, nil
}

func (api *API) Prune(p params.ActionPruneArgs) error {
if !api.authorizer.AuthController() {
return common.ErrPerm
}

return state.PruneActions(api.st, p.MaxHistoryTime, p.MaxHistoryMB)
}
5 changes: 5 additions & 0 deletions apiserver/params/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,8 @@ type ActionSpec struct {
Description string `json:"description"`
Params map[string]interface{} `json:"params"`
}

type ActionPruneArgs struct {
MaxHistoryTime time.Duration `json:"max-history-time"`
MaxHistoryMB int `json:"max-history-mb"`
}
73 changes: 54 additions & 19 deletions cloudconfig/containerinit/container_userdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ func GenerateNetworkConfig(networkConfig *container.NetworkConfig) (string, erro
prepared := PrepareNetworkConfigFromInterfaces(networkConfig.Interfaces)

var output bytes.Buffer
gatewayHandled := false
gateway4Handled := false
gateway6Handled := false
hasV4Interface := false
hasV6Interface := false
for _, name := range prepared.InterfaceNames {
output.WriteString("\n")
if name == "lo" {
Expand Down Expand Up @@ -103,22 +106,41 @@ func GenerateNetworkConfig(networkConfig *container.NetworkConfig) (string, erro
output.WriteString("iface " + name + " inet dhcp\n")
// We're expecting to get a default gateway
// from the DHCP lease.
gatewayHandled = true
gateway4Handled = true
continue
}

output.WriteString("iface " + name + " inet static\n")
_, network, err := net.ParseCIDR(address)
if err != nil {
return "", errors.Annotatef(err, "invalid address for interface %q: %q", name, address)
}

isIpv4 := network.IP.To4() != nil

if isIpv4 {
output.WriteString("iface " + name + " inet static\n")
hasV4Interface = true
} else {
output.WriteString("iface " + name + " inet6 static\n")
hasV6Interface = true
}
output.WriteString(" address " + address + "\n")
if !gatewayHandled && prepared.GatewayAddress != "" {
_, network, err := net.ParseCIDR(address)
if err != nil {
return "", errors.Annotatef(err, "invalid gateway for interface %q with address %q", name, address)
}

gatewayIP := net.ParseIP(prepared.GatewayAddress)
if network.Contains(gatewayIP) {
output.WriteString(" gateway " + prepared.GatewayAddress + "\n")
gatewayHandled = true // write it only once
if isIpv4 {
if !gateway4Handled && prepared.Gateway4Address != "" {
gatewayIP := net.ParseIP(prepared.Gateway4Address)
if network.Contains(gatewayIP) {
output.WriteString(" gateway " + prepared.Gateway4Address + "\n")
gateway4Handled = true // write it only once
}
}
} else {
if !gateway6Handled && prepared.Gateway6Address != "" {
gatewayIP := net.ParseIP(prepared.Gateway6Address)
if network.Contains(gatewayIP) {
output.WriteString(" gateway " + prepared.Gateway6Address + "\n")
gateway4Handled = true // write it only once
}
}
}

Expand All @@ -137,8 +159,12 @@ func GenerateNetworkConfig(networkConfig *container.NetworkConfig) (string, erro
generatedConfig := output.String()
logger.Debugf("generated network config:\n%s", generatedConfig)

if !gatewayHandled {
logger.Infof("generated network config has no gateway")
if hasV4Interface && !gateway4Handled {
logger.Infof("generated network config has no ipv4 gateway")
}

if hasV6Interface && !gateway6Handled {
logger.Infof("generated network config has no ipv6 gateway")
}

return generatedConfig, nil
Expand All @@ -154,7 +180,8 @@ type PreparedConfig struct {
NameToAddress map[string]string
NameToRoutes map[string][]network.Route
NameToMTU map[string]int
GatewayAddress string
Gateway4Address string
Gateway6Address string
}

// PrepareNetworkConfigFromInterfaces collects the necessary information to
Expand All @@ -163,7 +190,8 @@ type PreparedConfig struct {
func PrepareNetworkConfigFromInterfaces(interfaces []network.InterfaceInfo) *PreparedConfig {
dnsServers := set.NewStrings()
dnsSearchDomains := set.NewStrings()
gatewayAddress := ""
gateway4Address := ""
gateway6Address := ""
namesInOrder := make([]string, 1, len(interfaces)+1)
nameToAddress := make(map[string]string)
nameToRoutes := make(map[string][]network.Route)
Expand Down Expand Up @@ -195,8 +223,14 @@ func PrepareNetworkConfigFromInterfaces(interfaces []network.InterfaceInfo) *Pre

dnsSearchDomains = dnsSearchDomains.Union(set.NewStrings(info.DNSSearchDomains...))

if gatewayAddress == "" && info.GatewayAddress.Value != "" {
gatewayAddress = info.GatewayAddress.Value
if info.GatewayAddress.Value != "" {
switch {
case gateway4Address == "" && info.GatewayAddress.Type == network.IPv4Address:
gateway4Address = info.GatewayAddress.Value

case gateway6Address == "" && info.GatewayAddress.Type == network.IPv6Address:
gateway6Address = info.GatewayAddress.Value
}
}

if info.MTU != 0 && info.MTU != 1500 {
Expand All @@ -214,7 +248,8 @@ func PrepareNetworkConfigFromInterfaces(interfaces []network.InterfaceInfo) *Pre
AutoStarted: autoStarted.SortedValues(),
DNSServers: dnsServers.SortedValues(),
DNSSearchDomains: dnsSearchDomains.SortedValues(),
GatewayAddress: gatewayAddress,
Gateway4Address: gateway4Address,
Gateway6Address: gateway6Address,
}

logger.Debugf("prepared network config for rendering: %+v", prepared)
Expand Down
20 changes: 18 additions & 2 deletions cloudconfig/containerinit/container_userdata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ func (s *UserDataSuite) SetUpTest(c *gc.C) {
ConfigType: network.ConfigManual,
MACAddress: "aa:bb:cc:dd:ee:f4",
NoAutoStart: true,
}, {
InterfaceName: "any5",
ConfigType: network.ConfigStatic,
MACAddress: "aa:bb:cc:dd:ee:f5",
NoAutoStart: false,
CIDR: "2001:db8::/64",
Address: network.NewAddress("2001:db8::dead:beef"),
GatewayAddress: network.NewAddress("2001:db8::dead:f00"),
}}

for _, version := range []string{
Expand All @@ -123,7 +131,7 @@ bootcmd:
- install -D -m 644 /dev/null '%[1]s.templ'
- |-
printf '%%s\n' '
auto lo {ethaa_bb_cc_dd_ee_f0} {ethaa_bb_cc_dd_ee_f1} {ethaa_bb_cc_dd_ee_f3}
auto lo {ethaa_bb_cc_dd_ee_f0} {ethaa_bb_cc_dd_ee_f1} {ethaa_bb_cc_dd_ee_f3} {ethaa_bb_cc_dd_ee_f5}
iface lo inet loopback
dns-nameservers ns1.invalid ns2.invalid
Expand All @@ -144,10 +152,14 @@ bootcmd:
iface {ethaa_bb_cc_dd_ee_f3} inet dhcp
iface {ethaa_bb_cc_dd_ee_f4} inet manual
iface {ethaa_bb_cc_dd_ee_f5} inet6 static
address 2001:db8::dead:beef/64
gateway 2001:db8::dead:f00
' > '%[1]s.templ'
`
s.expectedSampleConfigTemplate = `
auto lo {ethaa_bb_cc_dd_ee_f0} {ethaa_bb_cc_dd_ee_f1} {ethaa_bb_cc_dd_ee_f3}
auto lo {ethaa_bb_cc_dd_ee_f0} {ethaa_bb_cc_dd_ee_f1} {ethaa_bb_cc_dd_ee_f3} {ethaa_bb_cc_dd_ee_f5}
iface lo inet loopback
dns-nameservers ns1.invalid ns2.invalid
Expand All @@ -168,6 +180,10 @@ iface {ethaa_bb_cc_dd_ee_f2} inet dhcp
iface {ethaa_bb_cc_dd_ee_f3} inet dhcp
iface {ethaa_bb_cc_dd_ee_f4} inet manual
iface {ethaa_bb_cc_dd_ee_f5} inet6 static
address 2001:db8::dead:beef/64
gateway 2001:db8::dead:f00
`

networkInterfacesScriptYamled := strings.Replace(containerinit.NetworkInterfacesScript, "\n", "\n ", -1)
Expand Down
3 changes: 3 additions & 0 deletions cmd/juju/application/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,9 @@ func (h *bundleHandler) addService(
}
}
resources := make(map[string]string)
for resName, path := range p.LocalResources {
resources[resName] = path
}
for resName, revision := range p.Resources {
resources[resName] = fmt.Sprint(revision)
}
Expand Down
25 changes: 25 additions & 0 deletions cmd/juju/application/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,31 @@ func (s *BundleDeployCharmStoreSuite) TestDeployBundleLocalPath(c *gc.C) {
})
}

func (s *BundleDeployCharmStoreSuite) TestDeployBundleLocalResources(c *gc.C) {
dir := c.MkDir()
testcharms.Repo.ClonedDir(dir, "dummy-resource")
path := filepath.Join(dir, "mybundle")
data := `
series: quantal
applications:
"dummy-resource":
charm: ./dummy-resource
series: quantal
num_units: 1
resources:
dummy: %s
`
data = fmt.Sprintf(data, filepath.Join(dir, "dummy-resource", "dummy-resource.zip"))
err := ioutil.WriteFile(path, []byte(data), 0644)
c.Assert(err, jc.ErrorIsNil)
_, err = runDeploy(c, path)
c.Assert(err, jc.ErrorIsNil)
s.assertCharmsUploaded(c, "local:quantal/dummy-resource-0")
s.assertApplicationsDeployed(c, map[string]serviceInfo{
"dummy-resource": {charm: "local:quantal/dummy-resource-0"},
})
}

func (s *BundleDeployCharmStoreSuite) TestDeployBundleNoSeriesInCharmURL(c *gc.C) {
testcharms.UploadCharmMultiSeries(c, s.client, "~who/multi-series", "multi-series")
dir := c.MkDir()
Expand Down
4 changes: 2 additions & 2 deletions cmd/juju/application/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,11 @@ Examples:
the 'cmd' or the 'database' spaces)
See also:
spaces
config
add-unit
config
set-constraints
get-constraints
spaces
`

// DeployStep is an action that needs to be taken during charm deployment.
Expand Down
6 changes: 2 additions & 4 deletions cmd/juju/block/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Commands that can be disabled are grouped based on logical operations as follows
add-ssh-key
add-user
change-user-password
config
deploy
disable-user
destroy-controller
Expand All @@ -33,6 +34,7 @@ Commands that can be disabled are grouped based on logical operations as follows
enable-user
expose
import-ssh-key
model-config
remove-application
remove-machine
remove-relation
Expand All @@ -41,13 +43,9 @@ Commands that can be disabled are grouped based on logical operations as follows
resolved
retry-provisioning
run
set-config
set-constraints
set-model-config
sync-tools
unexpose
unset-config
unset-model-config
upgrade-charm
upgrade-juju
`
10 changes: 10 additions & 0 deletions cmd/juju/commands/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1852,6 +1852,16 @@ clouds:
region-2:
dummy-cloud-without-regions:
type: dummy
dummy-cloud-with-region-config:
type: dummy
regions:
region-1:
region-2:
config:
network: cloud-network
region-config:
region-1:
network: region-network
dummy-cloud-with-config:
type: dummy
config:
Expand Down
Loading

0 comments on commit 14851f1

Please sign in to comment.