Giter Site home page Giter Site logo

docker-machine-driver-proxmox-ve's Introduction

Docker Machine Driver for Proxmox VE

This driver can be used to kickstart a VM in Proxmox VE to be used with Docker/Docker Machine.

  • Download and copy it into your PATH (don't forget to chmod +x) or build your own driver

  • Check if it works:

      $ docker-machine create --driver proxmoxve --help | grep -c proxmox
      35
    

Operation

Now you have two modes of operation:

  • use an iso to install a Docker distribution (e.g. RancherOS)
  • use a previously created cloud-init-based image VM template as a base

There are also other options to customize your VM which are not shown here, so please feel free to explore them with docker-machine create --driver proxmoxve --help

Preparing a special test user in PVE

If you want to test this docker-machine driver, i strongly recommend to secure it properly. Best way to do this to create a special user that has its own pool and storage for creating the test machines. This corresponds to the examples below.

Here is what I use (based on ZFS):

  • create a pool for use as --proxmoxve-proxmox-pool docker-machine

      pvesh create /pools -poolid docker-machine
    
  • create an user docker-machine with password D0ck3rS3cr3t

      pvesh create /access/users -userid docker-machine@pve -password D0ck3rS3cr3t
    
  • creating a special ZFS dataset and use it as PVE storage

      zfs create -o refquota=50G rpool/docker-machine-test
      zfs create rpool/docker-machine-test/iso
      pvesh create /storage -storage docker-machine -type zfspool -pool rpool/docker-machine-test
      pvesh create /storage -storage docker-machine-iso -type dir -path /rpool/docker-machine-test/iso -content iso
      pvesh set /pools/docker-machine -storage docker-machine
      pvesh set /pools/docker-machine -storage docker-machine-iso
    
  • set proper permissions for the user

      pvesh set /access/acl -path /pool/docker-machine -roles PVEVMAdmin,PVEDatastoreAdmin,PVEPoolAdmin -users docker-machine@pve
    

If you have additional test storages, you can also add them easily:

    pvesh set /pools/docker-machine -storage nfs
    pvesh set /pools/docker-machine -storage lvm
    pvesh set /pools/docker-machine -storage directory

Ceph is currently not directly tested by me, but there are fine people out there wo tried it.

Clone VM

This approach uses a predefined VM template with cloud-init support to be cloned and used. There a lot of ways to do that, here is an adopted one (courtesy of @travisghansen):

#!/bin/bash

set -x
set -e

export IMGID=9007
export BASE_IMG="debian-10-openstack-amd64.qcow2"
export IMG="debian-10-openstack-amd64-${IMGID}.qcow2"
export STORAGEID="docker-machine"

if [ ! -f "${BASE_IMG}" ];then
  wget https://cloud.debian.org/images/cloud/OpenStack/current-10/debian-10-openstack-amd64.qcow2
fi

if [ ! -f "${IMG}" ];then
  cp -f "${BASE_IMG}" "${IMG}"
fi

# prepare mounts
guestmount -a ${IMG} -m /dev/sda1 /mnt/tmp/
mount --bind /dev/ /mnt/tmp/dev/
mount --bind /proc/ /mnt/tmp/proc/

# get resolving working
mv /mnt/tmp/etc/resolv.conf /mnt/tmp/etc/resolv.conf.orig
cp -a --force /etc/resolv.conf /mnt/tmp/etc/resolv.conf

# install desired apps
chroot /mnt/tmp /bin/bash -c "apt-get update"
chroot /mnt/tmp /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y net-tools curl qemu-guest-agent nfs-common open-iscsi lsscsi sg3-utils multipath-tools scsitools"

# https://www.electrictoolbox.com/sshd-hostname-lookups/
sed -i 's:#UseDNS no:UseDNS no:' /mnt/tmp/etc/ssh/sshd_config

sed -i '/package-update-upgrade-install/d' /mnt/tmp/etc/cloud/cloud.cfg

cat > /mnt/tmp/etc/cloud/cloud.cfg.d/99_custom.cfg << '__EOF__'
#cloud-config

# Install additional packages on first boot
#
# Default: none
#
# if packages are specified, this apt_update will be set to true
#
# packages may be supplied as a single package name or as a list
# with the format [<package>, <version>] wherein the specifc
# package version will be installed.
#packages:
# - qemu-guest-agent
# - nfs-common

ntp:
  enabled: true

# datasource_list: [ NoCloud, ConfigDrive ]
__EOF__

cat > /mnt/tmp/etc/multipath.conf << '__EOF__'
defaults {
    user_friendly_names yes
    find_multipaths yes
}
__EOF__

# enable services
chroot /mnt/tmp systemctl enable open-iscsi.service || true
chroot /mnt/tmp systemctl enable multipath-tools.service || true

# restore systemd-resolved settings
mv /mnt/tmp/etc/resolv.conf.orig /mnt/tmp/etc/resolv.conf

# umount everything
umount /mnt/tmp/dev
umount /mnt/tmp/proc
umount /mnt/tmp

# create template
qm create ${IMGID} --memory 512 --net0 virtio,bridge=vmbr0
qm importdisk ${IMGID} ${IMG} ${STORAGEID} --format qcow2
qm set ${IMGID} --scsihw virtio-scsi-pci --scsi0 ${STORAGEID}:vm-${IMGID}-disk-0
qm set ${IMGID} --ide2 ${STORAGEID}:cloudinit
qm set ${IMGID} --boot c --bootdisk scsi0
qm set ${IMGID} --serial0 socket --vga serial0
qm template ${IMGID}

# set host cpu, ssh key, etc
qm set ${IMGID} --scsihw virtio-scsi-pci
qm set ${IMGID} --cpu host
qm set ${IMGID} --agent enabled=1
qm set ${IMGID} --autostart
qm set ${IMGID} --onboot 1
qm set ${IMGID} --ostype l26
qm set ${IMGID} --ipconfig0 "ip=dhcp"

Adapt to fit your needs and run it on your Proxmox VE until it works without any problems and creates a template in your Proxmox VE. You may need to install libguestfs-tools.

After the image is created, you can start to use the machine driver to create new VMs:

#!/bin/sh
set -ex

export PATH=$PWD:$PATH

PVE_NODE="proxmox"
PVE_HOST="192.168.1.5"

PVE_USER="docker-machine"
PVE_REALM="pve"
PVE_PASSWD="D0ck3rS3cr3t"

PVE_STORAGE_NAME="${1:-docker-machine}"
PVE_POOL="docker-machine"

VM_NAME="docker-clone"

docker-machine rm --force $VM_NAME >/dev/null 2>&1 || true

docker-machine --debug \
    create \
    --driver proxmoxve \
    --proxmoxve-proxmox-host $PVE_HOST \
    --proxmoxve-proxmox-node $PVE_NODE \
    --proxmoxve-proxmox-user-name $PVE_USER \
    --proxmoxve-proxmox-user-password $PVE_PASSWD \
    --proxmoxve-proxmox-realm $PVE_REALM \
    --proxmoxve-proxmox-pool $PVE_POOL \
    \
    --proxmoxve-provision-strategy clone \
    --proxmoxve-ssh-username 'debian' \
    --proxmoxve-ssh-password 'geheim' \
    --proxmoxve-vm-clone-vmid 9007 \
    \
    --proxmoxve-debug-resty \
    --proxmoxve-debug-driver \
    \
    $* \
    \
    $VM_NAME

eval $(docker-machine env $VM_NAME)

docker ps

Rancher OS

  • Use a recent, e.g. 1.5.6 version of RancherOS and copy the rancheros-proxmoxve-autoformat.iso to your iso image storage on your PVE
  • Create a script with the following contents and adapt to your needs:
PVE_NODE="proxmox-docker-machine"
PVE_HOST="192.168.1.10"

PVE_USER="docker-machine"
PVE_REALM="pve"
PVE_PASSWD="D0ck3rS3cr3t"

PVE_STORAGE_NAME="docker-machine"
PVE_STORAGE_SIZE="4"
PVE_POOL="docker-machine"

SSH_USERNAME="docker"
SSH_PASSWORD="tcuser"

PVE_MEMORY=2
PVE_CPU_CORES=4
PVE_IMAGE_FILE="docker-machine-iso:iso/rancheros-proxmoxve-autoformat-v1.5.5.iso"
VM_NAME="docker-rancher"

docker-machine rm --force $VM_NAME >/dev/null 2>&1 || true

docker-machine --debug \
    create \
    --driver proxmoxve \
    --proxmoxve-proxmox-host $PVE_HOST \
    --proxmoxve-proxmox-node $PVE_NODE \
    --proxmoxve-proxmox-user-name $PVE_USER \
    --proxmoxve-proxmox-user-password $PVE_PASSWD \
    --proxmoxve-proxmox-realm $PVE_REALM \
    --proxmoxve-proxmox-pool $PVE_POOL \
    \
    --proxmoxve-vm-storage-path $PVE_STORAGE_NAME \
    --proxmoxve-vm-storage-size $PVE_STORAGE_SIZE \
    --proxmoxve-vm-cpu-cores $PVE_CPU_CORES \
    --proxmoxve-vm-memory $PVE_MEMORY \
    --proxmoxve-vm-image-file "$PVE_IMAGE_FILE" \
    \
    --proxmoxve-ssh-username $SSH_USERNAME \
    --proxmoxve-ssh-password $SSH_PASSWORD \
    \
    --proxmoxve-debug-resty \
    --proxmoxve-debug-driver \
    \
    $VM_NAME


eval $(docker-machine env $VM_NAME)

docker ps
  • Run the script

At the first run, it is advisable to not comment out the debug flags. If everything works as expected, you can remove them.

Changes

Version 4

Version 3

Version 2

  • exclusive RancherOS support due to their special Proxmox VE iso files
  • adding wait cycles for asynchronous background tasks, e.g. create, stop etc.
  • use one logger engine
  • add guest username, password and ssh-port as new command line arguments
  • more and potentially better error handling

Version 1

  • Initial Version

docker-machine-driver-proxmox-ve's People

Contributors

bemanuel avatar lnxbil avatar psayker avatar travisghansen 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  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  avatar  avatar  avatar  avatar  avatar

docker-machine-driver-proxmox-ve's Issues

using clone

I'm interested in making this more cloud-like utilizing clone functionality of base images + cloud-init to inject keys etc.

Here's a crude outline of manual steps I did that I think will do the trick:

# clone
# -description
# -pool
pvesh create /nodes/cloud01/qemu/9003/clone --output-format json-pretty -newid 114

create linked clone of drive scsi0 (bitness-nfs:9003/base-9003-disk-0.qcow2)
clone 9003/base-9003-disk-0.qcow2: images, vm-114-disk-0.qcow2, 114 to vm-114-disk-0.qcow2 (base=../9003/base-9003-disk-0.qcow2)
Formatting '/mnt/pve/bitness-nfs/images/114/vm-114-disk-0.qcow2', fmt=qcow2 size=2361393152 backing_file=../9003/base-9003-disk-0.qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
create full clone of drive ide2 (bitness-nfs:9003/vm-9003-cloudinit.qcow2)
Formatting '/mnt/pve/bitness-nfs/images/114/vm-114-cloudinit.qcow2', fmt=qcow2 size=4194304 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16
"UPID:cloud01:00001DED:09D28645:5F1325C9:qmclone:9003:root@pam:"

# resize disk
pvesh set /nodes/cloud01/qemu/114/resize --output-format json-pretty -disk scsi0 -size 20G
Image resized.

# sockets, memory, etc
# -sshkeys (1 per line)
# -cores (# of cores per socket)
# -cpu (set cpu details)
pvesh create /nodes/cloud01/qemu/114/config --output-format json-pretty -autostart 1 -memory 4096 -sockets 4


# get currently set sshkeys 
pvesh get /nodes/cloud01/qemu/114/config --output-format json-pretty

# append newly created key to list
# urlencoded, 1 per-line
pvesh create /nodes/cloud01/qemu/114/config --output-format json-pretty -sshkeys ssh-rsa%20AAAAB3NzaC1yc2EAAAABIwAAAQEAnXCCFFYODq4Q%2FXy2NxUqbFWPm3nvK6NZezdWQCDI5gJrHJ%2Bw5%2BqemAQiLGZEVY0mfPrZk4bv%2FFUvJdF4ajq%2BQnFJ%2FnKAUQP0YI5QBQzAWWk4N8jLxBj9OjZ91tx9P3iV4qZ2V2gteQRQtnme6kojfgwajBhe1cFugkYEWVZIu08laixoUpq015j4JDt2bu0uiDbxG7XEze3kk5R23ynFWHOrYyaw7TD9ZuP4hI17PEcfhszDTBYbe8Dr%2FnDnogN9LLpDJftxxyoTbxhm86BDqVgBCfTGeq2g6hdpZsjf6CaanVSCc7BAlwg0ZMWVSEDYrrE9vg8X8pawuzy7G3ZueQ%3D%3D%20thansen%40e1405%0Assh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAABAQDVLz3tobhcdSTd4nnKvApwBKR2suEGDBfX13K2eilXm290KNGGU%2BLrAIO9b5Mm1cF27z6aZQ9Fsw5LTs4CKWTLSBV5JWtFdXyJ3B0ko8Sr6OA3Vi7QyF7076OX%2FsUTbx1egQTWsNUrknPNKwkjAD3ZMIkBgyT9L%2BrDleofjk22FTvpz40ZRNIma7P9STzvawB1OrD5d7iu0i5QY%2B2BVr2x1rugmN9GghYstTIQUl9gYnrlYmARkEdZaymc3pU5HdFNjPO%2FwPNSmZRcvUeXw6ZqhyrzaDzaQrC6pFevjLSzSpGQfFSjPOcYm9iGq5rymVDddt1%2BK8UPjwHS%2BJmrcRu1%0A

I create pre-baked images (based on the upstream provided cloud images from ubuntu, centos, etc) where common tools are added such as:

  • qemu-guest-agent
  • cloud-init
  • nfs-utils
  • iscsi
  • etc

My intent it to further add the templates to rancher-ui to provision directly from there.

Is there any interest in supporting the above flow and/or would it be accepted if I hacked something together?

Thank you thank you thank you!

Finally! Someone wrote a docker-machine driver for Proxmox VE :)

Thank you!

I'll be testing this out today and report back with any issues and hopefully I will have BW to contribute!

Getting IP Address of QEMU Guest

So I did a bit of research and found what I believe is a viable and reliable way of getting the IP Address of a QEMU Guest.

$ qm agent 302 network-get-interfaces | jq -r '.[] | select(."hardware-address" == "42:24:09:dd:1c:73") | ."ip-addresses" | .[] | ."ip-address"'

Basically this requires that the qemu-guest-agent is installed on the guest and qemu-ga daemon is running. You can then either run qm agent <vmid> <command> or probably talk tot he UNIX sokcet directly on the PRmoxox VE host.

Unexpected EOF

(test) {"time":"2018-03-04T11:57:09.662373565-08:00","level":"WARN","prefix":"-","file":"proxmoxdriver.go","line":"145","message":"Connected to version '5.1'"}
Error creating machine: Error in driver during machine creation: unexpected EOF
notifying bugsnag: [Error creating machine: Error in driver during machine creation: unexpected EOF]

Some thoughts:

  • I may be on a newer Proxmox VE than you.

Vlan Tag

Hi!
Great Work!
Is there a way to set the vlan tag on the network interface ?

Storage not found

Hello, I'm trying your driver that seems very interesting ! Perhaps I have a problem with "--proxmox-storage" option what ever I use it return "storage xxxx not found". This error happen even if I don't use option.

Here my command :
docker-machine create --driver proxmox-ve --proxmox-disksize-gb "16" --proxmox-driver-debug --proxmox-guest-password "tcuser" --proxmox-host "192.168.0.100" --proxmox-image-file "local:./boot2docker.iso" --proxmox-memory-gb "8" --proxmox-node prox --proxmox-password deploy --proxmox-realm "pve" --proxmox-resty-debug --proxmox-storage "disque_2" --proxmox-storage-type "raw" --proxmox-user "deploy" node1

And the error message :

(node1) {"time":"2019-08-15T22:23:03.100958642+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"58","message":"Create called"}
(node1) {"time":"2019-08-15T22:23:03.100978417+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"58","message":"Connecting to 192.168.0.100 as deploy@pve with password 'deploy'"}
(node1) {"time":"2019-08-15T22:23:03.135099605+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"58","message":"Connected to PVE version '5.4'"}
(node1) {"time":"2019-08-15T22:23:03.135121594+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"64","message":"Retrieving next ID"}
(node1) {"time":"2019-08-15T22:23:03.137414645+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"58","message":"Next ID was '102'"}
Error with pre-create check: "storage 'disque_2' not found"

I join a screenshot of my proxmox disk maybe i didn't understand something.
Capture d’écran de 2019-08-15 22-26-45

Thanks for your work and your help

Does it support Proxmox VE 6?

I have tried to use it in Rancher 2.3.2 as node driver but always got:

failed with : Error with pre-create check: "unexpected end of JSON input"

Does not work with Proxmox VE version 7.2

The drivers does not seems to work wuth Proxmox VE 7.2.
Steps to reproduce:
Run docker-machine command with following parameters:

docker-machine --debug create --driver proxmoxve --proxmoxve-proxmox-host proxmox15.example.com --proxmoxve-proxmox-node proxmox.example.com --proxmoxve-proxmox-user-name root --proxmoxve-proxmox-user-password veryVeryStrong_pass-123 --proxmoxve-proxmox-realm pam --proxmoxve-proxmox-pool kubernetes --proxmoxve-vm-clone-full 2 --proxmoxve-provision-strategy clone --proxmoxve-ssh-username ubuntu --proxmoxve-ssh-password geheim --proxmoxve-vm-clone-vmid 226 --proxmoxve-debug-resty --proxmoxve-debug-driver docker-clone

The stdout of docker-machine command:

Docker Machine Version: 0.16.2, build HEAD
Found binary path at /usr/local/bin/docker-machine-driver-proxmoxve
Launching plugin server for driver proxmoxve
Plugin server listening at address 127.0.0.1:43061
() Calling .GetVersion
Using API Version 1
() Calling .SetConfigRaw
() Calling .GetMachineName
(flag-lookup) Calling .GetMachineName
(flag-lookup) Calling .DriverName
(flag-lookup) Calling .GetCreateFlags
Found binary path at /usr/local/bin/docker-machine-driver-proxmoxve
Launching plugin server for driver proxmoxve
Plugin server listening at address 127.0.0.1:38731
() Calling .GetVersion
Using API Version 1
() Calling .SetConfigRaw
() Calling .GetMachineName
(docker-clone) Calling .GetMachineName
(docker-clone) Calling .DriverName
(docker-clone) Calling .GetCreateFlags
(docker-clone) Calling .SetConfigFromFlags
(docker-clone) {"time":"2022-11-07T16:20:59.776125384+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"95","message":"enabling Resty debugging"}
Reading certificate data from /root/.docker/machine/certs/ca.pem
Decoding PEM data...
Parsing certificate...
Reading certificate data from /root/.docker/machine/certs/cert.pem
Decoding PEM data...
Parsing certificate...
Running pre-create checks...
(docker-clone) Calling .PreCreateCheck
(docker-clone) {"time":"2022-11-07T16:20:59.776361357+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"Create called"}
(docker-clone) {"time":"2022-11-07T16:20:59.776369328+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"Connecting to proxmox16.example as root@pam with password 'veryVeryStrong_pass-123'"}
(docker-clone) {"time":"2022-11-07T16:21:00.271040299+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"Connected to PVE version '7.2-11'"}
(docker-clone) Calling .GetConfigRaw
Creating machine...
(docker-clone) Calling .Create
(docker-clone) {"time":"2022-11-07T16:21:00.273072673+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"95","message":"creating new ssh keypair"}
(docker-clone) {"time":"2022-11-07T16:21:00.484644432+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"sleeping 1369 milliseconds before retrieving next ID"}
(docker-clone) {"time":"2022-11-07T16:21:01.853857298+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"95","message":"Retrieving next ID"}
(docker-clone) RESTY 2022/11/07 16:21:01
(docker-clone) ---------------------- REQUEST LOG -----------------------
(docker-clone) GET /api2/json/cluster/nextid HTTP/1.1
(docker-clone) HOST : proxmox15.example:8006
(docker-clone) HEADERS:
(docker-clone) Cookie: PVEAuthCookie=PVE:root@pam:6368F82C::PXUiJUyD3TYhKvC10/ElKunBDwRo4NeJpCCRw14C0vhGz86rhcyXDQBXPOqLMf2kr0K14vO2OkhlRE9FUKnxiJsOK3229RwVQABpAxp+U5Udfe4gTnVLrdYcutSVu1oSYrKCSpJhs2ppmZWcpteqj01cnry0xZlQkRr+5G8VqRGyU+C0udy5Kvxv/fjJCzISkW8/2FfecQmngeoZ6Rc1sdpm+dMkuptm+CKBYZA8gXp4U3I8/6yxvmasf5XXvFatL9O//j0jOAfHnhj5P4bZ5PH24jc44qFpkRKAl/sVFtl55CG2YJnbR8sWorFI0gF9yjOLmfJpYDNdgiLJGkS4hg==
(docker-clone) Csrfpreventiontoken: 6368F82C:5Ib2saPoS3HnxwvboZrLNodvTDOzDDuBltyaf0n2GTk
(docker-clone) User-Agent: go-resty v1.7 - https://github.com/go-resty/resty
(docker-clone) BODY :
(docker-clone) ***** NO CONTENT *****
(docker-clone) ----------------------------------------------------------
(docker-clone) RESTY 2022/11/07 16:21:01
(docker-clone) ---------------------- RESPONSE LOG -----------------------
(docker-clone) STATUS : 200 OK
(docker-clone) RECEIVED AT : 2022-11-07T16:21:01.863114494+04:00
(docker-clone) RESPONSE TIME : 9.005886ms
(docker-clone) HEADERS:
(docker-clone) Cache-Control: max-age=0
(docker-clone) Connection: Keep-Alive
(docker-clone) Content-Length: 14
(docker-clone) Content-Type: application/json;charset=UTF-8
(docker-clone) Date: Mon, 07 Nov 2022 12:21:01 GMT
(docker-clone) Expires: Mon, 07 Nov 2022 12:21:01 GMT
(docker-clone) Pragma: no-cache
(docker-clone) Server: pve-api-daemon/3.0
(docker-clone) BODY :
(docker-clone) {
(docker-clone) "data": "106"
(docker-clone) }
(docker-clone) ----------------------------------------------------------
(docker-clone) {"time":"2022-11-07T16:21:01.863470063+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"Next ID is '106'"}
(docker-clone) {"time":"2022-11-07T16:21:01.863540458+04:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"cloning template id '226' as vmid '106'"}
(docker-clone) RESTY 2022/11/07 16:21:01
(docker-clone) ---------------------- REQUEST LOG -----------------------
(docker-clone) POST /api2/json/nodes/proxmox.example.com/qemu/226/clone HTTP/1.1
(docker-clone) HOST : proxmox15.example.com:8006
(docker-clone) HEADERS:
(docker-clone) Content-Type: application/x-www-form-urlencoded
(docker-clone) Cookie: PVEAuthCookie=PVE:root@pam:<SOME_STRING>//<SOME_STRING_2>
(docker-clone) Csrfpreventiontoken: <SOME_STRING>
(docker-clone) User-Agent: go-resty v1.7 - https://github.com/go-resty/resty
(docker-clone) BODY :
(docker-clone) name=docker-clone&newid=106&pool=kubernetes
(docker-clone) ----------------------------------------------------------
(docker-clone) RESTY 2022/11/07 16:21:31
(docker-clone) ---------------------- RESPONSE LOG -----------------------
(docker-clone) STATUS : 595 Connection timed out
(docker-clone) RECEIVED AT : 2022-11-07T16:21:31.911785414+04:00
(docker-clone) RESPONSE TIME : 30.047896419s
(docker-clone) HEADERS:
(docker-clone) Cache-Control: max-age=0
(docker-clone) Date: Mon, 07 Nov 2022 12:21:31 GMT
(docker-clone) Expires: Mon, 07 Nov 2022 12:21:31 GMT
(docker-clone) Pragma: no-cache
(docker-clone) Server: pve-api-daemon/3.0
(docker-clone) BODY :
(docker-clone)
(docker-clone) ----------------------------------------------------------
Error creating machine: Error in driver during machine creation: status code was '595' and error is
595 Connection timed out
notifying bugsnag: [Error creating machine: Error in driver during machine creation: status code was '595' and error is
595 Connection timed out]

Discuss: Add MIT license

@lnxbil I propose to add MIT license to relieve from any duties. This would be better to explicitly declare license, because you can have some problem with law or somebody can start a lawsuit against you.

Rancher: Error with pre-create check: "unexpected end of JSON input"

When trying the v2 binary from within Rancher, I get the following errors:

Error with pre-create check: "unexpected end of JSON input"

and

Timeout waiting for ssh key

While trying to provision nodes for the cluster. I'm not sure what troubleshooting steps to perform next. I will try to provision via cli as outlined in the Readme.

500 error during cfs-locked - downloaded binary

v4 binary fails with error:

(rancher) ---------------------- RESPONSE LOG -----------------------
(rancher) STATUS : 500 error during cfs-locked 'storage-docker-data' operation: illegal name 'vm--disk-0' - should be 'vm-103-*'
(rancher) RECEIVED AT : 2020-08-09T20:25:37.949677272+01:00
(rancher) RESPONSE TIME : 14.709889ms
(rancher) HEADERS:
(rancher) Cache-Control: max-age=0
(rancher) Content-Length: 13
(rancher) Content-Type: application/json;charset=UTF-8
(rancher) Date: Sun, 09 Aug 2020 19:25:37 GMT
(rancher) Expires: Sun, 09 Aug 2020 19:25:37 GMT
(rancher) Pragma: no-cache
(rancher) Server: pve-api-daemon/3.0
(rancher) BODY :
(rancher) {
(rancher) "data": null
(rancher) }
(rancher) ----------------------------------------------------------

however ID lookup shows

(rancher) BODY :
(rancher) {
(rancher) "data": "103"
(rancher) }

Cloning MASTER and compiling does not have this issue.

(rancher) ---------------------- RESPONSE LOG -----------------------
(rancher) STATUS : 200 OK
(rancher) RECEIVED AT : 2020-08-09T20:44:24.871733238+01:00
(rancher) RESPONSE TIME : 214.399028ms
(rancher) HEADERS:
(rancher) Cache-Control: max-age=0
(rancher) Content-Length: 36
(rancher) Content-Type: application/json;charset=UTF-8
(rancher) Date: Sun, 09 Aug 2020 19:44:24 GMT
(rancher) Expires: Sun, 09 Aug 2020 19:44:24 GMT
(rancher) Pragma: no-cache
(rancher) Server: pve-api-daemon/3.0
(rancher) BODY :
(rancher) {
(rancher) "data": "docker-data:vm-103-disk-0"
(rancher) }
(rancher) ----------------------------------------------------------

Rancher: Authentication when adding a node template

In Rancher web interface, the Proxmox provider password is currently displayed in clear in the form for adding a node template.

proxmox_auth

It would be nicer if the auth worked similarly to the other Rancher infrastructure providers with a prealable authentication check and a proper password form field, here is an example for Packet:

packet_auth

I am not sure if this issue should be here or in the Rancher repository, but it is related to #18 from @Sellto

Unsupported format "qcow2"

Trying out latest commits:

$ docker-machine create -d proxmox-ve --proxmox-storage zfs --proxmox-node vz1 --proxmox-memory-gb 1 --proxmox-image-file rancheros.iso --proxmox-host vz1 --proxmox-password $(read -s -p 'Password: ' password; echo $password) test1
Password: Running pre-create checks...
Creating machine...
(test1) {"time":"2018-04-17T22:56:11.14660046-07:00","level":"WARN","prefix":"-","file":"log.go","line":"297","message":"Create called"}
(test1) {"time":"2018-04-17T22:56:11.146728495-07:00","level":"WARN","prefix":"-","file":"log.go","line":"301","message":"Connecting to vz1 as root@pam with password 'xxx'\n"}
(test1) {"time":"2018-04-17T22:56:11.247815209-07:00","level":"WARN","prefix":"-","file":"log.go","line":"297","message":"Connected to version '5.1'"}
(test1) {"time":"2018-04-17T22:56:11.24785578-07:00","level":"WARN","prefix":"-","file":"log.go","line":"301","message":"Retrieving next ID\n"}
(test1) {"time":"2018-04-17T22:56:11.251795712-07:00","level":"WARN","prefix":"-","file":"log.go","line":"301","message":"Next ID was '105'\n"}
(test1) {"time":"2018-04-17T22:56:11.251851533-07:00","level":"WARN","prefix":"-","file":"log.go","line":"301","message":"Creating disk volume 'vm-105-disk-1.qcow2' with size '16G'\n"}
(test1) {"time":"2018-04-17T22:56:11.276793424-07:00","level":"FATAL","prefix":"-","file":"log.go","line":"321","message":"status code was '500' and error is\n500 unsupported format 'qcow2' at /usr/share/perl5/PVE/Storage/ZFSPoolPlugin.pm line 229."}
Error creating machine: Error in driver during machine creation: unexpected EOF

invalid format - unable to parse volume ID 'vm-104-disk-1'

2019/12/28 04:05:57 [INFO] [node-controller-docker-machine] (k8s-1) {"time":"2019-12-28T04:05:54.06368707Z","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"60","message":"Creating VM '104' with '6144' of memory"}
2019/12/28 04:05:57 [INFO] [node-controller-docker-machine] (k8s-1) RESTY 2019/12/28 04:05:54 
2019/12/28 04:05:57 [INFO] [node-controller-docker-machine] (k8s-1) ---------------------- REQUEST LOG -----------------------
2019/12/28 04:05:57 [INFO] [node-controller-docker-machine] (k8s-1) POST  /api2/json/nodes/cloud/qemu  HTTP/1.1
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) HOST   : cloud.domain:8006
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) HEADERS:
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)              Content-Type: application/x-www-form-urlencoded
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)                    Cookie: PVEAuthCookie=PVE:user@pam:cookie
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)       Csrfpreventiontoken: token
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)                User-Agent: go-resty/1.12.0 (https://github.com/go-resty/resty)
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) BODY   :
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) agent=1&autostart=1&cdrom=local%!A(MISSING)iso%!F(MISSING)rancheros-proxmoxve-autoformat.iso&cores=4&kvm=1&memory=6144&name=k8s-1&net0=virtio%!C(MISSING)bridge%!D(MISSING)vmbr0&ostype=l26&pool=heap&scsi0=vm-104-disk-1&vmid=104
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) ----------------------------------------------------------
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) RESTY 2019/12/28 04:05:54 
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) ---------------------- RESPONSE LOG -----------------------
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) STATUS              : 400 Parameter verification failed.
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) RECEIVED AT : 2019-12-28T04:05:54.087624868Z
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) RESPONSE TIME       : 23.668001ms
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) HEADERS:
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)             Cache-Control: max-age=0
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)            Content-Length: 140
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)              Content-Type: application/json;charset=UTF-8
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)                      Date: Sat, 28 Dec 2019 04:05:54 GMT
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)                   Expires: Sat, 28 Dec 2019 04:05:54 GMT
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)                    Pragma: no-cache
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)                    Server: pve-api-daemon/3.0
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) BODY   :
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) {
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)    "errors": {
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)       "scsi0": "invalid format - format error\nscsi0.file: invalid format - unable to parse volume ID 'vm-104-disk-1'\n\n"
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)    },
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1)    "data": null
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) }
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] (k8s-1) ----------------------------------------------------------
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine] The default lines below are for a sh/bash shell, you can specify the shell you're using, with the --shell flag.
2019/12/28 04:05:58 [INFO] [node-controller-docker-machine]

What am I doing wrong? Used v3-pre3 release and lvm-thinpool.

configdrive2? How does this work?

I set the following flags:

  --proxmoxve-vm-cienabled=1 \
  --proxmoxve-vm-citype=configdrive2 \

And I see the Clouddrive is created and attached to the VM. But most of the values are not filled in.

How do we fill these in when creating the Clouddrive2? I don't see where this is happenning in the code.

Driver does not work with Proxmox VE version 7.3-3

The driver does not seem to work with Proxmox VE 7.3-3.

Steps to reproduce:
Run the docker-machine command with the following flags:

docker-machine --debug
create
--driver proxmoxve
--proxmoxve-proxmox-host proxmox16.example.com
--proxmoxve-proxmox-user-name root
--proxmoxve-proxmox-user-password StrongPassword123
--proxmoxve-proxmox-realm pam
--proxmoxve-proxmox-pool rancher

--proxmoxve-vm-storage-path rancher
--proxmoxve-vm-storage-size 4
--proxmoxve-vm-cpu-cores 4
--proxmoxve-vm-memory 2

--proxmoxve-ssh-username testuser
--proxmoxve-ssh-password testpassword

--proxmoxve-debug-resty
--proxmoxve-debug-driver

testDockerMachineDriver

The stdout is:

Docker Machine Version: 0.16.2, build bd45ab13
Found binary path at /home/sam/docker-machine-driver-proxmoxve
Launching plugin server for driver proxmoxve
Plugin server listening at address 127.0.0.1:33947
() Calling .GetVersion
Using API Version 1
() Calling .SetConfigRaw
() Calling .GetMachineName
(flag-lookup) Calling .GetMachineName
(flag-lookup) Calling .DriverName
(flag-lookup) Calling .GetCreateFlags
Found binary path at /home/sam/docker-machine-driver-proxmoxve
Launching plugin server for driver proxmoxve
Plugin server listening at address 127.0.0.1:41877
() Calling .GetVersion
Using API Version 1
() Calling .SetConfigRaw
() Calling .GetMachineName
(test-proxmox-driver) Calling .GetMachineName
(test-proxmox-driver) Calling .DriverName
(test-proxmox-driver) Calling .GetCreateFlags
(test-proxmox-driver) Calling .SetConfigFromFlags
(test-proxmox-driver) {"time":"2023-05-17T10:28:40.553245879+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"95","message":"enabling Resty debugging"}
Creating CA: /home/sam/.docker/machine/certs/ca.pem
Creating client certificate: /home/sam/.docker/machine/certs/cert.pem
Running pre-create checks...
(test-proxmox-driver) Calling .PreCreateCheck
(test-proxmox-driver) {"time":"2023-05-17T10:28:41.182114366+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"Create called"}
(test-proxmox-driver) {"time":"2023-05-17T10:28:41.182175964+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"Connecting to proxmox16.example as root@pam with password 'StrongPassword123'"}
(test-proxmox-driver) {"time":"2023-05-17T10:28:41.278200363+02:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"89","message":"Connected to PVE version '7.3-3'"}
(test-proxmox-driver) RESTY 2023/05/17 10:28:41
(test-proxmox-driver) ---------------------- REQUEST LOG -----------------------
(test-proxmox-driver) GET /api2/json/nodes/proxmox16.example/storage HTTP/1.1
(test-proxmox-driver) HOST : proxmox16.example:8006
(test-proxmox-driver) HEADERS:
(test-proxmox-driver) Cookie: PVEAuthCookie=PVE:root@pam:64649039::-..........-
(test-proxmox-driver) Csrfpreventiontoken: 64649039:ID/........
(test-proxmox-driver) User-Agent: go-resty v1.7 - https://github.com/go-resty/resty
(test-proxmox-driver) BODY :
(test-proxmox-driver) ***** NO CONTENT *****
(test-proxmox-driver) ----------------------------------------------------------
(test-proxmox-driver) RESTY 2023/05/17 10:28:41
(test-proxmox-driver) ---------------------- RESPONSE LOG -----------------------
(test-proxmox-driver) STATUS : 596 tls_process_server_certificate: certificate verify failed
(test-proxmox-driver) RECEIVED AT : 2023-05-17T10:28:41.312148799+02:00
(test-proxmox-driver) RESPONSE TIME : 33.856571ms
(test-proxmox-driver) HEADERS:
(test-proxmox-driver) Cache-Control: max-age=0
(test-proxmox-driver) Date: Wed, 17 May 2023 08:28:41 GMT
(test-proxmox-driver) Expires: Wed, 17 May 2023 08:28:41 GMT
(test-proxmox-driver) Pragma: no-cache
(test-proxmox-driver) Server: pve-api-daemon/3.0
(test-proxmox-driver) BODY :
(test-proxmox-driver)
(test-proxmox-driver) ----------------------------------------------------------
Error with pre-create check: "unexpected end of JSON input"
notifying bugsnag: [Error with pre-create check: "unexpected end of JSON input"]

What worked for me:

The pve-node-name was incorrect and after changing it I was able to connect to the server

Tests in CEPH

I could provide some tests using CEPH.
Actually, I'm using now VMs provided by docker-machine with disks on RBD

Feature Request: VMID range

Dear lnxbil,

Your last update was amazing, everything seems to work as it should, so thanks for that!

We were wondering if it would be possible to add a vmid range to the options?

How could I go about to do it, for me to make a pull request?

Regards,

The System isn't using disk

After the system is created, even with disk attached the vm isn't using the disk yet. So there's a problem of disk space when run anything. There is a way to auto this process?

Inaccessible node can't connect to SSH

I tried to create a node with your driver and example script, but doesnt work:

"Error creating machine: Error in driver during machine creation: dial tcp :22: connect: connection refused"

I think that is because the machine doesn't have a IP address, how I can define it? I readed the docs and "helper" (docker-machine create --driver proxmoxve --help) but there is nothing about this. I use static ip's in my Proxmox instance. I need to use DHCP?

Integrate new API endpoints to copy data

via the new API endpoints, we can now finally copy files and execute commands:

root@proxmox ~ > pvesh create /nodes/proxmox/qemu/109/agent/file-write -content "file" -file "/root/test"

root@proxmox ~ > pvesh create /nodes/proxmox/qemu/109/agent/exec -command id
┌─────┬───────┐
│ key │ value │
├─────┼───────┤
│ pid │ 1708  │
└─────┴───────┘

root@proxmox ~ > pvesh get /nodes/proxmox/qemu/109/agent/exec-status -pid 1708
┌──────────┬────────────────────────────────────────┐
│ key      │ value                                  │
├──────────┼────────────────────────────────────────┤
│ exitcode │ 0                                      │
├──────────┼────────────────────────────────────────┤
│ exited   │ 1                                      │
├──────────┼────────────────────────────────────────┤
│ out-data │ uid=0(root) gid=0(root) groups=0(root) │
└──────────┴────────────────────────────────────────┘

This should be very useful in copying the initial SSH key over to the guest.

returned diskname is not correct

Hello,

I try to use your driver (v2) as a node-driver in Rancher to provide a Kubernetes cluster.
But i have a issue, the logs return me this error :
Error creating machine: Error in driver during machine creation: returned diskname is not correct.

Rancher Error

However, as you can see in the screen shot, the disk is correctly created but the VM isn't created:

proxmox

Here is my proxmox node template in Rancher:

proxmox option

Any idea to resolve this problem?

Next VM id doesn't mean there will be disk available

I'm not sure about this assumption, but it looks like vm disk name is generated automatically without checking if it is available:

Error creating machine: Error in driver during machine creation: status code was '500' and error is
500 lvcreate 'pve/vm-100-disk-1' error:   Logical Volume "vm-100-disk-1" already exists in volume group "pve"
notifying bugsnag: [Error creating machine: Error in driver during machine creation: status code was '500' and error is
500 lvcreate 'pve/vm-100-disk-1' error:   Logical Volume "vm-100-disk-1" already exists in volume group "pve"]
++ docker-machine env new-drv-test
Error checking TLS connection: Error checking and/or regenerating the certs: There was an error validating certificates for host "": dial tcp: missing address
You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'.
Be advised that this will trigger a Docker daemon restart which might stop running containers.

No enough space and infinite loop

At some point, I forgot to add PVE_MEMORY parameter and I ended up in infinite loop waiting for Qemu guest agent, but of course, Rancher crashed because of not enough space. I assume lack of PVE_MEMORY should just not run 🤔

Funding

I said in the forum that I'd put my money where my mouth is. Have somewhere I can send some funds to see this happen?

Copy of Patched ISO?

I have almost gotten this to work - but am having trouble building the new iso at the moment. Do you have a copy of it somewhere that would be accessible?

-Andy

Rancher OS and Proxmox VE 5.2-12

Hi @lnxbil,
many thanks for this driver.

I'm fighting little bit with setting infrastructure using it, after initial problems with running on my Proxmox VE server I was able to reliably create VMs. My setup-vm.sh script looks like that:

#!/bin/bash -x

export PATH=${PATH}:${HOME}/bin

PVE_NODE="pve"
PVE_HOST="<my_ip>"
PVE_MEMORY=${PVE_MEMORY:-1}
PVE_REALM="pve"
PVE_POOL="docker-machine"
PVE_STORAGE="local-lvm"
PVE_STORAGE_TYPE="RAW"
PVE_IMAGE_FILE="local:iso/rancheros.iso"

docker-machine rm --force $VM_NAME >/dev/null 2>&1 || true

docker-machine --debug \
    create \
    --driver proxmox-ve \
    --proxmox-host $PVE_HOST \
    --proxmox-user $PVE_USER \
    --proxmox-realm $PVE_REALM \
    --proxmox-password $PVE_PASSWD \
    --proxmox-node $PVE_NODE \
    --proxmox-memory-gb $PVE_MEMORY \
    --proxmox-image-file "$PVE_IMAGE_FILE" \
    --proxmox-storage $PVE_STORAGE \
    --proxmox-pool $PVE_POOL \
    --proxmox-storage-type $PVE_STORAGE_TYPE \
    --proxmox-driver-debug \
    $* \
    $VM_NAME

eval $(docker-machine env ${VM_NAME})

docker ps

Then I figured out that boot2docker doesn't persist data as it should - I described that on forum. So I wanted to give a try to Rancher OS.

First problem is that default image v1.5.0 doesn't have qemu-guest-agent enabled by default, which cause infinite loop in proxmox driver, I managed to enable and run that service manually:

(my-vm) {"time":"2018-12-31T17:24:11.88153714+01:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"64","message":"status code was '500' and error is\n500 QEMU guest agent is not running"}
(my-vm) {"time":"2018-12-31T17:24:11.88159905+01:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"58","message":"waiting for VM to become active"}
(my-vm) {"time":"2018-12-31T17:24:16.641505327+01:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"58","message":"VM is active waiting more"}
(my-vm) {"time":"2018-12-31T17:24:19.305080141+01:00","level":"INFO","prefix":"-","file":"proxmoxdriver.go","line":"58","message":"Creating directory '/home/docker/.ssh'"}
Error creating machine: Error in driver during machine creation: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
notifying bugsnag: [Error creating machine: Error in driver during machine creation: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain]
++ docker-machine env my-vm
Error checking TLS connection: Error checking and/or regenerating the certs: There was an error validating certificates for host "192.168.3.218:2376": dial tcp 192.168.3.218:2376: connect: connection refused
You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'.
Be advised that this will trigger a Docker daemon restart which might stop running containers.

+ eval
+ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

But as you can see I faced other error.

It would be great to improve little bit README.md so anyone can start debugging, development and bufixing - e.g. I'm not Go expert and had little problems with figuring out how to iterate through development cycle. Anyway this is great project and I definitely has potential of being very useful for community - maybe at some point could be included as default component of docker-machine.

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.