Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

util.libsonnet has methods that allow a <component>.part to be modified #1395

Merged
merged 15 commits into from Aug 24, 2018

Conversation

kkasravi
Copy link
Contributor

@kkasravi kkasravi commented Aug 21, 2018

Fixes #1231

After kfctl.sh generate k8s the user would update components/jupterhub.jsonnet

local jupyterhub = import "kubeflow/core/jupyterhub.libsonnet";
local util = import "kubeflow/core/util.libsonnet";
util.update(jupyterhub, updatedParams, 'StatefulSet/tf-hub',
  {
    template+: {
      spec+: {
        imagePullSecrets: [
          {name: "mySecret",}
        ],
      },
    },
  }
)

This change is Reviewable

@kkasravi
Copy link
Contributor Author

/assign @jlewi

@kkasravi
Copy link
Contributor Author

/cc @ankushagarwal

@ankushagarwal
Copy link
Contributor

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot removed the lgtm label Aug 21, 2018
@ankushagarwal
Copy link
Contributor

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot removed the lgtm label Aug 21, 2018
@kkasravi
Copy link
Contributor Author

/retest

@jlewi
Copy link
Contributor

jlewi commented Aug 22, 2018

See comment here:
#1231 (comment)

It looks like the pattern you are suggesting is to have parts define a list and then convert that to a map so you can modify an element by name. That's a useful function.

But why wouldn't we just rewrite the libsonnet file to be a map?

e.g suppose the libsonnet file looked like

{
    statefulset :: {
     ...
   }

   parts :: [$.statefulset, ....]
}

Then I think in the .jsonnet file you could do something like

local jupyterhub = import "kubeflow/core/jupyterhub.libsonnet";
local updated = jupterhub +  {
   statfulset +: {
        template+: {
      spec+: {
        imagePullSecrets: [
          {name: "mySecret",}
        ],
      },
    },
  }
 },
)

std.prune(updated.parts)

toList:: [$[key] for key in std.objectFields($)],

// Convert an array of kubernetes resources into a map[kind/name, resource]
toMap:: function(params) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is toMap taking params as an argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe I understand. Does the following make sense?

  1. Remove params from toMap (prometheus.libsonnet is an example where parts is a map and all is parts)
  2. Build the map first, then the parts which reference the map eg: [map.values()]

Question: What about repeating resources within a libsonnet? For example jupyterhub.libsonnet has 2 Services, 2 ServiceAccounts, 2 Roles, 2 RoleBindings. Should we deal with it only if needed? For example:

local jup = {
  Service: {
    "tf-hub-0": {foo:"bar",},
    "tf-hub-lb": {bar:"baz",},
  },
};

so the update would look like

jup +  {
   Service+: {
    "tf-hub-0"+: {one: "two",},
  },
}

yielding

{
   "Service": {
      "tf-hub-0": {
         "foo": "bar",
         "one": "two"
      },
      "tf-hub-lb": {
         "bar": "baz"
      }
   }
}

for non-repeating resources it would look like your example with StatefulSet or would that be too confusing?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think the top level items in the dictionary should be based on type. They should be based on what they do; e.g. if there are multiple services each service should be its own item.

Copy link
Contributor Author

@kkasravi kkasravi Aug 22, 2018

Choose a reason for hiding this comment

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

so how bout

{
  ConfigMap:: 
  HubService::
  HubServiceAccount::
  HubRole::
  HubRoleBinding::
  NotebookService::
  NotebookServiceAccount::
  NotebookRole::
  NotebookRoleBinding::  
  StatefulSet::
}

where the map is a set of functional hidden names. The one above would be jupyterhub.

Copy link
Contributor Author

@kkasravi kkasravi Aug 22, 2018

Choose a reason for hiding this comment

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

parts (or all) would be in the top level mapping

{
  ConfigMap:: 
  HubService::
  HubServiceAccount::
  HubRole::
  HubRoleBinding::
  NotebookService::
  NotebookServiceAccount::
  NotebookRole::
  NotebookRoleBinding::  
  StatefulSet::

  parts|all:: [ ConfigMap:: HubService:: ... ]
}

Copy link
Contributor

Choose a reason for hiding this comment

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

LGTM

@kkasravi
Copy link
Contributor Author

kkasravi commented Aug 23, 2018

@jlewi

This now works

local jupyterhub = import "kubeflow/core/jupyterhub.libsonnet";
local updated = jupyterhub + {
  StatefulSet+: {
     spec+: {
       template+: {
         spec+: {
          imagePullSecrets: [
            {name: "mySecret",}
          ],
        },
      },
    },
  },
};
updated.all(updatedParams).list

I can update the other libsonnets if this looks ok. Note that params is now referenced as $.params within the resources.

Kam D Kasravi added 2 commits August 23, 2018 12:57
if key != "list" && key != "params" && key != "all"
],

ConfigMap:: {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Change the name and StatefulSet name to be more descriptive
e.g
ConfigMap -> KubeSpawnerConfig

StatefulSet -> HubStatefulSet

@jlewi
Copy link
Contributor

jlewi commented Aug 23, 2018

Looks great to me. I had one nit about the names but otherwise this is ready IMO.

@kkasravi
Copy link
Contributor Author

thanks @jlewi

@jlewi
Copy link
Contributor

jlewi commented Aug 24, 2018

/lgtm
/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ankushagarwal, jlewi

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [ankushagarwal,jlewi]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot merged commit 70284dc into kubeflow:master Aug 24, 2018
saffaalvi pushed a commit to StatCan/kubeflow that referenced this pull request Feb 11, 2021
…ed (kubeflow#1395)

* initial checkin on generalized way of editing component parts

* added add, modify, remove examples

* kubeflow/core/util.libsonnet holds new methods to update <component>.parts

* added testing

* fix fmt error for kubeflow/core/util.jsonnet

* /retest

* /retest

* /retest

* /retest

* /retest

* /retest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants