Issue with pkg_optional_binds

Hello,
I’m trying to use pkg_bind_optional feature and I’m unable to access the bind data even though instance has that data received in the census. Here is the context:

  • There are two service groups using different service group keys in the same ring.
  • Both the service groups are running the same package. Based on a toml value they have different post-configuration steps at the end of the run hook.
    *So if toml value=primary(something) then I’m doing a hab config apply of a toml that has the below in the run hook.
cat <<TOML > {{pkg.svc_data_path}}/config.toml
[token]
roottoken = "${ROOT_TOKEN}"
dr_token = ${dr_token}
TOML

hab config apply --user "{{cfg.svc_group_enc.user_key}}" "{{svc.service}}.{{svc.group}}@{{svc.org}}" "$(date +%s)" "{{pkg.svc_data_path}}/config.toml"
  * If the toml value=secondary then nothing. (No hab config apply)

Now

  • Here are the bind details in the plan
    pkg_exports=(
    [port]=listener.port
    [root-token]=token.roottoken
    [dr_token]=token.dr_token
    )
    pkg_exposes=(port)
    pkg_binds=(
    [backend]=“port-https”
    [backend]=“encrypt-token”
    )
    pkg_binds_optional=(
    [vaultend]=dr_token
    )

Now in the VM that has the toml value=secondary when I do a curl localhost:9631/census | jq . | grep dr_token I see the value I need. However in the run hook when i try {{bind.vaultend.cfg.dr_token}} or {{bind.vaultend.first.cfg.dr_token}} or use the service name instead like {{vault.dev_kiran_edc1@umarla_dev_org.cfg.dr_token}} I receive blank values (nothing). I have also tried this

{{#if bind.vaultend ~}}
              echo "bind found"
{{else ~}}
              echo "no bind found"
{{/if ~}}

Which always prints no bind found.

Is there something I’m missing here?

Thanks,
Kiran Marla

Can you show your hab svc load command? Specifically you need to add a --bind for the optional service in order for the consuming service to see its configuration data.

Sorry for the delay in response. Here is my service load command:

/bin/hab svc load umarla/vault --group dev_kiran_edc1 --channel app_dev --strategy at-once --topology leader --bind consul:consul.dev_kiran_edc1@umarla_dev_org

I’m not specifying the optional bind as a --bind because if I use a --bind for the optional bind and if the bind doesn’t exist then this breaks with “waiting on the service bind…”. Also it wouldn’t be optional if I have to specify the bind.
The problem is the other service group’s bind can either exist or not exist. And based on the binds existence I want to be able to do some configuration.

In order for habitat to know which service to bind to (optional or not) it needs the service group name passed via --bind. When you have an optional bind that just means excluding the bind will nor prevent the service from loading. But it looks like you have found yourself in a sore of “catch-22.” I think what you want to do is specify --binding-mode relaxed which will allow a service to load and start regardless of whether the specified binds are found in the ring. See https://www.habitat.sh/docs/developing-packages/#service-start-up-behavior-binding-mode. So in this case with --binding-mode relaxed, you would go ahead and supply --bind arguments for both your required and optional binds. The service will load and run whether or not the services they are asked to bind to are present. You will just want to make sure your hooks are written in such a way that they can gracefully handle the bound service being absent.

I updated the habitat and supervisor versions to 0.81 and then applied --binding-mode relaxed when I loaded the service and that worked.

Thanks,
Kiran