0.2.3.1
This section outlines the minimal procedure for setting up a deployment area.
It will include a pollwiki and two vote-servers: an offline server
(voff
) for test purposes, and an online server (v
)
for public use.
This procedure tests the vote-server by running a voter simulation
with the script vosim-alex
.
It also tests the difference bridge.
Ensure the database server
(postgres), pollwiki (apache) and web interface (tomcat) are all running. Ensure
you are logged into a terminal as user voff
.
The script vosim-alex
should be on your path. Do a
dry run with a small group of simulated test voters:
$
vosim-alex ab 1-3 # voters a1, a2, a3, b1, b2 and b3
test-a1@zelea.com Sys/p/sandbox vote test-a@zelea.com test-a2@zelea.com Sys/p/sandbox vote test-a@zelea.com test-a3@zelea.com Sys/p/sandbox vote test-a@zelea.com test-b1@zelea.com Sys/p/sandbox vote test-b@zelea.com test-b2@zelea.com Sys/p/sandbox vote test-b@zelea.com test-b3@zelea.com Sys/p/sandbox vote test-b@zelea.com
It ouputs a list of commands for the voter shell.
Execute these commands by piping them to the voter shell:
$
vosim-alex ab 1-3 | voter
Old value: none Sys/p/sandbox You were voting for: nobody You are now voting for: test-a@zelea.com No results are available for this poll. They have yet to be reported. (Administrator see 'vocount report'.) . . . and so on
Compile the voter list by tracing the trust network.
$
votrace
You ought to see 1 or more voter registers (XML files) under
~/votorola/out/votrace/_readyTrace_report/_mounted_trace/
. The content of
the registers is unimportant for this test, because we are using a
minimal configuration that counts the votes of registered and
unregistered users alike. Nonetheless the trace must be mounted.
Count the votes.
$
vocount
You should see a tie between two leading candidates (a and b), at 3 votes apiece:
Cast a vote for a new candidate.
$
voter test-v@zelea.com Sys/p/sandbox vote test-c@zelea.com
Sys/p/sandbox You were voting for: nobody You are now voting for: test-c@zelea.com test-v@zelea.com | | 1 | V test-c@zelea.com ---> 1 removed from flow The final recipient of the vote is test-c@zelea.com. . . .
Recount the votes.
$
vocount
Now hit refresh in your browser. You should see a new candidate (c) with a single vote.
Import some test pages to the pollwiki.
%
cd /WIKI-INSTALL-PATH/mediawiki/maintenance
%
php importDump.php /home/voff/votorola/_/test/minimalPollwikiPages.xml
Done! You might want to run rebuildrecentchanges.php to regenerate the recentchanges page.
%
php rebuildrecentchanges.php
Loading from page and revision tables... $wgRCMaxAge=604800 (7 days) Updating links and size differences... Loading from user, page, and logging tables... Flagging bot account edits... Flagging auto-patrolled edits... Done.
BUG: if this rebuild fails with database errors (seen on Mediawiki 1.18.2 and PostgreSQL 9.1.4), then ignore them. These are not critical errors.
Test the difference bridge. Start in the votespace browser where it shows the new voter (Test-v-ZeleaCom):
http://localhost:8080/voff/w/Votespace?p=Sys!p!sandbox&u=Test-v-ZeleaCom
To the left of that voter's name, click on the small link.
That should take you to the voter's position page in the pollwiki. At the top of that page, click on the link “Diff vs. candidate's”.
That should take you to a diff page, the text of which looks something like this:
Tv. Test-v-ZeleaCom Tc. Test-c-ZeleaCom [ Patch ] [ ] ----------------------------------------------------------------------------------------------------- frag 1 but perhaps there are more paragraphs yet to come? This is sentence 30 of our position draft. ↩ Tv. It is followed by sentence 31, ↩ which introduces this important amendment. ↩ Tc. It is followed by sentence 31. ↩ Sentence 31 is followed by sentence 32, ↩ which consists of two phrases. ↩ Next comes the third sentence of this paragraph which is numbered 33 in the overall position draft. ↩ [ ] ----------------------------------------------------------------------------------------------------- frag 2 here is sentence 97. ↩ Eighth place in this paragraph belongs to sentence 98. ↩ Sentence 99 appears last in the paragraph, ↩ Tv. but perhaps there are more paragraphs yet to come? ↩ No, ↩ I am afraid that's the end of it. Tc. but perhaps there are more paragraphs yet to come? [ Patch ]
Test the patch facility. Press the login
link at the
top right of the diff page, and login under alias
‘c’.
The controls on the diff page are now enabled as though you were
the candidate. Select frag 1
to accept the
“important amendment” from the voter. Then press
the Patch
button.
That effects the patch and takes you to the revision history of your (the candidate's) position draft. If the login handshake fails with result "NeedToken", then ensure the wiki script URI is specified with a fully qualified domain name.
[BUG: it will fail with "WrongPass". You must create an account in the wiki for "Vobot", and set the password to the default.]
In the revision history, ensure that the two most recent revisions
are selected, then press the Compare selected
revisions
button. A comparison page is shown. In that
page, you should see that the voter's proposed change
“which introduces this important amendment” was
incorporated into sentence 31.
That ends the test. When you are finished, you may want to run
vox-clean
to erase everything from the vote-server. First,
stop any running services such as the web interface:
%
/etc/init.d/tomcat-6 stop
Then inspect the script in your editor.
$
emacs `which vox-clean`
Ensure that each line of the clean()
subroutine is
uncommented so that all test data is erased. Then run it:
$
vox-clean
removing directory: /home/voff/votorola/out/votrace removing database schema: out_trace NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to table out_trace."2012-9m-1-membership-1" drop cascades to table out_trace."2012-9m-1-trace_node-1" drop cascades to table out_trace."2012-9m-1-trust_edge-1" DROP SCHEMA removing database table: in_vote DROP TABLE removing directory: /home/voff/votorola/out/vocount removing database schema: out_count NOTICE: drop cascades to table out_count."2012-9m-2-count_node-1" DROP SCHEMA List of schemas Name | Owner --------+---------- public | postgres (1 row) List of relations Schema | Name | Type | Owner --------+-----------+-------+------- public | geocode | table | voff public | store_wap | table | voff public | user | table | voff (3 rows)
Finally, restart the web interface:
%
/etc/init.d/tomcat-6 start
You should no longer see the registry's output directory
~/votorola/out/votrace/
,
nor any poll results in the web interface (hit refresh here):
After voff
is properly configured and tested,
you can easily set up the online vote-server v
.
This is the general pattern to follow for all software and configuration upgrades:
first test them offline, then transfer them online.
Simply repeat the setup procedure above,
but this time for vote-server v
.
Copy its initial configuration from voff
and amend all references to the vote-server name. To find all references:
$
find ~/votorola -name code -prune -o -name out -prune \
-o -type f -exec grep voff {} +
The pollwiki provides 1) a shared database among separate facilities of the voting network; 2) a default UI layer of views and controls onto the shared database; and 3) a default drafting medium for poll positions.
This is optional. We provide a multi-area reference pollwiki and it is recommended that you start with that. You may migrate to your own pollwiki later. However there is a BUG: your users won't be able to patch their differences, because the username Vobot is hard coded into the difference bridge and we cannot share the password. But just ask, and we'll fix this ASAP.
Follow the usual instructions in order to install the MediaWiki software, and get a basic wiki running. Do not create any pages until after you install Semantic MediaWiki (below).
During configuration, you are prompted for a “Wiki name”. This gives you a special namespace in the wiki for site-specific pages. The reference pollwiki simply uses the name ‘Site’. Choose any name, you can always change it later.
You are also prompted for a database password. If you are using PostgreSQL “trust” authentication then there is no password. Leaving the field blank seems to work in that case, despite the warning “must not be blank”.
Once the basic wiki is running and before creating any pages, install Semantic MediaWiki. Install whatever version is recommended, but it must be at least 1.7.1.
Note the special instructions for PostgreSQL.
Install extension MailishUsername.
That should be sufficient to start. Later you can refine the configuration by copying from other pollwikis. See also the working example in the appendix.
A vote-server is
a server that provides polls and other voter services.
A deployment area typically has a pair of vote-servers,
one for online public use, and one for offline testing.
Each vote-server has a separate account on the local host computer,
under which its data is stored and its processes are run.
The login name of this account is also known as
the vote-server name.
Conventional vote-server names are v
and voff
.
|
The vote-server is configured by its configuration script,
located in the votorola
directory (shown above).
The internal structure of the script is outlined in the figure below.
vote-server.js function constructingVoteServer( vsCC ) |
Each vote-server maintains a store of relational data, as shown in the figure below.
Unix is required. Although testing is currently limited to Linux, it should also work with other versions of Unix.
Java version 1.7 is required.
$
java -version
Create the votorola
group.
This will be the default group for all vote-server accounts.
%
groupadd votorola
Add yourself to the group.
%
usermod --append --groups votorola MYLOGIN
This is a convenience for editing the vote-server's files without having to login as such.
Download votorola-0.2.3.tar.gz
.
Unpack it.
%
tar --extract --gzip --file votorola-0.2.3.tar.gz --dir /opt
You may actually unpack it anywhere. This manual assumes the
/opt
directory.
If you happen to have unpacked a version other than 0.2.3, then follow its instructions from this point on.
Test one of Votorola's executables. This one lists the Java runtime properties. Test it the long way, first:
$
java -jar /opt/votorola-0.2.3/votorola/s/_/bin/voqproperties | sort
awt.toolkit=sun.awt.X11.XToolkit file.encoding.pkg=sun.io file.encoding=UTF-8 file.separator=/ . . .
Do not place these executables on the path yet. You'll do that later when you create a vote-server.
If Linux kernel option binfmt_misc
is enabled,
and if PK-Zip is already bound to execute Java JAR archives,
then you needn't type java -jar
in front
of each Votorola command. You may execute it directly, like this:
$
/opt/votorola-0.2.3/votorola/s/_/bin/voqproperties | sort
For instructions on enabling this, see the example script
jar-wrapper
.13
That is all. Votorola is now installed.
Create the vote-server's user account.
%
useradd voff --gid votorola --create-home
%
passwd voff
Set the file creation mask so that new files are writeable by the
votorola
group.4
For example, add this line to the vote-server's
~/.bashrc
:
umask 0002 # creation mask (0002), files writeable by login group (votorola)
While you are there, also add the following line. This places the example scripts and the standard Votorola commands on the vote-server's path:13
PATH=$HOME/votorola/bin:$HOME/votorola/code/votorola/s/_/bin:$PATH
You may want to add the vote-server to the database group.
%
usermod --append --groups postgres voff
Whether or not this is necessary depends on how the database
engine is configured. It will be necessary, for example, if
access to the engine's socket file is restricted to members of the
postgres
group. The typical location of the socket
file is /var/run/postgresql/.s.PGSQL.5432
.
Login as the vote-server.
$
whoami
voff
In the vote-server's home directory, create the
votorola
directory.
$
mkdir ~/votorola
In that directory, create a symbolic link to the code that was previously installed.
$
ln --force --no-deref --sym /opt/votorola-0.2.3/ ~/votorola/code
Copy over the minimal configuration from the examples that were bundled with the release.
$
cp -R ~/votorola/code/votorola/s/_/example/minimal/home/voff/votorola/* ~/votorola/
Ensure the I/O directories are writeable
by the votorola
group.4
$
chmod g+w ~/votorola/in ~/votorola/out
Test that Votorola's executables are accessible. For example:
$
voqproperties | sort
awt.toolkit=sun.awt.X11.XToolkit file.encoding.pkg=sun.io file.encoding=UTF-8 file.separator=/ . . .
If not, then look at the PATH
environment variable.
Also look at binfmt_misc
.
Test the logging configuration, with the help
of volog
.
$
volog
In a default Java installation, the log is usually output to the console.
Wherever it is output, you should see volog's
test messages:
Sep 22, 2012 8:59:36 PM votorola.s.line.VOLog main INFO: volog is running with arguments [] Sep 22, 2012 8:59:36 PM votorola.g.logging.LoggerX test OFF: testing SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST and ALL... Sep 22, 2012 8:59:36 PM votorola.g.logging.LoggerX test SEVERE: this is SEVERE Sep 22, 2012 8:59:36 PM votorola.g.logging.LoggerX test WARNING: this is a WARNING Sep 22, 2012 8:59:36 PM votorola.g.logging.LoggerX test INFO: this is INFO
You may want to increase the verbosity level for the offline vote-server
from INFO
to at least CONFIG
.
And you may want to log the messages to files, and not just the console.
Refer to the discussion of
logging configuration
in the examples appendix.
Ensure the database server (postgres) is running.
Run a smoke test on a poll.
$
voter Sys/p/sandbox hello
hello
$
voter test-a@zelea.com Sys/p/sandbox vote test-b@zelea.com
. . . You were voting for: nobody You are now voting for: test-b@zelea.com No results are available for this poll. They have yet to be reported. (Administrator see 'vocount report'.)
$
voter test-a@zelea.com Sys/p/sandbox unvote
. . . You were voting for: test-b@zelea.com You are now voting for: nobody . . .
That is all. The vote-server is now created.
Download the new version of Votorola.
Unpack it.
%
tar --extract --gzip --file votorola-VERSION.tar.gz --dir /opt
Stop any processes that are running for the offline vote-server.
Unreport and unmount any mounted counts and lists.2
$
vocount ureport && vocount umount --verbose
$
votrace ureport && votrace umount --verbose
At this point, ensure you are reading from the new version of the software manual.
If you are deploying the web interface, then ensure no user sessions are persisted from the old version of Votorola:
%
(save=/tmp/var_run_tomcat-6_Catalina/; \
rm --force --recursive $save && mv /var/run/tomcat-6/Catalina/ $save)
(Here's the script of that.) Otherwise Tomcat may experience serialization errors at next startup as it tries to recover sessions from the previous run.3
Link to the newly installed code.
$
ln --force --no-deref --sym /opt/votorola-VERSION/ /home/voff/votorola/code
Read the top entry
in /home/voff/votorola/code/votorola/changes.xht
.
Update your configuration, if necessary.
Remount any lists and counts that were unmounted, above.
Restart any voter interface processes that were stopped, above.
The file server provides the file storage and communication interface of a vote-server's public archives. The main purpose of the public archives is to support the verification of poll results. A secondary purpose is to store backup data, as insurance against a database loss.9
The database server provides one or more databases for each vote-server. Databases contain administrative data, voter input, and mounted traces and counts. Votorola requires the PostgreSQL database management system (DBMS), version 9.1 or later.
The database cluster must be installed with a UTF-8 character encoding. According to Semantic MediaWiki's installation instructions, it is not enough to install a non-UTF-8 cluster with UTF-8 databases. Note also the additional configuration step for PostgreSQL 9.
This assumes that a PostgreSQL DBMS is already installed on the database server, as described above.
Start the DBMS process (postmaster
)
on the database server.
From the server, ensure you are logged into Linux as a DBMS superuser.
If root
has not been made a DBMS superuser,
then login as postgres
.
%
su - postgres # if necessary
Create a DBMS account for the vote-server, under the same user name.
%
createuser voff
When prompted, answer ‘no’ to special user permissions for creating databases, other users, and so forth. None of these are needed by the vote-server.
Create a vote-server database, with the same name as the vote-server.
%
createdb --owner=voff voff
votorola/s/line/
votorola.s.line
This section concerns the command-line administrative interface. Following are the details for each command provided by the interface.
vocount [--verbose] [--etc[=ready|mount|report|umount]] vocount snap [--verbose] [--etc[=ready|mount|report|umount]] [--churn] vocount ready [--verbose] [--etc[=mount|report|umount]] [~/votorola/out/vocount/snap-YYYY-MD-S] vocount mount [--verbose] [--etc[=report|umount]] [--churn] [~/votorola/out/vocount/snap-YYYY-MD-S/readyCount-S] vocount report [--verbose] [--etc] [~/votorola/out/vocount/snap-YYYY-MD-S/readyCount-S] vocount umount [--verbose] [~/votorola/out/vocount/snap-OLD-YYYY-MD-S/readyCount-OLD-S] vocount ureport [--verbose] vocount status vocount --help
Tool vocount
counts the votes
and makes the results available for other tools and processes.
It does this in separate, staged invocations, with these action arguments:
If no action is specified, the default is to carry out all actions
from snap
through umount
.
The following commands are therefore equivalent:
$
vocount
$
vocount snap --etc=umount
Repeated invocations of mount
/umount
will always generate the same results.
The results depend only on the archival
snap/readyCount record
that was created by the previous invocation of snap
/ready
.
Thus the snap/readyCount record alone is sufficient to do a recount,
and anyone obtaining a copy may use it to verify the reported results.
|
|
~/votorola/out/vocount/snap-YYYY-MD-S
snap
action.
It stores within that directory any administrative input that may be needed
by subsequent mount
actions,
such as special configuration for the count compiler.
In the process it creates a new ready directory,
the path of which it prints to standard out:
~/votorola/out/vocount/snap-YYYY-MD-S/readyCount-S
readyTrace
is also created.
It points to the snap/readyTrace record of the currently reported trace of the trust network.
It is created as a copy of the symbolic link
_readyTrace_report
,
which must already exist.
~/votorola/out/vocount/snap-YYYY-MD-S/readyCount-S/readyTrace
snap
or ready
action.
ready
action.
It reads the stored voter and administrative input.
It dereferences the symbolic link to the snap/readyTrace record
(which must already be mounted as a compiled trace),
and uses it to check the eligibility of voters.
It cascades and sums the votes, and finally writes the results
to the database and filebase for other tools and processes to read.
~/votorola/out/vocount/_readyCount_report -> snap-YYYY-MD-S/readyCount-S ~/votorola/out/vocount/_snap_report -> snap-YYYY-MD-S
mount
action,
erasing the results from the database and filebase.
The snap/readyCount record is not deleted, but remains available for remounting.
report
action,
unlinking the _readyCount_report
and _snap_report
links, so that no results are reported.
$
vocount status
M /home/voff/votorola/out/vocount/snap-2011-bj-1/readyCount-1 /home/voff/votorola/out/vocount/snap-2011-bk-1/readyCount-1 MR /home/voff/votorola/out/vocount/snap-2011-bl-1/readyCount-1
M |
mounted |
---|---|
R |
reported |
$
vocount snap --etc=mount
$
vocount snap
$
vocount ready
$
vocount mount
--etc
is specified
without an end-action, then it defaults to umount
.
--verbose
is in effect,
then all actions print their output as usual.
Unlike a mounted file system, a mounted count persists across system re-starts until explictly unmounted. So ‘mount’ is something of a misnomer.
cat MESSAGE-FILE | vodeliver [maildir:INBOX-PATH | INBOX-URL]
cat MESSAGE-FILE | vodeliver # to voface-mail inbox
vodeliver --help
Test tool vodeliver
delivers an email test message to an
inbox. It reads the message from standard input, and writes it to the
inbox.
If no INBOX-URL is specified, the default is the inbox
specified by the configuration of voface-mail
. Note that this bypasses
voface-mail
's authentication layer.
voface-mail [--help]
Process voface-mail
is the primary process
of the mail-based voter interface.
It implements the response layer of the interface;
waiting for email messages to arrive from voters, and responding to them.
For each message delivered to the inbox, it parses it into separate commands;
relays each command to the voter service; and transmits the reply back to the voter.
voharvest [--verbose] remove PAGE_NAME_OF_ARCHIVE_IN_POLLWIKI remove all messages of an archive update PAGE_NAME_OF_ARCHIVE_IN_POLLWIKI* update a particular forum voharvest [--help]
The command line tool voharvest
can harvest off-site messages
containing difference Urls to the difference bridge. The gathered messages
are then shown through a dedicated TalkTrack in the Stage. It also allows
to do maintenance on the harvested messages, e.g. removing all messages of an
archive.
Simple list compiler volist
has been replaced
by trust tracer votrace
which works in conjunction with external streetwikis.
Command vocomp
will later be introduced for compiling complex lists
that pull in non-residential and non-trust properties from other sources.
volog [--help]
Test tool volog
outputs messages to the log,
one for each of the standard logging levels.
It serves to verify the logger's configuration.
vomir vomir --help
Experimental tool vomir
is a prototype of a
pull-mode autocaster. It is not properly documented. See the
VOMir javadocs.
vonop
Command vonop
does nothing.
voqproperties | sort voqproperties --help
Test tool voqproperties
writes the runtime properties
of the Java virtual machine to standard output.
voscript SCRIPT-FILE voscript --help
Interpreter voscript
tests the compilation of a configuration script
using the JavaScript engine. The SCRIPT-FILE must be encoded in UTF-8
(or equivalently US-ASCII).
Voscript
provides the same include facility as the Votorola runtime.
A script may load other JavaScript files, pulling them into the compilation,
using a function call such as this:
vo.inc( '/home/voff/my-module.jsm' );
The filepath may be absolute, or relative to the including file. Shell variables in the filepath ($NAME) or expressions such as tildes (~) are not expanded.
voter [--id=ID|VOTER-EMAIL] SERVICE-NAME COMMAND [OPTION...] [ARGUMENT...] voter < ARGUMENT-FILE cat ARGUMENT-FILE | voter voter SERVICE-NAME help voter --help
Command shell voter
issues a service command on behalf of a voter.
The SERVICE-NAME identifies the service.
It may be an ordinary service
(registry or poll),
or the meta-service of the mail-based voter interface
(if any is configured).
The command is dispatched directly to the service's command/resonse interface,
bypassing the usual voter interface (mail or Web).
The reply is printed to standard output.
The personal identifier (--id
or VOTER-EMAIL) is
taken as the authentic issuer when carrying out the COMMAND.
The --id
may be in the form of either an email address or a
mailish
username. Neither is required if the command happens to allow for
anonymous issue. Here's an example of a help
command issued
anonymously to a poll named ‘mayor’:
voter mayor help
Any OPTIONS or ARGUMENTS following the COMMAND
are passed to the service's command responder.
The --help
option below, for example,
does not request help regarding the voter
shell,
but regarding the poll's vote
command:
voter --id=test-a@zelea.com mayor vote --help
With neither SERVICE-NAME, COMMAND nor other
arguments, voter
reads multiple lines from standard input and
executes them in sequence. The input must be encoded in UTF-8, or
equivalently US-ASCII. For example:
vosim-alex ab 1-3 | voter
Use vodeliver
to deliver
a command via the mail-based voter interface, instead of directly.
votrace [--verbose] [--etc[=ready|mount|report|umount]] votrace snap [--verbose] [--etc[=ready|mount|report|umount]] [--churn] votrace ready [--verbose] [--etc[=mount|report|umount]] [--churn] [~/votorola/out/votrace/snap-YYYY-MD-S] votrace mount [--verbose] [--etc[=report|umount]] [~/votorola/out/votrace/snap-YYYY-MD-S/readyTrace-S] votrace report [--verbose] [--etc] [~/votorola/out/votrace/snap-YYYY-MD-S/readyTrace-S] votrace umount [--verbose] [~/votorola/out/votrace/snap-YYYY-MD-S/readyTrace-S] votrace ureport [--verbose] votrace status votrace --help
Tool votrace
traces a neighbourhood trust network,
calculates trust levels, compiles a residential register,
and makes these available for other tools and processes.
It does this in separate, staged invocations, with these action arguments:
If no action is specified, the default is to carry out all actions
from snap
through umount
.
The following commands are therefore equivalent:
$
votrace
$
votrace snap --etc=umount
Repeated invocations of mount
/umount
will always generate the same trace.
The content of the trace depends only on the archival
snap/readyTrace record
that was created by the previous invocation of snap
/ready
.
Thus the snap/readyTrace record alone is sufficient to do a re-compilation,
and anyone obtaining a copy may use it to verify the reported trace.
|
~/votorola/out/votrace/snap-YYYY-MD-S
snap
action.
It stores within that directory any administrative input that may be needed
by subsequent mount
actions,
such as special configuration for the network tracer and list compiler.
In the process it creates a new ready directory,
the path of which it prints to standard out:
~/votorola/out/votrace/snap-YYYY-MD-S/readyTrace-S
snap
or ready
action.
ready
action.
It reads the stored registrant and administrative input,
traces the neighbourhood trust network, and writes the results
to the database and filebase for other tools and processes to read.
~/votorola/out/votrace/_readyTrace_report -> snap-YYYY-MD-S/readyTrace-S ~/votorola/out/votrace/_snap_report -> snap-YYYY-MD-S
mount
action,
erasing the trace from the database and filebase.
The snap/readyTrace record is not deleted, but remains available for remounting.
report
action,
unlinking the _readyTrace_report
and _snap_report
links, so that no trace is reported.
$
votrace status
M /home/voff/votorola/out/votrace/snap-2011-bj-1/readyTrace-1 /home/voff/votorola/out/votrace/snap-2011-bk-1 /home/voff/votorola/out/votrace/snap-2011-bl-1/readyTrace-1 /home/voff/votorola/out/votrace/snap-2011-bl-1/readyTrace-2 MR /home/voff/votorola/out/votrace/snap-2011-bl-1/readyTrace-3
M |
mounted |
---|---|
R |
reported |
$
votrace snap --etc=mount
$
votrace snap
$
votrace ready
$
votrace mount
--etc
is specified
without an end-action, then it defaults to umount
.
--verbose
is in effect,
then all actions print their output as usual.
Unlike a mounted file system, a mounted trace persists across system re-starts until explictly unmounted. So ‘mount’ is something of a misnomer.
votorola/a/register/
votorola.a.register
This section is obsolete. The design has shifted over to streetwikis and trustservers, and the admin manual has yet to be updated.
Each deployment area provides a voter registry, from which its voter lists are compiled. The voter registry is a public repository of user-specific attributes and inter-user trust edges. The user-specific attributes serve to record the eligibility credentials that are claimed by each user, while the inter-user trust edges serve to authenticate the claims. The collection of all attributes for a particular user comprises that user's registration. Each registration is keyed by email address, which serves as the primary user identifier.10
Voter input to a registry is synchronized throughout. The purpose of synchronization is single registration. Voters register at their local areas, as shown in the figure above. The registration data is then streamed from the local areas to higher juridictional areas, and thence throughout. So voters may register once and be eligible for polls at all jurisdictional levels.
Configuration is specified by startup and runtime scripts located in the registry's service directory (shown above). The internal structure of the scripts is outlined in the figures below.
register.js function constructingRegister( regCC ) |
register-run.js - Compiling a Voter List ----------------------------- function indexingListEntry( listIC ) - Trust Network -------------------------------------- function extendingTrust( trustEC ) function trustBarUnregistered( destinationEmail, registerUID ) |
The registry also maintains a store of relational data, as shown in the figure below.
The minimal configuration
already includes a registry. It will suffice for a minimal setup.
Test it first, using the voter
command shell.
$
voter register hello
hello
$
voter test-a@zelea.com register set residence 170 Main Street, M1M 1A1
Old value: none New value: 170 Main Street, M1M 1A1
$
voter test-a@zelea.com register unset residence
Old value: 170 Main Street, M1M 1A1 New value: none
It should respond as shown above.
A voter list is a snapshot copy of the register
in which the network of trust edges is traced,
and each voter's registration is evaluated at a particular level of trust.
The compilation of the lists is configured
by the runtime script register-run.js
.
register-run.js - Compiling a Voter List ----------------------------- function indexingListEntry( listIC ) |
To compile a voter list, use the tool volist
:
$
nice volist
Lists may be compiled either one at a time,
or repeatedly at scheduled intervals.6
Each newly compiled list creates a new
snap/readyList record in the output filestore.
For a quick overview of the records in the filestore, use volist status
:
$
volist status
/home/voff/votorola/out/volist/snap-2011-bh-1/readyList-1 /home/voff/votorola/out/volist/snap-2011-bi-1/readyList-1 MR /home/voff/votorola/out/volist/snap-2011-bj-1/readyList-1
The newly compiled list is automatically mounted (M) and reported (R), making it immediately visible in all voter interfaces. At the same time, all previous lists are unmounted. To revert to one of the previous lists, simply remount it and re-report it. For example:
$
nice volist mount --etc \
~/votorola/out/volist/snap-2011-bi-1/readyList-1
$
volist status
/home/voff/votorola/out/volist/snap-2011-bh-1/readyList-1 MR /home/voff/votorola/out/volist/snap-2011-bi-1/readyList-1 /home/voff/votorola/out/volist/snap-2011-bj-1/readyList-1
Much like count records, list records will require
occasional cleaning or archiving.
It is best to clean the count records first, because you must be careful afterwards
not to break the readyList
links
of those that remain. When cleaning the list records,
you must avoid deleting the referents of those links.
(It is usually safe to delete all records in a particular date range,
unless you know that counts were tallied against older lists.)
votorola/a/register/trust/
votorola.a.register.trust
The trust network is a directed graph of user-to-user trust edges that are extended by the users for the purpose of cross-authenticating the voter registry. Individual trust edges are stored as public input to the registry. During compilation of a voter list, the edges are traced to determine the level of trust for each particular registration. These levels are then incorporated into the resulting voter list.11
A trust edge extends from one registrant (source node) to another (destination node). It pertains to the following attributes of the latter's registration (D):
The trust edge asserts, “Yes. That's the email address of my neighbour across the street, and she really does live there.” More formally:
A given source node may extend trust to any number of destination nodes
(subject to any bars imposed by the configuration),
but may extend at most one edge to each. The extension of trust
is configured and controlled by the runtime script register-run.js
.
register-run.js - Trust Network -------------------------------------- function extendingTrust( trustEC ) function trustBarUnregistered( destinationEmail, registerUID ) |
In a fully elaborated network, each destination node is evaluated at a particular level of trust, which is recorded in its entry in the voter list. The recorded level (t) depends exclusively on the levels among the source nodes, where it is calculated as the highest level that does not exceed the count n(t) of sources at that level or higher. In other words, to have a trust level of 3, a voter must have 3 or more immediate trust sources, each itself having a trust level of 3 or higher.
t ≤ n(t)
The ultimate trust source is the root node, which is the registrar. All trust edges must be traceable to the root, otherwise they are discounted in the elaborated network. Unlike an ordinary node, the root has a high (effectively infinite) trust level, and it may extend any number of edges (primary trust edges) to the same destination.
The maximum trust level in the network, max(t), is limited both by the redundancy of primary edges, and by the number and distribution of primary destinations. As a rule, to attain a network with a max(t) of 3 requires a minimum of 3 destinations, with a minimum of 3 edges to each. Furthermore, in order for the primary destinations to propagate max(t) to other voters, at least max(t) of them must cooperate as a group in extending their edges to further destinations. In practice therefore, the primary destinations must be grouped such that:
register-run.js
.
A typical register-run.js
will impose range limits on trust extension.
Network activity is thus localized to neighbourhood scales,
where it may be moderated by everyday social constraints.
Rogue sources may not inject trust from afar,
and be shielded by distance from the fallout.
All trust is locally traceable and locally accountable.
(The range limits imposed on individual edges must nevertheless
allow for sufficient overlap, so the overall network is not limited in extent.
Trust extension ought not to be limited to a single postal code area, for example;
but rather to multiple, contiguous areas.)
Doubt signaling is an adjunct facility in the trust network. It serves to formally indicate suspicious voter registrations. A doubt signal extends from one voter (source) to another (destination). The source may extend signals to any number of destinations, but may extend at most one to each.
The negative messages of doubt signaling are complementary to the positive messages of the trust network. However, doubt signals propagate in a separate network of their own. The two polarities of message are kept apart, and never cancel each other in combination. This separation prevents instability that might arise if, for example, contention among sources and destinations were to lead to a tit-for-tat escalation of messages. This is prevented because the formal authenticity of the register depends only on the positive messages of the trust network. The negative doubt signals serve only to indicate that particular destinations in the network (particular voter registrations) are suspicious, and that the trust sources and registrars ought to consider withdrawing their trust from them. But the actual withdrawal does not follow automatically. Rather it is conditional on the understanding and agreement of the trust sources. Social inter-mediation of the opposing networks thus dampens any tendency to systematic instability. (The response time for withdrawal is nevertheless likely to be faster than any subsequent re-extension of trust to the untrustworthy destinations, so the asymettry between the two should be sufficient to deter abuse of the registry.)
Being the target of doubt signals does not formally affect a voter's inclusion in the voter list, nor her eligibility to vote in polls. Doubt signals are not needed therefore in order to compile a voter list, especially outside of the local area. Consequently they are not considered as part of the core voter input, and are not synchronized up to the super-areas.
votorola/a/count/
votorola.a.count
A deployment area may provide any number of polls. A poll is a collection of votes that are stored in a public repository from which vote counts are generated. The poll is provided by the lowest sub-area that is able to compile a complete list of eligible voters from its own registry. For example, a poll on the issue of electing a member to a national assembly would be provided by a local area (regional or municipal), because the constituencies for such a non-proportional assembly are local. On the other hand, a poll to propose a legislative bill for the same assembly would be provided by a national super-area, because such bills are national issues, on which everyone is entitled to vote. (A super-area would also host any local poll for which the voter list happened, somehow, to straddle the boundary between two local sub-areas.)
|
The vote-server is configured by its configuration script,
located in the votorola
directory (shown above).
The internal structure of the script is outlined in the figure below.
poll-service.js function castingVote( vCC ) function constructingPoll( pollCC ) function pollConstructed( poll ) function voterBarUnknown( voterEmail ) function voterBarUnregistered( voterEmail, registerUID ) |
Polls also store relational data, as shown in the figure below.
This section documents the command/response interface of a poll.
The command/response interface is responsible for servicing
the command oriented clients of the poll, such as the mail-based voter interface,
and the voter
command shell.
The following general-purpose commands are provided:
In addition, the poll provides a couple of special-purpose poll configuration and voting commands. These are documented below.
Reconstruct a count from scratch. reconstruct The service constucts the poll from scratch by ignoring any configuration items that were cached in previous constructions. It replies with detailed progress reports that are generated during the reconstruction process.
Withdraw a vote from a count. unvote The service replies, confirming the withdrawal: Sys/p/sandbox You were voting for: mychoice@somewhere.net You are now voting for: nobody If you change your mind later, and wish to vote again, use the 'vote' command.
Cast a vote in a count. vote CANDIDATE-EMAIL vote [--alter VOTER-EMAIL] You can vote for anyone you choose. All you need is a person's email address. For example: vote myChoice@somewhere.net To recall who you last voted for, simply send: vote The service replies, identifying the recipient of your vote: Sys/p/sandbox You are voting for: myChoice@somewhere.net If that person also casts a vote, then your vote is carried with it. Whoever gets that person's vote also get yours. And so on. Your vote is carried until it reaches someone who does not vote. This is called a 'delegate cascade'. At the end of the cascade, votes accumulate to reveal the favoured candidates. A trace of the cascade is included in the reply, so you can follow the path of your vote, and see who ultimately receives it. Or you can mark the vote as non-cascading, so it stays put until you change it: vote --cascade no (however, this option is not yet implemented) To see how another voter is voting, send: vote --alter VOTER-EMAIL To change your vote, send another 'vote' command. Or withdraw it altogether using 'unvote'. [There is currently no easy way to see who is voting for you, or to view the overall results. This will be corrected in the beta release.]
A vote count is
a snapshot copy of the results of a poll in which the flow of votes is traced,
and the total received by each candidate is recorded.
The count is configured by the runtime script poll-run.js
.
poll-run.js - Counting the Votes --------------------------------- function castingVote( vCC ) function voterBarUnknown( voterEmail ) function voterBarUnregistered( voterEmail, registerUID ) |
To count the votes, use the tool vocount
.
A voter list must already be mounted and reported.
$
nice volist # if a new list is need
$
nice vocount
Counts may be conducted either one at a time,
or repeatedly at scheduled intervals.6
Each separate count creates a new
snap/readyCount record in the output filestore.
For a quick overview of the records in the filestore, use vocount status
:
$
vocount status
/home/voff/votorola/out/vocount/snap-2011-bh-1/readyCount-1 /home/voff/votorola/out/vocount/snap-2011-bi-1/readyCount-1 MR /home/voff/votorola/out/vocount/snap-2011-bj-1/readyCount-1
The new count is automatically mounted (M) and reported (R), making the results immediately visible in all voter interfaces. At the same time, all previous counts are unmounted. To revert to one of the previous counts, simply remount it and re-report it. For example:
$
nice vocount mount --etc \
~/votorola/out/vocount/snap-2011-bi-1/readyCount-1
$
vocount status
/home/voff/votorola/out/vocount/snap-2011-bh-1/readyCount-1 MR /home/voff/votorola/out/vocount/snap-2011-bi-1/readyCount-1 /home/voff/votorola/out/vocount/snap-2011-bj-1/readyCount-1
Snap/readyList records will accumulate in the filestore over time,
as new lists are compiled. For the offline vote-server,
the records may be cleaned away by simply erasing the entire filestore,
using the script vox-clean
.
The online vote-server ought to be cleaned more carefully.
Provided a particular list is not currently mounted (M),
and no poll readyList
links are pointing to it
then its snap/readyList subdirectory may be deleted from the output store.
Deletion will cleanly remove all traces of it from the vote-server.
Any snap directory that is left childless
(without a snap/readyList subdirectory) may likewise be deleted.
It is also possible to move snap/readyList records.
You may wish to archive them, for example. When moving any particular record,
be sure to include the parent snap directory and its immediate files.
(There is no need to include sister snap/readyList records
that happen to share the same parent, you may move them independently.)
In addition, when a count record is moved,
its linked readyList
record
must also be moved.8
votorola/a/web/wic/
votorola.a.web.wic
|
The configuration of the web interface is specified by its startup script,
located in the vote-server's votorola/web
directory (shown above).
The internal structure of the script is outlined in the figure below.
vowicket.js function constructingVOWicket( wicCC ) function initializingVOWicket( web ) |
The file votorola/out/login-persistence.serial
contains hash salts (random numbers) for use by the login persistence facility
(“keep me logged in”).
The security of persisted logins depends on keeping this file private.
You may delete this file in order to invalidate all persisted logins.
A new file containing new salts will automatically be generated.
The file votorola/out/web-activity-list.serial
contains the activity list (http://localhost:8080/voff/w/Activity/).
It is periodically rewritten at runtime.
To clear it, first shut down the web interface, then delete the file.
A Java servlet container is required. Only Tomcat has been tested.
The minimal configuration
already includes a startup configuration file vowicket.js
,
and a Tomcat context file voff.xml
.
Ensure that the servlet container is a member
of the votorola
group. For example,
assuming the container runs under the name tomcat
:
%
groups tomcat
votorola tomcat
If it is not a member of votorola
, then add it:
%
usermod --append --groups votorola tomcat
Link the servlet context file into Tomcat. Do this as root:
%
ln --force --symbolic /home/voff/votorola/web/voff.xml \
CATALINA_BASE/conf/Catalina/localhost/
Or simply copy the context file to that directory.7
You may need to create the destination directory first.
The context directories (Catalina/localhost
)
are not pre-created in a clean installation of Tomcat.
For more information, see Tomcat's documentation regarding the directories
CATALINA_BASE/conf/[enginename]/[hostname].
Restart the servlet container. The Wicket web interface is accessible at:
http://localhost:8080/voff/w/
If you shut down the interface and restart it (e.g. while testing), then be aware that links in old pages may behave incorrectly after restarting. To clear away the old pages, go back to the first page in the browser history, press refresh, and continue from there. Or open a new browser window.
In addition to the interactive Wicket interface, Votorola also provides a web API. See the documentation for WAP and its Call subclasses.
votorola/s/mail/
votorola.s.mail
rough draft
This section concerns the mail-based voter interface (mail interface). The mail interface is currently only documented in rough draft. It is not required for a minimal installation.
|
mail-meta-service.js function constructingMailMetaService( metaCC ) |
mail-meta-service-run.js function serviceEmail( service ) |
voface-mail.js function constructingVOFaceMail( mailCC ) |
# # # # # # # # # # - inner response layer, to respond to (act on) authenticated messages - structure and function - MessageResponder.java feeds commands to voter services; gathers their responses; and transmits them back to sender - in exceptional cases, the responder may act repeatedly on the same message a) if processing of a message is interrupted by a server failure, the message will be reprocessed on a subsequent run - it is therefore possible that users will see multiple replies to a single message / but most re-processed messages will generate only a single reply b) a user might re-send a message - in any case, no critical anomalies will occur from partial processing of messages, or from repeated response to some/all of the commands they contain - localization - respond with language, date formats, etc. according to sender's MIME header Content-Language, per RFC 3282 - http://www.ietf.org/rfc/rfc3282.txt - some canned messages will not be localized: - error messages - expected to be rare - typically in English, or programmer's language - bar descriptions from runtime configuration scripts - difficult to localize, so this is postponed - will be in primary language(s) of the deployment area's internet domain - respond in UTF-8 - 7-bit characters (ASCII) will pass cleanly - 8-bit will be over-encoded for email (in whatever standard it uses) / presumeably the user's client can decode it, if they are used to receiving non-ASCII messages
Ensure you have s mail transfer agent (MTA) that is configured to receive mail for your vote-server account. Votorola has been tested with qmail, but it should work with any MTA that is supported by TMDA.
Set up an inbox for the mail interface. The default (which you can change in your configuration script, farther below) is:
~/Maildir
Messages for all voter services (service-name@HOST.DOMAIN.DOM) will be delivered to this inbox.
[Create configuration scripts for the mail interface.]
Test the meta-service from the command-line.
$
voter mail hello
hello
Run the mail interface, voface-mail.
$
voface-mail &
It is running in the background, so use fg
if you ever
need to foreground it.
Deliver an email message for the meta-service, using vodeliver.
$
echo 'Return-Path: <me@domain.dom>
Delivered-To: voff@HOST.DOMAIN.DOM
Date: Thu, 19 Nov 2009 12:24:37 -0400
Content-Language: en-US
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
To: voff@HOST.DOMAIN.DOM
From: me@domain.dom
Subject: this is a test message...
hello there
help me please' | vodeliver
That should put a message in the inbox. Vomailrd should pick it up, and send a reply to me@domain.dom, within about 20 seconds.
Use your ordinary mail client to send a message to the vote-server at the same address, voff@HOST.DOMAIN.DOM. If your MTA receives the message and delivers it to the vote-server inbox, then you should get a reply momentarilly.
Configure the MTA to deliver messages for all voter services (registry and polls) to the vote-server inbox. (For qmail, see the example /var/qmail/alias directory in the appendix.)
Send a message to the voter registry (register@HOST.DOMAIN.DOM), consisting of the single line:
help
You should get a reply momentarilly.
Test a poll too, by sending a help command to SERVICE-NAME@HOST.DOMAIN.DOM.
The interface will not support voter-input commands (such as 'vote'), until the authentication layer (below) is in place. If a voter-input command is received, then voface-mail will terminate with an error message.
This section documents the command/response interface of the mail meta-service.
The meta-service provides bootstrap instructions on accessing the voter services,
as well as general information about the vote-server.
Its commands are accessible by mail clients,
and through the voter
command shell.
For access from the shell, the service name is “mail”. For example:
$
voter mail version
Votorola 0.2.3
Ping the service, say hello to it. hello hello TEXT The service replies 'hello'. Any TEXT arguments are ignored.
Request general information on the service, and instructions on using it. help The service replies with information and instructions. To request help for a specific command, try 'COMMAND --help'; for instance 'vote --help'.
Ask what version of software the vote-server is running. version The service replies with the version.
The mail interface authenticates messages in order to verify sender identity. The only authentication method currently supported is a handshake across a challenge filter. The apparent sender must reply to a specific challenge (Did you send this message?) before the message is accepted.
# # # # # # # # # # - this section concerns the basic authentication layer of the mail interface - outer authentication layer, to authenticate address of sender - bypassed if message contains no command that requires authentication / some messages, such as read-only queries, do not require authentication - different methods of authentication will eventually be available, according to voter choice / e.g. challenge filter, or signed email - but challenge filter is the only one implemented at present - structure: 1. mail/tmda-filter-wrapper 2. Tagged Message Delivery Agent (TMDA) 3. spam filter, to suppress challenge of obvious spam - usage #TMDA - function - nominal senders are challenged in order to authenticate them as actual senders - once authenticated, messages pass to the response layer - localization - challenge message (TMDA template) will be in language(s) of sender's internet domain - otherwise: / global area might be the only one that needs this - use the top-level domain (country code) of the sender's address to select an appropriate template (which may itself be multilingual) - see TMDA configuration variable TEMPLATE_DIR_MATCH_SENDER / this is the best TMDA can do, at present; (it cannot read standard MIME headers, as the response layer does, below)
Ensure you have Tagged Message Delivery Agent (TMDA) — any recent version.
Ensure you have Perl 5:
$
perl --version
# # # # # # # # # # - basic TMDA - not forgetting to gen. a crypt_key = test TMDA
# # # # # # # # # # = ensure you have libraries needed by tmda-filter-wrapper, by test running it, without arguments
# # # # # # # # # # = set up MTA and TMDA for voter authentication - e.g., by following the example configuration - note the CAVEATS in tmda-filter-wrapper - it may need tweaking for your MTA
u
.
It hosts the online and offline vote-servers for Toronto.
The following subdirectories are of interest:
logging.properties
file. Since it is using
jar-wrapper
to invoke Java,
it does this by adding the following line to its ~/.bashrc:
export JAR_WRAPPER_OPT = \ "-Djava.util.logging.config.file=$HOME/.java/logging.properties"
logging.properties
, under
/etc/tomcat-6
.
1. |
It is not yet clear that synchronization of raw voter input data will be sufficient for registrations. Super-areas may find it difficult to compile their voter lists from scratch, because compiler configuration may vary depending on the sub-area of origin. |
2. |
Mounts may become inaccessible owing to structural changes
in the database tables, files or code. Unmounting prior to each upgrade
will avoid exceptions such as
|
3. |
If you make frequent code changes (developer) you may want to disable session persistence entirely. See example/full/home/vdev/votorola/web/vdev.xml. |
4. |
Write permission for the |
6. |
Runs of MAILTO=mike@zelea.com CBIN=/home/v/votorola/code/votorola/s/_/bin # Min Hour Etc Command 25 0-23/4 * * * nice $CBIN/votrace --churn; sleep 30s; nice $CBIN/vomir; sleep 30s; nice $CBIN/vocount This configuration recompiles the results every 4 hours, at 25 minutes past the hour. In order to guard against timed exploits, however, it might be better to add a degree of randomness to this schedule. |
7. |
For a script to simplify switching between on and offline web interfaces, see: http://reluk.ca/system/host/obsidian/usr/local/bin/vox-tomcat-context. |
8. |
Symbolic links created in the output filestore are not currently relative. They must therefore be recreated in archival copies, to point internally. Alteratively, the links may be replaced with copies of the entire referent (not yet tested). |
9. |
For an example backup script, see: http://reluk.ca/system/host/obsidian/usr/local/bin/vox-backup. |
10. |
The method of user identification is constrained by the following requirements. Each identifier must be:
The method that most easily meets all requirements is an email address. The requirement of nomination (3), in particular, is satisfied by the fact that an email address identifies not only a person, but also a communication channel. It is therefore likely to be known by others, so they can start voting for the addressee right away, and post relevant information in the pollwiki. Prior knowledge of the identifier also simplifies verification (4). Any identifier can be verified by a formal handshake between two parties (doubter and doubted), but a typical user would have to be guided through the process. A familiar email address that is recognized in advance, however, requires no handshake at all. Even if it is not recognized, the handshake can be informal, because an imposter would eventually be exposed through everyday communication. On the other hand, using email addresses as identifiers is likely to expose users to additional spam in their mail boxes. The usual remedies will not work here. Naive obsfuscations ("at" for "@" etc.) do not work at all, because the harvesting bots can see through them. Captcha guards cannot be used, because all registration and voting data is ultimately made public. The votes in particular must be published in machine-readable format for purposes of verification, and each vote is a couplet of email addresses. Closing this data to spammers would also close it to public verification. The whole verification process would then be suspect and the legitimacy of the polls questioned. So the possibility of increased spam will be a concern for some participants who lack adequate protections, at least until we have a fix for the general problem of spam. (That in itself may be something to vote for.) |
11. |
The design of the neighbourhood trust network was intially sketched by Michael Allan.12 |
12. |
Open electoral system (strawman plan). APSA_ITP, mailing list of the American Political Science Association, Information Technology and Politics Section, August 2007. http://lists.hmdc.harvard.edu/lists/apsa_itp_at_lists_hmdc_harvard_edu/2007_08/threads.html#00037 |
13. |
In the event that |
~ |
vote-server home directory |
---|---|
$ |
BASH command prompt |
ITEM |
variable, subtitute your own value for 'ITEM' |
[item] |
optional item in a command, type 'item' or nothing |
a | b |
choice of items in a command, type either 'a' or 'b' |
~/votorola/out/vocount/snap-YYYY-MD-S/readyCount-S
,
from which a particular vote count is generated and verified
~/votorola/out/volist/snap-YYYY-MD-S/readyList-S
,
from which a particular voter list is compiled and verified
~/votorola/out/votrace/snap-YYYY-MD-S/readyTrace-S
,
from which a particular residential trust network is traced and verified
Copyright 2007-2013, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE.