├── .gitignore ├── Makefile ├── README.md ├── Vagrantfile ├── config ├── default.yml └── rtorrent-dl.yml ├── lib ├── config.rb ├── helpers.rb └── network.rb ├── puppet ├── manifests │ └── default.pp └── modules │ ├── baseconfig │ ├── files │ │ ├── bashrc │ │ ├── environment │ │ ├── pam.common-session │ │ └── sshd_config │ └── manifests │ │ └── init.pp │ ├── builder │ ├── files │ │ ├── db.rtorrent.if1v4 │ │ ├── db.rtorrent.if1v6 │ │ ├── db.rtorrent.if2v4 │ │ ├── db.rtorrent.if2v6 │ │ ├── mararc.default │ │ ├── mararc.if1v4 │ │ ├── mararc.v4 │ │ ├── opentracker.conf │ │ ├── opentracker.init │ │ └── rtorrent.rc │ └── manifests │ │ └── init.pp │ └── client │ ├── files │ ├── rules.v4 │ └── rules.v6 │ └── manifests │ └── init.pp ├── scripts ├── build-branch ├── build-check ├── build-compare-headers ├── build-compare-libtorrent ├── build-compare-rtorrent ├── build-current ├── build-git-clone ├── build-has-feature ├── build-set-config ├── build-state-headers ├── build-state-libtorrent ├── build-state-rtorrent ├── build-tags ├── build-tracker ├── call-d-multicall ├── call-local-id ├── call-main ├── call-node ├── clean-builder ├── client-start ├── config-bind-add ├── config-bind-clear ├── config-bind-set ├── config-clear ├── config-disable-port-randomize ├── config-enable-dht-global ├── config-enable-port-randomize ├── config-enable-rpc-dump ├── config-set-block-accept ├── config-set-block-connect ├── config-set-port-range ├── config-set-protocol-encryption ├── cp-torrent ├── dl-export ├── dl-load ├── include │ ├── call │ ├── call-args │ ├── call-rpc │ ├── call-ssh │ ├── call-test │ ├── config │ ├── init │ ├── local-id.awk │ ├── ls-torrents.awk │ ├── repo │ ├── test │ ├── test-unit │ └── torrent ├── ip-dns-config ├── ip-dns-down ├── ip-dns-resolver ├── ip-dns-up ├── ip-down-4-1 ├── ip-down-4-2 ├── ip-down-6-1 ├── ip-down-6-2 ├── ip-up-4-1 ├── ip-up-4-2 ├── ip-up-6-1 ├── ip-up-6-2 ├── is-client-active ├── is-client-empty ├── is-client-inactive ├── is-completed ├── is-loaded ├── is-torrent-cached ├── is-unloaded ├── kill-rtorrent ├── ls-torrents ├── network-bind ├── node │ ├── build-rtorrent │ ├── build-tracker │ ├── change-ipv4-1 │ ├── change-ipv4-2 │ ├── change-ipv6-1 │ ├── change-ipv6-2 │ ├── check-libtorrent │ ├── check-rtorrent │ ├── disable-ipv4-1 │ ├── disable-ipv4-2 │ ├── disable-ipv6-1 │ ├── disable-ipv6-2 │ ├── enable-ipv4-1 │ ├── enable-ipv4-2 │ ├── enable-ipv6-1 │ ├── enable-ipv6-2 │ ├── kill-rtorrent │ ├── make-torrent │ ├── metadata.source │ ├── scripts │ │ ├── client-start │ │ └── ip-dns-resolver │ ├── start-rtorrent │ ├── stop-rtorrent │ ├── update-etc │ └── update-metadata ├── ns-all ├── ns-ip ├── ns-listen ├── rm-torrent ├── scp ├── ssh ├── start-rtorrent ├── stop-rtorrent ├── test-all ├── test-create-all ├── test-delete-all ├── test-feature-dns ├── test-list ├── test-torrent-all ├── torrent-activate ├── torrent-create ├── torrent-data-compare ├── torrent-data-root ├── torrent-data-wc ├── torrent-deactivate ├── torrent-export ├── torrent-info-hash ├── torrent-list ├── update-current-nodes ├── update-rtorrent-config ├── update-ssh-config ├── update-ssh-service └── xmlrpc2scgi.py └── test ├── bind_add_v4v6only_accept ├── bind_port_randomize ├── bind_port_simple ├── bind_set_v4v6only ├── default ├── dns_default ├── encryption_none └── encryption_require /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor poo # 2 | ############## 3 | .#* 4 | \#*# 5 | *~ 6 | 7 | # OS generated files # 8 | ###################### 9 | .DS_Store? 10 | .dirstamp 11 | ehthumbs.db 12 | Icon? 13 | Thumbs.db 14 | TAGS 15 | 16 | # VM files # 17 | ############ 18 | data/* 19 | .vagrant/ 20 | 21 | *.orig 22 | logs/ 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Current OS X uses GNU Make 3.81 which seems to not properly handle 2 | # dependencies, so use the ugly hack of calling 'make foo' directly. 3 | 4 | BRANCH?=master 5 | LIBTORRENT_BRANCH?=$(BRANCH) 6 | RTORRENT_BRANCH?=$(BRANCH) 7 | 8 | export USE_CONFIG?=$(shell cat ./data/current-config 2> /dev/null || echo default) 9 | export VAGRANT_USE_VAGRANT_TRIGGERS=1 10 | 11 | all: 12 | @echo "RTorrent Vagrant environment" 13 | @echo 14 | @echo "make setup - install required vagrant plugins" 15 | @echo "make init - initialize vms and build rtorrent (support BRANCH, or LIBTORRENT_BRANCH and RTORRENT_BRANCH variables)" 16 | @echo "make rebuild - rebuild libtorrent and rtorrent" 17 | 18 | init: 19 | @echo "Using branches libtorrent '$(LIBTORRENT_BRANCH)' and rtorrent '$(RTORRENT_BRANCH)'." 20 | 21 | -"$(MAKE)" clean 22 | 23 | ./scripts/build-set-config "$(USE_CONFIG)" 24 | vagrant up 25 | ./scripts/update-current-nodes 26 | ./scripts/update-ssh-service 27 | ./scripts/update-ssh-config 28 | 29 | ./scripts/build-git-clone 30 | ./scripts/build-tracker 31 | "$(MAKE)" build_branch 32 | ./scripts/build-tags 33 | ./scripts/config-clear 34 | ./scripts/ip-dns-config default 35 | ./scripts/ip-dns-resolver default 36 | ./scripts/start-rtorrent 37 | 38 | feature-bind: 39 | ./scripts/build-set-config "default" 40 | BRANCH=feature-bind USE_CONFIG=default "$(MAKE)" init 41 | 42 | node-dl: 43 | ./scripts/build-set-config "rtorrent-dl" 44 | BRANCH=feature-bind USE_CONFIG=rtorrent-dl "$(MAKE)" init 45 | 46 | vagrant destroy -f builder 47 | 48 | ./scripts/config-enable-dht-global "shared" 49 | "$(MAKE)" restart 50 | 51 | # TODO: This may have issues is the rtorrent clients don't shut down 52 | # fast enough. Consider adding a wait thing and do the stop_nodes 53 | # after build, or using a single script. 54 | rebuild: 55 | ./scripts/stop-rtorrent 56 | ./scripts/build-current 57 | ./scripts/start-rtorrent -s 58 | 59 | rebuild_rtorrent: 60 | ./scripts/stop-rtorrent 61 | SKIP_LIBTORRENT=yes ./scripts/build-current 62 | ./scripts/start-rtorrent -s 63 | 64 | check: 65 | ./scripts/stop-rtorrent 66 | ./scripts/ssh builder -- "check-libtorrent" 67 | ./scripts/ssh builder -- "check-rtorrent" 68 | ./scripts/start-rtorrent -s 69 | 70 | check_rtorrent: 71 | ./scripts/stop-rtorrent 72 | ./scripts/ssh builder -- "check-rtorrent" 73 | ./scripts/start-rtorrent -s 74 | 75 | restart: 76 | ./scripts/stop-rtorrent 77 | sleep 2 78 | ./scripts/start-rtorrent -s 79 | 80 | build_branch: 81 | @echo "Bulding libtorrent '$(LIBTORRENT_BRANCH)' and rtorrent '$(RTORRENT_BRANCH)'." 82 | ./scripts/build-branch $(LIBTORRENT_BRANCH) $(RTORRENT_BRANCH) 83 | 84 | tags: 85 | find scripts -name '[a-z0-9/-]*' | etags - 86 | 87 | setup: 88 | vagrant plugin install vagrant-vbguest 89 | vagrant plugin install vagrant-disksize 90 | vagrant plugin install vagrant-cachier 91 | vagrant plugin install vagrant-triggers 92 | 93 | # Change to also destroy all found nodes. 94 | clean: 95 | -./scripts/stop-rtorrent 96 | -vagrant destroy -f 97 | 98 | distclean: 99 | -./scripts/stop-rtorrent 100 | -vagrant destroy -f 101 | -rm -rf ./data/* 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | rtorrent-vagrant 2 | ================ 3 | 4 | Test environment for rtorrent using Vagrant. 5 | 6 | 7 | Stuff 8 | ----- 9 | 10 | While this environment primarily serves the needs of the main developer of rtorrent (me), that does not preclude contributions. 11 | 12 | 13 | Getting Started 14 | --------------- 15 | 16 | ``` 17 | make setup - install required vagrant plugins 18 | make init - initialize vms and build rtorrent (support BRANCH, or LIBTORRENT_BRANCH and RTORRENT_BRANCH variables) 19 | make rebuild - rebuild libtorrent and rtorrent 20 | make check - rebuild libtorrent and rtorrent with unittests 21 | make test_http4 - creates torrent and attempts to seed it 22 | ``` 23 | 24 | Example: 25 | 26 | ``` 27 | make setup && RTORRENT_BRANCH=feature-foo make init && make test_http4 28 | ``` 29 | 30 | 31 | Testing 32 | ------- 33 | 34 | Test all: 35 | 36 | ``` 37 | ./scripts/test-all 38 | ``` 39 | 40 | 41 | Blocked ports 42 | ------------- 43 | 44 | ``` 45 | eth1 ipv4 blocks 15000-15499 46 | eth2 ipv4 blocks 15500-15999 47 | eth1 ipv6 blocks 16000-16499 48 | eth2 ipv6 blocks 16500-16999 49 | ``` 50 | 51 | 52 | Cygwin issues 53 | ------------- 54 | 55 | Including emacs's bin directory in PATH may causes issues. -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | 3 | require './lib/config.rb' 4 | require './lib/helpers.rb' 5 | require './lib/network.rb' 6 | 7 | # TODO: Move to config file. 8 | DEFAULT_BOX = 'ubuntu/trusty64' 9 | CONFIG_DIR = 'config/' 10 | 11 | Vagrant.require_version ">= 1.8.0" 12 | 13 | config_name = ENV['USE_CONFIG'].to_s.empty? ? 'default' : ENV['USE_CONFIG'] 14 | global_config = parse_config_file(config_name) 15 | 16 | Vagrant.configure('2') do |config| 17 | global_config[:nodes].each do |node| 18 | name = node[:name] 19 | vm_name = node[:vm_name] || name 20 | 21 | config.vm.define name, node_define_params(node) do |node_config| 22 | node_config.vm.box = (node[:box] || DEFAULT_BOX) 23 | node_config.vm.hostname = name + '.example.com' 24 | 25 | configure_networks(node_config, node) 26 | 27 | disable_default_folder(node_config) 28 | 29 | add_local_data(node_config, node_name: name, 30 | auto_cleanup: !node[:builder]) 31 | add_shared_data(node_config, node_name: name, 32 | shared_name: 'shared', 33 | should_create: node[:primary], 34 | should_destroy: false) 35 | add_shared_data(node_config, node_name: name, 36 | shared_name: 'usr_local', 37 | shared_path: '/usr/local', 38 | should_create: node[:primary], 39 | should_destroy: false) 40 | 41 | node_config.vm.synced_folder "./scripts/node", "/data/scripts" 42 | 43 | # Change how update-metadata handles disabling of inet. 44 | node_config.trigger.after :up do 45 | run_remote '/data/scripts/update-metadata' 46 | end 47 | 48 | node_config.vm.provider 'virtualbox' do |vb| 49 | vb.name = "rtorrent-#{vm_name}" 50 | vb.linked_clone = true 51 | 52 | vb.cpus = node[:cpus] if node[:cpus] 53 | vb.memory = node[:memory] if node[:memory] 54 | vb.disksize.size = node[:disk_size] if node[:disk_size] 55 | 56 | vb.customize ["modifyvm", :id, "--groups", "/rtorrent-#{config_name}"] 57 | end 58 | 59 | node_config.vm.provision 'puppet' do |puppet| 60 | puppet.manifests_path = 'puppet/manifests' 61 | puppet.module_path = 'puppet/modules' 62 | #puppet.options="--verbose --debug" 63 | end 64 | end 65 | end 66 | 67 | config.vbguest.auto_update = false 68 | config.vbguest.installer_arguments = ['--nox11'] 69 | 70 | if Vagrant.has_plugin?('vagrant-cachier') 71 | config.cache.scope = :box 72 | config.cache.enable :apt_lists 73 | config.cache.auto_detect = true 74 | end 75 | 76 | config.trigger.after :destroy, vm: ['builder'], force: true do 77 | run 'bash ./scripts/clean-builder' 78 | end 79 | 80 | end 81 | -------------------------------------------------------------------------------- /config/default.yml: -------------------------------------------------------------------------------- 1 | nodes: 2 | 3 | - name: builder 4 | primary: true 5 | builder: true 6 | cpus: 8 7 | memory: 3072 8 | interfaces: 9 | - network: rnet1 10 | ipv4: 10.0.3.10 11 | ipv6: fd00:7103:0:1::10 12 | - network: rnet2 13 | ipv4: 10.0.4.10 14 | ipv6: fd00:7103:0:2::10 15 | 16 | - name: node1 17 | cpus: 1 18 | memory: 512 19 | forward: 20 | - guest: 5001 21 | host: 18601 22 | interfaces: 23 | - network: rnet1 24 | ipv4: 10.0.3.11 25 | ipv6: fd00:7103:0:1::11 26 | - network: rnet2 27 | ipv4: 10.0.4.11 28 | ipv6: fd00:7103:0:2::11 29 | 30 | - name: node2 31 | cpus: 1 32 | memory: 512 33 | forward: 34 | - guest: 5001 35 | host: 18602 36 | interfaces: 37 | - network: rnet1 38 | ipv4: 10.0.3.12 39 | ipv6: fd00:7103:0:1::12 40 | - network: rnet2 41 | ipv4: 10.0.4.12 42 | ipv6: fd00:7103:0:2::12 43 | 44 | - name: node3 45 | cpus: 1 46 | memory: 512 47 | forward: 48 | - guest: 5001 49 | host: 18603 50 | interfaces: 51 | - network: rnet1 52 | ipv4: 10.0.3.13 53 | ipv6: fd00:7103:0:1::13 54 | - network: rnet2 55 | ipv4: 10.0.4.13 56 | ipv6: fd00:7103:0:2::13 57 | 58 | - name: node4 59 | cpus: 1 60 | memory: 512 61 | forward: 62 | - guest: 5001 63 | host: 18604 64 | interfaces: 65 | - network: rnet1 66 | ipv4: 10.0.3.14 67 | ipv6: fd00:7103:0:1::14 68 | - network: rnet2 69 | ipv4: 10.0.4.14 70 | ipv6: fd00:7103:0:2::14 71 | 72 | - name: node5 73 | cpus: 1 74 | memory: 512 75 | forward: 76 | - guest: 5001 77 | host: 18605 78 | interfaces: 79 | - network: rnet1 80 | ipv4: 10.0.3.15 81 | ipv6: fd00:7103:0:1::15 82 | - network: rnet2 83 | ipv4: 10.0.4.15 84 | ipv6: fd00:7103:0:2::15 85 | -------------------------------------------------------------------------------- /config/rtorrent-dl.yml: -------------------------------------------------------------------------------- 1 | nodes: 2 | 3 | - name: builder 4 | vm_name: builder-dl 5 | primary: true 6 | builder: true 7 | cpus: 8 8 | memory: 2048 9 | interfaces: 10 | - network: rt-dl 11 | ipv4: 10.0.3.10 12 | ipv6: fd00:7103:0:ff::10 13 | 14 | - name: node-dl 15 | cpus: 4 16 | memory: 10240 17 | disk_space: 30GB 18 | forward: 19 | - guest: 5001 20 | host: 18701 21 | interfaces: 22 | - network: rt-dl 23 | ipv4: 10.0.3.11 24 | ipv6: fd00:7103:0:ff::11 25 | -------------------------------------------------------------------------------- /lib/config.rb: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | 3 | require 'json' 4 | 5 | def parse_config_file(name) 6 | config_file = File.expand_path(File.join('../config/', "#{name}.yml"), File.dirname(__FILE__)) 7 | 8 | deep_symbolize_keys(YAML.load(File.open(config_file).read)) 9 | end 10 | 11 | -------------------------------------------------------------------------------- /lib/helpers.rb: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | 3 | def deep_symbolize_keys(object) 4 | case object 5 | when Array 6 | object.map { |value| 7 | deep_symbolize_keys(value) 8 | } 9 | when Hash 10 | object.map { |key, value| 11 | [key.to_sym, deep_symbolize_keys(value)] 12 | }.to_h 13 | else 14 | object 15 | end 16 | end 17 | 18 | def node_define_params(node) 19 | { primary: node[:primary], 20 | autostart: node.has_key?(:autostart) ? node[:autostart] : true, 21 | } 22 | end 23 | 24 | def disable_default_folder(node_config) 25 | node_config.vm.synced_folder '.', '/vagrant', disabled: true 26 | end 27 | 28 | def add_local_data(node_config, node_name:, data_user: nil, data_group: nil, should_create: true, auto_cleanup:) 29 | raise Vagrant::Errors::VagrantError.new, "add_local_data called with no valid 'node_name'" if node_name.nil? 30 | 31 | node_config.vm.synced_folder "./data/#{node_name}", '/data/local', owner: data_user, group: data_group, create: should_create 32 | 33 | node_config.trigger.after :destroy, vm: [node_name], force: true do 34 | run "rm -rf ./data/#{node_name}" if auto_cleanup 35 | end 36 | end 37 | 38 | def add_shared_data(node_config, node_name:, shared_name:, shared_path: nil, should_create:, should_destroy:) 39 | raise Vagrant::Errors::VagrantError.new, "add_shared_data called with no valid 'node_name'" if node_name.nil? 40 | raise Vagrant::Errors::VagrantError.new, "add_shared_data called with no valid 'shared_name'" if shared_name.nil? 41 | 42 | node_config.vm.synced_folder "./data/#{shared_name}", shared_path || "/data/#{shared_name}", create: should_create 43 | 44 | if should_create && should_destroy 45 | node_config.trigger.after :destroy, vm: [node_name], force: true do 46 | run "rm -rf ./data/#{shared_name}" 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /lib/network.rb: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | 3 | def configure_networks(node, config) 4 | config[:interfaces] && config[:interfaces].each_with_index { |interface, nw_index| 5 | interface[:network].nil? && (raise Vagrant::Errors::ConfigInvalid.new) 6 | interface[:ipv4].nil? && (raise Vagrant::Errors::ConfigInvalid.new) 7 | interface[:ipv6].nil? && (raise Vagrant::Errors::ConfigInvalid.new) 8 | 9 | node.vm.network 'private_network', type: 'static', ip: private_network_ip(interface), virtualbox__intnet: interface[:network] 10 | # node.vm.network 'private_network', type: 'static', ip: private_network_ip(interface), virtualbox__hostonly: interface[:network] 11 | 12 | node.trigger.after :up do 13 | if enable_ipv4?(interface) 14 | run_remote "/data/scripts/change-ipv4-#{nw_index + 1} #{interface[:ipv4]}/24" 15 | else 16 | run_remote "/data/scripts/disable-ipv4-#{nw_index + 1}" 17 | end 18 | 19 | if enable_ipv6?(interface) 20 | run_remote "/data/scripts/change-ipv6-#{nw_index + 1} #{interface[:ipv6]}/64" 21 | else 22 | run_remote "/data/scripts/disable-ipv6-#{nw_index + 1}" 23 | end 24 | end 25 | } 26 | 27 | config[:forward] && config[:forward].each { |params| # Replace with named args. 28 | forward_port(node, params) 29 | } 30 | end 31 | 32 | def enable_ipv4?(interface) 33 | interface[:ipv4] 34 | end 35 | 36 | def enable_ipv6?(interface) 37 | interface[:ipv6] 38 | end 39 | 40 | def private_network_ip(interface) 41 | case 42 | when enable_ipv4?(interface) 43 | return interface[:ipv4] 44 | when enable_ipv6?(interface) 45 | return interface[:ipv6] 46 | else 47 | raise Vagrant::Errors::ConfigInvalid.new 48 | end 49 | end 50 | 51 | def valid_port?(port, allow_nil: false) 52 | if port 53 | port > 0 && port < (1 << 16) 54 | else 55 | allow_nil 56 | end 57 | end 58 | 59 | def forward_port(node, params) 60 | if !valid_port?(params[:guest]) || !valid_port?(params[:host]) 61 | raise Vagrant::Errors::ConfigInvalid.new 62 | end 63 | 64 | # TODO: Bind to NAT interface. 65 | guest_ip = nil 66 | 67 | node.vm.network 'forwarded_port', guest: params[:guest], guest_ip: guest_ip, host: params[:host] 68 | 69 | node.trigger.after :up do 70 | run_remote "echo #{params[:host]} > /data/local/metadata/forward.#{params[:guest]}" 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /puppet/manifests/default.pp: -------------------------------------------------------------------------------- 1 | Exec { 2 | path => "/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin", 3 | } 4 | 5 | stage { 'pre': 6 | before => Stage['main'] 7 | } 8 | 9 | class { 'baseconfig': 10 | stage => 'pre' 11 | } 12 | 13 | node /^builder\./ { 14 | include builder 15 | } 16 | 17 | node /^builder-dl\./ { 18 | include builder 19 | } 20 | 21 | node /^node\d+\./ { 22 | include client 23 | } 24 | 25 | node /^node-dl\./ { 26 | include client 27 | } 28 | -------------------------------------------------------------------------------- /puppet/modules/baseconfig/files/bashrc: -------------------------------------------------------------------------------- 1 | # If not running interactively, don't do anything 2 | case $- in 3 | *i*) ;; 4 | *) return;; 5 | esac 6 | 7 | shopt -s histappend 8 | 9 | if [ -x /usr/bin/dircolors ]; then 10 | test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" 11 | alias ls='ls --color=auto' 12 | #alias dir='dir --color=auto' 13 | #alias vdir='vdir --color=auto' 14 | 15 | alias grep='grep --color=auto' 16 | alias fgrep='fgrep --color=auto' 17 | alias egrep='egrep --color=auto' 18 | fi 19 | 20 | if ! shopt -oq posix; then 21 | if [ -f /usr/share/bash-completion/bash_completion ]; then 22 | . /usr/share/bash-completion/bash_completion 23 | elif [ -f /etc/bash_completion ]; then 24 | . /etc/bash_completion 25 | fi 26 | fi 27 | -------------------------------------------------------------------------------- /puppet/modules/baseconfig/files/environment: -------------------------------------------------------------------------------- 1 | PATH="/data/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 2 | LD_LIBRARY_PATH="/usr/local/lib" 3 | -------------------------------------------------------------------------------- /puppet/modules/baseconfig/files/pam.common-session: -------------------------------------------------------------------------------- 1 | # here are the per-package modules (the "Primary" block) 2 | session [default=1] pam_permit.so 3 | 4 | # here's the fallback if no module succeeds 5 | session requisite pam_deny.so 6 | 7 | # prime the stack with a positive return value if there isn't one already; 8 | # this avoids us returning an error just because nothing sets a success code 9 | # since the modules above will each just jump around 10 | session required pam_permit.so 11 | 12 | # The pam_umask module will set the umask according to the system default in 13 | # /etc/login.defs and user settings, solving the problem of different 14 | # umask settings with different shells, display managers, remote sessions etc. 15 | # See "man pam_umask". 16 | session optional pam_umask.so 17 | 18 | # and here are more per-package modules (the "Additional" block) 19 | session required pam_unix.so 20 | #session optional pam_systemd.so 21 | -------------------------------------------------------------------------------- /puppet/modules/baseconfig/files/sshd_config: -------------------------------------------------------------------------------- 1 | Protocol 2 2 | 3 | # HostKeys for protocol version 2 4 | HostKey /etc/ssh/ssh_host_rsa_key 5 | HostKey /etc/ssh/ssh_host_dsa_key 6 | HostKey /etc/ssh/ssh_host_ecdsa_key 7 | HostKey /etc/ssh/ssh_host_ed25519_key 8 | 9 | UsePrivilegeSeparation yes 10 | KeyRegenerationInterval 3600 11 | ServerKeyBits 1024 12 | 13 | SyslogFacility AUTH 14 | LogLevel INFO 15 | 16 | # Authentication: 17 | LoginGraceTime 120 18 | PermitRootLogin without-password 19 | StrictModes yes 20 | 21 | RSAAuthentication yes 22 | PubkeyAuthentication yes 23 | 24 | IgnoreRhosts yes 25 | RhostsRSAAuthentication no 26 | HostbasedAuthentication no 27 | 28 | ChallengeResponseAuthentication no 29 | GSSAPIAuthentication no 30 | KerberosAuthentication no 31 | 32 | PermitEmptyPasswords no 33 | PasswordAuthentication no 34 | 35 | X11Forwarding yes 36 | X11DisplayOffset 10 37 | PrintMotd no 38 | PrintLastLog yes 39 | TCPKeepAlive yes 40 | #UseLogin no 41 | 42 | # Allow client to pass locale environment variables 43 | AcceptEnv LANG LC_* 44 | 45 | Subsystem sftp /usr/lib/openssh/sftp-server 46 | 47 | # Disable UseDNS to speed up logging in. 48 | UsePAM yes 49 | UseDNS no 50 | -------------------------------------------------------------------------------- /puppet/modules/baseconfig/manifests/init.pp: -------------------------------------------------------------------------------- 1 | class baseconfig { 2 | 3 | group { 'puppet': 4 | ensure => 'present', 5 | } 6 | 7 | package { 8 | ['libncurses5', 'libxmlrpc-core-c3', 'libudns0', 9 | 'lsb-release', 'screen', 'gdb', 10 | ]: 11 | ensure => installed 12 | } 13 | 14 | $data_dirs = ['/data/local/log', 15 | '/data/local/metadata', 16 | '/data/local/run'] 17 | 18 | file { 19 | [$data_dirs, 20 | '/usr/local/bin/' 21 | ]: 22 | ensure => directory, 23 | } 24 | 25 | file { '/etc/environment': 26 | ensure => file, 27 | source => 'puppet:///modules/baseconfig/environment', 28 | } 29 | 30 | file { '/etc/ssh/sshd_config': 31 | ensure => file, 32 | source => 'puppet:///modules/baseconfig/sshd_config', 33 | } 34 | 35 | file { '/etc/pam.d/common-session': 36 | ensure => file, 37 | source => 'puppet:///modules/baseconfig/pam.common-session', 38 | } 39 | 40 | file { '/home/vagrant/.bashrc': 41 | ensure => file, 42 | owner => "vagrant", 43 | group => "vagrant", 44 | source => 'puppet:///modules/baseconfig/bashrc', 45 | } 46 | 47 | file { '/home/vagrant/.hushlogin': 48 | ensure => present, 49 | content => '', 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/db.rtorrent.if1v4: -------------------------------------------------------------------------------- 1 | builder.% A 10.0.3.10 ~ 2 | node1.% A 10.0.3.11 ~ 3 | node2.% A 10.0.3.12 ~ 4 | node3.% A 10.0.3.13 ~ 5 | node4.% A 10.0.3.14 ~ 6 | node5.% A 10.0.3.15 ~ 7 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/db.rtorrent.if1v6: -------------------------------------------------------------------------------- 1 | builder.% AAAA fd00:7103:0:1::10 ~ 2 | node1.% AAAA fd00:7103:0:1::11 ~ 3 | node2.% AAAA fd00:7103:0:1::12 ~ 4 | node3.% AAAA fd00:7103:0:1::13 ~ 5 | node4.% AAAA fd00:7103:0:1::14 ~ 6 | node5.% AAAA fd00:7103:0:1::15 ~ 7 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/db.rtorrent.if2v4: -------------------------------------------------------------------------------- 1 | builder.% A 10.0.4.10 ~ 2 | node1.% A 10.0.4.11 ~ 3 | node2.% A 10.0.4.12 ~ 4 | node3.% A 10.0.4.13 ~ 5 | node4.% A 10.0.4.14 ~ 6 | node5.% A 10.0.4.15 ~ 7 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/db.rtorrent.if2v6: -------------------------------------------------------------------------------- 1 | builder.% AAAA fd00:7103:0:2::10 ~ 2 | node1.% AAAA fd00:7103:0:2::11 ~ 3 | node2.% AAAA fd00:7103:0:2::12 ~ 4 | node3.% AAAA fd00:7103:0:2::13 ~ 5 | node4.% AAAA fd00:7103:0:2::14 ~ 6 | node5.% AAAA fd00:7103:0:2::15 ~ 7 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/mararc.default: -------------------------------------------------------------------------------- 1 | chroot_dir = "/data/shared/maradns" 2 | maradns_user = "maradns" 3 | no_fingerprint = 1 4 | 5 | ipv4_bind_addresses = "10.0.3.10" 6 | ipv6_bind_address = "fd00:7103:0:1::10" 7 | 8 | csv2 = {} 9 | csv2["rtorrent.if1v4."] = "db.rtorrent.if1v4" 10 | csv2["rtorrent.if1v6."] = "db.rtorrent.if1v6" 11 | csv2["rtorrent.if2v4."] = "db.rtorrent.if2v4" 12 | csv2["rtorrent.if2v6."] = "db.rtorrent.if2v6" 13 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/mararc.if1v4: -------------------------------------------------------------------------------- 1 | chroot_dir = "/data/shared/maradns" 2 | maradns_user = "maradns" 3 | no_fingerprint = 1 4 | 5 | ipv4_bind_addresses = "10.0.3.10" 6 | ipv6_bind_address = "fd00:7103:0:1::10" 7 | 8 | csv2 = {} 9 | csv2["rtorrent.if1v4."] = "db.rtorrent.if1v4" 10 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/mararc.v4: -------------------------------------------------------------------------------- 1 | chroot_dir = "/data/shared/maradns" 2 | maradns_user = "maradns" 3 | no_fingerprint = 1 4 | 5 | ipv4_bind_addresses = "10.0.3.10" 6 | ipv6_bind_address = "fd00:7103:0:1::10" 7 | 8 | csv2 = {} 9 | csv2["rtorrent.if1v4."] = "db.rtorrent.if1v4" 10 | csv2["rtorrent.if2v4."] = "db.rtorrent.if2v4" 11 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/opentracker.conf: -------------------------------------------------------------------------------- 1 | # opentracker config file 2 | # 3 | 4 | # I) Address opentracker will listen on, using both, tcp AND udp family 5 | # (note, that port 6969 is implicite if ommitted). 6 | # 7 | # If no listen option is given (here or on the command line), opentracker 8 | # listens on 0.0.0.0:6969 tcp and udp. 9 | # 10 | # The next variable determines if udp sockets are handled in the event 11 | # loop (set it to 0, the default) or are handled in blocking reads in 12 | # dedicated worker threads. You have to set this value before the 13 | # listen.tcp_udp or listen.udp statements before it takes effect, but you 14 | # can re-set it for each listen statement. Normally you should keep it at 15 | # the top of the config file. 16 | # 17 | # listen.udp.workers 4 18 | # 19 | # listen.tcp_udp 0.0.0.0 20 | # listen.tcp_udp 192.168.0.1:80 21 | # listen.tcp_udp 10.0.0.5:6969 22 | # 23 | # To only listen on tcp or udp family ports, list them this way: 24 | # 25 | # listen.tcp 0.0.0.0 26 | # listen.udp 192.168.0.1:6969 27 | # 28 | # Note, that using 0.0.0.0 for udp sockets may yield surprising results. 29 | # An answer packet sent on that socket will not necessarily have the 30 | # source address that the requesting client may expect, but any address 31 | # on that interface. 32 | # 33 | 34 | # II) If opentracker runs in a non-open mode, point it to files containing 35 | # all torrent hashes that it will serve (shell option -w) 36 | # 37 | # access.whitelist /path/to/whitelist 38 | # 39 | # or, if opentracker was compiled to allow blacklisting (shell option -b) 40 | # 41 | # access.blacklist ./blacklist 42 | # 43 | # It is pointless and hence not possible to compile black AND white 44 | # listing, so choose one of those options at compile time. File format 45 | # is straight forward: "\n\n..." 46 | # 47 | # If you do not want to grant anyone access to your stats, enable the 48 | # WANT_RESTRICT_STATS option in Makefile and bless the ip addresses 49 | # allowed to fetch stats here. 50 | # 51 | # access.stats 192.168.0.23 52 | # 53 | # There is another way of hiding your stats. You can obfuscate the path 54 | # to them. Normally it is located at /stats but you can configure it to 55 | # appear anywhere on your tracker. 56 | # 57 | # access.stats_path stats 58 | 59 | # III) Live sync uses udp multicast packets to keep a cluster of opentrackers 60 | # synchronized. This option tells opentracker which port to listen for 61 | # incoming live sync packets. The ip address tells opentracker, on which 62 | # interface to join the multicast group, those packets will arrive. 63 | # (shell option -i 192.168.0.1 -s 9696), port 9696 is default. 64 | # 65 | # livesync.cluster.listen 192.168.0.1:9696 66 | # 67 | # Note that two udp sockets will be opened. One on ip address 0.0.0.0 68 | # port 9696, that will join the multicast group 224.0.42.23 for incoming 69 | # udp packets and one on ip address 192.168.0.1 port 9696 for outgoing 70 | # udp packets. 71 | # 72 | # As of now one and only one ip address must be given, if opentracker 73 | # was built with the WANT_SYNC_LIVE feature. 74 | # 75 | 76 | # IV) Sync between trackers running in a cluster is restricted to packets 77 | # coming from trusted ip addresses. While source ip verification is far 78 | # from perfect, the authors of opentracker trust in the correct 79 | # application of tunnels, filters and LAN setups (shell option -A). 80 | # 81 | # livesync.cluster.node_ip 192.168.0.4 82 | # livesync.cluster.node_ip 192.168.0.5 83 | # livesync.cluster.node_ip 192.168.0.6 84 | # 85 | # This is the admin ip address for old style (HTTP based) asynchronus 86 | # tracker syncing. 87 | # 88 | # batchsync.cluster.admin_ip 10.1.1.1 89 | # 90 | 91 | # V) Control privilege drop behaviour. 92 | # Put in the directory opentracker will chroot/chdir to. All black/white 93 | # list files must be put in that directory (shell option -d). 94 | # 95 | # 96 | # tracker.rootdir /usr/local/etc/opentracker 97 | # 98 | # Tell opentracker which user to setuid to. 99 | # 100 | tracker.user nobody 101 | 102 | # VI) opentracker can be told to answer to a "GET / HTTP"-request with a 103 | # redirect to another location (shell option -r). 104 | # 105 | # tracker.redirect_url https://your.tracker.local/ 106 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/opentracker.init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### BEGIN INIT INFO 4 | # Provides: opentracker 5 | # Required-Start: $remote_fs $syslog 6 | # Required-Stop: $remote_fs $syslog 7 | # Default-Start: 2 3 4 5 8 | # Default-Stop: 0 1 6 9 | # Short-Description: Opentracker init script 10 | # Description: This a init script for Opentracker (a bittorrent tracker). 11 | ### END INIT INFO 12 | 13 | BIN="/usr/local/bin/opentracker" 14 | CONF_FILE="/etc/opentracker.conf" 15 | PID_FILE="/data/local/run/opentracker.pid" 16 | LOG_FILE="/data/local/log/tracker/opentracker.log" 17 | 18 | case "$1" in 19 | start) 20 | echo -n "Starting Open Bittorrent Tracker ..." 21 | 22 | # if [ -f ${LOG_FILE} ]; then 23 | # mv ${LOG_FILE} ${LOG_FILE}.`date +%F_%R` 24 | # fi 25 | 26 | start-stop-daemon --start --background --oknodo \ 27 | --chuid "vagrant" \ 28 | --pidfile "${PID_FILE}" --make-pidfile \ 29 | --exec /bin/bash -- -c "${BIN} -f ${CONF_FILE} > ${LOG_FILE}" 30 | 31 | if [ $? -ne 0 ]; then 32 | echo "Error: opentracker failed to start." 33 | exit 1 34 | fi 35 | 36 | sleep 1 37 | 38 | echo -n " [ OK ]" 39 | echo "." 40 | ;; 41 | 42 | stop) 43 | echo -n "Stopping Open Bittorrent Tracker" 44 | 45 | # if [ -f ${PID_FILE} ]; then 46 | # kill `cat ${PID_FILE}` 47 | # fi 48 | 49 | killall opentracker || true 50 | 51 | echo "." 52 | ;; 53 | 54 | *) 55 | echo "Usage: /etc/init.d/opentracker {start|stop}" 56 | exit 1 57 | esac 58 | -------------------------------------------------------------------------------- /puppet/modules/builder/files/rtorrent.rc: -------------------------------------------------------------------------------- 1 | # 2 | # Logging 3 | # 4 | 5 | # TODO: Rename 'critical' to something more descriptive. 6 | log.open_file = "crash", /data/local/log/crash.log 7 | try = ((log.add_output, "critical", "crash")) 8 | 9 | log.open_file = "rpc", /data/local/log/rpc.log 10 | try = ((log.add_output, "rpc", "rpc")) 11 | 12 | log.open_file = "connection", /data/local/log/connection.log 13 | log.open_file = "dht_all", /data/local/log/dht_all.log 14 | log.open_file = "net", /data/local/log/net.log 15 | log.open_file = "peer_list", /data/local/log/peer_list.log 16 | log.open_file = "system", /data/local/log/system.log 17 | 18 | try = ((log.add_output, "connection", "connection")) 19 | try = ((log.add_output, "dht_all", "dht_all")) 20 | try = ((log.add_output, "net_resolver", "net")) 21 | try = ((log.add_output, "peer_list_address", "peer_list")) 22 | try = ((log.add_output, "peer_list_events", "peer_list")) 23 | try = ((log.add_output, "system", "system")) 24 | 25 | 26 | # TODO: Refactor: 27 | log.open_file = "rtorrent", /data/local/log/rtorrent.log 28 | log.open_file = "torrent", /data/local/log/torrent.log 29 | log.open_file = "socket", /data/local/log/socket.log 30 | log.open_file = "storage", /data/local/log/storage.log 31 | log.open_file = "thread", /data/local/log/thread.log 32 | log.open_file = "tracker", /data/local/log/tracker.log 33 | log.open_file = "old_dht", /data/local/log/old_dht.log 34 | 35 | try = ((log.add_output, "debug", "rtorrent")) 36 | try = ((log.add_output, "torrent_debug", "torrent")) 37 | try = ((log.add_output, "socket_debug", "socket")) 38 | try = ((log.add_output, "storage_debug", "storage")) 39 | try = ((log.add_output, "thread_debug", "thread")) 40 | try = ((log.add_output, "tracker_debug", "tracker")) 41 | try = ((log.add_output, "dht_debug", "old_dht")) 42 | 43 | 44 | # 45 | # Settings: 46 | # 47 | 48 | print = "Loaded from '/etc/rtorrent.rc'" 49 | 50 | directory.default.set = "/data/torrents" 51 | session.path.set = "/data/local/session" 52 | 53 | #directory.watch.added = /data/shared/watch, load.start 54 | 55 | schedule = watch_directory,5,5,load.start=/data/shared/watch/*.torrent 56 | schedule = watch_untied, 10, 10, remove_untied= 57 | 58 | # 59 | # Per-node optional resource file: 60 | # 61 | 62 | try_import = /data/shared/config/extra.rc 63 | try_import = /data/local/config/extra.rc 64 | 65 | # 66 | # Others: 67 | # 68 | 69 | network.scgi.open_port = ":5001" 70 | -------------------------------------------------------------------------------- /puppet/modules/builder/manifests/init.pp: -------------------------------------------------------------------------------- 1 | class builder { 2 | 3 | exec { 'add-llvm-key': 4 | command => 'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -' 5 | } ~> Exec['update-apt'] 6 | 7 | exec { 'add-llvm-repo': 8 | command => 'sudo add-apt-repository "deb http://apt.llvm.org/`lsb_release -sc`/ llvm-toolchain-`lsb_release -sc` main"', 9 | } ~> Exec['update-apt'] 10 | 11 | exec { 'add-ubuntu-toolchain-r-test': 12 | command => 'sudo add-apt-repository ppa:ubuntu-toolchain-r/test', 13 | } ~> Exec['update-apt'] 14 | 15 | exec { 'update-apt': 16 | command => 'sudo apt-get update --fix-missing', 17 | } 18 | 19 | package { 20 | ['g++-4.8', 'g++-4.9', 'clang-9', 21 | 22 | 'automake', 'libtool', 'make', 'pkg-config', 'git-core', 23 | 'libcppunit-dev', 24 | 'libcurl4-openssl-dev', 'libncurses5-dev', 'libxmlrpc-core-c3-dev', 25 | 'libowfat-dev', 'libudns-dev', 26 | 27 | 'maradns', 28 | 'mktorrent', 29 | 'emacs24-nox', 30 | 'swapspace', 31 | ]: 32 | ensure => installed, 33 | require => Exec['add-llvm-key', 'add-llvm-repo', 'add-ubuntu-toolchain-r-test', 'update-apt'], 34 | } 35 | 36 | @group { opentracker: ensure=> present } 37 | @user { opentracker: ensure=> present, gid => opentracker } 38 | 39 | realize Group[opentracker] 40 | realize User[opentracker] 41 | 42 | file { '/etc/init.d/opentracker': 43 | ensure => file, 44 | mode => '0755', 45 | source => 'puppet:///modules/builder/opentracker.init' 46 | } 47 | 48 | file { '/etc/maradns/mararc.default': 49 | ensure => file, 50 | require => Package['maradns'], 51 | mode => '0644', 52 | source => 'puppet:///modules/builder/mararc.default' 53 | } 54 | 55 | file { '/etc/maradns/mararc.v4': 56 | ensure => file, 57 | require => Package['maradns'], 58 | mode => '0644', 59 | source => 'puppet:///modules/builder/mararc.v4' 60 | } 61 | 62 | file { '/etc/maradns/mararc.if1v4': 63 | ensure => file, 64 | require => Package['maradns'], 65 | mode => '0644', 66 | source => 'puppet:///modules/builder/mararc.if1v4' 67 | } 68 | 69 | file { '/etc/opentracker.conf': 70 | ensure => file, 71 | mode => '0644', 72 | source => 'puppet:///modules/builder/opentracker.conf' 73 | } 74 | 75 | file { 76 | ['/data/local/log/tracker', 77 | ]: 78 | ensure => directory, 79 | } 80 | 81 | file { 82 | ['/data/shared/config', 83 | '/data/shared/maradns', 84 | '/data/shared/torrents', 85 | '/data/shared/watch', 86 | ]: 87 | ensure => directory, 88 | mode => '0555', 89 | } 90 | 91 | file { '/data/shared/config/rtorrent.rc': 92 | ensure => file, 93 | mode => '0644', 94 | source => 'puppet:///modules/builder/rtorrent.rc' 95 | } 96 | 97 | file { '/data/shared/maradns/db.rtorrent.if1v4': 98 | ensure => file, 99 | mode => '0644', 100 | source => 'puppet:///modules/builder/db.rtorrent.if1v4' 101 | } 102 | 103 | file { '/data/shared/maradns/db.rtorrent.if1v6': 104 | ensure => file, 105 | mode => '0644', 106 | source => 'puppet:///modules/builder/db.rtorrent.if1v6' 107 | } 108 | 109 | file { '/data/shared/maradns/db.rtorrent.if2v4': 110 | ensure => file, 111 | mode => '0644', 112 | source => 'puppet:///modules/builder/db.rtorrent.if2v4' 113 | } 114 | 115 | file { '/data/shared/maradns/db.rtorrent.if2v6': 116 | ensure => file, 117 | mode => '0644', 118 | source => 'puppet:///modules/builder/db.rtorrent.if2v6' 119 | } 120 | 121 | 122 | } 123 | -------------------------------------------------------------------------------- /puppet/modules/client/files/rules.v4: -------------------------------------------------------------------------------- 1 | *filter 2 | :INPUT ACCEPT 3 | :FORWARD ACCEPT 4 | :OUTPUT ACCEPT 5 | -A INPUT -i eth1 -p tcp -m tcp --dport 15000:15499 -m state --state NEW,ESTABLISHED -j REJECT --reject-with tcp-reset 6 | -A INPUT -i eth2 -p tcp -m tcp --dport 15500:15999 -m state --state NEW,ESTABLISHED -j REJECT --reject-with tcp-reset 7 | COMMIT 8 | -------------------------------------------------------------------------------- /puppet/modules/client/files/rules.v6: -------------------------------------------------------------------------------- 1 | *filter 2 | :INPUT ACCEPT 3 | :FORWARD ACCEPT 4 | :OUTPUT ACCEPT 5 | -A INPUT -i eth1 -p tcp -m tcp --dport 16000:16499 -m state --state NEW,ESTABLISHED -j REJECT --reject-with tcp-reset 6 | -A INPUT -i eth2 -p tcp -m tcp --dport 16500:16999 -m state --state NEW,ESTABLISHED -j REJECT --reject-with tcp-reset 7 | COMMIT 8 | -------------------------------------------------------------------------------- /puppet/modules/client/manifests/init.pp: -------------------------------------------------------------------------------- 1 | class client { 2 | 3 | package { 4 | ['iptables-persistent']: 5 | ensure => installed 6 | } 7 | 8 | exec { 'iptables-persistent': 9 | command => 'sudo service iptables-persistent restart', 10 | } 11 | 12 | @group { rtorrent: ensure=> present } 13 | @user { rtorrent: ensure=> present, gid => rtorrent } 14 | 15 | realize Group[rtorrent] 16 | realize User[rtorrent] 17 | 18 | $data_dirs = ['/data/local/config', 19 | '/data/local/log/old', 20 | '/data/local/session', 21 | '/data/torrents'] 22 | 23 | file { $data_dirs: 24 | ensure => directory, 25 | owner => 'vagrant', 26 | group => 'vagrant' 27 | } 28 | 29 | File { 30 | owner => 'root', 31 | group => 'root', 32 | mode => '0755', 33 | } 34 | 35 | file { '/etc/iptables': 36 | ensure => directory 37 | } 38 | 39 | file { '/etc/iptables/rules.v4': 40 | ensure => file, 41 | mode => '0644', 42 | source => 'puppet:///modules/client/rules.v4' 43 | } 44 | 45 | file { '/etc/iptables/rules.v6': 46 | ensure => file, 47 | mode => '0644', 48 | source => 'puppet:///modules/client/rules.v6' 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /scripts/build-branch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | REPO_NAME=${3:-origin} 7 | LIBTORRENT_GIT_BRANCH=${1:?no libtorrent git branch provided} 8 | RTORRENT_GIT_BRANCH=${2:?no rtorrent git branch provided} 9 | 10 | echo "build-branch: updating git repositories" 11 | (cd $GIT_LIBTORRENT && (git pull $REPO_NAME || true) && git checkout $LIBTORRENT_GIT_BRANCH && (git pull || true)) || exit 1 12 | (cd $GIT_RTORRENT && (git pull $REPO_NAME || true) && git checkout $RTORRENT_GIT_BRANCH && (git pull || true)) || exit 1 13 | 14 | echo "build-branch: building rtorrent" 15 | call_ssh_node builder USE_CXX=g++-4.8 build-rtorrent 16 | 17 | echo "build-branch: building tags" 18 | "${SCRIPT_DIR}/build-tags" > /dev/null 19 | -------------------------------------------------------------------------------- /scripts/build-check: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | rm "${DATA_DIR}/builder/libtorrent/test/test-suite.log" || : 7 | rm "${DATA_DIR}/builder/rtorrent/test/test-suite.log" || : 8 | 9 | if [[ "${SKIP_LIBTORRENT}" != "yes" ]]; then 10 | call_ssh_node builder TEST_NAMES=${TEST_NAMES} check-libtorrent || cat "${DATA_DIR}/builder/libtorrent/test/test-suite.log" || exit 1 11 | fi 12 | 13 | if [[ "${SKIP_RTORRENT}" != "yes" ]]; then 14 | call_ssh_node builder TEST_NAMES=${TEST_NAMES} check-rtorrent || cat "${DATA_DIR}/builder/rtorrent/test/test-suite.log" || exit 1 15 | fi 16 | 17 | "${SCRIPT_DIR}/build-tags" > /dev/null 18 | -------------------------------------------------------------------------------- /scripts/build-compare-headers: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | OLD_HASH="$(<"${DATA_DIR}/current-state-headers")" 6 | CURRENT_HASH="$("${SCRIPT_DIR}/build-state-headers" 2> /dev/null)" 7 | 8 | [[ -n "${OLD_HASH}" ]] && [[ "${OLD_HASH}" == "${CURRENT_HASH}" ]] 9 | -------------------------------------------------------------------------------- /scripts/build-compare-libtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | OLD_HASH="$(<"${DATA_DIR}/current-state-libtorrent")" 6 | CURRENT_HASH="$("${SCRIPT_DIR}/build-state-libtorrent" 2> /dev/null)" 7 | 8 | [[ -n "${OLD_HASH}" ]] && [[ "${OLD_HASH}" == "${CURRENT_HASH}" ]] 9 | -------------------------------------------------------------------------------- /scripts/build-compare-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | OLD_HASH="$(<"${DATA_DIR}/current-state-rtorrent")" 6 | CURRENT_HASH="$("${SCRIPT_DIR}/build-state-rtorrent" 2> /dev/null)" 7 | 8 | [[ -n "${OLD_HASH}" ]] && [[ "${OLD_HASH}" == "${CURRENT_HASH}" ]] 9 | -------------------------------------------------------------------------------- /scripts/build-current: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | if [[ "$1" == "-r" ]]; then 7 | SKIP_LIBTORRENT="yes" 8 | fi 9 | 10 | call_build() { 11 | call_ssh_node builder \ 12 | USE_CXX=g++-4.8 \ 13 | BUILD_CONFIGURE=${BUILD_CONFIGURE} \ 14 | SKIP_LIBTORRENT=${SKIP_LIBTORRENT} \ 15 | SKIP_RTORRENT=${SKIP_RTORRENT} \ 16 | LIBTORRENT_CONF=\"${LIBTORRENT_CONF}\" \ 17 | RTORRENT_CONF=\"${RTORRENT_CONF}\" \ 18 | build-rtorrent 19 | } 20 | 21 | RTORRENT_CONF=("--with-xmlrpc-c") 22 | LIBTORRENT_CONF=() 23 | 24 | [[ "${WITH_UDNS}" == yes ]] && LIBTORRENT_CONF+=("--with-udns") 25 | [[ "${WITHOUT_UDNS}" == yes ]] && LIBTORRENT_CONF+=("--without-udns") 26 | 27 | [[ "${SKIP_LIBTORRENT}" != yes ]] && echo ${LIBTORRENT_CONF} > "${DATA_DIR}/current-libtorrent-conf" 28 | [[ "${SKIP_RTORRENT}" != yes ]] && echo ${RTORRENT_CONF} > "${DATA_DIR}/current-rtorrent-conf" 29 | 30 | if [[ "${BUILD_FORCE}" != yes ]]; then 31 | if "${SCRIPT_DIR}/build-compare-libtorrent"; then 32 | echo "build-current: libtorrent state unchanged, skipping" 33 | SKIP_LIBTORRENT=yes 34 | else 35 | echo "build-current: libtorrent state changed, compiling" 36 | fi 37 | 38 | if "${SCRIPT_DIR}/build-compare-headers" && "${SCRIPT_DIR}/build-compare-rtorrent"; then 39 | echo "build-current: rtorrent state unchanged, skipping" 40 | SKIP_RTORRENT=yes 41 | else 42 | echo "build-current: rtorrent state changed, compiling" 43 | fi 44 | else 45 | SKIP_LIBTORRENT=no 46 | SKIP_RTORRENT=no 47 | fi 48 | 49 | if [[ "${BUILD_QUIET}" == yes ]]; then 50 | echo "rtorrent started compiling..." 51 | call_quiet call_build 52 | call_quiet "${SCRIPT_DIR}/build-tags" 53 | echo "rtorrent finished compiling" 54 | else 55 | call_build 56 | "${SCRIPT_DIR}/build-tags" > /dev/null 57 | fi 58 | 59 | [[ "${SKIP_LIBTORRENT}" == yes ]] || "${SCRIPT_DIR}/build-state-libtorrent" > "${DATA_DIR}/current-state-libtorrent" 60 | [[ "${SKIP_RTORRENT}" == yes ]] || "${SCRIPT_DIR}/build-state-rtorrent" > "${DATA_DIR}/current-state-rtorrent" 61 | [[ "${SKIP_RTORRENT}" == yes ]] || "${SCRIPT_DIR}/build-state-headers" > "${DATA_DIR}/current-state-headers" 62 | -------------------------------------------------------------------------------- /scripts/build-git-clone: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | cd "${DATA_DIR}/builder/" 6 | 7 | [[ -d "libtorrent" ]] || git clone git@github.com:rakshasa/libtorrent 8 | [[ -d "rtorrent" ]] || git clone git@github.com:rakshasa/rtorrent 9 | [[ -d "opentracker" ]] || git clone git@github.com:rakshasa/opentracker 10 | -------------------------------------------------------------------------------- /scripts/build-has-feature: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | has_feature() { 6 | local feature="${1:?Missing feature name.}" 7 | local repo= 8 | local match= 9 | 10 | case "${feature}" in 11 | with-udns) 12 | repo=libtorrent 13 | match='#define USE_UDNS' 14 | ;; 15 | without-udns) 16 | repo=libtorrent 17 | match='#undef USE_UDNS' 18 | ;; 19 | *) 20 | echo "invalid feature name: ${feature}" 21 | exit 1 22 | ;; 23 | esac 24 | 25 | grep -e "${match}" "${DATA_DIR}/builder/${repo}/config.h" &> /dev/null 26 | } 27 | 28 | declare -a MISSING 29 | 30 | for feature in ${@}; do 31 | if ! has_feature ${feature}; then 32 | MISSING+=(${feature}) 33 | fi 34 | done 35 | 36 | if (( ${#MISSING[@]} )); then 37 | echo "missing features: ${MISSING[@]}" 38 | exit 1 39 | fi 40 | -------------------------------------------------------------------------------- /scripts/build-set-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | USE_CONFIG="${1:?Missing build config argument.}" 6 | 7 | mkdir "${DATA_DIR}" &> /dev/null || : 8 | echo "${USE_CONFIG}" > "${DATA_DIR}/current-config" 9 | -------------------------------------------------------------------------------- /scripts/build-state-headers: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Hash of all headers installed and used by nodes. 4 | 5 | source "${BASH_SOURCE[0]%/*}/include/init" 6 | 7 | find "${DATA_DIR}/usr_local/include/torrent/" -name \*.h -exec cat {} \; | md5sum 8 | -------------------------------------------------------------------------------- /scripts/build-state-libtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Returns an empty string any state source is missing. 4 | 5 | source "${BASH_SOURCE[0]%/*}/include/init" 6 | source "${BASH_SOURCE[0]%/*}/include/repo" 7 | 8 | cat "${DATA_DIR}/current-libtorrent-conf" && repo_state_blob "${GIT_LIBTORRENT}" | md5sum 9 | -------------------------------------------------------------------------------- /scripts/build-state-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Returns an empty string any state source is missing. 4 | 5 | source "${BASH_SOURCE[0]%/*}/include/init" 6 | source "${BASH_SOURCE[0]%/*}/include/repo" 7 | 8 | cat "${DATA_DIR}/current-rtorrent-conf" && repo_state_blob "${GIT_RTORRENT}" | md5sum 9 | -------------------------------------------------------------------------------- /scripts/build-tags: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_node builder 'cd /data/local/libtorrent && make tags' 7 | call_ssh_node builder 'cd /data/local/rtorrent && make tags' 8 | 9 | IFS=$'\n' 10 | 11 | for repo in 'libtorrent' 'rtorrent'; do 12 | ( 13 | cd "${DATA_DIR}/builder/${repo}" 14 | 15 | for i in `find . -name TAGS`; do 16 | echo "Changing base path of directory tags in '${i}'" 17 | 18 | path="${i/%TAGS/}" 19 | sed -e "s:^/data/local/${repo}/${path/.\//}:./:" "$i" > "$i.new" 20 | 21 | mv "$i.new" "$i" 22 | done 23 | ) 24 | done 25 | -------------------------------------------------------------------------------- /scripts/build-tracker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | echo "tracker stopping" 7 | call_ssh_node builder sudo service opentracker stop &> /dev/null || : 8 | echo "tracker building" 9 | call_ssh_node builder IPV4_ONLY=${IPV4_ONLY} build-tracker 10 | echo "tracker starting" 11 | call_ssh_node builder sudo service opentracker start 12 | echo "tracker started" 13 | -------------------------------------------------------------------------------- /scripts/call-d-multicall: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | VIEW="main" 6 | TARGET="s/" 7 | 8 | call_rpc_nodes d.multicall2 "${TARGET}" "${VIEW}" $@ 9 | -------------------------------------------------------------------------------- /scripts/call-local-id: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | AWK_FILE='local-id' 6 | 7 | call_rpc_awk_nodes d.multicall2 s/ main d.local_id= d.name= 8 | -------------------------------------------------------------------------------- /scripts/call-main: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | COMMAND="${1:?Missing command argument.}" 6 | TARGET="s/" 7 | ARGS=($@) 8 | 9 | call_rpc_nodes "$1" "${TARGET}" ${ARGS[@]:1} 10 | -------------------------------------------------------------------------------- /scripts/call-node: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | CALL_NODE="${1:?Missing node argument.}" 6 | COMMAND="${2:?Missing command argument.}" 7 | TARGET="${TARGET:-s/}" 8 | 9 | CALL_NODE="${CALL_NODE}" call_rpc "${COMMAND}" "${TARGET}" ${@:3} 10 | -------------------------------------------------------------------------------- /scripts/clean-builder: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ! -d './data/builder/' ]]; then 4 | echo "Could not find './data/builder/', success" 5 | exit 0 6 | fi 7 | 8 | DELETE_FILES=($(ls ./data/builder/)) 9 | 10 | for i in ${!DELETE_FILES[@]}; do 11 | if [[ "${DELETE_FILES[$i]}" == "libtorrent" ]] || [[ "${DELETE_FILES[$i]}" == "rtorrent" ]] || [[ "${DELETE_FILES[$i]}" == "opentracker" ]]; then 12 | unset DELETE_FILES[$i] 13 | fi 14 | done 15 | 16 | for i in ${DELETE_FILES[@]}; do 17 | echo rm -rf "./data/builder/$i" 18 | rm -rf "./data/builder/$i" 19 | done 20 | -------------------------------------------------------------------------------- /scripts/client-start: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_parallel "/data/scripts/scripts/client-start" 7 | -------------------------------------------------------------------------------- /scripts/config-bind-add: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | NODE=${1:?Target node not given.} 6 | BIND_NAME=${2:?Bind name not given.} 7 | PRIORITY=${3:?Priority not given.} 8 | NODE_IP=${4:?Node ip address not given.} 9 | OPTIONS="" 10 | 11 | case "${NODE_IP}" in 12 | ipv[46].[12]) 13 | NODE_IP="$(<"${DATA_DIR}/${NODE}/metadata/${NODE_IP}.address")" 14 | ;; 15 | esac 16 | 17 | for o in ${@:5}; do 18 | OPTIONS+=", ${o}" 19 | done 20 | 21 | echo "${NODE}: ${NODE_IP}${OPTIONS}" 22 | 23 | extra_rc_command_padding "network.bind" 24 | echo -e "network.bind.add = ${BIND_NAME}, ${PRIORITY}, ${NODE_IP}${OPTIONS}" >> "${DATA_DIR}/${NODE}/config/extra.rc" 25 | -------------------------------------------------------------------------------- /scripts/config-bind-clear: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | NODE=${1:?Target node not given.} 6 | 7 | extra_rc_command_padding "network.bind" 8 | echo -e "network.bind.clear =" >> "${DATA_DIR}/${NODE}/config/extra.rc" 9 | -------------------------------------------------------------------------------- /scripts/config-bind-set: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | NODE=${1:?Target node not given.} 6 | NODE_IP=${2:?Node ip address not given.} 7 | 8 | case "${NODE_IP}" in 9 | ipv[46].[12]) 10 | NODE_IP="$(<"${DATA_DIR}/${NODE}/metadata/${NODE_IP}.address")" 11 | ;; 12 | esac 13 | 14 | echo "${NODE}: ${NODE_IP}" 15 | 16 | extra_rc_command_padding "network.bind" 17 | echo -e "network.bind_address.set = ${NODE_IP}" >> "${DATA_DIR}/${NODE}/config/extra.rc" 18 | -------------------------------------------------------------------------------- /scripts/config-clear: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | for NODE in 'shared' ${NODES[@]}; do 6 | echo "$NODE: initializing extra.rc" 7 | rm "${DATA_DIR}/${NODE}/config/extra.rc" || true 8 | cat > "${DATA_DIR}/${NODE}/config/extra.rc" <> "${DATA_DIR}/${NODE}/config/extra.rc" 10 | -------------------------------------------------------------------------------- /scripts/config-enable-dht-global: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/config" 5 | 6 | config_add "${1}" 'dht.mode.set = on' 7 | export CONFIG_NO_SKIP="yes" 8 | 9 | config_add "${1}" 'schedule2 = dht_node_1, 1, 0, ((dht.add_node, "dht.transmissionbt.com"))' 10 | config_add "${1}" 'schedule2 = dht_node_2, 1, 0, ((dht.add_node, "router.utorrent.com:6881"))' 11 | -------------------------------------------------------------------------------- /scripts/config-enable-port-randomize: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | NODE=${1:?Target node not given.} 6 | 7 | echo "${NODE}: enable port randomize" 8 | 9 | echo -e "\nnetwork.port.randomize.set = true" >> "${DATA_DIR}/${NODE}/config/extra.rc" 10 | -------------------------------------------------------------------------------- /scripts/config-enable-rpc-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/config" 5 | 6 | config_add "${1}" 'log.add_output = "rpc_dump", "rpc"' 7 | -------------------------------------------------------------------------------- /scripts/config-set-block-accept: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | NODE=${1:?Target node not given.} 6 | 7 | echo "${NODE}: block accept" 8 | 9 | echo -e "\nnetwork.block.accept.set = true" >> "${DATA_DIR}/${NODE}/config/extra.rc" 10 | -------------------------------------------------------------------------------- /scripts/config-set-block-connect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | NODE=${1:?Target node not given.} 6 | 7 | echo "${NODE}: block connect" 8 | 9 | echo -e "\nnetwork.block.connect.set = true" >> "${DATA_DIR}/${NODE}/config/extra.rc" 10 | -------------------------------------------------------------------------------- /scripts/config-set-port-range: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | NODE=${1:?Target node not given.} 6 | PORT_BEGIN=${2:?Beginning port number not given.} 7 | PORT_END=${3:?Ending port number not given.} 8 | 9 | echo "${NODE}: port range ${PORT_BEGIN}-${PORT_END}" 10 | 11 | echo -e "\nnetwork.port_range.set = ${PORT_BEGIN}-${PORT_END}" >> "${DATA_DIR}/${NODE}/config/extra.rc" 12 | -------------------------------------------------------------------------------- /scripts/config-set-protocol-encryption: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | NODE="${1:?Target node not given.}" 6 | OPTIONS="${2:?Options not given.}" 7 | 8 | echo "${NODE}: protocol encryption set to '${OPTIONS}'" 9 | 10 | echo -e "\nprotocol.encryption.set = ${OPTIONS}" >> "${DATA_DIR}/${NODE}/config/extra.rc" 11 | -------------------------------------------------------------------------------- /scripts/cp-torrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | # TODO: Auto-detect node with torrent, and verify that it is finished. 6 | 7 | CALL_NODE="${1:?Target node not given.}" 8 | TORRENT_NAME="${2:?Torrent name not given.}" 9 | 10 | TORRENT_STATUS=$("${SCRIPT_DIR}/is-completed" "${CALL_NODE}" "${TORRENT_NAME}") 11 | 12 | if [[ "${TORRENT_STATUS}" != "1" ]]; then 13 | echo foo 14 | fi 15 | -------------------------------------------------------------------------------- /scripts/dl-export: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | dest_dir="${1:?Destination directory not specified.}" 6 | wildcard="${2:?Torrent wildcard name not specified.}" 7 | 8 | node="node-dl" 9 | 10 | if [[ -n "${3}" ]]; then 11 | echo "Excessive number of arguments." 12 | exit 1 13 | fi 14 | 15 | IFS=$'\n' 16 | 17 | for torrent_name in `${SCRIPT_DIR}/torrent-data-root ${node} /data/torrents "${wildcard}"`; do 18 | [[ -z "${torrent_name}" ]] && continue 19 | 20 | if "${SCRIPT_DIR}/torrent-data-compare" ${node} "${dest_dir}" "${torrent_name}" > /dev/null; then 21 | echo "skipping - ${torrent_name}" 22 | else 23 | echo "copying - ${torrent_name}" 24 | 25 | rm -rf "${dest_dir}/${torrent_name}" 26 | scp -F "${DATA_DIR}/ssh-config" -r "${node}:'/data/torrents/${torrent_name}'" "${dest_dir}/" 27 | fi 28 | done 29 | -------------------------------------------------------------------------------- /scripts/dl-load: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | URI="${1:?URI not given.}" 6 | CALL_NODE="${NODE:-node-dl}" 7 | 8 | call_rpc load.start "s/" "${URI}" 9 | -------------------------------------------------------------------------------- /scripts/include/call: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/init" 4 | 5 | call_ssh_nodes() { 6 | for node in ${NODES[@]}; do 7 | echo "${node}: $@" 8 | ${SCRIPT_DIR}/ssh "${node}" $@ 9 | done 10 | } 11 | 12 | call_ssh_nodes_p() { 13 | printf '%s\n' ${NODES[@]} | xargs -n 1 -P 8 -I{} "${SCRIPT_DIR}/ssh" {} $@ 14 | } 15 | 16 | call_ssh_nodes_s() { 17 | SLEEP_TIMER="0" 18 | 19 | for node in ${NODES[@]}; do 20 | sleep ${SLEEP_TIMER} 21 | 22 | echo "${node}: $@" 23 | ${SCRIPT_DIR}/ssh "${node}" $@ 24 | 25 | SLEEP_TIMER="2" 26 | done 27 | } 28 | 29 | call_rpc() { 30 | FORWARD_PORT=`cat ${DATA_DIR}/${CALL_NODE:?Missing node argument.}/metadata/forward.5001` 31 | 32 | if [[ -z ${FORWARD_PORT} ]]; then 33 | >&2 echo "Could not find forward port for ${CALL_NODE}" 34 | exit -1 35 | fi 36 | 37 | NODE_URL="scgi://localhost:${FORWARD_PORT}" 38 | CALL_CMD="${RPC_CLIENT} -s ${NODE_URL} $@" 39 | 40 | [[ "${DEBUG}" == "1" ]] && >&2 echo "${CALL_CMD}" 41 | [[ "${RPC_DEBUG}" == "1" ]] && >&2 ${CALL_CMD} 42 | 43 | ${CALL_CMD} 44 | } 45 | 46 | call_rpc_nodes() { 47 | for CALL_NODE in ${NODES[@]}; do 48 | echo "${CALL_NODE}:" 49 | call_rpc $@ 50 | done 51 | } 52 | 53 | call_rpc_awk_nodes() { 54 | for CALL_NODE in ${NODES[@]}; do 55 | echo "${CALL_NODE}:" 56 | call_rpc $@ | awk -f "${SCRIPT_DIR}/include/${AWK_FILE}.awk" 57 | done 58 | } 59 | 60 | # 61 | # Helper functions. 62 | # 63 | 64 | extra_rc_command_padding() { 65 | local name="${1:?Missing command name.}" 66 | (tail -n 1 "${DATA_DIR}/${NODE}/config/extra.rc" | grep -e "^${name}") &> /dev/null || (echo >> "${DATA_DIR}/${NODE}/config/extra.rc") 67 | } 68 | 69 | -------------------------------------------------------------------------------- /scripts/include/call-args: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ARG_ALL=false 4 | ARG_WAIT= 5 | 6 | # Define array of options, source the include file. 7 | while [[ -n "${1}" ]]; do 8 | case "${1}" in 9 | --all) 10 | shift 11 | ARG_ALL=true 12 | ;; 13 | --verbose | -v) 14 | shift 15 | set -x 16 | ;; 17 | --wait) 18 | shift 19 | [[ -z "${1##*[!0-9]*}" ]] && (echo "Not an integer."; exit 1) 20 | ARG_WAIT="${1}" 21 | shift 22 | ;; 23 | *) 24 | if [[ -z "${1##-*}" ]]; then 25 | echo "unknown parameter: ${1}" 2> /dev/null 26 | exit 1 27 | fi 28 | 29 | break 30 | ;; 31 | esac 32 | done 33 | -------------------------------------------------------------------------------- /scripts/include/call-rpc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | call_rpc_node() { 4 | local node="${1:?Missing node argument.}" 5 | local cmd="${2:?Missing command argument.}" 6 | local args=("${@:3}") 7 | 8 | # Include this in current-nodes. 9 | local forward_port=`cat ${DATA_DIR}/${node:?Missing node argument.}/metadata/forward.5001` 10 | 11 | if [[ -z "${forward_port}" ]]; then 12 | >&2 echo "Could not find forward port for ${CALL_NODE}" 13 | exit -1 14 | fi 15 | 16 | "${RPC_CLIENT}" -s "scgi://localhost:${forward_port}" "${cmd}" "${args[@]}" 2> /dev/null 17 | } 18 | 19 | call_rpc_sequential() { 20 | exit 111 21 | } 22 | 23 | call_rpc_parallel() { 24 | exit 111 25 | } 26 | -------------------------------------------------------------------------------- /scripts/include/call-ssh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Doesn't handle multiple spaces, etc. 4 | 5 | # echo "ssh failed to connect to '$1'" >&2 6 | 7 | call_ssh_init_socker() { 8 | local node="${1:?Missing node argument.}" 9 | local socket_path="${SOCKET_DIR:?Missing socket directory setting.}/ssh.${node}" 10 | 11 | [[ -s "${socket_path}" ]] && return 12 | [[ -d "${SOCKET_DIR}" ]] || mkdir -p "${SOCKET_DIR}" 13 | 14 | ssh -F "${DATA_DIR}/ssh-config" -M -S "${socket_path}" -o ControlPersist=1h "${node}" exit 15 | } 16 | 17 | call_ssh_node() { 18 | local node="${1:?Missing node argument.}" 19 | local cmd="${2:?Missing command argument.}" 20 | local socket_path="${SOCKET_DIR:?Missing socket directory setting.}/ssh.${node}" 21 | local args=("${@:3}") 22 | 23 | if [[ "${ENABLE_SOCKETS}" == "yes" ]]; then 24 | call_ssh_init_socker "${node}" 25 | ssh -F "${DATA_DIR}/ssh-config" -S "${socket_path}" "${node}" "${cmd}" "${args[@]}" 26 | else 27 | ssh -F "${DATA_DIR}/ssh-config" "${node}" "${cmd}" "${args[@]}" 28 | fi 29 | } 30 | 31 | call_ssh_interactive() { 32 | if (( ${#} >= 3 )); then 33 | call_ssh_node "${@}" 34 | return 35 | fi 36 | 37 | local node="${1:?Missing node argument.}" 38 | local socket_path="${SOCKET_DIR:?Missing socket directory setting.}/ssh.${node}" 39 | local args=("${@:2}") 40 | 41 | if [[ "${ENABLE_SOCKETS}" == "yes" ]]; then 42 | call_ssh_init_socker "${node}" 43 | ssh -F "${DATA_DIR}/ssh-config" -S "${socket_path}" "${node}" "${args[@]}" 44 | else 45 | ssh -F "${DATA_DIR}/ssh-config" "${node}" "${args[@]}" 46 | fi 47 | } 48 | 49 | call_ssh_sequential() { 50 | local cmd="${1:?Missing command argument.}" 51 | local args=("${@:2}") 52 | 53 | for node in "${NODES[@]}"; do 54 | call_ssh_node "${node}" "${cmd}" "${args[@]}" 55 | done 56 | } 57 | 58 | call_ssh_parallel() { 59 | local cmd="${1:?Missing command argument.}" 60 | local args=("${@:2}") 61 | local pids=() 62 | 63 | for node in "${NODES[@]}"; do 64 | call_ssh_node "${node}" "${cmd}" "${args[@]}" & 65 | pids+=(${!}) 66 | done 67 | 68 | local err=0 69 | 70 | while true; do 71 | set +e 72 | wait -n ${pids[@]} 73 | local result=${?} 74 | set -e 75 | 76 | # Wait return 127 if all pids are done or not sub-processes. 77 | [[ ${result} == 127 ]] && return ${err} 78 | [[ ${result} != 0 ]] && err=${result} 79 | done 80 | } 81 | -------------------------------------------------------------------------------- /scripts/include/call-test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | test_is_node() { 4 | if ${ARG_ALL}; then 5 | TEST_IS_WAIT="${ARG_WAIT}" test_is_node_all "${@}" 6 | else 7 | TEST_IS_WAIT="${ARG_WAIT}" test_is_node_single "${@}" 8 | fi 9 | } 10 | 11 | test_is_node_single() { 12 | SECONDS=0 13 | 14 | while ! test_is_node_check "${@}" ; do 15 | [[ -z "${TEST_IS_WAIT}" ]] && return 1 16 | (( SECONDS >= TEST_IS_WAIT )) && return 1 17 | sleep 0.2 18 | done 19 | } 20 | 21 | # Test doesn't wait for others sub-processes to complete once it 22 | # receives a negative result. 23 | test_is_node_all() { 24 | local pids=() 25 | 26 | for node in "${NODES[@]}"; do 27 | TEST_IS_WAIT="${TEST_IS_WAIT}" test_is_node_single "${node}" "${@}" & 28 | pids+=(${!}) 29 | done 30 | 31 | while true; do 32 | set +e 33 | wait -n ${pids[@]} 34 | local result=${?} 35 | set -e 36 | 37 | # Wait return 127 if all pids are done or not sub-processes. 38 | [[ ${result} == 127 ]] && return 39 | [[ ${result} != 0 ]] && return ${result} 40 | done 41 | } 42 | -------------------------------------------------------------------------------- /scripts/include/config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | config_add() { 4 | local node="${1:?Missing node argument.}" 5 | local entry="${2:?Missing config entry.}" 6 | 7 | local config_dir="${DATA_DIR}/${node}/config" 8 | local config_file="${config_dir}/extra.rc" 9 | 10 | if [[ ! -d "${config_dir}" ]]; then 11 | >&2 echo "Missing config file directory '${config_dir}'" 12 | exit -1 13 | fi 14 | 15 | touch "${config_file}" 16 | 17 | local new_name="$(echo ${entry} | cut -f 1 -d ' ')" 18 | local last_command="$(tail -n1 "${config_file}" | cut -f 1 -d ' ')" 19 | 20 | if [[ "${new_name}" != "${last_command}" ]] && [[ "${CONFIG_NO_SKIP}" != "yes" ]]; then 21 | echo >> "${DATA_DIR}/${node}/config/extra.rc" 22 | fi 23 | 24 | echo "${entry}" >> "${DATA_DIR}/${node}/config/extra.rc" 25 | } 26 | -------------------------------------------------------------------------------- /scripts/include/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | DEBUG=${DEBUG:-0} 6 | 7 | case "$OSTYPE" in 8 | cygwin* | msys* | win*) 9 | ENABLE_SOCKETS=no 10 | ;; 11 | bsd* | darwin* | linux* | solaris* | *) 12 | ENABLE_SOCKETS=yes 13 | ;; 14 | esac 15 | 16 | TMP_SCRIPT_DIR="${BASH_SOURCE[0]%/*}" 17 | ROOT_DIR="$(dirname "${TMP_SCRIPT_DIR[0]%/*}")" 18 | DATA_DIR="${ROOT_DIR}/data" 19 | SCRIPT_DIR="${ROOT_DIR}/scripts" 20 | SOCKET_DIR="${ROOT_DIR}/data/sockets" 21 | TEST_DIR="${ROOT_DIR}/test" 22 | 23 | RPC_CLIENT="${SCRIPT_DIR}/xmlrpc2scgi.py" 24 | 25 | DATA_VM_TORRENTS="/data/torrents" 26 | DATA_HOST_WATCH="${DATA_DIR}/shared/watch" 27 | 28 | TORRENT_VM_DIR="/data/torrents" 29 | TORRENT_VM_SHARED_DIR="/data/shared/torrents" 30 | TORRENT_SHARED_DIR="${DATA_DIR}/shared/torrents" 31 | 32 | GIT_RTORRENT="${DATA_DIR}/builder/rtorrent" 33 | GIT_LIBTORRENT="${DATA_DIR}/builder/libtorrent" 34 | 35 | NC='\033[0m' 36 | RED='\033[0;31m' 37 | GREEN='\033[0;32m' 38 | 39 | shopt -u progcomp 40 | declare -A LOG_FILENAMES 41 | 42 | [[ -f "${DATA_DIR}/current-nodes" ]] && source "${DATA_DIR}/current-nodes" 43 | 44 | SEED_NODE="${SEED_NODE:-node1}" 45 | 46 | call_quiet() { 47 | set +e 48 | local command="${1:?Missing call quiet command argument.}" 49 | local args=("${@:2}") 50 | local call_log="$("${command}" "${args}" 2>&1)" 51 | local call_result=$? 52 | set -e 53 | 54 | [[ ${call_result} -eq 0 ]] || echo "${call_log}" 55 | 56 | return ${call_result} 57 | } 58 | 59 | # DEPRECATE: Replace with parallel method. 60 | wait_for_nodes() { 61 | SECONDS=0 62 | 63 | local timeout="${WAIT_TIMEOUT:-40}" 64 | local nodes="${WAIT_NODES:-${NODES}}" 65 | local method="${1:?Missing wait node method.}" 66 | shift 67 | 68 | #echo "wait_for_node: ${remaining} calling '${method}' $i $@" 69 | 70 | while true; do 71 | local check="${nodes[@]}" 72 | local failed= 73 | 74 | for node in ${check[@]}; do 75 | if "${SCRIPT_DIR}/${method}" "${node}" $@ &> /dev/null; then 76 | [[ "${DEBUG}" == "1" ]] && >&2 echo "wait_for_nodes done: ${SCRIPT_DIR}/${method} ${node} $@" 77 | else 78 | [[ "${DEBUG}" == "1" ]] && >&2 echo "wait_for_nodes failed: ${SCRIPT_DIR}/${method} ${node} $@" 79 | failed+="${node} " 80 | fi 81 | done 82 | 83 | if [[ -z "${failed[@]}" ]]; then 84 | return 0 85 | fi 86 | 87 | if (( SECONDS > timeout )); then 88 | >&2 echo "could not verify ${method} for nodes: ${failed[@]}" 89 | >&2 echo "failed ${method} with arguments: $@" 90 | return 1 91 | fi 92 | 93 | sleep 0.5 94 | done 95 | } 96 | 97 | init_logging() { 98 | local log_type="${1:?Missing type.}" 99 | local log_category="${2:?Missing category name.}" 100 | local log_name="${3:?Missing log name.}" 101 | local log_dir="${ROOT_DIR}/logs" 102 | local log_target="${log_category}.logs/${log_name}.$(date '+%Y-%m-%d_%H:%M:%S')" 103 | local log_file="${ROOT_DIR}/logs/${log_target}" 104 | 105 | (cd "${ROOT_DIR}" && mkdir -p "logs/${log_category}.logs") 106 | echo "started logging category:${log_category} name:${log_name}" > "${log_file}" 107 | 108 | if [[ ${BASH_VERSINFO[0]} > 4 ]] || ( [[ ${BASH_VERSINFO[0]} == 4 ]] && [[ ${BASH_VERSINFO[1]} > 0 ]] ); then 109 | # exec 50>> "${log_file}" 110 | # export BASH_XTRACEFD=50 111 | # set -x 112 | : 113 | else 114 | echo "not logging 'set -x' output, bash version >= 4.1 required" 115 | echo "not logging named redirects, bash version >= 4.1 required" 116 | exit 1 117 | fi 118 | 119 | case "${log_type}" in 120 | standard) 121 | exec 1> >(tee -ia "${log_file}") 122 | exec 2> >(tee -ia "${log_file}") 123 | exec {log}>> "${log_file}" 124 | LOG_FILENAMES["log"]="${log_file}" 125 | ;; 126 | compile) 127 | exec {compile}>> "${log_file}" 128 | LOG_FILENAMES["compile"]="${log_file}" 129 | ;; 130 | *) 131 | echo "Unknown logging type." 132 | exit 1 133 | ;; 134 | esac 135 | 136 | ln -fs "./${log_target}" "${log_dir}/${log_category}.${log_name}" 137 | } 138 | -------------------------------------------------------------------------------- /scripts/include/local-id.awk: -------------------------------------------------------------------------------- 1 | { 2 | local_id = $1 3 | name = $2 4 | 5 | print local_id, name 6 | } 7 | -------------------------------------------------------------------------------- /scripts/include/ls-torrents.awk: -------------------------------------------------------------------------------- 1 | { 2 | info_hash = $1 3 | is_open = $2 4 | is_active = $3 5 | is_complete = $4 6 | completed_chunks = $5 7 | size_chunks = $6 8 | 9 | up_rate = $7 10 | down_rate = $8 11 | 12 | peers_connected = $9 13 | peers_not_connected = $10 14 | 15 | name = $11 16 | 17 | # !!!!!!!!!!!!!!!!!!!!!! 18 | # Remember to update 'i' 19 | # !!!!!!!!!!!!!!!!!!!!!! 20 | for (i = 12; i <= NF; i++) 21 | name = name " " $(i) 22 | 23 | if (is_active == 1) 24 | state = "active"; 25 | else if (is_open == 1) 26 | state = "open"; 27 | else 28 | state = "closed"; 29 | 30 | if (is_complete == 1) 31 | progress = "complete"; 32 | else 33 | progress = " partial"; 34 | 35 | print info_hash, state, progress, "chunks:" completed_chunks "/" size_chunks, "rate:" up_rate "/" down_rate, "peers:" peers_connected "/" peers_not_connected, name 36 | } 37 | -------------------------------------------------------------------------------- /scripts/include/repo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo_state_blob() { 4 | local repo_dir="${1:?Missing repo dir argument.}" 5 | echo "repo state block for '${repo_dir}'" 6 | 7 | cd "${repo_dir}" 8 | git log -n1 9 | git status 10 | 11 | cat "./config.h" 12 | 13 | IFS=$'\n' 14 | for status in $(git status -s); do 15 | local state=$(echo "${status}" | cut -b 1-2) 16 | local filename=$(echo "${status}" | cut -b 4-) 17 | cat "${filename}" 18 | done 19 | } 20 | -------------------------------------------------------------------------------- /scripts/include/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | FAILED=0 4 | LAST_VERIFY= 5 | 6 | start_nodes() { 7 | echo "clients: starting" 8 | "${SCRIPT_DIR}/start-rtorrent" 9 | 10 | echo "clients: waiting" 11 | if [[ -n "${ACTIVE_NODES}" ]]; then 12 | WAIT_NODES="${ACTIVE_NODES}" wait_for_nodes "is-client-active" 13 | else 14 | wait_for_nodes "is-client-active" 15 | fi 16 | 17 | echo "clients: active" 18 | } 19 | 20 | create_torrents() { 21 | echo "torrents: creating all" 22 | CREATE_PRESET="${CREATE_PRESET}" \ 23 | CREATE_IPV4="${CREATE_IPV4}" CREATE_IPV6="${CREATE_IPV6}" \ 24 | CREATE_IF1="${CREATE_IF1}" CREATE_IF2="${CREATE_IF2}" \ 25 | "${SCRIPT_DIR}/test-create-all" 26 | 27 | echo "torrents: waiting for loaded" 28 | local torrent= 29 | for torrent in $(${SCRIPT_DIR}/torrent-list); do 30 | WAIT_NODES="${ACTIVE_NODES}" WAIT_TIMEOUT=60 wait_for_nodes is-loaded ${torrent} 31 | echo "${torrent}: loaded" 32 | done 33 | 34 | echo "torrents: loaded all" 35 | } 36 | 37 | clean_all() { 38 | echo "clean all" 39 | 40 | "${SCRIPT_DIR}/stop-rtorrent"; sleep 5 41 | "${SCRIPT_DIR}/config-clear" 42 | 43 | echo "delete all torrents" 44 | "${SCRIPT_DIR}/test-delete-all" 45 | "${SCRIPT_DIR}/is-client-empty" --all --wait 20 46 | 47 | echo "ip down" 48 | "${SCRIPT_DIR}/ip-down-4-1" node1 node2 node3 node4 node5 &> /dev/null 49 | "${SCRIPT_DIR}/ip-down-6-1" node1 node2 node3 node4 node5 &> /dev/null 50 | "${SCRIPT_DIR}/ip-down-4-2" node1 node2 node3 node4 node5 &> /dev/null 51 | "${SCRIPT_DIR}/ip-down-6-2" node1 node2 node3 node4 node5 &> /dev/null 52 | } 53 | 54 | setup_if1v4v6() { 55 | "${SCRIPT_DIR}/ip-up-4-1" node1 node2 node3 node4 node5 56 | "${SCRIPT_DIR}/ip-up-6-1" node1 node2 node3 node4 node5 57 | } 58 | 59 | setup_if2v4v6() { 60 | "${SCRIPT_DIR}/ip-up-4-2" node1 node2 node3 node4 node5 61 | "${SCRIPT_DIR}/ip-up-6-2" node1 node2 node3 node4 node5 62 | } 63 | 64 | setup_if1p1() { 65 | "${SCRIPT_DIR}/ip-up-4-1" node1 node2 node4 66 | "${SCRIPT_DIR}/ip-up-6-1" node1 node3 node5 67 | "${SCRIPT_DIR}/ip-down-4-1" node3 node5 68 | "${SCRIPT_DIR}/ip-down-6-1" node2 node4 69 | } 70 | 71 | setup_if2p1() { 72 | "${SCRIPT_DIR}/ip-up-4-2" node1 node2 node4 73 | "${SCRIPT_DIR}/ip-up-6-2" node1 node3 node5 74 | "${SCRIPT_DIR}/ip-down-4-2" node3 node5 75 | "${SCRIPT_DIR}/ip-down-6-2" node2 node4 76 | } 77 | 78 | setup() { 79 | local config="${1:?Missing config setup argument.}" 80 | 81 | echo "setting up config '${config}'" 82 | 83 | case "${config}" in 84 | "if1p1") 85 | setup_if1p1 &> /dev/null 86 | CREATE_PRESET=if_single 87 | ;; 88 | "if1p1_if2p1") 89 | setup_if1p1 &> /dev/null 90 | setup_if2p1 &> /dev/null 91 | CREATE_PRESET=if_pair 92 | ;; 93 | "if1p1_if2v4v6") 94 | setup_if1p1 &> /dev/null 95 | setup_if2v4v6 &> /dev/null 96 | CREATE_PRESET=if_pair 97 | ;; 98 | "if1p1_if2v4v6_dns") 99 | setup_if1p1 &> /dev/null 100 | setup_if2v4v6 &> /dev/null 101 | CREATE_PRESET=if_dns_pair 102 | ;; 103 | "if1v4v6") 104 | setup_if1v4v6 &> /dev/null 105 | CREATE_PRESET=if_single 106 | ;; 107 | "if1v4v6_if2v4v6") 108 | setup_if1v4v6 &> /dev/null 109 | setup_if2v4v6 &> /dev/null 110 | CREATE_PRESET=if_pair 111 | ;; 112 | "if1v4v6_if2p1_dns") 113 | setup_if1v4v6 &> /dev/null 114 | setup_if2p1 &> /dev/null 115 | CREATE_PRESET=if_dns_pair 116 | ;; 117 | *) 118 | echo "missing config '${config}'" 119 | exit -1 120 | ;; 121 | esac 122 | 123 | if [[ "${SEED_IF1_V4ONLY}" == "yes" ]]; then 124 | echo "seed if1 v4only" 125 | "${SCRIPT_DIR}/ip-down-6-1" node1 126 | fi 127 | 128 | if [[ "${SEED_IF2_V4ONLY}" == "yes" ]]; then 129 | echo "seed if2 v4only" 130 | "${SCRIPT_DIR}/ip-down-6-2" node1 131 | fi 132 | 133 | if [[ "${SEED_IF1_V6ONLY}" == "yes" ]]; then 134 | echo "seed if1 v6only" 135 | "${SCRIPT_DIR}/ip-down-4-1" node1 136 | fi 137 | 138 | if [[ "${SEED_IF2_V6ONLY}" == "yes" ]]; then 139 | echo "seed if2 v6only" 140 | "${SCRIPT_DIR}/ip-down-4-2" node1 141 | fi 142 | 143 | "${SCRIPT_DIR}/build-tracker" 144 | 145 | echo "starting nodes" 146 | start_nodes 147 | 148 | echo "creating torrents" 149 | CREATE_PRESET="${CREATE_PRESET}" \ 150 | CREATE_IPV4="${CREATE_IPV4}" CREATE_IPV6="${CREATE_IPV6}" \ 151 | CREATE_IF1="${CREATE_IF1}" CREATE_IF2="${CREATE_IF2}" \ 152 | create_torrents 153 | echo "verifying seeds" 154 | verify_seeds 155 | 156 | # TODO: Replace with check to see if we have in-progess. 157 | echo "sleeping..." 158 | sleep 20 159 | } 160 | 161 | exit_test() { 162 | echo 163 | 164 | if [[ ${FAILED} -eq 0 ]]; then 165 | echo "done: success" 166 | else 167 | echo "done: failed:${FAILED}" 168 | fi 169 | 170 | exit ${FAILED} 171 | } 172 | 173 | verify_seeds() { 174 | local torrent= 175 | for torrent in `${SCRIPT_DIR}/torrent-list`; do 176 | WAIT_NODES=node1 WAIT_TIMEOUT=60 wait_for_nodes is-completed ${torrent} 177 | echo "${torrent}: seed ready" 178 | done 179 | 180 | echo "poking all nodes" 181 | sleep 5 182 | NODES="${ACTIVE_NODES}" "${SCRIPT_DIR}/call-d-multicall" d.tracker_announce.force= > /dev/null 183 | } 184 | 185 | verify_completed() { 186 | local node="${1:?Missing node argument.}" 187 | local torrent="${2:?Missing torrent argument.}" 188 | local message="${node} ${torrent} verify completed: ${3:?Missing message argument.}" 189 | 190 | [[ -z "${LAST_VERIFY}" ]] && echo 191 | LAST_VERIFY="${message}" 192 | 193 | if "${SCRIPT_DIR}/is-completed" "${node}" "${torrent}"; then 194 | echo -e "${GREEN}${message}... succeeded${NC}" 195 | else 196 | echo -e "${RED}${message}... failed${NC}" 197 | FAILED=$((FAILED+1)) 198 | fi 199 | 200 | return 0 201 | } 202 | 203 | verify_incompleted() { 204 | local node="${1:?Missing node argument.}" 205 | local torrent="${2:?Missing torrent argument.}" 206 | local message="${node} ${torrent} verify incomplete: ${3:?Missing message argument.}" 207 | 208 | [[ -z "${LAST_VERIFY}" ]] && echo 209 | LAST_VERIFY="${message}" 210 | 211 | if "${SCRIPT_DIR}/is-completed" "${node}" "${torrent}"; then 212 | echo -e "${RED}${message}... failed${NC}" 213 | FAILED=$((FAILED+1)) 214 | else 215 | echo -e "${GREEN}${message}... succeeded${NC}" 216 | fi 217 | 218 | return 0 219 | } 220 | 221 | verify_has_log_message() { 222 | local node="${1:?Missing node argument.}" 223 | local log_name="${2:?Missing log name argument.}" 224 | local message="${3:?Missing message argument.}" 225 | local log_message="${4:?Missing message argument.}" 226 | 227 | [[ -z "${LAST_VERIFY}" ]] && echo 228 | LAST_VERIFY="${message}" 229 | 230 | if grep "${log_message}" "${DATA_DIR}/${node}/log/${log_name}.log" &> /dev/null; then 231 | echo -e "${GREEN}${message}... succeeded${NC}" 232 | else 233 | echo -e "${RED}${message}... failed${NC}" 234 | FAILED=$((FAILED+1)) 235 | fi 236 | 237 | return 0 238 | } 239 | 240 | verify_bind_failed() { 241 | local node="${1:?Missing node argument.}" 242 | local message="${2:?Missing message argument.}" 243 | 244 | verify_has_log_message ${node} crash "${message}" "C Caught exception: 'Could not open/bind port for listening: Cannot assign requested address'." 245 | } 246 | -------------------------------------------------------------------------------- /scripts/include/test-unit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | declare -a TEST_NAMES 4 | declare -a TEST_RESULTS 5 | 6 | test_init() { 7 | init_logging "standard" "test-feature-dns" "output" 8 | init_logging "compile" "test-feature-dns" "compile" 9 | } 10 | 11 | test_cleanup() { 12 | test_print_header "Results" 13 | test_print_results 14 | } 15 | 16 | test_unit() { 17 | local unit="${1:?Missing unit name.}" 18 | 19 | TEST_NAMES+=("${unit}") 20 | ("${TEST_DIR}/${unit}" && TEST_RESULTS+=(0)) || TEST_RESULTS+=(1) 21 | } 22 | 23 | test_begin() { 24 | test_print_header "${1:?Missing message.}" 25 | "${SCRIPT_DIR}/stop-rtorrent" || : 26 | } 27 | 28 | test_has_features() { 29 | local features="${@}" 30 | echo "checking if build has features: ${features}" 31 | "${SCRIPT_DIR}/build-has-feature" ${features} 32 | } 33 | 34 | test_print_header() { 35 | local message="${1:?Missing message.}" 36 | 37 | echo 38 | echo "======================================================================" 39 | echo "${message}" 40 | echo "======================================================================" 41 | echo 42 | } 43 | 44 | test_print_results() { 45 | echo 46 | for (( i = 0; i < ${#TEST_RESULTS[@]}; i++ )); do 47 | if [[ "${TEST_RESULTS[i]}" == 0 ]]; then 48 | color="${GREEN}" 49 | else 50 | color="${RED}" 51 | fi 52 | 53 | echo -e "${color}${TEST_NAMES[i]}:\t ${TEST_RESULTS[i]}${NC}" 54 | done 55 | echo 56 | } 57 | 58 | test_compile() { 59 | local options="${1}" 60 | 61 | echo "compiling with options '${options}'" 62 | 63 | if ! eval "BUILD_CONFIGURE=yes ${options} '${SCRIPT_DIR}/build-current'" >&${compile} 2>&1; then 64 | test_print_header "compilation logs" 65 | #exec ${compile}>&- 66 | tail -n100 "${LOG_FILENAMES[compile]}" 67 | test_print_header "compilation failed" 68 | return 1 69 | fi 70 | 71 | echo "finished compiling" 72 | } 73 | 74 | test_dns_resolver() { 75 | local resolver="${1:?Missing resolver argument.}" 76 | 77 | echo "using resolver '${resolver}'" 78 | "${SCRIPT_DIR}/ip-dns-resolver" "${resolver}" 79 | } 80 | -------------------------------------------------------------------------------- /scripts/include/torrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SEED_NODE="${SEED_NODE:-node1}" 4 | 5 | DATA_FILENAME="${DATA_FILENAME:?no filename provided}" 6 | 7 | DATA_VM_PATH="/data/shared/torrents/${DATA_FILENAME}" 8 | DATA_HOST_PATH="${DATA_DIR}/shared/torrents/${DATA_FILENAME}" 9 | -------------------------------------------------------------------------------- /scripts/ip-dns-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | CONFIG_NAME="${1:?Missing config name argument.}" 7 | 8 | call_ssh_node builder sudo rm /etc/maradns/mararc 9 | call_ssh_node builder sudo ln -s "/etc/maradns/mararc.${CONFIG_NAME}" /etc/maradns/mararc 10 | call_ssh_node builder sudo service maradns restart 11 | 12 | call_ssh_parallel sudo service dns-clean restart 13 | -------------------------------------------------------------------------------- /scripts/ip-dns-down: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_node builder sudo service maradns stop 7 | -------------------------------------------------------------------------------- /scripts/ip-dns-resolver: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | # Glibc crashes if you have multiple nameservers and either ipv4 or 7 | # ipv6 nameservers are not routeable. 8 | # 9 | # Some resolvers don't handle multiple nameservers properly, pass 10 | # argument to reorder the nameservers. 11 | 12 | case "${1}" in 13 | builder) 14 | CLEAR_TARGET="base" 15 | RESOLV_TARGET="head" 16 | ;; 17 | internet | default) 18 | CLEAR_TARGET="head" 19 | RESOLV_TARGET="base" 20 | ;; 21 | *) 22 | echo "invalid argument: '${1}'" 23 | exit 1 24 | ;; 25 | esac 26 | 27 | NAMESERVER_IF1V4=$(<"${DATA_DIR}/builder/metadata/ipv4.1.address") 28 | NAMESERVER_IF1V6=$(<"${DATA_DIR}/builder/metadata/ipv6.1.address") 29 | 30 | call_ssh_parallel "/data/scripts/scripts/ip-dns-resolver" "${CLEAR_TARGET}" "${RESOLV_TARGET}" "${NAMESERVER_IF1V4}" "${NAMESERVER_IF1V6}" 31 | -------------------------------------------------------------------------------- /scripts/ip-dns-up: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_node builder sudo service maradns restart 7 | -------------------------------------------------------------------------------- /scripts/ip-down-4-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@}") 7 | 8 | call_ssh_parallel disable-ipv4-1 9 | -------------------------------------------------------------------------------- /scripts/ip-down-4-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@}") 7 | 8 | call_ssh_parallel disable-ipv4-2 9 | -------------------------------------------------------------------------------- /scripts/ip-down-6-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@}") 7 | 8 | call_ssh_parallel echo disable-ipv6-1 9 | -------------------------------------------------------------------------------- /scripts/ip-down-6-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@}") 7 | 8 | call_ssh_parallel disable-ipv6-2 9 | -------------------------------------------------------------------------------- /scripts/ip-up-4-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@}") 7 | 8 | call_ssh_parallel enable-ipv4-1 9 | -------------------------------------------------------------------------------- /scripts/ip-up-4-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@}") 7 | 8 | call_ssh_parallel enable-ipv4-2 9 | -------------------------------------------------------------------------------- /scripts/ip-up-6-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@}") 7 | 8 | call_ssh_parallel enable-ipv6-1 9 | -------------------------------------------------------------------------------- /scripts/ip-up-6-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@}") 7 | 8 | call_ssh_parallel enable-ipv6-2 9 | -------------------------------------------------------------------------------- /scripts/is-client-active: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-args" 5 | source "${BASH_SOURCE[0]%/*}/include/call-rpc" 6 | source "${BASH_SOURCE[0]%/*}/include/call-test" 7 | 8 | test_is_node_check() { 9 | local node="${1:?Target node not given.}" 10 | 11 | [[ -n "$(call_rpc_node "${node}" system.client_version)" ]] 12 | } 13 | 14 | test_is_node "${@}" 15 | -------------------------------------------------------------------------------- /scripts/is-client-empty: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-args" 5 | source "${BASH_SOURCE[0]%/*}/include/call-rpc" 6 | source "${BASH_SOURCE[0]%/*}/include/call-test" 7 | 8 | # Fail is-empty if any session torrents are still available as we 9 | # can't guarantee that the client successfuly loads all torrents. 10 | 11 | test_is_node_check() { 12 | local node="${1:?Target node not given.}" 13 | 14 | if local output="$(call_rpc_node "${node}" d.multicall2 s/ main d.hash=)"; then 15 | [[ -n "${output}" ]] && return 1 16 | fi 17 | 18 | ! ls "${DATA_DIR}"/"${node}"/session/*.torrent &> /dev/null 19 | } 20 | 21 | test_is_node 22 | -------------------------------------------------------------------------------- /scripts/is-client-inactive: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-args" 5 | source "${BASH_SOURCE[0]%/*}/include/call-rpc" 6 | source "${BASH_SOURCE[0]%/*}/include/call-test" 7 | 8 | test_is_node_check() { 9 | local node="${1:?Target node not given.}" 10 | 11 | [[ -z "$(call_rpc_node "${node}" system.client_version)" ]] 12 | } 13 | 14 | test_is_node "${@}" 15 | -------------------------------------------------------------------------------- /scripts/is-completed: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | CALL_NODE="${1:?Target node not given.}" 6 | TORRENT_NAME="${2:?Torrent name not given.}" 7 | 8 | INFO_HASH_RET="$(${SCRIPT_DIR}/torrent-info-hash "${CALL_NODE}" "${TORRENT_NAME}")" 9 | INFO_HASH="${INFO_HASH_RET:?Info hash not found.}" 10 | 11 | [[ "$(call_rpc d.complete s/${INFO_HASH})" == "1" ]] 12 | -------------------------------------------------------------------------------- /scripts/is-loaded: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-args" 5 | source "${BASH_SOURCE[0]%/*}/include/call-rpc" 6 | source "${BASH_SOURCE[0]%/*}/include/call-test" 7 | 8 | test_is_node_check() { 9 | local node="${1:?Target node not given.}" 10 | local torrents=("${@:2}") 11 | local output=($(call_rpc_node "${node}" d.multicall2 s/ s/ d.name=)) 12 | 13 | for match_name in "${torrents[@]}"; do 14 | local match_found= 15 | for output_name in "${output[@]}"; do 16 | [[ "${output_name}" =~ ^${match_name}$ ]] && match_found="${match_name}" 17 | done 18 | [[ -n "${match_found}" ]] || return 1 19 | done 20 | } 21 | 22 | test_is_node "${@}" 23 | -------------------------------------------------------------------------------- /scripts/is-torrent-cached: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | name="${1:?Missing torrent name argument.}" 6 | 7 | [[ -f "${TORRENT_SHARED_DIR}/${name}" ]] && [[ -f "${TORRENT_SHARED_DIR}/${name}.torrent" ]] 8 | -------------------------------------------------------------------------------- /scripts/is-unloaded: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-args" 5 | source "${BASH_SOURCE[0]%/*}/include/call-rpc" 6 | source "${BASH_SOURCE[0]%/*}/include/call-test" 7 | 8 | test_is_node_check() { 9 | local node="${1:?Target node not given.}" 10 | local torrents=("${@:2}") 11 | local output=($(call_rpc_node "${node}" d.multicall2 s/ s/ d.name=)) 12 | 13 | for match_name in "${torrents[@]}"; do 14 | local match_found= 15 | for output_name in "${output[@]}"; do 16 | [[ "${output_name}" =~ ^${match_name}$ ]] && match_found="${match_name}" 17 | done 18 | [[ -z "${match_found}" ]] || return 1 19 | done 20 | } 21 | 22 | test_is_node "${@}" 23 | -------------------------------------------------------------------------------- /scripts/kill-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_parallel kill-rtorrent 7 | -------------------------------------------------------------------------------- /scripts/ls-torrents: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | AWK_FILE='ls-torrents' 6 | 7 | # Why d.complete and not d.is_complete. 8 | call_rpc_awk_nodes d.multicall2 s/ main d.hash= d.is_open= d.is_active= d.complete= d.completed_chunks= d.size_chunks= d.up.rate= d.down.rate= d.peers_connected= d.peers_not_connected= d.name= 9 | -------------------------------------------------------------------------------- /scripts/network-bind: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | call_rpc_nodes network.bind 6 | -------------------------------------------------------------------------------- /scripts/node/build-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export CXX="${USE_CXX:?No C++ compiler specified.}" 4 | export CXXFLAGS="-Wno-error=strict-aliasing" 5 | export MAKEFLAGS="-j 8" 6 | 7 | if [[ "${SKIP_LIBTORRENT}" != "yes" ]]; then 8 | cd /data/local/libtorrent 9 | if [[ ! -f "Makefile" ]] || [[ "${BUILD_CONFIGURE}" == "yes" ]]; then 10 | ./autogen.sh && ./configure ${LIBTORRENT_CONF} || exit 1 11 | fi 12 | make && sudo make install || exit 1 13 | fi 14 | 15 | if [[ "${SKIP_RTORRENT}" != "yes" ]]; then 16 | cd /data/local/rtorrent 17 | if [[ ! -f "Makefile" ]] || [[ "${BUILD_CONFIGURE}" == "yes" ]]; then 18 | ./autogen.sh && ./configure ${RTORRENT_CONF} || exit 1 19 | fi 20 | make && sudo make install || exit 1 21 | fi 22 | -------------------------------------------------------------------------------- /scripts/node/build-tracker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cleanup() { 4 | rc=$? 5 | 6 | if [[ ${rc} -eq 0 ]]; then 7 | echo "Done building OpenTracker." 8 | else 9 | echo "Failed building OpenTracker." 10 | fi 11 | 12 | exit ${rc} 13 | }; trap cleanup EXIT; set -e 14 | 15 | WANTED="default" 16 | 17 | if [[ "${IPV4_ONLY}" != yes ]]; then 18 | export FEATURES="-DWANT_V6" 19 | else 20 | WANTED="${WANTED}_v4" 21 | fi 22 | 23 | if [[ ${WANTED} = "$( /dev/null 31 | 32 | cd /data/local/opentracker 33 | 34 | make clean 35 | make 36 | sudo PREFIX=/usr/local make install 37 | 38 | echo ${WANTED} > /data/local/metadata/tracker.info 39 | -------------------------------------------------------------------------------- /scripts/node/change-ipv4-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -4 addr flush dev ${PRIVATE_DEV_1} 7 | sudo ip -4 addr add $1 dev ${PRIVATE_DEV_1} 8 | 9 | ip -4 addr show dev ${PRIVATE_DEV_1} permanent primary | sed -n 's_^.*inet \([0-9.]*\)/\([0-9]*\).*$_\1_p' > "${METADATA}/ipv4.1.address" 10 | ip -4 addr show dev ${PRIVATE_DEV_1} permanent primary | sed -n 's_^.*inet \([0-9.]*\)/\([0-9]*\).*$_\2_p' > "${METADATA}/ipv4.1.prefix" 11 | 12 | touch "${METADATA}/ipv4.1.up" 13 | rm "${METADATA}/ipv4.1.down" &> /dev/null || true 14 | -------------------------------------------------------------------------------- /scripts/node/change-ipv4-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -4 addr flush dev ${PRIVATE_DEV_2} 7 | sudo ip -4 addr add $1 dev ${PRIVATE_DEV_2} 8 | 9 | ip -4 addr show dev ${PRIVATE_DEV_2} permanent primary | sed -n 's_^.*inet \([0-9.]*\)/\([0-9]*\).*$_\1_p' > "${METADATA}/ipv4.2.address" 10 | ip -4 addr show dev ${PRIVATE_DEV_2} permanent primary | sed -n 's_^.*inet \([0-9.]*\)/\([0-9]*\).*$_\2_p' > "${METADATA}/ipv4.2.prefix" 11 | 12 | touch "${METADATA}/ipv4.2.up" 13 | rm "${METADATA}/ipv4.2.down" &> /dev/null || true 14 | -------------------------------------------------------------------------------- /scripts/node/change-ipv6-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -6 addr flush dev ${PRIVATE_DEV_1} 7 | sudo ip -6 addr add $1 dev ${PRIVATE_DEV_1} 8 | 9 | ip -6 addr show dev ${PRIVATE_DEV_1} permanent primary | sed -n 's_^.*inet6 \([0-9a-f:]*\)/\([0-9]*\).*$_\1_p' > "${METADATA}/ipv6.1.address" 10 | ip -6 addr show dev ${PRIVATE_DEV_1} permanent primary | sed -n 's_^.*inet6 \([0-9a-f:]*\)/\([0-9]*\).*$_\2_p' > "${METADATA}/ipv6.1.prefix" 11 | 12 | touch "${METADATA}/ipv6.1.up" 13 | rm "${METADATA}/ipv6.1.down" &> /dev/null || true 14 | -------------------------------------------------------------------------------- /scripts/node/change-ipv6-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -6 addr flush dev ${PRIVATE_DEV_2} 7 | sudo ip -6 addr add $1 dev ${PRIVATE_DEV_2} 8 | 9 | ip -6 addr show dev ${PRIVATE_DEV_2} permanent primary | sed -n 's_^.*inet6 \([0-9a-f:]*\)/\([0-9]*\).*$_\1_p' > "${METADATA}/ipv6.2.address" 10 | ip -6 addr show dev ${PRIVATE_DEV_2} permanent primary | sed -n 's_^.*inet6 \([0-9a-f:]*\)/\([0-9]*\).*$_\2_p' > "${METADATA}/ipv6.2.prefix" 11 | 12 | touch "${METADATA}/ipv6.2.up" 13 | rm "${METADATA}/ipv6.2.down" &> /dev/null || true 14 | -------------------------------------------------------------------------------- /scripts/node/check-libtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export MAKEFLAGS="-j 8" 4 | export TEST_NAMES="${TEST_NAMES}" 5 | 6 | cd /data/local/libtorrent 7 | make check 8 | -------------------------------------------------------------------------------- /scripts/node/check-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export MAKEFLAGS="-j 8" 4 | export TEST_NAMES="${TEST_NAMES}" 5 | 6 | cd /data/local/rtorrent 7 | make check 8 | -------------------------------------------------------------------------------- /scripts/node/disable-ipv4-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -4 addr flush dev ${PRIVATE_DEV_1} 7 | 8 | touch "${METADATA}/ipv4.1.down" 9 | rm "${METADATA}/ipv4.1.up" &> /dev/null || true 10 | -------------------------------------------------------------------------------- /scripts/node/disable-ipv4-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -4 addr flush dev ${PRIVATE_DEV_2} 7 | 8 | touch "${METADATA}/ipv4.2.down" 9 | rm "${METADATA}/ipv4.2.up" &> /dev/null || true 10 | -------------------------------------------------------------------------------- /scripts/node/disable-ipv6-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -6 addr flush dev ${PRIVATE_DEV_1} 7 | 8 | touch "${METADATA}/ipv6.1.down" 9 | rm "${METADATA}/ipv6.1.up" &> /dev/null || true 10 | -------------------------------------------------------------------------------- /scripts/node/disable-ipv6-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -6 addr flush dev ${PRIVATE_DEV_2} 7 | 8 | touch "${METADATA}/ipv6.2.down" 9 | rm "${METADATA}/ipv6.2.up" &> /dev/null || true 10 | -------------------------------------------------------------------------------- /scripts/node/enable-ipv4-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -4 addr flush dev ${PRIVATE_DEV_1} 7 | sudo ip -4 addr add ${METADATA_PRIVATE_IPV4_1} dev ${PRIVATE_DEV_1} 8 | 9 | touch "${METADATA}/ipv4.1.up" 10 | rm "${METADATA}/ipv4.1.down" &> /dev/null || true 11 | -------------------------------------------------------------------------------- /scripts/node/enable-ipv4-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -4 addr flush dev ${PRIVATE_DEV_2} 7 | sudo ip -4 addr add ${METADATA_PRIVATE_IPV4_2} dev ${PRIVATE_DEV_2} 8 | 9 | touch "${METADATA}/ipv4.2.up" 10 | rm "${METADATA}/ipv4.2.down" &> /dev/null || true 11 | -------------------------------------------------------------------------------- /scripts/node/enable-ipv6-1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -6 addr flush dev ${PRIVATE_DEV_1} 7 | sudo ip -6 addr add ${METADATA_PRIVATE_IPV6_1} dev ${PRIVATE_DEV_1} 8 | 9 | touch "${METADATA}/ipv6.1.up" 10 | rm "${METADATA}/ipv6.1.down" &> /dev/null || true 11 | -------------------------------------------------------------------------------- /scripts/node/enable-ipv6-2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | set -e 5 | 6 | sudo ip -6 addr flush dev ${PRIVATE_DEV_2} 7 | sudo ip -6 addr add ${METADATA_PRIVATE_IPV6_2} dev ${PRIVATE_DEV_2} 8 | 9 | touch "${METADATA}/ipv6.2.up" 10 | rm "${METADATA}/ipv6.2.down" &> /dev/null || true 11 | -------------------------------------------------------------------------------- /scripts/node/kill-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | RTORRENT_LOCKFILE="/data/local/session/rtorrent.lock" 4 | 5 | if [[ ! -e $RTORRENT_LOCKFILE ]]; then 6 | exit 0 7 | fi 8 | 9 | RTORRENT_PID=`sed -n 's/^[^:]*:+\([0-9].*\)$/\1/p' $RTORRENT_LOCKFILE` 10 | 11 | kill -9 "${RTORRENT_PID}" || true 12 | rm "${RTORRENT_PID}" || true 13 | -------------------------------------------------------------------------------- /scripts/node/make-torrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DATA_FILENAME=${1:?no filename provided} 4 | DATA_PATH="/data/shared/torrents/${DATA_FILENAME}" 5 | 6 | DATA_COUNT=${DATA_COUNT:=5} 7 | 8 | openssl rand $(( DATA_COUNT * 1000 )) > "${DATA_PATH}" 9 | 10 | IPV4_1_TRACKER=`cat /data/local/metadata/ipv4.1.address` 11 | IPV6_1_TRACKER=`cat /data/local/metadata/ipv6.1.address` 12 | IPV4_2_TRACKER=`cat /data/local/metadata/ipv4.2.address` 13 | IPV6_2_TRACKER=`cat /data/local/metadata/ipv6.2.address` 14 | 15 | USE_IF1=${USE_IF1:=yes} 16 | USE_IF2=${USE_IF2:=no} 17 | USE_IPV4=${USE_IPV4:=yes} 18 | USE_IPV6=${USE_IPV6:=no} 19 | 20 | USE_HTTP_TRACKER=${USE_HTTP_TRACKER:=yes} 21 | USE_UDP_TRACKER=${USE_UDP_TRACKER:=no} 22 | 23 | if [[ "${USE_HTTP_TRACKER}" == "yes" ]]; then 24 | if [[ "${USE_IPV4}" == "yes" ]]; then 25 | [[ "${USE_IF1}" == "yes" ]] && ANNOUNCE_URLS+=",http://${IPV4_1_TRACKER}:6969/announce" 26 | [[ "${USE_IF2}" == "yes" ]] && ANNOUNCE_URLS+=",http://${IPV4_2_TRACKER}:6969/announce" 27 | [[ "${USE_IF1}" == "dns" ]] && ANNOUNCE_URLS+=",http://builder.rtorrent.if1v4:6969/announce" 28 | [[ "${USE_IF2}" == "dns" ]] && ANNOUNCE_URLS+=",http://builder.rtorrent.if2v4:6969/announce" 29 | fi 30 | 31 | if [[ "$USE_IPV6" == "yes" ]]; then 32 | [[ "${USE_IF1}" == "yes" ]] && ANNOUNCE_URLS+=",http://[${IPV6_1_TRACKER}]:6969/announce" 33 | [[ "${USE_IF2}" == "yes" ]] && ANNOUNCE_URLS+=",http://[${IPV6_2_TRACKER}]:6969/announce" 34 | [[ "${USE_IF1}" == "dns" ]] && ANNOUNCE_URLS+=",http://builder.rtorrent.if1v6:6969/announce" 35 | [[ "${USE_IF2}" == "dns" ]] && ANNOUNCE_URLS+=",http://builder.rtorrent.if2v6:6969/announce" 36 | fi 37 | fi 38 | 39 | if [[ "${USE_UDP_TRACKER}" == "yes" ]]; then 40 | if [[ "${USE_IPV4}" == "yes" ]]; then 41 | [[ "${USE_IF1}" == "yes" ]] && ANNOUNCE_URLS+=",udp://${IPV4_1_TRACKER}:6969" 42 | [[ "${USE_IF2}" == "yes" ]] && ANNOUNCE_URLS+=",udp://${IPV4_2_TRACKER}:6969" 43 | [[ "${USE_IF1}" == "dns" ]] && ANNOUNCE_URLS+=",udp://builder.rtorrent.if1v4:6969" 44 | [[ "${USE_IF2}" == "dns" ]] && ANNOUNCE_URLS+=",udp://builder.rtorrent.if2v4:6969" 45 | fi 46 | 47 | if [[ "${USE_IPV6}" == "yes" ]]; then 48 | [[ "${USE_IF1}" == "yes" ]] && ANNOUNCE_URLS+=",udp://[${IPV6_1_TRACKER}]:6969" 49 | [[ "${USE_IF2}" == "yes" ]] && ANNOUNCE_URLS+=",udp://[${IPV6_2_TRACKER}]:6969" 50 | [[ "${USE_IF1}" == "dns" ]] && ANNOUNCE_URLS+=",udp://builder.rtorrent.if1v6:6969" 51 | [[ "${USE_IF2}" == "dns" ]] && ANNOUNCE_URLS+=",udp://builder.rtorrent.if2v6:6969" 52 | fi 53 | fi 54 | 55 | ANNOUNCE_URLS=`echo ${ANNOUNCE_URLS} | sed -n 's/^,//p'` 56 | 57 | if ! type mktorrent; then 58 | echo "Could not find 'mktorrent'." 59 | exit -1 60 | fi 61 | 62 | mktorrent -v -p -a ${ANNOUNCE_URLS} -o ${DATA_PATH}.torrent ${DATA_PATH} 63 | -------------------------------------------------------------------------------- /scripts/node/metadata.source: -------------------------------------------------------------------------------- 1 | METADATA="/data/local/metadata" 2 | 3 | PRIVATE_DEV_1="eth1" 4 | PRIVATE_DEV_2="eth2" 5 | 6 | if [[ -f "${METADATA}/ipv4.1.address" ]]; then 7 | METADATA_PRIVATE_IPV4_1="`cat ${METADATA}/ipv4.1.address`/`cat ${METADATA}/ipv4.1.prefix`" 8 | fi 9 | 10 | if [[ -f "${METADATA}/ipv6.1.address" ]]; then 11 | METADATA_PRIVATE_IPV6_1="`cat ${METADATA}/ipv6.1.address`/`cat ${METADATA}/ipv6.1.prefix`" 12 | fi 13 | 14 | if [[ -f "${METADATA}/ipv4.2.address" ]]; then 15 | METADATA_PRIVATE_IPV4_2="`cat ${METADATA}/ipv4.2.address`/`cat ${METADATA}/ipv4.2.prefix`" 16 | fi 17 | 18 | if [[ -f "${METADATA}/ipv6.2.address" ]]; then 19 | METADATA_PRIVATE_IPV6_2="`cat ${METADATA}/ipv6.2.address`/`cat ${METADATA}/ipv6.2.prefix`" 20 | fi 21 | -------------------------------------------------------------------------------- /scripts/node/scripts/client-start: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | RTORRENT_EXEC="rtorrent -n -o try_import=/data/shared/config/rtorrent.rc,system.daemon.set=true" 6 | RTORRENT_LOG="/data/local/log" 7 | 8 | LOG_DATE=`date -u '+%F_%H-%M-%S'` 9 | 10 | for log_file in ${RTORRENT_LOG}/*.log; do 11 | mv "${log_file}" "${log_file/\/log\//\/log\/old\/}.${LOG_DATE}" &> /dev/null || : 12 | done 13 | 14 | if ls "${RTORRENT_LOG}/*.log" &> /dev/null; then 15 | echo "Log files not moved." 1>&2 16 | exit 1 17 | fi 18 | 19 | if [[ "$DEBUG" == "yes" ]]; then 20 | gdb --args ${RTORRENT_EXEC} 21 | else 22 | nohup ${RTORRENT_EXEC} > "${RTORRENT_LOG}/daemon.log" & 23 | fi 24 | -------------------------------------------------------------------------------- /scripts/node/scripts/ip-dns-resolver: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CLEAR_TARGET="/etc/resolvconf/resolv.conf.d/${1:?Missing clear file target.}" 4 | RESOLV_TARGET="/etc/resolvconf/resolv.conf.d/${2:?Missing resolv file target.}" 5 | 6 | NAMESERVER_IF1V4="${3:-}" 7 | NAMESERVER_IF1V6="${4:-}" 8 | 9 | [[ -n "${NAMESERVER_IF1V4}" ]] && [[ -f "/data/local/metadata/ipv4.1.up" ]] && ns4="nameserver ${NAMESERVER_IF1V4}" || ns4= 10 | [[ -n "${NAMESERVER_IF1V6}" ]] && [[ -f "/data/local/metadata/ipv6.1.up" ]] && ns6="nameserver ${NAMESERVER_IF1V6}" || ns6= 11 | 12 | [[ -n "${CLEAR_TARGET}" ]] && sudo bash -c "echo > '${CLEAR_TARGET}'" 13 | [[ -n "${RESOLV_TARGET}" ]] && sudo bash -c "cat > '${RESOLV_TARGET}'" < /dev/null 10 | done 11 | 12 | if ls "${RTORRENT_LOG}/*.log" &> /dev/null; then 13 | echo "Log files not moved." 1>&2 14 | exit 1 15 | fi 16 | 17 | if [[ "$DEBUG" == "yes" ]]; then 18 | gdb --args ${RTORRENT_EXEC} 19 | else 20 | nohup ${RTORRENT_EXEC} > ${RTORRENT_LOG}/daemon.log & 21 | fi 22 | 23 | sleep 1 24 | -------------------------------------------------------------------------------- /scripts/node/stop-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | RTORRENT_LOCKFILE="/data/local/session/rtorrent.lock" 4 | 5 | if [[ ! -e $RTORRENT_LOCKFILE ]]; then 6 | exit 0 7 | fi 8 | 9 | RTORRENT_PID=`sed -n 's/^[^:]*:+\([0-9].*\)$/\1/p' $RTORRENT_LOCKFILE` 10 | 11 | kill $RTORRENT_PID || true 12 | -------------------------------------------------------------------------------- /scripts/node/update-etc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig 4 | sed -e "s/^\(AcceptEnv[A-Z0-9 _*]*$\)/\1 SSH_AUTH_SOCK SSH_AGENT_PID/" /etc/ssh/sshd_config > /etc/ssh/sshd_config.new 5 | cp /etc/ssh/sshd_config.new /etc/ssh/sshd_config 6 | -------------------------------------------------------------------------------- /scripts/node/update-metadata: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source /data/scripts/metadata.source 4 | 5 | ip -4 addr show dev ${PRIVATE_DEV_1} permanent primary | sed -n 's_^.*inet \([0-9.]*\)/\([0-9]*\).*$_\1_p' > ${METADATA}/ipv4.1.address 6 | ip -4 addr show dev ${PRIVATE_DEV_1} permanent primary | sed -n 's_^.*inet \([0-9.]*\)/\([0-9]*\).*$_\2_p' > ${METADATA}/ipv4.1.prefix 7 | ip -6 addr show dev ${PRIVATE_DEV_1} permanent primary | sed -n 's_^.*inet6 \([0-9a-f:]*\)/\([0-9]*\).*$_\1_p' > ${METADATA}/ipv6.1.address 8 | ip -6 addr show dev ${PRIVATE_DEV_1} permanent primary | sed -n 's_^.*inet6 \([0-9a-f:]*\)/\([0-9]*\).*$_\2_p' > ${METADATA}/ipv6.1.prefix 9 | 10 | ip -4 addr show dev ${PRIVATE_DEV_2} permanent primary | sed -n 's_^.*inet \([0-9.]*\)/\([0-9]*\).*$_\1_p' > ${METADATA}/ipv4.2.address 11 | ip -4 addr show dev ${PRIVATE_DEV_2} permanent primary | sed -n 's_^.*inet \([0-9.]*\)/\([0-9]*\).*$_\2_p' > ${METADATA}/ipv4.2.prefix 12 | ip -6 addr show dev ${PRIVATE_DEV_2} permanent primary | sed -n 's_^.*inet6 \([0-9a-f:]*\)/\([0-9]*\).*$_\1_p' > ${METADATA}/ipv6.2.address 13 | ip -6 addr show dev ${PRIVATE_DEV_2} permanent primary | sed -n 's_^.*inet6 \([0-9a-f:]*\)/\([0-9]*\).*$_\2_p' > ${METADATA}/ipv6.2.prefix 14 | 15 | rm "${METADATA}"/ipv{4,6}.{1,2}.{up,down} &> /dev/null 16 | 17 | for prefix in "${METADATA}"/ipv{4,6}.{1,2}; do 18 | if [[ -n "$(<"${prefix}.address")" ]]; then 19 | touch "${prefix}.up" 20 | else 21 | touch "${prefix}.down" 22 | fi 23 | done 24 | -------------------------------------------------------------------------------- /scripts/ns-all: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_sequential "sudo netstat -pn | grep rtorrent" 7 | -------------------------------------------------------------------------------- /scripts/ns-ip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | export NODES=("${@:-${NODES[@]}}") 7 | 8 | call_ssh_sequential ip a 9 | -------------------------------------------------------------------------------- /scripts/ns-listen: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_parallel "sudo netstat -lpn | grep rtorrent" 7 | -------------------------------------------------------------------------------- /scripts/rm-torrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_parallel rm "${TORRENT_VM_DIR}/${1}" 7 | 8 | rm "${TORRENT_SHARED_DIR}/${1}" &> /dev/null 9 | rm "${TORRENT_SHARED_DIR}/${1}.torrent" &> /dev/null 10 | -------------------------------------------------------------------------------- /scripts/scp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | scp -F "${DATA_DIR}/ssh-config" $@ 6 | -------------------------------------------------------------------------------- /scripts/ssh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | args=("${@}") 7 | 8 | call_ssh_interactive "${args[@]}" 9 | -------------------------------------------------------------------------------- /scripts/start-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | if getopts "s" opt; then 7 | call_ssh_sequential "start-rtorrent" 8 | else 9 | call_ssh_parallel "start-rtorrent" 10 | fi 11 | -------------------------------------------------------------------------------- /scripts/stop-rtorrent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_parallel "stop-rtorrent" 7 | -------------------------------------------------------------------------------- /scripts/test-all: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | # TODO: If TESTS is defined, check that all tests are available. 6 | 7 | "${SCRIPT_DIR}/stop-rtorrent" 8 | 9 | echo 10 | echo "====================" 11 | echo "Unit tests:" 12 | echo "====================" 13 | echo 14 | 15 | "${SCRIPT_DIR}/build-check" 16 | 17 | TESTS=(${TESTS:-$(${SCRIPT_DIR}/test-list)}) 18 | 19 | RESULTS=() 20 | 21 | for (( i = 0; i < ${#TESTS[@]}; i++ )); do 22 | echo 23 | echo "====================" 24 | echo "${TESTS[i]}" 25 | echo "====================" 26 | 27 | "${TEST_DIR}/${TESTS[i]}" 28 | 29 | RESULTS+=("$?") 30 | done 31 | 32 | echo 33 | echo "====================" 34 | echo "Test results:" 35 | echo "====================" 36 | echo 37 | 38 | for (( i = 0; i < ${#RESULTS[@]}; i++ )); do 39 | if [[ "${RESULTS[i]}" == 0 ]]; then 40 | color="${GREEN}" 41 | else 42 | color="${RED}" 43 | fi 44 | 45 | echo -e "${color}${TESTS[i]}:\t ${RESULTS[i]}${NC}" 46 | done 47 | 48 | echo 49 | -------------------------------------------------------------------------------- /scripts/test-create-all: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | function create_torrent() { 6 | local name="${1:?Missing torrent name argument.}" 7 | 8 | # TODO: Caching the torrent is an issue when doing tests? Just make smaller torrents instead. 9 | if "${SCRIPT_DIR}/is-torrent-cached" "${name}"; then 10 | echo "test-create-all: already created, skipping: ${name}" 11 | else 12 | echo "test-create-all: creating ${name}" 13 | 14 | # Replace with call_quiet... 15 | if ! call_quiet "${SCRIPT_DIR}/torrent-create" "${name}"; then 16 | echo "test-create-all: failed to create torrent" 17 | exit 1 18 | fi 19 | fi 20 | 21 | if ! "${SCRIPT_DIR}/torrent-activate" "${name}"; then 22 | echo "test-create-all: failed to activate torrent" 23 | exit 1 24 | fi 25 | } 26 | 27 | case "${CREATE_PRESET}" in 28 | "if_single") 29 | CREATE_IF1="${CREATE_IF1:-yes}" 30 | CREATE_IF2="${CREATE_IF2:-no}" 31 | CREATE_DNS1="${CREATE_DNS1:-no}" 32 | CREATE_DNS2="${CREATE_DNS2:-no}" 33 | ;; 34 | "if_pair") 35 | CREATE_IF1="${CREATE_IF1:-yes}" 36 | CREATE_IF2="${CREATE_IF2:-yes}" 37 | CREATE_DNS1="${CREATE_DNS1:-no}" 38 | CREATE_DNS2="${CREATE_DNS2:-no}" 39 | ;; 40 | "if_dns_pair") 41 | CREATE_IF1="${CREATE_IF1:-yes}" 42 | CREATE_IF2="${CREATE_IF2:-yes}" 43 | CREATE_DNS1="${CREATE_DNS1:-yes}" 44 | CREATE_DNS2="${CREATE_DNS2:-yes}" 45 | ;; 46 | "") 47 | ;; 48 | *) 49 | echo "unknown preset: '${CREATE_PRESET}'" 50 | exit 1 51 | esac 52 | 53 | echo "test-create-all: deactivate torrents" 54 | for name in $("${SCRIPT_DIR}/test-torrent-all"); do 55 | "${SCRIPT_DIR}/torrent-deactivate" "${name}" &> /dev/null || : 56 | done 57 | 58 | # wait for deactiva 59 | 60 | echo "test-create-all: create torrents" 61 | 62 | if [[ "${CREATE_IF1}" = "yes" ]]; then 63 | [[ "${CREATE_IPV4}" = "no" ]] || USE_HTTP_TRACKER=yes USE_UDP_TRACKER=no USE_IPV4=yes USE_IPV6=no USE_IF1=yes USE_IF2=no create_torrent test_h4_if1 64 | [[ "${CREATE_IPV4}" = "no" ]] || USE_HTTP_TRACKER=no USE_UDP_TRACKER=yes USE_IPV4=yes USE_IPV6=no USE_IF1=yes USE_IF2=no create_torrent test_u4_if1 65 | [[ "${CREATE_IPV6}" = "no" ]] || USE_HTTP_TRACKER=yes USE_UDP_TRACKER=no USE_IPV4=no USE_IPV6=yes USE_IF1=yes USE_IF2=no create_torrent test_h6_if1 66 | [[ "${CREATE_IPV6}" = "no" ]] || USE_HTTP_TRACKER=no USE_UDP_TRACKER=yes USE_IPV4=no USE_IPV6=yes USE_IF1=yes USE_IF2=no create_torrent test_u6_if1 67 | fi 68 | 69 | if [[ "${CREATE_IF2}" = "yes" ]]; then 70 | [[ "${CREATE_IPV4}" = "no" ]] || USE_HTTP_TRACKER=yes USE_UDP_TRACKER=no USE_IPV4=yes USE_IPV6=no USE_IF1=no USE_IF2=yes create_torrent test_h4_if2 71 | [[ "${CREATE_IPV4}" = "no" ]] || USE_HTTP_TRACKER=no USE_UDP_TRACKER=yes USE_IPV4=yes USE_IPV6=no USE_IF1=no USE_IF2=yes create_torrent test_u4_if2 72 | [[ "${CREATE_IPV6}" = "no" ]] || USE_HTTP_TRACKER=yes USE_UDP_TRACKER=no USE_IPV4=no USE_IPV6=yes USE_IF1=no USE_IF2=yes create_torrent test_h6_if2 73 | [[ "${CREATE_IPV6}" = "no" ]] || USE_HTTP_TRACKER=no USE_UDP_TRACKER=yes USE_IPV4=no USE_IPV6=yes USE_IF1=no USE_IF2=yes create_torrent test_u6_if2 74 | fi 75 | 76 | if [[ "${CREATE_DNS1}" = "yes" ]]; then 77 | [[ "${CREATE_IPV4}" = "no" ]] || USE_HTTP_TRACKER=yes USE_UDP_TRACKER=no USE_IPV4=yes USE_IPV6=no USE_IF1=dns USE_IF2=no create_torrent test_h4_dns1 78 | [[ "${CREATE_IPV4}" = "no" ]] || USE_HTTP_TRACKER=no USE_UDP_TRACKER=yes USE_IPV4=yes USE_IPV6=no USE_IF1=dns USE_IF2=no create_torrent test_u4_dns1 79 | [[ "${CREATE_IPV6}" = "no" ]] || USE_HTTP_TRACKER=yes USE_UDP_TRACKER=no USE_IPV4=no USE_IPV6=yes USE_IF1=dns USE_IF2=no create_torrent test_h6_dns1 80 | [[ "${CREATE_IPV6}" = "no" ]] || USE_HTTP_TRACKER=no USE_UDP_TRACKER=yes USE_IPV4=no USE_IPV6=yes USE_IF1=dns USE_IF2=no create_torrent test_u6_dns1 81 | fi 82 | 83 | if [[ "${CREATE_DNS2}" = "yes" ]]; then 84 | [[ "${CREATE_IPV4}" = "no" ]] || USE_HTTP_TRACKER=yes USE_UDP_TRACKER=no USE_IPV4=yes USE_IPV6=no USE_IF1=no USE_IF2=dns create_torrent test_h4_dns2 85 | [[ "${CREATE_IPV4}" = "no" ]] || USE_HTTP_TRACKER=no USE_UDP_TRACKER=yes USE_IPV4=yes USE_IPV6=no USE_IF1=no USE_IF2=dns create_torrent test_u4_dns2 86 | [[ "${CREATE_IPV6}" = "no" ]] || USE_HTTP_TRACKER=yes USE_UDP_TRACKER=no USE_IPV4=no USE_IPV6=yes USE_IF1=no USE_IF2=dns create_torrent test_h6_dns2 87 | [[ "${CREATE_IPV6}" = "no" ]] || USE_HTTP_TRACKER=no USE_UDP_TRACKER=yes USE_IPV4=no USE_IPV6=yes USE_IF1=no USE_IF2=dns create_torrent test_u6_dns2 88 | fi 89 | 90 | echo "test-create-all: completed torrents" 91 | -------------------------------------------------------------------------------- /scripts/test-delete-all: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-args" 5 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 6 | 7 | "${SCRIPT_DIR}/stop-rtorrent" 8 | 9 | call_ssh_parallel rm "${TORRENT_VM_DIR}/*" 2> /dev/null || : 10 | 11 | for node in "${NODES[@]}"; do 12 | rm -f "${DATA_DIR}/${node}"/session/*.torrent &> /dev/null || : 13 | rm -f "${DATA_DIR}/${node}"/session/*.torrent.* &> /dev/null || : 14 | rm -f "${DATA_DIR}/${node}"/session/rtorrent.{dht_cache,input_history} &> /dev/null || : 15 | done 16 | -------------------------------------------------------------------------------- /scripts/test-feature-dns: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Compile with each of the different async dns resolvers, do make 4 | # check and ci test default/bind/dns. 5 | # 6 | # Improve test naming in the results. 7 | 8 | source "${BASH_SOURCE[0]%/*}/include/init" 9 | source "${BASH_SOURCE[0]%/*}/include/test-unit" 10 | 11 | test_dns() { 12 | test_unit "default" 13 | test_unit "dns_default" 14 | test_dns_resolver builder 15 | test_unit "dns_default" 16 | test_dns_resolver default 17 | } 18 | 19 | test_init "test-feature-dns" 20 | test_dns_resolver default 21 | 22 | test_begin "Default" 23 | test_compile "" 24 | test_has_features without-udns 25 | test_dns 26 | 27 | test_begin "Without UDNS" 28 | test_compile "WITHOUT_UDNS=yes" 29 | test_has_features without-udns 30 | test_dns 31 | 32 | test_begin "With UDNS" 33 | test_compile "WITH_UDNS=no" 34 | test_has_features with-udns 35 | test_dns 36 | 37 | test_cleanup 38 | -------------------------------------------------------------------------------- /scripts/test-list: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo default 4 | echo bind_port_simple 5 | echo bind_port_randomize 6 | echo bind_set_v4v6only 7 | echo bind_add_v4v6only_accept 8 | echo encryption_none 9 | echo encryption_require 10 | -------------------------------------------------------------------------------- /scripts/test-torrent-all: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo test_{h,u}{4,6}_{dns,if}{1,2} 4 | -------------------------------------------------------------------------------- /scripts/torrent-activate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | TORRENT_FILENAME="${1:?Missing torrent filename.}" 7 | 8 | call_ssh_node "${SEED_NODE}" cp -r "${TORRENT_VM_SHARED_DIR}/*" "${TORRENT_VM_DIR}" 9 | 10 | (rm "${DATA_HOST_WATCH}/${TORRENT_FILENAME}.torrent" || true) &> /dev/null 11 | cp "${TORRENT_SHARED_DIR}/${TORRENT_FILENAME}.torrent" "${DATA_HOST_WATCH}" 12 | -------------------------------------------------------------------------------- /scripts/torrent-create: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_node builder \ 7 | USE_HTTP_TRACKER=${USE_HTTP_TRACKER} USE_UDP_TRACKER=${USE_UDP_TRACKER} \ 8 | USE_IPV4=${USE_IPV4} USE_IPV6=${USE_IPV6} USE_IF1=${USE_IF1} USE_IF2=${USE_IF2} \ 9 | make-torrent $@ 10 | -------------------------------------------------------------------------------- /scripts/torrent-data-compare: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | node="${1:?Node or local not specified.}" 6 | remote_path="/data/torrents/" 7 | local_path="${2:?Local torrent path not specified.}" 8 | torrent_name="${3:?Torrent name not specified.}" 9 | 10 | remote_wc="`\"${SCRIPT_DIR}/torrent-data-wc\" ${node} \"${remote_path}\" \"${torrent_name}\"`" 11 | local_wc="`\"${SCRIPT_DIR}/torrent-data-wc\" local \"${local_path}\" \"${torrent_name}\"`" 12 | 13 | IFS=$'\n' 14 | 15 | for i in ${remote_wc}; do echo "remote: ${i}"; done 16 | echo 17 | for i in ${local_wc}; do echo "local: ${i}"; done 18 | echo 19 | 20 | if [[ -z "${remote_wc}" ]] || [[ -z "${local_wc}" ]]; then 21 | echo "result: missing" 22 | exit 1 23 | fi 24 | 25 | if [[ "${remote_wc}" = "${local_wc}" ]]; then 26 | echo "result: matching" 27 | exit 0 28 | else 29 | echo "result: mismatch" 30 | exit 1 31 | fi 32 | -------------------------------------------------------------------------------- /scripts/torrent-data-root: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | node="${1:?Node or local not specified.}" 7 | root_dir="${2:?Root directory not specified.}" 8 | wildcard="${3:?Wildcard not specified.}" 9 | 10 | if [[ "${node}" = "local" ]]; then 11 | (cd ${root_dir} && ls -1d ${wildcard}) 12 | else 13 | call_ssh_node "${node}" -- "(cd ${root_dir} && ls -1d ${wildcard})" 14 | fi 15 | -------------------------------------------------------------------------------- /scripts/torrent-data-wc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | source "${BASH_SOURCE[0]%/*}/include/torrent" 5 | 6 | node="${1:?Node or local not specified.}" 7 | torrent_path="${2:?Torrent path not specified.}" 8 | torrent_name="${3:?Torrent name not specified.}" 9 | 10 | if [[ "${node}" = "local" ]]; then 11 | cd "${torrent_path}" && ([ -d "${torrent_name}" ]] || [[ -f "${torrent_name}" ]) && (find "${torrent_name}" -type f -print0 | sort -z | xargs -0 wc -c) 12 | else 13 | call_ssh_node "${node}" -- "cd '${torrent_path}' && ([ -d '${torrent_name}' ]] || [[ -f '${torrent_name}' ]) && (find '${torrent_name}' -type f -print0 | sort -z | xargs -0 wc -c)" 14 | fi 15 | -------------------------------------------------------------------------------- /scripts/torrent-deactivate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | TORRENT_FILENAME="${1:?Missing torrent filename.}" 6 | 7 | rm "${DATA_HOST_WATCH}/${TORRENT_FILENAME}.torrent" 8 | -------------------------------------------------------------------------------- /scripts/torrent-export: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | torrent_name="${1:?Torrent name not specified.}" 6 | dst_dir="${2:?Destination directory not specified.}" 7 | 8 | "${SCRIPT_DIR}/scp" -r "node-dl:/data/torrents/${torrent_name}" "${dst_dir}/" 9 | -------------------------------------------------------------------------------- /scripts/torrent-info-hash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | CALL_NODE="${1:?Target node not given.}" 6 | TORRENT_NAME="${2:?Torrent name not given.}" 7 | 8 | call_rpc d.multicall2 s/ s/ d.hash= d.name= | grep -e "^[A-Z0-9]* ${TORRENT_NAME}" | cut -d ' ' -f 1 9 | -------------------------------------------------------------------------------- /scripts/torrent-list: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/call" 4 | 5 | find "${TORRENT_SHARED_DIR}" -name \*.torrent -exec basename {} \; | sed -e 's/\.torrent$//' 6 | -------------------------------------------------------------------------------- /scripts/update-current-nodes: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | nodes="$(( cd "${DATA_DIR}" && ls -d node* || :) 2> /dev/null)" 6 | 7 | echo "NODES=( 8 | ${nodes[@]} 9 | )" > "${DATA_DIR}/current-nodes" 10 | -------------------------------------------------------------------------------- /scripts/update-rtorrent-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | for CALL_NODE in ${NODES[@]}; do 6 | "${SCRIPT_DIR}/scp" -F "${DATA_DIR}/ssh-config" "${ROOT_DIR}/puppet/modules/client/files/rtorrent.rc" "${CALL_NODE}:" 7 | done 8 | 9 | call_ssh_parallel sudo mv ./rtorrent.rc /etc/rtorrent.rc 10 | -------------------------------------------------------------------------------- /scripts/update-ssh-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | 5 | vagrant ssh-config > "${DATA_DIR}/ssh-config" 6 | -------------------------------------------------------------------------------- /scripts/update-ssh-service: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/include/init" 4 | source "${BASH_SOURCE[0]%/*}/include/call-ssh" 5 | 6 | call_ssh_parallel sudo restart ssh 7 | -------------------------------------------------------------------------------- /scripts/xmlrpc2scgi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys, cStringIO as StringIO 4 | import xmlrpclib, urllib, urlparse, socket, re 5 | 6 | from urlparse import uses_netloc 7 | uses_netloc.append('scgi') 8 | 9 | def do_scgi_xmlrpc_request(host, methodname, params=()): 10 | xmlreq = xmlrpclib.dumps(params, methodname) 11 | xmlresp = SCGIRequest(host).send(xmlreq) 12 | return xmlresp 13 | 14 | def do_scgi_xmlrpc_request_py(host, methodname, params=()): 15 | xmlresp = do_scgi_xmlrpc_request(host, methodname, params) 16 | return xmlrpclib.loads(xmlresp)[0][0] 17 | 18 | class SCGIRequest(object): 19 | 20 | def __init__(self, url): 21 | self.url=url 22 | self.resp_headers=[] 23 | 24 | def __send(self, scgireq): 25 | scheme, netloc, path, query, frag = urlparse.urlsplit(self.url) 26 | host, port = urllib.splitport(netloc) 27 | 28 | if netloc: 29 | #sys.stderr.write("host:%s port:%s\n" % (host, port)) 30 | 31 | inet6_host = '' #re.search( r'^\[(.*)\]$', host, re.M).group(1) 32 | 33 | if len(inet6_host) > 0: 34 | #sys.stderr.write("inet6_host:%s\n" % (inet6_host)) 35 | addrinfo = socket.getaddrinfo(inet6_host, port, socket.AF_INET6, socket.SOCK_STREAM) 36 | else: 37 | #sys.stderr.write("inet_host:%s\n" % (host)) 38 | addrinfo = socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM) 39 | 40 | assert len(addrinfo) == 1, "There's more than one? %r" % addrinfo 41 | 42 | sock = socket.socket(*addrinfo[0][:3]) 43 | sock.connect(addrinfo[0][4]) 44 | else: 45 | sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 46 | sock.connect(path) 47 | 48 | sock.send(scgireq) 49 | recvdata = resp = sock.recv(1024) 50 | 51 | while recvdata != '': 52 | recvdata = sock.recv(1024) 53 | resp += recvdata 54 | sock.close() 55 | return resp 56 | 57 | def send(self, data): 58 | "Send data over scgi to url and get response" 59 | scgiresp = self.__send(self.add_required_scgi_headers(data)) 60 | resp, self.resp_headers = self.get_scgi_resp(scgiresp) 61 | return resp 62 | 63 | @staticmethod 64 | def encode_netstring(string): 65 | "Encode string as netstring" 66 | return '%d:%s,'%(len(string), string) 67 | 68 | @staticmethod 69 | def make_headers(headers): 70 | "Make scgi header list" 71 | return '\x00'.join(['%s\x00%s'%t for t in headers])+'\x00' 72 | 73 | @staticmethod 74 | def add_required_scgi_headers(data, headers=[]): 75 | "Wrap data in an scgi request,\nsee spec at: http://python.ca/scgi/protocol.txt" 76 | headers = SCGIRequest.make_headers([('CONTENT_LENGTH', str(len(data))),('SCGI', '1'),] + headers) 77 | enc_headers = SCGIRequest.encode_netstring(headers) 78 | return enc_headers+data 79 | 80 | @staticmethod 81 | def gen_headers(file): 82 | "Get header lines from scgi response" 83 | line = file.readline().rstrip() 84 | 85 | while line.strip(): 86 | yield line 87 | line = file.readline().rstrip() 88 | 89 | @staticmethod 90 | def get_scgi_resp(resp): 91 | "Get xmlrpc response from scgi response" 92 | fresp = StringIO.StringIO(resp) 93 | headers = [] 94 | 95 | for line in SCGIRequest.gen_headers(fresp): 96 | headers.append(line.split(': ', 1)) 97 | 98 | xmlresp = fresp.read() 99 | return (xmlresp, headers) 100 | 101 | class RTorrentXMLRPCClient(object): 102 | 103 | def __init__(self, url, methodname=''): 104 | self.url = url 105 | self.methodname = methodname 106 | 107 | def __call__(self, *args): 108 | scheme, netloc, path, query, frag = urlparse.urlsplit(self.url) 109 | xmlreq = xmlrpclib.dumps(args, self.methodname) 110 | 111 | if scheme == 'scgi': 112 | xmlresp = SCGIRequest(self.url).send(xmlreq) 113 | return xmlrpclib.loads(xmlresp)[0][0] 114 | elif scheme == 'http': 115 | raise Exception('Unsupported protocol') 116 | elif scheme == '': 117 | raise Exception('Unsupported protocol') 118 | else: 119 | raise Exception('Unsupported protocol') 120 | 121 | def __getattr__(self, attr): 122 | methodname = self.methodname and '.'.join([self.methodname,attr]) or attr 123 | return RTorrentXMLRPCClient(self.url, methodname) 124 | 125 | def convert_params_to_native(params): 126 | "Parse xmlrpc-c command line arg syntax" 127 | cparams = [] 128 | 129 | for param in params: 130 | if len(param) < 2 or param[1] != '/': 131 | cparams.append(param) 132 | continue 133 | if param[0] == 'i': 134 | ptype = int 135 | elif param[0] == 'b': 136 | ptype = bool 137 | elif param[0] == 's': 138 | ptype = str 139 | else: 140 | cparams.append(param) 141 | continue 142 | cparams.append(ptype(param[2:])) 143 | 144 | return tuple(cparams) 145 | 146 | def print_script(response): 147 | if type(response) is int: 148 | print response 149 | elif type(response) is str: 150 | print response 151 | else: 152 | for line in response: 153 | print " ".join(map(unicode, line)).encode('utf-8') 154 | 155 | def main(argv): 156 | if len(argv) < 1: 157 | print "No arguments." 158 | raise SystemExit, -1 159 | 160 | if len(argv[0]) and argv[0][0] == '-': 161 | output_arg = argv[0] 162 | argv.pop(0) 163 | 164 | if len(argv) < 2: 165 | print "Too few arguments." 166 | raise SystemExit, -1 167 | 168 | host, methodname = argv[:2] 169 | respxml = do_scgi_xmlrpc_request(host, methodname, convert_params_to_native(argv[2:])) 170 | 171 | if output_arg == '-p': 172 | print xmlrpclib.loads(respxml)[0][0] 173 | elif output_arg == '-s': 174 | print_script(xmlrpclib.loads(respxml)[0][0]) 175 | else: 176 | print respxml 177 | 178 | if __name__ == "__main__": 179 | try: 180 | main(sys.argv[1:]) 181 | except xmlrpclib.Fault as e: 182 | print "xmlrpclib.Fault({0}): {1}".format(e.faultCode, e.faultString) 183 | -------------------------------------------------------------------------------- /test/bind_add_v4v6only_accept: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/call" 4 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/test" 5 | 6 | # Test accepting connections when bound to v4/v6only. 7 | # 8 | # Both interfaces on all nodes have ipv4/v6 addresses. 9 | 10 | echo "running bind_add_v4v6only_accept" 11 | 12 | clean_all 13 | 14 | "${SCRIPT_DIR}/config-set-block-connect" node1 15 | "${SCRIPT_DIR}/config-set-block-accept" node2 16 | "${SCRIPT_DIR}/config-set-block-accept" node3 17 | "${SCRIPT_DIR}/config-set-block-accept" node4 18 | "${SCRIPT_DIR}/config-set-block-accept" node5 19 | 20 | # TODO: Add support for looking up address by name, 21 | # TODO: Pass hostname to bind, allow us to refresh it. 22 | # TODO: Test fails on invalid address. (:: on v4only, etc) 23 | # TODO: Make spec. 24 | # TODO: Add test for connect. 25 | 26 | "${SCRIPT_DIR}/config-bind-clear" node2 27 | "${SCRIPT_DIR}/config-bind-add" node2 v4 100 0.0.0.0 v4only 28 | 29 | "${SCRIPT_DIR}/config-bind-clear" node3 30 | "${SCRIPT_DIR}/config-bind-add" node3 v6 100 :: v6only 31 | 32 | "${SCRIPT_DIR}/config-bind-clear" node4 33 | "${SCRIPT_DIR}/config-bind-add" node4 v4 100 ipv4.1 v4only 34 | 35 | "${SCRIPT_DIR}/config-bind-clear" node5 36 | "${SCRIPT_DIR}/config-bind-add" node5 v6 100 ipv6.2 v6only 37 | 38 | setup if1v4v6_if2v4v6 39 | 40 | verify_completed node2 test_h4_if1 "bind ipv4 any address with v4only" 41 | verify_completed node2 test_u4_if1 "bind ipv4 any address with v4only" 42 | verify_incompleted node2 test_h6_if1 "bind ipv4 any address with v4only" 43 | verify_incompleted node2 test_u6_if1 "bind ipv4 any address with v4only" 44 | verify_completed node2 test_h4_if2 "bind ipv4 any address with v4only" 45 | verify_completed node2 test_u4_if2 "bind ipv4 any address with v4only" 46 | verify_incompleted node2 test_h6_if2 "bind ipv4 any address with v4only" 47 | verify_incompleted node2 test_u6_if2 "bind ipv4 any address with v4only" 48 | 49 | verify_incompleted node3 test_h4_if1 "bind ipv6 any address with v6only" 50 | verify_incompleted node3 test_u4_if1 "bind ipv6 any address with v6only" 51 | verify_completed node3 test_h6_if1 "bind ipv6 any address with v6only" 52 | verify_completed node3 test_u6_if1 "bind ipv6 any address with v6only" 53 | verify_incompleted node3 test_h4_if2 "bind ipv6 any address with v6only" 54 | verify_incompleted node3 test_u4_if2 "bind ipv6 any address with v6only" 55 | verify_completed node3 test_h6_if2 "bind ipv6 any address with v6only" 56 | verify_completed node3 test_u6_if2 "bind ipv6 any address with v6only" 57 | 58 | verify_completed node4 test_h4_if1 "bind ipv4 specific address with v4only" 59 | verify_completed node4 test_u4_if1 "bind ipv4 specific address with v4only" 60 | verify_incompleted node4 test_h6_if1 "bind ipv4 specific address with v4only" 61 | verify_incompleted node4 test_u6_if1 "bind ipv4 specific address with v4only" 62 | verify_incompleted node4 test_h4_if2 "bind ipv4 specific address with v4only" 63 | verify_incompleted node4 test_u4_if2 "bind ipv4 specific address with v4only" 64 | verify_incompleted node4 test_h6_if2 "bind ipv4 specific address with v4only" 65 | verify_incompleted node4 test_u6_if2 "bind ipv4 specific address with v4only" 66 | 67 | verify_incompleted node5 test_h4_if1 "bind ipv6 specific address with v6only" 68 | verify_incompleted node5 test_u4_if1 "bind ipv6 specific address with v6only" 69 | verify_incompleted node5 test_h6_if1 "bind ipv6 specific address with v6only" 70 | verify_incompleted node5 test_u6_if1 "bind ipv6 specific address with v6only" 71 | verify_incompleted node5 test_h4_if2 "bind ipv6 specific address with v6only" 72 | verify_incompleted node5 test_u4_if2 "bind ipv6 specific address with v6only" 73 | verify_completed node5 test_h6_if2 "bind ipv6 specific address with v6only" 74 | verify_completed node5 test_u6_if2 "bind ipv6 specific address with v6only" 75 | 76 | exit_test 77 | -------------------------------------------------------------------------------- /test/bind_port_randomize: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/call" 4 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/test" 5 | 6 | echo "running bind_port_randomize" 7 | 8 | clean_all 9 | 10 | # node2 will sequentially pick port 15499 11 | # node3 will randomly pick a port between 15499-15900 12 | # node4 will sequentially pick port 16499 13 | # node5 will randomly pick a port between 16499-16900 14 | "${SCRIPT_DIR}/config-set-port-range" node2 15499 15900 15 | "${SCRIPT_DIR}/config-set-port-range" node3 15499 15900 16 | "${SCRIPT_DIR}/config-set-port-range" node4 16499 16900 17 | "${SCRIPT_DIR}/config-set-port-range" node5 16499 16900 18 | 19 | "${SCRIPT_DIR}/config-set-block-connect" node2 20 | "${SCRIPT_DIR}/config-set-block-connect" node3 21 | "${SCRIPT_DIR}/config-set-block-connect" node4 22 | "${SCRIPT_DIR}/config-set-block-connect" node5 23 | 24 | "${SCRIPT_DIR}/config-disable-port-randomize" node2 25 | "${SCRIPT_DIR}/config-disable-port-randomize" node4 26 | 27 | setup if1v4v6_if2v4v6 28 | 29 | verify_incompleted node2 test_h4_if1 "sequential http4" 30 | verify_incompleted node2 test_u4_if1 "sequential udp4" 31 | verify_completed node2 test_h4_if2 "sequential http4" 32 | verify_completed node2 test_u4_if2 "sequential udp4" 33 | 34 | verify_completed node3 test_h4_if1 "randomized http4" 35 | verify_completed node3 test_u4_if1 "randomized udp4" 36 | verify_incompleted node3 test_h4_if2 "randomized http4" 37 | verify_incompleted node3 test_u4_if2 "randomized udp4" 38 | 39 | verify_incompleted node4 test_h6_if1 "sequential http6" 40 | verify_incompleted node4 test_u6_if1 "sequential udp6" 41 | verify_completed node4 test_h6_if2 "sequential http6" 42 | verify_completed node4 test_u6_if2 "sequential udp6" 43 | 44 | verify_completed node5 test_h6_if1 "randomized http6" 45 | verify_completed node5 test_u6_if1 "randomized udp6" 46 | verify_incompleted node5 test_h6_if2 "randomized http6" 47 | verify_incompleted node5 test_u6_if2 "randomized udp6" 48 | 49 | exit_test 50 | -------------------------------------------------------------------------------- /test/bind_port_simple: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/call" 4 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/test" 5 | 6 | echo "running bind_port_simple" 7 | 8 | clean_all 9 | 10 | # Tests that ipv4 and ipv6 are bound properly. 11 | "${SCRIPT_DIR}/config-set-port-range" node2 15500 15600 12 | "${SCRIPT_DIR}/config-set-port-range" node3 16500 16600 13 | 14 | "${SCRIPT_DIR}/config-set-block-connect" node2 15 | "${SCRIPT_DIR}/config-set-block-connect" node3 16 | 17 | setup if1p1_if2p1 18 | 19 | verify_completed node2 test_h4_if1 "incoming http4 tracker with v4only" 20 | verify_completed node2 test_u4_if1 "incoming udp4 tracker with v4only" 21 | verify_incompleted node2 test_h6_if1 "incoming http6 tracker with v4only" 22 | verify_incompleted node2 test_u6_if1 "incoming udp6 tracker with v4only" 23 | verify_incompleted node2 test_h4_if2 "incoming http4 tracker with v4only, port blocked" 24 | verify_incompleted node2 test_u4_if2 "incoming udp4 tracker with v4only, port blocked" 25 | verify_incompleted node2 test_h6_if2 "incoming http6 tracker with v4only, port blocked" 26 | verify_incompleted node2 test_u6_if2 "incoming udp6 tracker with v4only, port blocked" 27 | 28 | verify_incompleted node3 test_h4_if1 "incoming http4 tracker with v6only" 29 | verify_incompleted node3 test_u4_if1 "incoming udp4 tracker with v6only" 30 | verify_completed node3 test_h6_if1 "incoming http6 tracker with v6only" 31 | verify_completed node3 test_u6_if1 "incoming udp6 tracker with v6only" 32 | verify_incompleted node3 test_h4_if2 "incoming http4 tracker with v6only, port blocked" 33 | verify_incompleted node3 test_u4_if2 "incoming udp4 tracker with v6only, port blocked" 34 | verify_incompleted node3 test_h6_if2 "incoming http6 tracker with v6only, port blocked" 35 | verify_incompleted node3 test_u6_if2 "incoming udp6 tracker with v6only, port blocked" 36 | 37 | exit_test 38 | -------------------------------------------------------------------------------- /test/bind_set_v4v6only: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/call" 4 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/test" 5 | 6 | echo "running bind_set_v4v6only" 7 | 8 | clean_all 9 | 10 | "${SCRIPT_DIR}/config-bind-set" "node2" "ipv4.1" 11 | "${SCRIPT_DIR}/config-bind-set" "node3" "ipv4.1" 12 | "${SCRIPT_DIR}/config-bind-set" "node4" "ipv6.1" 13 | "${SCRIPT_DIR}/config-bind-set" "node5" "ipv6.1" 14 | 15 | ACTIVE_NODES="node1 node2 node5" setup if1p1 16 | 17 | verify_completed node2 test_h4_if1 "http4 tracker with v4only" 18 | verify_completed node2 test_u4_if1 "udp4 tracker with v4only" 19 | verify_incompleted node2 test_h6_if1 "http6 tracker with v4only" 20 | verify_incompleted node2 test_u6_if1 "udp6 tracker with v4only" 21 | 22 | verify_bind_failed node3 "bind4 fails when no ipv4 is available" 23 | verify_bind_failed node4 "bind6 fails when no ipv6 is available" 24 | 25 | verify_incompleted node5 test_h4_if1 "http4 tracker with v6only" 26 | verify_incompleted node5 test_u4_if1 "udp4 tracker with v6only" 27 | verify_completed node5 test_h6_if1 "http6 tracker with v6only" 28 | verify_completed node5 test_u6_if1 "udp6 tracker with v6only" 29 | 30 | exit_test 31 | -------------------------------------------------------------------------------- /test/default: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/../scripts/include/init" 4 | source "${BASH_SOURCE[0]%/*}/../scripts/include/test" 5 | 6 | echo "running default" 7 | 8 | clean_all 9 | setup if1p1_if2v4v6 10 | 11 | verify_completed node2 test_h4_if1 "http4 tracker with v4only" 12 | verify_completed node2 test_u4_if1 "udp4 tracker with v4only" 13 | verify_incompleted node2 test_h6_if1 "http6 tracker with v4only" 14 | verify_incompleted node2 test_u6_if1 "udp6 tracker with v4only" 15 | verify_completed node2 test_h4_if2 "http4 tracker with v4v6" 16 | verify_completed node2 test_u4_if2 "udp4 tracker with v4v6" 17 | verify_completed node2 test_h6_if2 "http6 tracker with v4v6" 18 | verify_completed node2 test_u6_if2 "udp6 tracker with v4v6" 19 | 20 | verify_incompleted node3 test_h4_if1 "http4 tracker with v6only" 21 | verify_incompleted node3 test_u4_if1 "udp4 tracker with v6only" 22 | verify_completed node3 test_h6_if1 "http6 tracker with v6only" 23 | verify_completed node3 test_u6_if1 "udp6 tracker with v6only" 24 | verify_completed node3 test_h4_if2 "http4 tracker with v4v6" 25 | verify_completed node3 test_u4_if2 "udp4 tracker with v4v6" 26 | verify_completed node3 test_h6_if2 "http6 tracker with v4v6" 27 | verify_completed node3 test_u6_if2 "udp6 tracker with v4v6" 28 | 29 | exit_test 30 | -------------------------------------------------------------------------------- /test/dns_default: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "${BASH_SOURCE[0]%/*}/../scripts/include/init" 4 | source "${BASH_SOURCE[0]%/*}/../scripts/include/test" 5 | 6 | echo "running dns_default" 7 | 8 | clean_all 9 | setup if1v4v6_if2p1_dns 10 | 11 | verify_completed node2 test_h4_if1 "http4 tracker with v4only" 12 | verify_completed node2 test_u4_if1 "udp4 tracker with v4only" 13 | verify_completed node2 test_h6_if1 "http6 tracker with v4only" 14 | verify_completed node2 test_u6_if1 "udp6 tracker with v4only" 15 | verify_completed node2 test_h4_if2 "http4 tracker with v4v6" 16 | verify_completed node2 test_u4_if2 "udp4 tracker with v4v6" 17 | verify_incompleted node2 test_h6_if2 "http6 tracker with v4v6" 18 | verify_incompleted node2 test_u6_if2 "udp6 tracker with v4v6" 19 | 20 | verify_completed node2 test_h4_dns1 "http4 tracker with v4only" 21 | verify_completed node2 test_u4_dns1 "udp4 tracker with v4only" 22 | verify_completed node2 test_h6_dns1 "http6 tracker with v4only" 23 | verify_completed node2 test_u6_dns1 "udp6 tracker with v4only" 24 | verify_completed node2 test_h4_dns2 "http4 tracker with v4v6" 25 | verify_completed node2 test_u4_dns2 "udp4 tracker with v4v6" 26 | verify_incompleted node2 test_h6_dns2 "http6 tracker with v4v6" 27 | verify_incompleted node2 test_u6_dns2 "udp6 tracker with v4v6" 28 | 29 | verify_completed node3 test_h4_if1 "http4 tracker with v6only" 30 | verify_completed node3 test_u4_if1 "udp4 tracker with v6only" 31 | verify_completed node3 test_h6_if1 "http6 tracker with v6only" 32 | verify_completed node3 test_u6_if1 "udp6 tracker with v6only" 33 | verify_incompleted node3 test_h4_if2 "http4 tracker with v4v6" 34 | verify_incompleted node3 test_u4_if2 "udp4 tracker with v4v6" 35 | verify_completed node3 test_h6_if2 "http6 tracker with v4v6" 36 | verify_completed node3 test_u6_if2 "udp6 tracker with v4v6" 37 | 38 | verify_completed node3 test_h4_dns1 "http4 tracker with v6only" 39 | verify_completed node3 test_u4_dns1 "udp4 tracker with v6only" 40 | verify_completed node3 test_h6_dns1 "http6 tracker with v6only" 41 | verify_completed node3 test_u6_dns1 "udp6 tracker with v6only" 42 | verify_incompleted node3 test_h4_dns2 "http4 tracker with v4v6" 43 | verify_incompleted node3 test_u4_dns2 "udp4 tracker with v4v6" 44 | verify_completed node3 test_h6_dns2 "http6 tracker with v4v6" 45 | verify_completed node3 test_u6_dns2 "udp6 tracker with v4v6" 46 | 47 | exit_test 48 | -------------------------------------------------------------------------------- /test/encryption_none: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/call" 4 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/test" 5 | 6 | echo "running encryption_none" 7 | 8 | clean_all 9 | 10 | "${SCRIPT_DIR}/config-set-block-connect" node2 11 | "${SCRIPT_DIR}/config-set-block-accept" node3 12 | "${SCRIPT_DIR}/config-set-block-connect" node4 13 | "${SCRIPT_DIR}/config-set-block-accept" node5 14 | 15 | "${SCRIPT_DIR}/config-set-protocol-encryption" node1 "none" 16 | "${SCRIPT_DIR}/config-set-protocol-encryption" node2 "none" 17 | "${SCRIPT_DIR}/config-set-protocol-encryption" node3 "none" 18 | "${SCRIPT_DIR}/config-set-protocol-encryption" node4 "require,require_rc4" 19 | "${SCRIPT_DIR}/config-set-protocol-encryption" node5 "require,require_rc4" 20 | 21 | setup if1v4v6 22 | 23 | verify_completed node2 test_h4_if1 "incoming unencrypted connections over ipv4" 24 | verify_completed node2 test_u4_if1 "incoming unencrypted connections over ipv4" 25 | verify_completed node2 test_h6_if1 "incoming unencrypted connections over ipv6" 26 | verify_completed node2 test_u6_if1 "incoming unencrypted connections over ipv6" 27 | 28 | verify_completed node3 test_h4_if1 "outgoing unencrypted connections over ipv4" 29 | verify_completed node3 test_u4_if1 "outgoing unencrypted connections over ipv4" 30 | verify_completed node3 test_h6_if1 "outgoing unencrypted connections over ipv6" 31 | verify_completed node3 test_u6_if1 "outgoing unencrypted connections over ipv6" 32 | 33 | verify_incompleted node4 test_h4_if1 "incoming encrypted connections over ipv4" 34 | verify_incompleted node4 test_u4_if1 "incoming encrypted connections over ipv4" 35 | verify_incompleted node4 test_h6_if1 "incoming encrypted connections over ipv6" 36 | verify_incompleted node4 test_u6_if1 "incoming encrypted connections over ipv6" 37 | 38 | verify_incompleted node5 test_h4_if1 "outgoing encrypted connections over ipv4" 39 | verify_incompleted node5 test_u4_if1 "outgoing encrypted connections over ipv4" 40 | verify_incompleted node5 test_h6_if1 "outgoing encrypted connections over ipv6" 41 | verify_incompleted node5 test_u6_if1 "outgoing encrypted connections over ipv6" 42 | 43 | exit_test 44 | -------------------------------------------------------------------------------- /test/encryption_require: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/call" 4 | source "`dirname ${BASH_SOURCE[0]}`/../scripts/include/test" 5 | 6 | echo "running encryption_require" 7 | 8 | clean_all 9 | 10 | "${SCRIPT_DIR}/config-set-block-connect" node2 11 | "${SCRIPT_DIR}/config-set-block-accept" node3 12 | "${SCRIPT_DIR}/config-set-block-connect" node4 13 | "${SCRIPT_DIR}/config-set-block-accept" node5 14 | 15 | "${SCRIPT_DIR}/config-set-protocol-encryption" node1 "require,require_rc4" 16 | "${SCRIPT_DIR}/config-set-protocol-encryption" node2 "none" 17 | "${SCRIPT_DIR}/config-set-protocol-encryption" node3 "none" 18 | "${SCRIPT_DIR}/config-set-protocol-encryption" node4 "require,require_rc4" 19 | "${SCRIPT_DIR}/config-set-protocol-encryption" node5 "require,require_rc4" 20 | 21 | setup if1v4v6 22 | 23 | verify_incompleted node2 test_h4_if1 "incoming plaintext connections with v4only" 24 | verify_incompleted node2 test_u4_if1 "incoming plaintext connections with v4only" 25 | verify_incompleted node2 test_h6_if1 "incoming plaintext connections with v6only" 26 | verify_incompleted node2 test_u6_if1 "incoming plaintext connections with v6only" 27 | 28 | verify_incompleted node3 test_h4_if1 "outgoing plaintext connections with v4only" 29 | verify_incompleted node3 test_u4_if1 "outgoing plaintext connections with v4only" 30 | verify_incompleted node3 test_h6_if1 "outgoing plaintext connections with v6only" 31 | verify_incompleted node3 test_u6_if1 "outgoing plaintext connections with v6only" 32 | 33 | verify_completed node4 test_h4_if1 "incoming encrypted connections with v4only" 34 | verify_completed node4 test_u4_if1 "incoming encrypted connections with v4only" 35 | verify_completed node4 test_h6_if1 "incoming encrypted connections with v6only" 36 | verify_completed node4 test_u6_if1 "incoming encrypted connections with v6only" 37 | 38 | verify_completed node5 test_h4_if1 "outgoing encrypted connections with v4only" 39 | verify_completed node5 test_u4_if1 "outgoing encrypted connections with v4only" 40 | verify_completed node5 test_h6_if1 "outgoing encrypted connections with v6only" 41 | verify_completed node5 test_u6_if1 "outgoing encrypted connections with v6only" 42 | 43 | exit_test 44 | --------------------------------------------------------------------------------