Top Level Namespace

Defined Under Namespace

Modules: Appsignal Classes: Object

Constant Summary collapse

EXT_PATH =
File.expand_path("..", __FILE__).freeze
AGENT_CONFIG =
YAML.load(File.read(File.join(EXT_PATH, "agent.yml"))).freeze
PLATFORM =
Appsignal::System.agent_platform
ARCH =
"#{RbConfig::CONFIG["host_cpu"]}-#{PLATFORM}".freeze
CA_CERT_PATH =
File.join(EXT_PATH, "../resources/cacert.pem").freeze

Instance Method Summary collapse

Instance Method Details

#check_architectureObject



38
39
40
41
42
43
44
45
46
47
48
# File 'ext/base.rb', line 38

def check_architecture
  if AGENT_CONFIG["triples"].keys.include?(ARCH)
    true
  else
    installation_failed(
      "AppSignal currently does not support your system architecture (#{ARCH})." \
      "Please let us know at [email protected], we aim to support everything our customers run."
    )
    false
  end
end

#download_archive(arch_config, type) ⇒ Object



50
51
52
53
# File 'ext/base.rb', line 50

def download_archive(arch_config, type)
  logger.info "Downloading agent release from #{arch_config[type]["download_url"]}"
  open(arch_config[type]["download_url"], :ssl_ca_cert => CA_CERT_PATH)
end

#ext_path(path) ⇒ Object



17
18
19
# File 'ext/base.rb', line 17

def ext_path(path)
  File.join(EXT_PATH, path)
end

#installObject



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'ext/extconf.rb', line 4

def install
  logger.info "Installing appsignal agent #{Appsignal::VERSION} for Ruby #{RUBY_VERSION} on #{RUBY_PLATFORM}"
  write_agent_architecture
  return unless check_architecture
  arch_config = AGENT_CONFIG["triples"][ARCH]

  unless File.exist?(ext_path("appsignal-agent")) &&
      File.exist?(ext_path("libappsignal.a")) &&
      File.exist?(ext_path("appsignal.h"))
    archive = download_archive(arch_config, "static")
    return unless verify_archive(archive, arch_config, "static")
    unarchive(archive)
  end

  logger.info "Creating makefile"
  require "mkmf"
  if !have_library("appsignal", "appsignal_start", "appsignal.h")
    installation_failed "Aborting installation, libappsignal.a or appsignal.h not found"
  elsif !find_executable("appsignal-agent", EXT_PATH)
    installation_failed "Aborting installation, appsignal-agent not found"
  else
    create_makefile "appsignal_extension"
    logger.info "Successfully created Makefile for appsignal extension"
  end
rescue => ex
  installation_failed "Exception while installing: #{ex}"
  ex.backtrace.each do |line|
    logger.error line
  end
end

#installation_failed(reason) ⇒ Object



25
26
27
28
29
30
# File 'ext/base.rb', line 25

def installation_failed(reason)
  logger.error "Installation failed: #{reason}"
  File.open(File.join(EXT_PATH, "Makefile"), "w") do |file|
    file.write "default:\nclean:\ninstall:"
  end
end

#loggerObject



21
22
23
# File 'ext/base.rb', line 21

def logger
  @logger ||= Logger.new(File.join(EXT_PATH, "install.log"))
end

#unarchive(archive) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
# File 'ext/base.rb', line 68

def unarchive(archive)
  Gem::Package::TarReader.new(Zlib::GzipReader.open(archive)) do |tar|
    tar.each do |entry|
      next unless entry.file?

      File.open(ext_path(entry.full_name), "wb") do |f|
        f.write(entry.read)
      end
    end
  end
  FileUtils.chmod(0o755, ext_path("appsignal-agent"))
end

#verify_archive(archive, arch_config, type) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
# File 'ext/base.rb', line 55

def verify_archive(archive, arch_config, type)
  if Digest::SHA256.hexdigest(archive.read) == arch_config[type]["checksum"]
    logger.info "Checksum of downloaded archive verified, extracting archive"
    true
  else
    installation_failed(
      "Aborting installation, checksum of downloaded archive could not be verified: " \
      "Expected '#{arch_config[type]["checksum"]}', got '#{checksum}'."
    )
    false
  end
end

#write_agent_architectureObject



32
33
34
35
36
# File 'ext/base.rb', line 32

def write_agent_architecture
  File.open(File.join(EXT_PATH, "appsignal.architecture"), "w") do |file|
    file.write ARCH
  end
end