Resolve conflicts in strucutre.sql
commit
4248c8fe4a
2
Gemfile
2
Gemfile
|
@ -35,8 +35,6 @@ gem "redis", "~> 4.0"
|
|||
|
||||
group :development, :test do
|
||||
gem "thin"
|
||||
gem "capybara"
|
||||
# gem "deep-cover", "~> 0.4", require: false
|
||||
gem "codecov", require: false
|
||||
gem "simplecov"
|
||||
gem "database_cleaner"
|
||||
|
|
126
Gemfile.lock
126
Gemfile.lock
|
@ -7,25 +7,25 @@ GIT
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
actioncable (5.2.2)
|
||||
actionpack (= 5.2.2)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailer (5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
actionview (= 5.2.1)
|
||||
activejob (= 5.2.1)
|
||||
actionmailer (5.2.2)
|
||||
actionpack (= 5.2.2)
|
||||
actionview (= 5.2.2)
|
||||
activejob (= 5.2.2)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (5.2.1)
|
||||
actionview (= 5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
actionpack (5.2.2)
|
||||
actionview (= 5.2.2)
|
||||
activesupport (= 5.2.2)
|
||||
rack (~> 2.0)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
actionview (5.2.2)
|
||||
activesupport (= 5.2.2)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
|
@ -35,20 +35,20 @@ GEM
|
|||
activemodel (>= 4.1, < 6)
|
||||
case_transform (>= 0.2)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||
activejob (5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
activejob (5.2.2)
|
||||
activesupport (= 5.2.2)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
activerecord (5.2.1)
|
||||
activemodel (= 5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
activemodel (5.2.2)
|
||||
activesupport (= 5.2.2)
|
||||
activerecord (5.2.2)
|
||||
activemodel (= 5.2.2)
|
||||
activesupport (= 5.2.2)
|
||||
arel (>= 9.0)
|
||||
activestorage (5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
activerecord (= 5.2.1)
|
||||
activestorage (5.2.2)
|
||||
actionpack (= 5.2.2)
|
||||
activerecord (= 5.2.2)
|
||||
marcel (~> 0.3.1)
|
||||
activesupport (5.2.1)
|
||||
activesupport (5.2.2)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
|
@ -56,21 +56,13 @@ GEM
|
|||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
amq-protocol (2.3.0)
|
||||
appsignal (2.7.2)
|
||||
appsignal (2.8.1)
|
||||
rack
|
||||
arel (9.0.0)
|
||||
bcrypt (3.1.12)
|
||||
builder (3.2.3)
|
||||
bunny (2.12.0)
|
||||
bunny (2.13.0)
|
||||
amq-protocol (~> 2.3, >= 2.3.0)
|
||||
capybara (3.11.0)
|
||||
addressable
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.8)
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (~> 1.2)
|
||||
xpath (~> 3.2)
|
||||
case_transform (0.2)
|
||||
activesupport
|
||||
childprocess (0.9.0)
|
||||
|
@ -82,7 +74,7 @@ GEM
|
|||
simplecov
|
||||
url
|
||||
coderay (1.1.2)
|
||||
concurrent-ruby (1.1.3)
|
||||
concurrent-ruby (1.1.4)
|
||||
crass (1.0.4)
|
||||
daemons (1.2.6)
|
||||
database_cleaner (1.7.0)
|
||||
|
@ -103,8 +95,7 @@ GEM
|
|||
discard (1.0.0)
|
||||
activerecord (>= 4.2, < 6)
|
||||
docile (1.3.1)
|
||||
effin_utf8 (1.0)
|
||||
erubi (1.7.1)
|
||||
erubi (1.8.0)
|
||||
eventmachine (1.2.7)
|
||||
excon (0.62.0)
|
||||
factory_bot (4.11.1)
|
||||
|
@ -159,17 +150,17 @@ GEM
|
|||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.7)
|
||||
hashdiff (0.3.7)
|
||||
hashdiff (0.3.8)
|
||||
hashie (3.6.0)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.1.1)
|
||||
i18n (1.4.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.1.0)
|
||||
jsonapi-renderer (0.2.0)
|
||||
jwt (2.1.0)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.6.0)
|
||||
letter_opener (1.7.0)
|
||||
launchy (~> 2.2)
|
||||
lol_dba (2.1.5)
|
||||
actionpack (>= 3.0)
|
||||
|
@ -187,17 +178,17 @@ GEM
|
|||
mime-types (3.2.2)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2018.0812)
|
||||
mimemagic (0.3.2)
|
||||
mimemagic (0.3.3)
|
||||
mini_mime (1.0.1)
|
||||
mini_portile2 (2.3.0)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.11.3)
|
||||
multi_json (1.13.1)
|
||||
multipart-post (2.0.0)
|
||||
mutations (0.8.3)
|
||||
activesupport
|
||||
nio4r (2.3.1)
|
||||
nokogiri (1.8.5)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
nokogiri (1.9.1)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
orm_adapter (0.5.0)
|
||||
os (1.0.0)
|
||||
paperclip (6.1.0)
|
||||
|
@ -206,7 +197,7 @@ GEM
|
|||
mime-types
|
||||
mimemagic (~> 0.3.0)
|
||||
terrapin (~> 0.6.0)
|
||||
passenger (5.3.7)
|
||||
passenger (6.0.0)
|
||||
rack
|
||||
rake (>= 0.8.1)
|
||||
pg (1.1.3)
|
||||
|
@ -215,11 +206,10 @@ GEM
|
|||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
pry-rails (0.3.7)
|
||||
pry-rails (0.3.9)
|
||||
pry (>= 0.10.4)
|
||||
public_suffix (3.0.3)
|
||||
rabbitmq_http_api_client (1.9.1)
|
||||
effin_utf8 (~> 1.0.0)
|
||||
rabbitmq_http_api_client (1.11.0)
|
||||
faraday (~> 0.13.0)
|
||||
faraday_middleware (~> 0.12.0)
|
||||
hashie (~> 3.5)
|
||||
|
@ -230,18 +220,18 @@ GEM
|
|||
rack-cors (1.0.2)
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (5.2.1)
|
||||
actioncable (= 5.2.1)
|
||||
actionmailer (= 5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
actionview (= 5.2.1)
|
||||
activejob (= 5.2.1)
|
||||
activemodel (= 5.2.1)
|
||||
activerecord (= 5.2.1)
|
||||
activestorage (= 5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
rails (5.2.2)
|
||||
actioncable (= 5.2.2)
|
||||
actionmailer (= 5.2.2)
|
||||
actionpack (= 5.2.2)
|
||||
actionview (= 5.2.2)
|
||||
activejob (= 5.2.2)
|
||||
activemodel (= 5.2.2)
|
||||
activerecord (= 5.2.2)
|
||||
activestorage (= 5.2.2)
|
||||
activesupport (= 5.2.2)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 5.2.1)
|
||||
railties (= 5.2.2)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
|
@ -258,15 +248,14 @@ GEM
|
|||
rails_stdout_logging
|
||||
rails_serve_static_assets (0.0.5)
|
||||
rails_stdout_logging (0.0.5)
|
||||
railties (5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
railties (5.2.2)
|
||||
actionpack (= 5.2.2)
|
||||
activesupport (= 5.2.2)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.19.0, < 2.0)
|
||||
rake (12.3.1)
|
||||
redis (4.0.3)
|
||||
regexp_parser (1.3.0)
|
||||
rake (12.3.2)
|
||||
redis (4.1.0)
|
||||
representable (3.0.4)
|
||||
declarative (< 0.1.0)
|
||||
declarative-option (< 0.2.0)
|
||||
|
@ -277,7 +266,7 @@ GEM
|
|||
actionpack (>= 4.2.0, < 5.3)
|
||||
railties (>= 4.2.0, < 5.3)
|
||||
retriable (3.1.2)
|
||||
rollbar (2.18.0)
|
||||
rollbar (2.18.2)
|
||||
multi_json
|
||||
rspec (3.8.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
|
@ -319,9 +308,9 @@ GEM
|
|||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.2)
|
||||
skylight (3.1.1)
|
||||
skylight-core (= 3.1.1)
|
||||
skylight-core (3.1.1)
|
||||
skylight (3.1.2)
|
||||
skylight-core (= 3.1.2)
|
||||
skylight-core (3.1.2)
|
||||
activesupport (>= 4.2.0)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
|
@ -352,8 +341,6 @@ GEM
|
|||
websocket-driver (0.7.0)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zero_downtime_migrations (0.0.7)
|
||||
activerecord
|
||||
|
||||
|
@ -364,7 +351,6 @@ DEPENDENCIES
|
|||
active_model_serializers
|
||||
appsignal
|
||||
bunny
|
||||
capybara
|
||||
climate_control
|
||||
codecov
|
||||
database_cleaner
|
||||
|
|
|
@ -2,9 +2,9 @@ class SendNervesHubInfoJob < ApplicationJob
|
|||
queue_as :default
|
||||
|
||||
def perform(device_id:, serial_number:, tags:)
|
||||
device = Device.find(device_id)
|
||||
DeviceSerialNumber.transaction do
|
||||
DeviceSerialNumber.create!(device_id: device_id,
|
||||
serial_number: serial_number)
|
||||
device.update_attributes!(serial_number: serial_number)
|
||||
resp_data = NervesHub.create_or_update(serial_number, tags)
|
||||
certs = NervesHub.sign_device(resp_data.fetch(:identifier))
|
||||
Transport.current.amqp_send(certs.to_json, device_id, "nerves_hub")
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
require "net/http"
|
||||
require "openssl"
|
||||
require "base64"
|
||||
|
||||
class NervesHub
|
||||
class NervesHubHTTPError < StandardError; end
|
||||
# There is a lot of configuration available in this class to support:
|
||||
|
@ -68,12 +67,28 @@ class NervesHub
|
|||
raise NervesHubHTTPError, NERVES_HUB_ERROR % [code, body]
|
||||
end
|
||||
|
||||
APPLICATION = "application"
|
||||
CHANNEL = "channel"
|
||||
|
||||
def self.update_channel(serial_number, channel)
|
||||
dev = device(serial_number)
|
||||
return unless dev
|
||||
# ["application:prod", "channel:stable"]
|
||||
# Becomes: {"application"=>"prod", "channel"=>"stable"}
|
||||
# NEVER DUPLICATE TAG PREFIXES (thing before ":"). Must be unique!
|
||||
tag_map = dev.fetch(:tags).map { |x| x.split(":") }.to_h
|
||||
tag_map[CHANNEL] = channel
|
||||
next_tags = tag_map.to_a.map { |x| x.join(":") }
|
||||
update(serial_number, next_tags)
|
||||
end
|
||||
|
||||
# Checks if a deivce exists in NervesHub
|
||||
# if it does -> does a PUT request updating the tags.
|
||||
# if it does not -> does a POST request creating the device with given tags.
|
||||
def self.create_or_update(serial_number, tags)
|
||||
current_nerves_hub_devcice = device(serial_number)
|
||||
if current_nerves_hub_devcice
|
||||
# Hash | nil
|
||||
current_nerves_hub_device = device(serial_number)
|
||||
if current_nerves_hub_device
|
||||
update(serial_number, tags)
|
||||
else
|
||||
new_device(serial_number, tags)
|
||||
|
@ -161,7 +176,7 @@ class NervesHub
|
|||
|
||||
# HTTP connection.
|
||||
def self.conn
|
||||
active? && !@conn ? set_conn : @conn
|
||||
(active? && !@conn) ? set_conn : @conn
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -41,7 +41,11 @@ class ApplicationRecord < ActiveRecord::Base
|
|||
|
||||
def force_serialization
|
||||
serializer = ActiveModel::Serializer.serializer_for(self)
|
||||
return (serializer ? serializer.new(self) : self).as_json
|
||||
if serializer
|
||||
serializer.new(self).as_json
|
||||
else
|
||||
self.as_json
|
||||
end
|
||||
end
|
||||
|
||||
def broadcast_payload(label)
|
||||
|
|
|
@ -32,6 +32,7 @@ class Device < ApplicationRecord
|
|||
has_many :diagnostic_dumps, dependent: :destroy
|
||||
has_many :fragments, dependent: :destroy
|
||||
has_one :fbos_config, dependent: :destroy
|
||||
has_one :device_serial_number, dependent: :destroy
|
||||
has_many :in_use_tools
|
||||
has_many :in_use_points
|
||||
has_many :users
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
class DeviceSerialNumber < ApplicationRecord
|
||||
belongs_to :device
|
||||
# DO NOT USE THIS TABLE. IT IS DEPRECATED. DESTROY FEB 2019.
|
||||
end
|
||||
|
|
|
@ -1,4 +1,27 @@
|
|||
# An API backup of user options for Farmbot OS.
|
||||
class FbosConfig < ApplicationRecord
|
||||
class MissingSerial < StandardError; end
|
||||
|
||||
belongs_to :device
|
||||
after_save :maybe_sync_nerves, on: [:create, :update]
|
||||
|
||||
NERVES_FIELD = "update_channel"
|
||||
|
||||
def push_changes_to_nerves_hub(serial_number, channel)
|
||||
NervesHub.update_channel(serial_number, channel)
|
||||
end
|
||||
|
||||
def sync_nerves
|
||||
serial = device.serial_number
|
||||
return unless serial
|
||||
self.delay.push_changes_to_nerves_hub(serial, update_channel)
|
||||
end
|
||||
|
||||
def nerves_info_changed?
|
||||
the_changes.keys.include?(NERVES_FIELD)
|
||||
end
|
||||
|
||||
def maybe_sync_nerves
|
||||
sync_nerves if nerves_info_changed?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class DeviceSerializer < ApplicationSerializer
|
||||
attributes :name, :timezone, :last_saw_api, :last_saw_mq, :tz_offset_hrs,
|
||||
:fbos_version, :throttled_until, :throttled_at, :mounted_tool_id
|
||||
attributes :fbos_version, :last_saw_api, :last_saw_mq,
|
||||
:mounted_tool_id, :name, :serial_number,
|
||||
:throttled_at, :throttled_until, :timezone,
|
||||
:tz_offset_hrs
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddSerialNumberToDevice < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :devices, :serial_number, :string, limit: 32
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
class DeprecateDeviceSerialNumberTable < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
DeviceSerialNumber.preload(:devices) do |x|
|
||||
x.device
|
||||
.update_attributes!(serial_number: x.serial_number)
|
||||
end
|
||||
end
|
||||
end
|
3450
db/structure.sql
3450
db/structure.sql
File diff suppressed because it is too large
Load Diff
|
@ -53,7 +53,7 @@ services:
|
|||
- ./docker_volumes/rabbit:/farmbot
|
||||
webpack: # ====================
|
||||
<<: *base_config
|
||||
image: node:8.12.0
|
||||
image: node:10.15.0
|
||||
working_dir: /farmbot
|
||||
command: ./node_modules/.bin/webpack-dev-server --config config/webpack.config.js
|
||||
volumes:
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
"@types/react": "^16.7.13",
|
||||
"@types/react-color": "2.13.6",
|
||||
"@types/react-dom": "^16.0.11",
|
||||
"@types/react-joyride": "^2.0.1",
|
||||
"@types/react-joyride": "2.0.1",
|
||||
"@types/react-redux": "^6.0.10",
|
||||
"axios": "^0.18.0",
|
||||
"boxed_value": "^1.0.0",
|
||||
|
|
|
@ -58,7 +58,7 @@ describe Api::DeviceCertsController do
|
|||
end
|
||||
expect(response.status).to eq(200)
|
||||
expect(json).to eq({})
|
||||
expect(DeviceSerialNumber.count).to be > old_count
|
||||
expect(DeviceSerialNumber.count).to eq(old_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FactoryBot.define do
|
||||
factory :device_serial_number do
|
||||
device { nil }
|
||||
serial_number { "" }
|
||||
serial_number { raise "Stop using this model" }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,5 +2,6 @@ FactoryBot.define do
|
|||
factory :device do
|
||||
name { Faker::Food.vegetables }
|
||||
timezone { Device::TIMEZONES.sample }
|
||||
serial_number { SecureRandom.hex(16)}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe NervesHub do
|
||||
class StubResp
|
||||
attr_accessor :code, :body
|
||||
|
||||
def initialize(code, body)
|
||||
@code, @body = code, body
|
||||
end
|
||||
end
|
||||
|
||||
def stub_connection
|
||||
double(SecureRandom.hex.first(6), :ca_file= => nil,
|
||||
:cert_store => nil,
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe FbosConfig do
|
||||
let(:device) { FactoryBot.create(:device) }
|
||||
let(:config) { FbosConfig.create!(device: device) }
|
||||
|
||||
it 'triggers callbacks' do
|
||||
conn = double("Create a cert", :ca_file= => nil,
|
||||
:cert_store => nil,
|
||||
:cert_store= => nil,
|
||||
:use_ssl => nil,
|
||||
:use_ssl= => nil,
|
||||
:cert= => nil,
|
||||
:key= => nil)
|
||||
NervesHub.set_conn(conn)
|
||||
url = "/orgs/farmbot/devices/#{device.serial_number}"
|
||||
resp = StubResp.new("200", { "data" => { "tags": [] } }.to_json)
|
||||
resp2 = StubResp.new("201", { "data" => { "tags": [] } }.to_json)
|
||||
params = [ url,
|
||||
{"tags": ["channel:beta"]}.to_json,
|
||||
{"Content-Type"=>"application/json"} ]
|
||||
expect(NervesHub.conn).to(receive(:get).with(url).and_return(resp))
|
||||
expect(NervesHub.conn).to(receive(:put).with(*params).and_return(resp2))
|
||||
|
||||
run_jobs_now do
|
||||
config.update_attributes!(update_channel: "beta")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -119,6 +119,14 @@ def const_reassign(target, const, value)
|
|||
target.const_set(const, value)
|
||||
end
|
||||
|
||||
class StubResp
|
||||
attr_accessor :code, :body
|
||||
|
||||
def initialize(code, body)
|
||||
@code, @body = code, body
|
||||
end
|
||||
end
|
||||
|
||||
class NiceResponse
|
||||
attr_reader :r, :body
|
||||
|
||||
|
|
Loading…
Reference in New Issue