Re: set_remote() <-> get_local()?

2017-06-08 Thread Cory Johns
get/set_remote deal with relation data sent over the wire.  get/set_local
never leave the unit in question and are simply there as a way to associate
information locally with a given remote unit.  Generally speaking,
get/set_local aren't actually what you want, and I wouldn't recommend using
them.  As for their implementation, get/set_local are basically just
calling charmhelpers.core.unitdata.kv().get/set with a key derived from the
conversation (e.g., the relation name and remote unit name), which stores
data in a local sqlite database.

On Wed, Jun 7, 2017 at 11:27 PM, fengxia  wrote:

> Hi Juju,
>
> provide and require are two ends of a pipe. If I use set_remote() from
> provide, require side can use get_remote() to retrieve the exchanged data.
> My question is, from require's prospective, shouldn't it be "get_local"?
>
> When provide set_remote or set_local, where is the data stored, and how
> require knows to retrieve it?
>
> --
> Feng xia
> Engineer
> Lenovo USA
>
> Phone: 5088011794
> fx...@lenovo.com
>
> Lenovo.com
> Twitter | Facebook | Instagram | Blogs | Forums
>
>
> --
> Juju mailing list
> Juju@lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailm
> an/listinfo/juju
>
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: Does relation scopes need to match?

2017-06-08 Thread Cory Johns
The original intention of conversations and scopes was to simply certain
interface interaction patterns where it may not be relevant or useful on
your end of the relation to deal with each remote unit individually.  An
example might be if the remote service is expected to have a leader which
speaks for all the units (SERVICE scope), or subordinates where you are
guaranteed to only ever have a single remote unit (GLOBAL scope).  When in
doubt, you can always use UNIT scope (which is the default) and treat the
list of conversations as a list of all of the remote units on the relation.

The effect of SERVICE scope is to merge the received data from remote units
on a per-remote-service basis, and the effect of GLOBAL scope is to both
merge received data from all remote units and to send the same data to all
connected relations.  The scope that one end of a relation uses has no
effect on the other end of the relation.

The error that you got seems like you performed an upgrade-charm after
changing the scope of the interface layer.  There is persisted context used
to associate states with individual remote units based on the scope which
does not deal well with such a change.  You will need to redeploy if you
change the scope of a interface layer.

On Wed, Jun 7, 2017 at 9:27 PM, fengxia  wrote:

> Just to clarify my question. I know the official doc of these scopes, that
> data are broadcasted in GLOBAL and UNIT is maintained as 1-to-1. What I'd
> like to know is when we should use GLOBAL, and when to use UNIT? When I
> deploy multiple units of a charm, does it mean its end of relation must use
> UNIT? if so, what about the provide end, should it be UNIT? GLOBAL? SERVICE?
>
>
>
> On 06/07/2017 09:22 PM, fengxia wrote:
>
>> Hi Juju,
>>
>> I'm learning to write a relation. One thing that's puzzling to me is the
>> scope. The question is, must provide and require use the same scope?
>>
>> For experiment, I have a scope.GLOBAL provide and scope.UNIT require. In
>> deployment, there is one provide unit and three require units. In this
>> setup, I was able to call set_remote() from provide side to pass a dict to
>> require side (get_remote()).
>>
>> However, if I change provide to be scope.UNIT also, it generated an error:
>>
>> unit-A-52: 21:15:44 INFO unit.A/52.b-relation-joined ValueError:
>> Conversation with scope 'b/120' not found
>>
>> Could you elaborate what the behavior should be when these scopes
>> selected on either side?
>>
>> | provides | requires |
>> | GLOBAL   | GLOBAL   |
>> | UNIT | UNIT |
>> | GLOBAL   | UNIT |
>>
>>
> --
> Feng xia
> Engineer
> Lenovo USA
>
> Phone: 5088011794
> fx...@lenovo.com
>
> Lenovo.com
> Twitter | Facebook | Instagram | Blogs | Forums
>
>
> --
> Juju mailing list
> Juju@lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailm
> an/listinfo/juju
>
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: Is base64 really the best way to use complex config values

2017-06-08 Thread Tilman Baumann
On 08.06.2017 13:39, Stuart Bishop wrote:
> It is only popular because people keep cargo culting it
> into their charms when it is unnecessary. I always call it out in
> reviews and get people to switch to unencoded text.

On the topic of cargo-culting.
I'm re-writing a charm right now. Partly because I must. But also partly
because I slightly disagree with the approach taken. (Simplicity vs.
future proofing)

Question.
In upgrade-charm, can I see from which version I'm coming? I need to do
cleanup when coming from a older version. I have other ways of detecting
that, but would be cool if it had a similar logic to dpkg postinst where
I get told where I'm coming from.

And how about changing config options? I like to split one option into
multiple. I could parse out the old values and transform them into the
new config fields. I don't expect that to be possible though.

What is the policy there. OK to break API? Can I remove options?
How will the user notice?


Cheers
 Tilman

-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: How to count relations?

2017-06-08 Thread Cory Johns
Alex,

I should clarify, conv.scope should only be None if the class's scope is
GLOBAL.  Otherwise, it should be the name of the service or unit.  If the
scope is defined as SERVICE or UNIT and the conv.scope is None, it was a
bug, yes (but let's work to get rid of the confusing idea of scopes and
conversations anyway, instead).

On Wed, Jun 7, 2017 at 12:30 PM, Alex Kavanagh 
wrote:

>
>
> On Wed, Jun 7, 2017 at 4:44 PM, Cory Johns 
> wrote:
>
>> Alex beat me to it, but here's a marginally more complete example:
>> https://gist.github.com/johnsca/a91cb5897d92dfb6741ee1a09d82b39b
>>
>> The key points are:
>>
>> * The interface needs to be UNIT scoped (because you care about
>> individual units)
>> * The joined handler sets a state for each unit that joins
>> * The @when('rel.connected') predicate in the charm layer matches all
>> units that have had that state set, so the set of conversations in the
>> interface layer includes those units, and only those units.  This is
>> trivially all of the units in my example, but you could also set a
>> different state in a -changed handler based on data sent by each remote
>> unit, and the conversations would only include the units that had that
>> specific state set when you matched that state using @when
>>
>> Alex: A conversation will always have a scope, so that list comprehension
>> isn't necessary.
>>
>
> Ah, interesting Cory.  It must have been a bug then; I ran into a
> situation where scope was None and had to filter it out; maybe I can remove
> that check from the interface I wrote (manila-plugin).
>
> Thanks!
> Alex.
>
>
>> On Wed, Jun 7, 2017 at 11:38 AM, Alex Kavanagh <
>> alex.kavan...@canonical.com> wrote:
>>
>>> Hi
>>>
>>> I'm assuming you are using charms.reactive; if not then look into
>>> relation_ids command.
>>>
>>> In your interface, count the number of conversations that have a scope
>>> set to something other than None.  scope shouldn't be None, but I've had
>>> cases where it has been (it may have been a bug):
>>>
>>> So in the provider.py RelationBase derived class, something along the
>>> lines of:
>>>
>>> num = len([c for c in self.conversations() if c.scope])
>>>
>>> in a method would be a relatively simple way of doing it.
>>>
>>> (There may be better ways of doing this!)
>>>
>>> Cheers
>>> Alex.
>>>
>>> On Wed, Jun 7, 2017 at 4:22 PM, fengxia  wrote:
>>>
 Hi Juju,

 I'm building two charms and linking them with one relation, one charm
 ("A") will provide and the other ("B") will require.

 The deployment will have one "A" and three "B"s. How do I know all
 three Bs have joined? I'm thinking to use a counter in A's relation, then
 at relation-joined hook by B to add this counter. But set_remote() and
 set_local() didn't work. Not sure what's the right way to achieve this?


 --
 Feng xia
 Engineer
 Lenovo USA

 Phone: 5088011794
 fx...@lenovo.com

 Lenovo.com
 Twitter | Facebook | Instagram | Blogs | Forums
 9


 --
 Juju mailing list
 Juju@lists.ubuntu.com
 Modify settings or unsubscribe at: https://lists.ubuntu.com/mailm
 an/listinfo/juju

>>>
>>>
>>>
>>> --
>>> Alex Kavanagh - Software Engineer
>>> Cloud Dev Ops - Solutions & Product Engineering - Canonical Ltd
>>>
>>> --
>>> Juju mailing list
>>> Juju@lists.ubuntu.com
>>> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailm
>>> an/listinfo/juju
>>>
>>>
>>
>
>
> --
> Alex Kavanagh - Software Engineer
> Cloud Dev Ops - Solutions & Product Engineering - Canonical Ltd
>
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju


Re: Is base64 really the best way to use complex config values

2017-06-08 Thread Stuart Bishop
On 7 June 2017 at 23:22, Tilman Baumann  wrote:
> I see a lot of charms use base64 values in config parameters. Especially
> when the values are stuff like custom templates.
>
> Is this really the way to go? It may avoid shell quoting hell for
> parameters set via command line. (Usually trivial)
> But when set via --file option (which is clearly the better way with
> complex fields) then I have to say the 'here document' features of YAML
> are actually quite good.
>
> The problem I see with bas64 is that nobody can read it without decoding
> it every time.
>
> Opinions?

base64 is occasionally useful for binary data or text in arbitrary
encodings. It is only popular because people keep cargo culting it
into their charms when it is unnecessary. I always call it out in
reviews and get people to switch to unencoded text.

> Just as a example of what I mean:
> application: logstash-supportcloud
> charm: logstash-conf-d
> settings:
>   config:
> value: |
>filter {
>if [message] == "" {
>drop { }
>}
>}
>output {
>gelf {
>host => "foobar"
>port => "5002"
>}
>}

Yes, much better.  It involves teaching people the difference between
> and | in multiline yaml strings.

-- 
Stuart Bishop 

-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju