Git Product home page Git Product logo

puppet-nfs's Introduction

nfs

Table of Contents

  1. Overview - What is the nfs module?
  2. Module Description - What does this module do?
  3. Setup - The basics of getting started with nfs
  4. Usage - The classes and defined types available for configuration
  5. Requirements
  6. Limitations - OS compatibility, etc.
  7. Contributing to the graphite module

Overview

This module installs, configures and manages everything on NFS clients and servers.

Puppet Forge Build Status Puppet Forge Downloads

Module Description

This module can be used to simply mount nfs shares on a client or to configure your nfs servers. It can make use of storeconfigs on the puppetmaster to get its resources.

Setup

What nfs affects:

  • packages/services/configuration files for NFS usage
  • can be used with puppet storage

Simple mount nfs share

This example mounts a nfs share on the client, with NFSv3

include '::nfs::client'

::nfs::client::mount { '/mnt/mymountpoint':
  server  => 'nfsserver.my.domain',
  share   => '/share/on/server',
  options => 'rw',
}

NFSv3 server and client

This will export /data/folder on the server and automagically mount it on client. You need storeconfigs/puppetdb for this to work.

node server {
  include nfs::server

  ::nfs::server::export{ '/data_folder':
    ensure  => 'mounted',
    clients => '10.0.0.0/24(rw,insecure,async,no_root_squash) localhost(rw)'
  }
}

By default, mounts are mounted in the same folder on the clients as they were exported from on the server.

node client {
  include '::nfs::client'
  Nfs::Client::Mount <<| |>> 
}

NFSv3 multiple exports, servers and multiple node

  node server1 {
    include '::nfs::server'
    ::nfs::server::export{ 
      '/data_folder':
        ensure  => 'mounted',
        clients => '10.0.0.0/24(rw,insecure,async,no_root_squash) localhost(rw)'
      # exports /homeexport and mounts them om /srv/home on the clients
      '/homeexport':
        ensure  => 'mounted',
        clients => '10.0.0.0/24(rw,insecure,async,root_squash)',
        mount   => '/srv/home'
    }
  }

  node server2 {
    include '::nfs::server'
    # ensure is passed to mount, which will make the client not mount it
    # the directory automatically, just add it to fstab
    ::nfs::server::export{ 
      '/media_library':
        ensure  => 'present',
        nfstag     => 'media'
        clients => '10.0.0.0/24(rw,insecure,async,no_root_squash) localhost(rw)'
    }
  }

  node client {
    include '::nfs::client'
    Nfs::Client::Mount <<| |>>; 
  }

  # Using a storeconfig override, to change ensure option, so we mount
  # all shares
  
  node greedy_client {
    include '::nfs::client'
    Nfs::Client::Mount <<| |>> {
      ensure => 'mounted'
    }
  }


  # only the mount tagged as media 
  # also override mount point
  node media_client {
    include '::nfs::client'
    Nfs::Client::Mount <<|nfstag == 'media' |>> {
      ensure => 'mounted',
      mount  => '/import/media'
    }
  }

  # All @@nfs::server::mount storeconfigs can be filtered by parameters
  # Also all parameters can be overridden (not that it's smart to do
  # so).
  # Check out the doc on exported resources for more info:
  # http://docs.puppetlabs.com/guides/exported_resources.html
  node single_server_client {
    include '::nfs::client'
    Nfs::Client::Mount <<| server == 'server1' |>> {
      ensure => 'absent',
    }
  }

NFSv4 Simple example

We use the $::domain fact for the Domain setting in /etc/idmapd.conf. For NFSv4 to work this has to be equal on servers and clients set it manually if unsure.

All nfsv4 exports are bind mounted into /export/$mount_name and mounted on /srv/$mount_name on the client. Both values can be overridden through parameters both globally and on individual nodes.

  node server {
    class { 'nfs::server':
      nfs_v4 => true,
      nfs_v4_export_root_clients =>
        '10.0.0.0/24(rw,fsid=root,insecure,no_subtree_check,async,no_root_squash)'
    }
    nfs::server::export{ '/data_folder':
      ensure  => 'mounted',
      clients => '10.0.0.0/24(rw,insecure,no_subtree_check,async,no_root_squash) localhost(rw)'
    }
  }

Set ownership and permissions on the folder being exported

  node server {
    nfs::server::export{ '/data_folder':
      ensure  => 'mounted',
      clients => '10.0.0.0/24(rw,insecure,no_subtree_check,async,no_root_squash) localhost(rw)',
      owner => 'root',
      group => 'root',
      perms => '0755',
    }
  }

By default, mounts are mounted in the same folder on the clients as they were exported from on the server

node client {
  class { 'nfs::client':
    nfs_v4 = true,
    nfs_v4_export_root_clients =>
      '10.0.0.0/24(rw,fsid=root,insecure,no_subtree_check,async,no_root_squash)'
  }
  Nfs::Client::Mount <<| |>>; 
}

We can also mount the NFSv4 Root directly through nfs::client::mount::nfsv4::root. By default /srv will be used for as mount point, but can be overriden through the 'mounted' option.

node client2 {
  $server = 'server'

  class { '::nfs::client':
    nfs_v4 = true,
  }
  Nfs::Client::Mount::Nfs_v4::Root <<| server == $server |>> { 
    mount => "/srv/$server",
  }
}

NFSv4 insanely overcomplicated reference

Just to show you, how complex we can make things ;-)

  # and on individual nodes.
  node server {
    class { 'nfs::server':
      nfs_v4              => true,
      # Below are defaults
      nfs_v4_idmap_domain => $::domain,
      nfs_v4_export_root  => '/export',
      # Default access settings of /export root
      nfs_v4_export_root_clients =>
        "*.${::domain}(ro,fsid=root,insecure,no_subtree_check,async,root_squash)"
    }
    
    nfs::server::export{ '/data_folder':
      # These are the defaults
      ensure  => 'mounted',
      # rbind or bind mounting of folders bindmounted into /export 
      # google it
      bind    => 'rbind',
      # everything below here is propogated by to storeconfigs
      # to clients
      #
      # Directory where we want export mounted on client 
      mount     => undef, 
      remounts  => false,
      atboot    => false,
      #  Don't remove that option, but feel free to add more.
      options   => '_netdev',
      # If set will mount share inside /srv (or overridden mount_root)
      # and then bindmount to another directory elsewhere in the fs -
      # for fanatics.
      bindmount => undef,    
      # Used to identify a catalog item for filtering by by
      # storeconfigs, kick ass.
      nfstag     => undef,
      # copied directly into /etc/exports as a string, for simplicity
      clients => '10.0.0.0/24(rw,insecure,no_subtree_check,async,no_root_squash)'
  }

  node client {
    class { 'nfs::client':
      nfs_v4              => true,
      nfs_v4_idmap_domain => $::domain
      nfs_v4_mount_root   => '/srv',
    }

    # We can as you by now know, override options set on the server
    # on the client node.
    # Be careful. Don't override mount points unless you are sure
    # that only one export will match your filter!
    
    Nfs::Client::Mount <<| # filter goes here # |>> {
      # Directory where we want export mounted on client 
      mount     => undef, 
      remounts  => false,
      atboot    => false,
      #  Don't remove that option, but feel free to add more.
      options   => '_netdev',
      # If set will mount share inside /srv (or overridden mount_root)
      # and then bindmount to another directory elsewhere in the fs -
      # for fanatics.
      bindmount => undef,    
    }
  }

A large number of clients

If a server has many clients it's a bit of a mess to put them all in a single 'clients' option for nfs::server::export. Instead, you can put them in a array or hash and use the mk_client_list function to generate the clients string.

$nfs_clients = [
    'common-*.loc.dom', 
    'hostb.loc.dom', 
    '10.0.9.0/24']

nfs::server::export { '/data':
    clients => mk_client_list($nfs_clients, {}, "ro"),
    # Which will produce:
    # 'common-*.loc.dom(ro) hostb.loc.dom(ro) 10.0.9.0/24(ro)'
    ...
}

In this case mk_client_list generates the string: `

The second option is a hash of client -> options. The third option is the default in case a client doesn't have options specified in the hash. In the above example none of the clients had specific settings, so they were all given the default options of ro.

$nfs_clients = [
    'common-*.loc.dom', 
    'hostb.loc.dom', 
    '10.0.9.0/24']

$nfs_client_options = {
    'hostb.loc.dom'     => 'rw,no_root_squash'}

nfs::server::export {'/data':
    # Use the stdlib keys function to get the array of keys from our hash.
    clients => mk_client_list($nfs_clients, $nfs_client_options, 'ro'),
    # Which will produce:
    # 'common-*.loc.dom(ro) hostb.loc.dom(rw,no_root_squash) 10.0.9.0/24(ro)'
    ...
}

You can also give options to each host in a hash, and then use the stdlib keys() function to extract the client array from the hash: mk_client_list(keys($client_hash), $client_hash, '')

Usage

Class: nfs::server

Set up NFS server and exports. NFSv3 and NFSv4 supported.

Parameters within nfs::server:

service_manage (true)

Should this class manage the services behind nfs? Set this to false if you are managing the service in another way (e.g. pacemaker).

package_ensure (installed)

Allow to update or set to a specific version the nfs server packages.

nfs_v4 (optional)

NFSv4 support. Will set up automatic bind mounts to export root. Disabled by default.

nfs_v4_export_root (optional)

Export root, where we bind mount shares, default /export

nfs_v4_idmap_domain (optional)

Domain setting for idmapd, must be the same across server and clients. Default is to use $domain fact.

exports (optional)

If set, this attribute will be used to construct nfs::server::export resources. You can use you ENC or hiera to provide the hash of nfs::server::export resources definitions:

nfs::server::exports:
  /mnt/something:
    ensure: mounted
    clients: '*(fsid=0,ro,insecure,async,all_squash,no_subtree_check,mountpoint=/mnt/something)'
Examples
class { '::nfs::server':
  nfs_v4                      => true,
  nfs_v4_export_root_clients  => "*.${::domain}(ro,fsid=root,insecure,no_subtree_check,async,root_squash)",
  # Generally parameters below have sane defaults.
  nfs_v4_export_root          => "/export",
  nfs_v4_idmap_domain         => $::domain,
}

Defined Type: nfs::server::export

Set up NFS export on the server (and stores data in configstore)

Parameters within nfs::server::export:

v3_export_name (optional)

Default is $name. Usally you do not set it explicit.

v4_export_name (optional)

Default results from $name. Usally you do not set it explicit.

ensure (optional)

Default is 'mounted'

bind (optional)

Default is 'rbind'. rbind or bind mounting of folders bindmounted into /export. Google it!

Following parameteres are propogated by to storeconfigs to clients

mount (optional)

Default is undef. This means client mount path is the same as server export path. Directory where we want export mounted on client

remounts (optional)

Default is false.

atboot (optional)

Default is false.

options (optional)

Default is '_netdev'. Don't remove that option, but feel free to add more.

bindmount (optional)

Default is undef. If set will mount share inside /srv (or overridden mount_root) and then bindmount to another directory elsewhere in the fs - for fanatics.

nfstag (optional)

Default is undef. Used to identify a catalog item for filtering by storeconfigs on clients.

clients (optional)

Default is 'localhost(ro)'. Copied directly into /etc/exports as a string, for simplicity.

server (optional)

Default is $::clientcert. Used to specify a other ip/name for the client to connect to. Usefull in machines with multiple ip addresses or network interfaces

Example
::nfs::server::export { '/media_library':
  nfstag  => 'media'
  clients => '10.0.0.0/24(rw,insecure,async,no_root_squash) localhost(rw)'
}

Class: nfs::client

Set up NFS client and mounts. NFSv3 and NFSv4 supported.

Parameters within nfs::client:

package_ensure (installed)

Allow to update or set to a specific version the nfs client packages.

nfs_v4

NFSv4 support. Disabled by default.

nfs_v4_mount_root

Mount root, where we mount shares, default /srv

nfs_v4_idmap_domain

Domain setting for idmapd, must be the same across server and clients. Default is to use $::domain fact.

mounts (optional)

If set, this attribute will be used to construct nfs::client::mount resources. You can use you ENC or hiera to provide the hash of nfs::client::mount resources definitions:

nfs::client::mounts:
  /mnt/test:
    ensure: 'mounted'
    server: '192.0.2.100'
    share:  '/export/data'
Example
class { '::nfs::client':
  nfs_v4              => true,
  # Generally parameters below have sane defaults.
  nfs_v4_mount_root   => '/srv',
  nfs_v4_idmap_domain => $::domain,
}

Defined Type: nfs::client::mount

Set up NFS mount on client.

Parameters within nfs::client::mount:

server

FQDN or IP of the NFS server.

share

Name of share to be mounted.

ensure (optional)

Default is 'mounted'.

mount (optional)

Default is $title of defined type. Defines mountpoint of the share on the client.

remounts (optional)

Default is false.

atboot (optional)

Default is false.

options (optional)

Default is '_netdev'. Don't remove that option, but feel free to add more.

bindmount (optional)

Default is undef. If set will mount share inside /srv (or overridden mount_root) and then bindmount to another directory elsewhere in the fs - for fanatics.

nfstag (optional)

Default is undef. Used to identify a catalog item for filtering by storeconfigs on clients.

owner (optional)

Default is 'root'. Sets owner of mountpoint directory. This is applied to the directory on every run, which means it is used both on the base mountpoint creation when unmounted, and also once mounted on the target NFS server and thus all servers accessing the same share.

group (optional)

Default is root. Sets group of mountpoint directory. This is applied to the directory on every run, which means it is used both on the base mountpoint creation when unmounted, and also once mounted on the target NFS server and thus all servers accessing the same share.

perm (optional)

Default is '0755'. Sets mode of mountpoint directory. This has changed from previous versons which used '0777' (world writable). This is applied to the directory on every run, which means it is used both on the base mountpoint creation when unmounted, and also once mounted on the target NFS server and thus all servers accessing the same share.

Requirements

If you want to have the full potential of this module its recommend to have storeconfigs enabled.

Limitations

##Contributing

Echocat modules are open projects. So if you want to make this module even better, you can contribute to this module on Github.

This module is forked/based on Harald Skoglund [email protected] from https://github.com/haraldsk/puppet-module-nfs/

Please read DEVELOP.md on how to contribute to this module.

puppet-nfs's People

Contributors

asasfu avatar barn avatar cristifalcas avatar cypherfox avatar danifr avatar derdanne avatar dnlsng avatar dwerder avatar gozer avatar hairyhenderson avatar hskwirblies avatar jasuca avatar jkroepke avatar madddi avatar mikebryant avatar mjrider avatar nauxliu avatar paul-ferrell avatar peradel avatar pflarr avatar rbroemeling avatar rnelson0 avatar roidelapluie avatar secondhans avatar tbartelmess avatar traylenator avatar trentl avatar wiene avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

puppet-nfs's Issues

Continued maintainence of puppet-nfs

Since there isn't any private way of contacting you I'll just leave this here publicly.

I authored alot of the original code of this module before the fork. I would have liked to continue maintaining it, but I have to realize that i just don't have the time for it right now.

I have a huge backlog of PRs, which is just don't have enough time to merge inn and give the quality assurance it would need. If you feel you'll be able to spend more time on this. I'll be happy to put up a deprecation message on my repo and fon the forge and tell people to submit PRs to your fork instead.

Ubuntu 16.04: service imapd is not available

Ubuntu 16.04 runs Systemd and apparently, the service scripts for idmapd are not available (the systemd-modules are linked to /dev/null)

Because of this, running the module yields the following result:

Error: Could not start Service[idmapd]: Execution of '/usr/sbin/service idmapd start' returned 1: Failed to start idmapd.service: Unit idmapd.service is masked.

I guess, you should simply remove the start of the service for Ubuntu >= 16.04.

Setting nfs::server::mountd_threads parameter has no effect

Changing the value of parameter has no effect because the code simply does not use this parameter. To fix this, I added the following code (just for redhat as an example):

nfs::server::redhat

file_line { 'rpc-mount-args':
ensure => present,
path => '/etc/sysconfig/nfs',
line => "RPCMOUNTDOPTS=${mountd_threads}",
match => '^#?RPCMOUNTDOPTS='
} ~> Service[$service_name]

Nfs::Server::Debian/File_line[rpc-mount-options] does not depend on Package['nfs-kernel-server']

As authored, File_line[rpc-mount-options] in manifests/server/debian.pp has no dependency on Package['nfs-kernel-server']. This causes it to break, sometimes, when puppet chooses to order things such that the File_line is executed before the package is installed (at this point the file that the stanza is attempting to modify does not exist, and thus things explode).

This can be fixed by adding require => Package['nfs-kernel-server'] to the rpc-mount-options file_line declaration, so that it looks like this:

    file_line { 'rpc-mount-options':
      ensure  => present,
      path    => '/etc/default/nfs-kernel-server',
      line    => "RPCMOUNTDOPTS=\"--manage-gids --port ${mountd_port} --num-threads ${mountd_threads}\"",
      match   => '^#?RPCMOUNTDOPTS',
      require => Package['nfs-kernel-server'];
    }

Disable bind mount

Hey guys

Thanks for the great module!
I am curious if there is a way to disable the "bind mount" functionality for nfs4?

When I set bind "bindmount => false" or "bindmount => undef," I still see the bind mount point under /export.

Maybe I am not understanding the concept here?

Thanks again

Use file_line instead shellvar

Hi!

first, thank for all your work. This module help me a lot on my work.

I want to ask, If it is possible to replace augeas shellvar function with stdlib's file_line.
Currently, the augeasproviders_core and augeasproviders_shellvar modules are not very active and augeasproviders_core do not have offical puppet4 support.

Also puppetlabs inifile module would be an option, too.

What did you think about this?

Could not find init script or upstart conf file for 'nfs-common' on Ubuntu 14.04LTS

My manifest:

$server = 'nfs.localdomain'

  class { 'nfs::server':
    nfs_v4 => true,
    # nfs_v4_idmap_domain => $::domain,
  }

  Nfs::Client::Mount::Nfs_v4::Root <<| server == $server |>> { 
    mount => "/srv/$server",
  }
Error: /Stage[main]/Nfs::Client::Debian::Service/Service[idmapd]: Could not evaluate: Could not find init script or upstart conf file for 'nfs-common'

Ubuntu 12.04 Could not find init script or upstart conf file for 'rpcbind'

This might be related to issue #27 - a simple include nfs::servers on Ubuntu 12.04 results in:

Error: /Stage[main]/Nfs::Client::Ubuntu::Service/Service[rpcbind]: Could not evaluate: Could not find init script or upstart conf file for 'rpcbind'

adding provider => 'init' to the service resource in manifests/client/ubuntu/service.pp solved this problem. Perhaps this should be set via params where it determines the major os version.

firewall rules

how can I specify INPUT firewall rules for NFS server? I am using puppetlabs-firewall and RHEL 5, 6, 7 servers.

Puppet warning using nfs::server version 1.9.0

Hi

I'm working on upgrading from version 1.8.1 to 1.9.0 of this module, and when using nfs::server with default parameters I get these warning in catalog compile:

Warning: Scope(Class[Nfs::Client::Redhat::Install]): Could not look up qualified variable '::nfs::client::package_ensure'; class ::nfs::client has not been evaluated
Warning: Scope(Class[Nfs::Client::Redhat::Install]): Could not look up qualified variable '::nfs::client::package_ensure'; class ::nfs::client has not been evaluated

nfs::server::redhat declares nfs::client::redhat and this class declares nfs::client::redhat::install.
No class declares nfs::client....

I guess this could be solved by defining nfs::client in nfs::server instead of in the os spesific classes.

For now I resolved it by defining both nfs::client and nfs::server in my profile.

Best regards
Hugo

Mountpoint directory should not be 0777 world writable by default

manifests/mkdir.pp defaults to creating the mount-point directory with world-writable permissions (0777)

This was introduced in the following commit:
968117b added gentoo compatibility

It is not desirable to create a mountpoint as world writable by default, as if
the filesystem is not mounted any user can write data that may be inadvertently
used by another service and security context.

Additionally, the directory assumes permissions from the NFS server once mounted
which will then be modified by this resource to make the entire NFS share world
writable on all servers.

This option is configurable and any user requiring this behaviour can override
the default.

rpcbind service - changes on every run

Hi,
using this module for nfs will generate changes on every puppet run. The error is located on the service definition for the rpcbind service and the handling of systemd states in puppets Service Provider.

On my system Ubuntu 16.04 with systemd puppet verifies status of service by these commands:
Debug: Executing: '/bin/systemctl is-active rpcbind' Debug: Executing: '/bin/systemctl is-enabled rpcbind'
The is-active part is fine, but systemctl returns for is-enabled indirect, what is treated in puppet as false and so you have on every run changes.

There is a bug & open feature request at Puppet for this behaviour:
https://tickets.puppetlabs.com/browse/PUP-6759
https://tickets.puppetlabs.com/browse/PUP-7163

Any idea for a workarround for this problem ? Perhaps setting the enable parameter for the service would help ? https://puppet.com/docs/puppet/5.3/types/service.html#service-attribute-enable

New release

Hi.

We are starting to roll out servers with Ubuntu 16.04 and there seems to be a couple of issues that are fixed but not released.
Do you have a plan for releasing a new version anytime soon with those fixes?

Redhat NFS lock service name is incorrect for version 7

Looks like Redhat changed the service name in 7 but not to 'rpc-statd' but to 'nfs-lock'

in nfs/manifests/client/redhat/service.pp this section:

service {'nfslock':
    ensure    => running,
    name      => $::nfs::client::redhat::params::osmajor ? {
    7       => 'rpc-statd',
    default => 'nfslock'
},

Should read

service {'nfslock':
    ensure    => running,
    name      => $::nfs::client::redhat::params::osmajor ? {
    7       => 'nfs-lock',
    default => 'nfslock'
},

Tested with RHEL7.0 and RHEL7.1

Mounting is not idempotent

I am using Puppet for server cold-metal rebuilds on Red Hat 7. I'm finding that client mounting of NFS4 is not idempotent. If puppet is run more than once and the module has already successfully mounted the NFS shares, it attempts to do it again anyway. This, of course, throws an error and failure in puppet because NFS refuses to do the mount.

nfs::client::mounts generates a dependency cycle

When using nfs::client::mounts (i.e. from hiera), a dependency cycle is generated:

(Mount[shared 192.168.1.10:test by xenial.openvpn on /srv/test] => Nfs::Client::Mount[test] => Class[Nfs::Client] => Mount[shared 192.168.1.10:test by xenial.openvpn on /srv/test])

Workaround: Create a profile, that creates the nfs::client::mount-types independently of the class:

# Generate nfs::client::mount types, because nfs::client::mounts generates
# a dependency cycle

class profile::nfs_client_mounts () {

  $nfs_mounts = hiera_hash('nfs_client_mounts', undef)

  if $nfs_mounts {
    create_resources(nfs::client::mount, $nfs_mounts)
  }

}

and include that into the classes list.

local cache - using cachefiles

Hi,
We are looking at enabling local cache for nfs share, in case the server that hosts files dies (it causes website down time)

Hopefully something like:
http://xmodulo.com/how-to-enable-local-file-caching-for-nfs-share-on-linux.html

We are using the below config:

nfs::client::mount {"/var/path/to/media":
share => '/var/path/to/media',
ensure => present,
server => "x.x.x.x", # Ip of media server
atboot => true
}

Do you support local caching? If so, what would the correct config be?

Thanks,

Publish version 2.0.0

With issue #101 resolved, a new upload to the forge would allow for better dependency resolution. Thanks!

nfs and nfs4 mounts on same host not supported?

Looking at nfs::client::mount - it only has a central switch for nfsv4 - which forces all mounts to be nfsv4..
Which means, if I have a host who needs to mount from one server - running nfs4 and another host - which runs nfs (nfsv3).. I can't use this class :(

Would you accept a PR for a per-mount Boolean setting of nfsv4 ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.