On 02/28/2014 10:00 AM, Ritesh Raj Sarraf wrote:
> Actually this is done on load, and before commit: checked against
> installed policy (defaults, references to other objects in the config,
> required attributes, syntax). More is to be implemented, as the
> verify() (should call it validate, rally) command is lacking currently
> and does not do a few things yet: check a portal IP exists on the
> server's interfaces, files and devices path are valid, etc.
> Well. Have them distinguished. :-)
> Validate() => To check the syntactical correctness of the data. (Is the
> IP Address in the correct syntactical format)
> Verify() => To check the authenticity of the data. (Is the IP Address
> existent on the server)
Interesting, I never thought of it this way explicitly, although it is
more or less what happens under the hood. I will take any opinion on the
topic as I have doubts myself re. the correct way to do things.
For now, at the time you import a configuration statement, you must go
through three step:
* The parser transforms it into an AST (parse_tree in the code). That
- All object names are recognized (target, fabric, lun, disk, etc.)
- Object identifiers (fileio, iscsi, etc.) and attribute names and
values fit the syntactic requirements.
- Tokens are categorized in object specifiers, attribute group names
* Nested statements from the AST are imported, and in the process:
- Matched against the policy data - a statement MUST match one
policy rule, always. The rule gives the loader information about
expected types (int, bytes, iqn) and default values or absence thereof
- Checked for object references coherency
- All values are normalized to an internal canonical format, that
ensure repeatability of load/dump operations: you can load one config
saying "size 1.0M; enable Yes" and an other "size 1M; enable true" and
they will have the same representation once dumped (size 1.0MB; enable yes).
- Each statement ends up being loaded as a ConfigTree instance in
Config.current (which hold teh current, "candidate" configuration). That
includes a bunch of information that you can retrieve from the API or
the cli: type, default value, required/optional, source statement info
(operation type and date for loading that statement, source metadata
i.e. for load operations file name and modification time, pointer to the
policy rule covering that configuration node etc.)
All of the above happen when you load or merge a config file, issue a
single statement from cli with the set command, etc.
Then, triggered either by commit, or manually using the "commit check"
command, pre-commit consistency checks are performed.
* A for now dummy verify() _should_ check IP addresses, existence of
devices and file paths, etc.
* All objects are checked again for missing required values (this is
delayed so you can craft configs in a temporary state, fithout filling
all the bits in a strict order and in one go - gives your more
flexibility). I am thinking of moving object references (like which
backend a LUN should use) to that step BTW.
A couple of other things might happen here, but out of the top of my
head, that's the rough process.
Now, this whole system is open to discussion. Should I move the
reference check to pre-commit instead of enforcing that at config
statement load time ? Are there some checks that the user should be able
to relax for flexibility reasons ? The guideline I use for now is that
you should be able to compose a configuration one one system, dump it
and load it on a production system, and only commit it there. So all
system-specific checks should be done during pre-commit, before we
compute the commit execution plan, the non-system specific checks being
done at load time (hence the reason why object references are checked
>> BTW Ritesh, as a package maintainer, what do you thinks would be the
>> best in the eventuallity we want to include rtslib + the lio cli only:
>> rename the rtslib package into say 'lio', including all API + the cli,
>> or split it in two packages (but the cli one would be tiny) ?
> Today, for the packages available in Debian, apart from targetcli,
> OpenStack (python-cinder) is the other suite that has a dependency on
> rtslib. Your library has been out for some time now, so I'm not sure who
> else have consumed it.
> As a package maintainer, it wouldn't cost me much as I can still derive
> both the packages from the same source archive (irrespective of the
> rename), provided the library interfaces remain the same.
> I'd suggest you merge them to one, name it as rtslib, and ship the tiny
> lio CLI along with it.
Mmmh. One problem here is the init sequence. With the lio cli, no need
for lio-utils anymore. The initscript will be included too. So that new
rtslib+configAPI+lio cli package would conflict with lio-utils, which is
required by the current targetcli, which also ull configshell BTW. So it
would make it impossible to install both targetcli+lio-utils and a
lio-cli enabled rtslib, which I think we should support at least during
some migration period, and for side-to-side debug/testing. I really
don't know how to best do it, or I should leave all of that up to