Giter Club home page Giter Club logo

addon-context-linux's Introduction


⚠️⚠️⚠️⚠️⚠️⚠️⚠️

Important

This repository is being moved to a new location https://github.com/OpenNebula/one-apps During the transition the repository is in read-only mode


OpenNebula Linux VM Contextualization

Description

This addon provides contextualization packages for the Linux (and, other Unix-like) guest virtual machines running in the OpenNebula cloud. Based on the provided contextualization parameters, the packages prepare the networking in the running guest virt. machine, configure SSH keys, set passwords, run custom start scripts, and many others.

Download

Latest versions can be downloaded from the release page. Check the supported OpenNebula versions for each release.

Install

Documentation on packages installation and guest contextualization can be found in the latest stable OpenNebula Operation Guide. For beta releases, refer to the latest development documentation.

Tested platforms

List of tested platforms only:

Platform Versions
AlmaLinux 8, 9
Alpine Linux 3.15, 3.16, 3.17
ALT Linux 9, 10
Amazon Linux 2
CentOS 7, 8 Stream
Debian 10, 11
Devuan 3, 4
Fedora 37
FreeBSD 12, 13
openSUSE 15
Oracle Linux 7, 8, 9
Red Hat Enterprise Linux 7, 8, 9
Rocky Linux 8, 9
Ubuntu 20.04, 22.04
Ubuntu Minimal 20.04, 22.04

(the packages might work on other versions or flavours, but those aren't tested)

Guest Network Configuration

NOTE: Available since context packages version 6.2.0.

The context scripts support selectable guest network management service (a component in guest OS responsible for assigning IP addresses, routes, and bringing interfaces up). Following network configuration types can be selected by setting the context variable NETCFG_TYPE (empty default fallbacks to autodetection of the most suitable one for a particular platform):

  • bsd for FreeBSD network configuration,
  • interfaces for Debian-style configuration in /etc/network/interfaces,
  • netplan for Netplan with following renders set in context variable NETCFG_NETPLAN_RENDERER:
    • empty or networkd for systemd-network (default),
    • NetworkManager for NetworkManager
  • networkd for systemd-networkd,
  • nm for NetworkManager,
  • scripts for legacy Red Hat-style configuration via /etc/sysconfig/network-scripts/ifcfg-ethX files.

Interface IP address configuration method can be customized as well. Following IPv4 configuration methods are supported via NIC attribute METHOD:

  • empty or static for static address assignment based on context variables,
  • dhcp for DHCPv4,
  • skip to skip IPv4 configuration.

Following IPv6 configuration methods are supported via NIC attribute IP6_METHOD:

  • empty or static for static address assignment based on context variables,
  • auto for SLAAC,
  • dhcp for SLAAC and DHCPv6,
  • disable to disable IPv6 in guest,
  • skip to skip IPv6 configuration.

Selectable configuration types and IP configuration methods are supported only on the following platforms:

Platform Network Type (NETCFG_TYPE)
Alpine Linux 3.15+ interfaces
ALT Linux p10, Sisyphus networkd, nm
Amazon Linux 2 scripts
Debian 10+ interfaces, netplan, nm, networkd
Devuan 3 interfaces
Fedora 36+ scripts, nm, networkd
FreeBSD 12+ bsd
openSUSE 15 scripts
RHEL-like 7 (CentOS, Oracle Linux) scripts
RHEL-like 8 (CentOS, Oracle/Rocky/AlmaLinux) scripts, nm, networkd
RHEL-like 9 (CentOS Stream 9, Oracle/Rocky/AlmaLinux) nm, networkd
Ubuntu 18.04, 20.04, 22.04 interfaces, netplan, nm, networkd

(other than listed platforms are not supported for using NETCFG_TYPE nor METHOD/IP6_METHOD!):

Known Issues:

  • Alpine Linux: IP6_METHOD=dhcp runs DHCPv4 client instead of DHCPv6,
  • Debian 10: NETCFG_TYPE=netplan with networkd doesn't configure IPv6 (only) SLAAC (IP6_METHOD=auto) when no IPv4 is configured,
  • Debian/Ubuntu: NETCFG_TYPE=netplan with NetworkManager might not configure IPv6 SLAAC (IP6_METHOD=auto) for hot-plugged interfaces,
  • Debian 10 and Ubuntu 18.04, 20.04: might trigger DHCPv6 with IP6_METHOD=auto
    • on NETCFG_TYPE=netplan with networkd,
    • on NETCFG_TYPE=networkd.

Build own package

Packages for each release for supported guests are available in the release page. Also, any version can be built by the scripts provided in this repository.

Requirements

  • Linux host
  • Ruby >= 1.9
  • gem fpm >= 1.10.0
  • dpkg utils for deb package creation
  • rpm utils for rpm package creation

Steps

The script generate.sh is able to create all package types and can be configured to include more files in the package or change some of its parameters. Package type and content are configured by the env. variable TARGET, the corresponding target must be defined in target.sh. Target describes the package format, name, dependencies, and files. Files are selected by the tags. Set of required tags is defined for the target (in targets.sh), each file has a list of corresponding tags right in its filename (divided by the regular name by 2 hashes ##, dot-separated).

Package name or version can be overridden by env. variables NAME and VERSION.

Examples:

$ TARGET=deb ./generate.sh
$ TARGET=el7 NAME=my-one-context ./generate.sh
$ TARGET=alpine ./generate.sh
$ TARGET=freebsd VERSION=5.7.85 ./generate.sh

NOTE: The generator must be executed from the same directory it resides.

Check generate.sh for general package metadata and targets.sh for the list of targets and their metadata. Most of the parameters can be overriden by the appropriate environment variable.

Development

To contribute bug patches or new features, you can use the github Pull Request model. It is assumed that code and documentation are contributed under the Apache License 2.0.

More info:

Repository structure

All code is located under src/ and structure follows the installation directory structure. Files for different environments/targets are picked by the tag, tags are part of the filename separated from the installation name by 2 hashes (##). Tags are dot-separated.

Examples:

  • script - non-tagged file for all targets
  • script##systemd - file tagged with systemd
  • script##systemd.rpm - file tagged with systemd and rpm

Contextualization scripts

Contextualization scripts, which are executed on every boot and during the reconfiguration, are located in src/etc/one-context.d/. Scripts are divided into following 2 parts:

  • local - pre-networking, prefixed with loc-
  • post-networking, prefixed with net-

All other scripts, which are not prefixed with loc- or net-, are executed as a first during the post-networking contextualization stage.

License

Copyright 2002-2022, OpenNebula Project, OpenNebula Systems (formerly C12G Labs)

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

addon-context-linux's People

Contributors

5u623l20 avatar atodorov-storpool avatar baby-gnu avatar beerwatch avatar brunorro avatar codyro avatar cro avatar dann1 avatar dchepishev avatar dmamolina avatar feldsam avatar jamtaylo avatar jfontan avatar kvaps avatar laurencegill avatar lkhn avatar madko avatar ravenox avatar remipcomaite avatar remyzandwijk avatar rsmontero avatar sergiojvg avatar shaba avatar telemaco avatar th0masl avatar tinova avatar tyzhnenko avatar vholer avatar xorel avatar yenya avatar

Stargazers

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

Watchers

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

addon-context-linux's Issues

Race condition in SSH setup and user creation

Current execution order

  • 12-ssh_public_key
  • 13-selinux-ssh
    ...
  • 20-set-username-password

configures SSH access by 12-ssh_public_key for the $USERNAME before the user is actually created by 20-set-username-password. If the $USERNAME doesn't exist for SSH, script fallbacks to root. In subsequent runs, the desired $USERNAME is configured.

resolvconf needs dns and search information in the /etc/network/interfaces

Based on:

https://wiki.debian.org/NetworkConfiguration#The_resolv.conf_configuration_file
and
https://help.ubuntu.com/lts/serverguide/network-configuration.html#name-resolution

If your system uses resolvconf then the information about name servers is only available to other programs if they are included in the /etc/network/interfaces file.

This causes programs to fail when they try to grab contextualized vms dns settings such as when adding a transparent dns proxy/cache to the vm.

resolv.conf has no nameservers

Hi,

don't quite understand why, but no nameservers are set in /etc/resolv.conf.
To fix that I have to do:
cp /etc/one-context.d/loc-11-dns /etc/one-context.d/net-11-dns

My dns are passed thru context with ETHX_DNS

This is on Fedora 26 server. I can try on CentOS 7.
OpenNebula 5.4 one-context-5.4.0-1.el7.noarch

I think it was working nice with one-context-5.0.x

As far as I understand this might be because one-contextd is run in network type configuration. Which seems fine, but why there is no net-xx-dns ?

Best regards,
Edouard

Use "ip" and MAC address to identify interfaces

The context packages use ifconfig that is deprecated in some distros to get the MAC addresses from interfaces. It also expects the interfaces to have names starting with "ETH", this is no longer true. The interfaces should be identified with its MAC address.

Add support for EC2 instances

  • Network scripts should not be applied
  • CONTEXT information should be retrieved from the metadata server
curl http://169.254.169.254/latest/user-data
curl -X "GET" "http://onegate.endpoint/vm" --header "X-ONEGATE-TOKEN: freqdptHxEQ+D43d7guTRZQ==" --header "X-ONEGATE-VMID: 55"

On non-EC2 fetching the EC2 user-data can take too long to fail

# curl -o /tmp/context.sh.new http://169.254.169.254/latest/user-data
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:02:07 --:--:--     0curl: (7) Failed connect to 169.254.169.254:80; Connection timed out

VM startup won't report READY=YES to OneGate (authentication issue)

Seems like context package 5.0 don't authenticate with token to report ready state to onegate.

From opennebula onegate log:

------
Tue Jun 21 01:15:51 2016 [E]: X_ONEGATE_TOKEN header not preset
Tue Jun 21 01:15:51 2016 [I]: Unauthorized login attempt
Tue Jun 21 01:15:51 2016 [I]: 192.168.17.200 - - [21/Jun/2016:01:15:51 +0300] "PUT /vm HTTP/1.1" 401 14 0.0016
------

VM (ubuntu 16.04) context log:
Waiting one minute to reconfigure the machine Waiting one minute to reconfigure the machine Reconfiguring diff: /tmp/context.sh: No such file or directory Reconfiguring NOCHANGE: partition 2 could only be grown by 2015 [fudge=2048] /sbin/ifdown: interface eth0 not configured /usr/bin/onegate.rb:21:in <module:CloudClient>': undefined method +' for nil:NilClass (NoMethodError) from /usr/bin/onegate.rb:13:in <main>' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed ^M 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0^M100 23 100 14 100 9 2356 1514 --:--:-- --:--:-- --:--:-- 2800 Not authorized
In VM /tmp/one_env file does have TOKENTXT variable present.

Also allready contextualized VM with persistent disks and waits for network to come up too long.
This does not happen on 1st boot.
boot

Update /etc/hosts with $SET_HOSTNAME

Hello,

I just tried the 4.90.0 context for linux (ubuntu package) and found that /etc/hosts is not updated with the new host name provided by SET_HOSTNAME context attribute.

cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   xenial.eole.lan xenial

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

I think the line 127.0.1.1 could be replaced.

Regards.

Handle gateway metric on OpenNebula vrouter (Alpine) - v 5.2

Issue originally reported by Nicolas Belan at dev.opennebula.org:

Hi,
When using multiple network on vrouter, you may have multiple default gateway defined (1 per vnet)

To choose the right gateway, it is possible to set "metric", as in:
`
localhost:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 172.25.104.254
network 172.25.104.0
netmask 255.255.255.0
gateway 172.25.104.254
metric 1000

auto eth1
iface eth1 inet static
address 172.25.101.201
network 172.25.101.0
netmask 255.255.0.0
gateway 172.25.8.20
metric 101
`

Metric may be set in context variable, and retrieve from context, using something like:

`

Gets the gateway metric

get_metric() {
if is_gateway; then
metric=$(get_iface_var "METRIC")

    if [ -z "$metric" ]; then
        if [ "$DEV" = "eth0" ]; then
            metric=1000
        else
            metric=$((100+$IFACE_NUM))
        fi
    fi

    echo $metric

fi
}
`
Using that code, by default, the second network interface is the default gateway (1=LAN, 2=WAN), and that can be change using ETH{X}_METRIC=10

Perhaps a hardcoded "eth0" is not correct; but this is a starting point.

Adding the right call "METRIC=$(get_metric)" in the interface loop, this makes the job for me :)

`--- /etc/one-context.d/00-network.orig
+++ /etc/one-context.d/00-network
@@ -88,7 +88,23 @@
echo $gateway
fi
}
+# Gets the gateway metric
+get_metric() {

  • if is_gateway; then

  •    metric=$(get_iface_var "METRIC")
    
  •    if [ -z "$metric" ]; then
    
  •        if [ "$DEV" = "eth0" ]; then
    
  •            metric=1000
    
  •        else
    
  •            metric=$((100+$IFACE_NUM))
    
  •        fi
    
  •    fi
    
  •    echo $metric
    
  • fi
    +}

Gets the network gateway6

get_gateway6() {
if is_gateway; then
@@ -147,6 +163,10 @@
echo " gateway $GATEWAY6"
fi

  • if [ -n "$METRIC" ]; then
  •    echo "  metric $METRIC" 
    
  • fi
  • echo ""
    }

@@ -191,6 +211,7 @@
MASK=$(get_mask)
MTU=$(get_mtu)
GATEWAY=$(get_gateway)

  •    METRIC=$(get_metric)
    
       IPV6=$(get_iface_var "IPV6")
       [[ -z $IPV6 ]] && IPV6=$(get_iface_var "IP6")
    

`

VM Context failed to start IPV6 addr on CentOS 7

By Nicolas Belan from http://dev.opennebula.org/issues/3160

I have installed a CentOS 7 from scratch.
I installed one-context RPM for 4.8.0.

I rebooted and 'cat' eth0 configuration:

[root@localhost network-scripts]# cat ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
TYPE=Ethernet
NETMASK=255.255.255.128
IPADDR=192.168.0.135
GATEWAY=192.168.0.254

IPV6INIT=yes
IPV6ADDR=2a00:afee:0:f:400:b9ff:fe1e:5c87
IPV6_DEFAULTGW=2a00:afee:0:f::ffff

The IPv6 addr is not set correctly on reboot. Only L-local IP is set (fe80::)

To fix that, I added NM_CONTROLLED=no in 00-network:gen_network_configuration()

ONBOOT=yes
NM_CONTROLLED=no
TYPE=Ethernet

Now, IPv6 is correctly set on reboot.

ssh contextualisation should *not* overwrite authorized_keys file

By Nico Schottelius in http://dev.opennebula.org/issues/3931.

The problem with overwriting on (re-)boot is that every manual change is overwritten. This causes problems, because users are usually not aware of what opennebula is "doing to their VM".

I suggest to change it to append, if the key is not present. It can be a very simple script like if ! grep "$key" ~root/.ssh/authorized_keys; then echo $key >> ... ; fi

If the contextualisation packages are somewhere available in a version control repo, I can also create a pull request

Excess gateway in interfaces file

If gateway is not defined in virtual network context, it will be createad in vm interfaces file anyway.

Network definition:

BRIDGE = "vmbr1"
DESCRIPTION = "vlan30"
FILTER_IP_SPOOFING = "YES"
FILTER_MAC_SPOOFING = "YES"
NETWORK_MASK = "255.255.254.0"
PHYDEV = ""
SECURITY_GROUPS = "0"
VLAN_ID = ""
VN_MAD = "fw"


VM template:

AUTOMATIC_DS_REQUIREMENTS = ""CLUSTERS/ID" @> 0"
AUTOMATIC_REQUIREMENTS = "(CLUSTER_ID = 0) & !(PUBLIC_CLOUD = YES)"
CONTEXT = [
DISK_ID = "1",
DNS_HOSTNAME = "YES",
ETH0_CONTEXT_FORCE_IPV4 = "",
ETH0_DNS = "",
ETH0_GATEWAY = "",
ETH0_GATEWAY6 = "",
ETH0_IP = "192.168.31.2",
ETH0_IP6 = "",
ETH0_IP6_ULA = "",
ETH0_MAC = "02:00:c0:a8:1f:02",
ETH0_MASK = "255.255.254.0",
ETH0_MTU = "",
ETH0_NETWORK = "",
ETH0_SEARCH_DOMAIN = "",
ETH0_VLAN_ID = "",
ETH0_VROUTER_IP = "",
ETH0_VROUTER_IP6 = "",
ETH0_VROUTER_MANAGEMENT = "",
NETWORK = "YES",
ONEGATE_ENDPOINT = "http://192.168.40.165:5030",
REPORT_READY = "YES",
SET_HOSTNAME = "Ubuntu-xenial-template-204-204",
SSH_PUBLIC_KEY = "ssh-rsa ....",
TARGET = "hda",
TOKEN = "YES",
VMID = "204" ]
...

And vm ends up with interfaces file like this:

auto eth0
iface eth0 inet static
address 192.168.31.2
network 192.168.31.0
netmask 255.255.254.0
gateway 192.168.31.1


version 5.0.1

Move udev rules to /lib/udev

Right now the rules are located at /etc/udev/rules.d. As this is installed by a package they should be in /lib/udev.

  • Check if this path is the same in all distributions
  • Find the best place in that directory (order number)

Race condition in script start locking

Multiple instances can run in parallel

  492 ?        S      0:00  \_ /usr/lib/systemd/systemd-udevd
  524 ?        S      0:00  |   \_ /bin/sh /usr/sbin/one-context-reconfigure
  526 ?        S      0:00  |       \_ /bin/sh /usr/sbin/one-context-reconfigure
 2084 ?        S      0:00  |           \_ /bin/bash /usr/sbin/one-contextd reconfigure
 2093 ?        S      0:00  |               \_ curl -o /tmp/context.sh.new http://169.254.169.254/latest/user-data
  493 ?        S      0:00  \_ /usr/lib/systemd/systemd-udevd
  494 ?        S      0:00  \_ /usr/lib/systemd/systemd-udevd
  495 ?        S      0:00  \_ /usr/lib/systemd/systemd-udevd
  525 ?        S      0:00  |   \_ /bin/sh /usr/sbin/one-context-reconfigure
  527 ?        S      0:00  |       \_ /bin/sh /usr/sbin/one-context-reconfigure
 2085 ?        S      0:00  |           \_ /bin/bash /usr/sbin/one-contextd reconfigure
 2094 ?        S      0:00  |               \_ curl -o /tmp/context.sh.new http://169.254.169.254/latest/user-data
  496 ?        S      0:00  \_ /usr/lib/systemd/systemd-udevd
  512 ?        S      0:00  |   \_ /bin/sh /usr/sbin/one-context-reconfigure
  513 ?        S      0:00  |       \_ /bin/sh /usr/sbin/one-context-reconfigure
 2086 ?        S      0:00  |           \_ /bin/bash /usr/sbin/one-contextd reconfigure
 2095 ?        S      0:00  |               \_ curl -o /tmp/context.sh.new http://169.254.169.254/latest/user-data
  497 ?        S      0:00  \_ /usr/lib/systemd/systemd-udevd
# head -8 /tmp/context.log
Waiting one minute to reconfigure the machine
Waiting one minute to reconfigure the machine
Waiting one minute to reconfigure the machine
Reconfiguring
Reconfiguring
Reconfiguring
+ get_new_context
+ get_new_context

Contextualize SSH user

Hello,

I'm in the process of writing a patch to contextualize the user used to configure the ssh public key.

The idea is to avoid untraceable generic account like root, so I'll proposed another pull request for sudo context script to create a local account with sudo permission.

I started with a ${SSH_USER} variable, but I saw the ${USERNAME} used for windows machines and I think reusing it here is better than creating a new one.

Tell me what do you think about this.

Regards.

'dpkg -i one-context_4.14.4.deb' shows '/etc/init.d/vmcontext' file does not exist error

I'm using ubuntu 14.04

I downloaded the deb from https://github.com/OpenNebula/addon-context-linux/releases/download/v4.14.4/one-context_4.14.4.deb

when i try to install this package using 'dpkg -i one-context_4.14.4.deb', it thows '/etc/init.d/vmcontext' file does not exist error.

To resolve this problem, now i copy and paste all the scripts to my image.

root@tom:~# dpkg -i one-context_4.14.3.deb 
(Reading database ... 51873 files and directories currently installed.)
Preparing to unpack one-context_4.14.3.deb ...
Unpacking one-context (4.14.3) over (4.14.3) ...
Setting up one-context (4.14.3) ...
`update-rc.d: /etc/init.d/vmcontext: file does not exist`
Processing triggers for ureadahead (0.100.0-16) ...

root@tom-resize:/etc/init.d# nano vmcontext
root@tom-resize:/etc/init.d# dpkg -i /root/one-context_4.14.3.deb
(Reading database ... 51873 files and directories currently installed.)
Preparing to unpack /root/one-context_4.14.3.deb ...
Unpacking one-context (4.14.3) over (4.14.3) ...
Setting up one-context (4.14.3) ...
System start/stop links for /etc/init.d/vmcontext already exist.

Split contextualisation scripts in two parts

Hello,

I think we could split the contextualisation scripts in two parts:

  • what should be done before the network is UP (setting configuration parameters like network, hostname, etc.)
  • what should be done when the system is running, i.e after multi-user.target (like $START_SCRIPT)

Regards.

Grow rootfs doesn't grow the filesystem if partition is already extended

If partition was extended by dracut module, the filesystem resize in the one-context is never done because the script terminates after growpart has nothing to do (NOCHANGE: partition 1 is size 25155742. it cannot be grown)

#!/bin/sh
set -e
...
for PART in ${PARTITION}; do
  ${GROWPART} ${DISK} ${PART}  # <------ exits
done
...
case "${FSTYPE}" in
  ext2|ext3|ext4)
    resize2fs ${DEVICE}

Support VM reconfiguration

On VM nic hotplug the context data is updated. The context packages should be able to notice this using udev rules and reconfigure the machine.

Network is not configured in Debian 8

service networking start no longer works in Debian 8 after d96cb50. This happens because it disables network confguration in /etc/default/networking:

CONFIGURE_INTERFACES=no

Network should be configured with ifup, the same as Ubuntu.

activate_network()
{
. /etc/os-release
if [ $ID = "ubuntu" ]; then
IFACES=`/sbin/ifquery --list -a`
for i in $IFACES; do
/sbin/ifup $i
done
else
service networking stop
sleep 1
service networking start
fi
sleep 2
}

Contextualize on each boot

There is a check in /usr/sbin/one-contextd which prevents subsequent contextualizations, until the context ISO changes. It should be aligned with Windows context. to run on each boot. State files should be also moved from /tmp somewhere in /var (e.g. /var/run?) .

Network in Debian 8

After deploy new VM of Debian 8, network not start. Interface present but not up.

Get EC2 context data at the end

The packages try to get context data in this order:

  • Context CDROM
  • EC2 metadata server
  • vmware tools

The timeout for EC2 can take minutes making vmware machines wait a lot before booting. EC2 should be the last check.

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.