Commit Graph

1079 Commits

Author SHA1 Message Date
Mathieu Lonjaret 2c5c524412 Merge "server/camlistored/ui: add map aspect" 2017-06-20 22:23:10 +00:00
mpl d2ced13e5e server/camlistored/ui: add map aspect
To display permanodes with a location on a map graphical interface (like
Google Maps, Open Street Map, etc).

Screenshots:
https://storage.googleapis.com/camlistore-screenshots/Screenshot_20170620-230922.png
https://storage.googleapis.com/camlistore-screenshots/Screenshot_20170620-231221.png
https://storage.googleapis.com/camlistore-screenshots/Screenshot_20170620-235006.png

Lots more features possible, but I think this is a good point to add it
as an mvp. TODOs in the code.

Using leaflet.js version 1.0.3, and tiles from mapbox.com (Open Street
Map).

Change-Id: Ib31610c122de633c5268174928c22c1cc481f388
2017-06-21 00:21:02 +02:00
mpl 04afc9ae8a pkg/server: add recovery option on web UI and instance page
When the blobpacked index gets corrupted/destroyed, it needs to be
rebuilt and hence camlistored refuses to start without the -recovery
flag being set if it detects it is needed.

This is a problem on GCE, because camlistored is handled by systemd, and
so the only way to restart camlistored with -recovery is to edit the
systemd service, then issue 'systemctl daemon-reload', and 'systemctl
restart camlistored'. Then revert the change for the next time
camlistored restarts. This is not user-friendly.

This change adds a check on camlistored startup based on the presence
and value (as a boolean) of the "camlistore-recovery" key as an instance
attribute. Therefore, the user only has to add the
("camlistore-recovery", "true") attribute in the Custom metadata of
their Google Cloud instance page to switch to recovery mode. (And
restart the instance).

As an additional feature (for non-GCE users), this change also adds the
option to restart the server in recovery mode from the status page of
the web UI.

Change-Id: I44f5ca293ddd0a0033fc5d9c2edca1bac0ee9c8f
2017-06-07 23:00:50 +02:00
mpl 8fa2ec5a06 camlistored/ui: refresh blob and permanode aspects state on navigation
Fixes #922

Change-Id: I02c3c01947f7ab29681fb96e69e6b1f17fa7b067
2017-04-28 19:35:22 +02:00
mpl 86679899f5 camlistored/ui: fix share URL dialog for all pages
The code to find the prefix URL that is used to display the share URL on
after successfully sharing an item, worked only on the main web UI page.
This change makes it work on hopefully any page.

Change-Id: I05e085f91ef7ebe39f880104e52ca487b80c607a
2017-04-27 19:12:10 +02:00
mpl dace68256b camlistored/ui: connect temp form to DOM before submitting
The download action of the web UI uses an ephemeral form, that we do not
connect to the DOM, behind the scenes. However, according to
https://html.spec.whatwg.org/multipage/forms.html#form-submission-algorithm,
step 2., a form must be connected to the DOM in order for it to be
submitted.

This change connects the form right before submitting, and removes it
from the DOM right after submission.

Fixes #921

Change-Id: I4d993c633c60a369ce4260f84731a64e8b955c76
2017-04-26 17:59:29 +02:00
Mathieu Lonjaret 9095ea9a00 Merge "server/camlistored/ui: enable multi-items sharing" 2017-04-17 15:55:39 +00:00
mpl 9e34d14ef5 pkg/serverinit: enable sharing on GCE by default
The default server config on GCE (as deployed by the launcher) did not
have a share handler. This CL adds one, so that users can benefit from
the new sharing feature from the web UI.

Also, the button for sharing from the web UI does not appear anymore if
the config that the web UI gets from the discovery does not have a
"shareRoot", because it's a strong hint that the server does not have a
share handler.

Change-Id: I6c444995339fda8dba864b1d6729fb7c1b6d72bd
2017-04-05 16:17:46 +02:00
mpl 0e55a06f5c server/camlistored/ui: enable multi-items sharing
Sharing through the web UI was limited to a selection of one (permanode)
file or directory.

This change enables sharing of all the selected items, as long as they
are (permanodes of) files or directories, by creating a new directory
blob containing the selected items. The new directory is the item
getting shared. For clarity, and hopefully helping with search later,
the new directory is named "shared-YYYYMMDDhhmmss".

Change-Id: Iabd2266c9af85f3e8fbfa56ce98f653c0ce0f1ee
2017-03-31 01:22:52 +02:00
mpl 77dfe8046d server/camlistored/ui: add "Share" feature
To share a file or directory through Camlistore's sharing
mechanism (https://camlistore.org/doc/sharing).

Only single-item sharing supported for now.

On success, the share URL is displayed in a dialog.
If the item is a file, it can be fetched with any HTTP client through
that URL. If the item is a dir, the share URL is of the claim, so one
must follow the transitive chain of sharing to get the directory's
children, i.e. use camget -shared.

Fixes #880

Change-Id: I324a684dec10225e5b8314dda7f1b77a0de6f727
2017-03-23 00:44:18 +01:00
mpl 71090f7c80 pkg/server: add files "zipper" to DownloadHandler
We want to add a feature for clients (the web UI), where they can select
a bunch of files and ask the server for a zip archive of all these files.

This CL modifies the DownloadHandler so it does exactly that upon
reception of a POST request with a query parameter of the form
files=sha1-foo,sha1-bar,sha1-baz

This CL also adds a new button to the contextual sidebar of the web UI,
that takes care of sending the download request to the server.

known limitations: only permanodes with file as camliContent are
accepted as a valid selection (i.e. no sets, or static-dirs, etc) for
now.

Implementation detail:
We're creating an ephemeral DOM form on the fly to send the request.
The reason is: if we sent it as a Go http request, we'd have to read
the response manually and then we'd have no way of writing it to disk.
If we did it with an xhr, we could write the response to disk by
creating a File or Blob and then using URL.createObjectURL(), but we'd
have to keep the response in memory while doing so, which is
unacceptable for large enough archives.

Fixes #899

Change-Id: I104f7c5bd10ab3369e28d33752380dd12b5b3e6b
2017-03-17 00:59:19 +01:00
mpl ceb5ea5b10 web UI: add "About" menu entry and dialog
This change adds an "About" entry to the header menu, that pops up an
"About" dialog when clicked on.

But, under this innocent sounding feature is actually a more important
change: this feature is partly added through the use of gopherjs
generated code. In addition, the element added (a menu item) is
integrated
seamlessly into the menu as a React element, thanks to the use of
github.com/myitcv/gopherjs/react.

pkg/env had to be broken with build tags, because importing
"cloud.google.com/go/compute/metadata" (or one of its deps) seems to be
breaking the generated javascript.
https://github.com/camlistore/camlistore/issues/904

github.com/myitcv/gopherjs/react at rev
c04b811da4a086defd882a94cc1901da2d2158b0

honnef.co/go/js/dom at rev 24aa052bc5c63cfb9383bf59493ee48621ca788c

Issue #904
Fixes #798

Change-Id: Ic09b94014d520277f8178727293787ece468babd
2017-03-07 00:24:07 +01:00
Mathieu Lonjaret a3d7e6183b Merge "camlistored/ui: remove deprecated getDOMNode calls" 2017-02-14 22:48:34 +00:00
mpl f4fc8921cd camlistored/ui: remove deprecated getDOMNode calls
getDOMNode is deprecated:
https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html#dom-node-refs

Also fix a couple of component instanciations that still didn't use React.createElement.

Change-Id: Ic15d353be3815796d0aa6a3591c215056805a5bf
2017-02-13 18:12:49 +01:00
Steve Armstrong b2fb893b48 ui: Fix js error on all search queries
React would bail out with:

    Uncaught TypeError: this.refs.searchbox.getDOMNode is not a function
      at Object.getSearchNode_ (http://localhost:3179/ui/header.js:321:33)

Change-Id: I26e3474ed08c9339eda2e78de87b458a4130c746
2017-02-12 22:47:53 -08:00
mpl 4d12c68989 camlistored: do not use syslog on windows
Change-Id: I351c45739c517c107a5f16fee4298af75086d81d
2017-02-08 02:16:21 +01:00
mpl 1e69b9f784 vendor: update cloud.google.com/go/logging to V2 API
In addition to API changes, the V2 logging API uses
google.golang.org/grpc, which does not rely directly on net/http. This
is a problem for us because, among other things, when needed (on
CoreOS), we insert the system Root CAs in the TLSConfig of the
default http client through httputil.InstallCerts, which has no effect
on google.golang.org/grpc calls. Therefore, we switch to
github.com/bradfitz/grpc-go instead, which does rely on net/http.

And since GRPC requires HTTP/2, we also now need to manually configure
the default transport (since we're already modifying it) to be HTTP/2
enabled.

Related dependencies updated/added:

updated:

cloud.google.com/go/logging
a64eb5d53f434cc548fd6b2898b5a3e8a0c31b78

github.com/golang/protobuf
8ee79997227bf9b34611aee7946ae64735e6fd93

added:

github.com/bradfitz/grpc-go
188a132adcfba339f1f2d5da52498451341f9ee8
as a replacement for google.golang.org/grpc

github.com/googleapis/gax-go
da06d194a00e19ce00d9011a13931c3f6f6887c7

google.golang.org/genproto/googleapis/logging
08f135d1a31b6ba454287638a3ce23a55adace6f

google.golang.org/genproto/googleapis/datastore
08f135d1a31b6ba454287638a3ce23a55adace6f

google.golang.org/api/support/bundler
e4c04685e5d7db47ff294aa9e514b3a638c431c9

google.golang.org/genproto/googleapis/rpc/status
08f135d1a31b6ba454287638a3ce23a55adace6f

Fixes #873

Change-Id: I3ba14c94122dd9f1b88ef61c2dc26430690d28a9
2017-02-06 19:59:24 +01:00
Filippo Valsorda 3fb504426a camlistored: add -syslog flag
Change-Id: I5ee14834d3083ed1e40dfbb3fc79fc5b5239caf2
2017-02-04 23:15:53 +00:00
Eric Drechsel 2b093f38c8 vendor: update react to 15.4.2
The main motivation is that we want to use gopherjs +
github.com/myitcv/gopherjs/react , which requires a recent react.

This CL also fully switches to only using minified js files.

The changes in server/camlistored/ui are the result of some react
API changes, such as:

 - wraps component instantiation in React.createElement
 - React.classSet -> classNames
 - Need tbody between table and tr in a couple places
 - component array elts need unique keys (longstanding warning)
 - change root elt from body to a child div (to fix warning)
 - don't check isMounted in container render function
 - fix a bunch of style keys using kebab-case instead of camelCase

Change-Id: Idc22d07704688ccde3e4f67d4f188a5ad32b6e32
2017-01-25 19:11:58 +01:00
mpl 7f59a27060 website: run on staging instance
Add the -staging flag to camweb so one can deploy on a staging
instance.
The instance name is then "camweb-staging" instead of "camweb", and its
hostname is "staging.camlistore.net", instead of "camlistore.org".

server/camnetdns: automatically and regularly discovers the IP of the
"camweb-staging" instance, so it can keep the record for
"staging.camlistore.net" up to date.

Change-Id: I7d64a774049ac01472666ee7e351fd6fb5e4c287
2017-01-24 15:34:37 +01:00
Mathieu Lonjaret f12b9fea60 Merge "pkg/deploy: no self-signed certs, name in camlistore.net" 2017-01-18 21:40:49 +00:00
Mathieu Lonjaret 8a17e7252b Merge "pkg/sorted/mysql: drop tables on reindex" 2017-01-18 18:14:06 +00:00
mpl af77128123 pkg/sorted/mysql: drop tables on reindex
When reindexing on a (My)SQL based sorted.KeyValue, we should recreate
the database schema from scratch, which means dropping the tables.

However, index.Reindex just calls Wipe on the newly created
sorted.KeyValue, which only deletes the rows, and does not drop the
tables.

Therefore, this CL changes the implementation of Wipe in the MySQL case,
so that it takes care of dropping the tables, and doing everything that
needs to be done afterwards to set up the sorted.KeyValue.

In addition, with the introduction of the sorted.NeedWipeError, we detect
upon initialization of a sorted.KeyValue if it failed because it needed
a schema update. If that is the case, and we're in reindex mode, we can
fix the sorted.KeyValue with a Wipe and carry on.

Finally, we introduce the new sorted.NewKeyValueMaybeWipe function that
automatically wipes a KeyValue when a NeedWipeError was returned upon
its creation.

Next, do the same with other sorted SQLs.

Fixes #806

Change-Id: I2032781cbf453a364880bd3e2e8b3c09aac7aed9
2017-01-16 19:10:05 +01:00
mpl 8813375592 pkg/deploy: no self-signed certs, name in camlistore.net
This CL changes the GCE launcher to work with the new features of
camlistored: i.e. that it can automatically get a hostname in
camlistore.net, and that it can get an HTTPS certificate from Let's
Encrypt, for said hostname.

In order for the user to easily (without having to look at the logs)
know what their hostname is, camlistored stores it as the
"camlistore-hostname" key in the custom metadata of the GCE instance.
The deployer can then query for that key, to report the hostname on the
instance creation success page.

Change-Id: Iaaef2d51f34fa5e1e0ee90097919abab7ee72a12
2017-01-13 16:47:04 +01:00
Mathieu Lonjaret d864e35802 Merge "server/camlistored: request a name in camlistore.net" 2017-01-13 14:50:31 +00:00
mpl 620388bd57 server/camlistored: request a name in camlistore.net
In order to use HTTPS, one must have a certificate, and one must have a
domain name for which the certificate is valid.
The first part is solved by the use of Let's Encrypt. For the second
part, we want to provide to any Camlistore instance a name such as
<gpgKeyId>.camlistore.net, where gpgKeyId is the fingerprint of its GPG
key. The DNS for camlistore.net agrees to add a record for that name if
and only if the Camlistore instance can prove it owns the GPG key, as
well as the IP address bound to that name in the DNS record.

A protocol such as the above is already implemented in pkg/gpgchallenge.

This CL:
- uses the client-side of the gpgchallenge protocol in camlistored, so
that it can claim a hostname in camlistore.net on startup (and then use
that hostname when requesting a certificate from Let's Encrypt).
- adds the configuration parameter "CamliNetIP" for the high-level
config. This parameter specifies the IP address that camlistored will
supply during the gpgpchallenge, so it can  prove to the DNS server that
we own this address.

Fixes #722

Change-Id: I6bf4ec149b6dffd0ae93a6fa7bf208b2e8a05445
2017-01-13 00:43:24 +01:00
mpl b0eefd74fa server/camnetdns: get certificate from Lets Encrypt
Change-Id: Icd67eca36a153fe142d07b39df9ace6ef8301992
2016-12-17 23:38:40 +01:00
mpl 9a32570a48 server/camnetdns: persist records in datastore
Store records in Google Datastore in production (on GCE), with an LRU
cache in front.

Keep dev mode that stores in sorted mem key value though.

Change-Id: I17b088b56a68a019f4e253b60c6bd42395a64984
2016-12-16 00:36:08 +01:00
mpl c55c8602d3 server/camlistored: use Let's Encrypt
Or to be more precise, golang.org/x/crypto/acme/autocert

The default behaviour regarding HTTPS certificates changes as such:

1) If the high-level config does not specify a certificate, the
low-level config used to be generated with a default certificate path.
This is no longer the case.
2) If the low-level config does not specify a certificate, we used to
generate self-signed ones at the default path. This is no longer always
the case. We only do this if our hostname does not look like an FQDN,
otherwise we try Let's Encrypt.
3) As a result, if the high-level config does not specify a certificate,
and the hostname looks like an FQDN, it is no longer the case that we'll
generate a self-signed. Let's Encrypt will be tried instead.

To sum up, the new rules are:
If cert/key files are specified, and found, use them.
If cert/key files are specified, not found, and the default values,
generate them (self-signed CA used as a cert), and use them.
If cert/key files are not specified, use Let's Encrypt if we have an
FQDN, otherwise generate self-signed.

Regarding cert caching:

On non-GCE, store the autocert cache dir in
osutil.CamliConfigDir()/letsencrypt.cache
On GCE, store in /tmp/camli-letsencrypt.cache

Fixes #701
Fixes #859

Change-Id: Id78a9c6f113fa93e38d690033c10a749d1844ea6
2016-12-05 19:43:37 +01:00
mpl 99a6268893 server/camlistored/ui: specify sort order in search queries
In particular, specify "blobref" when search is not about permanode
results (instead of the "-created" default).

Fixes #886

Change-Id: I112288d42ea498873a5dcc3ddd37aa780620f309
2016-11-30 17:14:05 +01:00
Mathieu Lonjaret 10fb1f2bd3 Merge "pkg/blobserver/blobpacked: change the meaning of -recovery" 2016-11-28 17:28:19 +00:00
Mathieu Lonjaret fd0ee3791c Merge "pkg/test/integration: make sure testing not linked in camlistored" 2016-11-28 16:59:30 +00:00
mpl 745f8516ea pkg/test/integration: make sure testing not linked in camlistored
I had to add the "-help" flag to camlistored, as otherwise relying on
the automatic usage gets us an exit status == 2, and hence an error when
running the Command.

fixes #475

Change-Id: I6f90329dbdb876a77c13d016f698de5026169e4a
2016-11-25 00:57:01 +01:00
mpl 06f6272e93 camlistored/ui: implement swipe for left/right nav on mobile
Naive implementation for now. I imitated how things were setup for the
left and right keys, but maybe the listener should be on the image
container instead of on the index page? It seems to work anyway.

No animation when starting to swipe though, which means users have no
clue swipe exists/works until they actually try to do it for real.

Change-Id: If0baed3c8d3ff1f5d8886fca891a8ac40980f66e
2016-11-23 17:56:01 +01:00
mpl 14322f8afe pkg/blobserver/blobpacked: change the meaning of -recovery
The -recovery flag from camlistored, now forces the blobpacked index to
be rebuilt, regardless of its state.

Fixes #876

Change-Id: I4e6bd5374ec68d7bb32de9fc119abbc881707625
2016-11-07 22:44:59 +01:00
Mathieu Lonjaret 4081409698 Merge "server/camnetdns: reply with NXDOMAIN when needed" 2016-10-31 17:21:38 +00:00
Filippo Valsorda e8b9df32af blobserver/b2: add new Storage based on Backblaze B2
github.com/FiloSottile/b2: c32038dd691290351948e8fbe956b0ade65e70ea

Change-Id: I0fb5ed3a622ed541170a9fb946b6781defef96fe
2016-10-23 18:04:48 +01:00
mpl 0ab95c3f13 server/camnetdns: reply with NXDOMAIN when needed
When we get a query for a name we are authoritative about, we should
reply with NXDOMAIN when this name does not exist.

This change moves the name lookup to as early as possible to make sure
of that. This means we're now doing lookups even for cases where we
technically wouldn't have needed them, so maybe a substantial increase
in load? We'll see.

Change-Id: I5e9946dd67757856f626f484b547197c6246cccd
2016-10-21 19:14:35 +02:00
mpl 0273e6c5f5 server/camnetdns: implement more of the DNS protocol
As Let's Encrypt DNS server (Unbound) is pretty strict, it
wouldn't resolve names camlistore.net until we implemented more of the
DNS protocol and fix various things.

Since I had no way at first to know what exactly it didn't like, I
started by fixing all errors and warnings reported at:
http://dnsviz.net/d/camlistore.net/dnssec/

Therefore, this CL adds:
-TCP support
-NS response
-SOA response
-MX (empty) response
-DNSKEY (empty) response
-TXT (empty) response
-explicit non-support of EDNS

Then I found out we also needed this:

-https://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00
-CAA response. A proper response is optional here, as Let's Encrypt only
enforces the response if it finds one. But we do have to reply.

Fixes #867

Change-Id: Ib45f8a642cd83cf19c8ab36435644a2c645a70e7
2016-10-20 17:53:11 +02:00
mpl 39a33c7fa9 server/camnetdns: make it work
Before that change, one would only get a response to a DNS query, if
directly sending the query to the dns server.

I think the main problem was that one has to copy the question section
of the query in the response message, which is part of what SetReply
does.

With this change, I seem to get responses (for e.g. www.camlistore.net
and 6401800c.camlistore.net), without having to specify a server to
query to dig (or nslookup), so by letting the resolver and the DNS
hierarchy follow its normal course.

Issue #722

Change-Id: I530529920fdaa3e5fb025c7684b563e3f05772ac
2016-10-06 16:26:18 +02:00
mpl 2c4332ada2 make.go: optionally build camnetdns
server/camnetdns: update to cloud.google.com/go imports.

vendor: add github.com/miekg/dns at rev
3f1f7c8ec9ead89493df11f2c3d8bec353a2c2c0 as a dep of server/camnetdns

Change-Id: Ief8e0ad3e09a6c3511c72a7991309808f855d3df
2016-10-04 01:58:50 +02:00
mpl ab06dbd80d vendor: rename google.golang.org/cloud to cloud.google.com/go
rm google.golang.org/cloud
add cloud.google.com/go at a47b182e769f5e75f5fc927ff6ee2678f7f552cf
update google.golang.org/api to 63cb68f1e3834e44683ca062ddf06cb9a889380a
update google.golang.org/grpc to
0e6ec3a4501ee9ee2d023abe92e436fd04ed4081
update go4.org to f5283521d7365fb2875408726e9cbf349f173767

fix in cmd/ pkg/ server/

TODO(mpl): fix misc/docker tools as well. next CL.

Fixes #832

Change-Id: I842b968a0afea8a5822913bd614d67cdbe50ee63
2016-09-08 15:14:12 +02:00
mpl c052bd2804 web UI: upload with input file button
Fixes #830

Change-Id: Ic69fb7e6edc6a0dc0d604356f0214aaf6c8136a9
2016-08-16 18:18:56 +02:00
mpl@serenity 5522ebbeb1 webUI: disable tokenAuth when auth is None
This allows deferring HTTP authentication and authorization to a proxy
(such as nginx) between Camlistore and the rest of the world, without
breaking the web UI.

Fixes #816

Change-Id: Ia4b5be8f2236ddac68dc0d3a09f0f24e588c4995
2016-06-28 01:56:08 +02:00
Mathieu Lonjaret fbe5656196 Merge "Add button to remove selection from current set." 2016-05-10 23:24:24 +00:00
Mathieu Lonjaret cdadfd650b Merge "server/camlistored: allow GCL for non-GCE" 2016-05-05 13:47:55 +00:00
mpl 1ddc5ec092 server/camlistored: allow GCL for non-GCE
This change enables camlistored to log on Google Cloud Logging even when
not running on Google Compute Engine.

The main reason is to help with debugging cloud logging bugs, because
it usually is easier to do so from a local camlistored than from one
running on GCE.

Related: issue #704

Change-Id: I7de23cf9365683f8641a6bbad0deab754fc579f7
2016-05-05 15:47:09 +02:00
Brad Fitzpatrick e305847941 Merge "ui: fix reload menu item for broken websocket connection" 2016-04-30 21:28:24 +00:00
Tilman Dilo d208b531c9 Fix permissions for files
Use mode 0644 instead of 0755 for non-vendored files.

Change-Id: Ifbe1d5e21f24814531248a8a6c84d6f0a72c071c
2016-04-28 21:15:09 +02:00
Tilman Dilo cb67c554ec ui: fix reload menu item for broken websocket connection
The "click to reload" menu item displayed when the websocket connection
fails was non-functional. Clicking on the menu item only produced an
error (Uncaught TypeError: Illegal invocation) in the JavaScript
console.

Change-Id: Iea44dd35c92c99562c35f87c38687f4fa433ad41
2016-04-28 21:11:44 +02:00