diff --git a/README.rst b/README.rst index 09c1dcf3b..051c8f312 100644 --- a/README.rst +++ b/README.rst @@ -124,7 +124,6 @@ Table of Contents doc/content-packages doc/rackn/license Trademark - LICENSE doc/fun-facts .. _rs_license: @@ -150,3 +149,5 @@ Digital Rebar Provision documentation is available from multiple authors under t In the case of works protected by multiple Creative Common licenses, the user may choose either. + +.. Release v4.6.0 Start diff --git a/cli/catalog.go b/cli/catalog.go index 5346c5d6b..cc1e7a6fb 100644 --- a/cli/catalog.go +++ b/cli/catalog.go @@ -57,47 +57,121 @@ func getLocalCatalog() (res *models.Content, err error) { return } -func catalogCommands() *cobra.Command { - - type catItem struct { - Type string - Versions []string +func fetchCatalog() (res *models.Content, err error) { + buf := []byte{} + buf, err = bufOrFile(catalog) + if err == nil { + err = json.Unmarshal(buf, &res) + } + if err != nil { + err = fmt.Errorf("Error fetching catalog: %v", err) } + return +} - fetchCatalog := func() (res *models.Content, err error) { - buf := []byte{} - buf, err = bufOrFile(catalog) - if err == nil { - err = json.Unmarshal(buf, &res) +func itemsFromCatalog(cat *models.Content, name string) map[string]*models.CatalogItem { + res := map[string]*models.CatalogItem{} + for k, v := range cat.Sections["catalog_items"] { + item := &models.CatalogItem{} + if err := models.Remarshal(v, &item); err != nil { + continue } - if err != nil { - err = fmt.Errorf("Error fetching catalog: %v", err) + if name == "" || name == item.Name { + res[k] = item + } + } + return res +} + +func oneItem(cat *models.Content, name, version string) *models.CatalogItem { + items := itemsFromCatalog(cat, name) + for _, v := range items { + if v.Version == version { + return v } - return } + return nil +} - itemsFromCatalog := func(cat *models.Content, name string) map[string]*models.CatalogItem { - res := map[string]*models.CatalogItem{} - for k, v := range cat.Sections["catalog_items"] { - item := &models.CatalogItem{} - if err := models.Remarshal(v, &item); err != nil { +func installItem(catalog *models.Content, name, version, arch, tgtos string, replaceWritable bool, inflight map[string]struct{}) error { + inflight[name] = struct{}{} + if name == "BasicStore" { + return nil + } + item := oneItem(catalog, name, version) + if item == nil { + return fmt.Errorf("%s version %s not in catalog", name, version) + } + src, err := urlOrFileAsReadCloser(item.DownloadUrl(arch, tgtos)) + if src != nil { + defer src.Close() + } + if err != nil { + return fmt.Errorf("Unable to contact source URL for %s: %v", item.Name, err) + } + switch item.ContentType { + case "ContentPackage": + content := &models.Content{} + if err := json.NewDecoder(src).Decode(&content); err != nil { + return fmt.Errorf("Error downloading content bundle %s: %v", item.Name, err) + } + + prereqs := strings.Split(content.Meta.Prerequisites, ",") + for _, p := range prereqs { + p = strings.TrimSpace(p) + if p == "" { continue } - if name == "" || name == item.Name { - res[k] = item + pversion := version + if pversion != "tip" && pversion != "stable" { + pversion = "stable" } - } - return res - } + parts := strings.Split(p, ":") + pname := strings.TrimSpace(parts[0]) - oneItem := func(cat *models.Content, name, version string) *models.CatalogItem { - items := itemsFromCatalog(cat, name) - for _, v := range items { - if v.Version == version { - return v + if _, err := Session.GetContentItem(pname); err == nil { + inflight[pname] = struct{}{} + continue + } + + if err := installItem(catalog, pname, pversion, arch, tgtos, replaceWritable, inflight); err != nil { + return err } } - return nil + return doReplaceContent(content, "", replaceWritable) + case "PluginProvider": + res := &models.PluginProviderUploadInfo{} + req := Session.Req().Post(src).UrlFor("plugin_providers", item.Name) + if replaceWritable { + req = req.Params("replaceWritable", "true") + } + // TODO: One day handle prereqs. Save to local file, mark executable, get contents, check prereqs + if err := req.Do(res); err != nil { + return err + } + return prettyPrint(res) + case "DRP": + if info, err := Session.PostBlob(src, "system", "upgrade"); err != nil { + return generateError(err, "Failed to post upgrade of DRP") + } else { + return prettyPrint(info) + } + case "DRPUX": + if info, err := Session.PostBlobExplode(src, true, "files", "ux", "drp-ux.zip"); err != nil { + return generateError(err, "Failed to post upgrade of DRP") + } else { + return prettyPrint(info) + } + default: + return fmt.Errorf("Don't know how to install %s of type %s yet", item.Name, item.ContentType) + } +} + +func catalogCommands() *cobra.Command { + + type catItem struct { + Type string + Versions []string } cmd := &cobra.Command{ @@ -220,39 +294,13 @@ and wind up in a file with the same name as the item + the default file extensio if err != nil { return fmt.Errorf("Unable to fetch session information to determine endpoint arch and OS") } - item := oneItem(catalog, args[0], version) - if item == nil { - return fmt.Errorf("%s version %s not in catalog", args[0], version) - } arch = info.Arch tgtos = info.Os - src, err := urlOrFileAsReadCloser(item.DownloadUrl(arch, tgtos)) - if src != nil { - defer src.Close() - } + err = installItem(catalog, args[0], version, arch, tgtos, replaceWritable, map[string]struct{}{}) if err != nil { - return fmt.Errorf("Unable to contact source URL for %s: %v", item.Name, err) - } - switch item.ContentType { - case "ContentPackage": - content := &models.Content{} - if err := json.NewDecoder(src).Decode(&content); err != nil { - return fmt.Errorf("Error downloading content bundle %s: %v", item.Name, err) - } - return doReplaceContent(content, "", replaceWritable) - case "PluginProvider": - res := &models.PluginProviderUploadInfo{} - req := Session.Req().Post(src).UrlFor("plugin_providers", item.Name) - if replaceWritable{ - req = req.Params("replaceWritable","true") - } - if err := req.Do(res); err != nil { - return err - } - return prettyPrint(res) - default: - return fmt.Errorf("Don't know how to install %s of type %s yet", item.Name, item.ContentType) + return err } + return nil }, } install.Flags().BoolVar(&replaceWritable, "replaceWritable", false, "Replace identically named writable objects") @@ -389,3 +437,7 @@ and wind up in a file with the same name as the item + the default file extensio func init() { addRegistrar(func(c *cobra.Command) { c.AddCommand(catalogCommands()) }) } + +func installOne() { + +} diff --git a/conf.py b/conf.py index cd5780edd..82b1e320c 100644 --- a/conf.py +++ b/conf.py @@ -361,7 +361,7 @@ def fetch_urls(url): "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/chef-bootstrap.rst", "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/classify.rst", "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/cloud-wrappers.rst", - "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/coheisity.rst", + "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/cohesity.rst", "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/coreos.rst", "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/dell-support.rst", "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/dev-library.rst", @@ -401,7 +401,6 @@ def fetch_urls(url): "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/vmware.rst", "https://s3-us-west-2.amazonaws.com/rebar-catalog/docs/vmware-lib.rst", ] - fetch_n_save(urls, path="doc/content-packages") urls = [ diff --git a/doc/api.rst b/doc/api.rst index 52bd7035c..0c1830232 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -52,6 +52,26 @@ The API includes specialized filter behavior for Params that allows deep searchi To filter Machines or Profiles by Param values, pass the Param name and value using the normal Field filter specification. When the Field is not found, the backend will search model's Params keys and evalute the filter against the Param value. +.. _rs_api_proxy: + +Leveraging Multi-Site Proxy Forwarding +-------------------------------------- + +In the :ref:`rs_manager_arch`, API calls to a DRP manager for remote objects are automatically forwarded to the correct attached endpoint. This allows operators to make API calls to remote endpoints from a centralized manager without knowing the actual owner of the object. The owning endpoint can be determined for any object by inspecting its `Endpoint` property. + +For most cases, no additional information or API notation is required to leverage this functionality. The exception is creating objects on attached endpoints. The create (aka POST) case requires API callers to specify the target remote endpoint (the endpoint must be registered or the request will be rejected) to the manager. + +To make an explicit API proxy call, prefix the path of the request with the endpoint identity. For example: + + :: + + /[target endpoint id]/api/v3/machines + + +This pattern is also invoked by with the `-u` flag in the DRPCLI. + +NOTE: Multi-site is a licensed feature available in DRP v4.5+ and must be enabled for the endpoint. + .. _rs_api_slim: Payload Reduction (slim) diff --git a/doc/arch.rst b/doc/arch.rst index 2f9c21cbf..8e229270a 100644 --- a/doc/arch.rst +++ b/doc/arch.rst @@ -27,4 +27,5 @@ dr-provision for developers and power users. arch/cluster arch/pooling arch/manager + arch/Swagger diff --git a/doc/arch/manager.rst b/doc/arch/manager.rst index 0292a18d8..ad5d62610 100644 --- a/doc/arch/manager.rst +++ b/doc/arch/manager.rst @@ -68,8 +68,9 @@ The two main functions of manager are discussed here. Single Pane of Glass ==================== -When making API requests, the manager will provide results from all the attached endpoints. Additionally, all objects -have a field, **Endpoint**, that is populated with the Endpoint Id (the High Availability Id) of the owning endpoint. +When making API requests, the manager will provide results from all the attached endpoints. Additionally, all objects have a field, **Endpoint**, that is populated with the Endpoint Id (the High Availability Id) of the owning endpoint. API requests made to objects from attached endpoints are +automatically forward to the correct endpoint. See :ref:`rs_api_proxy` for more information about +using this automatic API behavior explicity. Only the local objects are replicated up to the manager, objects provided by content packages and plugins are not replicated to the manager. It is assumed that the manager will have all the content packages and plugins loaded to diff --git a/doc/kb/kb-00042.rst b/doc/kb/kb-00042.rst index df7c737a2..62dc7bb06 100644 --- a/doc/kb/kb-00042.rst +++ b/doc/kb/kb-00042.rst @@ -39,6 +39,7 @@ JQ Raw Mode =========== Raw JSON output is usefull when passing the results of one ``jq`` command in to another for scripted interaction. Be sure to specify "Raw" mode in this case - to prevent colorization and extraneous quotes being wrapped around Key/Value data output. + :: | jq -r ... @@ -52,11 +53,13 @@ Filter Out gohai-inventory The ``gohai-inventory`` module is extremely useful for providing Machine classification information for use by other stages or tasks. However, it is very long and causes a lot of content to be output to the console when listing Machine information. Using a simple ``jq`` filter, you can delete the ``gohai-inventory`` content from the output display. Note that since the Param name is ``gohai-inventory``, we have to provide some quoting of the Param name, since the dash (``-``) has special meaning in JSON parsing. + :: drpcli machines list | jq 'del(.[].Params."gohai-inventory")' Subsequently, if you are listing an individual Machine, then you can also filter it's ``gohai-inventory`` output as well, with: + :: drpcli machines show | jq 'del(.Params."gohai-inventory")' @@ -68,6 +71,7 @@ List BootEnv Names ================== Get list of bootenvs available in the installed content, by name: + :: drpcli bootenvs list | jq '.[].Name' @@ -79,11 +83,13 @@ Reformat Output With Specific Keys ================================== Get list of machines, output "Name:Uuid" pairs from the the JSON output: + :: drpcli machines list | jq -r '.[] | "\(.Name):\(.Uuid)"' Output is printed as follows: + :: machine1:05abe5dc-637a-4952-a1be-5ec85ba00686 @@ -98,6 +104,7 @@ Extract Specific Key From Output ================================ ``jq`` can also pull out only specific Keys from the JSON input. Here is an example to get ISO File name for a bootenv: + :: drpcli contents show os-discovery | jq '.sections.bootenvs.discovery.OS.IsoFile' @@ -109,6 +116,7 @@ Display Job Logs for Specific Machine ===================================== The Job Logs provide a lot of information about the provisioning process of your DRP Endpoint. However, you often only want to see Job Logs for a specific Machine to evaluate provisioning status. To get specific Jobs from the job list - based on Machine UUID, do: + :: export UUID=`abcd-efgh-ijkl-mnop-qrps" @@ -120,7 +128,7 @@ The Job Logs provide a lot of information about the provisioning process of your Using --args deal with pipes and quotes (NOT A DRPCLI JQ feature) ================================================================= -.. note:: This is NOT supported by the DROCLI JQ_ +.. note:: This is NOT supported by the DROCLI JQ In scripts, it can become very difficult to correctly pass variables inside of pipes. For this reason, operators may want to use the `jq --args` instead of attempting to inject values into jq queries. @@ -133,7 +141,7 @@ In the example below, we needed to match a value inside an array of JSON objects This example looks for a value in an array. - :: + :: licensed=$(jq --args m "$mc" -r 'contains(["$m"])' <<< $endpoints) diff --git a/doc/operation.rst b/doc/operation.rst index 68c9a753f..41c62dd0c 100644 --- a/doc/operation.rst +++ b/doc/operation.rst @@ -20,7 +20,6 @@ Some of these operations are in the :ref:`rs_ui`, but not all. This will focus operations/airgap operations/bios - operations/commands operations/contexts operations/drpcli operations/esxi-getting-started diff --git a/doc/operations/drpcli.rst b/doc/operations/drpcli.rst index da3bf0bf9..537dc20f0 100644 --- a/doc/operations/drpcli.rst +++ b/doc/operations/drpcli.rst @@ -775,4 +775,4 @@ to assist them with troubleshooting your issue. drpcli can be used to create the drpcli support machine-bundle [id] -How to update drpcli to obtain the support commands: :ref:`_rs_kb_00049` \ No newline at end of file +How to update drpcli to obtain the support commands: :ref:`rs_kb_00049` diff --git a/doc/operations/manager.rst b/doc/operations/manager.rst index 43d40c0af..8b5df34d9 100644 --- a/doc/operations/manager.rst +++ b/doc/operations/manager.rst @@ -80,6 +80,12 @@ or content packages. The **files** api can be used to update the catalog. The UX has a helper button for this action. +Proxy Creating an Object on Managed Endpoint +____________________________________________ + +It is possible to create objects on managed endpoints by using proxy pass-through from the manager. Details are available in :ref:`rs_api_proxy`. + + Manager Common Methods ---------------------- diff --git a/doc/rel_notes/summaries/release_v43.rst b/doc/rel_notes/summaries/release_v43.rst index e57be5fa0..7179d1960 100644 --- a/doc/rel_notes/summaries/release_v43.rst +++ b/doc/rel_notes/summaries/release_v43.rst @@ -92,17 +92,17 @@ Other Items of Note * UX Messaging Feature * Secure Boot * VMware v7 Integration -* Other Notable Enhancements - * Support for additional DHCP Options - * Significant performance enhancements on backend storage - * Machine fingerprint supports constrained external DHCP - * Re-integration of automated test coverage reports (sustained >70%) +* Other Notable Enhancements + * Support for additional DHCP Options + * Significant performance enhancements on backend storage + * Machine fingerprint supports constrained external DHCP + * Re-integration of automated test coverage reports (sustained >70%) * Integrations and Operational Helpers - * Integrated log rotation settings with safe defaults - * Improved Ansible Integrations via API and Contexts - * Endpoint bootstrapping workflows (was beta in v4.2) + * Integrated log rotation settings with safe defaults + * Improved Ansible Integrations via API and Contexts + * Endpoint bootstrapping workflows (was beta in v4.2) * Hardware Expansions - * Raspberry Pi Support (exposed via EdgeLab.digital) - * Netapp Solidfire and Cohesity Support (not in public catalog) + * Raspberry Pi Support (exposed via EdgeLab.digital) + * Netapp Solidfire and Cohesity Support (not in public catalog) diff --git a/doc/rel_notes/summaries/release_v44.rst b/doc/rel_notes/summaries/release_v44.rst index 7758bb1fc..552b7b9dc 100644 --- a/doc/rel_notes/summaries/release_v44.rst +++ b/doc/rel_notes/summaries/release_v44.rst @@ -58,16 +58,16 @@ Other Items of Note * Cloud Wrap - standardizes patterns to create cloud instances using Contexts with Terraform and Ansible. * Prototype Terraform Provider - enables use of the Pooling API via Terraform * UX Enhancements - * Significant UX performance rendering improvements - helpful for large scale and systems that are under stress due to error storms - * Select entire row instead of just checkbox - * Improve claimed editing - * Improve editing panels and pages - * Content pack differencing + * Significant UX performance rendering improvements - helpful for large scale and systems that are under stress due to error storms + * Select entire row instead of just checkbox + * Improve claimed editing + * Improve editing panels and pages + * Content pack differencing * Backup Enhancements - improved tooling around server backups and diagnostics * Workflow timeout - allows operators to determine if a workflow has stalled * Agent auto-update - Agent can upgrade itself. This is very helpful for agents embedded in image deploys and containers. * Additional Operating Systems - * Debian 10 - * Centos 8 / RHEL 8 - * Ubuntu 20.04 -* Moved into open ecosystem: Cohesity and Solidfire Support \ No newline at end of file + * Debian 10 + * Centos 8 / RHEL 8 + * Ubuntu 20.04 +* Moved into open ecosystem: Cohesity and Solidfire Support diff --git a/doc/rel_notes/summaries/release_v45.rst b/doc/rel_notes/summaries/release_v45.rst index 451cbd417..3be10d435 100644 --- a/doc/rel_notes/summaries/release_v45.rst +++ b/doc/rel_notes/summaries/release_v45.rst @@ -74,6 +74,18 @@ To leverage the new SL8, add the enabling SL8 profile in your workflow. Note: SL8 is expected to become default in DRP v4.6. A profile will be provided the enable backwards SL7 support. +.. _rs_release_v45_backup: + +WAL Backup +~~~~~~~~~~ + +DRP v4 introduced the WAL transcation log data store for Digital Rebar data. This critical core change has enabled endpoint replication features such as muiti-site and high availably. In this release, RackN added additional tooling to help operators make backups of the WAL. + +Operators can now use the `dr-backup` utility to capture DRP snapshots of live systems with confidence that they will detect and work with system transaction boundaries. It can also be used remotely to ensure off-system and test convenience backups. + +Operators are advised to migrate all backup operations to this new utility since it is more reliable than capturing the state of the file system. + + .. _rs_release_v45_log_capture: Log Capture @@ -126,5 +138,5 @@ Other Items of Note * Improved stability for self-runner bootstrapping agent * Improved data collection and communication within HA clusters * Web UX - * Improved Params update from Machines List view including setting secure values - * Numerous rendering and edit page fixes + * Improved Params update from Machines List view including setting secure values + * Numerous rendering and edit page fixes diff --git a/doc/rel_notes/summaries/release_v46.rst b/doc/rel_notes/summaries/release_v46.rst index b499e232e..abfeb3cc3 100644 --- a/doc/rel_notes/summaries/release_v46.rst +++ b/doc/rel_notes/summaries/release_v46.rst @@ -61,4 +61,4 @@ Planned, not committed Other Items of Note ~~~~~~~~~~~~~~~~~~~ -* TBD \ No newline at end of file +* TBD diff --git a/doc/upgrade.rst b/doc/upgrade.rst index 3439c5ad7..c70fd0a82 100644 --- a/doc/upgrade.rst +++ b/doc/upgrade.rst @@ -513,7 +513,7 @@ Please see the `Release Notes # Workflow to assign to the DRP's self machine as install finishes # This is only valid with create-self object + --initial-profiles= + # Initial profiles to add to the DRP endpoint before starting the workflow + # This is only valid with create-self object --initial-contents= # Initial content packs to deliver, comma separated list. # A file, URL, or content-pack name + --initial-plugins= + # Initial plugins to deliver, comma separated list. + # A file, URL, or content-pack name + --initial-parameters= + # Initial parameters to set on the system. Simple parameters + # as a comma separated list. --bootstrap # Store the install image and the install script in the files bootstrap --drp-id= # String to use as the DRP Identifier (only with --systemd) --ha-id= # String to use as the HA Identifier (only with --systemd) @@ -119,7 +128,8 @@ DEFAULTS: | container-type = $CNT_TYPE | container-name = $CNT_NAME | container-netns = $CNT_NETNS | container-restart = $CNT_RESTART | bootstrap = false | initial-workflow = unset - | initial-contents = unset | systemd-services = unset + | initial-contents = unset | initial-profiles = unset + | initial-plugins = unset | systemd-services = unset | ha-enabled = false | ha-address = unset | ha-passive = false | ha-interface = unset | ha-token = unset @@ -159,7 +169,10 @@ KEEP_INSTALLER=false CONTAINER=false BOOTSTRAP=false INITIAL_WORKFLOW= +INITIAL_PROFILES= +INITIAL_PARAMETERS= INITIAL_CONTENTS= +INITIAL_PLUGINS= SYSTEMD_ADDITIONAL_SERVICES= START_LIMIT_INTERVAL=5 START_LIMIT_BURST=100 @@ -218,7 +231,10 @@ while (( $# > 0 )); do --local-ui) LOCAL_UI=true ;; --remove-rocketskates) REMOVE_RS=true ;; --initial-workflow) INITIAL_WORKFLOW="${arg_data}" ;; + --initial-profiles) INITIAL_PROFILES="${arg_data}" ;; + --initial-parameters) INITIAL_PARAMETERS="${arg_data}" ;; --initial-contents) INITIAL_CONTENTS="${arg_data}" ;; + --initial-plugins) INITIAL_PLUGINS="${arg_data}" ;; --drp-user) DRP_USER=${arg_data} ;; --drp-password) DRP_PASSWORD="${arg_data}" ;; --drp-id) DRP_ID="${arg_data}" ;; @@ -752,7 +768,8 @@ case $MODE in else if [[ ! -e rackn-catalog.json ]] ; then get $DRP_CATALOG - mv rackn-catalog.json rackn-catalog.json.gz + FILE=${DRP_CATALOG##*/} + mv ${FILE} rackn-catalog.json.gz gunzip rackn-catalog.json.gz fi SOURCE=$(grep "drp-$DRP_VERSION:::" rackn-catalog.json | awk -F\" '{ print $4 }') @@ -974,11 +991,51 @@ EOF elif [[ $i == http* ]] ; then drpcli contents upload ${i} else - drpcli catalog item install ${i} --version=${DRP_CONTENT_VERSION} + drpcli catalog item install ${i} --version=${DRP_CONTENT_VERSION} -c $DRP_CATALOG + fi + done + fi + + if [[ "$INITIAL_PLUGINS" != "" ]] ; then + IFS=',' read -ra plugins_array <<< "$INITIAL_PLUGINS" + for i in "${plugins_array[@]}" ; do + if [[ -f ${OLD_PWD}/$i ]] ; then + drpcli plugin_providers upload ${OLD_PWD}/${i} + elif [[ $i == http* ]] ; then + drpcli plugin_providers upload ${i} + else + drpcli catalog item install ${i} --version=${DRP_CONTENT_VERSION} -c $DRP_CATALOG fi done fi + if [[ "$INITIAL_PROFILES" != "" ]] ; then + if [[ $CREATE_SELF == true ]] ; then + cp $(which drpcli) /tmp/jq + chmod +x /tmp/jq + ID=$(drpcli info get | /tmp/jq .id -r | sed -r 's/:/-/g') + rm /tmp/jq + IFS=',' read -ra profiles_array <<< "$INITIAL_PROFILES" + for i in "${profiles_array[@]}" ; do + drpcli machines addprofile "Name:$ID" "$i" >/dev/null + done + fi + fi + + if [[ "$INITIAL_PARAMETERS" != "" ]] ; then + if [[ $CREATE_SELF == true ]] ; then + cp $(which drpcli) /tmp/jq + chmod +x /tmp/jq + ID=$(drpcli info get | /tmp/jq .id -r | sed -r 's/:/-/g') + rm /tmp/jq + IFS=',' read -ra param_array <<< "$INITIAL_PARAMETERS" + for i in "${param_array[@]}" ; do + IFS="=" read -ra data_array <<< "$i" + drpcli machines set "Name:$ID" param "${data_array[0]}" to "${data_array[1]}" >/dev/null + done + fi + fi + if [[ "$INITIAL_WORKFLOW" != "" ]] ; then if [[ $CREATE_SELF == true ]] ; then cp $(which drpcli) /tmp/jq @@ -1012,7 +1069,7 @@ EOF check_drp_ready if [[ "$NO_CONTENT" == "false" ]] ; then - drpcli catalog item install task-library --version=${DRP_CONTENT_VERSION} + drpcli catalog item install task-library --version=${DRP_CONTENT_VERSION} -c $DRP_CATALOG if [[ "$INITIAL_CONTENTS" != "" ]] ; then IFS=',' read -ra contents_array <<< "$INITIAL_CONTENTS" @@ -1022,11 +1079,51 @@ EOF elif [[ $i == http* ]] ; then drpcli contents upload ${i} else - drpcli catalog item install ${i} --version=${DRP_CONTENT_VERSION} + drpcli catalog item install ${i} --version=${DRP_CONTENT_VERSION} -c $DRP_CATALOG + fi + done + fi + + if [[ "$INITIAL_PLUGINS" != "" ]] ; then + IFS=',' read -ra plugins_array <<< "$INITIAL_PLUGINS" + for i in "${plugins_array[@]}" ; do + if [[ -f ${OLD_PWD}/$i ]] ; then + drpcli plugin_providers upload ${OLD_PWD}/${i} + elif [[ $i == http* ]] ; then + drpcli plugin_providers upload ${i} + else + drpcli catalog item install ${i} --version=${DRP_CONTENT_VERSION} -c $DRP_CATALOG fi done fi + if [[ "$INITIAL_PROFILES" != "" ]] ; then + if [[ $CREATE_SELF == true ]] ; then + cp $(which drpcli) /tmp/jq + chmod +x /tmp/jq + ID=$(drpcli info get | /tmp/jq .id -r | sed -r 's/:/-/g') + rm /tmp/jq + IFS=',' read -ra profiles_array <<< "$INITIAL_PROFILES" + for i in "${profiles_array[@]}" ; do + drpcli machines addprofile "Name:$ID" "$i" >/dev/null + done + fi + fi + + if [[ "$INITIAL_PARAMETERS" != "" ]] ; then + if [[ $CREATE_SELF == true ]] ; then + cp $(which drpcli) /tmp/jq + chmod +x /tmp/jq + ID=$(drpcli info get | /tmp/jq .id -r | sed -r 's/:/-/g') + rm /tmp/jq + IFS=',' read -ra param_array <<< "$INITIAL_PARAMETERS" + for i in "${param_array[@]}" ; do + IFS="=" read -ra data_array <<< "$i" + drpcli machines set "Name:$ID" param "${data_array[0]}" to "${data_array[1]}" >/dev/null + done + fi + fi + if [[ "$INITIAL_WORKFLOW" != "" ]] ; then if [[ $CREATE_SELF == true ]] ; then cp $(which drpcli) /tmp/jq