geerlingguy / ansible-role-elasticsearch Goto Github PK
View Code? Open in Web Editor NEWAnsible Role - Elasticsearch
Home Page: https://galaxy.ansible.com/geerlingguy/elasticsearch/
License: MIT License
Ansible Role - Elasticsearch
Home Page: https://galaxy.ansible.com/geerlingguy/elasticsearch/
License: MIT License
Hello !
Following the news of the fork of ElasticSearch for OpenSearch, is there a plan to support the OpenSearch fork ?
Thanks a lot for this role btw !
Cheers,
TASK [elasticsearch_new : Configure Elasticsearch 7+.] ********************************************************
changed: [x.x.x.x] => (item=/etc/elasticsearch/elasticsearch.yml)
changed: [x.x.x.x] => (item=/etc/elasticsearch/elasticsearch.yml)
changed: [x.x.x.x] => (item=/etc/elasticsearch/elasticsearch.yml)
failed: x.x.x.x => {"ansible_loop_var": "item", "changed": false, "checksum": "4218eb0f9d1fa2a2404c7bd3d8484aefe80cdb5a", "item": "/etc/elasticsearch/jvm.options.d/heap.options", "msg": "Destination directory /etc/elasticsearch/jvm.options.d does not exist"}
`(venv) rev@devnull:/opt/.work/devnull$ ansible-galaxy install geerlingguy.ansible-role-elasticsearch
Starting galaxy role install process
looks like this issue occurred on other repos due to the ansible-role prefix?
Elasticsearch 7.x comes with new parameters for discovery of cluster nodes:
https://www.elastic.co/guide/en/elasticsearch/reference/current/discovery-settings.html
If network.host: 0.0.0.0
is set, Elasticsearch will not start without setting initial_master_nodes
as well:
#/etc/elasticsearch/elasticsearch.yml
cluster.initial_master_nodes:
- "elastic0"
If this is not the case, Elasticsearch will fail to start with the following message:
[2019-07-03T14:23:13,130][ERROR][o.e.b.Bootstrap ] [elastic0] node validation exception
[1] bootstrap checks failed
[1]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
I did not check on the other parameters, seed_hosts
or seed_providers
. Probably they could be implemented in the same "task". However, a single-node Elasticsearch bootstraps fine by defining initial_master_nodes
only.
with snippets like below
- name: Install Elasticsearch.
package:
name: elasticsearch
state: "{{ elasticsearch_package_state }}"
there is no way to pin specific versions of elasticsearch, this is not very handy for keeping versions of elk stack nodes with consistent versions
ES is usually used in more than one instances.
Starting the Elasticsearch service fails with:
elasticsearch[6073]: JNA Warning: IOException removing temporary files: JNA temporary directory '${ES_TMPDIR}' does not exist
root@debian-10:~# printenv | grep ES_TMP
ES_TMPDIR=/tmp
Replacing -Djava.io.tmpdir=${ES_TMPDIR}
with -Djava.io.tmpdir=/tmp
in /etc/elasticsearch/jvm.options fixes the issue. It seems the environment variable is not being recognized.
Any idea?
Hi,
I saw there has been a pull request . Is there a reason it's not merged? Or is there an other way to install ElasticSearch plugins?
I use : elasticsearch_network_host: eth1
the playbook fails at :
TASK [geerlingguy.elasticsearch : Make sure Elasticsearch is running before proceeding.] ********************************************************************************************************************************
fatal: [vs-inf-prd-elm-fr-501]: FAILED! => {"changed": false, "elapsed": 300, "msg": "Timeout when waiting for _eth1_:9200"}
Hello,
I have a problem, because my project need Elasticsearch version 6. I have 2 computers. On first I installed role-elasticsearch on January 2020 and there works everything:
{
"name" : "KpjgCIr",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "PUwl9EAdTmeZhtMNmBf2YQ",
"version" : {
"number" : "6.8.6",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "3d9f765",
"build_date" : "2019-12-13T17:11:52.013738Z",
"build_snapshot" : false,
"lucene_version" : "7.7.2",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
On the second computer I installed yesterday. I added in configuration: elasticsearch_version: '6.x'
but it didn't help:
{
"name" : "dsjhf82754",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "7Hq6QNnuQQOls_hojmN7Nw",
"version" : {
"number" : "7.7.0",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "81a1e9eda8e6183f5237786246f6dced26a10eaf",
"build_date" : "2020-05-12T02:01:37.602180Z",
"build_snapshot" : false,
"lucene_version" : "8.5.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
Can you tell me, that I'm doing something wrong?
I haven't run this playbook for several months. Looks like a recent commit broke it for 1.9/2.0 versions of Ansible: 0914a77
TASK [geerlingguy.elasticsearch : Add Elasticsearch GPG key.] ******************
fatal: [nrg-logstash]: FAILED! => {"changed": false, "failed": true, "msg": "Unsupported proxy scheme: https. Currently ansible only supports HTTP proxies."}
It's kind of absurd that a HTTPS URL is not supported by rpm_key in the first place. But until it is, there should be an alternative that doesn't require modifying the module or running a proxy just to get the playbook to complete.
Reproduce on Centos 7
Java version : openjdk version "1.8.0_262"
i run ansible-galaxy install -r requirements.yml
to update the repo and get the tag 5.0.0
run again the playbook
TASK [geerlingguy.elasticsearch : Configure Elasticsearch.] ************************************************************
ok: [elasticserver] => (item=/etc/elasticsearch/elasticsearch.yml)
changed: [elasticserver] => (item=/etc/elasticsearch/jvm.options.d/heap.options)
RUNNING HANDLER [geerlingguy.elasticsearch : restart elasticsearch] ****************************************************
fatal: [elasticserver]: FAILED! => {"changed": false, "msg": "Unable to start service elasticsearch: Job for elasticsearch.service failed because the control process exited with error code. See \"systemctl status elasticsearch.service\" and \"journalctl -xe\" for details.\n"}
prompt output :
Sep 30 16:25:14 SRVLAPES1 systemd[1]: Starting Elasticsearch...
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: Exception in thread "main" java.lang.RuntimeException: starting jav
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: output:
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: error:
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: Unrecognized VM option 'UseConcMarkSweepGC'
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: Error: Could not create the Java Virtual Machine.
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: Error: A fatal exception has occurred. Program will exit.
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: at org.elasticsearch.tools.launchers.JvmErgonomics.flagsFinal(JvmEr
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: at org.elasticsearch.tools.launchers.JvmErgonomics.finalJvmOptions(
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: at org.elasticsearch.tools.launchers.JvmErgonomics.choose(JvmErgono
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: at org.elasticsearch.tools.launchers.JvmOptionsParser.jvmOptions(Jv
Sep 30 16:25:16 SRVLAPES1 systemd-entrypoint[25730]: at org.elasticsearch.tools.launchers.JvmOptionsParser.main(JvmOptio
Sep 30 16:25:16 SRVLAPES1 systemd[1]: elasticsearch.service: main process exited, code=exited, status=1/FAILURE
Sep 30 16:25:16 SRVLAPES1 systemd[1]: Failed to start Elasticsearch.
Sep 30 16:25:16 SRVLAPES1 systemd[1]: Unit elasticsearch.service entered failed state.
Sep 30 16:25:16 SRVLAPES1 systemd[1]: elasticsearch.service failed.
Sep 30 16:29:34 SRVLAPES1 systemd[1]: Starting Elasticsearch...
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: Exception in thread "main" java.lang.RuntimeException: starting jav
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: output:
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: error:
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: Unrecognized VM option 'UseConcMarkSweepGC'
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: Error: Could not create the Java Virtual Machine.
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: Error: A fatal exception has occurred. Program will exit.
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: at org.elasticsearch.tools.launchers.JvmErgonomics.flagsFinal(JvmEr
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: at org.elasticsearch.tools.launchers.JvmErgonomics.finalJvmOptions(
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: at org.elasticsearch.tools.launchers.JvmErgonomics.choose(JvmErgono
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: at org.elasticsearch.tools.launchers.JvmOptionsParser.jvmOptions(Jv
Sep 30 16:29:36 SRVLAPES1 systemd-entrypoint[26602]: at org.elasticsearch.tools.launchers.JvmOptionsParser.main(JvmOptio
Sep 30 16:29:36 SRVLAPES1 systemd[1]: elasticsearch.service: main process exited, code=exited, status=1/FAILURE
Sep 30 16:29:36 SRVLAPES1 systemd[1]: Failed to start Elasticsearch.
Here the syslog:
Apr 9 12:53:24 store-live systemd[1]: Started Elasticsearch.
Apr 9 12:53:24 store-live elasticsearch[56767]: OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
Apr 9 12:53:24 store-live elasticsearch[56767]: [0.000s][error][logging] Error opening log file 'logs/gc.log': No such file or directory
Apr 9 12:53:24 store-live elasticsearch[56767]: [0.000s][error][logging] Initialization of output 'file=logs/gc.log' using options 'filecount=32,filesize=64m' failed.
Apr 9 12:53:24 store-live elasticsearch[56767]: Invalid -Xlog option '-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m', see error log for details.
Apr 9 12:53:24 store-live elasticsearch[56767]: Error: Could not create the Java Virtual Machine.
Apr 9 12:53:24 store-live elasticsearch[56767]: Error: A fatal exception has occurred. Program will exit.
Apr 9 12:53:24 store-live systemd[1]: elasticsearch.service: Main process exited, code=exited, status=1/FAILURE
Apr 9 12:53:24 store-live systemd[1]: elasticsearch.service: Failed with result 'exit-code'.
I think it's because you replace the entire jvm.options file and it's broken for this versions matrix.
I think we have to do the same you said in this comment but even for ES 6.
Being able to configure JVM options using jvm.options.d
only starts working in elasticsearch 7.x
, and an install of 6.x
fails as this directory does not exist:
(item=/etc/elasticsearch/jvm.options.d/heap.options) => {"ansible_loop_var": "item", "changed": false, "checksum": "34a473b4557de33ad88f13c4ef2289c329071077", "item": "/etc/elasticsearch/jvm.options.d/heap.options", "msg": "Destination directory /etc/elasticsearch/jvm.options.d does not exist"}
There's an ES_HEAP_SIZE
environment variable that can be used to limit Elasticsearch RAM usage. It would be nice to allow that to be configured for the role. It's configured (along with other directives) inside /etc/default/elasticsearch
.
I have a fresh install of ansible on my Mac, with two ansible-galaxy installs, geerlingguy.java
and geerlingguy.elasticsearch
.
I'm trying to run this playbook:
---
- hosts: localhost
roles:
- geerlingguy.elasticsearch
It results in this error
TASK [geerlingguy.java : Define java_packages.] ****************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: '__java_packages' is undefined\n\nThe error appears to have been in '/Users/haywood/.ansible/roles/geerlingguy.java/tasks/main.yml': line 20, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Define java_packages.\n ^ here\n"}
I tried it on my newer mac, and an older one. I was able to get this working on a fresh Ubuntu install, same conditions (fresh ansible).
I'm just now learning this stuff, so apologies in advance if I'm missing something obvious. Thanks for your time.
Right now it's 6.x... should be 7.x now.
This is sort of a dupe of this issue: geerlingguy/ansible-role-nginx#21
Likewise, your Elasticsearch role explicitly restarts the service at the end of it. This doesn't work well if you want to modify ES configuration in another role executed after yours (in my case, modifying /etc/sysconfig/elasticsearch to increase heap size). Anyone who really, definitely needs elasticsearch running before executing another role should probably split them into different plays.
I'm trying to use this Ansible role to install ElasticSearch 8.x. When ElasticSearch tries starting it dies with an error:
org.elasticsearch.ElasticsearchSecurityException: invalid configuration for xpack.security.transport.ssl - [xpack.security.transport.ssl.enabled] is not set, but the following settings have been configured in elasticsearch.yml : [xpack.security.transport.ssl.keystore.secure_password,xpack.security.transport.ssl.truststore.secure_password] at org.elasticsearch.xpack.core.ssl.SSLService.validateServerConfiguration
It appears that some additional configuration needs to be done for 8.x in order to get it to run.
Hello,
I couldn't start elasticsearch because of the heap map size that was different in min and max default variables in file defaults/main.yml. I mention that I adapted the playbook a bit for my use but the main.
Currently elasticsearch_heap_size_min
and elasticsearch_heap_size_max
are not the same . But according to java configuration comment, it should be the same. I confirm that when I changed the value to match, i was able to start the service.
Below the comment that mention that point:
You should always set the min and max JVM heap
size to the same value. For example, to set
the heap to 4 GB, set:
-Xms4g
-Xmx4g
Currently the role is not completing CI tests successfully—ES installs, but won't start:
# journalctl -u elasticsearch
-- Logs begin at Sat 2020-09-26 04:08:07 UTC, end at Sat 2020-09-26 04:10:49 UTC. --
Sep 26 04:10:48 instance systemd[1]: Starting Elasticsearch...
Sep 26 04:10:49 instance systemd-entrypoint[4660]: Exception in thread "main" java.lang.RuntimeException: starting java failed with [1]
Sep 26 04:10:49 instance systemd-entrypoint[4660]: output:
Sep 26 04:10:49 instance systemd-entrypoint[4660]: error:
Sep 26 04:10:49 instance systemd-entrypoint[4660]: Unrecognized VM option 'UseConcMarkSweepGC'
Sep 26 04:10:49 instance systemd-entrypoint[4660]: Error: Could not create the Java Virtual Machine.
Sep 26 04:10:49 instance systemd-entrypoint[4660]: Error: A fatal exception has occurred. Program will exit.
Sep 26 04:10:49 instance systemd-entrypoint[4660]: at org.elasticsearch.tools.launchers.JvmErgonomics.flagsFinal(JvmErgonomics.java:126)
Sep 26 04:10:49 instance systemd-entrypoint[4660]: at org.elasticsearch.tools.launchers.JvmErgonomics.finalJvmOptions(JvmErgonomics.java:88)
Sep 26 04:10:49 instance systemd-entrypoint[4660]: at org.elasticsearch.tools.launchers.JvmErgonomics.choose(JvmErgonomics.java:59)
Sep 26 04:10:49 instance systemd-entrypoint[4660]: at org.elasticsearch.tools.launchers.JvmOptionsParser.jvmOptions(JvmOptionsParser.java:137)
Sep 26 04:10:49 instance systemd-entrypoint[4660]: at org.elasticsearch.tools.launchers.JvmOptionsParser.main(JvmOptionsParser.java:95)
Sep 26 04:10:49 instance systemd[1]: elasticsearch.service: Main process exited, code=exited, status=1/FAILURE
Sep 26 04:10:49 instance systemd[1]: elasticsearch.service: Failed with result 'exit-code'.
Sep 26 04:10:49 instance systemd[1]: Failed to start Elasticsearch.
The error from the role is:
RUNNING HANDLER [geerlingguy.elasticsearch : restart elasticsearch] ************
fatal: [instance]: FAILED! => {"changed": false, "msg": "Unable to start service elasticsearch: Job for elasticsearch.service failed because the control process exited with error code. See \"systemctl status elasticsearch.service\" and \"journalctl -xe\" for details.\n"}
See failed build: https://travis-ci.org/github/geerlingguy/ansible-role-elasticsearch/builds/730446020
Related: elastic/elasticsearch#62716
I get the below error after generating an Elasticsearch instance in Virtualbox. I fixed it by replacing
script.disable_dynamic: false
with
script.inline: on
and
script.indexed: on
as per the error message. Not sure if this error is happening for other people, but it would be a simple fix to change.
Guice Exception: java.lang.IllegalArgumentException: script.disable_dynamic is not a supported setting, replace with fine-grained script settings.
Dynamic scripts can be enabled for all languages and all operations by replacing script.disable_dynamic: false
with script.inline: on
and script.indexed: on
in elasticsearch.yml
A recent Ansible moans about repository file permissions.
When using this role I get:
[WARNING]: File
'/etc/apt/sources.list.d/artifacts_elastic_co_packages_7_x_apt.list' created
with default permissions '600'. The previous default was '666'. Specify 'mode'
to avoid this warning.
in the file _.../tasks/main.yml
add a line:
'```
mode: '0600'
> Same is true for your logstash repository, and probably a few others.
Currently the usage of the lineinfile
module just makes the configuration of ES somewhat awkward and more difficult than it really needs to be.
A better approach would be to use a template.
Since many Java apps (SonarQube, Jenkins, ES, et all) like to take 5-10 seconds on first boot, I like to make sure they're responding before moving forward in my playbooks.
Recently while Modernizing my ELK example I noticed that ES wasn't running by the time Logstash was installed, so Logstash bailed when it started due to ES not being available.
Hi geerling, do you have any plan to support X-Pack security for this role?
elasticsearch does not support Java 9 or 10, which is the default on Ubuntu.
I believe the solution is just to have it install java 8
roles:
- role: geerlingguy.java
java_packages:
- openjdk-8-jdk
- geerlingguy.elasticsearch
(not tested, I don't think you need to make a change, just document the dependency in the readme).
Low priority.
- geerlingguy.elasticsearch was installed successfully
[DEPRECATION WARNING]: The comma separated role spec format, use the
yaml/explicit format instead..
This feature will be removed in a future
release. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.
(Or when changing other options...).
I need to flush_handlers after the Configure Elasticsearch.
task, because if it changes and then we hit the Make sure Elasticsearch is running before proceeding.
task, everything fails...
The current role always starts Elasticsearch, even it is configured not to be.
For cluster configuration I need to copy several files before the Elasticsearch can be started
See #75 with a more in depth explanation and Sample playbook.
Requires #74 to be able to configure the path for log files and data.
When attempting to run Elasticsearch from the ELK example, I get the following error:
[2015-06-17 08:50:43,297][ERROR][bootstrap ] {1.4.5}: Initializa
tion Failed ...
- RuntimeException[Java version: 1.7.0_51 suffers from critical bug https://bug
s.openjdk.java.net/browse/JDK-8024830 which can cause data corruption.
Please upgrade the JVM, see http://www.elastic.co/guide/en/elasticsearch/refere
nce/current/_installation.html for current recommendations.
If you absolutely cannot upgrade, please add -XX:-UseSuperWord to the JVM_OPTS
environment variable.
Upgrading is preferred, this workaround will result in degraded performance.]
This seems to be here: elastic/elasticsearch#10611
I have expected to be able to run Elasticsearch after running the role.
Putting
tasks:
- name: Configuring elasticsearch to work with OpenJDK 7
lineinfile:
state: present
dest: /etc/default/elasticsearch
line: ES_JAVA_OPTS=-XX:-UseSuperWord
in the playbook helps me.
I guess a solution is to either require a more modern Java version (which is complicated on contemporary stable systems like Ubuntu or Debian) or to configure Elasticsearch the way I've shown.
For a simple way to configure Elasticsearch options which are not exposed in this rather simple role, I would like to add an elasticsearch_extra_options
variable, which is basically dropped into the end of the elasticsearch.yml
template file.
Users could then add options to the file like:
elasticsearch_extra_options: |
some.option: true
another.option: false
The most 'stable' release of the Drupal module, Elasticsearch Connector, requires Elasticsearch 1.x installed.
It would be nice to have an option between Elasticsearch 1.x and 2.x.
I'm not sure if this feature request belongs here or on geerlingguy/drupal-vm.
Hello all,
Thanks for your ansible module, it's very clear
Could you variabilize path.data and path.log in elasticsearch.yml jinja template ?
Thanks in advance
Hi,
I have an issue with elasticsearch.service startup - it timeouts.
I found this solution: https://terryl.in/en/elasticsearch-service-start-operation-timed-out/
I tried it manually and it works.
Is possible to do it automatically with your role?
Thank you!
Not really a bug with this code, but more a gotcha.
https://github.com/geerlingguy/ansible-role-elasticsearch/blob/master/tasks/setup-Debian.yml#L8
You will need to do something like this...
- role: geerlingguy.elasticsearch
environment:
# required as the apt_key module doesnt use the apt proxy settings, Doh!!
http_proxy: "http://{{ proxy_ip }}:{{ proxy_port }}/"
https_proxy: "http://{{ proxy_ip }}:{{ proxy_port }}/" # HTTPS URI not supported by ansible
When changing any of the configuration values which cause a change to elasticsearch.yml.j2
, the service is not restarted. There is a handler defined, but it doesn't appear to be used. Instead there is this task:
- name: Force a restart if configuration has changed.
meta: flush_handlers
but this doesn't appear to do anything?
Currently there's just Elasticsearch 2.x... which is ancient. I want to introduce an elasticsearch_version
variable, and make it default to the current major version, 6.x
. Should also fix #36.
When I try to install version 7.10.1, I get the following error.
TASK [geerlingguy.elasticsearch : Install Elasticsearch.] ***********************************************************
fatal: [rabbitmq]: FAILED! => changed=false
msg: |-
Failure talking to yum: failure: repodata/repomd.xml from elasticsearch-7.10.1: [Errno 256] No more mirrors to try.
https://artifacts.elastic.co/packages/7.10.1/yum/repodata/repomd.xml: [Errno 14] HTTPS Error 404 - Not Found
I have passed elasticsearch_version: '7.10.1'.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.