Skip to content

Commit

Permalink
Pebble support with *-workload-ready hook.
Browse files Browse the repository at this point in the history
  • Loading branch information
hpidcock committed Feb 12, 2021
1 parent d8a04d8 commit 9c756d2
Show file tree
Hide file tree
Showing 89 changed files with 1,463 additions and 349 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ define MAIN_PACKAGES
github.com/juju/juju/cmd/juju
github.com/juju/juju/cmd/jujuc
github.com/juju/juju/cmd/jujud
github.com/juju/juju/cmd/k8sagent
github.com/juju/juju/cmd/containeragent
github.com/juju/juju/cmd/plugins/juju-metadata
github.com/juju/juju/cmd/plugins/juju-wait-for
endef

ifeq ($(GOOS),linux)
MAIN_PACKAGES += github.com/hpidcock/juju-fake-init
MAIN_PACKAGES += github.com/canonical/pebble/cmd/pebble
endif

# Allow the tests to take longer on restricted platforms.
Expand Down
10 changes: 5 additions & 5 deletions api/caasapplicationprovisioner/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (c *Client) SetPassword(appName string, password string) error {
return errors.Errorf("invalid number of results %d expected 1", len(result.Results))
}
if result.Results[0].Error != nil {
return errors.Trace(result.Results[0].Error)
return errors.Trace(maybeNotFound(result.Results[0].Error))
}
return nil
}
Expand Down Expand Up @@ -135,7 +135,7 @@ func (c *Client) ProvisioningInfo(applicationName string) (ProvisioningInfo, err
}
r := result.Results[0]
if err := r.Error; err != nil {
return ProvisioningInfo{}, errors.Trace(err)
return ProvisioningInfo{}, errors.Trace(maybeNotFound(err))
}

info := ProvisioningInfo{
Expand Down Expand Up @@ -221,7 +221,7 @@ func (c *Client) ApplicationCharmURL(appName string) (*charm.URL, error) {
}
res := result.Results[0]
if res.Error != nil {
return nil, errors.Annotatef(res.Error, "unable to fetch charm url for %s", appName)
return nil, errors.Annotatef(maybeNotFound(res.Error), "unable to fetch charm url for %s", appName)
}
url, err := charm.ParseURL(res.Result)
if err != nil {
Expand Down Expand Up @@ -258,7 +258,7 @@ func (c *Client) Units(appName string) ([]names.Tag, error) {
}
res := result.Results[0]
if res.Error != nil {
return nil, errors.Annotatef(res.Error, "unable to fetch units for %s", appName)
return nil, errors.Annotatef(maybeNotFound(res.Error), "unable to fetch units for %s", appName)
}
tags := make([]names.Tag, 0, len(res.Entities))
for _, v := range res.Entities {
Expand Down Expand Up @@ -312,7 +312,7 @@ func (c *Client) ApplicationOCIResources(appName string) (map[string]resources.D
}
res := result.Results[0]
if res.Error != nil {
return nil, errors.Annotatef(res.Error, "unable to fetch OCI image resources for %s", appName)
return nil, errors.Annotatef(maybeNotFound(res.Error), "unable to fetch OCI image resources for %s", appName)
}
if res.Result == nil {
return nil, errors.Errorf("missing result")
Expand Down
6 changes: 3 additions & 3 deletions apiserver/facades/client/application/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ func caasPrecheck(

// For older charms, operator-storage model config is mandatory.
if k8s.RequireOperatorStorage(ch.Meta().MinJujuVersion) {
storageClassName, _ := cfg.AllAttrs()[k8s.OperatorStorageKey].(string)
storageClassName, _ := cfg.AllAttrs()[k8sconstants.OperatorStorageKey].(string)
if storageClassName == "" {
return errors.New(
"deploying a Kubernetes application requires a suitable storage class.\n" +
Expand All @@ -631,7 +631,7 @@ func caasPrecheck(
return errors.Annotatef(err, "getting operator storage params for %q", args.ApplicationName)
}
if sp.Provider != string(k8sconstants.StorageProviderType) {
poolName := cfg.AllAttrs()[k8s.OperatorStorageKey]
poolName := cfg.AllAttrs()[k8sconstants.OperatorStorageKey]
return errors.Errorf(
"the %q storage pool requires a provider type of %q, not %q", poolName, k8sconstants.StorageProviderType, sp.Provider)
}
Expand All @@ -640,7 +640,7 @@ func caasPrecheck(
}
}

workloadStorageClass, _ := cfg.AllAttrs()[k8s.WorkloadStorageKey].(string)
workloadStorageClass, _ := cfg.AllAttrs()[k8sconstants.WorkloadStorageKey].(string)
for storageName, cons := range args.Storage {
if cons.Pool == "" && workloadStorageClass == "" {
return errors.Errorf("storage pool for %q must be specified since there's no model default storage class", storageName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/juju/juju/apiserver/facade"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/caas"
"github.com/juju/juju/caas/kubernetes/provider"
k8sconstants "github.com/juju/juju/caas/kubernetes/provider/constants"
"github.com/juju/juju/cloudconfig/podcfg"
"github.com/juju/juju/controller"
Expand Down Expand Up @@ -628,7 +627,7 @@ func filesystemParams(
}
filesystemTags[tags.JujuStorageOwner] = app.Name()

storageClassName, _ := modelConfig.AllAttrs()[provider.WorkloadStorageKey].(string)
storageClassName, _ := modelConfig.AllAttrs()[k8sconstants.WorkloadStorageKey].(string)
if cons.Pool == "" && storageClassName == "" {
return nil, errors.Errorf("storage pool for %q must be specified since there's no model default storage class", storageName)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (a *API) OperatorProvisioningInfo(args params.Entities) (params.OperatorPro

oneProvisioningInfo := func(storageRequired bool) params.OperatorProvisioningInfo {
var charmStorageParams *params.KubernetesFilesystemParams
storageClassName, _ := modelConfig.AllAttrs()[provider.OperatorStorageKey].(string)
storageClassName, _ := modelConfig.AllAttrs()[k8sconstants.OperatorStorageKey].(string)
if storageRequired {
if storageClassName == "" {
return params.OperatorProvisioningInfo{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/juju/juju/apiserver/facades/controller/caasoperatorprovisioner"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/caas"
"github.com/juju/juju/caas/kubernetes/provider"
k8sconstants "github.com/juju/juju/caas/kubernetes/provider/constants"
"github.com/juju/juju/cloudconfig/podcfg"
"github.com/juju/juju/controller"
"github.com/juju/juju/core/status"
Expand Down Expand Up @@ -389,7 +389,7 @@ func filesystemParams(
}
filesystemTags[tags.JujuStorageOwner] = app.Name()

storageClassName, _ := modelConfig.AllAttrs()[provider.WorkloadStorageKey].(string)
storageClassName, _ := modelConfig.AllAttrs()[k8sconstants.WorkloadStorageKey].(string)
if cons.Pool == "" && storageClassName == "" {
return nil, errors.Errorf("storage pool for %q must be specified since there's no model default storage class", storageName)
}
Expand Down
4 changes: 1 addition & 3 deletions caas/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ RUN apt-get update \
# below apt dependencies are required by controller pod.
iproute2 \
curl \
# TODO(new-charms): remove when pebble/initer is complete.
openssh-client \
&& pip3 install --upgrade pip setuptools \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /root/.cache
Expand All @@ -33,7 +31,7 @@ RUN pip3 install -r /tmp/wheelhouse/requirements.txt
WORKDIR /var/lib/juju
COPY jujud /opt/
COPY jujuc /opt/
COPY k8sagent /opt/
COPY containeragent /opt/
COPY pebble /opt/

ENTRYPOINT ["sh", "-c"]
16 changes: 11 additions & 5 deletions caas/kubernetes/provider/application/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ func (a *app) applicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
ImagePullPolicy: corev1.PullIfNotPresent,
Image: config.CharmBaseImage.RegistryPath,
WorkingDir: jujuDataDir,
Command: []string{"/charm/bin/k8sagent"},
Command: []string{"/charm/bin/containeragent"},
Args: []string{
"unit",
"--data-dir", jujuDataDir,
Expand All @@ -890,6 +890,10 @@ func (a *app) applicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
Value: constants.AgentHTTPProbePort,
},
},
SecurityContext: &corev1.SecurityContext{
RunAsUser: int64Ptr(0),
RunAsGroup: int64Ptr(0),
},
LivenessProbe: &corev1.Probe{
Handler: corev1.Handler{
HTTPGet: &corev1.HTTPGetAction{
Expand Down Expand Up @@ -953,13 +957,15 @@ func (a *app) applicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
Image: v.Image.RegistryPath,
Command: []string{"/charm/bin/pebble"},
Args: []string{
"listen",
"--socket", "/charm/container/pebble.sock",
"--append-env", "PATH=$PATH:/charm/bin",
"run",
"--hold",
},
Env: []corev1.EnvVar{{
Name: "JUJU_CONTAINER_NAME",
Value: v.Name,
}, {
Name: "PEBBLE",
Value: "/charm/container/pebble",
}},
VolumeMounts: []corev1.VolumeMount{
{
Expand All @@ -986,7 +992,7 @@ func (a *app) applicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
ImagePullPolicy: corev1.PullIfNotPresent,
Image: config.AgentImagePath,
WorkingDir: jujuDataDir,
Command: []string{"/opt/k8sagent"},
Command: []string{"/opt/containeragent"},
Args: []string{"init", "--data-dir", jujuDataDir, "--bin-dir", "/charm/bin"},
Env: []corev1.EnvVar{
{
Expand Down
24 changes: 10 additions & 14 deletions caas/kubernetes/provider/application/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func getPodSpec(c *gc.C) corev1.PodSpec {
ImagePullPolicy: corev1.PullIfNotPresent,
Image: "operator/image-path",
WorkingDir: jujuDataDir,
Command: []string{"/opt/k8sagent"},
Command: []string{"/opt/containeragent"},
Args: []string{"init", "--data-dir", "/var/lib/juju", "--bin-dir", "/charm/bin"},
Env: []corev1.EnvVar{
{
Expand Down Expand Up @@ -268,7 +268,7 @@ func getPodSpec(c *gc.C) corev1.PodSpec {
ImagePullPolicy: corev1.PullIfNotPresent,
Image: "ubuntu:20.04",
WorkingDir: jujuDataDir,
Command: []string{"/charm/bin/k8sagent"},
Command: []string{"/charm/bin/containeragent"},
Args: []string{"unit", "--data-dir", jujuDataDir, "--charm-modified-version", "9001", "--append-env", "PATH=$PATH:/charm/bin"},
Env: []corev1.EnvVar{
{
Expand Down Expand Up @@ -337,22 +337,22 @@ func getPodSpec(c *gc.C) corev1.PodSpec {
Name: "gitlab-database-appuuid",
MountPath: "path/to/here",
},
// {
// Name: "gitlab-logs",
// MountPath: "path/to/there",
// },
},
}, {
Name: "gitlab",
ImagePullPolicy: corev1.PullIfNotPresent,
Image: "gitlab-image:latest",
Command: []string{"/charm/bin/pebble"},
Args: []string{"listen", "--socket", "/charm/container/pebble.sock", "--append-env", "PATH=$PATH:/charm/bin"},
Args: []string{"run", "--hold"},
Env: []corev1.EnvVar{
{
Name: "JUJU_CONTAINER_NAME",
Value: "gitlab",
},
{
Name: "PEBBLE",
Value: "/charm/container/pebble",
},
},
VolumeMounts: []corev1.VolumeMount{
{
Expand All @@ -370,10 +370,6 @@ func getPodSpec(c *gc.C) corev1.PodSpec {
Name: "gitlab-database-appuuid",
MountPath: "path/to/here",
},
// {
// Name: "gitlab-logs",
// MountPath: "path/to/there",
// },
},
}},
Volumes: []corev1.Volume{
Expand Down Expand Up @@ -1017,7 +1013,7 @@ func (s *applicationSuite) TestUpdatePortsStatelessUpdateContainerPorts(c *gc.C)
ImagePullPolicy: corev1.PullIfNotPresent,
Image: "operator/image-path",
WorkingDir: "/var/lib/juju",
Command: []string{"/charm/bin/k8sagent"},
Command: []string{"/charm/bin/containeragent"},
Args: []string{"unit", "--data-dir", "/var/lib/juju", "--append-env", "PATH=$PATH:/charm/bin"},
Env: []corev1.EnvVar{{
Name: "HTTP_PROBE_PORT",
Expand Down Expand Up @@ -1143,7 +1139,7 @@ func (s *applicationSuite) TestUpdatePortsStatefulUpdateContainerPorts(c *gc.C)
ImagePullPolicy: corev1.PullIfNotPresent,
Image: "operator/image-path",
WorkingDir: "/var/lib/juju",
Command: []string{"/charm/bin/k8sagent"},
Command: []string{"/charm/bin/containeragent"},
Args: []string{"unit", "--data-dir", "/var/lib/juju", "--append-env", "PATH=$PATH:/charm/bin"},
Env: []corev1.EnvVar{{
Name: "HTTP_PROBE_PORT",
Expand Down Expand Up @@ -1269,7 +1265,7 @@ func (s *applicationSuite) TestUpdatePortsDaemonUpdateContainerPorts(c *gc.C) {
ImagePullPolicy: corev1.PullIfNotPresent,
Image: "operator/image-path",
WorkingDir: "/var/lib/juju",
Command: []string{"/charm/bin/k8sagent"},
Command: []string{"/charm/bin/containeragent"},
Args: []string{"unit", "--data-dir", "/var/lib/juju", "--append-env", "PATH=$PATH:/charm/bin"},
}, {
Name: "gitlab",
Expand Down
7 changes: 4 additions & 3 deletions caas/kubernetes/provider/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"k8s.io/client-go/tools/cache"

"github.com/juju/juju/caas/kubernetes/provider"
k8sconstants "github.com/juju/juju/caas/kubernetes/provider/constants"
"github.com/juju/juju/caas/kubernetes/provider/mocks"
k8sspecs "github.com/juju/juju/caas/kubernetes/provider/specs"
"github.com/juju/juju/caas/kubernetes/provider/utils"
Expand Down Expand Up @@ -165,9 +166,9 @@ func (s *BaseSuite) SetUpTest(c *gc.C) {

// init config for each test for easier changing config inside test.
cfg, err := config.New(config.UseDefaults, testing.FakeConfig().Merge(testing.Attrs{
config.NameKey: "test",
provider.OperatorStorageKey: "",
provider.WorkloadStorageKey: "",
config.NameKey: "test",
k8sconstants.OperatorStorageKey: "",
k8sconstants.WorkloadStorageKey: "",
}))
c.Assert(err, jc.ErrorIsNil)
s.cfg = cfg
Expand Down
7 changes: 4 additions & 3 deletions caas/kubernetes/provider/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/juju/juju/api"
"github.com/juju/juju/caas/kubernetes/provider"
k8sconstants "github.com/juju/juju/caas/kubernetes/provider/constants"
k8swatcher "github.com/juju/juju/caas/kubernetes/provider/watcher"
k8swatchertest "github.com/juju/juju/caas/kubernetes/provider/watcher/test"
"github.com/juju/juju/cloudconfig/podcfg"
Expand Down Expand Up @@ -56,9 +57,9 @@ func (s *bootstrapSuite) SetUpTest(c *gc.C) {
s.BaseSuite.SetUpTest(c)

cfg, err := config.New(config.UseDefaults, testing.FakeConfig().Merge(testing.Attrs{
config.NameKey: "controller-1",
provider.OperatorStorageKey: "",
provider.WorkloadStorageKey: "",
config.NameKey: "controller-1",
k8sconstants.OperatorStorageKey: "",
k8sconstants.WorkloadStorageKey: "",
}))
c.Assert(err, jc.ErrorIsNil)
s.cfg = cfg
Expand Down
11 changes: 6 additions & 5 deletions caas/kubernetes/provider/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

"github.com/juju/juju/caas"
"github.com/juju/juju/caas/kubernetes/clientconfig"
k8sconstants "github.com/juju/juju/caas/kubernetes/provider/constants"
"github.com/juju/juju/cloud"
"github.com/juju/juju/environs"
environscloudspec "github.com/juju/juju/environs/cloudspec"
Expand Down Expand Up @@ -123,11 +124,11 @@ func updateK8sCloud(k8sCloud *cloud.Cloud, clusterMetadata *caas.ClusterMetadata
if k8sCloud.Config == nil {
k8sCloud.Config = make(map[string]interface{})
}
if _, ok := k8sCloud.Config[WorkloadStorageKey]; !ok {
k8sCloud.Config[WorkloadStorageKey] = workloadSC
if _, ok := k8sCloud.Config[k8sconstants.WorkloadStorageKey]; !ok {
k8sCloud.Config[k8sconstants.WorkloadStorageKey] = workloadSC
}
if _, ok := k8sCloud.Config[OperatorStorageKey]; !ok {
k8sCloud.Config[OperatorStorageKey] = operatorSC
if _, ok := k8sCloud.Config[k8sconstants.OperatorStorageKey]; !ok {
k8sCloud.Config[k8sconstants.OperatorStorageKey] = operatorSC
}
return storageMsg
}
Expand Down Expand Up @@ -289,7 +290,7 @@ func (p kubernetesEnvironProvider) FinalizeCloud(ctx environs.FinalizeCloudConte
}

// if storage is already defined there is no need to query the cluster
if opStorage, ok := cld.Config[OperatorStorageKey]; ok && opStorage != "" {
if opStorage, ok := cld.Config[k8sconstants.OperatorStorageKey]; ok && opStorage != "" {
return cld, nil
}

Expand Down
10 changes: 10 additions & 0 deletions caas/kubernetes/provider/constants/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ const (
StorageMode = "storage-mode"
)

const (
// WorkloadStorageKey is the model config attribute used to specify
// the storage class for provisioning workload storage.
WorkloadStorageKey = "workload-storage"

// OperatorStorageKey is the model config attribute used to specify
// the storage class for provisioning operator storage.
OperatorStorageKey = "operator-storage"
)

// QualifiedStorageClassName returns a qualified storage class name.
func QualifiedStorageClassName(namespace, storageClass string) string {
if namespace == "" {
Expand Down
Loading

0 comments on commit 9c756d2

Please sign in to comment.