[ARVADOS] updated: 4c7323ea090e7570f962d821fa24c3ab20308e1e

git at public.curoverse.com git at public.curoverse.com
Fri Apr 11 16:04:35 EDT 2014


Summary of changes:
 .gitignore                                         |    7 +-
 apps/workbench/Gemfile                             |    3 +-
 apps/workbench/Gemfile.lock                        |    2 +
 apps/workbench/README.textile                      |    8 +-
 .../app/assets/javascripts/application.js          |    1 +
 .../app/controllers/application_controller.rb      |    3 +-
 .../controllers/pipeline_instances_controller.rb   |    6 +
 apps/workbench/app/controllers/users_controller.rb |  163 ++++-
 apps/workbench/app/helpers/application_helper.rb   |   14 +-
 apps/workbench/app/helpers/provenance_helper.rb    |   68 +--
 apps/workbench/app/models/arvados_api_client.rb    |    2 +-
 apps/workbench/app/models/arvados_base.rb          |    4 +
 apps/workbench/app/models/arvados_resource_list.rb |    7 +
 apps/workbench/app/models/collection.rb            |    7 +
 apps/workbench/app/models/user.rb                  |   11 +
 .../workbench/app/views/application/index.html.erb |   19 +-
 .../app/views/layouts/application.html.erb         |    5 +-
 .../pipeline_instances/_show_components.html.erb   |   26 +-
 .../app/views/pipeline_instances/show.js.erb       |   15 +-
 .../app/views/users/_setup_popup.html.erb          |   69 ++
 .../app/views/users/_show_activity.html.erb        |    4 +
 .../workbench/app/views/users/_show_admin.html.erb |   16 +
 apps/workbench/app/views/users/_tables.html.erb    |   10 +-
 apps/workbench/app/views/users/activity.html.erb   |   72 ++
 apps/workbench/app/views/users/setup.js.erb        |    2 +
 apps/workbench/app/views/users/setup_popup.js.erb  |   44 ++
 apps/workbench/config/application.default.yml      |    1 +
 .../config/initializers/arvados_api_client.rb      |    1 -
 .../{zz_load_config.rb => zza_load_config.rb}      |    3 +
 .../config/initializers/zzz_arvados_api_client.rb  |    8 +
 apps/workbench/config/routes.rb                    |    5 +
 apps/workbench/doc/README_FOR_APP                  |    2 -
 apps/workbench/lib/tasks/config_check.rake         |   13 +-
 .../integration/api_client_authorizations_test.rb  |   11 -
 apps/workbench/test/integration/logins_test.rb     |    2 +-
 apps/workbench/test/integration/smoke_test.rb      |   39 +
 apps/workbench/test/integration/users_test.rb      |  219 ++++++
 apps/workbench/test/integration_helper.rb          |   20 +-
 apps/workbench/test/unit/collection_test.rb        |   15 +-
 doc/.gitignore                                     |    1 -
 doc/README                                         |   28 -
 doc/README.textile                                 |   69 ++
 doc/Rakefile                                       |   31 +-
 doc/_config.yml                                    |    7 +
 doc/_includes/_webring.liquid                      |    6 +-
 doc/api/permission-model.html.textile.liquid       |   20 +-
 doc/api/schema/ApiClient.html.textile.liquid       |    4 +-
 .../ApiClientAuthorization.html.textile.liquid     |    2 +-
 doc/api/schema/AuthorizedKey.html.textile.liquid   |    5 +-
 doc/api/schema/Collection.html.textile.liquid      |    6 +-
 doc/api/schema/Commit.html.textile.liquid          |    4 +-
 doc/api/schema/CommitAncestor.html.textile.liquid  |    4 +-
 doc/api/schema/Group.html.textile.liquid           |    4 +-
 doc/api/schema/Human.html.textile.liquid           |    4 +-
 doc/api/schema/Job.html.textile.liquid             |    6 +-
 doc/api/schema/JobTask.html.textile.liquid         |    4 +-
 doc/api/schema/KeepDisk.html.textile.liquid        |    4 +-
 doc/api/schema/Link.html.textile.liquid            |    4 +-
 doc/api/schema/Log.html.textile.liquid             |    4 +-
 doc/api/schema/Node.html.textile.liquid            |    4 +-
 .../schema/PipelineInstance.html.textile.liquid    |    4 +-
 .../schema/PipelineTemplate.html.textile.liquid    |    4 +-
 doc/api/schema/Repository.html.textile.liquid      |    4 +-
 doc/api/schema/Specimen.html.textile.liquid        |    4 +-
 doc/api/schema/Trait.html.textile.liquid           |    4 +-
 doc/api/schema/User.html.textile.liquid            |    4 +-
 doc/api/schema/VirtualMachine.html.textile.liquid  |    4 +-
 .../pipeline_templates/gatk-exome-fq-snp.json      |   28 +-
 doc/gen_api_schema_docs.py                         |    3 +-
 doc/images/dax-reading-book.png                    |  Bin 0 -> 211000 bytes
 doc/index.html.liquid                              |    4 +-
 doc/install/client.html.textile.liquid             |   14 +
 doc/sdk/cli/index.html.textile.liquid              |   60 ++
 doc/sdk/index.html.textile.liquid                  |   10 +-
 doc/sdk/perl/index.html.textile.liquid             |   99 +++
 doc/sdk/ruby/index.html.textile.liquid             |  125 ++++
 doc/user/copying/agpl-3.0.html                     |    2 +-
 .../getting_started/ssh-access.html.textile.liquid |   82 +--
 doc/user/index.html.textile.liquid                 |   24 +-
 doc/user/reference/api-tokens.html.textile.liquid  |   25 +-
 .../job-and-pipeline-reference.html.textile.liquid |  223 ++++++
 doc/user/topics/keep.html.textile.liquid           |   10 +-
 ...nning-pipeline-command-line.html.textile.liquid |   45 +-
 ...rial-gatk-variantfiltration.html.textile.liquid |    1 +
 .../topics/tutorial-job-debug.html.textile.liquid  |   26 +-
 doc/user/topics/tutorial-job1.html.textile.liquid  |  122 ++--
 .../topics/tutorial-parallel.html.textile.liquid   |   11 +-
 .../running-external-program.html.textile.liquid   |   13 +-
 .../tutorial-firstscript.html.textile.liquid       |   40 +-
 .../tutorials/tutorial-keep.html.textile.liquid    |   30 +-
 .../tutorial-new-pipeline.html.textile.liquid      |   19 +-
 ...tutorial-pipeline-workbench.html.textile.liquid |   25 +-
 docker/.gitignore                                  |    2 +-
 docker/api/Dockerfile                              |    6 +-
 docker/api/production.rb.in                        |    2 +-
 docker/arvdock                                     |    4 +-
 docker/base/Dockerfile                             |   19 +-
 docker/build.sh                                    |   44 +-
 docker/{ => build_tools}/Makefile                  |   56 +-
 docker/build_tools/build.rb                        |  221 ++++++
 docker/{ => build_tools}/config.rb                 |   40 +-
 docker/doc/Dockerfile                              |    3 +-
 docker/docker_build                                |   18 -
 docker/install_sdk.sh                              |   13 +
 docker/workbench/Dockerfile                        |   15 +-
 sdk/cli/arvados-cli.gemspec                        |    1 +
 sdk/cli/bin/arv                                    |   21 +-
 sdk/cli/bin/arv-run-pipeline-instance              |  150 ++--
 sdk/cli/bin/crunch-job                             |  200 +++---
 sdk/perl/Makefile.PL                               |   10 +
 services/api/Gemfile                               |    2 +-
 services/api/Gemfile.lock                          |   10 -
 .../api/app/controllers/application_controller.rb  |   19 +-
 .../app/controllers/arvados/v1/jobs_controller.rb  |   73 ++-
 .../app/controllers/arvados/v1/links_controller.rb |   31 +-
 .../controllers/arvados/v1/schema_controller.rb    |   25 +-
 .../app/controllers/arvados/v1/users_controller.rb |   62 ++-
 .../api/app/models/api_client_authorization.rb     |   12 +
 services/api/app/models/arvados_model.rb           |   75 ++-
 services/api/app/models/commit.rb                  |  122 +++-
 services/api/app/models/job.rb                     |   10 +-
 services/api/app/models/link.rb                    |   19 +-
 services/api/app/models/log.rb                     |   46 ++-
 services/api/app/models/user.rb                    |  221 ++++++-
 services/api/config/application.default.yml        |   12 +-
 services/api/config/application.yml.example        |    7 +-
 services/api/config/database.yml.sample            |    4 +-
 services/api/config/environment.rb                 |    6 +
 .../api/config/environments/development.rb.example |   39 -
 .../api/config/environments/production.rb.example  |   42 -
 services/api/config/environments/test.rb.example   |   40 -
 services/api/config/routes.rb                      |    5 +-
 ...317135600_add_nondeterministic_column_to_job.rb |    9 +
 ...0547_separate_repository_from_script_version.rb |   31 +
 .../20140321191343_add_repository_column_to_job.rb |    9 +
 ...140324024606_add_output_is_persistent_to_job.rb |    5 +
 .../migrate/20140325175653_remove_kind_columns.rb  |   18 +-
 .../db/migrate/20140402001908_add_system_group.rb  |   18 +
 ...20140407184311_rename_log_info_to_properties.rb |    5 +
 services/api/db/schema.rb                          |    7 +-
 services/api/db/seeds.rb                           |   14 +-
 services/api/lib/current_api_client.rb             |   29 +
 services/api/lib/kind_and_etag.rb                  |    5 +-
 services/api/lib/tasks/config_check.rake           |   13 +-
 services/api/script/crunch-dispatch.rb             |   55 +-
 services/api/script/rails                          |    4 +-
 services/api/script/setup-new-user.rb              |   66 ++
 .../test/fixtures/api_client_authorizations.yml    |   12 +
 services/api/test/fixtures/collections.yml         |    2 +-
 services/api/test/fixtures/groups.yml              |   17 +
 services/api/test/fixtures/jobs.yml                |   23 +
 services/api/test/fixtures/links.yml               |   91 +++-
 services/api/test/fixtures/repositories.yml        |    4 +
 services/api/test/fixtures/specimens.yml           |   11 +
 services/api/test/fixtures/users.yml               |   20 +
 .../arvados/v1/collections_controller_test.rb      |   44 ++
 .../arvados/v1/commits_controller_test.rb          |   86 +++
 .../api/test/functional/arvados/v1/git_setup.rb    |   27 +
 .../arvados/v1/job_reuse_controller_test.rb        |  167 +++++
 .../functional/arvados/v1/jobs_controller_test.rb  |   12 +-
 .../functional/arvados/v1/links_controller_test.rb |   56 ++-
 .../functional/arvados/v1/logs_controller_test.rb  |   11 +
 .../arvados/v1/schema_controller_test.rb           |    2 +-
 .../functional/arvados/v1/users_controller_test.rb |  784 ++++++++++++++++++++
 .../api/test/integration/collections_api_test.rb   |   26 +-
 services/api/test/integration/permissions_test.rb  |  140 +++-
 services/api/test/test.git.tar                     |  Bin 0 -> 112640 bytes
 services/api/test/test_helper.rb                   |    3 +
 services/api/test/unit/log_test.rb                 |  226 ++++++-
 services/api/test/unit/user_test.rb                |  288 +++++++-
 services/keep/keep.go                              |  333 +++++++++
 services/keep/keep_test.go                         |  340 +++++++++
 172 files changed, 5845 insertions(+), 1092 deletions(-)
 create mode 100644 apps/workbench/app/views/users/_setup_popup.html.erb
 create mode 100644 apps/workbench/app/views/users/_show_activity.html.erb
 create mode 100644 apps/workbench/app/views/users/activity.html.erb
 create mode 100644 apps/workbench/app/views/users/setup.js.erb
 create mode 100644 apps/workbench/app/views/users/setup_popup.js.erb
 delete mode 100644 apps/workbench/config/initializers/arvados_api_client.rb
 rename apps/workbench/config/initializers/{zz_load_config.rb => zza_load_config.rb} (90%)
 create mode 100644 apps/workbench/config/initializers/zzz_arvados_api_client.rb
 delete mode 100644 apps/workbench/doc/README_FOR_APP
 delete mode 100644 apps/workbench/test/integration/api_client_authorizations_test.rb
 create mode 100644 apps/workbench/test/integration/smoke_test.rb
 create mode 100644 apps/workbench/test/integration/users_test.rb
 delete mode 100644 doc/.gitignore
 delete mode 100644 doc/README
 create mode 100644 doc/README.textile
 create mode 100644 doc/images/dax-reading-book.png
 create mode 100644 doc/sdk/cli/index.html.textile.liquid
 create mode 100644 doc/sdk/perl/index.html.textile.liquid
 create mode 100644 doc/sdk/ruby/index.html.textile.liquid
 create mode 100644 doc/user/reference/job-and-pipeline-reference.html.textile.liquid
 mode change 100644 => 100755 docker/build.sh
 rename docker/{ => build_tools}/Makefile (79%)
 create mode 100755 docker/build_tools/build.rb
 rename docker/{ => build_tools}/config.rb (72%)
 delete mode 100755 docker/docker_build
 create mode 100755 docker/install_sdk.sh
 create mode 100644 sdk/perl/Makefile.PL
 create mode 100644 services/api/db/migrate/20140317135600_add_nondeterministic_column_to_job.rb
 create mode 100644 services/api/db/migrate/20140319160547_separate_repository_from_script_version.rb
 create mode 100644 services/api/db/migrate/20140321191343_add_repository_column_to_job.rb
 create mode 100644 services/api/db/migrate/20140324024606_add_output_is_persistent_to_job.rb
 create mode 100644 services/api/db/migrate/20140402001908_add_system_group.rb
 create mode 100644 services/api/db/migrate/20140407184311_rename_log_info_to_properties.rb
 create mode 100755 services/api/script/setup-new-user.rb
 create mode 100644 services/api/test/fixtures/repositories.yml
 create mode 100644 services/api/test/fixtures/specimens.yml
 create mode 100644 services/api/test/functional/arvados/v1/commits_controller_test.rb
 create mode 100644 services/api/test/functional/arvados/v1/git_setup.rb
 create mode 100644 services/api/test/functional/arvados/v1/job_reuse_controller_test.rb
 create mode 100644 services/api/test/test.git.tar
 create mode 100644 services/keep/keep.go
 create mode 100644 services/keep/keep_test.go

       via  4c7323ea090e7570f962d821fa24c3ab20308e1e (commit)
       via  cc5023d40182e503e8ba109fc86e09efd6337836 (commit)
       via  e3c48fef662408636cb49fe1bb0a3c1040269e7c (commit)
       via  94c762ed797f2567c1dcc70d12582c7d640da7bb (commit)
       via  45ff1f04cf0a562b870e18ca13b02d914db6bcb3 (commit)
       via  9bcbc09d57774d068a3867c2630a4b69a59b4812 (commit)
       via  27cb596cfbff2f81210260d49f824bfdbac6dd5d (commit)
       via  1bb8374adcc014d4898d8ebfadf2bcb119262f0b (commit)
       via  aa75c6199c209d9967e3eff976039494f58ff6bc (commit)
       via  4f552c0187f8c31d94ff74485c57ef7f9888597e (commit)
       via  966ab8387e2762d1720e6104a5f5f6d1e0cc52fe (commit)
       via  a2ebfeadbbdba03dc6e4a02cb5d4e6b85fa747f3 (commit)
       via  51db46ba942baf7f718ae12544008e6f6b2f7ea4 (commit)
       via  c6763b5de6a0dc98493bf288472134db0ac22ffa (commit)
       via  506e5678188ff5a51d4e38558fe8fc0fb4357be2 (commit)
       via  3420c2d2c55eb9466b04bc3c4ca3073caf66aba0 (commit)
       via  88e682e6fc472fcc4fd2d9a0ab39ee6ba6252de0 (commit)
       via  e3193d31ed03056cff6c9d21e0b3cc8898d184a4 (commit)
       via  013ced576824a05cd9a162fbd11e65d4d183a6d5 (commit)
       via  38dea652d11a2a562623d80328d270707ed44887 (commit)
       via  b452636351b19ed5641a20eabc68881bd8905ca4 (commit)
       via  bb3a7e08a90ea7826c0b0e1289c64b395b472151 (commit)
       via  442e5c6553061ef1bbb8d9194bb5b8d9cdb68545 (commit)
       via  2386475f3bf86824e320ad121838955278ed3083 (commit)
       via  de3768fdd71eb58cf040d72b0d989deeb0bb75ae (commit)
       via  44df50add91dc3117291e3a6a908fa442b883106 (commit)
       via  bb3b70b2435a0886b4a2ace9070e24903b04c8a9 (commit)
       via  91f2216807f5b7fb521d61f1a110484a6e5aa2e7 (commit)
       via  e37caee5e3cfc165c6505ea5f3b55a4b8b07fe5e (commit)
       via  b16daa6053ebc15d306c29c01a2134f420e3dab1 (commit)
       via  e35ed29187d83ebd4cbc493b9251119013825ac1 (commit)
       via  c2bd59c55177f431d91c21521196f421d5ffb88f (commit)
       via  e9ee7a48d3f95d41f5b17d4c1c5c65471ff0b598 (commit)
       via  635a2b59e4a9a3ec147b7064a932e4db17bc3955 (commit)
       via  e93b022d02fa68cc3cf34afb8d5448cf984789ac (commit)
       via  71b0d0fb51e3c54a7959f51fd4dbf523fbaf57db (commit)
       via  6ea2e62b70a015226c4f3361ab3591509100a820 (commit)
       via  7e28b26cc58f9d5833ffac6760a99a6a037e4770 (commit)
       via  c6bc2555aae64b937e022637f1fe2c279e1e4936 (commit)
       via  e4b0ff638bb41ce55ab3770c4f2b7f744d653aac (commit)
       via  50ee9817061629f9ffe2568f937149f6e877df04 (commit)
       via  54978ac2108a5b1913f641d480143356659a413a (commit)
       via  19f8cc45bfbe938c0988a719a146a577c2ca7ca5 (commit)
       via  a6c0c9dccbe036132c110817d69c08b757aab5fa (commit)
       via  7488683807205fdfebd3c52e6ba50a0879ef1da7 (commit)
       via  351718c4524ede8442f1cc078d61ced8839440c5 (commit)
       via  0c632a2429105322f793809f1ab5bb158050ed56 (commit)
       via  da1c3891473b02f891eaa0af3d9d799ec6b6ed54 (commit)
       via  6783336d968c8e47ad63e929086aa704299bb403 (commit)
       via  3dd13d1a0643fdcc9e4f391b74b2496ca2ebbc7c (commit)
       via  dcbdaf47dd1486f58893413c07a9cb5c6d180923 (commit)
       via  c7b2768cd590b633fe4154dedec2d8ad387a9d9b (commit)
       via  a0d41ce990cf0a6fcd516a6a10f662a85258238c (commit)
       via  19d60097652447fe7c71ec78f5c8d52a7002b3b8 (commit)
       via  4c179135909d37a6cd9722af909785393d9e117d (commit)
       via  64d449da29bbbe6bce2b54a2ed67eb4cb44243c9 (commit)
       via  c7f17227456c27d71bca83895c84bc83fb3b4ec5 (commit)
       via  2908852ef9d52b12eb715474c5f31e35f7c44b18 (commit)
       via  11a9f64426c1fc50529e694fead97f81e6eb4457 (commit)
       via  e9339eb1983e33798270f61f57d90cde4b656bd8 (commit)
       via  8ea149362539b3d50e14a7fbd8831c7cbf347446 (commit)
       via  847b4a5d6e179dde49295a7118962e764d63e544 (commit)
       via  1d6d51202a936a28eee2384ceaa7c725813a2b03 (commit)
       via  d0dc31b9feb56c026f7c7ae0d46e63434b46742f (commit)
       via  a6724f72c5a93edf2b8a456783a474024743f1ff (commit)
       via  cbdb5dc18ccbd8cd2cdc4ebeaace82aa33b36f70 (commit)
       via  1418580063cbe02ab3376adb27928c5325ba10b3 (commit)
       via  a3212e71057712af58a7d2b849d69915b4fd79b1 (commit)
       via  59b0a3a8e5209ef85967a93c500167b7cf882757 (commit)
       via  9349484f1e607064cf96fa7f7212979d30e58448 (commit)
       via  0f92cdd76a8ecc456e0ab068abce468e3a169bc0 (commit)
       via  fdbdc0cdecb027265dccef0810b189e578cb8c60 (commit)
       via  0b76b475d2e1dc33bd80de9923d99009231e6671 (commit)
       via  4d918da1c7f7499d19491d44ecead48008d2fe1e (commit)
       via  38f8414fb8357b57ab3b859b7721676d62dfe984 (commit)
       via  eba6e6988be540b8d6015903e58d8acf71476149 (commit)
       via  7043cad00647bc44f83586d895b70f950d5a26c2 (commit)
       via  043a17b21c0f18eaaddcdd5d1144989c1d48e3e2 (commit)
       via  2c5412052d38751d538696c9d5cbb0b8adbfd1a6 (commit)
       via  4e3dca8c84d77baaa1a58c195204f91da5f4176d (commit)
       via  2c292c1942746dfa7b93411d76a8374e1b0aff16 (commit)
       via  c267f657aae5d43389a41861c2b9649c30482468 (commit)
       via  b8ee1ea826cd2f02233893e8e06bac5fc44bb473 (commit)
       via  55684214f941cf73ce1eb542943dea24a17d48e5 (commit)
       via  cb2c6a830abda3390146a4933b8cd8ce6ed55d31 (commit)
       via  8f8feb2866fd36bbc44188116d3bed6e4a4109a4 (commit)
       via  190fe9cdc4ea41267a89f8c0e54dbc179cd1e4b8 (commit)
       via  9d9b194941e7d3c9b459d27657e3c3c67bf388b8 (commit)
       via  835332abdd0fb8d0046529ff4d2f026f67736418 (commit)
       via  e8dea4fda0347c612ba6b0d4a8045916febeb680 (commit)
       via  a2164fe94a9909e5b38856b881a1d856f822747d (commit)
       via  47d130ae61a2aa0c637060d4a5be9f3728af30b7 (commit)
       via  5a7b7aa6a6a11b5e0a397d01a6fe527169ed5f15 (commit)
       via  4efa06e83f82096b70c03192bce74df96ed230c5 (commit)
       via  9f87668ecf0768f83b95253d8888481b1d8ff95e (commit)
       via  e6e7736641231fe43b5f68bf4d0653d4321bbc36 (commit)
       via  4882cd9ebd6311c4f84d8efff21561b1a229e244 (commit)
       via  33d7da6903a0fc2c9570a11c939dce6a4894f66e (commit)
       via  a992c11d76c013d42470a5142714d68e918bccfa (commit)
       via  20e876e9d9809d6097da440453c20f737229ee28 (commit)
       via  1697fcdd746eb5a30127275e533c3d799aa9f681 (commit)
       via  921ec0ddab4c949659d54490204acdd431986450 (commit)
       via  c6cb3423e9ca2b421bda3bb97c1448dcde19df97 (commit)
       via  3ca0861ae65a9c61f0db226bbe9f70cfc0a4ec7b (commit)
       via  fe0d9b8e3a46c610deb95b9a8b501e8c2aad9f54 (commit)
       via  cb19d007add188f2c83a082c419ee0b523fb664b (commit)
       via  a15ff495c8c576378f55f58fe22ce9f3c49121e8 (commit)
       via  4eba2cb5d7d6a5d76b9ce4d3f535a1de911400cd (commit)
       via  bc4eea1e54651c507b8add0f5edc80968673c6fc (commit)
       via  61f1066c9ff0114b5c321832a8002cb2511480ca (commit)
       via  5dd1c07e56d32ae4c569ceffdbd4549bceb92de4 (commit)
       via  2b5d9607892a48d32401ff59516e8d73234eee89 (commit)
       via  92f572b9c49ecbdd8f2884e52fa8e814e23daab8 (commit)
       via  2c7e73fafb98fff4f9d061074d6b58d668d5c1dc (commit)
       via  39717c4347c00ee0697942d60a50000bfc89fe3c (commit)
       via  6d73acc845a2dd7413fdde0742473d83bf3d0719 (commit)
       via  80b7ca3bd2bde86272e4de5524f09701b85d6456 (commit)
       via  3854a47d632dde711f57c047e80ca84b0b786815 (commit)
       via  b1b9ffbb5e49d04c058d11702ecd240b1ef8a958 (commit)
       via  bb511c0b9c011610d38dc10f6312a6b83720aa42 (commit)
       via  385b439532e90ccd2429941574d8b44029a6ea54 (commit)
       via  a20025f9ce967ae845e3c675d764d4d1ce4f4f2c (commit)
       via  9454df6ea65e3afa9586cabea34abc42c328bd65 (commit)
       via  cab9d1a8bd750638efbff292093624bf5bdb8767 (commit)
       via  d12e6551586651ee5251f70fac1b1c086674a835 (commit)
       via  47d1fdfe8a1d7c4275f9b97f7ddf932e6671f0af (commit)
       via  7449c28473b6a5f47148ee5ce321fa994db883cb (commit)
       via  d7d1117bbd5e2441a93c6563ba628debac82741a (commit)
       via  3acd32f8a766269e0d7841000eb58e6d8364fcc9 (commit)
       via  5a19b986fd10f0584b33eb5953e72bd373e487d2 (commit)
       via  d06f12a2866e92737f27a05a7782d67106edd2cf (commit)
       via  05d6c99e5b40c7e0792c44a7c2d9af5b91164f9b (commit)
       via  6b55fdd2cb5e1d6c43dd6df9c7af16a2da324f26 (commit)
       via  13b092de0b24b586fe2c8adf8cb0fb4eb3b62d4b (commit)
       via  091af67c8481567a9e6724df0a77b3fae13ee1ad (commit)
       via  9c7fa026f56632db13c7afaa3db31899f824d7c8 (commit)
       via  73dcec308547f3ae2170ea0907b27f1ebe02439b (commit)
       via  896b812c4d11b960f64cc443bc3af8061d98dd47 (commit)
       via  069df612230d821160fd1d4453c742d1ba2cce9e (commit)
       via  d8d47e5f8c4666e44733d8729665e1af64e82049 (commit)
       via  fe2eda8cd9e167b3519eb21c276bd8ee44a3b7d9 (commit)
       via  3cc99771ce18ed7669294b3cac0fef3773a9162c (commit)
       via  4cd8b568c98baea57cca7a1921c9457718c0b335 (commit)
       via  23d2f0ee32c146061a6212006afef3c519f58d7d (commit)
       via  e0cdfbacae4dfc256d483d8055b5aabb581bb964 (commit)
       via  fc28c638a1917bb1156cf6082947be2302843dd8 (commit)
       via  3f7da17f62967a5a2717e5a102aa1e3070f679c9 (commit)
       via  6440d5e8b701fb8f1d2c335924b6568389adab19 (commit)
       via  6893889064303b551111de3e3fbc49741c294713 (commit)
       via  c67b7cfdb650039ef403d16bcd619f2c7dbe9fd6 (commit)
       via  cd5c3d352b5baa2e0faf9a34af5b6144cb2aeff8 (commit)
       via  d042ae6b63ca96aa3fd7106de31bca2dc89105e8 (commit)
       via  f6b24b30e9f3794943f628c22ee4dabcadca5a1a (commit)
       via  fa71dfeaa60db30385fed3f92f12e5a1e18e1804 (commit)
       via  01e105fdeeaec55b18e3ec77612378a554f3f659 (commit)
       via  b0542ec0dd2bb6fbf040d1c7d719e7fa4d82d58a (commit)
       via  bdc87ddb113a2e05dd859a7f68f5fe1135bbc650 (commit)
       via  6566142db3e00a866559402a10991c2ded1e74b8 (commit)
       via  a97c22ce97e867813d27dbace041de166bb26c09 (commit)
       via  a7ef84a9780f37b7ea27f29df6326d67869a03ac (commit)
       via  7023263e319cbd93365f7104c866aba4886616da (commit)
       via  1a825caf53f352f63cafe10ef6211f4f689177e0 (commit)
       via  d2027b0323287c57131e3c064a78d77830fa1dcb (commit)
       via  b268423c81bddfb3e0a6de14a404b4e8efc97977 (commit)
       via  935dec2c33e2ab45bc97146305e5937bab116d18 (commit)
       via  2c2d5fc62029b559669c860ab1d083eed44cf30e (commit)
       via  28ed7a8f36a671b8c9e629ad923c904eecf08ac4 (commit)
       via  6287b16dd4fa87f5828387987514e21e00c33f4c (commit)
       via  960a09a85db9fb7f38b8c4e1c93cf27a1d186d90 (commit)
       via  24a0882b04f95ee44fddcc94fab541486700a0dc (commit)
       via  33507442d1b24551985199ef453641f2c65a66e3 (commit)
       via  9c5dc2759edaa0f3c7bde4aa086971ffa54cbb42 (commit)
       via  71f1843d04d596d7912bfa068f64717e5347afc5 (commit)
       via  c817aafff76211ac69ef7c7650f88dd5002e6ffe (commit)
       via  7ff586c2f32f7cd652381ccb7211691cbe66e3a4 (commit)
       via  4a389d125083663b5b58a3f4ab3d24a842962840 (commit)
       via  ec4d769ca8aa94d3406ece303afc3c6fd4f6c9b3 (commit)
       via  9c1787c9c626b3d9ca24463410d7bc7d963584d4 (commit)
       via  180890198f08267989ab33ad55776999ed66d273 (commit)
       via  075688b8e7bea4ae33b9c949d8e8f8733ec9c6db (commit)
       via  91cdce018ef0906d43452c1b0079c110e7babb60 (commit)
       via  31c82149c41a5c2c1377b617bfedc0dfbb08faf4 (commit)
       via  d5a749082fab8cb70a814ab9329cf5b8f9e36bb7 (commit)
       via  dbbf7f7e313392314139bbdb66a50b740b26d532 (commit)
       via  1956ba70cdf1a367a61c8a8a5428db52fa02fc7c (commit)
       via  477b2aa7dcbf5cd4e1f1a56d2275cc3ded5ad023 (commit)
       via  4ac093dfacb82c270ef2536822ee4ab07715c88e (commit)
       via  4545c9039616be21017862a78f60b2b02540b613 (commit)
       via  d6f1334e74ce51269ee3d7f462b2ec17dc8ca3f8 (commit)
       via  5abb716e9209f26b29ba883feeaa8ded8f046aaf (commit)
       via  ad0944aa970bf52bcc2387ac57e12cb69ae54d66 (commit)
       via  64b24877bdb4b35938e8b691463b78073a4fd31d (commit)
       via  c6043720763ecad450078728e2a3c815c51148bc (commit)
       via  56e5fc30bc2f466bac84ee3d8cf8119cdd783603 (commit)
       via  e661ffb13884990e8c359fc4ed973db1d7f95db9 (commit)
       via  26446197bb00d7f899673b7f9434e6bd622b8904 (commit)
       via  331ffafdb6a080bac50765c4eca15508d52ac0ae (commit)
       via  660e8d8345bfe7f34dfc8db655eff6a0af8bd47f (commit)
       via  82f30795293f8e84fe5b43710938f246d6604119 (commit)
       via  fbbb1beaca00df2d1483087451b81ed3c40953a9 (commit)
       via  6232434d6b86192b0531bacd7e4f0d5ae589f368 (commit)
       via  b0af0440838407be80c6208b15f969bc2942008e (commit)
       via  736c7c62cb2bd45637a54ac8937315ba4b64ed37 (commit)
       via  0136e134c210fe60e6a1e0eee5e2f77d8bc939dc (commit)
       via  3262e46dd0fff9d6289f8d91207a585df9de7074 (commit)
       via  960e0078e260149cb82c27583bafa2aad6e995b7 (commit)
       via  08a7509697639aa6fcbd7a16d00788db89dfcddf (commit)
       via  96b6172daeeb0c4ca6ee9f3f72bccbcedc3b95d2 (commit)
       via  5390a8a8578538ad3b2bf0e7e541485c342acbea (commit)
       via  8a265d208908cd8fbfa808add745c3e842557dc0 (commit)
       via  1158c797ee6479ec6d6b90b0512fbfa38da89a72 (commit)
       via  06d0c1434c815ff2f00e5723f902fdf11b51ab14 (commit)
       via  9c78924f523b5420a21fe5c7eba0f913de4c4d69 (commit)
       via  c0b66870cafce4d75625e16b5b36bed8b58d7c8e (commit)
       via  fbb4e2d894e5c6043e778991002629fbfdd08956 (commit)
       via  e40fdedbc285a0fa6af16e41b5b4f72e46e9987d (commit)
       via  8d003a7abe0b4d633c6c125dabbf011394fde2e7 (commit)
       via  31c6426b70e2b277087188dad2b9b346c904f30b (commit)
       via  ee86983a93c335413c508c5717a8707bbced93e6 (commit)
       via  2c81dc8f676cad13b61c47b89fffd3dea93055fb (commit)
       via  392c382ddaf8ea4c0c4b6655c7f508de73274d12 (commit)
       via  e423bbb1f70a3244af625165357acea8afbbfc85 (commit)
       via  7a537556b3503bf957ad3da2bf27885518a33230 (commit)
       via  1013c7cee5478538901fd9ba5fc0fb2ce30f6422 (commit)
       via  231b9f25a701e9bdbb69b61135d4856647dcce55 (commit)
       via  b836fb6c2d2fb439787b68ecca278e1f8c868d50 (commit)
       via  8e34082da3e9952c18e8bd9c0afac2516dea1287 (commit)
       via  04e3622dad1430dfae82c8e7130b2fb9f4610cf7 (commit)
       via  2a3f8231a1682e7bac956e4079ff19ccc8b133ec (commit)
       via  10184eeb601e432f8e81aea00cbc2375f79bcf45 (commit)
       via  73b1451ebad641dec4617292e98de61425b4c285 (commit)
       via  52cbd3bc6d8b7b2fe0735cb8ccd6e57c89c8d797 (commit)
       via  c54e3ca6bf62f1f4e41af25e920b49ee33c97805 (commit)
       via  402461a12dbff7d0ec00c8446b925b021aabc2ed (commit)
       via  7c04fe3e0e93d22b9c884934dbbd80fed6072ee3 (commit)
       via  df4897f1390e58825dd8afcc053955c6d3894169 (commit)
       via  921c13a95c2d13c94de74601e5bc26e5b0c71c31 (commit)
       via  4e26baca96b4cb9e2145475bf31f18a0ffad2c26 (commit)
       via  e23961a316dc64068a6cc9b799d618f021f85ddb (commit)
       via  56c13e4c3af29ec274a8c3c5564ff3dbec2505fc (commit)
       via  e102a3b3100577137def302ecd0f810bc46b808a (commit)
       via  0ce7d041f53bea47f98f509ccf7c196b8ad393b0 (commit)
       via  eff1d4ece26ce459c1f19b202a2048b2f663bddc (commit)
       via  23a65392c4dd88f28cbf94ac451bd1f1d9cd0be4 (commit)
       via  b98ffafdc9e1b5904b200013ebe106959334c0c3 (commit)
       via  51a07a4abf5b21fb983e5df39dc2ea9ae58d0469 (commit)
       via  4995783a3270e2f6d2d3b5226238fbbccf2864c1 (commit)
       via  64cdcaf6b38437c459bce30445e547c274e3f99e (commit)
       via  031ad8460650129f8bed088e801fb0762d4d29b3 (commit)
       via  b65cb64f0d7865266bd8674e681cd0f48fd476c7 (commit)
       via  b9e9a418b7db148352bfc6b9f616c37163f38c32 (commit)
       via  9f5d16ade2d95497ed9610eefd03d76fb15eb747 (commit)
       via  ee21f45e958de5ef39970981ead6416e3790cd1a (commit)
       via  03ab8baef455f5eb9cde83c2b05d82b42c46e216 (commit)
       via  2013479619e9aa838037262564ac4f265f786ad0 (commit)
       via  c95bf51af6261d2707421305342043f499b69f67 (commit)
       via  d08be17d479e5bbc17c28811f97d84059fc78403 (commit)
       via  7079ddb46ce3e855a30a4bd5b8f1f3e626ce7b7a (commit)
       via  9a405be1112c8bad4c56160a4fc234943449f7c5 (commit)
       via  fad09fd18d6c364f358f3d7c5782b4d0360c68ab (commit)
       via  070332d12b114e0536ccc5025743bea854bd4c9e (commit)
       via  5991a5bb4a4ccf74b763570941458dfee640f6d1 (commit)
       via  31bb970d362490abc5238e895e04ab41d828e64c (commit)
       via  48b87a694a78f09e8e7c6d05212f1e21aa2423d3 (commit)
       via  de10e681e82e0cb987ffb95109a6c09a13f49944 (commit)
       via  91526e84bf213e08b602fdbd4e7b69a18d401483 (commit)
       via  a248323fdb1bfa315a3dc9af0a2362aa5b0a0f46 (commit)
       via  f75abd5da51c048fd26e7076a8a8fe96f6f5e0a2 (commit)
       via  545b33abf34ebbc74fe16e5e541e82d5a79e8457 (commit)
       via  1d3810b3150d653314437471d7858cdbf76b62c7 (commit)
       via  67a54670123669370bb4e664c7e40c71f7539b5f (commit)
       via  0e560c4a9b3f1d46edcbd3fbc595beffc6efca47 (commit)
       via  8dd84d8f667aa40b9c8ce91d1a9248e1a7218039 (commit)
       via  4baccff09d5f8c48cc3c431365f1e029a8c40bb1 (commit)
       via  87501e7bf8d4f2303cc25a00e93476784911438b (commit)
       via  2bfc24e6eb5cbd51bbb2717cd70b02a25b008ae5 (commit)
       via  fefc1d78df0a65c949099f98062877f93dfbec8a (commit)
       via  b50bbef5f429465fe71781be7edebbb8c4479d50 (commit)
       via  381f3ce2529a027cc0eb1c402b94135711658f6b (commit)
       via  6a8e3decba6bf4cd890bf98241646d0d070990b7 (commit)
       via  73e9bb7585add05c044a80c6811681d58b6148b4 (commit)
       via  69d0e98d74c221ba2161b4851c51dd47ee7a9409 (commit)
       via  3dc88c9d537e6056e544746753f7e7befe55cbff (commit)
       via  968a749a6981074ba2159df70adde92b2e681263 (commit)
       via  dff5bfa5afbdd49bf0003b75583b7120f21b7df7 (commit)
       via  83fa2045a190732f8dd9bed3e5c6071ce66da07f (commit)
       via  8c021e4b54a8179e86dd887e1eb8db9ef4dd9672 (commit)
       via  6a18fc0d6f3f9859e905d4762796d813a157605b (commit)
       via  35e245f09cfc5ace6259a671a1f12fd508750b13 (commit)
       via  6fc29fa2b44072bc9a1cd015282dde30a0ee72c4 (commit)
       via  ee1abbc5a99dc2fa67de7713107ccd5473bd94a5 (commit)
       via  1896a42e2da493b024dce40266a4814883c08003 (commit)
       via  a66dcf3c878be422520771e5bde3791248dba001 (commit)
       via  be04ef9fec4824bd09b290999f2f961379bd2b83 (commit)
       via  46f47b1e941e1471363a5d5480dbe4c68c18703a (commit)
       via  007446e69619bae44193f219b6d9b7fda31bafad (commit)
       via  971452bda26fc20bfff3c07f6203d61fd4ca0df8 (commit)
       via  bf53b14daa894c77ea2b9413e9a574897446a2b7 (commit)
       via  178545086f0752789ca79d212e92f8c45030ead9 (commit)
       via  65a085e1a2812e48a6f4b21d5229430549fb8791 (commit)
       via  2d2e5e107fc258c2d6c864f61cb0b03b901c2088 (commit)
       via  e9a25bfe507179a20c4bb8a994ad394759b5239f (commit)
       via  d51fa3200eef8da2798ab7d29e0e6180d3da71f7 (commit)
       via  eb0fdee4d4fdb516dd57998ae6a34840354e6e77 (commit)
       via  e8167f6b3a83525a07c79e03917bad570a6c5c26 (commit)
       via  33166913f14878fd317b9a07e038f8d294453b94 (commit)
       via  24742cd39eff59df5d4ac17d7d39c437c79a456b (commit)
       via  71d1a30b467a43ef312fd7e81d795864799415b2 (commit)
       via  994fa8b63a19f2253b6027d64f7ea72c43ea1192 (commit)
       via  3e130a782321de2a0343fcec8a3365442ecde431 (commit)
       via  d65964ad6063b6cd5420004a5cbdc58fe2d0b194 (commit)
       via  c09ec8260b02c4767c82bcb5b346899193329828 (commit)
       via  03aadd3864de6d5687e1e6c71815fafc4ec030af (commit)
       via  6849ec08498a596d0604c2876dcd605ce6c6aaeb (commit)
       via  4ad105bd22c9141e5f88139ad3bf334a52f7a5d1 (commit)
       via  4d3a1c5346c99da360af58f1932b8f7a2ba87723 (commit)
       via  5b039149732231ec9bd53fd8b5b005babf9eb82e (commit)
       via  296a8cba6b65654156d3ff3abc07522a4824935e (commit)
       via  127f1e032068d83365d783e8fe8cad5f0117638a (commit)
       via  1f5561a43693243ad3b6737dcd1020cbe0cc809f (commit)
       via  00a420599077a5063aba449fe9986a765db6bdb3 (commit)
       via  24e20b5eb6f6e021b7f6789ce6e6b4c5a8c678be (commit)
       via  620bcbd5734e860a1e67bb85e4899233bc4a6b28 (commit)
       via  375c23fa047e5fcd09e71f5c473dbd05cbe14891 (commit)
       via  3de8b7c50ba3d254acb888579f16de44ce693e36 (commit)
       via  e5804f99569634967d4affe322a382034d81cfa8 (commit)
       via  23a7957589e03db8576c6547d3204477c2b0e7f3 (commit)
       via  0496ff36445af8eae98914b91869ac52d951148e (commit)
       via  86c192b3ae3614f69305cfd60664c9b720b84692 (commit)
       via  7112a411de36be33f6857aea3bc750a87b139854 (commit)
       via  3e5b4f4602903d00650aa7d57a6934617468dd9f (commit)
       via  1b6d98d5000a0c21a5e06a5195cba70d0c2d4dde (commit)
       via  87f67abc3c73634afbaf7ebad1445c1f234dc5d4 (commit)
       via  240c16d4be50f3cb73d5d573421430efb7ece00f (commit)
       via  9c3904d27dc7d6b6aa5834ff0f5815a8b3685e99 (commit)
       via  4b57d5f64a980777888fa49657d6fe0617514218 (commit)
       via  851f7d9cc9d3f6e4843a8fbd507338b1cc0e9f2c (commit)
       via  107377eaf36cba7130e7bc9f42111147049cbd0b (commit)
       via  8b7a06f6d4f3f40fc0b2a2d5debf4b4553cc4ba0 (commit)
       via  9b10524c349d0c28a6dcf33ad0a473c3eb2d2b2f (commit)
       via  ed65efe8ac537694369f46fb5130e4f3d47183d3 (commit)
       via  fe4b3736c374e703d53ac3c444da7eb49a54a6d6 (commit)
       via  dc01c0405fbc4c17e3fc947dd154e1adb915a790 (commit)
       via  5351e44b4947d93c1027c70afde0b2fda150abb2 (commit)
       via  ea812dad57e1e31cfce0167a8b8431aad15bf01a (commit)
       via  af19eb3a35900457a1dcfadee789a9052fb50335 (commit)
       via  7db862a48062c6086ea8a6787149afa7d66b1919 (commit)
       via  ac4facb25d9c5828c247ada1fa7618c5a2e8b2d8 (commit)
       via  dcbb5acc0f9767c6b358e5f5d6055b78290430ab (commit)
       via  daf4ff30727f49ee3606fe8adab3b67f35e00beb (commit)
       via  8a274345e3279b561d17d546d4f3581862811125 (commit)
       via  cf8b27749cf44aee74914622dc8bc2a9690204dc (commit)
       via  3690225e29161191cc5daabe4a335a0ec5737d3d (commit)
       via  e3c95c76496fe399ef145990114eb83918e10dac (commit)
       via  39cb61dfbcbeca5ff2d79ea9e9329beb6a4e489a (commit)
       via  cf7e30873ef4b92cc8ec099b2bb344391a070e93 (commit)
       via  cbfc8eea7f3fc96f478530c77441b7175a043a17 (commit)
       via  8993f82f9148553603d9d6ce5f638a253f7fce70 (commit)
       via  76f9268395068d47fda7f34426bc83d603c834c7 (commit)
       via  ced5e21f292fd8afa2cf2dc3345eb8a1c714d9cf (commit)
       via  501db79a2d00dcd79b3cf3757f6a93ef6c1c1696 (commit)
       via  c26e7fdbccc106aafb30603ff71ffc529ecf78c0 (commit)
       via  22b6371cb0ff61b9dd19cef581ec1bdaae1b0bd9 (commit)
       via  189fee6586b290a78cdc1b3a3b9845efe0cf7499 (commit)
       via  041a71c199e15f89b5adf4a5b5058b5ccbb171ee (commit)
       via  ef35b37af2b60cce2b5d7668874ba4cabaf4482e (commit)
       via  0b38582960918090082c2f52d74e9dfe4f8c478e (commit)
       via  5fbb2a9454e18443b2d6e55c7ae811aca3876714 (commit)
       via  428359fce0a1b8f9b922236cb55937ec6339a275 (commit)
       via  c8060b94c485d5bf0e500d2321793cd56db4c856 (commit)
       via  c7ee682e45f191903e5f82b0b5104aa236cfe2e0 (commit)
       via  3bd6252a86bc5fc8697c9d4accb12ff3d43ca021 (commit)
       via  57b36a0ec32ba48689089bce6b8c449da2e57c40 (commit)
       via  4127b85f2c1af611bb70d5ab469adac126d0a7a4 (commit)
       via  93dea89cdc20082b6f22593279f6f6d11b9e6e52 (commit)
       via  e7b601c25f6ac88e7adaf219f296c448d29c3904 (commit)
       via  2d9d106c40b83e9a72d431bdb198ed5b8b13550a (commit)
       via  acf1ba5bb4d987012030de8978cc6930e1bee654 (commit)
       via  fca114122bb204b34414a17e278748ec8e87e136 (commit)
       via  b37cf5e27548d8af4ec355c9a102c9a5734b3306 (commit)
       via  12af96fba8ef1c218cb3cfb04c41c5507b394717 (commit)
       via  6263b4bdab2869ffc52c49ab283dd39c93f25a32 (commit)
       via  d20f1211b3766e1703aa337462aecfabf5a5c908 (commit)
       via  7a86103d2b5d03eefc8f1063e17929abbfb9005e (commit)
       via  7a669da106bd775adffb69ffbfda639509e62e3f (commit)
       via  7898f77240327d8858e37955e47cb3f14c0f083c (commit)
       via  396df0e121349eeb9793fa87d916bbe69e934abf (commit)
       via  e46640c01c65600cbf620cec62a51b0c65cea4ae (commit)
       via  5aaa5c31fd5d9e00d367cbfc2792fe2335c698b4 (commit)
       via  d8f89cee7bbac961f15309442dfed4292cb00d2c (commit)
       via  4f72ea0df20682c92525d6370b7198371fc75f91 (commit)
       via  edd7d3d2958c4d57327961e380075341fd87086a (commit)
       via  02586026a32a3913d02986ddd9469247b504d713 (commit)
       via  4151af1d89da4c3f3fff3fb6732c0249d93dcda9 (commit)
       via  3d2c9602f0309c1b25a434c053561c0c98dafbce (commit)
      from  4177bcc9b935391630c874a2abcedb81efa350f0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 4c7323ea090e7570f962d821fa24c3ab20308e1e
Merge: cc5023d e3c48fe
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Fri Apr 11 16:04:28 2014 -0400

    Merge remote-tracking branch 'origin/master' into origin-2228-check-filter-uuid-columns
    
    Conflicts:
    	services/api/app/models/arvados_model.rb

diff --cc services/api/app/models/arvados_model.rb
index 0cc26c5,921d2b1..08bb5ea
--- a/services/api/app/models/arvados_model.rb
+++ b/services/api/app/models/arvados_model.rb
@@@ -11,11 -12,13 +12,15 @@@ class ArvadosModel < ActiveRecord::Bas
    before_create :ensure_permission_to_create
    before_update :ensure_permission_to_update
    before_destroy :ensure_permission_to_destroy
 +
-   before_validation :maybe_update_modified_by_fields
+   before_create :update_modified_by_fields
+   before_update :maybe_update_modified_by_fields
+   after_create :log_create
+   after_update :log_update
+   after_destroy :log_destroy
    validate :ensure_serialized_attribute_type
    validate :normalize_collection_uuids
 +  validate :ensure_valid_uuids
  
    has_many :permissions, :foreign_key => :head_uuid, :class_name => 'Link', :primary_key => :uuid, :conditions => "link_class = 'permission'"
  
diff --cc services/api/app/models/log.rb
index bf3c8d3,af0b533..923a681
--- a/services/api/app/models/log.rb
+++ b/services/api/app/models/log.rb
@@@ -12,7 -13,32 +12,31 @@@ class Log < ArvadosMode
      t.add :event_at
      t.add :event_type
      t.add :summary
-     t.add :info
+     t.add :properties
+   end
+ 
+   def fill_object(thing)
 -    self.object_kind ||= thing.kind
+     self.object_uuid ||= thing.uuid
+     self.summary ||= "#{self.event_type} of #{thing.uuid}"
+     self
+   end
+ 
+   def fill_properties(age, etag_prop, attrs_prop)
+     self.properties.merge!({"#{age}_etag" => etag_prop,
+                              "#{age}_attributes" => attrs_prop})
+   end
+ 
+   def update_to(thing)
+     fill_properties('new', thing.andand.etag, thing.andand.logged_attributes)
+     case event_type
+     when "create"
+       self.event_at = thing.created_at
+     when "update"
+       self.event_at = thing.modified_at
+     when "destroy"
+       self.event_at = Time.now
+     end
+     self
    end
  
    protected
@@@ -20,4 -56,8 +54,12 @@@
    def set_default_event_at
      self.event_at ||= Time.now
    end
+ 
+   def log_change(event_type)
+     # Don't log changes to logs.
+   end
++
++  def ensure_valid_uuids
++    # logs can have references to deleted objects
++  end
  end
diff --cc services/api/db/migrate/20140325175653_remove_kind_columns.rb
index 1ecd5d5,0000000..d77130d
mode 100644,000000..100644
--- a/services/api/db/migrate/20140325175653_remove_kind_columns.rb
+++ b/services/api/db/migrate/20140325175653_remove_kind_columns.rb
@@@ -1,21 -1,0 +1,27 @@@
 +class RemoveKindColumns < ActiveRecord::Migration
 +  include CurrentApiClient
 +
 +  def up
 +    remove_column :links, :head_kind
 +    remove_column :links, :tail_kind
++    remove_column :log, :object_kind
 +  end
 +
 +  def down
 +    add_column :links, :head_kind, :string
 +    add_column :links, :tail_kind, :string
++    add_column :log, :object_kind, :string
 +
 +    act_as_system_user do
 +      Link.all.each do |l|
 +        l.head_kind = ArvadosModel::resource_class_for_uuid(l.head_uuid).kind if l.head_uuid
 +        l.tail_kind = ArvadosModel::resource_class_for_uuid(l.tail_uuid).kind if l.tail_uuid
 +        l.save
 +      end
++      Log.all.each do |l|
++        l.object_kind = ArvadosModel::resource_class_for_uuid(l.object_uuid).kind if l.object_uuid
++        l.save
++      end
 +    end
 +  end
 +end
diff --cc services/api/db/schema.rb
index a2b89e3,2ef90d2..e2301e5
--- a/services/api/db/schema.rb
+++ b/services/api/db/schema.rb
@@@ -11,12 -11,12 +11,12 @@@
  #
  # It's strongly recommended to check this file into your version control system.
  
- ActiveRecord::Schema.define(:version => 20140402001908) do
+ ActiveRecord::Schema.define(:version => 20140407184311) do
  
    create_table "api_client_authorizations", :force => true do |t|
 -    t.string   "api_token",                                             :null => false
 -    t.integer  "api_client_id",                                         :null => false
 -    t.integer  "user_id",                                               :null => false
 +    t.string   "api_token",                                           :null => false
 +    t.integer  "api_client_id",                                       :null => false
 +    t.integer  "user_id",                                             :null => false
      t.string   "created_by_ip_address"
      t.string   "last_used_by_ip_address"
      t.datetime "last_used_at"
diff --cc services/api/test/unit/log_test.rb
index f2afee2,2898033..3876775
--- a/services/api/test/unit/log_test.rb
+++ b/services/api/test/unit/log_test.rb
@@@ -1,7 -1,228 +1,227 @@@
  require 'test_helper'
  
  class LogTest < ActiveSupport::TestCase
-   # test "the truth" do
-   #   assert true
-   # end
+   include CurrentApiClient
+ 
+   EVENT_TEST_METHODS = {
+     :create => [:created_at, :assert_nil, :assert_not_nil],
+     :update => [:modified_at, :assert_not_nil, :assert_not_nil],
+     :destroy => [nil, :assert_not_nil, :assert_nil],
+   }
+ 
+   def setup
+     @start_time = Time.now
+     @log_count = 1
+   end
+ 
+   def assert_properties(test_method, event, props, *keys)
+     verb = (test_method == :assert_nil) ? 'have nil' : 'define'
+     keys.each do |prop_name|
+       assert_includes(props, prop_name, "log properties missing #{prop_name}")
+       self.send(test_method, props[prop_name],
+                 "#{event.to_s} log should #{verb} #{prop_name}")
+     end
+   end
+ 
+   def get_logs_about(thing)
+     Log.where(object_uuid: thing.uuid).order("created_at ASC").all
+   end
+ 
+   def assert_logged(thing, event_type)
+     logs = get_logs_about(thing)
+     assert_equal(@log_count, logs.size, "log count mismatch")
+     @log_count += 1
+     log = logs.last
+     props = log.properties
+     assert_equal(current_user.andand.uuid, log.owner_uuid,
+                  "log is not owned by current user")
+     assert_equal(current_user.andand.uuid, log.modified_by_user_uuid,
+                  "log is not 'modified by' current user")
+     assert_equal(current_api_client.andand.uuid, log.modified_by_client_uuid,
+                  "log is not 'modified by' current client")
 -    assert_equal(thing.kind, log.object_kind, "log kind mismatch")
+     assert_equal(thing.uuid, log.object_uuid, "log UUID mismatch")
+     assert_equal(event_type.to_s, log.event_type, "log event type mismatch")
+     time_method, old_props_test, new_props_test = EVENT_TEST_METHODS[event_type]
+     if time_method.nil? or (timestamp = thing.send(time_method)).nil?
+       assert(log.event_at >= @start_time, "log timestamp too old")
+     else
+       assert_in_delta(timestamp, log.event_at, 1, "log timestamp mismatch")
+     end
+     assert_properties(old_props_test, event_type, props,
+                       'old_etag', 'old_attributes')
+     assert_properties(new_props_test, event_type, props,
+                       'new_etag', 'new_attributes')
+     yield props if block_given?
+   end
+ 
+   def assert_auth_logged_with_clean_properties(auth, event_type)
+     assert_logged(auth, event_type) do |props|
+       ['old_attributes', 'new_attributes'].map { |k| props[k] }.compact
+         .each do |attributes|
+         refute_includes(attributes, 'api_token',
+                         "auth log properties include sensitive API token")
+       end
+       yield props if block_given?
+     end
+   end
+ 
+   def set_user_from_auth(auth_name)
+     client_auth = api_client_authorizations(auth_name)
+     Thread.current[:api_client_authorization] = client_auth
+     Thread.current[:api_client] = client_auth.api_client
+     Thread.current[:user] = client_auth.user
+   end
+ 
+   test "creating a user makes a log" do
+     set_user_from_auth :admin_trustedclient
+     u = User.new(first_name: "Log", last_name: "Test")
+     u.save!
+     assert_logged(u, :create) do |props|
+       assert_equal(u.etag, props['new_etag'], "new user etag mismatch")
+       assert_equal(u.first_name, props['new_attributes']['first_name'],
+                    "new user first name mismatch")
+       assert_equal(u.last_name, props['new_attributes']['last_name'],
+                    "new user first name mismatch")
+     end
+   end
+ 
+   test "updating a virtual machine makes a log" do
+     set_user_from_auth :admin_trustedclient
+     vm = virtual_machines(:testvm)
+     orig_etag = vm.etag
+     vm.hostname = 'testvm.testshell'
+     vm.save!
+     assert_logged(vm, :update) do |props|
+       assert_equal(orig_etag, props['old_etag'], "updated VM old etag mismatch")
+       assert_equal(vm.etag, props['new_etag'], "updated VM new etag mismatch")
+       assert_equal('testvm.shell', props['old_attributes']['hostname'],
+                    "updated VM old name mismatch")
+       assert_equal('testvm.testshell', props['new_attributes']['hostname'],
+                    "updated VM new name mismatch")
+     end
+   end
+ 
+   test "destroying an authorization makes a log" do
+     set_user_from_auth :admin_trustedclient
+     auth = api_client_authorizations(:spectator)
+     orig_etag = auth.etag
+     orig_attrs = auth.attributes
+     orig_attrs.delete 'api_token'
+     auth.destroy
+     assert_logged(auth, :destroy) do |props|
+       assert_equal(orig_etag, props['old_etag'], "destroyed auth etag mismatch")
+       assert_equal(orig_attrs, props['old_attributes'],
+                    "destroyed auth attributes mismatch")
+     end
+   end
+ 
+   test "saving an unchanged client still makes a log" do
+     set_user_from_auth :admin_trustedclient
+     client = api_clients(:untrusted)
+     client.is_trusted = client.is_trusted
+     client.save!
+     assert_logged(client, :update) do |props|
+       ['old', 'new'].each do |age|
+         assert_equal(client.etag, props["#{age}_etag"],
+                      "unchanged client #{age} etag mismatch")
+         assert_equal(client.attributes, props["#{age}_attributes"],
+                      "unchanged client #{age} attributes mismatch")
+       end
+     end
+   end
+ 
+   test "updating a group twice makes two logs" do
+     set_user_from_auth :admin_trustedclient
+     group = groups(:empty_lonely_group)
+     name1 = group.name
+     name2 = "#{name1} under test"
+     group.name = name2
+     group.save!
+     assert_logged(group, :update) do |props|
+       assert_equal(name1, props['old_attributes']['name'],
+                    "group start name mismatch")
+       assert_equal(name2, props['new_attributes']['name'],
+                    "group updated name mismatch")
+     end
+     group.name = name1
+     group.save!
+     assert_logged(group, :update) do |props|
+       assert_equal(name2, props['old_attributes']['name'],
+                    "group pre-revert name mismatch")
+       assert_equal(name1, props['new_attributes']['name'],
+                    "group final name mismatch")
+     end
+   end
+ 
+   test "making a log doesn't get logged" do
+     set_user_from_auth :active_trustedclient
+     log = Log.new
+     log.save!
+     assert_equal(0, get_logs_about(log).size, "made a Log about a Log")
+   end
+ 
+   test "non-admins can't modify or delete logs" do
+     set_user_from_auth :active_trustedclient
+     log = Log.new(summary: "immutable log test")
+     assert_nothing_raised { log.save! }
+     log.summary = "log mutation test should fail"
+     assert_raise(ArvadosModel::PermissionDeniedError) { log.save! }
+     assert_raise(ArvadosModel::PermissionDeniedError) { log.destroy }
+   end
+ 
+   test "admins can modify and delete logs" do
+     set_user_from_auth :admin_trustedclient
+     log = Log.new(summary: "admin log mutation test")
+     assert_nothing_raised { log.save! }
+     log.summary = "admin mutated log test"
+     assert_nothing_raised { log.save! }
+     assert_nothing_raised { log.destroy }
+   end
+ 
+   test "failure saving log causes failure saving object" do
+     Log.class_eval do
+       alias_method :_orig_validations, :perform_validations
+       def perform_validations(options)
+         false
+       end
+     end
+     begin
+       set_user_from_auth :active_trustedclient
+       user = users(:active)
+       user.first_name = 'Test'
+       assert_raise(ActiveRecord::RecordInvalid) { user.save! }
+     ensure
+       Log.class_eval do
+         alias_method :perform_validations, :_orig_validations
+       end
+     end
+   end
+ 
+   test "don't log changes only to ApiClientAuthorization.last_used_*" do
+     set_user_from_auth :admin_trustedclient
+     auth = api_client_authorizations(:spectator)
+     start_log_count = get_logs_about(auth).size
+     auth.last_used_at = Time.now
+     auth.last_used_by_ip_address = '::1'
+     auth.save!
+     assert_equal(start_log_count, get_logs_about(auth).size,
+                  "log count changed after 'using' ApiClientAuthorization")
+     auth.created_by_ip_address = '::1'
+     auth.save!
+     assert_logged(auth, :update)
+   end
+ 
+   test "token isn't included in ApiClientAuthorization logs" do
+     set_user_from_auth :admin_trustedclient
+     auth = ApiClientAuthorization.new
+     auth.user = users(:spectator)
+     auth.api_client = api_clients(:untrusted)
+     auth.save!
+     assert_auth_logged_with_clean_properties(auth, :create)
+     auth.expires_at = Time.now
+     auth.save!
+     assert_auth_logged_with_clean_properties(auth, :update)
+     auth.destroy
+     assert_auth_logged_with_clean_properties(auth, :destroy)
+   end
  end

commit cc5023d40182e503e8ba109fc86e09efd6337836
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Fri Apr 11 15:45:08 2014 -0400

    API server tests pass, workbench tests are failing

diff --git a/services/api/Gemfile b/services/api/Gemfile
index 5932778..25b2c24 100644
--- a/services/api/Gemfile
+++ b/services/api/Gemfile
@@ -63,4 +63,4 @@ gem 'test_after_commit', :group => :test
 gem 'google-api-client', '~> 0.6.3'
 gem 'trollop'
 
-gem 'arvados-cli', '>= 0.1.20140328152103'
+#gem 'arvados-cli', '>= 0.1.20140328152103'
diff --git a/services/api/Gemfile.lock b/services/api/Gemfile.lock
index 39718bd..95f37df 100644
--- a/services/api/Gemfile.lock
+++ b/services/api/Gemfile.lock
@@ -35,20 +35,6 @@ GEM
     addressable (2.3.5)
     andand (1.3.3)
     arel (3.0.2)
-    arvados (0.1.20140328152103)
-      activesupport (>= 3.2.13)
-      andand
-      google-api-client (~> 0.6.3)
-      json (>= 1.7.7)
-    arvados-cli (0.1.20140328152103)
-      activesupport (~> 3.2, >= 3.2.13)
-      andand (~> 1.3, >= 1.3.3)
-      arvados (~> 0.1.0)
-      curb (~> 0.8)
-      google-api-client (~> 0.6.3)
-      json (~> 1.7, >= 1.7.7)
-      oj (~> 2.0, >= 2.0.3)
-      trollop (~> 2.0)
     autoparse (0.3.3)
       addressable (>= 2.3.1)
       extlib (>= 0.9.15)
@@ -67,7 +53,6 @@ GEM
       coffee-script-source
       execjs
     coffee-script-source (1.6.3)
-    curb (0.8.5)
     daemon_controller (1.1.7)
     erubis (2.7.0)
     execjs (2.0.2)
@@ -198,7 +183,6 @@ PLATFORMS
 DEPENDENCIES
   acts_as_api
   andand
-  arvados-cli (>= 0.1.20140328152103)
   coffee-rails (~> 3.2.0)
   google-api-client (~> 0.6.3)
   jquery-rails
diff --git a/services/api/app/controllers/application_controller.rb b/services/api/app/controllers/application_controller.rb
index 94ef19c..9aad195 100644
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@ -251,7 +251,7 @@ class ApplicationController < ActionController::Base
       end
     else
       @offset = 0
-    end      
+    end
 
     orders = []
     if params[:order]
@@ -465,7 +465,7 @@ class ApplicationController < ActionController::Base
       order: { type: 'string', required: false }
     }
   end
-  
+
   def client_accepts_plain_text_stream
     (request.headers['Accept'].split(' ') &
      ['text/plain', '*/*']).count > 0
diff --git a/services/api/app/controllers/arvados/v1/links_controller.rb b/services/api/app/controllers/arvados/v1/links_controller.rb
index deeda28..1b79295 100644
--- a/services/api/app/controllers/arvados/v1/links_controller.rb
+++ b/services/api/app/controllers/arvados/v1/links_controller.rb
@@ -1,10 +1,33 @@
 class Arvados::V1::LinksController < ApplicationController
-  def index
+
+  prepend_before_filter :load_kind_params, :only => :index
+
+  def create
+    resource_attrs.delete :head_kind
+    resource_attrs.delete :tail_kind
+    super
+  end
+
+  def load_kind_params
     if params[:tail_uuid]
       params[:where] = Oj.load(params[:where]) if params[:where].is_a?(String)
-      params[:where] ||= {}
-      params[:where][:tail_uuid] = params[:tail_uuid]
+      @where ||= {}
+      @where[:tail_uuid] = params[:tail_uuid]
     end
-    super
+
+    if params[:where] and params[:where].is_a? Hash
+      if params[:where][:head_kind]
+        params[:filters] ||= []
+        params[:filters] << ['head_uuid', 'is_a', params[:where][:head_kind]]
+        params[:where].delete :head_kind
+      end
+      if params[:where][:tail_kind]
+        params[:filters] ||= []
+        params[:filters] << ['tail_uuid', 'is_a', params[:where][:tail_kind]]
+        params[:where].delete :tail_kind
+      end
+    end
+
   end
+
 end
diff --git a/services/api/app/controllers/arvados/v1/users_controller.rb b/services/api/app/controllers/arvados/v1/users_controller.rb
index 0934642..de067ce 100644
--- a/services/api/app/controllers/arvados/v1/users_controller.rb
+++ b/services/api/app/controllers/arvados/v1/users_controller.rb
@@ -59,7 +59,7 @@ class Arvados::V1::UsersController < ApplicationController
           "but is not invited"
         raise ArgumentError.new "Cannot activate without being invited."
       end
-      act_as_system_user do       
+      act_as_system_user do
         required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
                                     system_user_uuid,
                                     'signature',
@@ -130,7 +130,7 @@ class Arvados::V1::UsersController < ApplicationController
                     params[:repo_name], params[:vm_uuid]
     end
 
-    render json: { kind: "arvados#HashList", items: @response }
+    render json: { kind: "arvados#HashList", items: @response.as_api_response(nil) }
   end
 
   # delete user agreements, vm, repository, login links; set state to inactive
diff --git a/services/api/app/models/arvados_model.rb b/services/api/app/models/arvados_model.rb
index 493cf82..0cc26c5 100644
--- a/services/api/app/models/arvados_model.rb
+++ b/services/api/app/models/arvados_model.rb
@@ -229,6 +229,24 @@ class ArvadosModel < ActiveRecord::Base
     end
   end
 
+  class Email
+    def self.kind
+      "email"
+    end
+
+    def kind
+      self.class.kind
+    end
+
+    def self.readable_by (u)
+      self
+    end
+
+    def self.where (u)
+      [{:uuid => u[:uuid]}]
+    end
+  end
+
   def self.resource_class_for_uuid(uuid)
     if uuid.is_a? ArvadosModel
       return uuid.class
@@ -245,6 +263,11 @@ class ArvadosModel < ActiveRecord::Base
     uuid.match @@UUID_REGEX do |re|
       return uuid_prefixes[re[1]] if uuid_prefixes[re[1]]
     end
+
+    if uuid.match /.+ at .+/
+      return Email
+    end
+
     nil
   end
 
diff --git a/services/api/app/models/link.rb b/services/api/app/models/link.rb
index 8e17ce6..cf4ffce 100644
--- a/services/api/app/models/link.rb
+++ b/services/api/app/models/link.rb
@@ -9,16 +9,13 @@ class Link < ArvadosModel
   after_create :maybe_invalidate_permissions_cache
   after_destroy :maybe_invalidate_permissions_cache
 
-  attr_accessor :head
-  attr_accessor :tail
-
   api_accessible :user, extend: :common do |t|
     t.add :tail_uuid
     t.add :link_class
     t.add :name
     t.add :head_uuid
-    t.add :head, :if => :head
-    t.add :tail, :if => :tail
+    t.add :head_kind
+    t.add :tail_kind
     t.add :properties
   end
 
@@ -27,6 +24,18 @@ class Link < ArvadosModel
     super
   end
 
+  def head_kind
+    if k = ArvadosModel::resource_class_for_uuid(head_uuid)
+      k.kind
+    end
+  end
+
+  def tail_kind
+    if k = ArvadosModel::resource_class_for_uuid(tail_uuid)
+      k.kind
+    end
+  end
+
   protected
 
   def permission_to_attach_to_objects
diff --git a/services/api/app/models/user.rb b/services/api/app/models/user.rb
index 41858e8..50dc668 100644
--- a/services/api/app/models/user.rb
+++ b/services/api/app/models/user.rb
@@ -129,7 +129,6 @@ class User < ArvadosModel
   def unsetup
     # delete oid_login_perms for this user
     oid_login_perms = Link.where(tail_uuid: self.email,
-                                 head_kind: 'arvados#user',
                                  link_class: 'permission',
                                  name: 'can_login')
     oid_login_perms.each do |perm|
@@ -138,7 +137,6 @@ class User < ArvadosModel
 
     # delete repo_perms for this user
     repo_perms = Link.where(tail_uuid: self.uuid,
-                            head_kind: 'arvados#repository',
                             link_class: 'permission',
                             name: 'can_write')
     repo_perms.each do |perm|
@@ -147,7 +145,6 @@ class User < ArvadosModel
 
     # delete vm_login_perms for this user
     vm_login_perms = Link.where(tail_uuid: self.uuid,
-                                head_kind: 'arvados#virtualMachine',
                                 link_class: 'permission',
                                 name: 'can_login')
     vm_login_perms.each do |perm|
@@ -160,7 +157,6 @@ class User < ArvadosModel
     end.first
     group_perms = Link.where(tail_uuid: self.uuid,
                              head_uuid: group[:uuid],
-                             head_kind: 'arvados#group',
                              link_class: 'permission',
                              name: 'can_read')
     group_perms.each do |perm|
@@ -169,7 +165,6 @@ class User < ArvadosModel
 
     # delete any signatures by this user
     signed_uuids = Link.where(link_class: 'signature',
-                              tail_kind: 'arvados#user',
                               tail_uuid: self.uuid)
     signed_uuids.each do |sign|
       Link.delete sign
@@ -254,17 +249,14 @@ class User < ArvadosModel
 
     # Check oid_login_perm
     oid_login_perms = Link.where(tail_uuid: self.email,
-                                   head_kind: 'arvados#user',
                                    link_class: 'permission',
-                                   name: 'can_login')
+                                   name: 'can_login').where("head_uuid like ?", User.uuid_like_pattern)
 
     if !oid_login_perms.any?
       # create openid login permission
       oid_login_perm = Link.create(link_class: 'permission',
                                    name: 'can_login',
-                                   tail_kind: 'email',
                                    tail_uuid: self.email,
-                                   head_kind: 'arvados#user',
                                    head_uuid: self.uuid,
                                    properties: login_perm_props
                                   )
@@ -291,7 +283,6 @@ class User < ArvadosModel
 
       # Look for existing repository access for this repo
       repo_perms = Link.where(tail_uuid: self.uuid,
-                              head_kind: 'arvados#repository',
                               head_uuid: repo[:uuid],
                               link_class: 'permission',
                               name: 'can_write')
@@ -306,9 +297,7 @@ class User < ArvadosModel
     repo ||= Repository.create(name: repo_name)
     logger.info { "repo uuid: " + repo[:uuid] }
 
-    repo_perm = Link.create(tail_kind: 'arvados#user',
-                            tail_uuid: self.uuid,
-                            head_kind: 'arvados#repository',
+    repo_perm = Link.create(tail_uuid: self.uuid,
                             head_uuid: repo[:uuid],
                             link_class: 'permission',
                             name: 'can_write')
@@ -336,7 +325,6 @@ class User < ArvadosModel
 
       login_perms = Link.where(tail_uuid: self.uuid,
                               head_uuid: vm[:uuid],
-                              head_kind: 'arvados#virtualMachine',
                               link_class: 'permission',
                               name: 'can_login')
 
@@ -349,9 +337,7 @@ class User < ArvadosModel
       end
 
       if !perm_exists
-        login_perm = Link.create(tail_kind: 'arvados#user',
-                                 tail_uuid: self.uuid,
-                                 head_kind: 'arvados#virtualMachine',
+        login_perm = Link.create(tail_uuid: self.uuid,
                                  head_uuid: vm[:uuid],
                                  link_class: 'permission',
                                  name: 'can_login',
@@ -380,14 +366,11 @@ class User < ArvadosModel
 
       group_perms = Link.where(tail_uuid: self.uuid,
                               head_uuid: group[:uuid],
-                              head_kind: 'arvados#group',
                               link_class: 'permission',
                               name: 'can_read')
 
       if !group_perms.any?
-        group_perm = Link.create(tail_kind: 'arvados#user',
-                                 tail_uuid: self.uuid,
-                                 head_kind: 'arvados#group',
+        group_perm = Link.create(tail_uuid: self.uuid,
                                  head_uuid: group[:uuid],
                                  link_class: 'permission',
                                  name: 'can_read')
@@ -407,9 +390,7 @@ class User < ArvadosModel
     act_as_system_user do
       Link.create(link_class: 'permission',
                   name: 'can_manage',
-                  tail_kind: 'arvados#group',
                   tail_uuid: system_group_uuid,
-                  head_kind: 'arvados#user',
                   head_uuid: self.uuid)
     end
   end
diff --git a/services/api/db/migrate/20140325175653_remove_kind_columns.rb b/services/api/db/migrate/20140325175653_remove_kind_columns.rb
index 115048d..1ecd5d5 100644
--- a/services/api/db/migrate/20140325175653_remove_kind_columns.rb
+++ b/services/api/db/migrate/20140325175653_remove_kind_columns.rb
@@ -1,13 +1,21 @@
 class RemoveKindColumns < ActiveRecord::Migration
+  include CurrentApiClient
+
   def up
     remove_column :links, :head_kind
     remove_column :links, :tail_kind
-    remove_column :logs, :object_kind
   end
 
   def down
     add_column :links, :head_kind, :string
     add_column :links, :tail_kind, :string
-    add_column :logs, :object_kind, :string
+
+    act_as_system_user do
+      Link.all.each do |l|
+        l.head_kind = ArvadosModel::resource_class_for_uuid(l.head_uuid).kind if l.head_uuid
+        l.tail_kind = ArvadosModel::resource_class_for_uuid(l.tail_uuid).kind if l.tail_uuid
+        l.save
+      end
+    end
   end
 end
diff --git a/services/api/db/schema.rb b/services/api/db/schema.rb
index a63fdf4..a2b89e3 100644
--- a/services/api/db/schema.rb
+++ b/services/api/db/schema.rb
@@ -182,8 +182,8 @@ ActiveRecord::Schema.define(:version => 20140402001908) do
     t.boolean  "running"
     t.boolean  "success"
     t.string   "output"
-    t.datetime "created_at",                                  :null => false
-    t.datetime "updated_at",                                  :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.string   "priority"
     t.string   "is_locked_by_uuid"
     t.string   "log"
@@ -245,6 +245,8 @@ ActiveRecord::Schema.define(:version => 20140402001908) do
     t.string   "head_uuid"
     t.text     "properties"
     t.datetime "updated_at"
+    t.string   "head_kind"
+    t.string   "tail_kind"
   end
 
   add_index "links", ["created_at"], :name => "index_links_on_created_at"
diff --git a/services/api/lib/kind_and_etag.rb b/services/api/lib/kind_and_etag.rb
index 9df1289..89c01ef 100644
--- a/services/api/lib/kind_and_etag.rb
+++ b/services/api/lib/kind_and_etag.rb
@@ -5,10 +5,13 @@ module KindAndEtag
   end
 
   module ClassMethods
+    def kind
+      'arvados#' + self.to_s.camelcase(:lower)
+    end
   end
 
   def kind
-    'arvados#' + self.class.to_s.camelcase(:lower)
+    self.class.kind
   end
 
   def etag
diff --git a/services/api/test/fixtures/groups.yml b/services/api/test/fixtures/groups.yml
index 958aab9..c2f2dde 100644
--- a/services/api/test/fixtures/groups.yml
+++ b/services/api/test/fixtures/groups.yml
@@ -22,6 +22,12 @@ system_owned_group:
   name: System Private
   description: System-owned Group
 
+system_group:
+  uuid: zzzzz-j7d0g-000000000000000
+  owner_uuid: zzzzz-tpzed-000000000000000
+  name: System Private
+  description: System-owned Group
+
 empty_lonely_group:
   uuid: zzzzz-j7d0g-jtp06ulmvsezgyu
   owner_uuid: zzzzz-tpzed-000000000000000
diff --git a/services/api/test/fixtures/links.yml b/services/api/test/fixtures/links.yml
index 47de7e5..e3f6e2b 100644
--- a/services/api/test/fixtures/links.yml
+++ b/services/api/test/fixtures/links.yml
@@ -146,11 +146,9 @@ foo_file_readable_by_active_duplicate_permission:
   modified_by_user_uuid: zzzzz-tpzed-000000000000000
   modified_at: 2014-01-24 20:42:26 -0800
   updated_at: 2014-01-24 20:42:26 -0800
-  tail_kind: arvados#user
   tail_uuid: zzzzz-tpzed-xurymjxw79nv3jz
   link_class: permission
   name: can_read
-  head_kind: arvados#collection
   head_uuid: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45
   properties: {}
 
@@ -162,11 +160,9 @@ foo_file_readable_by_active_redundant_permission_via_private_group:
   modified_by_user_uuid: zzzzz-tpzed-000000000000000
   modified_at: 2014-01-24 20:42:26 -0800
   updated_at: 2014-01-24 20:42:26 -0800
-  tail_kind: arvados#group
   tail_uuid: zzzzz-j7d0g-22xp1wpjul508rk
   link_class: permission
   name: can_read
-  head_kind: arvados#collection
   head_uuid: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45
   properties: {}
 
@@ -234,11 +230,9 @@ foo_repository_readable_by_spectator:
   modified_by_user_uuid: zzzzz-tpzed-000000000000000
   modified_at: 2014-01-24 20:42:26 -0800
   updated_at: 2014-01-24 20:42:26 -0800
-  tail_kind: arvados#user
   tail_uuid: zzzzz-tpzed-l1s2piq4t4mps8r
   link_class: permission
   name: can_read
-  head_kind: arvados#repository
   head_uuid: zzzzz-2x53u-382brsig8rp3666
   properties: {}
 
@@ -250,11 +244,9 @@ miniadmin_user_is_a_testusergroup_admin:
   modified_by_user_uuid: zzzzz-tpzed-000000000000000
   modified_at: 2014-04-01 13:53:33 -0400
   updated_at: 2014-04-01 13:53:33 -0400
-  tail_kind: arvados#user
   tail_uuid: zzzzz-tpzed-2bg9x0oeydcw5hm
   link_class: permission
   name: can_manage
-  head_kind: arvados#group
   head_uuid: zzzzz-j7d0g-48foin4vonvc2at
   properties: {}
 
@@ -266,11 +258,9 @@ rominiadmin_user_is_a_testusergroup_admin:
   modified_by_user_uuid: zzzzz-tpzed-000000000000000
   modified_at: 2014-04-01 13:53:33 -0400
   updated_at: 2014-04-01 13:53:33 -0400
-  tail_kind: arvados#user
   tail_uuid: zzzzz-tpzed-4hvxm4n25emegis
   link_class: permission
   name: can_read
-  head_kind: arvados#group
   head_uuid: zzzzz-j7d0g-48foin4vonvc2at
   properties: {}
 
@@ -282,10 +272,8 @@ testusergroup_can_manage_active_user:
   modified_by_user_uuid: zzzzz-tpzed-000000000000000
   modified_at: 2014-04-01 13:56:10 -0400
   updated_at: 2014-04-01 13:56:10 -0400
-  tail_kind: arvados#group
   tail_uuid: zzzzz-j7d0g-48foin4vonvc2at
   link_class: permission
   name: can_manage
-  head_kind: arvados#user
   head_uuid: zzzzz-tpzed-xurymjxw79nv3jz
   properties: {}
diff --git a/services/api/test/functional/arvados/v1/links_controller_test.rb b/services/api/test/functional/arvados/v1/links_controller_test.rb
index d2863f3..4c0c8dc 100644
--- a/services/api/test/functional/arvados/v1/links_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/links_controller_test.rb
@@ -19,7 +19,7 @@ class Arvados::V1::LinksControllerTest < ActionController::TestCase
       assert_equal false, assigns(:object).properties.has_key?(:username)
     end
   end
-  
+
   test "head must exist" do
     link = {
       link_class: 'test',
@@ -44,6 +44,38 @@ class Arvados::V1::LinksControllerTest < ActionController::TestCase
     assert_response 422
   end
 
+  test "head and tail exist" do
+    link = {
+      link_class: 'test',
+      name: 'stuff',
+      head_uuid: users(:active).uuid,
+      tail_uuid: users(:spectator).uuid,
+    }
+    authorize_with :admin
+    post :create, link: link
+    assert_response :success
+    l = JSON.parse(@response.body)
+    assert 'arvados#user', l['head_kind']
+    assert 'arvados#user', l['tail_kind']
+  end
+
+  test "can supply head_kind and tail_kind without error" do
+    link = {
+      link_class: 'test',
+      name: 'stuff',
+      head_uuid: users(:active).uuid,
+      tail_uuid: users(:spectator).uuid,
+      head_kind: "arvados#user",
+      tail_kind: "arvados#user",
+    }
+    authorize_with :admin
+    post :create, link: link
+    assert_response :success
+    l = JSON.parse(@response.body)
+    assert 'arvados#user', l['head_kind']
+    assert 'arvados#user', l['tail_kind']
+  end
+
   test "tail must be visible by user" do
     link = {
       link_class: 'test',
@@ -95,10 +127,30 @@ class Arvados::V1::LinksControllerTest < ActionController::TestCase
     }
     assert_response :success
     found = assigns(:objects)
+    assert_not_equal 0, found.count
+    assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-f0-9]{32}\+\d+/}).count
+  end
+
+  test "test can still use where tail_kind" do
+    authorize_with :admin
+    get :index, {
+      where: { tail_kind: 'arvados#user' }
+    }
     assert_response :success
     found = assigns(:objects)
     assert_not_equal 0, found.count
-    assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-f0-9]{32}\+\d+/}).count
+    assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
+  end
+
+  test "test can still use where head_kind" do
+    authorize_with :admin
+    get :index, {
+      where: { head_kind: 'arvados#user' }
+    }
+    assert_response :success
+    found = assigns(:objects)
+    assert_not_equal 0, found.count
+    assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
   end
 
 
diff --git a/services/api/test/functional/arvados/v1/users_controller_test.rb b/services/api/test/functional/arvados/v1/users_controller_test.rb
index e62eff8..5f1a3f0 100644
--- a/services/api/test/functional/arvados/v1/users_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/users_controller_test.rb
@@ -67,7 +67,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       repo_name: repo_name,
       openid_prefix: 'https://www.google.com/accounts/o8/id',
       user: {
-        uuid: "this_is_agreeable",
+        uuid: 'zzzzz-tpzed-abcdefghijklmno',
         first_name: "in_create_test_first_name",
         last_name: "test_last_name",
         email: "foo at example.com"
@@ -77,9 +77,10 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     response_items = JSON.parse(@response.body)['items']
 
     created = find_obj_in_resp response_items, 'User', nil
+
     assert_equal 'in_create_test_first_name', created['first_name']
     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
-    assert_equal 'this_is_agreeable', created['uuid']
+    assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
     assert_not_nil created['email'], 'expected non-nil email'
     assert_nil created['identity_url'], 'expected no identity_url'
 
@@ -106,7 +107,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       vm_uuid: @vm_uuid,
       openid_prefix: 'https://www.google.com/accounts/o8/id',
       user: {
-        uuid: "this_is_agreeable",
+        uuid: 'zzzzz-tpzed-abcdefghijklmno',
         first_name: "in_create_test_first_name",
         last_name: "test_last_name",
         email: "foo at example.com"
@@ -118,7 +119,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     created = find_obj_in_resp response_items, 'User', nil
     assert_equal 'in_create_test_first_name', created['first_name']
     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
-    assert_equal 'this_is_agreeable', created['uuid']
+    assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
     assert_not_nil created['email'], 'expected non-nil email'
     assert_nil created['identity_url'], 'expected no identity_url'
 
@@ -714,12 +715,12 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       end
 
       if object_type == 'User'
-        if !x['head_kind']
+        if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
           return_obj = x
           break
         end
       else  # looking for a link
-        if x['head_kind'] == head_kind
+        if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
           return_obj = x
           break
         end
@@ -745,19 +746,19 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       assert [] != object, "expected #{class_name} with name #{head_uuid}"
       head_uuid = object.first[:uuid]
     end
-    assert_equal link['link_class'], link_class,
+    assert_equal link_class, link['link_class'],
         "did not find expected link_class for #{link_object_name}"
 
-    assert_equal link['name'], link_name,
+    assert_equal link_name, link['name'],
         "did not find expected link_name for #{link_object_name}"
 
-    assert_equal link['tail_uuid'], tail_uuid,
+    assert_equal tail_uuid, link['tail_uuid'],
         "did not find expected tail_uuid for #{link_object_name}"
 
-    assert_equal link['head_kind'], head_kind,
+    assert_equal head_kind, link['head_kind'],
         "did not find expected head_kind for #{link_object_name}"
 
-    assert_equal link['head_uuid'], head_uuid,
+    assert_equal head_uuid, link['head_uuid'],
         "did not find expected head_uuid for #{link_object_name}"
   end
 
@@ -765,9 +766,8 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       expect_repo_perms, expect_vm_perms, expect_group_perms, expect_signatures
     # verify that all links are deleted for the user
     oid_login_perms = Link.where(tail_uuid: email,
-                                 head_kind: 'arvados#user',
                                  link_class: 'permission',
-                                 name: 'can_login')
+                                 name: 'can_login').where("head_uuid like ?", User.uuid_like_pattern)
     if expect_oid_login_perms
       assert oid_login_perms.any?, "expected oid_login_perms"
     else
@@ -775,9 +775,8 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     end
 
     repo_perms = Link.where(tail_uuid: uuid,
-                              head_kind: 'arvados#repository',
                               link_class: 'permission',
-                              name: 'can_write')
+                              name: 'can_write').where("head_uuid like ?", Repository.uuid_like_pattern)
     if expect_repo_perms
       assert repo_perms.any?, "expected repo_perms"
     else
@@ -785,9 +784,8 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     end
 
     vm_login_perms = Link.where(tail_uuid: uuid,
-                              head_kind: 'arvados#virtualMachine',
                               link_class: 'permission',
-                              name: 'can_login')
+                              name: 'can_login').where("head_uuid like ?", VirtualMachine.uuid_like_pattern)
     if expect_vm_perms
       assert vm_login_perms.any?, "expected vm_login_perms"
     else
@@ -799,7 +797,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     end.first
     group_read_perms = Link.where(tail_uuid: uuid,
                              head_uuid: group[:uuid],
-                             head_kind: 'arvados#group',
                              link_class: 'permission',
                              name: 'can_read')
     if expect_group_perms
@@ -809,7 +806,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     end
 
     signed_uuids = Link.where(link_class: 'signature',
-                                  tail_kind: 'arvados#user',
                                   tail_uuid: uuid)
 
     if expect_signatures
diff --git a/services/api/test/unit/user_test.rb b/services/api/test/unit/user_test.rb
index 16c05a7..6cee757 100644
--- a/services/api/test/unit/user_test.rb
+++ b/services/api/test/unit/user_test.rb
@@ -161,9 +161,7 @@ class UserTest < ActiveSupport::TestCase
     email = 'foo at example.com'
     openid_prefix = 'http://openid/prefix'
 
-    user = User.new
-    user.email = email
-    user.uuid = 'abcdefghijklmnop'
+    user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
 
     vm = VirtualMachine.create
 
@@ -173,8 +171,10 @@ class UserTest < ActiveSupport::TestCase
     verify_user resp_user, email
 
     oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
+
     verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
         resp_user[:uuid]
+
     assert_equal openid_prefix, oid_login_perm[:properties][:identity_url_prefix],
         'expected identity_url_prefix not found for oid_login_perm'
 
@@ -194,9 +194,7 @@ class UserTest < ActiveSupport::TestCase
     email = 'foo at example.com'
     openid_prefix = 'http://openid/prefix'
 
-    user = User.new
-    user.email = email
-    user.uuid = 'abcdefghijklmnop'
+    user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
 
     response = User.setup user, openid_prefix
 
@@ -243,16 +241,20 @@ class UserTest < ActiveSupport::TestCase
     verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
   end
 
-  def find_obj_in_resp (response, object_type, head_kind=nil)
+  def find_obj_in_resp (response_items, object_type, head_kind=nil)
     return_obj = nil
-    response.each { |x|
-      if x.class.name == object_type
-        if head_kind
-          if x.head_kind == head_kind
-            return_obj = x
-            break
-          end
-        else
+    response_items.each { |x|
+      if !x
+        next
+      end
+
+      if object_type == 'User'
+        if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
+          return_obj = x
+          break
+        end
+      else  # looking for a link
+        if ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
           return_obj = x
           break
         end
@@ -269,18 +271,18 @@ class UserTest < ActiveSupport::TestCase
   end
 
   def verify_link (link_object, link_class, link_name, tail_uuid, head_uuid)
-    assert_not_nil link_object, 'expected link for #{link_class} #{link_name}'
+    assert_not_nil link_object, "expected link for #{link_class} #{link_name}"
     assert_not_nil link_object[:uuid],
-        'expected non-nil uuid for link for #{link_class} #{link_name}'
+        "expected non-nil uuid for link for #{link_class} #{link_name}"
     assert_equal link_class, link_object[:link_class],
-        'expected link_class not found for #{link_class} #{link_name}'
+        "expected link_class not found for #{link_class} #{link_name}"
     assert_equal link_name, link_object[:name],
-        'expected link_name not found for #{link_class} #{link_name}'
+        "expected link_name not found for #{link_class} #{link_name}"
     assert_equal tail_uuid, link_object[:tail_uuid],
-        'expected tail_uuid not found for #{link_class} #{link_name}'
+        "expected tail_uuid not found for #{link_class} #{link_name}"
     if head_uuid
       assert_equal head_uuid, link_object[:head_uuid],
-          'expected head_uuid not found for #{link_class} #{link_name}'
+          "expected head_uuid not found for #{link_class} #{link_name}"
     end
   end
 

commit 4f552c0187f8c31d94ff74485c57ef7f9888597e
Merge: 4177bcc 506e567
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Fri Apr 11 09:44:13 2014 -0400

    Merged master

diff --cc services/api/app/models/user.rb
index 5c15fa2,5c03eda..41858e8
--- a/services/api/app/models/user.rb
+++ b/services/api/app/models/user.rb
@@@ -79,10 -80,10 +80,11 @@@ class User < ArvadosMode
          Group.where('owner_uuid in (?)', lookup_uuids).each do |group|
            newgroups << [group.owner_uuid, group.uuid, 'can_manage']
          end
-         Link.where('tail_uuid in (?) and link_class = ? and head_uuid like ?',
 -        Link.where('tail_uuid in (?) and link_class = ? and head_kind in (?)',
++        Link.where('tail_uuid in (?) and link_class = ? and (head_uuid like ? or head_uuid like ?)',
                     lookup_uuids,
                     'permission',
-                    Group.uuid_like_pattern).each do |link|
 -                   ['arvados#group', 'arvados#user']).each do |link|
++                   Group.uuid_like_pattern,
++                   User.uuid_like_pattern).each do |link|
            newgroups << [link.tail_uuid, link.head_uuid, link.name]
          end
          newgroups.each do |tail_uuid, head_uuid, perm_name|
diff --cc services/api/test/fixtures/links.yml
index 523c466,0342d3d..47de7e5
--- a/services/api/test/fixtures/links.yml
+++ b/services/api/test/fixtures/links.yml
@@@ -9,7 -9,9 +9,7 @@@ user_agreement_required
    tail_uuid: zzzzz-tpzed-000000000000000
    link_class: signature
    name: require
-   head_uuid: b519d9cb706a29fc7ea24dbea2f05851+93
 -  head_kind: arvados#collection
+   head_uuid: b519d9cb706a29fc7ea24dbea2f05851+249025
    properties: {}
  
  user_agreement_readable:
@@@ -23,7 -25,9 +23,7 @@@
    tail_uuid: zzzzz-j7d0g-fffffffffffffff
    link_class: permission
    name: can_read
-   head_uuid: b519d9cb706a29fc7ea24dbea2f05851+93
 -  head_kind: arvados#collection
+   head_uuid: b519d9cb706a29fc7ea24dbea2f05851+249025
    properties: {}
  
  active_user_member_of_all_users_group:
@@@ -65,7 -73,9 +65,7 @@@ user_agreement_signed_by_active
    tail_uuid: zzzzz-tpzed-xurymjxw79nv3jz
    link_class: signature
    name: click
-   head_uuid: b519d9cb706a29fc7ea24dbea2f05851+93
 -  head_kind: arvados#collection
+   head_uuid: b519d9cb706a29fc7ea24dbea2f05851+249025
    properties: {}
  
  user_agreement_signed_by_inactive:
@@@ -79,7 -89,9 +79,7 @@@
    tail_uuid: zzzzz-tpzed-7sg468ezxwnodxs
    link_class: signature
    name: click
-   head_uuid: b519d9cb706a29fc7ea24dbea2f05851+93
 -  head_kind: arvados#collection
+   head_uuid: b519d9cb706a29fc7ea24dbea2f05851+249025
    properties: {}
  
  spectator_user_member_of_all_users_group:

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list