main.rb 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. # frozen_string_literal: true
  2. require_relative 'base'
  3. require_relative 'accounts'
  4. require_relative 'cache'
  5. require_relative 'canonical_email_blocks'
  6. require_relative 'domains'
  7. require_relative 'email_domain_blocks'
  8. require_relative 'emoji'
  9. require_relative 'feeds'
  10. require_relative 'ip_blocks'
  11. require_relative 'maintenance'
  12. require_relative 'media'
  13. require_relative 'preview_cards'
  14. require_relative 'search'
  15. require_relative 'settings'
  16. require_relative 'statuses'
  17. require_relative 'upgrade'
  18. module Mastodon::CLI
  19. class Main < Base
  20. desc 'media SUBCOMMAND ...ARGS', 'Manage media files'
  21. subcommand 'media', Media
  22. desc 'emoji SUBCOMMAND ...ARGS', 'Manage custom emoji'
  23. subcommand 'emoji', Emoji
  24. desc 'accounts SUBCOMMAND ...ARGS', 'Manage accounts'
  25. subcommand 'accounts', Accounts
  26. desc 'feeds SUBCOMMAND ...ARGS', 'Manage feeds'
  27. subcommand 'feeds', Feeds
  28. desc 'search SUBCOMMAND ...ARGS', 'Manage the search engine'
  29. subcommand 'search', Search
  30. desc 'settings SUBCOMMAND ...ARGS', 'Manage dynamic settings'
  31. subcommand 'settings', Settings
  32. desc 'statuses SUBCOMMAND ...ARGS', 'Manage statuses'
  33. subcommand 'statuses', Statuses
  34. desc 'domains SUBCOMMAND ...ARGS', 'Manage account domains'
  35. subcommand 'domains', Domains
  36. desc 'preview_cards SUBCOMMAND ...ARGS', 'Manage preview cards'
  37. subcommand 'preview_cards', PreviewCards
  38. desc 'cache SUBCOMMAND ...ARGS', 'Manage cache'
  39. subcommand 'cache', Cache
  40. desc 'upgrade SUBCOMMAND ...ARGS', 'Various version upgrade utilities'
  41. subcommand 'upgrade', Upgrade
  42. desc 'email_domain_blocks SUBCOMMAND ...ARGS', 'Manage e-mail domain blocks'
  43. subcommand 'email_domain_blocks', EmailDomainBlocks
  44. desc 'ip_blocks SUBCOMMAND ...ARGS', 'Manage IP blocks'
  45. subcommand 'ip_blocks', IpBlocks
  46. desc 'canonical_email_blocks SUBCOMMAND ...ARGS', 'Manage canonical e-mail blocks'
  47. subcommand 'canonical_email_blocks', CanonicalEmailBlocks
  48. desc 'maintenance SUBCOMMAND ...ARGS', 'Various maintenance utilities'
  49. subcommand 'maintenance', Maintenance
  50. option :dry_run, type: :boolean
  51. desc 'self-destruct', 'Erase the server from the federation'
  52. long_desc <<~LONG_DESC
  53. Erase the server from the federation by broadcasting account delete
  54. activities to all known other servers. This allows a "clean exit" from
  55. running a Mastodon server, as it leaves next to no cache behind on
  56. other servers.
  57. This command is always interactive and requires confirmation twice.
  58. No local data is actually deleted, because emptying the
  59. database or removing files is much faster through other, external
  60. means, such as e.g. deleting the entire VPS. However, because other
  61. servers will delete data about local users, but no local data will be
  62. updated (such as e.g. followers), there will be a state mismatch
  63. that will lead to glitches and issues if you then continue to run and use
  64. the server.
  65. So either you know exactly what you are doing, or you are starting
  66. from a blank slate afterwards by manually clearing out all the local
  67. data!
  68. LONG_DESC
  69. def self_destruct
  70. require 'tty-prompt'
  71. prompt = TTY::Prompt.new
  72. exit(1) unless prompt.ask('Type in the domain of the server to confirm:', required: true) == Rails.configuration.x.local_domain
  73. unless dry_run?
  74. prompt.warn('This operation WILL NOT be reversible. It can also take a long time.')
  75. prompt.warn('While the data won\'t be erased locally, the server will be in a BROKEN STATE afterwards.')
  76. prompt.warn('A running Sidekiq process is required. Do not shut it down until queues clear.')
  77. exit(1) if prompt.no?('Are you sure you want to proceed?')
  78. end
  79. inboxes = Account.inboxes
  80. processed = 0
  81. Setting.registrations_mode = 'none' unless dry_run?
  82. if inboxes.empty?
  83. Account.local.without_suspended.in_batches.update_all(suspended_at: Time.now.utc, suspension_origin: :local) unless dry_run?
  84. prompt.ok('It seems like your server has not federated with anything')
  85. prompt.ok('You can shut it down and delete it any time')
  86. return
  87. end
  88. prompt.warn('Do NOT interrupt this process...')
  89. delete_account = lambda do |account|
  90. payload = ActiveModelSerializers::SerializableResource.new(
  91. account,
  92. serializer: ActivityPub::DeleteActorSerializer,
  93. adapter: ActivityPub::Adapter
  94. ).as_json
  95. json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(account))
  96. unless dry_run?
  97. ActivityPub::DeliveryWorker.push_bulk(inboxes, limit: 1_000) do |inbox_url|
  98. [json, account.id, inbox_url]
  99. end
  100. account.suspend!(block_email: false)
  101. end
  102. processed += 1
  103. end
  104. Account.local.without_suspended.find_each { |account| delete_account.call(account) }
  105. Account.local.suspended.joins(:deletion_request).find_each { |account| delete_account.call(account) }
  106. prompt.ok("Queued #{inboxes.size * processed} items into Sidekiq for #{processed} accounts#{dry_run_mode_suffix}")
  107. prompt.ok('Wait until Sidekiq processes all items, then you can shut everything down and delete the data')
  108. rescue TTY::Reader::InputInterrupt
  109. exit(1)
  110. end
  111. map %w(--version -v) => :version
  112. desc 'version', 'Show version'
  113. def version
  114. say(Mastodon::Version.to_s)
  115. end
  116. end
  117. end