@Handler
  public void handler(OpsTarget target) throws OpsException {
    File canaryFile = new File(repoDir, "config");

    if (OpsContext.isConfigure()) {
      if (target.getFilesystemInfoFile(canaryFile) == null) {
        target.executeCommand(Command.build("git --bare init {0}", repoDir));

        File hooks = new File(repoDir, "hooks");
        File postUpdateHook = new File(hooks, "post-update");
        target.mv(new File(hooks, "post-update.sample"), postUpdateHook);
        target.chmod(postUpdateHook, "755");

        target.executeCommand(Command.build("cd {0}; git update-server-info", repoDir));
        target.executeCommand(Command.build("cd {0}; git config http.receivepack true", repoDir));

        target.chown(repoDir, "www-data", "www-data", true, false);
      }
    }
  }
  public void configureRules(OpsTarget target, int port, List<FirewallRecord> desired)
      throws OpsException {
    List<FirewallRecord> actual = getConfiguredRules(target, port);

    if (DUMP_CONFIG || true) {
      log.debug("Actual configuration:");
      for (FirewallRecord rule : actual) {
        log.debug("\t" + rule);
      }
    }

    SetCompareResults<FirewallRecord> setCompareResults = SetUtils.setCompare(desired, actual);
    // LEFT= desired
    // RIGHT= actual

    if (!setCompareResults.leftNotRight.isEmpty() || !setCompareResults.rightNotLeft.isEmpty()) {

      List<FirewallRecord> deferredAdd = Lists.newArrayList();

      for (FirewallRecord add : setCompareResults.leftNotRight) {
        if (OpsContext.isConfigure()) {
          if (!add.isQuick()) {
            // We add these default rules last, so that we can have all our non-default rules in
            // place
            // This is particularly important for block, with IpTables
            log.info("Deferring add of firewall entry: " + add);
            deferredAdd.add(add);
          } else {
            log.info("Adding firewall entry: " + add);
            configureAddRule(target, add);
          }
        } else if (OpsContext.isValidate()) {
          OpsContext.get().addWarning(this, "Firewall rule not found: {1}", add);
        }
      }

      for (FirewallRecord remove : setCompareResults.rightNotLeft) {
        if (OpsContext.isConfigure()) {
          log.info("Removing firewall entry: " + remove);
          configureRemoveRule(target, remove);
        } else if (OpsContext.isValidate()) {
          OpsContext.get().addWarning(this, "Extra firewall rule found: {1}", remove);
        }
      }

      for (FirewallRecord add : deferredAdd) {
        if (OpsContext.isConfigure()) {
          log.info("Adding firewall entry: " + add);
          configureAddRule(target, add);
        }
      }
    }

    // if (isConfigure) {
    // afterChangeConfiguration(desired);
    // }

    List<FirewallRecord> duplicates = findDuplicates(target);

    if (OpsContext.isValidate()) {
      for (FirewallRecord duplicate : duplicates) {
        log.warn("Duplicate rule found: " + duplicate);
      }
    }

    if (OpsContext.isForce()) {
      for (FirewallRecord duplicate : duplicates) {
        configureRemoveRule(target, duplicate);
      }
    }
  }